From 45c1fc799da52ccc5c7e8b3bec1d669982169826 Mon Sep 17 00:00:00 2001 From: Serhiy Mytrovtsiy Date: Tue, 6 Feb 2024 17:58:40 +0100 Subject: [PATCH] feat: added leveldb as a backend for historical data storage --- Kit/Supporting Files/Kit.h | 20 + Kit/extensions.swift | 4 + Kit/lldb/LICENSE.txt | 27 ++ Kit/lldb/include/c.h | 270 ++++++++++++ Kit/lldb/include/cache.h | 103 +++++ Kit/lldb/include/comparator.h | 64 +++ Kit/lldb/include/db.h | 167 +++++++ Kit/lldb/include/dumpfile.h | 28 ++ Kit/lldb/include/env.h | 417 ++++++++++++++++++ Kit/lldb/include/export.h | 33 ++ Kit/lldb/include/filter_policy.h | 72 +++ Kit/lldb/include/iterator.h | 112 +++++ Kit/lldb/include/options.h | 190 ++++++++ Kit/lldb/include/slice.h | 114 +++++ Kit/lldb/include/status.h | 122 +++++ Kit/lldb/include/table.h | 84 ++++ Kit/lldb/include/table_builder.h | 93 ++++ Kit/lldb/include/write_batch.h | 83 ++++ Kit/lldb/libleveldb.a | Bin 0 -> 390360 bytes Kit/lldb/lldb.h | 30 ++ Kit/lldb/lldb.m | 145 ++++++ Kit/plugins/DB.swift | 97 ++++ Kit/scripts/uninstall.sh | 1 + Stats.xcodeproj/project.pbxproj | 109 ++++- .../xcshareddata/xcschemes/SMC.xcscheme | 2 +- .../xcshareddata/xcschemes/Stats.xcscheme | 2 +- 26 files changed, 2382 insertions(+), 7 deletions(-) create mode 100644 Kit/Supporting Files/Kit.h create mode 100644 Kit/lldb/LICENSE.txt create mode 100644 Kit/lldb/include/c.h create mode 100644 Kit/lldb/include/cache.h create mode 100644 Kit/lldb/include/comparator.h create mode 100644 Kit/lldb/include/db.h create mode 100644 Kit/lldb/include/dumpfile.h create mode 100644 Kit/lldb/include/env.h create mode 100644 Kit/lldb/include/export.h create mode 100644 Kit/lldb/include/filter_policy.h create mode 100644 Kit/lldb/include/iterator.h create mode 100644 Kit/lldb/include/options.h create mode 100644 Kit/lldb/include/slice.h create mode 100644 Kit/lldb/include/status.h create mode 100644 Kit/lldb/include/table.h create mode 100644 Kit/lldb/include/table_builder.h create mode 100644 Kit/lldb/include/write_batch.h create mode 100644 Kit/lldb/libleveldb.a create mode 100644 Kit/lldb/lldb.h create mode 100644 Kit/lldb/lldb.m create mode 100644 Kit/plugins/DB.swift diff --git a/Kit/Supporting Files/Kit.h b/Kit/Supporting Files/Kit.h new file mode 100644 index 00000000..2d74b4a9 --- /dev/null +++ b/Kit/Supporting Files/Kit.h @@ -0,0 +1,20 @@ +// +// Kit.h +// Kit +// +// Created by Serhiy Mytrovtsiy on 05/02/2024 +// Using Swift 5.0 +// Running on macOS 14.3 +// +// Copyright © 2024 Serhiy Mytrovtsiy. All rights reserved. +// + +#import + +//! Project version number for Kit. +FOUNDATION_EXPORT double KitVersionNumber; + +//! Project version string for Kit. +FOUNDATION_EXPORT const unsigned char KitVersionString[]; + +#import "lldb.h" diff --git a/Kit/extensions.swift b/Kit/extensions.swift index e966f8a2..02221b72 100644 --- a/Kit/extensions.swift +++ b/Kit/extensions.swift @@ -576,6 +576,10 @@ public extension Date { func convertToTimeZone(_ timeZone: TimeZone) -> Date { return addingTimeInterval(TimeInterval(timeZone.secondsFromGMT(for: self) - TimeZone.current.secondsFromGMT(for: self))) } + + func currentTimeSeconds() -> Int { + return Int(self.timeIntervalSince1970) + } } public extension TimeZone { diff --git a/Kit/lldb/LICENSE.txt b/Kit/lldb/LICENSE.txt new file mode 100644 index 00000000..8e80208c --- /dev/null +++ b/Kit/lldb/LICENSE.txt @@ -0,0 +1,27 @@ +Copyright (c) 2011 The LevelDB Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Kit/lldb/include/c.h b/Kit/lldb/include/c.h new file mode 100644 index 00000000..3025c145 --- /dev/null +++ b/Kit/lldb/include/c.h @@ -0,0 +1,270 @@ +/* Copyright (c) 2011 The LevelDB Authors. All rights reserved. + Use of this source code is governed by a BSD-style license that can be + found in the LICENSE file. See the AUTHORS file for names of contributors. + + C bindings for leveldb. May be useful as a stable ABI that can be + used by programs that keep leveldb in a shared library, or for + a JNI api. + + Does not support: + . getters for the option types + . custom comparators that implement key shortening + . custom iter, db, env, cache implementations using just the C bindings + + Some conventions: + + (1) We expose just opaque struct pointers and functions to clients. + This allows us to change internal representations without having to + recompile clients. + + (2) For simplicity, there is no equivalent to the Slice type. Instead, + the caller has to pass the pointer and length as separate + arguments. + + (3) Errors are represented by a null-terminated c string. NULL + means no error. All operations that can raise an error are passed + a "char** errptr" as the last argument. One of the following must + be true on entry: + *errptr == NULL + *errptr points to a malloc()ed null-terminated error message + (On Windows, *errptr must have been malloc()-ed by this library.) + On success, a leveldb routine leaves *errptr unchanged. + On failure, leveldb frees the old value of *errptr and + set *errptr to a malloc()ed error message. + + (4) Bools have the type uint8_t (0 == false; rest == true) + + (5) All of the pointer arguments must be non-NULL. +*/ + +#ifndef STORAGE_LEVELDB_INCLUDE_C_H_ +#define STORAGE_LEVELDB_INCLUDE_C_H_ + +#include +#include +#include + +#include "export.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Exported types */ + +typedef struct leveldb_t leveldb_t; +typedef struct leveldb_cache_t leveldb_cache_t; +typedef struct leveldb_comparator_t leveldb_comparator_t; +typedef struct leveldb_env_t leveldb_env_t; +typedef struct leveldb_filelock_t leveldb_filelock_t; +typedef struct leveldb_filterpolicy_t leveldb_filterpolicy_t; +typedef struct leveldb_iterator_t leveldb_iterator_t; +typedef struct leveldb_logger_t leveldb_logger_t; +typedef struct leveldb_options_t leveldb_options_t; +typedef struct leveldb_randomfile_t leveldb_randomfile_t; +typedef struct leveldb_readoptions_t leveldb_readoptions_t; +typedef struct leveldb_seqfile_t leveldb_seqfile_t; +typedef struct leveldb_snapshot_t leveldb_snapshot_t; +typedef struct leveldb_writablefile_t leveldb_writablefile_t; +typedef struct leveldb_writebatch_t leveldb_writebatch_t; +typedef struct leveldb_writeoptions_t leveldb_writeoptions_t; + +/* DB operations */ + +LEVELDB_EXPORT leveldb_t* leveldb_open(const leveldb_options_t* options, + const char* name, char** errptr); + +LEVELDB_EXPORT void leveldb_close(leveldb_t* db); + +LEVELDB_EXPORT void leveldb_put(leveldb_t* db, + const leveldb_writeoptions_t* options, + const char* key, size_t keylen, const char* val, + size_t vallen, char** errptr); + +LEVELDB_EXPORT void leveldb_delete(leveldb_t* db, + const leveldb_writeoptions_t* options, + const char* key, size_t keylen, + char** errptr); + +LEVELDB_EXPORT void leveldb_write(leveldb_t* db, + const leveldb_writeoptions_t* options, + leveldb_writebatch_t* batch, char** errptr); + +/* Returns NULL if not found. A malloc()ed array otherwise. + Stores the length of the array in *vallen. */ +LEVELDB_EXPORT char* leveldb_get(leveldb_t* db, + const leveldb_readoptions_t* options, + const char* key, size_t keylen, size_t* vallen, + char** errptr); + +LEVELDB_EXPORT leveldb_iterator_t* leveldb_create_iterator( + leveldb_t* db, const leveldb_readoptions_t* options); + +LEVELDB_EXPORT const leveldb_snapshot_t* leveldb_create_snapshot(leveldb_t* db); + +LEVELDB_EXPORT void leveldb_release_snapshot( + leveldb_t* db, const leveldb_snapshot_t* snapshot); + +/* Returns NULL if property name is unknown. + Else returns a pointer to a malloc()-ed null-terminated value. */ +LEVELDB_EXPORT char* leveldb_property_value(leveldb_t* db, + const char* propname); + +LEVELDB_EXPORT void leveldb_approximate_sizes( + leveldb_t* db, int num_ranges, const char* const* range_start_key, + const size_t* range_start_key_len, const char* const* range_limit_key, + const size_t* range_limit_key_len, uint64_t* sizes); + +LEVELDB_EXPORT void leveldb_compact_range(leveldb_t* db, const char* start_key, + size_t start_key_len, + const char* limit_key, + size_t limit_key_len); + +/* Management operations */ + +LEVELDB_EXPORT void leveldb_destroy_db(const leveldb_options_t* options, + const char* name, char** errptr); + +LEVELDB_EXPORT void leveldb_repair_db(const leveldb_options_t* options, + const char* name, char** errptr); + +/* Iterator */ + +LEVELDB_EXPORT void leveldb_iter_destroy(leveldb_iterator_t*); +LEVELDB_EXPORT uint8_t leveldb_iter_valid(const leveldb_iterator_t*); +LEVELDB_EXPORT void leveldb_iter_seek_to_first(leveldb_iterator_t*); +LEVELDB_EXPORT void leveldb_iter_seek_to_last(leveldb_iterator_t*); +LEVELDB_EXPORT void leveldb_iter_seek(leveldb_iterator_t*, const char* k, + size_t klen); +LEVELDB_EXPORT void leveldb_iter_next(leveldb_iterator_t*); +LEVELDB_EXPORT void leveldb_iter_prev(leveldb_iterator_t*); +LEVELDB_EXPORT const char* leveldb_iter_key(const leveldb_iterator_t*, + size_t* klen); +LEVELDB_EXPORT const char* leveldb_iter_value(const leveldb_iterator_t*, + size_t* vlen); +LEVELDB_EXPORT void leveldb_iter_get_error(const leveldb_iterator_t*, + char** errptr); + +/* Write batch */ + +LEVELDB_EXPORT leveldb_writebatch_t* leveldb_writebatch_create(void); +LEVELDB_EXPORT void leveldb_writebatch_destroy(leveldb_writebatch_t*); +LEVELDB_EXPORT void leveldb_writebatch_clear(leveldb_writebatch_t*); +LEVELDB_EXPORT void leveldb_writebatch_put(leveldb_writebatch_t*, + const char* key, size_t klen, + const char* val, size_t vlen); +LEVELDB_EXPORT void leveldb_writebatch_delete(leveldb_writebatch_t*, + const char* key, size_t klen); +LEVELDB_EXPORT void leveldb_writebatch_iterate( + const leveldb_writebatch_t*, void* state, + void (*put)(void*, const char* k, size_t klen, const char* v, size_t vlen), + void (*deleted)(void*, const char* k, size_t klen)); +LEVELDB_EXPORT void leveldb_writebatch_append( + leveldb_writebatch_t* destination, const leveldb_writebatch_t* source); + +/* Options */ + +LEVELDB_EXPORT leveldb_options_t* leveldb_options_create(void); +LEVELDB_EXPORT void leveldb_options_destroy(leveldb_options_t*); +LEVELDB_EXPORT void leveldb_options_set_comparator(leveldb_options_t*, + leveldb_comparator_t*); +LEVELDB_EXPORT void leveldb_options_set_filter_policy(leveldb_options_t*, + leveldb_filterpolicy_t*); +LEVELDB_EXPORT void leveldb_options_set_create_if_missing(leveldb_options_t*, + uint8_t); +LEVELDB_EXPORT void leveldb_options_set_error_if_exists(leveldb_options_t*, + uint8_t); +LEVELDB_EXPORT void leveldb_options_set_paranoid_checks(leveldb_options_t*, + uint8_t); +LEVELDB_EXPORT void leveldb_options_set_env(leveldb_options_t*, leveldb_env_t*); +LEVELDB_EXPORT void leveldb_options_set_info_log(leveldb_options_t*, + leveldb_logger_t*); +LEVELDB_EXPORT void leveldb_options_set_write_buffer_size(leveldb_options_t*, + size_t); +LEVELDB_EXPORT void leveldb_options_set_max_open_files(leveldb_options_t*, int); +LEVELDB_EXPORT void leveldb_options_set_cache(leveldb_options_t*, + leveldb_cache_t*); +LEVELDB_EXPORT void leveldb_options_set_block_size(leveldb_options_t*, size_t); +LEVELDB_EXPORT void leveldb_options_set_block_restart_interval( + leveldb_options_t*, int); +LEVELDB_EXPORT void leveldb_options_set_max_file_size(leveldb_options_t*, + size_t); + +enum { leveldb_no_compression = 0, leveldb_snappy_compression = 1 }; +LEVELDB_EXPORT void leveldb_options_set_compression(leveldb_options_t*, int); + +/* Comparator */ + +LEVELDB_EXPORT leveldb_comparator_t* leveldb_comparator_create( + void* state, void (*destructor)(void*), + int (*compare)(void*, const char* a, size_t alen, const char* b, + size_t blen), + const char* (*name)(void*)); +LEVELDB_EXPORT void leveldb_comparator_destroy(leveldb_comparator_t*); + +/* Filter policy */ + +LEVELDB_EXPORT leveldb_filterpolicy_t* leveldb_filterpolicy_create( + void* state, void (*destructor)(void*), + char* (*create_filter)(void*, const char* const* key_array, + const size_t* key_length_array, int num_keys, + size_t* filter_length), + uint8_t (*key_may_match)(void*, const char* key, size_t length, + const char* filter, size_t filter_length), + const char* (*name)(void*)); +LEVELDB_EXPORT void leveldb_filterpolicy_destroy(leveldb_filterpolicy_t*); + +LEVELDB_EXPORT leveldb_filterpolicy_t* leveldb_filterpolicy_create_bloom( + int bits_per_key); + +/* Read options */ + +LEVELDB_EXPORT leveldb_readoptions_t* leveldb_readoptions_create(void); +LEVELDB_EXPORT void leveldb_readoptions_destroy(leveldb_readoptions_t*); +LEVELDB_EXPORT void leveldb_readoptions_set_verify_checksums( + leveldb_readoptions_t*, uint8_t); +LEVELDB_EXPORT void leveldb_readoptions_set_fill_cache(leveldb_readoptions_t*, + uint8_t); +LEVELDB_EXPORT void leveldb_readoptions_set_snapshot(leveldb_readoptions_t*, + const leveldb_snapshot_t*); + +/* Write options */ + +LEVELDB_EXPORT leveldb_writeoptions_t* leveldb_writeoptions_create(void); +LEVELDB_EXPORT void leveldb_writeoptions_destroy(leveldb_writeoptions_t*); +LEVELDB_EXPORT void leveldb_writeoptions_set_sync(leveldb_writeoptions_t*, + uint8_t); + +/* Cache */ + +LEVELDB_EXPORT leveldb_cache_t* leveldb_cache_create_lru(size_t capacity); +LEVELDB_EXPORT void leveldb_cache_destroy(leveldb_cache_t* cache); + +/* Env */ + +LEVELDB_EXPORT leveldb_env_t* leveldb_create_default_env(void); +LEVELDB_EXPORT void leveldb_env_destroy(leveldb_env_t*); + +/* If not NULL, the returned buffer must be released using leveldb_free(). */ +LEVELDB_EXPORT char* leveldb_env_get_test_directory(leveldb_env_t*); + +/* Utility */ + +/* Calls free(ptr). + REQUIRES: ptr was malloc()-ed and returned by one of the routines + in this file. Note that in certain cases (typically on Windows), you + may need to call this routine instead of free(ptr) to dispose of + malloc()-ed memory returned by this library. */ +LEVELDB_EXPORT void leveldb_free(void* ptr); + +/* Return the major version number for this release. */ +LEVELDB_EXPORT int leveldb_major_version(void); + +/* Return the minor version number for this release. */ +LEVELDB_EXPORT int leveldb_minor_version(void); + +#ifdef __cplusplus +} /* end extern "C" */ +#endif + +#endif /* STORAGE_LEVELDB_INCLUDE_C_H_ */ diff --git a/Kit/lldb/include/cache.h b/Kit/lldb/include/cache.h new file mode 100644 index 00000000..eae88ad0 --- /dev/null +++ b/Kit/lldb/include/cache.h @@ -0,0 +1,103 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. +// +// A Cache is an interface that maps keys to values. It has internal +// synchronization and may be safely accessed concurrently from +// multiple threads. It may automatically evict entries to make room +// for new entries. Values have a specified charge against the cache +// capacity. For example, a cache where the values are variable +// length strings, may use the length of the string as the charge for +// the string. +// +// A builtin cache implementation with a least-recently-used eviction +// policy is provided. Clients may use their own implementations if +// they want something more sophisticated (like scan-resistance, a +// custom eviction policy, variable cache sizing, etc.) + +#ifndef STORAGE_LEVELDB_INCLUDE_CACHE_H_ +#define STORAGE_LEVELDB_INCLUDE_CACHE_H_ + +#include + +#include "export.h" +#include "slice.h" + +namespace leveldb { + +class LEVELDB_EXPORT Cache; + +// Create a new cache with a fixed size capacity. This implementation +// of Cache uses a least-recently-used eviction policy. +LEVELDB_EXPORT Cache* NewLRUCache(size_t capacity); + +class LEVELDB_EXPORT Cache { + public: + Cache() = default; + + Cache(const Cache&) = delete; + Cache& operator=(const Cache&) = delete; + + // Destroys all existing entries by calling the "deleter" + // function that was passed to the constructor. + virtual ~Cache(); + + // Opaque handle to an entry stored in the cache. + struct Handle {}; + + // Insert a mapping from key->value into the cache and assign it + // the specified charge against the total cache capacity. + // + // Returns a handle that corresponds to the mapping. The caller + // must call this->Release(handle) when the returned mapping is no + // longer needed. + // + // When the inserted entry is no longer needed, the key and + // value will be passed to "deleter". + virtual Handle* Insert(const Slice& key, void* value, size_t charge, + void (*deleter)(const Slice& key, void* value)) = 0; + + // If the cache has no mapping for "key", returns nullptr. + // + // Else return a handle that corresponds to the mapping. The caller + // must call this->Release(handle) when the returned mapping is no + // longer needed. + virtual Handle* Lookup(const Slice& key) = 0; + + // Release a mapping returned by a previous Lookup(). + // REQUIRES: handle must not have been released yet. + // REQUIRES: handle must have been returned by a method on *this. + virtual void Release(Handle* handle) = 0; + + // Return the value encapsulated in a handle returned by a + // successful Lookup(). + // REQUIRES: handle must not have been released yet. + // REQUIRES: handle must have been returned by a method on *this. + virtual void* Value(Handle* handle) = 0; + + // If the cache contains entry for key, erase it. Note that the + // underlying entry will be kept around until all existing handles + // to it have been released. + virtual void Erase(const Slice& key) = 0; + + // Return a new numeric id. May be used by multiple clients who are + // sharing the same cache to partition the key space. Typically the + // client will allocate a new id at startup and prepend the id to + // its cache keys. + virtual uint64_t NewId() = 0; + + // Remove all cache entries that are not actively in use. Memory-constrained + // applications may wish to call this method to reduce memory usage. + // Default implementation of Prune() does nothing. Subclasses are strongly + // encouraged to override the default implementation. A future release of + // leveldb may change Prune() to a pure abstract method. + virtual void Prune() {} + + // Return an estimate of the combined charges of all elements stored in the + // cache. + virtual size_t TotalCharge() const = 0; +}; + +} // namespace leveldb + +#endif // STORAGE_LEVELDB_INCLUDE_CACHE_H_ diff --git a/Kit/lldb/include/comparator.h b/Kit/lldb/include/comparator.h new file mode 100644 index 00000000..7bfd9891 --- /dev/null +++ b/Kit/lldb/include/comparator.h @@ -0,0 +1,64 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#ifndef STORAGE_LEVELDB_INCLUDE_COMPARATOR_H_ +#define STORAGE_LEVELDB_INCLUDE_COMPARATOR_H_ + +#include + +#include "export.h" + +namespace leveldb { + +class Slice; + +// A Comparator object provides a total order across slices that are +// used as keys in an sstable or a database. A Comparator implementation +// must be thread-safe since leveldb may invoke its methods concurrently +// from multiple threads. +class LEVELDB_EXPORT Comparator { + public: + virtual ~Comparator(); + + // Three-way comparison. Returns value: + // < 0 iff "a" < "b", + // == 0 iff "a" == "b", + // > 0 iff "a" > "b" + virtual int Compare(const Slice& a, const Slice& b) const = 0; + + // The name of the comparator. Used to check for comparator + // mismatches (i.e., a DB created with one comparator is + // accessed using a different comparator. + // + // The client of this package should switch to a new name whenever + // the comparator implementation changes in a way that will cause + // the relative ordering of any two keys to change. + // + // Names starting with "leveldb." are reserved and should not be used + // by any clients of this package. + virtual const char* Name() const = 0; + + // Advanced functions: these are used to reduce the space requirements + // for internal data structures like index blocks. + + // If *start < limit, changes *start to a short string in [start,limit). + // Simple comparator implementations may return with *start unchanged, + // i.e., an implementation of this method that does nothing is correct. + virtual void FindShortestSeparator(std::string* start, + const Slice& limit) const = 0; + + // Changes *key to a short string >= *key. + // Simple comparator implementations may return with *key unchanged, + // i.e., an implementation of this method that does nothing is correct. + virtual void FindShortSuccessor(std::string* key) const = 0; +}; + +// Return a builtin comparator that uses lexicographic byte-wise +// ordering. The result remains the property of this module and +// must not be deleted. +LEVELDB_EXPORT const Comparator* BytewiseComparator(); + +} // namespace leveldb + +#endif // STORAGE_LEVELDB_INCLUDE_COMPARATOR_H_ diff --git a/Kit/lldb/include/db.h b/Kit/lldb/include/db.h new file mode 100644 index 00000000..e8f9d4eb --- /dev/null +++ b/Kit/lldb/include/db.h @@ -0,0 +1,167 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#ifndef STORAGE_LEVELDB_INCLUDE_DB_H_ +#define STORAGE_LEVELDB_INCLUDE_DB_H_ + +#include +#include + +#include "export.h" +#include "iterator.h" +#include "options.h" + +namespace leveldb { + +// Update CMakeLists.txt if you change these +static const int kMajorVersion = 1; +static const int kMinorVersion = 23; + +struct Options; +struct ReadOptions; +struct WriteOptions; +class WriteBatch; + +// Abstract handle to particular state of a DB. +// A Snapshot is an immutable object and can therefore be safely +// accessed from multiple threads without any external synchronization. +class LEVELDB_EXPORT Snapshot { + protected: + virtual ~Snapshot(); +}; + +// A range of keys +struct LEVELDB_EXPORT Range { + Range() = default; + Range(const Slice& s, const Slice& l) : start(s), limit(l) {} + + Slice start; // Included in the range + Slice limit; // Not included in the range +}; + +// A DB is a persistent ordered map from keys to values. +// A DB is safe for concurrent access from multiple threads without +// any external synchronization. +class LEVELDB_EXPORT DB { + public: + // Open the database with the specified "name". + // Stores a pointer to a heap-allocated database in *dbptr and returns + // OK on success. + // Stores nullptr in *dbptr and returns a non-OK status on error. + // Caller should delete *dbptr when it is no longer needed. + static Status Open(const Options& options, const std::string& name, + DB** dbptr); + + DB() = default; + + DB(const DB&) = delete; + DB& operator=(const DB&) = delete; + + virtual ~DB(); + + // Set the database entry for "key" to "value". Returns OK on success, + // and a non-OK status on error. + // Note: consider setting options.sync = true. + virtual Status Put(const WriteOptions& options, const Slice& key, + const Slice& value) = 0; + + // Remove the database entry (if any) for "key". Returns OK on + // success, and a non-OK status on error. It is not an error if "key" + // did not exist in the database. + // Note: consider setting options.sync = true. + virtual Status Delete(const WriteOptions& options, const Slice& key) = 0; + + // Apply the specified updates to the database. + // Returns OK on success, non-OK on failure. + // Note: consider setting options.sync = true. + virtual Status Write(const WriteOptions& options, WriteBatch* updates) = 0; + + // If the database contains an entry for "key" store the + // corresponding value in *value and return OK. + // + // If there is no entry for "key" leave *value unchanged and return + // a status for which Status::IsNotFound() returns true. + // + // May return some other Status on an error. + virtual Status Get(const ReadOptions& options, const Slice& key, + std::string* value) = 0; + + // Return a heap-allocated iterator over the contents of the database. + // The result of NewIterator() is initially invalid (caller must + // call one of the Seek methods on the iterator before using it). + // + // Caller should delete the iterator when it is no longer needed. + // The returned iterator should be deleted before this db is deleted. + virtual Iterator* NewIterator(const ReadOptions& options) = 0; + + // Return a handle to the current DB state. Iterators created with + // this handle will all observe a stable snapshot of the current DB + // state. The caller must call ReleaseSnapshot(result) when the + // snapshot is no longer needed. + virtual const Snapshot* GetSnapshot() = 0; + + // Release a previously acquired snapshot. The caller must not + // use "snapshot" after this call. + virtual void ReleaseSnapshot(const Snapshot* snapshot) = 0; + + // DB implementations can export properties about their state + // via this method. If "property" is a valid property understood by this + // DB implementation, fills "*value" with its current value and returns + // true. Otherwise returns false. + // + // + // Valid property names include: + // + // "leveldb.num-files-at-level" - return the number of files at level , + // where is an ASCII representation of a level number (e.g. "0"). + // "leveldb.stats" - returns a multi-line string that describes statistics + // about the internal operation of the DB. + // "leveldb.sstables" - returns a multi-line string that describes all + // of the sstables that make up the db contents. + // "leveldb.approximate-memory-usage" - returns the approximate number of + // bytes of memory in use by the DB. + virtual bool GetProperty(const Slice& property, std::string* value) = 0; + + // For each i in [0,n-1], store in "sizes[i]", the approximate + // file system space used by keys in "[range[i].start .. range[i].limit)". + // + // Note that the returned sizes measure file system space usage, so + // if the user data compresses by a factor of ten, the returned + // sizes will be one-tenth the size of the corresponding user data size. + // + // The results may not include the sizes of recently written data. + virtual void GetApproximateSizes(const Range* range, int n, + uint64_t* sizes) = 0; + + // Compact the underlying storage for the key range [*begin,*end]. + // In particular, deleted and overwritten versions are discarded, + // and the data is rearranged to reduce the cost of operations + // needed to access the data. This operation should typically only + // be invoked by users who understand the underlying implementation. + // + // begin==nullptr is treated as a key before all keys in the database. + // end==nullptr is treated as a key after all keys in the database. + // Therefore the following call will compact the entire database: + // db->CompactRange(nullptr, nullptr); + virtual void CompactRange(const Slice* begin, const Slice* end) = 0; +}; + +// Destroy the contents of the specified database. +// Be very careful using this method. +// +// Note: For backwards compatibility, if DestroyDB is unable to list the +// database files, Status::OK() will still be returned masking this failure. +LEVELDB_EXPORT Status DestroyDB(const std::string& name, + const Options& options); + +// If a DB cannot be opened, you may attempt to call this method to +// resurrect as much of the contents of the database as possible. +// Some data may be lost, so be careful when calling this function +// on a database that contains important information. +LEVELDB_EXPORT Status RepairDB(const std::string& dbname, + const Options& options); + +} // namespace leveldb + +#endif // STORAGE_LEVELDB_INCLUDE_DB_H_ diff --git a/Kit/lldb/include/dumpfile.h b/Kit/lldb/include/dumpfile.h new file mode 100644 index 00000000..a82eb2f4 --- /dev/null +++ b/Kit/lldb/include/dumpfile.h @@ -0,0 +1,28 @@ +// Copyright (c) 2014 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#ifndef STORAGE_LEVELDB_INCLUDE_DUMPFILE_H_ +#define STORAGE_LEVELDB_INCLUDE_DUMPFILE_H_ + +#include + +#include "env.h" +#include "export.h" +#include "status.h" + +namespace leveldb { + +// Dump the contents of the file named by fname in text format to +// *dst. Makes a sequence of dst->Append() calls; each call is passed +// the newline-terminated text corresponding to a single item found +// in the file. +// +// Returns a non-OK result if fname does not name a leveldb storage +// file, or if the file cannot be read. +LEVELDB_EXPORT Status DumpFile(Env* env, const std::string& fname, + WritableFile* dst); + +} // namespace leveldb + +#endif // STORAGE_LEVELDB_INCLUDE_DUMPFILE_H_ diff --git a/Kit/lldb/include/env.h b/Kit/lldb/include/env.h new file mode 100644 index 00000000..918cd8e6 --- /dev/null +++ b/Kit/lldb/include/env.h @@ -0,0 +1,417 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. +// +// An Env is an interface used by the leveldb implementation to access +// operating system functionality like the filesystem etc. Callers +// may wish to provide a custom Env object when opening a database to +// get fine gain control; e.g., to rate limit file system operations. +// +// All Env implementations are safe for concurrent access from +// multiple threads without any external synchronization. + +#ifndef STORAGE_LEVELDB_INCLUDE_ENV_H_ +#define STORAGE_LEVELDB_INCLUDE_ENV_H_ + +#include +#include +#include +#include + +#include "export.h" +#include "status.h" + +// This workaround can be removed when leveldb::Env::DeleteFile is removed. +#if defined(_WIN32) +// On Windows, the method name DeleteFile (below) introduces the risk of +// triggering undefined behavior by exposing the compiler to different +// declarations of the Env class in different translation units. +// +// This is because , a fairly popular header file for Windows +// applications, defines a DeleteFile macro. So, files that include the Windows +// header before this header will contain an altered Env declaration. +// +// This workaround ensures that the compiler sees the same Env declaration, +// independently of whether was included. +#if defined(DeleteFile) +#undef DeleteFile +#define LEVELDB_DELETEFILE_UNDEFINED +#endif // defined(DeleteFile) +#endif // defined(_WIN32) + +namespace leveldb { + +class FileLock; +class Logger; +class RandomAccessFile; +class SequentialFile; +class Slice; +class WritableFile; + +class LEVELDB_EXPORT Env { + public: + Env(); + + Env(const Env&) = delete; + Env& operator=(const Env&) = delete; + + virtual ~Env(); + + // Return a default environment suitable for the current operating + // system. Sophisticated users may wish to provide their own Env + // implementation instead of relying on this default environment. + // + // The result of Default() belongs to leveldb and must never be deleted. + static Env* Default(); + + // Create an object that sequentially reads the file with the specified name. + // On success, stores a pointer to the new file in *result and returns OK. + // On failure stores nullptr in *result and returns non-OK. If the file does + // not exist, returns a non-OK status. Implementations should return a + // NotFound status when the file does not exist. + // + // The returned file will only be accessed by one thread at a time. + virtual Status NewSequentialFile(const std::string& fname, + SequentialFile** result) = 0; + + // Create an object supporting random-access reads from the file with the + // specified name. On success, stores a pointer to the new file in + // *result and returns OK. On failure stores nullptr in *result and + // returns non-OK. If the file does not exist, returns a non-OK + // status. Implementations should return a NotFound status when the file does + // not exist. + // + // The returned file may be concurrently accessed by multiple threads. + virtual Status NewRandomAccessFile(const std::string& fname, + RandomAccessFile** result) = 0; + + // Create an object that writes to a new file with the specified + // name. Deletes any existing file with the same name and creates a + // new file. On success, stores a pointer to the new file in + // *result and returns OK. On failure stores nullptr in *result and + // returns non-OK. + // + // The returned file will only be accessed by one thread at a time. + virtual Status NewWritableFile(const std::string& fname, + WritableFile** result) = 0; + + // Create an object that either appends to an existing file, or + // writes to a new file (if the file does not exist to begin with). + // On success, stores a pointer to the new file in *result and + // returns OK. On failure stores nullptr in *result and returns + // non-OK. + // + // The returned file will only be accessed by one thread at a time. + // + // May return an IsNotSupportedError error if this Env does + // not allow appending to an existing file. Users of Env (including + // the leveldb implementation) must be prepared to deal with + // an Env that does not support appending. + virtual Status NewAppendableFile(const std::string& fname, + WritableFile** result); + + // Returns true iff the named file exists. + virtual bool FileExists(const std::string& fname) = 0; + + // Store in *result the names of the children of the specified directory. + // The names are relative to "dir". + // Original contents of *results are dropped. + virtual Status GetChildren(const std::string& dir, + std::vector* result) = 0; + // Delete the named file. + // + // The default implementation calls DeleteFile, to support legacy Env + // implementations. Updated Env implementations must override RemoveFile and + // ignore the existence of DeleteFile. Updated code calling into the Env API + // must call RemoveFile instead of DeleteFile. + // + // A future release will remove DeleteDir and the default implementation of + // RemoveDir. + virtual Status RemoveFile(const std::string& fname); + + // DEPRECATED: Modern Env implementations should override RemoveFile instead. + // + // The default implementation calls RemoveFile, to support legacy Env user + // code that calls this method on modern Env implementations. Modern Env user + // code should call RemoveFile. + // + // A future release will remove this method. + virtual Status DeleteFile(const std::string& fname); + + // Create the specified directory. + virtual Status CreateDir(const std::string& dirname) = 0; + + // Delete the specified directory. + // + // The default implementation calls DeleteDir, to support legacy Env + // implementations. Updated Env implementations must override RemoveDir and + // ignore the existence of DeleteDir. Modern code calling into the Env API + // must call RemoveDir instead of DeleteDir. + // + // A future release will remove DeleteDir and the default implementation of + // RemoveDir. + virtual Status RemoveDir(const std::string& dirname); + + // DEPRECATED: Modern Env implementations should override RemoveDir instead. + // + // The default implementation calls RemoveDir, to support legacy Env user + // code that calls this method on modern Env implementations. Modern Env user + // code should call RemoveDir. + // + // A future release will remove this method. + virtual Status DeleteDir(const std::string& dirname); + + // Store the size of fname in *file_size. + virtual Status GetFileSize(const std::string& fname, uint64_t* file_size) = 0; + + // Rename file src to target. + virtual Status RenameFile(const std::string& src, + const std::string& target) = 0; + + // Lock the specified file. Used to prevent concurrent access to + // the same db by multiple processes. On failure, stores nullptr in + // *lock and returns non-OK. + // + // On success, stores a pointer to the object that represents the + // acquired lock in *lock and returns OK. The caller should call + // UnlockFile(*lock) to release the lock. If the process exits, + // the lock will be automatically released. + // + // If somebody else already holds the lock, finishes immediately + // with a failure. I.e., this call does not wait for existing locks + // to go away. + // + // May create the named file if it does not already exist. + virtual Status LockFile(const std::string& fname, FileLock** lock) = 0; + + // Release the lock acquired by a previous successful call to LockFile. + // REQUIRES: lock was returned by a successful LockFile() call + // REQUIRES: lock has not already been unlocked. + virtual Status UnlockFile(FileLock* lock) = 0; + + // Arrange to run "(*function)(arg)" once in a background thread. + // + // "function" may run in an unspecified thread. Multiple functions + // added to the same Env may run concurrently in different threads. + // I.e., the caller may not assume that background work items are + // serialized. + virtual void Schedule(void (*function)(void* arg), void* arg) = 0; + + // Start a new thread, invoking "function(arg)" within the new thread. + // When "function(arg)" returns, the thread will be destroyed. + virtual void StartThread(void (*function)(void* arg), void* arg) = 0; + + // *path is set to a temporary directory that can be used for testing. It may + // or may not have just been created. The directory may or may not differ + // between runs of the same process, but subsequent calls will return the + // same directory. + virtual Status GetTestDirectory(std::string* path) = 0; + + // Create and return a log file for storing informational messages. + virtual Status NewLogger(const std::string& fname, Logger** result) = 0; + + // Returns the number of micro-seconds since some fixed point in time. Only + // useful for computing deltas of time. + virtual uint64_t NowMicros() = 0; + + // Sleep/delay the thread for the prescribed number of micro-seconds. + virtual void SleepForMicroseconds(int micros) = 0; +}; + +// A file abstraction for reading sequentially through a file +class LEVELDB_EXPORT SequentialFile { + public: + SequentialFile() = default; + + SequentialFile(const SequentialFile&) = delete; + SequentialFile& operator=(const SequentialFile&) = delete; + + virtual ~SequentialFile(); + + // Read up to "n" bytes from the file. "scratch[0..n-1]" may be + // written by this routine. Sets "*result" to the data that was + // read (including if fewer than "n" bytes were successfully read). + // May set "*result" to point at data in "scratch[0..n-1]", so + // "scratch[0..n-1]" must be live when "*result" is used. + // If an error was encountered, returns a non-OK status. + // + // REQUIRES: External synchronization + virtual Status Read(size_t n, Slice* result, char* scratch) = 0; + + // Skip "n" bytes from the file. This is guaranteed to be no + // slower that reading the same data, but may be faster. + // + // If end of file is reached, skipping will stop at the end of the + // file, and Skip will return OK. + // + // REQUIRES: External synchronization + virtual Status Skip(uint64_t n) = 0; +}; + +// A file abstraction for randomly reading the contents of a file. +class LEVELDB_EXPORT RandomAccessFile { + public: + RandomAccessFile() = default; + + RandomAccessFile(const RandomAccessFile&) = delete; + RandomAccessFile& operator=(const RandomAccessFile&) = delete; + + virtual ~RandomAccessFile(); + + // Read up to "n" bytes from the file starting at "offset". + // "scratch[0..n-1]" may be written by this routine. Sets "*result" + // to the data that was read (including if fewer than "n" bytes were + // successfully read). May set "*result" to point at data in + // "scratch[0..n-1]", so "scratch[0..n-1]" must be live when + // "*result" is used. If an error was encountered, returns a non-OK + // status. + // + // Safe for concurrent use by multiple threads. + virtual Status Read(uint64_t offset, size_t n, Slice* result, + char* scratch) const = 0; +}; + +// A file abstraction for sequential writing. The implementation +// must provide buffering since callers may append small fragments +// at a time to the file. +class LEVELDB_EXPORT WritableFile { + public: + WritableFile() = default; + + WritableFile(const WritableFile&) = delete; + WritableFile& operator=(const WritableFile&) = delete; + + virtual ~WritableFile(); + + virtual Status Append(const Slice& data) = 0; + virtual Status Close() = 0; + virtual Status Flush() = 0; + virtual Status Sync() = 0; +}; + +// An interface for writing log messages. +class LEVELDB_EXPORT Logger { + public: + Logger() = default; + + Logger(const Logger&) = delete; + Logger& operator=(const Logger&) = delete; + + virtual ~Logger(); + + // Write an entry to the log file with the specified format. + virtual void Logv(const char* format, std::va_list ap) = 0; +}; + +// Identifies a locked file. +class LEVELDB_EXPORT FileLock { + public: + FileLock() = default; + + FileLock(const FileLock&) = delete; + FileLock& operator=(const FileLock&) = delete; + + virtual ~FileLock(); +}; + +// Log the specified data to *info_log if info_log is non-null. +void Log(Logger* info_log, const char* format, ...) +#if defined(__GNUC__) || defined(__clang__) + __attribute__((__format__(__printf__, 2, 3))) +#endif + ; + +// A utility routine: write "data" to the named file. +LEVELDB_EXPORT Status WriteStringToFile(Env* env, const Slice& data, + const std::string& fname); + +// A utility routine: read contents of named file into *data +LEVELDB_EXPORT Status ReadFileToString(Env* env, const std::string& fname, + std::string* data); + +// An implementation of Env that forwards all calls to another Env. +// May be useful to clients who wish to override just part of the +// functionality of another Env. +class LEVELDB_EXPORT EnvWrapper : public Env { + public: + // Initialize an EnvWrapper that delegates all calls to *t. + explicit EnvWrapper(Env* t) : target_(t) {} + virtual ~EnvWrapper(); + + // Return the target to which this Env forwards all calls. + Env* target() const { return target_; } + + // The following text is boilerplate that forwards all methods to target(). + Status NewSequentialFile(const std::string& f, SequentialFile** r) override { + return target_->NewSequentialFile(f, r); + } + Status NewRandomAccessFile(const std::string& f, + RandomAccessFile** r) override { + return target_->NewRandomAccessFile(f, r); + } + Status NewWritableFile(const std::string& f, WritableFile** r) override { + return target_->NewWritableFile(f, r); + } + Status NewAppendableFile(const std::string& f, WritableFile** r) override { + return target_->NewAppendableFile(f, r); + } + bool FileExists(const std::string& f) override { + return target_->FileExists(f); + } + Status GetChildren(const std::string& dir, + std::vector* r) override { + return target_->GetChildren(dir, r); + } + Status RemoveFile(const std::string& f) override { + return target_->RemoveFile(f); + } + Status CreateDir(const std::string& d) override { + return target_->CreateDir(d); + } + Status RemoveDir(const std::string& d) override { + return target_->RemoveDir(d); + } + Status GetFileSize(const std::string& f, uint64_t* s) override { + return target_->GetFileSize(f, s); + } + Status RenameFile(const std::string& s, const std::string& t) override { + return target_->RenameFile(s, t); + } + Status LockFile(const std::string& f, FileLock** l) override { + return target_->LockFile(f, l); + } + Status UnlockFile(FileLock* l) override { return target_->UnlockFile(l); } + void Schedule(void (*f)(void*), void* a) override { + return target_->Schedule(f, a); + } + void StartThread(void (*f)(void*), void* a) override { + return target_->StartThread(f, a); + } + Status GetTestDirectory(std::string* path) override { + return target_->GetTestDirectory(path); + } + Status NewLogger(const std::string& fname, Logger** result) override { + return target_->NewLogger(fname, result); + } + uint64_t NowMicros() override { return target_->NowMicros(); } + void SleepForMicroseconds(int micros) override { + target_->SleepForMicroseconds(micros); + } + + private: + Env* target_; +}; + +} // namespace leveldb + +// This workaround can be removed when leveldb::Env::DeleteFile is removed. +// Redefine DeleteFile if it was undefined earlier. +#if defined(_WIN32) && defined(LEVELDB_DELETEFILE_UNDEFINED) +#if defined(UNICODE) +#define DeleteFile DeleteFileW +#else +#define DeleteFile DeleteFileA +#endif // defined(UNICODE) +#endif // defined(_WIN32) && defined(LEVELDB_DELETEFILE_UNDEFINED) + +#endif // STORAGE_LEVELDB_INCLUDE_ENV_H_ diff --git a/Kit/lldb/include/export.h b/Kit/lldb/include/export.h new file mode 100644 index 00000000..6ba9b183 --- /dev/null +++ b/Kit/lldb/include/export.h @@ -0,0 +1,33 @@ +// Copyright (c) 2017 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#ifndef STORAGE_LEVELDB_INCLUDE_EXPORT_H_ +#define STORAGE_LEVELDB_INCLUDE_EXPORT_H_ + +#if !defined(LEVELDB_EXPORT) + +#if defined(LEVELDB_SHARED_LIBRARY) +#if defined(_WIN32) + +#if defined(LEVELDB_COMPILE_LIBRARY) +#define LEVELDB_EXPORT __declspec(dllexport) +#else +#define LEVELDB_EXPORT __declspec(dllimport) +#endif // defined(LEVELDB_COMPILE_LIBRARY) + +#else // defined(_WIN32) +#if defined(LEVELDB_COMPILE_LIBRARY) +#define LEVELDB_EXPORT __attribute__((visibility("default"))) +#else +#define LEVELDB_EXPORT +#endif +#endif // defined(_WIN32) + +#else // defined(LEVELDB_SHARED_LIBRARY) +#define LEVELDB_EXPORT +#endif + +#endif // !defined(LEVELDB_EXPORT) + +#endif // STORAGE_LEVELDB_INCLUDE_EXPORT_H_ diff --git a/Kit/lldb/include/filter_policy.h b/Kit/lldb/include/filter_policy.h new file mode 100644 index 00000000..445fe7b5 --- /dev/null +++ b/Kit/lldb/include/filter_policy.h @@ -0,0 +1,72 @@ +// Copyright (c) 2012 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. +// +// A database can be configured with a custom FilterPolicy object. +// This object is responsible for creating a small filter from a set +// of keys. These filters are stored in leveldb and are consulted +// automatically by leveldb to decide whether or not to read some +// information from disk. In many cases, a filter can cut down the +// number of disk seeks form a handful to a single disk seek per +// DB::Get() call. +// +// Most people will want to use the builtin bloom filter support (see +// NewBloomFilterPolicy() below). + +#ifndef STORAGE_LEVELDB_INCLUDE_FILTER_POLICY_H_ +#define STORAGE_LEVELDB_INCLUDE_FILTER_POLICY_H_ + +#include + +#include "export.h" + +namespace leveldb { + +class Slice; + +class LEVELDB_EXPORT FilterPolicy { + public: + virtual ~FilterPolicy(); + + // Return the name of this policy. Note that if the filter encoding + // changes in an incompatible way, the name returned by this method + // must be changed. Otherwise, old incompatible filters may be + // passed to methods of this type. + virtual const char* Name() const = 0; + + // keys[0,n-1] contains a list of keys (potentially with duplicates) + // that are ordered according to the user supplied comparator. + // Append a filter that summarizes keys[0,n-1] to *dst. + // + // Warning: do not change the initial contents of *dst. Instead, + // append the newly constructed filter to *dst. + virtual void CreateFilter(const Slice* keys, int n, + std::string* dst) const = 0; + + // "filter" contains the data appended by a preceding call to + // CreateFilter() on this class. This method must return true if + // the key was in the list of keys passed to CreateFilter(). + // This method may return true or false if the key was not on the + // list, but it should aim to return false with a high probability. + virtual bool KeyMayMatch(const Slice& key, const Slice& filter) const = 0; +}; + +// Return a new filter policy that uses a bloom filter with approximately +// the specified number of bits per key. A good value for bits_per_key +// is 10, which yields a filter with ~ 1% false positive rate. +// +// Callers must delete the result after any database that is using the +// result has been closed. +// +// Note: if you are using a custom comparator that ignores some parts +// of the keys being compared, you must not use NewBloomFilterPolicy() +// and must provide your own FilterPolicy that also ignores the +// corresponding parts of the keys. For example, if the comparator +// ignores trailing spaces, it would be incorrect to use a +// FilterPolicy (like NewBloomFilterPolicy) that does not ignore +// trailing spaces in keys. +LEVELDB_EXPORT const FilterPolicy* NewBloomFilterPolicy(int bits_per_key); + +} // namespace leveldb + +#endif // STORAGE_LEVELDB_INCLUDE_FILTER_POLICY_H_ diff --git a/Kit/lldb/include/iterator.h b/Kit/lldb/include/iterator.h new file mode 100644 index 00000000..5f648ab4 --- /dev/null +++ b/Kit/lldb/include/iterator.h @@ -0,0 +1,112 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. +// +// An iterator yields a sequence of key/value pairs from a source. +// The following class defines the interface. Multiple implementations +// are provided by this library. In particular, iterators are provided +// to access the contents of a Table or a DB. +// +// Multiple threads can invoke const methods on an Iterator without +// external synchronization, but if any of the threads may call a +// non-const method, all threads accessing the same Iterator must use +// external synchronization. + +#ifndef STORAGE_LEVELDB_INCLUDE_ITERATOR_H_ +#define STORAGE_LEVELDB_INCLUDE_ITERATOR_H_ + +#include "export.h" +#include "slice.h" +#include "status.h" + +namespace leveldb { + +class LEVELDB_EXPORT Iterator { + public: + Iterator(); + + Iterator(const Iterator&) = delete; + Iterator& operator=(const Iterator&) = delete; + + virtual ~Iterator(); + + // An iterator is either positioned at a key/value pair, or + // not valid. This method returns true iff the iterator is valid. + virtual bool Valid() const = 0; + + // Position at the first key in the source. The iterator is Valid() + // after this call iff the source is not empty. + virtual void SeekToFirst() = 0; + + // Position at the last key in the source. The iterator is + // Valid() after this call iff the source is not empty. + virtual void SeekToLast() = 0; + + // Position at the first key in the source that is at or past target. + // The iterator is Valid() after this call iff the source contains + // an entry that comes at or past target. + virtual void Seek(const Slice& target) = 0; + + // Moves to the next entry in the source. After this call, Valid() is + // true iff the iterator was not positioned at the last entry in the source. + // REQUIRES: Valid() + virtual void Next() = 0; + + // Moves to the previous entry in the source. After this call, Valid() is + // true iff the iterator was not positioned at the first entry in source. + // REQUIRES: Valid() + virtual void Prev() = 0; + + // Return the key for the current entry. The underlying storage for + // the returned slice is valid only until the next modification of + // the iterator. + // REQUIRES: Valid() + virtual Slice key() const = 0; + + // Return the value for the current entry. The underlying storage for + // the returned slice is valid only until the next modification of + // the iterator. + // REQUIRES: Valid() + virtual Slice value() const = 0; + + // If an error has occurred, return it. Else return an ok status. + virtual Status status() const = 0; + + // Clients are allowed to register function/arg1/arg2 triples that + // will be invoked when this iterator is destroyed. + // + // Note that unlike all of the preceding methods, this method is + // not abstract and therefore clients should not override it. + using CleanupFunction = void (*)(void* arg1, void* arg2); + void RegisterCleanup(CleanupFunction function, void* arg1, void* arg2); + + private: + // Cleanup functions are stored in a single-linked list. + // The list's head node is inlined in the iterator. + struct CleanupNode { + // True if the node is not used. Only head nodes might be unused. + bool IsEmpty() const { return function == nullptr; } + // Invokes the cleanup function. + void Run() { + assert(function != nullptr); + (*function)(arg1, arg2); + } + + // The head node is used if the function pointer is not null. + CleanupFunction function; + void* arg1; + void* arg2; + CleanupNode* next; + }; + CleanupNode cleanup_head_; +}; + +// Return an empty iterator (yields nothing). +LEVELDB_EXPORT Iterator* NewEmptyIterator(); + +// Return an empty iterator with the specified status. +LEVELDB_EXPORT Iterator* NewErrorIterator(const Status& status); + +} // namespace leveldb + +#endif // STORAGE_LEVELDB_INCLUDE_ITERATOR_H_ diff --git a/Kit/lldb/include/options.h b/Kit/lldb/include/options.h new file mode 100644 index 00000000..3d1a8231 --- /dev/null +++ b/Kit/lldb/include/options.h @@ -0,0 +1,190 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#ifndef STORAGE_LEVELDB_INCLUDE_OPTIONS_H_ +#define STORAGE_LEVELDB_INCLUDE_OPTIONS_H_ + +#include + +#include "export.h" + +namespace leveldb { + +class Cache; +class Comparator; +class Env; +class FilterPolicy; +class Logger; +class Snapshot; + +// DB contents are stored in a set of blocks, each of which holds a +// sequence of key,value pairs. Each block may be compressed before +// being stored in a file. The following enum describes which +// compression method (if any) is used to compress a block. +enum CompressionType { + // NOTE: do not change the values of existing entries, as these are + // part of the persistent format on disk. + kNoCompression = 0x0, + kSnappyCompression = 0x1, + kZstdCompression = 0x2, +}; + +// Options to control the behavior of a database (passed to DB::Open) +struct LEVELDB_EXPORT Options { + // Create an Options object with default values for all fields. + Options(); + + // ------------------- + // Parameters that affect behavior + + // Comparator used to define the order of keys in the table. + // Default: a comparator that uses lexicographic byte-wise ordering + // + // REQUIRES: The client must ensure that the comparator supplied + // here has the same name and orders keys *exactly* the same as the + // comparator provided to previous open calls on the same DB. + const Comparator* comparator; + + // If true, the database will be created if it is missing. + bool create_if_missing = false; + + // If true, an error is raised if the database already exists. + bool error_if_exists = false; + + // If true, the implementation will do aggressive checking of the + // data it is processing and will stop early if it detects any + // errors. This may have unforeseen ramifications: for example, a + // corruption of one DB entry may cause a large number of entries to + // become unreadable or for the entire DB to become unopenable. + bool paranoid_checks = false; + + // Use the specified object to interact with the environment, + // e.g. to read/write files, schedule background work, etc. + // Default: Env::Default() + Env* env; + + // Any internal progress/error information generated by the db will + // be written to info_log if it is non-null, or to a file stored + // in the same directory as the DB contents if info_log is null. + Logger* info_log = nullptr; + + // ------------------- + // Parameters that affect performance + + // Amount of data to build up in memory (backed by an unsorted log + // on disk) before converting to a sorted on-disk file. + // + // Larger values increase performance, especially during bulk loads. + // Up to two write buffers may be held in memory at the same time, + // so you may wish to adjust this parameter to control memory usage. + // Also, a larger write buffer will result in a longer recovery time + // the next time the database is opened. + size_t write_buffer_size = 4 * 1024 * 1024; + + // Number of open files that can be used by the DB. You may need to + // increase this if your database has a large working set (budget + // one open file per 2MB of working set). + int max_open_files = 1000; + + // Control over blocks (user data is stored in a set of blocks, and + // a block is the unit of reading from disk). + + // If non-null, use the specified cache for blocks. + // If null, leveldb will automatically create and use an 8MB internal cache. + Cache* block_cache = nullptr; + + // Approximate size of user data packed per block. Note that the + // block size specified here corresponds to uncompressed data. The + // actual size of the unit read from disk may be smaller if + // compression is enabled. This parameter can be changed dynamically. + size_t block_size = 4 * 1024; + + // Number of keys between restart points for delta encoding of keys. + // This parameter can be changed dynamically. Most clients should + // leave this parameter alone. + int block_restart_interval = 16; + + // Leveldb will write up to this amount of bytes to a file before + // switching to a new one. + // Most clients should leave this parameter alone. However if your + // filesystem is more efficient with larger files, you could + // consider increasing the value. The downside will be longer + // compactions and hence longer latency/performance hiccups. + // Another reason to increase this parameter might be when you are + // initially populating a large database. + size_t max_file_size = 2 * 1024 * 1024; + + // Compress blocks using the specified compression algorithm. This + // parameter can be changed dynamically. + // + // Default: kSnappyCompression, which gives lightweight but fast + // compression. + // + // Typical speeds of kSnappyCompression on an Intel(R) Core(TM)2 2.4GHz: + // ~200-500MB/s compression + // ~400-800MB/s decompression + // Note that these speeds are significantly faster than most + // persistent storage speeds, and therefore it is typically never + // worth switching to kNoCompression. Even if the input data is + // incompressible, the kSnappyCompression implementation will + // efficiently detect that and will switch to uncompressed mode. + CompressionType compression = kSnappyCompression; + + // Compression level for zstd. + // Currently only the range [-5,22] is supported. Default is 1. + int zstd_compression_level = 1; + + // EXPERIMENTAL: If true, append to existing MANIFEST and log files + // when a database is opened. This can significantly speed up open. + // + // Default: currently false, but may become true later. + bool reuse_logs = false; + + // If non-null, use the specified filter policy to reduce disk reads. + // Many applications will benefit from passing the result of + // NewBloomFilterPolicy() here. + const FilterPolicy* filter_policy = nullptr; +}; + +// Options that control read operations +struct LEVELDB_EXPORT ReadOptions { + // If true, all data read from underlying storage will be + // verified against corresponding checksums. + bool verify_checksums = false; + + // Should the data read for this iteration be cached in memory? + // Callers may wish to set this field to false for bulk scans. + bool fill_cache = true; + + // If "snapshot" is non-null, read as of the supplied snapshot + // (which must belong to the DB that is being read and which must + // not have been released). If "snapshot" is null, use an implicit + // snapshot of the state at the beginning of this read operation. + const Snapshot* snapshot = nullptr; +}; + +// Options that control write operations +struct LEVELDB_EXPORT WriteOptions { + WriteOptions() = default; + + // If true, the write will be flushed from the operating system + // buffer cache (by calling WritableFile::Sync()) before the write + // is considered complete. If this flag is true, writes will be + // slower. + // + // If this flag is false, and the machine crashes, some recent + // writes may be lost. Note that if it is just the process that + // crashes (i.e., the machine does not reboot), no writes will be + // lost even if sync==false. + // + // In other words, a DB write with sync==false has similar + // crash semantics as the "write()" system call. A DB write + // with sync==true has similar crash semantics to a "write()" + // system call followed by "fsync()". + bool sync = false; +}; + +} // namespace leveldb + +#endif // STORAGE_LEVELDB_INCLUDE_OPTIONS_H_ diff --git a/Kit/lldb/include/slice.h b/Kit/lldb/include/slice.h new file mode 100644 index 00000000..6d443c0d --- /dev/null +++ b/Kit/lldb/include/slice.h @@ -0,0 +1,114 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. +// +// Slice is a simple structure containing a pointer into some external +// storage and a size. The user of a Slice must ensure that the slice +// is not used after the corresponding external storage has been +// deallocated. +// +// Multiple threads can invoke const methods on a Slice without +// external synchronization, but if any of the threads may call a +// non-const method, all threads accessing the same Slice must use +// external synchronization. + +#ifndef STORAGE_LEVELDB_INCLUDE_SLICE_H_ +#define STORAGE_LEVELDB_INCLUDE_SLICE_H_ + +#include +#include +#include +#include + +#include "export.h" + +namespace leveldb { + +class LEVELDB_EXPORT Slice { + public: + // Create an empty slice. + Slice() : data_(""), size_(0) {} + + // Create a slice that refers to d[0,n-1]. + Slice(const char* d, size_t n) : data_(d), size_(n) {} + + // Create a slice that refers to the contents of "s" + Slice(const std::string& s) : data_(s.data()), size_(s.size()) {} + + // Create a slice that refers to s[0,strlen(s)-1] + Slice(const char* s) : data_(s), size_(strlen(s)) {} + + // Intentionally copyable. + Slice(const Slice&) = default; + Slice& operator=(const Slice&) = default; + + // Return a pointer to the beginning of the referenced data + const char* data() const { return data_; } + + // Return the length (in bytes) of the referenced data + size_t size() const { return size_; } + + // Return true iff the length of the referenced data is zero + bool empty() const { return size_ == 0; } + + // Return the ith byte in the referenced data. + // REQUIRES: n < size() + char operator[](size_t n) const { + assert(n < size()); + return data_[n]; + } + + // Change this slice to refer to an empty array + void clear() { + data_ = ""; + size_ = 0; + } + + // Drop the first "n" bytes from this slice. + void remove_prefix(size_t n) { + assert(n <= size()); + data_ += n; + size_ -= n; + } + + // Return a string that contains the copy of the referenced data. + std::string ToString() const { return std::string(data_, size_); } + + // Three-way comparison. Returns value: + // < 0 iff "*this" < "b", + // == 0 iff "*this" == "b", + // > 0 iff "*this" > "b" + int compare(const Slice& b) const; + + // Return true iff "x" is a prefix of "*this" + bool starts_with(const Slice& x) const { + return ((size_ >= x.size_) && (memcmp(data_, x.data_, x.size_) == 0)); + } + + private: + const char* data_; + size_t size_; +}; + +inline bool operator==(const Slice& x, const Slice& y) { + return ((x.size() == y.size()) && + (memcmp(x.data(), y.data(), x.size()) == 0)); +} + +inline bool operator!=(const Slice& x, const Slice& y) { return !(x == y); } + +inline int Slice::compare(const Slice& b) const { + const size_t min_len = (size_ < b.size_) ? size_ : b.size_; + int r = memcmp(data_, b.data_, min_len); + if (r == 0) { + if (size_ < b.size_) + r = -1; + else if (size_ > b.size_) + r = +1; + } + return r; +} + +} // namespace leveldb + +#endif // STORAGE_LEVELDB_INCLUDE_SLICE_H_ diff --git a/Kit/lldb/include/status.h b/Kit/lldb/include/status.h new file mode 100644 index 00000000..170dd2ab --- /dev/null +++ b/Kit/lldb/include/status.h @@ -0,0 +1,122 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. +// +// A Status encapsulates the result of an operation. It may indicate success, +// or it may indicate an error with an associated error message. +// +// Multiple threads can invoke const methods on a Status without +// external synchronization, but if any of the threads may call a +// non-const method, all threads accessing the same Status must use +// external synchronization. + +#ifndef STORAGE_LEVELDB_INCLUDE_STATUS_H_ +#define STORAGE_LEVELDB_INCLUDE_STATUS_H_ + +#include +#include + +#include "export.h" +#include "slice.h" + +namespace leveldb { + +class LEVELDB_EXPORT Status { + public: + // Create a success status. + Status() noexcept : state_(nullptr) {} + ~Status() { delete[] state_; } + + Status(const Status& rhs); + Status& operator=(const Status& rhs); + + Status(Status&& rhs) noexcept : state_(rhs.state_) { rhs.state_ = nullptr; } + Status& operator=(Status&& rhs) noexcept; + + // Return a success status. + static Status OK() { return Status(); } + + // Return error status of an appropriate type. + static Status NotFound(const Slice& msg, const Slice& msg2 = Slice()) { + return Status(kNotFound, msg, msg2); + } + static Status Corruption(const Slice& msg, const Slice& msg2 = Slice()) { + return Status(kCorruption, msg, msg2); + } + static Status NotSupported(const Slice& msg, const Slice& msg2 = Slice()) { + return Status(kNotSupported, msg, msg2); + } + static Status InvalidArgument(const Slice& msg, const Slice& msg2 = Slice()) { + return Status(kInvalidArgument, msg, msg2); + } + static Status IOError(const Slice& msg, const Slice& msg2 = Slice()) { + return Status(kIOError, msg, msg2); + } + + // Returns true iff the status indicates success. + bool ok() const { return (state_ == nullptr); } + + // Returns true iff the status indicates a NotFound error. + bool IsNotFound() const { return code() == kNotFound; } + + // Returns true iff the status indicates a Corruption error. + bool IsCorruption() const { return code() == kCorruption; } + + // Returns true iff the status indicates an IOError. + bool IsIOError() const { return code() == kIOError; } + + // Returns true iff the status indicates a NotSupportedError. + bool IsNotSupportedError() const { return code() == kNotSupported; } + + // Returns true iff the status indicates an InvalidArgument. + bool IsInvalidArgument() const { return code() == kInvalidArgument; } + + // Return a string representation of this status suitable for printing. + // Returns the string "OK" for success. + std::string ToString() const; + + private: + enum Code { + kOk = 0, + kNotFound = 1, + kCorruption = 2, + kNotSupported = 3, + kInvalidArgument = 4, + kIOError = 5 + }; + + Code code() const { + return (state_ == nullptr) ? kOk : static_cast(state_[4]); + } + + Status(Code code, const Slice& msg, const Slice& msg2); + static const char* CopyState(const char* s); + + // OK status has a null state_. Otherwise, state_ is a new[] array + // of the following form: + // state_[0..3] == length of message + // state_[4] == code + // state_[5..] == message + const char* state_; +}; + +inline Status::Status(const Status& rhs) { + state_ = (rhs.state_ == nullptr) ? nullptr : CopyState(rhs.state_); +} +inline Status& Status::operator=(const Status& rhs) { + // The following condition catches both aliasing (when this == &rhs), + // and the common case where both rhs and *this are ok. + if (state_ != rhs.state_) { + delete[] state_; + state_ = (rhs.state_ == nullptr) ? nullptr : CopyState(rhs.state_); + } + return *this; +} +inline Status& Status::operator=(Status&& rhs) noexcept { + std::swap(state_, rhs.state_); + return *this; +} + +} // namespace leveldb + +#endif // STORAGE_LEVELDB_INCLUDE_STATUS_H_ diff --git a/Kit/lldb/include/table.h b/Kit/lldb/include/table.h new file mode 100644 index 00000000..1555199a --- /dev/null +++ b/Kit/lldb/include/table.h @@ -0,0 +1,84 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#ifndef STORAGE_LEVELDB_INCLUDE_TABLE_H_ +#define STORAGE_LEVELDB_INCLUDE_TABLE_H_ + +#include + +#include "export.h" +#include "iterator.h" + +namespace leveldb { + +class Block; +class BlockHandle; +class Footer; +struct Options; +class RandomAccessFile; +struct ReadOptions; +class TableCache; + +// A Table is a sorted map from strings to strings. Tables are +// immutable and persistent. A Table may be safely accessed from +// multiple threads without external synchronization. +class LEVELDB_EXPORT Table { + public: + // Attempt to open the table that is stored in bytes [0..file_size) + // of "file", and read the metadata entries necessary to allow + // retrieving data from the table. + // + // If successful, returns ok and sets "*table" to the newly opened + // table. The client should delete "*table" when no longer needed. + // If there was an error while initializing the table, sets "*table" + // to nullptr and returns a non-ok status. Does not take ownership of + // "*source", but the client must ensure that "source" remains live + // for the duration of the returned table's lifetime. + // + // *file must remain live while this Table is in use. + static Status Open(const Options& options, RandomAccessFile* file, + uint64_t file_size, Table** table); + + Table(const Table&) = delete; + Table& operator=(const Table&) = delete; + + ~Table(); + + // Returns a new iterator over the table contents. + // The result of NewIterator() is initially invalid (caller must + // call one of the Seek methods on the iterator before using it). + Iterator* NewIterator(const ReadOptions&) const; + + // Given a key, return an approximate byte offset in the file where + // the data for that key begins (or would begin if the key were + // present in the file). The returned value is in terms of file + // bytes, and so includes effects like compression of the underlying data. + // E.g., the approximate offset of the last key in the table will + // be close to the file length. + uint64_t ApproximateOffsetOf(const Slice& key) const; + + private: + friend class TableCache; + struct Rep; + + static Iterator* BlockReader(void*, const ReadOptions&, const Slice&); + + explicit Table(Rep* rep) : rep_(rep) {} + + // Calls (*handle_result)(arg, ...) with the entry found after a call + // to Seek(key). May not make such a call if filter policy says + // that key is not present. + Status InternalGet(const ReadOptions&, const Slice& key, void* arg, + void (*handle_result)(void* arg, const Slice& k, + const Slice& v)); + + void ReadMeta(const Footer& footer); + void ReadFilter(const Slice& filter_handle_value); + + Rep* const rep_; +}; + +} // namespace leveldb + +#endif // STORAGE_LEVELDB_INCLUDE_TABLE_H_ diff --git a/Kit/lldb/include/table_builder.h b/Kit/lldb/include/table_builder.h new file mode 100644 index 00000000..c691b533 --- /dev/null +++ b/Kit/lldb/include/table_builder.h @@ -0,0 +1,93 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. +// +// TableBuilder provides the interface used to build a Table +// (an immutable and sorted map from keys to values). +// +// Multiple threads can invoke const methods on a TableBuilder without +// external synchronization, but if any of the threads may call a +// non-const method, all threads accessing the same TableBuilder must use +// external synchronization. + +#ifndef STORAGE_LEVELDB_INCLUDE_TABLE_BUILDER_H_ +#define STORAGE_LEVELDB_INCLUDE_TABLE_BUILDER_H_ + +#include + +#include "export.h" +#include "options.h" +#include "status.h" + +namespace leveldb { + +class BlockBuilder; +class BlockHandle; +class WritableFile; + +class LEVELDB_EXPORT TableBuilder { + public: + // Create a builder that will store the contents of the table it is + // building in *file. Does not close the file. It is up to the + // caller to close the file after calling Finish(). + TableBuilder(const Options& options, WritableFile* file); + + TableBuilder(const TableBuilder&) = delete; + TableBuilder& operator=(const TableBuilder&) = delete; + + // REQUIRES: Either Finish() or Abandon() has been called. + ~TableBuilder(); + + // Change the options used by this builder. Note: only some of the + // option fields can be changed after construction. If a field is + // not allowed to change dynamically and its value in the structure + // passed to the constructor is different from its value in the + // structure passed to this method, this method will return an error + // without changing any fields. + Status ChangeOptions(const Options& options); + + // Add key,value to the table being constructed. + // REQUIRES: key is after any previously added key according to comparator. + // REQUIRES: Finish(), Abandon() have not been called + void Add(const Slice& key, const Slice& value); + + // Advanced operation: flush any buffered key/value pairs to file. + // Can be used to ensure that two adjacent entries never live in + // the same data block. Most clients should not need to use this method. + // REQUIRES: Finish(), Abandon() have not been called + void Flush(); + + // Return non-ok iff some error has been detected. + Status status() const; + + // Finish building the table. Stops using the file passed to the + // constructor after this function returns. + // REQUIRES: Finish(), Abandon() have not been called + Status Finish(); + + // Indicate that the contents of this builder should be abandoned. Stops + // using the file passed to the constructor after this function returns. + // If the caller is not going to call Finish(), it must call Abandon() + // before destroying this builder. + // REQUIRES: Finish(), Abandon() have not been called + void Abandon(); + + // Number of calls to Add() so far. + uint64_t NumEntries() const; + + // Size of the file generated so far. If invoked after a successful + // Finish() call, returns the size of the final generated file. + uint64_t FileSize() const; + + private: + bool ok() const { return status().ok(); } + void WriteBlock(BlockBuilder* block, BlockHandle* handle); + void WriteRawBlock(const Slice& data, CompressionType, BlockHandle* handle); + + struct Rep; + Rep* rep_; +}; + +} // namespace leveldb + +#endif // STORAGE_LEVELDB_INCLUDE_TABLE_BUILDER_H_ diff --git a/Kit/lldb/include/write_batch.h b/Kit/lldb/include/write_batch.h new file mode 100644 index 00000000..eb2647f5 --- /dev/null +++ b/Kit/lldb/include/write_batch.h @@ -0,0 +1,83 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. +// +// WriteBatch holds a collection of updates to apply atomically to a DB. +// +// The updates are applied in the order in which they are added +// to the WriteBatch. For example, the value of "key" will be "v3" +// after the following batch is written: +// +// batch.Put("key", "v1"); +// batch.Delete("key"); +// batch.Put("key", "v2"); +// batch.Put("key", "v3"); +// +// Multiple threads can invoke const methods on a WriteBatch without +// external synchronization, but if any of the threads may call a +// non-const method, all threads accessing the same WriteBatch must use +// external synchronization. + +#ifndef STORAGE_LEVELDB_INCLUDE_WRITE_BATCH_H_ +#define STORAGE_LEVELDB_INCLUDE_WRITE_BATCH_H_ + +#include + +#include "export.h" +#include "status.h" + +namespace leveldb { + +class Slice; + +class LEVELDB_EXPORT WriteBatch { + public: + class LEVELDB_EXPORT Handler { + public: + virtual ~Handler(); + virtual void Put(const Slice& key, const Slice& value) = 0; + virtual void Delete(const Slice& key) = 0; + }; + + WriteBatch(); + + // Intentionally copyable. + WriteBatch(const WriteBatch&) = default; + WriteBatch& operator=(const WriteBatch&) = default; + + ~WriteBatch(); + + // Store the mapping "key->value" in the database. + void Put(const Slice& key, const Slice& value); + + // If the database contains a mapping for "key", erase it. Else do nothing. + void Delete(const Slice& key); + + // Clear all updates buffered in this batch. + void Clear(); + + // The size of the database changes caused by this batch. + // + // This number is tied to implementation details, and may change across + // releases. It is intended for LevelDB usage metrics. + size_t ApproximateSize() const; + + // Copies the operations in "source" to this batch. + // + // This runs in O(source size) time. However, the constant factor is better + // than calling Iterate() over the source batch with a Handler that replicates + // the operations into this batch. + void Append(const WriteBatch& source); + + // Support for iterating over the contents of a batch. + Status Iterate(Handler* handler) const; + + private: + friend class WriteBatchInternal; + + std::string rep_; // See comment in write_batch.cc for the format of rep_ +}; + +} // namespace leveldb + +#endif // STORAGE_LEVELDB_INCLUDE_WRITE_BATCH_H_ diff --git a/Kit/lldb/libleveldb.a b/Kit/lldb/libleveldb.a new file mode 100644 index 0000000000000000000000000000000000000000..cffa186f8b61df9a04211d9980dd1252ba28bf08 GIT binary patch literal 390360 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�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 z z=X2<%v6z3|HrNB_!qt>^gY%)C56Ss*%wXMznA5pTma})K1Nq+tEVUAAe1+o4B-@UiT&*#}?2 z-|x;_>?gaTAAisKvKR_NH=jd&-$%Jh%kBl3jzNbw_lN^?{_*i5RDrqo&%lv|{8`h){vq%pljq-eOBeg!hmNN?SYQsG zHfC&Z5Mf>KA2A2GEz<`NLbq1T5l6Bt<6fJ+JM{$7^C!%exPMq3w59K*{&IZPJ>>Y> z?4jAnzZ>l){XqFbwsA6@^4rIZ?+s2eznM5~?-1s}FQI+uCmwiYw3yJl0d+N6(qG$U z89hk2eW?FBgx#=T%JFwP^2|q=`el*Da^e{A5c3zwKEdBG{4YS*EkAdFU)LRf;F0BM z_j^e1v5bCgnr-xJz1zf*F=+EcfbXLn9*gU_I!D)Y+u)nn;aEg>8jn1L?{lE%M)WcD z>nrHTp8_wv6-0JR5c2FJThAs!;N!!KVT

`0B^Egnc(Bb47^4q=N#5m=7Tn^ftrE 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 W=R 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∓9UzH*YaMTj-i3GxyT9)o7PdEP|-h<^OxgnD@Xp((z1qYwV` z1kWFSWW`@Nyzf0{oi#4vztef9b(DMxi?6?go>)39uRPW1~O&`o;K^J(LG>7aXPW+vya{XURe|zYqndrlxarEKw7skXj zjwV)yQAH`;>+T-!JuVL3JalH+oy=!zDD1y#fzel^6F>&%>96={iK4DU^ zSrmc~xH2M7zKmHfZjWc&noN&>l{L5z9a_FW_MK$v_aDpWwV(M`^^4+DHkUc7l77J5 z4~xb#Hyx*+ZbXm4{4#qZ`cLqhovIoXPkpHUiEg#WCuNr8Q(nN?lV*P(U3lUL1F`Yc z9yQ}A`$GFkcL3XK>E%4Tt~%-y$}&6toOi1`nZJ(@8x(J%oJRCe!pFz?BaLmk^UY~f z^jU!gE)-Rb-P-mxz{^=n@|`cveC7Y4=;fs?bZmm1{m>s1xT zQ@>}Q?xee~m&*3F9M1H$ID31AzLwNLzCC%?pJ(jvrAF}kQpNN8D&i*by_{#`eeOQr z^@L~mS`K~L*SgoY`1MZq`exd_zGLRxy*@841ABw^`+#0t?s?*dohRI{=l1PyZtY8bMBP%&boN%5>WjBNL5F`DoH%g4XRKy%=I%Y&!pn9{?;^)I?p9_#*6(C=Z)FN2i#$89g`a0i8W?;)fA`W4MKL7u!7__~D=#a~j!2`nKx9 zCif8UsGp6)pZGt02RV*$FTuE1g&b5i#LTX`-5hO1)=bGBojNp8$4?9WC7K7LJ;Oga ziSD+)v$n8fj-Pb}bMU7xWX9!d-6;bcREB6hgfTPE^sCu#$NK8uJvFPW$BPeE4>h|y z9xz?QFUPu>mp6XLlq3qLwC(4P_;S3N@{2iN>F((U;?f7l+R?7*O8N)%m(Ta6IsV%H z!x%4C`f8Wc-mUF&y=|B4kuhwWBnn?EInBIU#6GR~s+#pl6a9Z5c&J9lt^b(44rNu~%bY;Dgk-a;3B5 zww^_Qof>x=&pPTaiPRhJIRBiRukcX*P4rVi`SFiICx=H_uW3EHdu6|*%4clf0W#xm z^ODL(Y(nJBWI>CRk6A3J3E zvt1ZsbcVA1xyfKJ_L?dtmrM(oG2D@ZOz7@i%YJ_IGlufq`w%ovBfF2OfBnv# zI@__Fu`PzYAKYDxNXFK2ExGY_n6%U613#;~Ku@LjF<#=$eJ54RtueBsbUT9qkV z$wT0v@vew5HNhIt<0DVLRhsGy?#dvY-WdSx&WEe)t>e_$&GWk*=4tGlza0CD{nSnQ z#$;o`cvgK0;~@CgopjHuxHebk(j>6WU7r_)iq{7&o)XvjUBmfZSJ$QUKb*^5#@W}Y zI``_^qV!p$(;4?-(q+e|qUX)tgFbq1&d6)xoD0~qfZyGJd@Z`k?t9Qn?(H$QEROzo z&&&MoxocV+z2Tl;@Hw@rB7_iz^0LY*Lj(~xay;}>udVfOyK-#fOi7SC628W_1j8$ zS_55Z&s^il`OahqntZi=!;B4?jLn?$4RfcH_;q~9)asn0_L_Gv-X-XNPCU95@k2Tf z7}{Gr@THpr>!)%4QDcO7K)NdI1@qX)J-<(Q<^|bdMA3_|M^_s~=cjz6+mcV4s-90a zZ^piR1bVH*wD;rCLGtSfz6`WGq#t;T=f@f6r$g5hvTNwAy}T^PKBb&J@y+Nz-l87E zS@*s_6xv$*g+aZHW4F*RAbkuth@X7yA2WYP3C9Sl%tDjp`05YfV}1zZ>Mx=H1boD6 z?3EtL^V7eSalQdNiy-U6BK-76TT7SA2r~guL@7PbjY1Y~J;nZ~o`23-M`fq9P z$DVp!usyo6r%wG`TM*-%muf=qrTP}~4T6*6vPd`lXllo5(q?thv$Os72cT&Yebcoe zasBoi{PqXCNN;6Yw1&>_z-RxHzf0{{LY~qMdu56aS>!+bRBFe inNw>Lf)Gd>qN z<8HvI2V?IutgDX}v)?nxp8L|dF6pIp?n_YPqqhg7JwWYe4rkw|=Va|$W;y$o`+{xz zmP4qAw{Q99{JxAmz!CoJbM`GG?Dfg^z`#G62Lj!*YO>h(nGTJ@K2uX{_kEo4d8*_9 zKVx>Aj|bQjzfH~ZCR*XbOF>~58oeMQGV z6#iys7vsxgDEi@H=!Xvu(|$*wRiD!Ig8b7M=j?^Izw4Zn3%dKeL8lz;i@9ZqK0!_d zV%e+5?aY1L?G)6RW-bd%(f;ku;#;^T+^&{Pd>gTQ9{yVi}u(<5= z)sJ)+s^6ynmhCs~^VKgt?Sl1t^}k{L!gk#+`*F{w%!!-14+{C#8LyBtI`{kH`j67O zMe<}BcLGPz&#>oFvXMK1B?n30&l=UaBe>rBPTIsc`Blc4YR$jQtGdTYX{GPiJgsN= z`fl;kqpz9WpLuEDT^i3^oB4gO>9>1cUg;!%PP*6}J;1)luZSyw*4jstJlh(Ne7c`; zrvIalCZ!{jKcz!|+vZQ{u+~E8nB-3>aj7p}ZROL|9o*;J2%cxlr|9jG-(u)kg`;QB zo#-(&d5C-_u@(ya__=k5kyX;m=v-DbZGJnD8C{!Iw+zXrGmu48|9#X$W8U9)GIx4w zJ;{rmx1)RRRp-dCSH)!0or_8$;duXy0ggS;BbmvcpZaX-Gu~cA09&@EOx9M+SqbiN zF5Cz0(a8nPfIX9ZzN0Jot#yp#zTlxJzB2;b$>ABE#vOS8RQGh&fupT++gPthJ8jlLlmQ*%23EGg-v>wn-VTP2Ik12bgfnRn#?l?1}GOnGvXY z%=q_|XPTo6*ylZA&k*Yz+9G^-+`%^={}w^+3f5WOuP}cFGY0Hg-E(z~{1+WAFgxV0 z2wU?#+4wN3qRy4_!VIvs^^yAQ{~CZZx<$I>%GaL zd(SQ3y(=8QSuy~7ve(IuCZk95NOS}79zBqA`Z@2HvG&{J5A0bu#Jszawx3F#-7^Av zWM7i9qu(@e~4_<>0n&5-| z@IkMkE+5FAW)t#q8TcsQ=|IU2>2+guHv44vK{eBd;Uk1P9fAhs;53IlY_$(EPffP3 z?;bC%%JSzC=vM}Q$h);Oz^@Yg624$f+#jsTfp%-a@8uPy_IKEb)q&sUG(P=>`k@vE&ht$1@qT}<74<5ZY9Z${v1bVlCn`qt-y1M)Gx$vmF--mC&n)O3Xd|ei2 zDaEJML40_OJ?Cp}-Q`orqwhk>%b~m~+C$}4GhWL6ZGrZEX@e(Og9q6sABsFW4L?O$ zz;f={ZblxQ0{<<5E(?ABni|eG$j-blqkD7rl~1kv9rnbsZNsO*o{bg0qf?<_cV9N` z%6_HVlzv?U%@*1=eF>V$??E=-FY@~r-FssPHNb6K=y##Et$=nKra>tL3C|a( zQw?=8-Gh7f**^T5zb|xayARXVf3)dvlI2s`d!54G?BrG*muTqp=am}&I^LJn{N>2t z>R;&O0>#{)o?%K-nWki%3GcdzJye5F6y>8neUi3GT=JH)9yZVt-QgHx{lzIwz|rlJ z&t%3veit)$@vNnYaHZ^-@DV3}UGbsQ&+^xG7kUOyPj(=~9m}+K9miZY7#ex$i%r9O zMGpmPf@ki0hPm=+Xw$~ubcEYv^ds8;>B+mm_afx~Yv=6rBi7HF&WpHy*5pGkHh+Aw z{*vj=Tq=KkD`j(|x_*C;TUX{zba1;^XN``)7k^NlH_y0moqsbf*@(VhXB(ww(4Ljf zN__CO@H5~0#kd;Pqs6JmqvzD4VSY(cXF2M>Kf|eq{4lB>{WAL3=sc*-+KtZl1$#i7yYW02 zR~v79Eu+MJ-idZ=6fni9qbou`ss)$yUpoFTrf^be@H z3cI<7XrKAzu6^7V>>Q*gD8P3o72m-gMBaSnG=<+n=Ujvh!eRC}XW+YHCN^~&k*^kT z7HfLfaLXEGxamJ$v#$9iAAD;TMMtpi{qg#Bu3Ts0`{sD^lsm>smv|X6srrC$^>CC- zseUkresm?}e|PhA?!m_QCu7!MV_*K=n@r0{o@*VeeWrov^6LEq_vnnqo8+areR%hC z?aH&6(>1qG#71cYdaY{N*Rv1m`6ld_)2}9gZ$a_A{8;S9KcRF}-6=zJUq|u6X$xmh z-ol@n(rZrW3qIewBr9Hhn`!xO+MLpl=hZj4cd0LDJooC{7u{O*ZSM0r@~dYKYm^;5 z^~_S)9#8Q+ou|_6_mx*QbC`E#SLbzq?l+j~yFO**6X?4uumeC2+fO@aoJ$|mb#~Bu zj$Aj(^FJgXFbUQYI!ju_nQ-?VcP-$qUC#CgbLyU}nFpqJ=oh9a%`eRF99@JvN1W|P zz-&SHzN_e>w*FZ~|EzNQXKri%jL<);=$}=#e^%N48KEyk=${d%f3i+V>!0pe({>I$ zmC=o{r4M6EE@Mj`do+E~5A|c8fivH)cWt$w9b;mes!{kv7g{XJY;f9dyR?=M^b%dzQ>@cS#B*!r(OkFEbQ-@sN||H>^hqz7>DZGR@g z!&i0~!dLK5h3|&*;QP1_S=s6&>wd75dD1kuT#rpRW6bbQXso>f;Vjr0&b`9!c?zFB zPvOy5cJyDg=P8!+TjwdHOKpFi;`w$sXXj+sNX}h@zVUhH4G(9>A0l%{eINQJ^Jg)8 z6oDs#>x(l6u|5ejKgqg7_T~5*gGal?Qg0J=cah=N?Zs4ZB8qRLACiz9VO3Ip+l@BMa(GW{7>!`Hmdr?g_s1(o%TB-4kp% zmJvV9-rlFjeDOmswC%4WS32v`I{N88a8dbn^w)jh~s8e!MLm%HU9Qr5nGJTe1iCd%y||5P`uz557rM_tAM$8Kz6AG7EP zI4sXHy+yaVQ!;A3{_Nm+>?X&~PWp~G_;2~qL-Cu@r#y_!i){5(2S081p*<)4vtt7$ z?4)kU$$5>P*!cZySV_E2_63YV(sy|BTj7Fn6YBj1HLd5PW#7i!Bs}U?e&C$%mW^Y5 zmTB3(GJmIRD$Nj6y9vCMCVGi`KY;A!<12638T1+2y`fZlJV9)K4K}|4#v}PUOzeKG zq{x>XR{)-oyL`3cC#Sx$wPZe0d{nUT^^$sE{jpz7NC?Un4<99Gmfg&leiLK+R~h4H zGuGe8{4^`h*zf4sJi9#QgCD|iP1xore&;eO z*Z0=F^&il6N!B=9pN4FPK25r=8pj8e)_v|=)jE{dKMTPPTNr?Inw_2Dx3FM;eni1}|d?d|C0u<1%a6IzH~ z;!B)?@y-XM+e|wjEO|Y!WgPN)>KuRKXU8=#ezy6!c4hTPC_mlDb^lXsen0*y)N;`efzT(f-N* zS8Iy)vz`ihZdoYBlBH(AaWn`9qk|a3md-6hG*F@Yd|OdF3TtMzjWVd zigV)0uMU5?c3qVh3|Sr56Hk1n5S{5J+B{h2>VOKLc;e#-Vb-*>wAT~>N7-lui@tI} z8Cv`Il1BwYz(0k||9Q{%ru#76h!4}IfAIWYpWjAD_Bh%@QQsO9^VN=n4zek9?L+0q zH#Tc$o*9>9TuH!hLFC+9hal$;o9?Wuni#iakJU`v0$+I7GGA8qaBP$AKnL<9>kt+A^+2$C(zjyX@_<7#qv6oqFLT?xA3A_(N@U`gLHVGaWnX-;k$tZyxR* z9S)zw_Y83z&FASl_Y3WvF`w)z>}?jUq0Q9?q*GVhOHV%b3)l_?O>IBZ#qobU0G>xr znioaRsx0^9to7@p3-siyV&tL3rET(vyH_eb2QmWkNTh3WT;V``LPNWg_~cf9D*S?3 zRL9&_orT_H*nstok1b738!^S%!!PXqWb+F6|0;a#M+9Uq5 z%e60Cy2X*$!vxunX`Ek~R9iOAFFvcR*OB!;fUfAdo&Ilp8GGp@W8w{WOLy0Y_&XWnY~7Y^JW7_kW38B)Jxwq}s}dvFo}o+%nzgrda{c1|F@v zz}*EM(HXhQ%IXW4%jdr~wWRW4Z0(o}-a4HclSQ7gg<9}6*2TyN^S{OzL47sWMVXhQ zJb#mUz4&6j_`@#dOsC`n#*5iiq}A^xe4Bed*H7GxUOvOMPv~f#!w&1Lc}{ywnw#{k z$~xPpXZ!a9X?r(;ReooUm9DQNkG#+Oj>_}qNWB*b<0F0$bu13Yr_qPyW2os;cdjT5 zyMEvU#0Q6jmA1FY4k@QdWQ7$vQLyB zsOgpPpT_c;T_%LP2d=~a+tU@khEo64`|i{4Is7(PAGpsHZR(LdF{ek4xnyvd-`)9L z_l0iP#lDbrUE~Wrt}{hLdT^2CD>KeS_h#prk{M?n*qfbiN~WJ#x;JZ(DRJ?N*WaS>P_M~wjG;05bw!pdKevCUnDP$8mv1t^7J)lbDv?l%uzd^i^(sJ3CHn8-g4bo6K71?zJ=c-BjJ*-Xl^&Y=CCie z?y?^20rxQ5U+Qkghz{~gpm|^P%yP;xi@NjUO#OrKeBPe{4%wWMYqeh{{5EG)y!ya{%`xl@RIe@Q z64G(eJ2R9&`OK$`8Ptos94H(&g2xf?h~9cxG7EeqSGD3myy~|=?<#NB_F3fj)+ed$ zYO6J$q{b?)lHcsFIdq<;HsCvr_k!d%jd-=U&gM?Da0GFpbu;A-zjZ{i4E(Z)lg+`! z&{6YH5qUUc2lBM!Hjg(Z{~lgpu1ctXkxn#MI*&HOg}L->T);U<8J`OmaQ1M?2N&_b zcs5ABs+(74CBK8z!;{6PQ_s&MlS+mZzUR#se20^_+T(NOOWnMD&!=PaWV`Bbg_Dh( zzjW^!Ft=d0rXyn(DkPKqs!8{4=Zy?KPBDOA@pzQ zY0~dNI>Z^0*70nrtDkblH2JHOjUH_p$Yg%ttNC>$d%Q`;s$JmmUxdT>Ea;GqgZ76+ z6VWS*tnDXWYq&>PW4U{r=i0hJe@B1p-5;a*d6F^CxKf0CuYRg^WPrSe!$bR^wfe7j zu3^581)Zmj?j-}4EOOWRx?9ElMzEe2zn!mOJ-JbJ%3cs)Op8IMm z{>*#M?=O1K@x49R{ar!XXWL1gI}W9<|5b**`)H%H*GleMe+Y6P8?(<S?T!b-s33aeKoZ6)@dp?41TecdrmY0kEX}9zXL++t-J~0mf6@O zJp>&^r`@!*^qjf0qx|Ej?VIQ`_15>!&+xrdpXPg~&idZ*o{I_Lnm#C*Xj)hQ&R|~unrzNvu7S_xr!0maGWmPji2pI2O;|81j31}$W`ho8 z4Zg~9@KvTXN}pr*iM_N+Ctqbtz8H>2hnsk1mO=K+Yp$UEmpJ}CbZtF9<`UVb>)!9vtdYdO-yLS& zt)7YwEfaq|;BgGuYjsBco+8HZ!oKF{n-`hclm2hU(R;sWX8-JRvmHCRce6hE+TQ8- zKVIt3su})oD`!n&Tt0vt5kPk%zsQf_-*X^#-r|{k*y-&j&jaYu4q6?8=ALT!s*Z03 zZj$Bges`*>w|@2BJMrNx2sIK@X; zE7b!vzir~Hee?GDqDL5ilKCX%&uuo$x1UPxWq%w!6#_(5nVOL2`8@%4|fwZ<25%bPtn0gTBT8Y3kU7n zwlDA24(Qa-&5ZvU`5=p&L&K)7X8ezcE6MJleB$bfE3$Pe{-$BxHTbs2S3dS=rx+jQ z&&|Vo2=sGk1I@i>lerU2&tj>}@wy{-%D?G6w97N1k$C3!D!&8VjL(d(?j$b!QRX3m(PrK`>yP5T)m%oJ_+x+b~uAt zpR?C7_R)XN9G~#x!;gD;wVpamS?TZVKF8mDmU>R_C-4JO((~Lli=50HFJI41q}hj0 z8~6N9zb$X`o_rhqiuVMc|4rt&D(Dn+Z0k+!lg6BNx2fvrj4QT|F?2Igemmm|b-bT< zl?J}%PG{GrXzM%3BziV3%l75$v-@%d?^b}{T~kDdT*kD%&X{&SeZAqGhj|AbY38ea(aD*vG72yQA#L-z*sTgWc) zO3uAVW>MN`Hy1~>pMyXA**=f+m8*I1)IER0yy`=)Xn)SS?VkEFL;lErn`}9<2hmxF zrXG`%QJ!giqw-JS(?@BV=leU)go$9|&Jn!s;9||+_9NB^~&bbdyvRgl&VgELNOMr1&W3{tqg&YA*XFK_%_uFWIl9rkEeI7eBiayxhC;xNiddP7XEiHhh*jUTFgr+@nmNOSfG} zmQTh$?eAPaaGlUn@`HD7rpUOqkdhUm*hYmI4?F9dot0B98m=f$!W#|^LwU42zvDd9 z+*iM%Fu4I*DjjLg?zei+w%1Jox8F8oscp(>OWKQfpW@xm-3OJQ?SoCo5>6lFnKLhv zmvBh$gAI%?3Hz+0KG=XxxP2dF59OS?oMb!^|2cK^>XYHtr;hnK3je7-74Y9E-mhRx zxr;I71=>@6(;G)-5f`HVPQL-~O7%U9w@14W`dzQ@>3ms?J)-tFikIQH)^wWd&+4P( z?WEBd1HMjM*|J6}Eqw3wXQyANFT?kh@V&;tLgwNo#uf3s{Lo3Kp>v53Q%Cl>dzTM0 zi!>)nN86s}5%BVOKH84wo8bA?v`0rgueAN1@+H0e8H1P~+xIi>MPW}?eB2qos$c4k zohE!Cb(W^1waq8o*?6+`&PI1VTy3x!=DS=x1kL43rk>voe7*iK!EeSXzJYdX1Xe?% zSNY19i_$jnb=sn<=I#7*))*QWV^)59leFqnjePZPgs)e&A^&P89=#0l;O5!7{)hqzh;A74rBY#m*8Fb z@CpRYyT^$yI5T-KcMH|lGbSXE<61bI&4M@YHh5LxxJ}sB85)<*zixzSs0==J=lz*4!Ad?<>wZ|4zQL zSCv1<@Tt_;6Y#&}*`SX-!i+)9FL6G&`qQet@^Q8P)2g4w`wXg?fUV&G>`X*I-FNjQ zV}@6r{68<}o-E-j+}7r!{8^Me8t$q=l~izOrA}b!EQ3XJ^zS*2HF4gH{$*NdnRG4 zJ`EfHljy=^6YZT15np0g6PGQ_!#T;H2k|*DiSz%(%b#B-KLp?=KJrQ?T>M`e+6gzL--yTn&yK-_S~{%j%l1_|K?46bO*m~ z*dsvC3eTzEx8VoxgI_{@=sfk5EY=wf^nS-OgDWTG*2#xN?w(0GtDEDD7tg_~mHz&F z#+~83slTt|OX5lFt6g6b{X6s}F#+A^2X^nIjC~hx?<9-5{1QId!MSR8o#&p7T}-~u zfb#(24Sb`sr%IF0{)qOGygT+9Nmu3X@9gbVvX}BEdnpQwPS1en_lBDIT6pCcWhnpl z`b+Ab*Zx_$PBX*w?zeQQ3FadVcI$N`!*c5T@oE>`P!OA7`z7)E6ah93-)mgKyxo&po?#hMp zLUZq*w>Wg){Yygg?wcEWq;g3#bl<#37FOOjk86m$gb&U#d994e1KG~i5A{}&wUTwd)K@NL8`-43o8~c8M%1gqKD?)H)r0+ z^Q67z!3Qb*!FhA;e|X-5!U?dr^8Wimi{~wIYkTorC;Gv;i$xqWYu-bP=Y>3~x%ARA zz3V-7h^R^|zCFb2=l+i<%en;GBpo zb1hlVnpZKG`d8lf@cj$s*@k%t;yo~L&Jw~8S1f#Jo|$w1gAYFRfWiyrJsP@ObpCJo zDf_N5%ZwR$HE=8NGGH8-K&$^Uu))H5;7f!@0hR8fXN=hfyurc%@JEE-|BjpPS)lS+ zf}-p(;I`E+G{8%YnR&X}fu*OvVRSkB$TxuZ0WSk8eZa!GUpI#CH#6eG(u1pvd4Tx0 zEzDo;re6|s>+t|k_>}=wevyT1s$9GV0rmXtueq?^!nGFO0eq178*Dgi;bj&!JYftZ z8u>I(`BVeH1zc*w6D&N9l3a960)@{zz=wcuSh&-|trpf<_^gH17A^&G-v=uG4I97H#&5UrPXm?D8ldX+{(Kid zQ)$d-!XHK5_#;5Ye*l~Ye8)a-uyC7&R|8>%k%@cU_dWoY5Plo@2(TKc_?bY_;cDQc zz-@OMb0aVYRC_%RRD0b56n#NQ zpNNGwSQxf&l!Z+d#ym{A4Zs(GOM!at4&XN6M4<5g2x17|cYum-uyC7&brwDiyqfr> zK-E8DVHr?(Pqc6pa1G%iAQRloi(FXxez`F-c>W6TM&JhERABf{_jwUe&rjdsmh(Q) zNe^_=1C_qoKL6-;m;PIUqH{e^bgl!c9#3017pQhC11g_UK;`q%ZEm{vfiDq$)`rK} z@Qb&){Q28k+;ZxGN*A;62KzkEhU;%Ork?l>K!&K14*==nBgX)1fR_P%(4)wOrKfK) z<_GY1(uH?^1bm$E5f|Q>06xci2Z1WL9;o~l0=EFeK;=6DsC>t`urvTvzFk~+=jpGy z`6gX>=W(F&{RpUh-vKJWYTz>9Dxm0i2T*)6)57pf5bi-38Q7jj`~0H}2DGYE-(TY(#aF`(*w3sCJo5vY7F0;)bC7nbG$a|!oy zVd*;)jM+rGg+S#u6ZlQw1mM?!AB}hW@e!c-?+u{ZW-U}E}`k`(Zy@bO@)i%5e_$=`e8@>am^fQ5f1q=hf z4;%%gDMt-dJ8uI_5K|;JQKK@a2Mbj;OUUlpJpaq zSlR>>|JMO)fe!#3{sJnWFmMWR0x%351!Tw=c@dByU}P7d=*OKs4t(3fZ5Halj^dYE zc!z~A4tAeU0G25~pz4tad;*vQi~zgX=f}U`#vioseGA{PaJz*sTDS`M1n)l%R6h9Z za`L|jDEjByaGs5SdXS5cCW{|14|7M4;GId}3#4BQ6n@VFm0vHQ>J=++(?9OQJC_2L zz6hxF`M{09wqp2Z5p= z`?gL!ih%3&K8>*uC`W5uc<%-mmQDn!zDIIgIv=D_MDJ&TYLBOZ$}b93x+Fw!;(;}U z*8qLwSM9>mJAlved^S+&dI81nIWD|20DN3>s0;5r9(40v3sm|r@N2+r5L5N81AYUz z7AX3#&*#wRaTk{2JJ$Fqf1wLYqd>hs3Ml*r0fk?_3rn#BbnrRo!aF|z3ZM5~c;`Dn z;okrhK59hOdp5)t9S=ghYT!(u!tc{q;*(c^O1IU*4HmAk@No+lT6l+r?3Fn0O|bAd zl~F$LTlj{BF$*IW-e6&lg-58Q-utbEYb{)AVbsElEbL<8apS(X&BCWGj9EC*Lh5WT zqKoVKFyK<)KwtzoA9xF}5_kjf9$*>pW?&e26L12MG(AQEX9J6XUj>GMQD8psR$wpS zZNN(m@NWla`s)f`EaZRa#Zaby)sX5Tnf`4Bk+kKq64w?}9C z8%Dpu|Lvo9@;`RPsw*=62S+DH2mGhU#K!V}d~8CdKRNmIWWWETdyd~jo)5nGV5a}+ z2cPAC-I5oVkn_^*OUZfZ8vbv8eCOlfSrv=s!0lUoJGc6%+*V(;VDcs3>6dt3|3lx_A1eH^@AS*SBQN_t zdYR`hHu&lr2yg$;xAQ|_;zQq&4}E?=F6i(I<@2vS;Nz!XaKi!8H$CY;_@o~+Yq<*! z_HjPJOCUNt;eCF?yruA%fcs?n#f0et<#Y~xCMv!9gbmj-t}6Wz#v6U!XC7Ag9mXep z-eNpe_>KqN@RfR>!e=t5=`-HuUv2aIH-*#UzZr7hKf?H{&p+Gro9z34XTvYp@KzhH zx8XDNW8wR>4NFdQ@VDV-Z2FgM_!kP(CnGl8Q|Z&fkJB zy7*4E@jV#C^pRYs^k1{#Yb`!k+VBY*e~S(OjSX+{!sIP_YF(+%W*h%cHh#4Y|K5fl zu;DJ2zIWR2P#fN%Fk{*S7XN(VlNSDW8y~arPm7+EAA7x83fBt8KUogO5HVsE_kLgP1;rl&$dNHXcX4PIw~a>htPQH+;vnZny^i zR{B+UyWwvzI4T?k>hm%EK;fJzZg>N7o5BY*Ao6+J*6;0`-S97Me9;|lxR1?m%~##< zdVtdVQ%;aC%*=B*`;pyR9C%E_%SzJn{D$S z?}lHo?%Z|N)fT%YAm`ShPb zZg`Hx=Y7jhTl>22KYo`R|FEU!Mf2S77UUS^AA@K0Sz+lBo8yL?m|ztDktP^EH(ca~ z8}0b^Amf+f@1Py^+06K*@MU(qx!1P$TIizB-`Mw`{(rf97x*ZvGk^S@nLs815hPs1 z3&W)vz}QU4)g@(;5Sl>56jJN9wv!M76B3e`43~(&0M-UW{SidhQhz00wwpoePrJ~< z)?Fjo{$g>h6l>Z3-5S8%4PslcsEG^a|NWkG-kJA(XC{|oyZ!&qCvTp4&gD7x+jE}t z9Hfip-|Y0?siika9PdO3{1%0;QTXV4r2F3}{Cb5i5$(BCyG!}65bd#3JE_|HPElT+ z+S3ZZsM_03mEL74e_Wi?96~uT{nsn^#}s~x!ixlbj6-NAH1kw_NKDg`RsK&Z_cv7d zIMqMCuKL#-1v12MRevfgmUu#;v|HkC z(SAF%7rrF%UbIW5Cw-5^e}nc(oSST#u6T*ps`QO#{~FmD8ZQr{JW>52GXeEw#NTn5 z@$1n3jPCnU-bQ=_`lS(12V%s3j+l)2A7+^Gn^5mY_i~i45qF~>8SyBDk|LslMzs8cES1t81&JsW5 zYE0qt&|Z!7Y#0xWcpnfWe!-HyQVaf(rT+3P?l~45#c86y&63{@7QDz3Uh{gtx+F_T zT&!3=x1@emVd;`(-c0;hRn=Hny14RQ&AX;*O=Ux~*(c;0GUdU3fm;M|r!Nyi4F2kh zTAupT((TP&TGdeB=m)9gQ3!m6f*g%Hfi$8O%WJDdaI<%J>YY;BVOf>moqc;nV+}nm z5t0>OZmL>QXz`B3_zTuHHbUq^PmFhNVcojIrHhv=^Uw8q-R`vI6;0KZ-X=eVDT*tX zEK7rBrLUsV>u;>6_BRz*78cSnr=qsDzLKIJv?+{;DX*ac@+LAVW%bN<4Em|j=%)@w zKYKw)s6=GBVolXRnHWwaD{4#Eu~t`9NVsIN-Vm}>X{V)@P!>m(bulW72^p^SyQZ&iQeKfgpkrO!`xX>TfM@PTDP&{7Nl8S4V4z*n5}oe z2p84hMBj{XoEsjgLxXXIC*$y%mA|&S76MyQJcXN3gri=55e}hb7YvwNx1}g_deQ4+ zf$|=nx=cA(Duv_>9dd?E;Me5(vj0pbT>K2MYtLJc!Z;#_LvSaGLb;gbH(e%3m7W@>6`CWh{c<(QSV zTJNox{x}7c-8p!yrjnGaf;A1Aclo_ljrAJmQA9&pb?euNwL+|UFxoU|odq*1nwqLt z)o}sxSr8Lbbck48g^_0FI>;enaxV=v3U?YOyxSq;xuC*dfkl8Zb<5^@u?RpxV|2#6 zUnoh1h8(@_)6$nztuLsr!@{AeuENhHhMGOa?2R&D%ete1lSETtwJ0!syfZc~^qNvE zS-e?8@QQ_46tAJA8M}ykE*30erjgT&Ou!&sSt=1}%|7dP7BZV{vu3dl)Bo^aV@*NN4{@b9=p^TzQ*nF(frq z_b5t0#8mp=X>VR&qsVLM8<(`}0ylf4Y=T%L9tTU_$5gpZ?=Jl?uu3O>7 z=A@#wSmbvp8>2f@M(eGsUr~j^#}ch{U16bg%TR9U;KIFlSs~KBbg?(tWauZZsx>%&Gq&ig;X|}gmR?f0~R1BgwwdpkXvidb*pQILwO-n24R>_Tl zH_cc-V#*dPgTm#Zy^mhGq8zM)-CWaXm&w|c<4VS|+Um-xLTg%#HIwtjD!)icT6m8# zU}SDnWTNR5F3a(Xgc-9@h+;66fHBr=J=QCTG_u<7!kK&!O5)(E)3jWQCGbZ9V%RwkvnB{ z$H<+ssVc=zIU+W}G2ko`+BdM+KcjtlDTXk^0LGD#!wR}~Z3V7Ycq>+-o2kJvv=qXi z6LToQK!w`MFcNixb0CN|R&mN2KABMC$-%T)w!U6W!J(A_6BC{!OBaHHQo2sG1@m%2 zSgGz<2o{AUkrAAYXw_wGt*otzWvKDbf)Lm_VM2O-)g%nJCCgI1=>-^bMFaEdgG#!k zQy3d&n%Z~BF|Jy!F3h9DTyyY}oMjd3s;~iDi`ib5pdOLMXO_;SPBX)PX8pn(4L=p;RCS#6KNJpv0XuXa^wJ%;vXOnw8c7ce@PiurqWnVX}S{KMM8 z5S1GXW6OGE?q?P4IvK4c!W=9#DzN;is8!1!tbIP47%`p{7KXA~mgc=fk6Lfl?kvgt zGcY@@oc|~Ldsb;hBlwy|%I5hmeIZsgB^8aU)Z#}3i_sQE0~TD#@HB=NU~V%@u>LUc zI+v-LpH0Qo*UZT<_R}1cMq~YkYTTWxx?|-^+)KM-rQi+golJJ50m!9^T~c0{kgSBfx)sP~ZL`RjiJc>C(#h`5xSc$;LQ6@hQH)$cPWfW0UjXi) z+yaVTY~&7EgNIp#I)^4hC4`Fwb4nQV;2U}~Z-o0baR(0xEL2mtxS8c4k$#GXRYIXVV@37Kl~p*6!#dpG z+)!o7@mw+4ahPB7*&J_`HZ$ia2W&MWqBAs==tqy1&KmAXV%-(0d@**J7v{~)g3*;B zg2+sU)`_Num?oBa%hs-0gH0c+3Fme>M!RJw!V2u@EoliiRCiW!Q$DyB`jVBSr$~`n zG@1gIxHB*$vN%GiA9Q13B4C^Svy7k%Kw0c}-HWZ+O~$s%+| zT~fr%rjc=qzV54ETe|`U*^pm_3+3jOxG8sr7LkLQnVh!96_JV4mwoJCEB@?@l4$j) zm#G^&X{M1=>9PuP`^fwq-}{TbAX;TA0gW(Pk7oNb&)Sn^ElP;6FAMH(ME@uqe!e zMhJ|u`eIQr56E#WZYH-e3dNZGT8dK`#}Iu+844G4fOKHhA0s8qnq>XTyvclm-C)hB zuo@_@@DPea??igLbZ0NDZ!E+*MeTqaaFAeV%z_1iZ7E1ZYdF^NF}$#Hr=cg8RId|U z(k2eEVvRKyyAsx#+gNQT))ni`OjZmJ@*vQiN~i`1He}W3bn=nBvh--{*7S&Vt7r+K z(a$v8W*35^zd|hx4DPm>&1&GV*Se3>DZx{(pK z1Y8H>&NNH#q@zZamWp}K(2~?DF9y#jTC@?n;;3=Ulha$>IqD4c*3b`kwr&;r;m*>n zLO-&XIfQ=U2OQEu4xwN80SC8MTToh@neD|7 zaqxSqJN!%dNEJTPa=h{fyyC~Avf}Iv{l{GO!=1_>l1f_WmpfIP;r@JDsw-^VS*e*h zIcYg_-7Z%~D*m~ovm58o>FKabPs^6R%M;gA91Q$g%oDd(R^BQkgn#kL?>>ddsSu&# zKZqAG~%BV@^myk%8!oInjggZgu&1Z*&Brbc)ewXca?>4{nt#$ zJJOIIME$h$kf);zrWU6K2z2B1R$}DGSf(tj^mIB(tX3NhIz~gs^pn zmKXNXq0&{ZtagDO^Hv1;KMQH$BMtv4!YqpgLhp8bFt_4^NUO$saM^%N2mN&dPXXKo z`Ci_cfEXoJ9SFma{3t?Bc|>>}wlTi>Kz;XoyL2kve%WdZEVV;F8wl=^I;ryT?!i%^ z_tts0d=CL4-Z@k6)^ZGflbq16hBtI_@HV-TM#Q^-Ly5vm|tH#Zlj=_buwQ?DdX-KIM@ppLo1C=?q?W*zw+^bAQ6! zo*dlk9nUvNQ6~2k;|;#~DbNE9ooQ$ryPP)YGmHx??YTLQx{w9lv&9iSjd$bDysWi- z4OjjzqD~TJnclPL`M};qZodDi?Rv|uwS5G?A8oM*XSuZt?}0`Ddf%vbm~UmGEhKfI zT%6E%dY6Qd)5f;IBB#%XDQ#Qn}+ua zx{(fsW!bu*V^`pyBk;@p88Z=w(GLa*q1)eim5ehYzDxawTJSD=ittco1^ae@DKjBK1nMO(dW__5c>+y{;CN3-nqaK^>06+ha%g&dRh<-%SeX zp`$(DeZ9Of{DukY($Y88o3n$^x0&dN-@7I~W7;?#%mOXGxj0|+fvtP-p5KvK{O~3- z)0>Qbl7N0P`xZ}7_v6FcmDAAH?QZQjX|kNoBEPu4n8mPjfb$*0IlvbI$9s;W-h+D) zaJ*p!n&_|i&3DnJrH1JwFg?cbcu$6DGtzLvj(tw2(}OpLrnx*pBc1-2wd0pJ;(b~4 z2V5oDH4A70(2rJq%+d{I_gEvH-`s?Kh0-2>j>doj>y4G*C68!cmZEammUH$qxqi27` zD$PLFSJ4DLgY`o7-`cwHyo<8=vzj=}<2PZdy@-Vl=H8O?66PKRr2S4ntT$3x0Fwc0 z0jB{L0b<^Mnh?`-$pVEF0?$ncycz!9#{fk5w1TC8Gl9*5Tr}qmN54XK#(YTO~TwxKm;v$LBiZ3z!{*EuHZ}s4`Z;w&ys@@ z=I&HD<^kI0-Uo=k65a#HUoPe>Q4U?G4N)F|vp{!+f+Y&N6ub)%YZh^@8*`Gl*Ny%% z#shn_MRAY&7C;wpLaupmHALLw#uXLZ<8E>6bl?uP{SvMmA9NhX?-xdNj)=FvHsTHZ ze|tnX{=YxsJpR9u*p(P>KR@asBK#H#pZ803^Y8f0`=t8%ZwcLjx1&&LzM}ANDtxoT z3l(0j@H&OpEBr2n{~CqQ`@JU>{xN7W{`*i#G~Z(U_}GqUR>3dvT?$`=aKztG_y$E^ zPj5AGgwfZVydT5+d5^=6W)VK(=>mhUD&<}VNb>{Gr+b{jS?|PopPwdK;Vy+g20OZ6 zuW-DDC~%+ft!cke?h4gzSMF~si+@(`k1PBH@tDt}mC2t1&0Mnm_2%Fo@(|1Apt zg33>aO8=wEeT8!8MRbNQQh1G`$9&PuQT{y&k0%bldU-n#oX}awr+L3v zaz}n%iPyUX%$-bKSfp6UVInH4EW43fC_Mvt8ju3cEQXmLB_AHOv_t8kr?5PD%yYkJ z+$TW_Ir!G|j(%Q{DhMv0>_Bfr}kaQISN;XW0aDvRt> zw80}&9(P6#8<37wB27B?GA#|9z7lb<0k_LmR&S_UA>~s!O<+Wl(WYLp#xWrt?vyK=cRnF|A#bSK}HYqMBpEY>wN*=jMN<5)fl zzN@~*7%JaY4^Mhnl4wO(7hzoASh!1EhYec35JG9^zv%P5hWf>ZQ2gRF~GLy$jXdfdHOc*@|!5ys4#*-hkRimtO;a3$(-K+w4IrpYzW_ zGm@tRp2mIPRoHs7woKP@@b*NGA8)PuC*pk}ymPz{Z((c$Uu@q(?J(`2hC#eDMII~P zsIdBd8GNy`f86{-r!5KZzveyc9id%V^v!*E|1|;czxM7f!W#z(mp7l-;m{6Ez&oY- zJIqeJ@fs?NC+$J(ybqFJgi6@6iemJhTX-#1>$=>ZRPi`|y9uIKmc%>y6GnwLxU|AaT-Y;QjnOZmf_!>ylg{NKZy!4n_kV@$V{>PY6YXgV%6Y?+ z`N64p!^e(tn({^M@CLM@#qe`4-b>Tn3J`WZ+T3+`pR&0>|KVBjTH9>2kwti8{5{c@ z_+Ccd!&}gXs>NHviJ~pdLtA~Z$9C~TjPO`H=kg8NpN1<>U3V;%6HwrTBsc! z<(MSi8c#;N*x~&$n!5{cok1tZ@hum$3k7)BY_vl=w$paqv3)k%g_lu2HJ9^G)PUbr zd-lHF524*&ysrOf20v}s{bG`$0WwTAfJ0RDF-e-Y3#+YjbUCE1` zv|s1Hh5aXm{QGVbZ=sL#A^yu73(?LNpuH8K-Q}bGB7ABuSH0;Iorfb`dbgb|W2LHKv@Pd(nUH*{Zt^KV;l-_qjyp%m6^N~QlV8Y#%OJzQqWqcNCk|cL zloxhG>ufg`dUsavD(YNZwT-#&9pdV4wPnc(;tRPo`Rr(4$rdxyyju;GfvNh$CegS` zg@lkfS0?XZkC?@e2l8vZp=@5q4ohwzGZoSUG-@3?$oiGtu8SSUg%4&>xdAQ=VR}?2 zb1Ix`Lw*>3gc<7k)sMlBhV(eZoX6mlO^ad54d`@kW>}cJLC0v+@D;KeOm3iErOT&6 zw16J-_8bOjmE{mE{)n}{z7=ki8*pNA?Ez#uxZW-TJ`<4ohKn$Elcp{=fTcLk63Ay4 zel1yn?cin>&chO1T5$FPPflVf&ik*zxi;ohp8Io7O2k}_^;zqzm%NAPCoDQwZE$lY zBrJB0)4t>!E6++lOIp@7yR($%&02an=3@`$b>wW%VC(#$gz4XIJ8oV3IeE^Ha!AJd z#c4Q;?)e8>_CKwzvgJ&@&z6I3ljNK!_cT+JHSQCS zI49$*9pMtHs}GC)%Y7q*QPVt6tlhqp0Gd0vXPS;Z(`HGt8u`W^BWKHO?C}O9$r^i3LpK8Q9%84=2bbfOLMjp2lEFX&DDdS{N@ue9tP zH3H}3*h{Q_{=vOxpRwb8>2E;2pbU2k?UrxRGd$mG)v)h)WW1Kn_hZ*D^c=xDEeZRx zrNqC4-y2|e2VjqV@+h2NkGpo0Z5j8u%>P8>|JYZXQLdv}U$r}r%|~B4hqpvW+dMh% zPoi9dbN^M>d$NBwUOSQy=gB#HwRYrL+vwRlZ3(mYUAEoh!x)1_X4_4mzr~hVa};=j zty7dg{V)Je1tbWQI6Qx)#M?~zZ%h-#XeRP7j9?M zk>>InJ(uy0!)3jn7gO%#AJG5NSNA}E=wiPu*nI}|hdMk{86JzuZ^K)rQ}LeYZFm=R zsumiH7zg`@u`T1BY$5N(w(Lin75oW<-3GL8)-T&C^4&V?Z#Rg3!}h&)x=qO4u#I=K zjf4JFvG-mOob~)8d&ws#!e0370Og~7+Mi{W*Wuf#y3A12zKK4}J@{y}x1^axv*v8t zeB#^HHHTlcCDm-lK6wuImuoP8y*N&Lz8yGaqpFdQXEtr#{Sf>efZIFpYsa3k7HNLp zP$t;FB>BF8emdPb3vzi$#`4kIIcX&z?pdJ4F~r!{wHSRJe4v^hOFwt+T+o{Uc@vB! z_c$RNMme)tD6>4snX!F~F)eN(#u543JU2q-#4tve+sU&r%8_t>i^HB1e2tBm7clQ| zZc0dA7~~iT*_~F*@5d56+7Xte7vm`8bIRsy^6XB68~gAM)ra{W@KF137y82l^x+o! zgvIZTmvTKE<9zXWqZVb|F;eo6PEF$2Z9DfAcASrchkrq%fA}q66MfXXGhU@R-^CNpzkk2d#K6x9C0D8lIH5e`@r{NeXuXU zKi-Q^s38xl4dp>U(b7UOBf&ezv!L=ELlbgFp%*@dBYON_(C{4!jL#{2hr$Ke0XPkC z7a&x=rfdMTLw?3DVXhAl>->@x66R(DLZx+zQ^AuMtckyd&CYdzWq@!>>A<8ySfb#0 zOiGOBBp~DI1Y|rfNSON^Ame#f!rWv)((T2fhOkRPA3TvR_-z7GUT8Y-=K!G+Hl;)1 z?FwSv5cc;2GX4g@NnqcQe*^gSyOeto;B>fq6rK!7|4D%KPreWRU$TikNDB9euqt^) z!rW&8>90e=ualpHxg`bsMr{V*3czWAWq{aIrj!7(9H>{AbW$bEoe7A)5|@Oz@1t!@ zgFo_Z2+IK>Pb=P^z<4d>lqh#p1bgh6#&`fx#p3-5?32X%6Q~j)w}h%1-)}U z@SA)x77mS+*Xh(KZ$|SdKI+SU6Eta3@e%Jv=4saBBhGe7a~D41&nmo6(C-Y%C;cbl zq5Iv6-ajgwl|>U!=_!$@_GLYN3jc-h4?Xt^$C(J|h0nsU%@y?TSLyqrqTi|L-=y#k z<$gx_KdA8EGCoIVsC-7iKmI}ndpZ;Tb^Jic(pFt2<3x5vG1rUUW4Jz!>~R(==;zj-po9;5?8H zS);cB6vi67#n28b)F-TI@Hgu>qO9Ch1BvK*M~xn$DH#o^5Q>m%k|86kLjfXWoeWV$ z2qh_ER&gX_5VKIxXQLQ01|wIUHoA!K?YcyAu77dX0F+-zo-UsCly-h`}Ms zy>HW{wOEo4G36Z6qTee^&(^P@l_##OuBGZPu`08$i6i73usqQ=Z~$}RgCU=|NBoNZ zub2!?n8(zhr{f&X`C&K|W~hAPA_F~!?ZIS^_0O>R#5x^)Ebay!qtVl)+YQFoJ&8pH z`MC^7cpf;`8(J#(yF80yvUR>LP_Fre9o8U%#|tnlgLFs8OK5@Zkej$4-#76+FmLKS z$>SZ4U*q00{nFwS3GLWN+7gcKOKdrpfPI4CdxH0b#O|qnGVJEVp1`;-{bbcoz}Ldv zov+xj$8%uMg0pvr+?yudoge(ro^-Ap^mqo|gZm$ou^;}?rv(pl?~OY~=T2jP+53Rj zyB_D@b=;qS;iViO_$HI!Z|(Fi2494q<=BJ$81fctv5&gEaRK5fKz#X#HxK8oKNV-L z8*qMZq+5BpzwA|<#m~OH>BM`}ac=&HO+p4^6l4v|=jNAo=iuD@JJ@3;_isAUF-<$< z`r{^XZtg;Q)=&5J>FGH0-~DC&Oi$lod(yFqIG307H=lTKs(vn?6!l!5^p8v?{mmyj zZUp_%x%@<&%U>(b<-dY+`Daj8d6TuWQ=&=XTz)j%M@#p+zNz&-Gacvg6}AhN*w;V% z!KU56vunq|Z!?_97pOD&O}ihuu<69_?D9n*WYRDJ9 z)i}3*XQX!F*aQ3avJ0(&yu*R35?X(d;R)`vjcMf`^Z?`u>aZ7o9sJkVGPEFh=B&F; z&|8D{^giS(ZpYoA65Q!I&wV@E4&^M^#@3Tv_t=WVFZz2F%Xp+1wxYKJ_b`kaLNoFeM;F4X5Sl-V@IpRCuX zGt%8hyKiDd-Jar}?r@KQh$mvDc-X#XEYP?kBGR{6a&W zR-V?{p8T}nM7bUJoKOc&@ePpR9jnh` zmjT(6$Ua~#6YPaspS2s?xw%XZs51G1D3c+yb5$lE8p`AuRVFW5%4E;m{X*_4S{~58 zIrQ)0H;@bx$5JO`t&-6;uSMHTFY^S~Lk@`J-*mK(J~jSfua(q{am?sG18sC2%JCEX z#AA2$7d)IGWPvuFSe>AcX%jK#M2=~HgEsnIv{4_%v}C7ts9cR{38N=tOu0_9(Z9u* za?U={+(x6gi~5)*#~#W8m7qS}H`T{L4^O(e^^MbQxzPcA@Dd)f+DH{d(!PN-~t;MrEv%KIZGCiY_?i$Ql@gOA$CwucJ#n7uvfw?C<7>5nmMvlNxtsYkD$f1z%^K(FJMCaQaPD_uY% zu$G_mpccKU~c-kNC3#}#g;M}R}nxxhpBemnRf9Kf^9)h^1 z>b*g`Faz-|!koAGKQ`_D)itA9U$fiVC@1T>!MWsjj#2vqwl5qA*yiKY@YxRRwAtGZ zOw%rqM+=$7a{-iLaP!s^xaid#PY_>ME@m;Uu{w(9~MEt*p9A7))Z%6#?h`$~2A3*%CtN1Cu*NOPC z_T5#3aEmu>?eMa{ARUQgC%3+1pLDJq@wD6DnfENl-Z^>NahGl1ybnS5Eb_Jw@{-fw zw;bhNGhGX=#@vB?9*i~Sori%2+_~ zs#2ZT@`Rwkt# zkoG5$INEd1Mi@YDK{^FDGRJq12RAdR7cc8RJK;Ghr-0cEI!1oxTH>Ik@0aQ=cr)C{ z-)jexmF5<>6Q^JW%~|E{R5+Z3JNb|_+4w|wfng9={yVtQgsH(t_Yx$UCQrHFB2o3e zph5s{gkQ=L7NPuU9>GU^p2ExF&NS%eIDQ!M7cB1NryAXVZoyx+;3kFwbT^5uwct7E zO8HZv?yJ!+tYY2vixw>Xi&b^h97ugl*sWVwe9>Yu2_ydXNES*Kldj1qbm>lAN#f#tKP$i?dV?+&cvBG5;+MQC& zJ#0O@x{oVQEt*4Zxj;Ib7~@?^fpCY`-!b*DF#1m zZdOjFOBnFOphTg* z^LPUL39ikNxINvFQIxuG!u%%C6KhkXU+M}{dTVr?Iy_Ee9UQ5@CX&Wb^TV`k#hx&f z&oSZOw6l#c>xDYCdf!r8!}ELhq4neUhrzgk2&;2zPYZSSRTg9H7%2TDy*-PqS5W1A@w&gZF;(T;yr!kpzTAx zx}kRlG!CMy_b@)+C;f-Ij%sZ?W_z$FlyW*PH)$sM4r5;Wx7&|js*eM2a|C#tBT-NB z;CVui)y4$uv+Qjb9gh9I*bjY-I>EWFXv>fx*!5M1)^;!Sg>7+Z&0j-3uA9U>$-Oe` z<`d|rvN=3`$@mf=W7zW)%J*gZ;hmU?``<-haA6PC19{gjvCo!$gE;f`d6Wm`(5Bk3 zCkG$kqw7G!?#Y2nKzf(`x>n~n&*6l>-?lXPf1YWiOys1(mhsEMui)NJm(`o9O{#eU zJg=_R|D8QGLAxgac_Hez!r)kjv*3((>=VwpoZO4cxKR&Fxi8B_++jP}|8@xZIa}}( z$nc)7L|$evFX6Ugl-s?$u^44ogtGi1%5)*hwh;GqAdj?N>aw!ZK5L-e?T8{Dj56s# zIYNdJeG~iYkNOY&7(7TTombJWe;vg>0sZ!P6#G}f7dQs{WaRsiIxX0;P|In_2Y-$2 z3URjg^&g`AQdsuJClotqb@hH%MV+gu$#=HZ39UdrXt$mf;e#aBRIIA5 zbk&LXV`pjp#6S3}ZNQ1x*SrSk zgngHUxvwbugMgSKOP-T3m-ngYpZBP^pQ;7KR;$D(VeSg$K2O0^K>8aCi215yw1l}% z<&Jqr(0c_i3H~_Ok^VeDjCUzB0Wl|*V9X=TwuCT33GW53rQ1;( z^ho%3?sCG_`9A(XmvAs4-rkk)8vb`Dyo=_dX)BRQFtQufk_5{3i;ZtMJ_lpQiBB3jd12_4LdFE$)BQnRuAX_$~Is zfHZp){yzNC{6zVen5KPA;cqAl$`7fa!iK+%_$&)f`7NV6_tQrFT8sMw7WW@naPy+y z4ILFyCLuFjD7Dbl1zVo04qrl({;o{LfFLe}Z43%s^i5@EWn<;sw93rF4bZ@_qHwkT z!lwQxrta^rZSxu9?%Hr=D{{D9l*|dCn+=jxJ59j zPe^Jg8A#Y7bD@}sOuF(7s!1&E#6Wt$5TPrViu`A-8#+YaZOrXw8H-YR5z?0&Qi&W@ z35L=ztm`i}?}HU7XdRY%FrwZcjI|$5&ko%mgw|p4WQB1@9Bn_$IYx8ggP~kVwsD{k zw&8!@!8k|5`HDuz_5HANMl%?i-r+7a{*fMkwqQKPx-{B;ctAbDIvstybjROX>BEjMIU=zSOh&5%w_7ot|DN;?S_JMy~b2s3tyWJdv0}RW5SK~LB5T#%*s(#I&VXT1*!l48SW!64y5b?MBgvjDPe9v;rA(= z^4z>n;8AciAjXEL39&yZaVne;xY$=<3{Sa;fs6hK@mF$Q;e`0h<#`F|wkUf-(z{>b zgrpY$B)tY@Pl&&gT7?thFV};A%n!y35icSB#61C~BUR$LEyR9K*kG2N3=V>D~p1^SCjcfTIBq1L8<<%yWPk zipO*SIsw}OF+`7f3=sRvF}naU4v%R81nn^aKn&YsHUOgN$CLwN4{n!O4K=T;iSs_HDT5pkb$!dEc)r3nC>(o8;m&qWvj>p(C-ixj`cN5ur*fa5aPGTlxL@af zO`rGwg}5PnG5mAC^{(_TbdeGtjgRIe!V+hF(!7V?#C3D8a=%|$q$xb0@Hdoy)Ri#R zi2G_odVYl826Aj$CY)|Y_wQQ#KWV|auGaOOMBX>BD3P06Xq3Z`asy#N|IzLm3>+ZJ z?SlaW40Io1;D7_%P#7@apL%CuK%&uaF$^4Jc=sA&Utkz8mWV42AvzH*1Jki;SPj#O zb^~Hy9j1fdCkRn@LuJpZ>LzSo3Tmq=>ee0;DGZ*X>e)^s#pX=ot;uYBXs;I44X0k>{qnU`2O^BkWK(^~T}MMV#5$_d`ZHvi~U=nY<;A8fbno!4%A9N+im3Awa!kc-3Je9EP{kjG~>Z+v(Z z?mI(&MxS?@mQ%dR7F@KIdiqA4tAN~D%M`8ek=wK*`=)Ds`xa?OUL2|2GYV%^lxBE8!S-_0 z1(1yU?@5rcOW5k|-GRMw#@UT0CT`V^qj@DA+NNFT#@TM?>b1S?{r#r&_NjPTZ`M6J z?2`VHaWf4@9s%Qbx_I`8^v6s6Fx2@IP3NPKw}uV`o-5A5xndIPkvb`{E>9AAC~pfK z*@JqdtmJCcA@8D0v?aB6>UE*y+(Wpoj|Fw6ecGQMvR8H1i8^}^Wykn%k5|OUw!=7a z){#_>GxKE7w~gq`Z6Dd0+a0eR5Oof^rwXXA1!tsa7t|~A;SV3#OFe^>A!ZuiIhuTK zHrg1uZK@mNK*(OTscy8Xvw!VvYM}mC~AYFdu3 zrR7@L7ecrp9qql5^{XKtFQR_gXZ_PXeW5feIw4%q380;HB0nK}LtgYU*2f;boULO| z=OF#+qaQvh#vYE5VtkA-_N+tS`bdpE><8=6w_=VvgR~L0jdrvRJrASsTOWtOZ%KN~ zZWxzUo;luH$MHoNzt*Yt^J|3ptlG~>(9$61VVt8`cW2Rlx>dWv7?h5C8)7Wf?bu#K zyJY|Fi_dx!bq)ELn0`8Y`!jU84~|i$Hlb*T>V6n);x9eM#%c$gyR{K{L9SuMZ<{Pr z+vhxeE^X>t{SM0Nnb)Zou|C9n-{(|w`C^Q%oU`=y&3Rj^UMqB;CCq{>&J4(!puV> zNGSotJ}f00ka8U5fY<^Fz9spgrNFUg5&Buk7xe%K?@H)raRR0S$NE|5XCYtI1)O}* z$$;dGA`OBs8gJiYdkp-_yY7b06-N&^l-+TZ{aJ`bEBSi5`B!9ye7t0}FC)K@d^~-h zmP8!>$#0`spm6dlX`X>S-CtAqe%KLzTjBqqaLW78TvFka)uGyY*wO#p$PCQ_e8dCD zERD{m)b+lsgB#uVpm1o=o&}CIi!dJM4{_-ExsA9XKRe)N-Vet_&ZU?6UZ@uaoJqG6_T0;zhmlzRbaBiYC$T0Yc5kZH}QM3mA zjChJxvP0r3Mg;mZ@fEG{48}i<@E?s&_|*uRoa`l4>n&|ff04zYmZMZW$)Yz#`N~mj z#-24P19I@Jo`=N4W2cR&zhiE6{T-RvIpFZolqU+w&LO^2!r_Xtewqs(4EcFI;#c&4 zV-#QOF*O+IIC)O|Ff0f&RDRyum>g(Gk73E@s-#7n79h~gVEi|o4*6;{e$X)*JzcsT z{c&!Q*??!uy@gH;&@Q+$9Q}0zzZtL;lPP48P5d{OAwTR*IoEQY9=3_bfBO*f3?E@1 z$+e6&Kg?I_9GQPWi?bi-O2gVHRqH!C#&f_vT08L5Yw`|^7;8H)somCQhrSO-;9K)X z1X`f`H%AAxc1PR3Pp`uJrMe!(5x5sC-$iIyKC*4!>5(}?UIKSG ze}y=HMY)BsGJgFY1j>aa@yozz@WQ6Y=Qy>%?w08{1owS( z2|&I>_=Ajvu;-f^uortV_$$X+obGhvXO+VU+~|??K?nQoL(~@$fQ*IoE6b}KG{E0E zbOCO#$32Pgo3gW!<^+6mux=&a5DlmdbE~+&n+RF%vvX`g9Y1Tj2jbkn6?_NALw*)$ z%KOc6o&(dJow?I?Xa`)jK(6clyaUsdI&){IdirL&wZ3Ty_5-e~0=bOSrTk9c+A?q2 z)^E*oZGB*#$$ypBH+^d>+#ZD64qSl*4a7M+s6i*El!MXZ?RW5f>^SgwM}Xf;9g}z? z8#+0485_3ANeJKFhxb^z-luR^8z1TR{L9b8-S@Nm{}%dXAKlw+AJG=p zF^fHVfB5~Ev(Mn|nCBncEA`K6!Bdsso6V4P`q55%`tfED-uR`AJZX2ImhC}r*WF0l z6L{}K#QPicFYugtexvn$^rS=Fk)S`JH<@9PcHs|gW~$~qhjFV+@E_n7tsL0S$zO}5 z2ZwsWJ0r?7%!8sH8{REKoJn0bz9RHQupE+YTEx9({SH#sX7CijzkL(w{}sx1J<4D2 z3s{P(x65%aVkvaNI&seec_7c<1Grq%GP>inpdD@GltbQ`IHT@c^!)b!iun7t#pm?@ zHa0{rx2eL{?6PDgdJs+TKpfkJwBP|rK?x$S!!*=*3&#epf)45vi_Y%-HdJre~ zX)Kc-?5(>RNh7S+xD$2f>Fq!GQk|?z>)md>45IHD?HE_(9WRzU?|7kHL+2H|qjhvh zWikP8JL zT!k#1FAjQQ^>V@YTfPI(fo8h*km(9g`EvG`XcQwD%qu=41uErwg zyukQ`ul?_(#ia+uU7ennZHF0m2iz~tz@WXVB(n8}c(*a)E zAs@!mAo4>U%FYQ|TSpzoo+xR%<6kiDNSzUs=VDx38{(NCWlE_SSNGq?orlX8cXCW5#Xxa)KSI{kH3ID2Q!XQUL8u z)5p5_5y4aFi%+56cwWOkLb`f*Obp^qo9@3;(b3(z6SYIDL9-h)^m(`i^t+&=ya%*; z=G$_*Zu$1omT&){vFC5JBP~DJxwPo@zi;gMN5|p*ek~`ECi{ubKSJ5>|L6?*C_bj6 ze~UfXe;vlr?OIzq(s&Ax_C53S#GCE&p?mu5GX-Ki6=UTLjHB-u#?d*3aTN6|(pjL+ zAV}vO=;@l&o7FQP^X}x{tRJD==!bE9-0z6pcfRG2;|bFF)OJ~R48y*Y>`*z+RvfMI^u%e5VA1=2&?5Ky;gd4q>x?vE&xLXcfKRX@TuG5bEdw-F&R1{TTh(;-_1+>vjbL=;P&a+MyW; z_r&)54s?IZexM)iq5o#B??dECv?D;~D}Zq%vOPW`=WcOF(=fK6EI1dC{#lGIJ1k?% z4vsBo+d=ft7JGIU{drWH+<}}Zro)Q=>^RI+Qa);_jQk#cB1|F^oRU>f&5#HF|$zK38zNp z2tFpqoPWdIPM#)zuaUpa@~V*cef$6B6rm6J&~91?zwxu2F2M31$~IsABTb~kxA~_z z9d!Tnm7E^BKcL(nRPIk3DlEyRyXoN;?D^&dKe ze3gG+`9Zus`gv6OLHsWGIZZ$JDm%ul>?(2fknA3DrLRI<9dNDp;qHh_yroGOv1Qd( z3JnIgB3;^R*cW~de8j^Fb||<4#^}LY(N6QSJZn|=xsbCTy{atcO`dxse|12Qst^g$662R$z6eh(SlkzSSL%P%}L%MGQ zVsBRRhJ?AV0OBv@S^S#<_&6Z_?*XL$T0kT{B~{_w*xL$sK+j({U!$M z4X7vbk#%!3GDW_z&L1hKJMgO%AE#R3x_iCCM=1Ayij#chyHSrczeYKd&-{XlBOdmG z?~HIX4a$8N;-L8t_@n;ti|A)Gzs5)ZShEUKB;3ItMWc>h+! zCsB>{N1XLT^D{u=aSCsN9r3pny-I~AsrYJ@{~qO@hjgi+B&T`s8S$Awj5yn+5$A6s z&U>In{1c1&K1+O0AwNd{<1FqO7WYpq^dClGWB9!m_n%tA-)X_KE$QRAjFH~07XRe? zhjjKt(>mmisoy9hZXCKoX?iHn^t@vDo?TiQ@2xB4NoH1g3{URVC2Q9d*7+N&tD3B8 zl1$XH@|N>*W8HwBG8WdZ4ZY|XN_iB8J|=Zb;UY5SF_s@w9%H>BY4pVStHk?}Qq{Ym zD8yAsUD;IZrzQ<4G!l-`eeO0D+1#a74TE?Qto`uCT3xBRUUaeU*T#HV((86(LDA^- zH&#^pn~Ez73(Y#BU{RP^(bQDEst&yVO7ruTv4w@NNYgp=8t`&3qBHe};a;|Nn;ORu z9+ouL)ZpHuG}0kyk22M`du{=jb5(aV_^WYqQmRqU(lJx^&DqhTisjds7hOGj$gjA2 zoc5K*YCn6wxOZ%c$`o9wZ2uF3yVcA0)C?~#E}QB_S{d*AT91H?X>reGs;ib(te3Z_ zjq0k~nF3`c!C1fneW$0X$O_(w3Rw*A|ubG}MM{$dCzfyVkPAsl{pv635J**{< z)3jNDhjEy89%~pTzZ4%0fAhmSn`?XSCx&hMw>!XxPXs?;6!-$8!6&>5I+GlD2cCRJ z^2N!Y1P^oj^}Sm(t{cA*P0q|!}mE2bW*e;8@dL*)pbe#)lwBu(6(r}%+?izNOL zdYC>0f0;7zI$!YP{t>~vPVIOHcsS&ro~g98y^HWY;I9aNBJL8C-_ZqkCv-S>|5to{ z_jcQXo=WggUIwof{*mcDopA5D8hk@Lcr#aPAzmxPL6_*EkMUNZ(}lE-*P8pmi*1?h z0Ut?APe%G62bI$UT6XA5$9lZ&)C}lGswAIZ>QoZ6$#*Ah@ZHN5KZUe?;PGe<$@Bae z`QkYX)1yt0cH%Aoc|7W@vLy}qz?+*mOT*cvc3`VL?|@CS9hi{Kba&=zGXuGkN}-Q1Lp`T6IO$*zd1x>usIsQGgL7ek|f3{=qd@bRe z4d4!aWi}2Qqy+?QWbiA+2b8@{B~d<9rf$kjW(H_wT)>Yf?kzs`_->51*yank9AJYZ+2uH;*U`a6W84;7#f zP11xMu(2(i-LBqb-R3v>iO$m!-ZjK_7i77X6-8^1b68q@fz+o?M9bj`L!M z^8vS^UiEWK;#wZhKFn#f@)LR1k;Jp}{4g&xu+Z>(spK0n4t_ji_o)2qZO_U#gukSI z2ggn)`c(q@S0cvFQ8*j6 zx?#+cj_ucFYsu5bv_E{^3kjEfCxR!g%TBo5a3Xl-x@_m=4JSJOcwKf6&k+zuhvWKe z8|YirnuaiJGpA8LXO!H_N|cM) zZQ_21l3DS>4efpp<`l>`yoh&e7+#(iQx^#P1jq7DgFF2j-Pi~0?e_U^(GSM#K9Nqu z=>okEF@LPJYkeZTm}_Ks=ma>#Gz3g<-Kjwxts zQoiaFLA*kE`Z76!)@1btq+Me4#p&_h3BG zp{m!Da1-Su-FQbv%z@iwA7VXl4%EaM8s?5-{DvKt-=c35$ND_!BJw0?i84^M#26fY zTSLE3hVa7l_DchKDq(sQ>{bv*KUJ>krm!AL{BkX?GN`IFo(@Sl=o#RTCt)LiJwQq) z4h5!=Zw^R%>f`760ncG@6qMovr2XB1^v`n^`acZF^Ma=V;jaXDObBxySMEMQjBP39 zfIKhY`3vy{3Qq;R33xJ~3ve)19P+uiuCCqgKVw^0AlQ8#vIHC?q zc#Z>@`vTz2c(3)agkOISknyzx@|v z6oj75WWe(vG99o3kmXGM9z17x43OnZ{U40K0dNK&?@@^I1;k$o?*rg3_mWN4@0)-u zC*Bue{<{Ei+#>X6lFka?JYTvSkT}nM7*CPHvjG{83ve3X+vpXjYa~vKepR(;4_5LWkeb?wcqiy#4NADVK$N!em2y=DU z)ld<0^(Fk@Gxo8uP^&raY1F&+?<36TOh;j7ypQnDbVr^1gd263pAkpKbUwrx3;vqI z1Ij<+;5ilsFJV59u*4e_PFlpv6#iospU#(fQ{n%p=#2!#MuvMSYO271YMdtmH+z`y);GtF^o$zN$_VNuRQ{~Mtq^g zeX9k}0}Z2p+$}TVt%%>~KF5M@w1mfg#pM4VEcAjF|G&1lAGM_avc*4!T@!t#&6qxJ zz>N4w3;v!3f7ODM8yum>Mn7XHac3>4s;%-@6;wb!u~KJgWW<)5AINoQ=QsPS)>k)G z8Ey%fy<`X;Z^Y4ue7Q5?HiPnQefm}BPlGkSPScM_)>N&jT+_h($fFW(lfR;}##`yD z@vf|>u7!iaX4Tq?#ufB?g~uh)&oA6LxIa<0zP_YtT~%%9euVk9MCn4l7Q0TV{G_%} z{Vc#(z=e3ZV_Ak*q*Sk!;hv6!bfyeXjZ2B!Eh}I0-=Xd$)trtJciK|4j*6zLSUzO+ zrQd-=9?N-$IG2djiP~IRYK_G`1Z^^*Gq}H)*3}_AaT_{AkfmUL<2FjQo9bB7H;0M- zE^a9AGMa3*q}!|f6|%t9`GxtQ<Fk)iYw($iR6 z2jX=VwNTzHJx9?7tSfR}2aQY1vb@VO`By0P)Z%Q%qPDi6v^c}-)~)eFs5Yt<))Yv9 z8See4jJc^w-7W4%t*`gia!B)vBNM#L96kiPQa!c_YJTrglbMdkBhCCU%?dNr^Pk5# zal()umma-X&wQR15$8XZ1M0DDS9E*~3)2EROiKgKfz%R7*z5lWJO6R2eCl)dc?%J> zOw!2>s>ikq>A?D2&Vit!)C%H>SQ37X*{(U`uEp zE_npy%WXMGaC-S{@=YWUgFKD$ks~3St0irL``Uc1Zwu}>Z8;6UcvG)@Tg$xiZ9C>k z9&F^DDKj6*tS{F2IAoe37hQgv;XDQVbrC1h5CH!{q(is6Da>az@_bREN#%RY@+c<~P0b=e60Yv9Lm{1G~gReKh^$Qe=wz8gHcax+w4Rn{a*s+@s^5!!k6ErTQ2iEnaIqv+P7#K*M)B zFQ*4@8~K*!;U1Zm@j1lJ-%jx1L*td+#`Sqb@9RSxGukgHU2X%6YXRsxVwyyr4C5Lu zXo|ZH#x@ixFUdES<%Qp-@&Z1z^2)~<9_~1T=gvN2EvwMDguY{{JJl~fi?sML|MJW< zV*Varytnod&fiu$YhH$3@A~+2rS(3*T=CaZ@7n)>sm1!3=Kwq(Am6(O9Utp;anFMG z=Yi1P4@i84!q0=RPJaskX`c=#!h_#O{`lK~SkH?0dcmVjaRH}0`Q!9YJ|rRe-&j(o zkS~a+#r+1t6*EDC2uO65O^-v@f0*vth;ygy^3Bn#g=m|m<4M9&(Nol-2Jv-k1 zrtKv31-)T^6UhYM8s$sAv2G?1hl{>HN<%r5Z>{fd-hdnZzoG)z=nmYYXslH3oeDny ze{}Cs_}2i5>wMy0D4h2+XwKrJd#y+v>Oj%c`P{ozddDJOnr3|T|AN8`6+RjMXmq~0 zU*X?T@dXsl`wI-eOW}op#Ggi^qWLv(q(Lu_!y9Dz45s{j76Ad-a zw9I8S)eS-=eJJ9lh4qc=!4i+S!ZC3CX<1Q7<%8{Rpf%)1mGNiNnG{iK5yuRJ)zSi^ z)+FmW!<8N(4Ex4KsGk2Erwp<6H$@bqnW;Qj8M-r;Rf&ck<2=N~gB^_6kkvsATh85` zl^x=DRy0=CRfJibVyw3EIXNA0&evSRnRCDPnEV;_e=^2l8lG#@=s2ele)5wjq?t?4Bvn+rv)@j z^MPEkkGJ3vyq=kPLFigI*ACh7B*>E?&ZIrin~HVTv3+A&&OxVonRA1`*9RRfwJrGo_%@KiT6fmhY~O6KkUW( z)5TkN?0xSKn|?S-yR>_%E%98AyLB(tNC%VqH=XE$OuOrkn@%vD38N>sI!9mI`X1`w z%iq*`-?2|RHw|@#HE9y+{+H3*JCT-S4|#j%e0!?!{{(c#KZ^A1m~9KTT%+}^LtX0f zh%HZQZPnB9wwG;IFJ+vK`cJ6m=aW@G6=lM-@QW;e@Ox)^f{6*94@N;Qezh&}*i`&J z=Xh}MYMZSU??<1@M|!zuW*xnZ-#SmkT1Ogm-aGN$v@c4X$oj+k;i39VLj5Hji{@9C zjbwUfVthbZrCdVC#LpD2qY3?h=zl`)hVGQJ;lAcwbWE)CQv$NjrpyDRf8LiSd>2IN z?=?X5U2!j(c)7y$buCa~KE;2oQ#XJ<&9Cth?-dx%6%)IgvsHlbiCoTAQEqK&*u0Dfi(UVadK9-%J0k1TIbG8O-;=N z?TY1iH<}4lcRQ_W7$s$QW?n6B)Zt_iLIrY_Xug|i^|r90wstwzV1-e=W$4uMYH`!E zY6X1BV?t4!vFA&?VwsWZcDY<>Vt#ZZ3+b>+OP`wwOPKP+<+b(oYX+GwId_OXo=e8Z z`BI+?rH%PN_wO`4s?v2_pD&d&N^xlKTT&mePLDsSUm@CjiF3RG&jocl*^->r4mwN= z<)Na@kAs~HQtpn1@@O@$nzQ0Yr`G(vR}pS%vvwiDy<;!#zg$S3uy3!^Y1UVTR3#b5OkG|a_Pg*29%!sN zkuu)Y52??MMfZ6gPJnK(}cy`a3acs(>%LON1TfI8F#x{EPvDLHDG!sTSp@;85 zgyo!F3EkZPiS<#eInz2z z%tYjGl$JOu1#!ObxN84=+g0bvF%SRFF>3Y?61w*O>mlcNe}HgxtLw7=55m>h5=VU- z`F#CzznJpSr}0_)Y)R+3v-VA~rq>lE4=CF|$p|@!70Yj>f&hPY9meJQHBwrHJrfm* z#=?1-^CV#$AjX*#&ZC^aTL94|OYWC2HvkAeo|vD}2UBW+6LLI2KYp4JBudzqi4y|P z#iELMN-7}6L=%4x?MmnY$G9Z)fFntGzi{&Pc&X6Vg1|KYL`(IX_yznXA4?zKz5zSB zGd(oB@DXnin4GVPGaocZ@saPPk7v^reTJj?d(y}E3O<^HbT`EJ1LB78J@CWzf^N8; zFreBS7W^tW8r|=*;B+&(ziPpa>xCt;SQlA_>MpIXt*&fNUsAEA%CcT?r^yB(eMGD> zEPLEYnuD<^qJ%K=DMHJNkc3!zQ3W(`P`ATsW;0};mMT{kdJC2bminBpOg<9#^Q-Tz zDqJJgJ6wsXh@1v!55bBG%Nj{+=yhY3J~K*JE=v~@jj?$ikwq+-9>a({t)Q_AYd0lH zCS>@OOjk98ApLW_;OnI=uV|{Sgm@}1ju%%hfy8GNWgQvb9IWiP60C2e`i{bo7}!wW zv5T>O%gU7NIj-L-DdqbauirYk=z!7JZ#w>`uHVj&4b#I=p>^P%`$}3x$aM{TuV1I5 z$Z0395%)bLar_r+!Vt!H_6A-Lip3TDcd9TwpvU##NgUd6jJ6ui5^4;`FT`fiqrCx# zNpxo(33maX0oaKJ^LY^FI;|8R4dxB;aovV9vWT?9YEZ-Z+@;%L%!?1txG|0kC0#Blz{u6-FU}`_XoQl3e3~je1LsIA9i5tyeY05 z+a|P6Y@6u1x@~fMe47^7Hjgr3THyY9-@&|mtsj2Xo8va{hHSX&UVg9E=UZ-T^G%Nr z`nK8Id{2&o97tzw`L_Qx@6<@=fm0(B4mAHhO1KXYZu$s>n;7)vk3_gBBAkXao_gTw z1E(Gsd!TuxEi%5$zy{gUkGr*tA@SS$Xe1q}JJYit;eUYdhxmR3I{y-;BkCS+$Cn>P zm?y7m^KAos0N>H;+kD>#-0y%M>(1Of)Jyk&Zq4m}58vR{aiR2t=-d{E@|oJ^ z`vhS>#kbAX=DQJg)8qO+@jtTkt6%6twO<#SV;?>&V3JwAJKn{N#4 zt{KsHZ`z2y?!5^6J$z5%`#xxVFA9w(;s43mZNBAzEAbtj)8=~s@Ilbn4;pVF>~HY> z7T;;mm^d;r9aBc4TyAai{RZKFi*MWK+kBq_+DG=?JAGtd_chydyC>qCg73!dxy=tn zp|Kk@rl+;}mIB_1FMn>EZyn&hps^P;mLTj>e0SpeDrk(1k4#5mJjx@Z&G&PJdmW!W ztIhX&zz;y7n~^n+4kJ>pW}NS-!Hf4_CV&!w;3PwMLRbF{->?4i{r;z_P!3npP{{c0d@2v ze7B-(zK`!lr0r3BV~{q%gAL!q?Dgh@mk61f?ehI1j*rwe9i7h_mLcW+?k@0ElU(z} z{a22Y7?+a*PdbkC_eJn5U&Py%?bzr2-8TF2N49;X_eI4cedMU)cwn2iw;lUDF}`B2 z_W!c?9bi!%-QRb2QFZ~but>2`Y=EM4K_x6;q1gbt1`tpX1f|#&Yzc@BMI~qyTV%0B z4H`5iVoU6?$5^o>qS!0g_PqH}C%|&vze|bI+Z2=1e+a#eq zYFr+>qCfXWzwU+powJMn|4QD7XPR?c!Cp7nEqNO+Mwv>G@9OsXU*Y_B8FT~X&<(tX z?w7_kbIfIhIX;!EbV}18S@YDuCOwtQlf1d}&6H+8?9<9^&e>vk3x6g<8Kv<#vC^!V zadX7jW^hs4+Ngmj(-ZsOigBKqwcC$yQ3&@ukx`cDF$F&Gm*&CjT6~Lfi<&9Uj1I?s zx(y;_mwGri4I3d%8=?-k1r!-)OlixMPbyXHikgi5f7(o6Yf)nzgPztI6HxB3@42G{ z@tVotpW4JDwyrdcdPH{>n8qk&OmI5VdIkNw^+dBE+~XFr7Io<5w5ewW9R{rv(ES3G zw@{?9Tgsk=K6AG&)7K7lSz6z->>2818P;9$XkVN+?jRI3j`2i1Qk?ZR6B(A?fUd#B zK!i46gt$y9^KAaU!dZ%Q+;>5v6=;kGjk2|#O4uzbm*RZ14EZ$!52UzfAWb4Y7KOY@ zJ-GTV1%Fnf-AEC(9Cw+Ch@U72uAbuzI_RAQ9!-IJh@@$03H%NrdZ8OY-b+JaTSaF= zRM{M?89`@K9^k3iHCH5?Gxy2Vvztf7mh}WZ`J>vE-IM6%>sD0kc#1Z&sy=wF5~mOJ z5Zw`{0#jE?FByH!_)=zsss~D}0TI9R8gcw)`;^9t^1Y#n5=ZlnB z*eXv)zwAWyw+_<~W@~sr8=kJD|r9Q?`BwJqKRn^Bt z@qK<2;x|VcurbPIA5kwe3|Bv+>Et7lqKX5rrZE@MuAQP(1|q`c@**< z4PKPAVU%H(3dqMoJF23c@}Nq;aOZ+KgMFkl9)4h+K(-e?)Q6g&EFD$K(h6m1U0Ifm zbvpI5$_PgLh7pB=ANwnm)E3gv7G8s=bZ_BdlrvYZT))GWE7$L2tF;BLo>E&N9jcE6 zcR_G{VqYt?g>;^8X*}OnVSG(PTd+o(w-QN@S)n~poj}=+rLq;FUZi2XEgQfnr>l*# z*q_gqImbWEdm2?`2~9mK@kv!)i2ANaIo;Wt{2j?9LcFxrslM*}u`#V!n<+PezL?|> zAs#oZ?Rt1KPq3I6T!MB=b**y?nc8?Z1$`ISUo|aNpdW|L5{>@KbWRZZt7PQ=d=358 zGrqqnsqC*zKdZk|8Mi*zUq$m}L}LW%d8JHb@sU332>Pmz^-ndH5$;$Q_?T=%V>wqg zNn)+a@8i}~eLoM~c+!6DDmPQl$}p_k4BaZXMH+5i^{d=;ywt;q4XWH`Xt?cfT;=v! z!)=CXm0NENP7x8!j zkFVqLY#vYJ@hLnW%j2Ou-iOD#^0+IHx8v~=sL;%iZYrP!pcIhkxQ)dYqH6^Y(*Wsv z0FQSCq;O=%ox)84B==B2+HWogr0{xx2u#;l9&7q!i8vkldXB zDIDEzK>q0d0;uq84?;Oc-y;C&yBv`0mSC-u-QPV13Q|kpT>;GjT>&ZGrhpXxL3HZ0 z@4OI@;)w;Mcol%q7qa{537P{(5v?N#nJAzsj}rv$PW$XBJgpZ~_y|A>H;{*20VzB| z3a{XCf)t+Y(9nK#R~|w?$l_ah7|TQ2r$+v6L!n79n}>aPDCJ?1h;yI7L)sfa{>#up z2^R4%jfZ^zi9Uizg56I~cmRjHcL7Aytlbwtb{{>~(rgRy9YwFd6%a+Mp9hGd)XxP( zk?CgxqNwy20-{LtDLt@WKNS$H)1Lqc7U+)wq;^^+L75sNs9@_EH ziihSrGzNsKoL#4b>KN;EIBFnv4G^>DXo_?W>S&8s=;i7aBa^g#COnr2N5%ww_TL)# z0l3k6S}3oFcR^SRPxgoCnabmoDSE!<<1glMDUXiAo$~*cVeo4dsSq=Q1 z27X)vx7MJK?D@b;0@ng`HCxiu8$s+1m%lCxykrf_lP8 z&1gSH3f4A#HTSi1q*N}+s^<1%tFD@)RrAlst+`F?BV@8$%vBd<`DkcGmn}jvZ8LmQ zWI{ZZWGx%USbHHt8L->GLc%A6g^Wo~hzuDQosg6qMrLrT7Jk(hghwPqMj|P8iBZkh zM<}Ol`^lX7b&h5iAKV5J8~MTQ;hJ3R$Xk+Ot+-c@ruG$D&4}1kRlIX?eHJY)0rBxM z$zy7_-|;bqbW4CuoPQkL#WyZ7GJ&@UQfdBUG}-@fB3nQ;t@@IQ562K1Tgbi#zk%JH z9{Y}VE^clPZjQCA|2lTGuiU>E9v^}AXY~bO&He7w?OIU>V~!sl>L0V&x0?T94$3~z zo3W38(`Wh#ebuM#-xI=9eCP@p=n!fAueSdCvGvtFgfmAlii5`9!@#L8zld=z8{-2F zZ+-BihiIf94OtK?NzVA}r(!1Eb<5q!xcY!u;c5fs^bF`>5fN*%0q)${T@`;A(<<$$ z<9svL%Gh6~n78N6&fnq3T2y7fdph=NkqrnTK8oMtt!Qi%zKi6HE9q^lrsxNi;GDD- zW8#1`+^nW(2T8RUHwZc`4c1c(gREg|+8XX)i<>pvtwnf;AIPU}7>rqeHgE^K+-%_P z2X`HE2P8jM(3Phl4VfPNH{j!?IDli$;D$x)mdw>Zn7Ous?tcQVxGgrt}a!q$D@&`9- z(5s~QDeZ<#X8tWRSBOAzA9BY#`yF>~DxaCTD&a>gk{w$Os9Am7m>d1>+bwp(yr4$A~zh+D$AB)4LxVP2DhhcUJ{%2q`5q<--4YhvQ4BSRSQjKUm7pHN#mURVd=!ZdQ!sfRG& z6@|%zP3+pjtUEiBo7pi}&_;fcT-OU!qbMi$x`E!vj z_?(#{l9iTXe=Vge#4qG24}NjBCEp5ZTZwd!>7tyh5TD>rphFjRUbT!%sm%EDl~MU( z&v%JL$A<2fSd04J4)MsW6iRE*>w~r^(7(c=;p0EWrzhM`NcsH zzw_{?>aIS+aq1Qa;Wx5>7&c%gxj1#}6V6VUD|g7+JHbYu;Myk%CI$V&$$Y1VFMAbV z+)O42n}abo((vcNMHRrF2CH>b+;+Tpknj=LtgY7Se|{MDHH40E=dVCS!C zY8?ajUHD(b_b;wI+{i;={wnAhKXv}9rxG8%mLLM?@vF^WKepev0Uu8)g~j88c&KYE zME@!1N?8Z~-^b3ME#%{aj-7oD3mM~a-kHZ}KlJd##7d0tuAaf3RUfwU0WgMDK77~B z;+ib~*nHg>e zgg=U~mEkdmR}GJHkcYgJjP=9*7_Wx@lf2ojNP_ut8_kcTMHFGD`CXUs_oy4yxYxuzgq5$Gj-0p%+U^r9}vZ9psZ0R`mG8u7P{ z=KStM+T=Hc_e*r#MOvefwoSAZ(NHaI@bZ8AQ+eL3nt^qWG$|Se>bmV*G%SJ#@fl4c zpooL+*?_bjNpcyEOxT73!fOD@nSkyC0cl;a4uh@r^-(_L5kms|K5_vjd^#1UxU1i^)3mzwa({ql(_u#egi)J<%Fw*UqZMFy%!ONz(oq_9EgT@_E#aEHxGHFtjv+*<=DAw;lGRV9YI z)_T7{Eh|Y54%I{WjvfD6 zKeL=Vaz&!Pno`5DJ(beYTmkwtMsh1epGlpAJ?rM&bjt=2fGCOrBHOcLV(MK@m6N^MO*>)`jHbm3g%Q+@4&m#-T$E~OH48!N0e z>AaY>$chnXkPQQ*iS;ffQv#VU0D99R=u{s-e%oTGaE*tK_@PMOul=C7!ebWxetY4c zi8XUmj<;O99hV|4{H!q zXCU`}a;kAq+`zcP`Ha5bIzG%Srmo+5760p1{BMT;(E~>p&SUENMO3EY$)*vh5++h5 zObo)r42&tvV08UvsiZMm#s6#-|8wC#c3^DbTt?52^8Lt@IbGq-Jc%u@2(EyxTo>yN zy%|x)Bk)5r|0wr`7RW!!eW4fNW9X7$qanXkqL&}gO;LCN>9-ghUKoqG4KOgu^lwJa3ku@r@X_?hF>hgv>Oy#n1L`K zdWT#qN1Mmm9+R1i^NM`?5i7SLd7AKSn-T?xZgn z)92tHiD$oW^|g70%dE9o2Xj|_owK&-{ip$t_Dl|r{Ud#^wArvd8RNe9nb3NV|C^q@ zuFe11{A#@mXRP0Uwa;ei1IK+PZSL&P2{3etZd%v*-uUMYFGS=w>Q{f@-`|D!|JBNA zm%iuw(e?H(SygU-XzuInTc&OEy=AxkXxjenZWm8?+x)6AhVjbCfddtK6x>>l|CK^yTsuOOhYQ?P)gIbMMLqKlqPU~hdhvaO-Y;Jxd5~=p zWp?&btG=fO^;+99zxmcS*2!MSd+uHO`^j?=o!w`Rcm3tj?4~o`UN#dgvo3x5Tc?t- zn+{71M>J)Y)_eFoa@f09f4kHlzWCR$um+nKFS+$Db!q6*gsECXznk`T$KW|hBYUL3 z(%Z55m|5u-pCpsPKef~u`}93D#yhZk zlWn^!Pe<-vy?a@&zd&Wt zu4rrWbN>p{FWl=rJTbcYgI;y-A8bAEz;EmSws-8m)6(wz)l-+Z8EIW~nDVmSzIK0g z@akctJ1y8(`p)C0xBBsU74x(P%kQ3?Z!~KClw04th%Yu>`R&FVXV2yhFSHn%S>h1V zXl7BtIA8gXFD(D|uAA^eG228tVwcXKk)6UeEh#&XNlGier* zU6YQEOx$whw((GRBcI-1WVQG?IX>>$xchZPGtBxmn!e(T;!$PKouVhN`t{qi-_Nhq zUDsxJ#~&x|D!7u-v&Y=*UI*`tTAyqC%Xclh2LzsK9MU&v>Sk*H@9XJ3tvCAljc1`{ z2Bn*{el=Vzb^3eX<2J^}-=1&N;ji>RE$>dY@oE@#u6MJX<1=scc9{R*=Y0<);FMC>QKeC#4d#==Ghl`EP3a1FXnMqjwlI4C|WTyzkEKXEuiiTwk5JckiGXp4{Wzx4X~>+O4b-SPW=>%H#7@>=gs>)&?gr1k#2qK9<% zS{|`}$Zt7$1DvA|f8To9p|$50$U;P8wSu0_h}c*>C3-`n8PCooO?iLus|72~myBK9 zZe(=GsqM=GuP7oMS_b8KSgl@v#s1xp)9&^2wjFBPf6tMJy~a3q-a6IohUp5tYYh|SWqv>;_(%a=tOpLy{rE@py zQQ4D$2DbJ4nO%SDeCN2>we*X!ZuZ;i`nY?)usYO7x7Cp~26vsuKe+8SyZNkrON-M_ zL|h+r&edY%#iM7m&Hrqt)2^-4uczK0J$6OUZDUKb-@dbY&||dGhFzge`uQ=px);=Y zRIq8EL0I5%v&E}7-AN5uU78T;^|bxU-tVuB?ojvl#g;nm84q8UB;R^%`qfOaY{Go~ zH($x8emlWrY<$MV^eM?nv*(X4oH%6hj$~!%`FXonUYzc;x^uQX#3k$RP5onE1P%$+ z_FJ~%OhL{<^B%9G9Cy8n*yq+|NXBpW11384{eINZp=-0xEDY({?%SZf*WYd2Wbt^z zm(2}+5f?Y#{@7re->nCU-5b8xyZfN-_MI+eXL_}&d)?~~tvkxQukWpIBAYWz`s(Yx zuOInu?$EIN>Z>F*_--`X;T+iOOGQh4VeE$I3 zC5QUAi}JVc5P$KT_KW(zzi8Cx#Gm(82)bE`-foXsAZ^n5Qtw`<`jKoAv$lPCADN z+hlAW@<*Mc15Yg-KFHR%&i8pkUAFW)(|2>AXZfb@e_!c2=P} z-7H^!+4XvoTaSx(GP}2mez`T*_RzLrYu9WaY^U?XhF?a1*>_iL$fl0ELpQElJFLIW z!Hs9*UgfthUZ}KAbj>^WE+p~bluik5Plt{DBJ9PO1CJJc)qUgYuYYRw>#RLH<7Ruh z%A$VskVgA$iyzg~^0%0+n{vN(E?KfiY9(364Z!yK<{AMVuKH2lcEsq;O4ow8uRPm{TaF8?sk zwcokPKR3KHNwF$*Vh=s53A<l-(>(P5ZiRYTe>Dla~0r z{<=vAJ#k3WdKIT9>z8?*tzYMO!OdsKcHGkMcBWW%VbYD~1DhF*ZQ8!^+(o{I8KN8V zaSOhh)Ajk!8M`K3O8ez*Lb~@z!<1iJw4T;^v**+u-$pHDB-LbG2x^t*O@=dN$tuI0K5YrF%4{vH#wCCaFe^3C49!O0i@PAgBklRVzwcEatS z{#r2Vih)l1M~zqZT_=kQ(T4Q*Z>=9nCyu@*fJ{6bJ;Pm1r-Y3m*d>CCt#|^Fx~rU2hYvd&pTQndwaLVlYZZidnt-cuXxwu zN}2LZkDD8_8vRxA<%9bY({I5 zT5Q>K=}+y~3$6v(jrrsIajj0h`TCcm<@-ucY}S<@?Az1xK%Ka6J8!Z&+@%rMPFs_>diAVLo1C8|Mq&cC)cQ?WK_uw zdApzgR$OiU)@ymeMqz=%eFZ_`PKB``22fgR@vNt8eu34qHM;M!y;9m>oLR{+jcoNcqvk zZvs~(ofzvqH=<+X47+!CXB_`&&+KfoYd;f!pIUE{x%6@KLnC9fezW*Ovbc1g zPW!p*O{b)TLnG5D&@k^2iSFW8l~U{mCn*7xkjCz$^}ZT^UyiIe%x2cGJ+1F+=^ZonapFO@uPj%Kf*XC+seRpB;5yG`rJ}(|0VXcy;^nZ>`Q9i)+$-OaCL|M9ufMiD*6A=ujKCI=N=0&h-a; z8!;-rcW~cd$NuW{e(lTUJI`-;KVN%U(?wmsnwYy(XN>uxhFJ4^oiyG_4V1m51drQ?<1E6*2MEZAE1Y_HkY z*$*eB4Y=lM5gpLdD>irk@^ZT5_%GW|zin8) zVRO>HG=c$f4!yMjCC@?GW}l&gh4u{eGD@(C({{s8uJe-Cn?~`6nReCvwmXU+#Zpo-&ziH+dR*( z_uCTNZ;zjywf4)Md&b6@JlFP^a{PS#t0$&6D|``TYxHxgDG9S*1^Bi*a;=@b$-|jL zNALYRV($X232#@1DcWy2DIHj`(QeM~3%@BC_G0yj(Sz?c=;CpDzn*;6ZTZ*@E-kM; zQY8QM$D(ej(>DF_SNCam{Pd+eJGfl>>V(ZV%kmoeZ_pm>{&M*6N52j_b~?DrGfBka zpOT$l&fHLEz>H@`4!bSdeEW33xU!?OyB`Su>D+fiqHoI#%yz`KJu!QJ$N5>M^@pzO z+Qa6BMM~Kr(+j^2NO>q9dFs32E<09kt-EOb(MGSnHMSghJ}%My!5;6rU1yvQpVH^X zai`W>m3q%p{Tuw4+1@I0_4H7K$F~RWE4u!qB5?N++u?@Ohd7Sel`c75c(q|cYJH0) zhbNAi_IRVB+n^<9%)@%zTwrbg!@Y*LW=iYjE*kBeux9^Mt!Ep$T{y7feo5c*bDhHa zuL!VnT(^?l9|>K(tud6;(9;IUIp|J{4bauwK8A9YzTfAd`(YqhUk{+QZ$NkG)oGnQ zU=Ih~N%xPn;(!7Ux^D$UQ~{ef=w5{WhQjaRpnD-8g)iWs`&K{-zlnqHd4Lpt9S7Z= z06|KC9S7Z^b7$$JwFe~Ot}WJUpe?p@(iZO#72#g00#PCUZxU_A|8=4~{68o;EP<<} z2>%Nth4{ZovK9aD*Lhq=Tbxxl8|1+l9U`N3b>XqZ3$5b|>oQXb2Vugx$_@dig(EzV z@nhX-Ap{ThiE}tM?b1W%Pg!?tvY=-J;VSX37Tl2rJwVxYc^1LHDE^y(2WjB!daST0 z?GnzeoVj$HkQ5mg(QOo&b|nuz`d96ntjSL|d%G~K3dTkzz%r@&vhPRNf;G}sUtP6# zi=p*)mY&4u_&D||ZEk7xgW((;VuE1&G(sb!<3A7T@Xv$V|MQ@BH66}lixTUj_73cc zJnmoRxx8A|M_ujQc<-S)k#XZH7f1iobWcB?fYh%2s$eT`$hfV$M!Q0N}r)X~t-4L=Y59pJMbVXX*|wY5b1)XW9@tSaZlXdOxLYmM_O zC2d4X+A9a!`D3l=oW-{3Ia2JI^TBO1*Ey7E-)%~L%SnFqS)jH47ZNMW084R8kb3suiD z-hyqun^?ESImmpx{C5VG0y4eGUcI&19W9k zd>B`E?1T-m%CNZ0nZkZ7TpGevhQXb)wS`geX_4PlytDkP13PS>i_*_4uVC+Fm7&Z^ zT5$G@=)NIJzZmwPa?3bdleOhpljki3p2HSq_4|g1&(eG!)W0;Gn@SNgZYf_fZfM%_ zDA0mB>6TKLD`VmzR|ayHmNeoO%lj((l!EO>SeIw(DwQAh^ew!AHTahmjIxqHR2~xC zX^i}d;P)2nPf`9-5oZZ(h^0}v;OuND&nrHy9ki}0oc*Kni^3i0g1tbRw6ReVH`q+69ci~CmLEImD|{ImJ*TjfsvMg6$D zx``e(e}j1c%>RG>KL`G2IRI-Qo@2&9S`Hf?OGf!4`Q+&gffwdQQvf{y$!?JXkmdn| z(|I%e1<-s7f9?(N&l}%YKp?=MZ7lwgzjizE{BP17e(_{pR|qfY@TE zKLL>TU5^2zeb!Nc5S8>p0kH>0e;^=4G5tP(kj?ac0HuHmK*&(~u7GU;?EoQX>01Fp zp42x7v;s5+glMPV01%>~z7!C$mOcXrF-*S5cj{%_s*DnDCKlO_NO#m+fngSL9 zQho|~xRr-_Jj~@`HV+r_FpY<)JeiwgrhD9^0y)HF38UlP$*ZO+JX^})=lJw=`SjTafv{PqJmmj2@BTuY!-aFE0X%+? zcV7WW{?GC8T41_W~YY$Ui}*%(9*{~U)h2dI7^4BeYb&m^k9 zz=dSA-|~fAq9~JCd(_oKSyM@uhH4 z#pi3_(>463Y2a%5CC7mHk?h%6m_!;mG7?+J{lh1z`LMU^7B_A{0v+Q`V2{+&kQzjH z{?PHxS`LWX*R%=VzS<^u?$oq!2&B?znV?8gP1>zj{P>>H;R*4H8h0=`g1j2ea#Rsr z&5_S)weQ$b9~&7EA0AW9#oi?l2Cw2rd$Jqt$y;?VxUhI^a%5ambXaW79vlWFL?;O{ zNwx5ljcWH%vU#g^6h);#svS5H@}?Q6DsP%DHRP?D7tOp?^PrwLO=mV6)lR>tW<%3a z$cEEoJ??B`8$@k&y{4+JS<^L6!4Kx{0j=rKPL*0$ zwe~yM1;s{2j=>e~TpNhQRYehr{QX@*a|y6_>l#m$ERr;>aU+A{sUotin@T|K$jJxV z?kC<%HN5s-!Y&YZu8wA9?|-3_2y#faw$Ds-B!n zP*PY@aw2Yj?GbiGT;$5lpW$Wy}M9L?mX>Zq$wTfBURMf+$WT1KvQ+rPAiLIJr#=p=O`VfO_Aw-o_ zjh^lUgmwg>>Lb^`MrKV!s1m8x+kSvVXOO5mcK&Mwet-aKXZFM!bydRuMAE7);(r$j z9skFM5w(uV!M<9$K@;P`)%$nBjLQf5h)*2C)Y4XCy9>;y1mnPGSDcRx$7PHYiG*4P zmQU;(YfsFM?RzFfCnhES3-wDa9jeA|fsv!*$3-G5|90%EEc@@J!sekXma>!n>v`ZV z^87DwitSDy7EwX`O9Px*Ijfe0{eLkXE+1TB{MYkA_M5z;qGKZxBIEvrs*4tEAL25O zZO^_z9Yg32R)W>9S!HGZ_V&EVB0Bf%`dRDxFvQC~p*kaQb#!Dx$Qbqp;mQ?$ZfdW& z&JVQ=L%LMPoO6dRlPTd|Yy9uSe@)|+0Rm2H1o}axz&@XP{uyc;_M!NMuvVv zRzI(-ZWl<<)3|ccG1-U@DhTEjAg@BUh+df;vK15xH$0g84s=Pne*%JpAoE@S37(G4Qlsu6Ha*mjjVnbe9$NTjjBF( zA>r^K@QwBpkp2m3CiXGMf5It`^iUoN7oG&dRl?JK-YU*yxJhMF`LP?T(W+5n`3tQz zC-NHiU32s28fUR;a-M3O-1ZrvZBZUR*RFuGqp-^+R3{48U28O}YIX&PZ?vYsnB#|s z+Eq6DR`b6!{bK9pDoq{M6E@ zOzh(?SYOYNewr1Sey%V<7w5rkrpTHoL}EXW2F#ODI8%QQ>;6#n%5`8zRd2Qe=eZf( zxl?6LQauCw%tX4dZ>p1TjdRLTI7d#lVa;)FA9oZ!$wgSQ*=YgXN2YLN6jEKEI)LVY zB88ijk?Kkj4-@9&M{SYHN40%WzEtbGT76cvZy(E9s`%XclhrK!0mMm5cn`mm*oJrHP11<$Y_={dWfCG`x}Hy7@}o)#>f z$l+FA44d7auvaYH6G}F`g}cTs)P;>-+&_0+EG=DwHWP(CF4E|6uCnP&Uyq5Ru~OLb z6*XfFYVyApZY9{)0-mbbjNhk{AG#M-Gf(P#6!x1TT@m&d&1_zlGL2ED=x}>%{@eVd z{Y9EQU4`^lA$=)$dzj@d?GySxo3GNA*qaAh$$qn*NS5*7j%d5B~dhOxm*YKoUKJV8M?5|oC5n1#oDV($#1LJ*koqtgjRMA6BydpfHrA6 z0T6vaY!U~D4F$v!AiK{2^~ly7IO?q}?JK}vfEEYcK_?sT3I~T30aARq{Pz|7_bfn) zhvZ6%X9^(x0;mtgpL;0&QTjtUIIJrm#beHYZ_0ny0wlULzHl#yxpwKT9-wAi)`+HL!7u-`pERBn_pP!z-_^FPQBu^0T!@Cn8JQwlM zlZSW0lQ@*Q14w>^#}SAsUI+(OoXSBJKdOPNjnfV=-xZgbJUX&#WOy`gpy`!7dN{2% zR+**Mw4m(7d8yR#YnVB9;uLd&rw{07KG}?NtT%0h)?&vDa%0qSH$0Xq_LZaGK zKvQlbdBd10tT}#oJ~j_1W_>|^;VZd-3v!!K_diu`6T(w`)C6hY7SW_Bw|#6L;EHf0 zH_`r#34rL^D(AyQ6a6TD>NW^|?(@9&FOaFYdu&LiLinsuF;kw>h?$sT!)|%c3Y{iW zN~O7hbnmcqYHDDV4YNzi%m_@elqjXxqaNi2Tnp~4nR0V2rhcdm^Dbq$$SuWzWC#P? zbL)va>i4rYb^oW+TZjyS@3yIc;E}C4k2m1)v4E=m@<8C!PtrI-k1#*yFmB%q@mzR> zG7xaJ21W|Bj$I>1geAu&X>4S$uif;eu)^E1H&@TAZ4{_Tu!My32lY@qW(XMAIC~~W(l~^o_J@l3wPBCgA$?$2~oF) zC&YS=uiO+Lz4ie?tO>x+oCgWRm>S94|2{(tP<+-1byAGHs2pT;SQMZ$ge-{72uC2%SH`)a2KD*a&3xe3!yrp3MI zi5q83M;L5)%>-Rp$>_JZ{-)~8L0O0=?y5h;_C5c%(p_+N^#$fnF%v?IOY_PeOWt;&VNRgVV*Ac!F(bLXE{ou(*vW# z=<9VDx0d)`qB4hmLGxynd9-krqNH@nb~6U^RoD`IiFC{cGEZo}G7j;*LVZD6^27Ry z?Z&L_ZDV#!c}4U{JhzWq!zgKdDaKiw8#vb?ly$`@7gs7v%U}g;=^3zLN{p({ZEvu1 z+wR~)H}In?>Y+Dm)yLmM11xJp? z=B-F__Kh1C78@O5j+-bUu*N0Pr{3m~2?_BDc7N_|U%2VGQ zPzp$W5xOE)zm2X*AKyqmA=MA{L;6}cugjg>Es@;E94JdG8*`xCI_v7>(GbG?g!EO% zTWfryJ+neTI+5IwH#5FprSr&ytM=Qf_;%j?5BQ;HEsx*iahi{k|3^HY!Q&!6{uw+j z=kad|SE1(>;v{)Mczp3r_rsy>N-+qm#m;+OxYD+hbMXL%u`8hQnxbzvv!^463-X>I3w^4*XY5=R zA4QqniD6DqMXxUJVJb+ijC(ZiEfM0O^+{8*V&co*(|Q9T1KxB+IBBrOT_>Gxg2UC2RJ^O!On z#DTLNnSkZYZ6=;cWi~T__s}<3(n;69!c*Sjuc|gnmGN_l|hG@|$m-N~a!KE`8^9R)|x8 zs&QB2EAq$Dg>$D^Ul4d=0r_(c(k0%|@1KUN?X387%tKyaO@?G-IzMj>xtPw-o8$bv z$UK)zS5nrIPsDFSMkiEF2!|I-D%CG1iFxA_>MEt z<+Yu)UIjObM~pcY$+Q%2O@84AXWqr9-^OcUu2KgwZC%K=+K_Rjko9HCci!U67s$^` z0?-*Th{t_aKX@-N`$FE-Oi=LWZwHEDdX^?06aiwK6Mdz??=V>RjkihZ&3WSHY$&7&m!+ z=&W=x51F~Y3o~xvSuOr6D#XePGn&uHxx7~t zxlx{?m@=1Q%wLE<6kj8?JXX;e3Z7HDi-MnG(5c|hv3hs5Hyu%iOkoTJE zJkk1j?W1O!5FcvimHG1gKQ~`OzgMj-qr8cKIGa1R*k~2*1LN)_dmFzSZ9#-KAx7Jf zpp9TXd@^(b-l9z61@#fsKlC$KD9uEMrF56plDbU!;V+Baj-W1aec;j@in~~wDIgsT zy({W61+Ou$#~cvjfKh&h*sxTAbw{Hx=CllV&_-8OxG>YdEF-^Vuw75}Q)p{~Ucg+7 zDQFzbWG-KWJI*B1(whih%(q7~#%(h{ceOiL z7ycV@{}Y-kBoge4kbz%1sC&A~cL%ufsW$pqc>}yj1#kAETr~MZ_`Aveh|drF_f;Z( zR-aSi$k|}wcvjv0Q_92#W4|xM)q9I=GuV3nxqPItxwbKx@=SHLwlP`ggFF>geGrY$ zBzG9y60`j$TL!lz7`x=Gu9fgI#7liEy-%pabQIbVa8~ww(L$72f**w;KP4&q+^B8e z-Pjd2f|gX-2wICZ8eT5EOZJ2|h?O^Q!Di4}>bni{SM&W0h0l|gb<`YRXuPGqn$oCh zFI1=1$7f+&CV%L&c11BoXDV9MQC76Um_W3$ZMbp1h?hGdN7xsmZ(>wsFK-$bx%>z; zSIS=6MeeNZ1=)gRuOCs5xO!2Y4uM`nR_@~D0Zz{0;ud(Q%D)?+k@z9((P8=Vs=}qX z4L6R}lwWqdtznN4)d}iXsZO{^6}tqU_^>e}lD#mB4_sADNJ`4Mv zRQCy0NJthHqYspzFVsSttb?`*o%3XEv~^J?>G&bcv-_P4&8Z%7@^YHk%gw3|EHbY{3>;}dQ%Kr-BX?~O*V1i5;Bx2+wOQnf1r{e1(E6WnU`2AwAr&Vc# z%Lw@Lw=qzPQXN$5nVQUW|M! zLB8_D2FI@JrjkNe1E!qgyZ-V`iZc~wNhQ9@KI^_oQL~O$CLA{Fcw*qwM*2CNdbz?p7s0y#eL{nw{ zTQfVxv-#)x%Qwht)aw*BFD8r>d@#x&`GI&$b&_O`YWV|S4x^kXk7)}+%1Y*&l~KJZ zN19Xz6=fB{9-vo*J+CPe!%{EwU3uar$7-yLJRcJ!(v0B}lVjt>;$vL@Bgi%;`EStI z{EhVT#3pL|@-=66$m%hf&Kf+UGBwgO%!rbhl)eE?xmbIVfoE^TvJ4&YjCgYww1*SwQx`>}TuKm!wM3SoC(+B8JDth2 zoylZA#Jx|sby7C3skeVqY8{WwGwRLQbkc%(Lie%aPTA62=m%_OE6Q|cGi7F?CZ((K z-B4l*K682ep3R#P_`{WzP#=6vm>tjHN64cITQ9gUQshs@m}Jo2V=CWr@F*1d)T!4v zV{{AVH0^u4k9_V$9$O%f8xc%ims+KAXRJ$lqw>F9r9GQT|fbNR@NG zlPQ;BJ|>LKR7Z@bo0Vnv_f<+kV;cG`)0rWa{nuXX>!iB2uK^RhjP1jWN_{bZuCd;z z^kHknRejhF^c9tTSbv!^5p7@;^4=49-y||V#`25L_bBAsANh_&zUL#~IwJiHV~Kvo zX5{wc7LF7mww`F_NgYl=vZ&9^T4Uw`B~MAWo0-z$*sV&o%~pP#Nk z-?Ut#k0Kh=^Zk^*=-b=A>vlHg>eNNj=$JBTL+cEaL5$J|bfpchlGoo&?tyWoJI0r8 z7-za-yzz#7j{T|zL8Xl-T(^-0v9sMj0nPfRlM#m1#CP)EwqzEe?es82Ce z=~ITI&JwRoc>eVQ|BkEhkJ^SR|K_p$tCvwvQZM5q_*Wn8;xYJF4F25&|BArB{or2% zzTTAKzO?E*G_2&|5{F<~yJI*u9kVUz}{<5!ES@k=4X_ywHe7vQ_e-blj>W#Wl);MP^u=r|w- z9a8v#UTQMrf5?Zb@(w4r(RfRHiJQ@Uu~Ju>in@cjK)#ewxM3_K6?zuwJfI8a_G||+ znbY;Sxy}u|3p$WI$UidJ#3Q+eWDSxL%^?So45Q%dBgsU0Glx~%+r5unFZKhyzQ~gg z){3j-S=!%S^FD^!b%%mHZ=s@7C>C?_yegj<+^5aT6_B|ppOt*^#C?cE8D(mv{8}Z) z(Ov~XmJ{UtRq#jQt7LD|Ayy9qKhPmEr-i*-;A^FvLi#0{Pg>wzQEtLL-PB!-wQRYn z&elVV(~GHwr+r>lQ}ULR4bQ5&0s3Y#?0kUgqk3Ir@?J(9ULiM@% zP!!6+8fi#H)`d~O)KXUZpH^1VkHlST`KiQDc~zyKbg;GQ=*WgGm18-|k>>aU--wPV zdo4Krh>-mmp2`I>OECggQcT;XI1-1B_1!^eL(|rM`iFP^e#Q znVO<=g1f%J)O@)>^hIaaSwbYW*JeU`Z9_ zzBohYfwLFBkW0C~9_M@Ir>^J*vOV1(O&PDwAP+Nak zTi+!`JW`P;BTC9Bx%S14+d_Xy{j;XLK;tyqo)n6zwGoCXZ*0M2UPpb}PitK8a|1dV zF_XH8@}Bmk!Yv)+uMW;2vF#c2q>Q?X@(}9Zw`JvEjVA+h`^+fVqrN9G&zIsHiW%fd zOZbzbjbiOqF8G~;aAdcd+*_bevVx4Dv`#y7#9I0ENZ#S6(R1!SrM1Tr=(`U)Fm6#^ zicG^WCNouBTY^eBC2|CD7BPf@f3?wfX-~Y4YJ|N>ibUtMj$f zby$V2XXp#C{|@>h5#)C<Kbw1#{nYw68*(vnq!ii2Y`AHwlCJ4RZ{?0);M(gC+>e z&GpSID%8foVys7`p-vg2PEj7K#zM|N^>ZOervx%3jfssAKea7d6RCilLT(quMj7KI zM#m1n?{hX!44dApJZg+IIXz>4qLb>TifsCBvig3-*CV|!&!IBs`d!eTaY4)+>;Jxj z&qGywwdFysng@OiW$Ovj4aGXhEh-o9+T>eqtd^oYj8Gmg(7uzwzonK;Ch-)sWZ?Yb zvGb5&i&@!%%7YsVYNLnRX(dltdN}_T#0y@JS&a5!$n#Y7J0mW0i2@CWVI!T&M=ftE zvPvlY2xAe+jS61&M?cf31btU+a!Ogq9?1Thb0_rMD*4}m{8K$`j5?^wgBPE{12wu; z%7pSN$euK>DhoNtu0c^fsm<+E%dW&h;g+VwIK5Z{o$`B<7Yy_BFdq@d<|2M>62`BS z7wf=wJzrN-@m^VGd|yfU3)CUO&kGr|1Lxx8x!}DJXX-nZv0fuwvXt3D^~n%xftvM+ z>exT3Pbz6p`4i8qu*dmBax3|HfqF;$5b|y=ro40YvIuKY)#{o`nblU8sLX0}GsHMk z$+uS(1<4=qE3Eqxzdy95Tk=e_-KXD;r!w6A;3twD^MmfY6yIX{EqOX%s_yc8(BYCE zJx!Mh7RGly$Rp|SYYo5F@YA+D$s#hCAqb>ecvuv$2CXa z*l$3S<(%9~Yh7HQNqfJo!kNtIKn2EiS*ZfL>C_q5y3CmoQf4#Ltjv7o$}Vo<%;{Cr zJd~?uG%uSo9OE$T4}?Hg*oQtnskK5m5%O*__9j$zDcE39)zVV&DtWu2QVQ+|z&-}ip&6`jXrvV=6xp}(z3)>U0=emUT0 zjPq5pgHTo!PqLWSo;bY*;ZaySz`U+B7h@guNixWKO7wLlI7e(PQj{O5sMvvhm7rgq zZzY3lhHu1+yO@7Xhg_vZ`y)PhV(x`8syuW}SEUr|FF3bVF3kH#9*M#}4ME-z%9@jX zxUv7`fCDU_YCAVUdy+^7qB%*)d_|cR_7GSPRk+zeRwS9PE$Zwb$hqUN=ZgB&G|=@5 zG=moOwXiR76?!1}ozs|GpB)UpAsFKaIDV6}4DFlpXH(A$`ekP9K)6xcqIDfXHYlPw z;k$~C*jp<1keHTA-cWi+CEv%M3U0EtHqpXr79^W=6q3 z=`|>R5!*-5d{=!=Eu2yDU>H{ZwF+h2Qn4mxL-SmOvk7C|ZgBJc(z}q4Wxz+_{*6%V z>9UsM%tsjJW_1~7st>xLDFyW*7v-M;UdPV!bk%!b;be_?bn7U}V?Zl?i+xw&WW&}S zQE4&Swhi3;fw!&0uzsRt=w}h14-bWSOL4wjXHeTRU+5le;N}BAG71M;{Xv%*eiWAu z-2IRih1Y=}@=K7?pmXXJk1yh}LV7Z|kxoIN2W1s}1N9x}n&dX9|2Bwg6yk#JoTbT1 z%0Z#--$PuYK{jR9THrPL0Z(WSX$?LSJu=Wkabw-%(`Z6^0!{Zo2j#7;X5Pvxb{vJA zRkM7-bVE%u?_45xL^*{4{hQ(`X627?>h9>C2dxjnn@a$G8U@_ zm!K}9j$*#JEGKLGvK%AO-4Sxg-D_NXxyQE`Y7-Q8ze9G;&36@OFGiK^MFBUV&SJcF zz5_Z}VI2*6$KZ569--Y0fZqyn$5A*P)yDLK#sWxPG>3 zUM0vk){LV39_EurP;OQzLyXr2q<^P2gSECDz9^HskokzW0jL*g_-=-A%7SPF|Ivq( zrZz$wg}(sQ?+}rwbRYV5+;1SKcy$qu>Yf$KTQ$5n`tx*@vk(U3ey}a-Lr?f?4|o#k zV4bM+A?i&2p!Q|$ofOKWaO>sFD0_ld3}ofDp$fO2RNjoJR3S>uX{QfaNuMd$SdT$F zN)05Li0YLT>FcnxF=MqFDqa_3ol>=q(_GePP*fRx3qZQM@Vg3ipW3D_WDu&qb0o|T z%2O%iIBH{UvCh#6IJNN*{QQysSbPtlJb}JBe12njI1g@n!M6vdZSAKbgvnnkV#-HLxJfo0? zKk|jRSV%Ok0v-23N7SHpWz^QF?N`zOcgi27If~-eM*b1s(H9j3R916eR5+7cG~SQY z<@oGNWq_YA!pRVyFWjlT>AoTA3kbG_o6w)wpg-{eeL8TXHNjTkBhBxv5C`=ym@7a= zljRF_!}Ag93fe{q`gtl>;yL*fctf;6zrmJyB`u&?hBQ8j7SJrvg8lBOx42IUG|Lb# z#V4d0jdvOH@lX5B55^06Z4mcA>H9SGbQp_Za|de}3{x&$QHySl*W+=rM3v6_V{z50 zk5h?{fqbNr;bMEfbqM`16EKfl)57Hgd`4Q(qf z?vE$7etxVq~%v|T^@?$z8|-iW*;lRp1uaaaFF&VLr5+uQ?`ZOrS} zGl=^BAkT7`{iiwGd-X2DaPDyY^Ujgphq?DAj^cXle-mjwPMWpL@moya@s3B&_RlWu z+5XJZY(0nf1Luh9t=~g?%$fL}H)fh=`n)uHpIGMZ8(yEQ{k-$2dv^L6=ht6n?dTzF z2Jb<0w(0&ZK-eR%J-+Nn_P750dgiO^`~Sc(TV4HFWmcGLid%yI{3@~I`w_zTim}6QwOj7s*B1k zTYf5cztZ)UyEl|OsN55r+-usict?GRvbNFI_wbz9oD9}_+BHO-x3j;OE@)4$JiIg7 z7vIc!l=X}I4s%~y@elMTeW3d+?>WLebV9l^n|Da0SFdl+*j-ka*YD{`@0;H>;U5|p zN6O=7^wiT6Z=Twp`SJb<=-F)M75!8Gb2roWjFH`=-H(#yd)NO*El{raIiVW~x4>u! zdvaq#xCTn==Ekjwn%lzb?^lJP$JSxzdSO%N!(9@3Gf*B2zV6y6u8r3E4UT87W^z&3GM{L z;C}GZ0^S)1&x721#~7Q!=sxgq+-pIFTLCKEJmVkBGZ;NP-*Fzs{V*5@_k-)fz2IMg z+rY;tcdNm5Nw5z03a|yt1GnHm%iy|PuoXGS;JS$*3s-)BgnsBkMR7K63OdEi&TT#$Fs^Dh*baOW-df(myMRJd+X;dWX7a74}E;eOo8-4+j7_fGIS?BoeqJ7asTEJTjBgNok@svb>Nt^gHJ zsCea87AjupT*vtW;bqKC*qY}!_k$vSs|J^X+rVs4{-6#ZGQWzKFaHRKCTa!WCM%bC!vp1V1Bpkb#;% z3w#310iOZ0!FKS(OyhqPl>a`9d%-T`TI;{Yx|f5`7o z;oCr!qX|?#Yb=(7%BSaMGtQ2K3U?S(xK2>{v|HR}{p+oNg~b@Cbk2uO{4=29AG3HA zlz$tj@mvq?0rNoRmkTPqW3hjR34at+xV51AA!f1AVgdMo;)6Yli*T|(?RK{kOw4UxmFe;M~^|Yv6k=$KL3!4^Fr46RmrHuJP{!UsOEsQ{X=EL2$2?_gHMV?yaEmskCyr^)Iz@f%VS@*AlL8 zs_Bnj@Egd7K)LU=?t83zDOicSNLqG*y;Dp*j)AJjQBe8r1S^;-+YPSU0dB)R2|f)r zflNWMdV|qQ@Oj*G!8Y*1WHayg8C-W3+=_cQSOp#ezYgvPnQCJD3`X~YpToT!d=}gR z-im*l!DteEl5#Z}To(fy2v-U+v|}p_M(2UexX%I~1#`i@;6(5~!etwb_UD*-^?@7k z@3rzVQ0aDqO82P2=wVRvW(TN#?76|j?*KLbR)BKv{xdUgt_3CUzuvYVDESzJOzpV~ z{319JlzZQ`*4<(aDEDzz?we%%_gmZsZp6PHRDEke)prf3`o_SUDSxTK=u(g=Cst%I zD*K5lM;@s9hpl|+eWqNpr`U-5bWr7(2uklSaiA!D=?6E1eIQdx?7YEfHz++i3{D4S zcTw~64p8w{fJ(0rRC=>OrIQOXbYeLMqq1|a_~SsO*ME)GQ;;UxcNApE#|~Rrh#Wlx zRug_7sQT>zm46ec{OdvGTWaN5;9BHta2n~2GZ;NfAeHMBsB)b&7(D^1Jl$Xu2$8OM z4)gbcYOh_O#zO(fUw$qh%J(|(tKhx~#$EPA<=zhN1Bz)g~fP8d3*3m)Pf>k|RL6xrpRQO^L)y*#e)gNI{`Ah`WKF6*y@j5}p+XgCL zEvR^FK*cKs6|WFfJn`Ut29&+ft>9iz`R@dkP8+Cn>OqBbKoXG_nvm%K40& zkL>2Hi6ZIuLKo820jP&g-m(HpQZHpJ;P0}7*u*f zx;VDf%0lF55vcU?K&6)ps@`WZOuwE6cOstvY0B7fgHfInaGqj*JZf;=AyD}Use0_7 zm4(Pr@jh)Qola2c=^=ilx65F(9aMTd46fS-y6pfey;ds=m0l${J;T{2q{y+gRu&>h z*MR)RDhx&m>-hBXO zUE0!>g-W-^%0l^9T3IOnwcuZn&Ke`fDy(}sNEhdqf}aLgSpQ;!(Lzx93YBhwm4!-o zmURzXnYyUl`-D_EhEBP%5ZSfMEq6p$R)60O)l4@?8C*NrWnd@rhrtdo3buhuLG{mv zz$UN=tOY*^R)R}F^~++g7^KXu9qa{Q0rGq>7mR?{fz-jZdwmDkM|o}sd%=9L2b>3< z2Iqp^;2iKUI2$|&-UjXmX@g0f;7qUsoB{3v*=kN|2XnzTkgdw3R*8f!BcrAWNKU2ZbqqQW!ZK%mta!T%I_l80=h! zXJv&73bR7RE3!hBHCdsGHCdta8GUeScVz74b6Z(wbJzQ=F%1j_FE6Gj)$D7ZX!9$%GsMCHHV`d_Qg=X;NpcB zuVUy9&;2(3Bpd!X`RIDmwpTgruItw}e4PznYxCc1 z<(H%{q(7a0(RIJ|f7<%rgP;7*TmQ|rzh+G};mb6L6<-6JDf?3vo35*D{G^rtlMUZNJL}T^N$K@jd8G|sZuRMs{An+bPwhqN zAN^Hn`|Hy-y%_b@Rf?a|yA*asXOT_6$NJBp9`dhY64mt^zDpi=i;@4v#y@Q3eFZ zWXj;pA3aRYvTJ{cMMqZ~ev;d*{5{GqxzfrXrvJrr>0MV@*{Zj52Y&Lm-R*pj#b5^U zx3Ng+`W54CMn;>HZPRPE{s;4n|L4$W<+tKCBcEhkNUoV<CXuG|Ia}BKMS;HW+42wfc!>4J{Cw%gp~gL z2Y7-vB$COxO^L?!HB|wtEc4@c$L_y#Su7sEFCHoKeu0e0lBdjtuCDu(F`hn*Dc!N! zXdfxp$Pzc(beqrtW4Bcc)?rVH( zWnFc1V~e#Caj&%tv(OZQ67Z|;!<*L+T?h)cq^h1DaI5$|)-BZnV%VfiN((n_#?Hbb z^E2)cK85=E*SdQ=$&s|eMi#p*?KjQ6@UD6+(4?id$oxROs3rk9v*$JT1ee!0wj|OL zj1=)(b4{HLzQngwHP=-=T%U*(G&Cmb)^CkBHh6)@oJFB)V%l_=ZR90z61zWZ$JK=O zF2Qb~DXf+I74rk`Df97zd?Jg22H^(>37AYD93ahPdCJ=qdx=pE6nJQ*C<%lgn>q(0 z4JaT(U|0nl$jj>oje(Til0nKmVp^$aURvpTn3`u+c=k%Yf9!*I3r_zbI8XUvw zW1@MmZ@RWGaKmaEi!m}r2|eGWJgCRL5~fO!p2tvg*C;s+F$zbCVav91Q&rO{9_`Th zQLR$3OzYWk8*q&*47BO;QED`QwfFQ1{a<$9>VkNxyGlw%iJS_#!dRO1nXyglxIw<@ zjT-2hy9Ao<2v3FC$tQy)sRG!*;Z^4 zZf-y&LHBcgjZ${v=97#A<^#M1alU^+9D3p#yc#ZSUSHQxQ&K%(JYaowL$cl!E8T_w z3uIlxMkik1l1Ko4TgpYKv^yzO@I+H-qP{87JilOdBB@bze?$G&l`E^7Vrt!zx=|xW zihL38S}|m_H1$ah4zjFIB%1DOY&IK)gqFvaV3uidhnO=Mio;rD7~{4qP|5Th3*3e( zkr9>4V9TAX*00xAL+$FD7Si%ewUFkpk_DSuHaPJu1E%~2zBSp!z9mtQiN8&WO`96G zB*@{h=DH+k!3$N*-cQc!T@`oY7NGTSt%`5hT-96?Z%))F*g{I31{|xZAKhHnj3egk zt2Viw1NJK1cxHRLxvs{EH<1ZoKG(NwZ7}92?85f8bbe8DqDA}fO(f;jr6rMUX~H7o z`nq&;7ZLybTFCmiMHVs2O`w$3kMw1Dn3=OsqoHK$Ccml2v7{4Ro`z57Ev%&`ks-=r z8g_nxH-ENlZAm6JnK`bc&a(#cj+(!!rKN5|L&~y+6;1b7#N8Rm7J^zgClc?d z5b?r#o(eSu@fE31^Q`9@cXtou6lYvDySFA3T#6Bim?Fd*u&SisrLg*H&w!8E}k~E&2O;u&I8m zE1z5QbWP(S-GX>Ug!+`-dJ8>wnQy{p!v zLGikVmPB)MKnq+|TI5qD_fEb{%7ofi#8)r$CmLB`LpCQg;lJ%<(pz)LLjlw+a6is^ zOGBrZ=N%=qX%p!cn)-RFI2J2JX*-&s*UzHW)wPM5&FHPh2HiA2J)2<$NhE?TrRHRX zdnf(YqRwA*C%do>%`(_#<2NLmx0W|zg}0=9b;RF|w!hzv*=s)YhBu+w8D(Q)D;w(# z?o4+NE$&XdbZ=o(Ro%c`^H%1#hs`vnNx8tSSH**)PCptN{$T#)y2Kqfo(c@pH%snI zJZ5ftFT-3^u5o7%MBLo{MN3nuNcz3ln2K7Y+wIFVYq}*(9np*_`$)k9?wby72~^Sa z=)+cZnC;Nm@>KT(&kinEM-4uQ8l}&MI+Pe&H5OBi^n=*TR*Aq#*(g;Qe5*aS3M`}o z{`1YtR{XScys?!)`Huq$&(?x4Fog8Ba3{u9e8{u!lI}Eqsg< z_L5Z$z(~Z-#T+PXba#I4Q8r7wofd5(_B>Rl^_)TJ=wi4tdlC&S&nBq~uRQNOsRzBJ z2F_34+5!GZEj+NvT*NOeI*nMtou+OqwvJ%BeT+NJu`DN%0(W|Bt!qiPTn4QiOO{Jk zxw|$hdZjX4jshhU?|O!jLVGA(y|F?geUYi?6{@9fQ?whtObc#WPwFRtB`e&Utx;Mr zGWd73``GmjHAqu?C8ZuIFv*Wr`nQw*Fgq#t$Ia!nb@erz>s*FTVv8|9zQ`U6tS*Y* z#}=~;)GdtLns#=JBx~zh?A`E^7M%db*W0tT_@e6C=EjD`qMFUzW%D~(St~Q#Lic-F ztUgl0Kj*;aQo2ew?ZEf;NMwm;gf#V~$a7ijeZh1o?{%i^mhuG=>!o}KOqWKmT{^T8 z(}?H67vdG9MEls=@ODiXhrp}HW6Rf zJq8@T-{-$nR{u30fk$ZUGXp%l7~-GncK&(P%julUvy7nPDO~wH_dOq{Ekd1nhLOh| z^nQnXE#OoCdM0Ek|MrnXzK#7F#GCOx^KL#Vz=Lf$OJYu!XNNO8+i)^CZBJrT^C|wf zFP%{U_XB(ZGoHPwe@3V5sts^f2l?B?p^-|L$5$uk6<^G$%-H>H_~gFIJNT8ioA>uC z?=-xa;&k}^x?Eg%vJG!I6tb%g z7hX3UPL8$Dqj>%>Q{Y8O^~EQgt{K;ehr`4_erNF!@irX4Q{2YJ?J!&_FY?bLh&kT| zkAJe;<*R>XPBFH#u!93Xv$!^1o0*Zao%ISF5aN~i1$-XA%v5=EUizx#fAGp4PU(U;{0x`J@rR8rFsW2b znO=PH$M7V2{2{0RcWKuQIQ_oLBj2;=SKedZEtz>0y(zxf249c#>$i*MtvgA7A7V+nm#P6<<6J z&(Eu?q?4u|UjK{YnMnX_iY;VsUy?=zp3A zy@6M5x9ryZ5-!PywmZAep{M(uqQ#HYJyI0^@6My$j4AeKIp;#~U0Js$;qVbB{9OKH zq$!S}&oXD8AiXE}-T`l5oVHlb_{%2DZ2rGb{Ey(bj5+o-zR%!$7>+}aue&GYEabfc z#x&gR)#BWo`ckIHL;u%m+X?5yE8mmZ9ewQ@)~I9vux?l9jDC4@mfBGBvB$}%_2+uZy5FunUGCcBv)lNV*Pa1BQOfGtbD(`) zPE8Ll=Q`Bw_QSwBJyr9^Et-$b8vC17h9gOB`}fqA5&PFzVyt-m#lZN7VGfp(mi^KO7_%HqYI`+jm zy|({fbNm0fx4idYuM7|H)FF9*UvbCV)N|Z6R2-)dI=@!p^3uUk181!%WAD!l4{(pQ zJK(KR>aT%)&0zj|Z>~z;cgr3XHelE*so%}o#@=k1;R~#^df?wzr^nA`PbFK|#DTL= zwkVvGy~}~UxI)Y_NKFJ!gnZ3jl?q0(9RkFXRq|GXESDR~pV9;A<((gH5hFex?g&Dt{=!bt_w@fyc|6lY?-k$UEcWyAvtN3TiyNNgO4g5mFI?Qg`6zXN#oDa7+M65w zbJ1AiD6T)=o6BVFp4x1iVVPj-G`$KFbKc3D0Ftq!kwbv#)Uz)dc|26GQao2-0 z2lh#&t69r3;L>Jp_saST=N!Gag;Hk^y-#Fx{epe@FPCd?JlS{dVD?)3na6vta$cUp zJfr)Mn<5=AJPsHCg$+*Eg+HwP5jH|TKf&3tYIX*;cCgi26#4QCWp}e*-kR*cIYYdr z12%KEao-W9EWPZfbFm-Wj-AmQxN4^o|HW&HfBpP|=Uyl!Zbn_QU-!GRJ*IZa&AjoM zJ*+Kzxz~|Rh6^)`yV@HZ)-AIqQW%wUzk`hz)`mLHv+~GW-1xtLyp(pkoA$elb}XSi zS70A!Ikpgutwyh1+L;G~>E-?5&6m$>e?IJ4(}0b&T-tt$ukCYbdvCw`COqnOzCL(b z9Ie>r^759w?t!zP0lVqLo%uXR9f#Www^R4mLh6gj=VnK~_=4J@opyMFwi+(IvFfN_ zKgSy9t?IRB!_M1JYtMHhV{3uiwr1avXZ8BK>@&PJ99gdi&eJ?So`xQOiaik=I~ND* z@w9V`BQLx#J57%V>_&Y8`@uRV`Z4yJq{GwE;T&}M33Rx1!JZfLTpiwq4o^jg&Hnv2 zq1~c*`*=%_^ zH02q^$<7cu7njI(0i5wSM2i1!25kq6k$VrIz1ozSWnHgg2l*-1kstr1(?8{22U`(N z&Q0{eE7;I3#7@oA*s+;|z3@5XotLvSZu-I1*o~G=ld>nDe&O|h{q%p9U4U%o(&v|A zvt}Fn&h|I4TRqNsx$WPKy_)QaInT)c$ztplzZ$yfTn2i_E6DuP(DuKAe%+Mg`=5*V zU;XS1H>_+sPoXSVPn`Zt_BXS;uD;*7xP?8nH#cNcm!sP6GN(xwhB~|P?0M0ieOU7#B=Rw-*4eFxyFQtEukDrpV@xyO3rhQm% zxvUE1* zRGxjFovwYJi7&l~jUm@Q&+Wxsb#t69&Gk>nE)9KC!M(6K%S^vNImhn+vdIGpY()!c z)>@l9l|Gw1URpWK{lR+{ukC|v?A<%$6l?7@_efi~$A2~CoGWIYkehcl<8W`Obo_1# z=TL5)9q3-3v!=9rd4A8z36|wG#!KD=^osK&>9S{^=V{hK&HcJBZ)eW0wD;w;?tQsA zH`<@NZ<4*=^fu~D-8T*Pn@!o@v$^q}&5ieLZW#L?I%6BrHU?w!PtE3r))4=F={Ig#th;!3KZKkO^1Ma<*&9td$1E0r_v5~cfue9bL4|7v%fL0D^1Z}C zv%-n@_CBy4WP_Jq1eSv1K!xj{;_~F>_kk+US&%*DJ|Rzt#CohOM2?;Sql6PruEHO* z{z8R6U}d4gw}L8HEqDw5H3p-_pvp7R;&FJfRwzAC;SLy#c7mJ($Ha>ZMt6cLzxd5m z{-q%2KKX^9%997G{6hAVG4bC@79vNl0~KE6c?y4l9hLlr3NId9$wGzKvo9+DUQqca zL6vhYsB*3`7>$9mkV_3lmx78{04iP|{6~_-m#cVZ3`RSx`!-PRvBF~ipPBG|pz=En zD&8rB(c_@n<(R?fAyD}=fohi;@WY_^cU8}FQ1uc{AYRPMLgZ)>sPK89!cVvULWR$@ zvQXj6Nvxc3Ip9aZ6Y%*6#nZb4JVoc<1s(%keFf!TY4P~`OgRr*JYcZ~EF;`fFb2-D z?m6H+$l~7>j)Pgu*Gd#>ztEsBSt`zC5r56b~;$I2JY- z?O>yLFZ`e4&jr`*0u_D@sC;AKN^ph6La+$=!qv9lK>lK<3`Tc>8vkuzHrQmb2Bhor zW7dBusQR3zv6atRPL(#85<6gJA#!vdsCM5ADtEUbx-SJOVt#>jcR+wpw{~S=^$AQXEI6+mhvJg4ipJDRT^N-5!6sY`;fr?)V(ggX~5OVckDabQ{`Gw#; z;5?8b=ZiO0`3U)oO|-I*zvwa6Ri$$fRQ$c5;_m?!zZFz`q2ed4EL8lkm4))3Ze^kT zSr(l;Nr&m!tw$S<1$22Ucn8=7-VUw-^TBd(9>{YTE{|(5I0sqJp3Vjfz&tP)ybV;n zJ^*Hew}O4-GZX9u!(b0M13V3~RhZNb7J`StMWE_USzTUOmi|ed$P2&@a3Q!0Wa*#O z4pNs%Z6Hf{8ZYcJWoe;a88Q;U_;R#14 zWQ7h~bMTt1(5dTBUk_>P4aaZb`{dJ;pekb@68_fXe4e?j=QhIRoymg^Htz(VeX}n>1iNp}en?*r%smL%>)yGYe4d@xI}exq zgHXQqOphSK0t|Y7FEgjiKuSzDw?4@ag(1lu>fO z5uIi=8nSq!b?sK8@x6d_bbX1zBKd?(?|C&Yc^*U=bbS}47ms99*cF|BA|Hj{OBh`V z8@|VeAI~Hu|4!oQ5^tH(%MQDu^Cjy)j!x6{iaMF_7p(j!E6*n#$=S5CF7en)Zl#>Mp0n~{E3dTWn`qm&S^Y)b z4u##|&M(zp#9wOtkJ$bzwf;+Ne`Hf`U9;7m3UB47rM$>VD?e}3e} zo+2%!CwmyW!d8}@3|)V3W$_{E`ia$F-GAtM#pZX?%GcTQoVD^7R3GAa`oF{0&(pss z?JHi-OSXSrrM!~cZTnwu{m)zfSIATTt=7N8^>>Tneq^8*;u+0mQ>9D$49OMryRKaH zQ1K7g`aDa1@-Mai=cq4#sjG&v`{m^UIUJDx0)6*~4+rG!f$-S@`RA11AO8gH>6c3b z{<{OR)&qa|Ur`gk+!4s{ceJbD|2u*3M*{L`+RGpQhXMJ&1>{!(vf}#V8^WKa5jp%K zWeqEN4T;y+c&F!zvIj!L193z{vaYILH}qxDX{5*lhae41y=GlNNgryiYJvl35O<$> zW9Kpu?k)1ai>jif@$IF`lJ?5=5>U9<)(80N(%))|49>w%z&CUbgCqGV z^-^(sEtKMv^E`)R(;NJ*@}Q`Zz?;B>1EjrcJIGtFjim_Y{5_RoKJyA0Xez&sjuy7y zzQ+5T#zZqWzaaSDxB7Xs^oP*e(V`6M>Cqyj)pry+G=F_Z4mwPIM~)=2tl%geg*$Dq zl6n!|I&GSHlg-RyA}))6yy39{CNV!lm`~^54o#P@8OKV(G^F~xW$vUQ+IJM{q_@Xj zwCDCdN_oVTbteqHPUcgLId+M?_cVzc1TAdzO$KD zH*RXGYKD^tCY%CA*vLrtxB(kG)0+QuJku2djB+1eO zO7RZJRK`%>f$E4o#bt|C1H6z8RrQyFh-J*W^&VqR%F4u;w?0>t XHODf~q + +@interface LLDB:NSObject +-(instancetype)init:(NSString *) path; + +-(NSArray *)keys:(NSString *)key; + +-(bool)insert:(NSString *)key value:(NSString *)value; + +-(NSString *)findOne:(NSString *)key; +-(NSString *)findLast:(NSString *)prefix; +-(NSArray *)findMany:(NSString *)prefix; + +-(bool)deleteOne:(NSString *)key; +-(bool)deleteMany:(NSArray*)keys; + +-(void)close; + +@end diff --git a/Kit/lldb/lldb.m b/Kit/lldb/lldb.m new file mode 100644 index 00000000..1c242884 --- /dev/null +++ b/Kit/lldb/lldb.m @@ -0,0 +1,145 @@ +// +// lldb.m +// Kit +// +// Created by Serhiy Mytrovtsiy on 03/02/2024 +// Using Swift 5.0 +// Running on macOS 14.3 +// +// Copyright © 2024 Serhiy Mytrovtsiy. All rights reserved. +// + +#import "lldb.h" + +#include +#include +#include + +#import +#import + +using namespace std; + +@implementation LLDB { + leveldb::DB *db; +} + +- (instancetype) init:(NSString *) name { + self = [super init]; + if (self) { + [self createDB:name]; + } + return self; +} + +-(void)createDB:(NSString *) path { + leveldb::Options options; + options.create_if_missing = true; + leveldb::Status status = leveldb::DB::Open(options, [path UTF8String], &self->db); + if (false == status.ok()) { + NSLog(@"ERROR: Unable to open/create database."); + std::cout << status.ToString(); + } +} + +-(NSArray *)keys:(NSString *)key { + leveldb::ReadOptions readOptions; + leveldb::Iterator *it = db->NewIterator(readOptions); + leveldb::Slice slice = leveldb::Slice(key.UTF8String); + NSMutableArray *array = [[NSMutableArray alloc] init]; + + for (it->Seek(slice); it->Valid() && it->key().starts_with(slice); it->Next()) { + NSString *value = [[NSString alloc] initWithCString:it->key().ToString().c_str() encoding: NSUTF8StringEncoding]; + [array addObject:value]; + } + delete it; + + return array; +} + +-(bool)insert:(NSString *)key value:(NSString *)value { + ostringstream keyStream; + keyStream << key.UTF8String; + + ostringstream valueStream; + valueStream << value.UTF8String; + + leveldb::WriteOptions writeOptions; + leveldb::Status s = self->db->Put(writeOptions, keyStream.str(), valueStream.str()); + + return s.ok(); +} + +-(NSString *)findOne:(NSString *)key { + ostringstream keyStream; + keyStream << key.UTF8String; + + leveldb::ReadOptions readOptions; + string value; + leveldb::Status s = self->db->Get(readOptions, keyStream.str(), &value); + + NSString *nsstr = [[NSString alloc] initWithUTF8String:value.c_str()]; + + return [nsstr stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; +} + +-(NSString *)findLast:(NSString *)prefix { + leveldb::ReadOptions readOptions; + leveldb::Iterator *it = db->NewIterator(readOptions); + leveldb::Slice slice = leveldb::Slice(prefix.UTF8String); + NSString *value; + + it->SeekToLast(); + + for (it->SeekToLast(); it->Valid() && it->key().starts_with(slice);) { + value = [[NSString alloc] initWithCString:it->value().ToString().c_str() encoding:[NSString defaultCStringEncoding]]; + break; + } + delete it; + + return value; +} + +-(NSArray *)findMany:(NSString *)prefix { + leveldb::ReadOptions readOptions; + leveldb::Iterator *it = db->NewIterator(readOptions); + leveldb::Slice slice = leveldb::Slice(prefix.UTF8String); + NSMutableArray *array = [[NSMutableArray alloc] init]; + + for (it->Seek(slice); it->Valid() && it->key().starts_with(slice); it->Next()) { + NSString *value = [[NSString alloc] initWithCString:it->value().ToString().c_str() encoding:[NSString defaultCStringEncoding]]; + [array addObject:value]; + } + delete it; + + return array; +} + +-(bool)deleteOne:(NSString *)key { + ostringstream keySream; + keySream << key.UTF8String; + + leveldb::WriteOptions writeOptions; + leveldb::Status s = self->db->Delete(writeOptions, keySream.str()); + + return s.ok(); +} + +-(bool)deleteMany:(NSArray*)keys { + leveldb::WriteBatch batch; + + for (int i=0; i <[keys count]; i++) { + NSString *key = [keys objectAtIndex:i]; + leveldb::Slice slice = leveldb::Slice(key.UTF8String); + batch.Delete(slice); + } + + leveldb::Status s = self->db->Write(leveldb::WriteOptions(), &batch); + return s.ok(); +} + +-(void)close { + delete self->db; +} + +@end diff --git a/Kit/plugins/DB.swift b/Kit/plugins/DB.swift new file mode 100644 index 00000000..ddde54f0 --- /dev/null +++ b/Kit/plugins/DB.swift @@ -0,0 +1,97 @@ +// +// DB.swift +// Kit +// +// Created by Serhiy Mytrovtsiy on 03/02/2024 +// Using Swift 5.0 +// Running on macOS 14.3 +// +// Copyright © 2024 Serhiy Mytrovtsiy. All rights reserved. +// + +import Foundation + +public class DB { + public static let shared = DB() + + private var lldb: LLDB? = nil + private let queue = DispatchQueue(label: "eu.exelban.db") + private let ttl: Int = 60*60 + + public var keys: [String] = [] + + private var _values: [String: Codable] = [:] + public var values: [String: Codable] { + get { self.queue.sync { self._values } } + set { self.queue.sync { self._values = newValue } } + } + + init() { + var dbPath: URL + + let fileManager = FileManager.default + let appSupportURL = fileManager.urls(for: .applicationSupportDirectory, in: .userDomainMask).first! + let folder = appSupportURL.appendingPathComponent("Stats") + do { + try fileManager.createDirectory(at: folder, withIntermediateDirectories: true, attributes: nil) + dbPath = folder.appendingPathComponent("lldb") + } catch { + dbPath = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("Stats").appendingPathComponent("lldb") + } + + self.lldb = LLDB(dbPath.path) + } + + deinit { + self.lldb?.close() + } + + public func setup(_ type: T.Type, _ key: String) { + self.keys.append(key) + self.clean(key) + + if let raw = self.lldb?.findOne(key), let value = try? JSONDecoder().decode(type, from: Data(raw.utf8)) { + self.values[key] = value + } + } + + public func insert(key: String, value: Codable, ts: Bool = true) { + self.values[key] = value + guard let blobData = try? JSONEncoder().encode(value) else { return } + self.lldb?.insert(key, value: String(decoding: blobData, as: UTF8.self)) + if ts { + self.lldb?.insert("\(key)@\(Date().currentTimeSeconds())", value: String(decoding: blobData, as: UTF8.self)) + } + } + + public func findOne(_ dynamicType: T.Type, key: String) -> T? { + return self.values[key] as? T + } + + public func findMany(_ type: T.Type, key: String) -> [T] { + guard let values = self.lldb?.findMany(key) as? [String] else { return [] } + + var list: [T] = [] + values.forEach({ value in + if let value = try? JSONDecoder().decode(type, from: Data(value.utf8)) { + list.append(value) + } + }) + + return list + } + + private func clean(_ key: String) { + guard let keys = self.lldb?.keys(key) as? [String] else { return } + let maxLiveTS = Date().currentTimeSeconds() - self.ttl + var toDeleteKeys: [String] = [] + + keys.forEach { (key: String) in + if let ts = key.split(separator: "@").last, let ts = Int(ts), ts < maxLiveTS { + toDeleteKeys.append(key) + } + } + + self.lldb?.deleteMany(toDeleteKeys) + } +} diff --git a/Kit/scripts/uninstall.sh b/Kit/scripts/uninstall.sh index 3c1c0156..114f3922 100644 --- a/Kit/scripts/uninstall.sh +++ b/Kit/scripts/uninstall.sh @@ -3,3 +3,4 @@ sudo launchctl unload /Library/LaunchDaemons/eu.exelban.Stats.SMC.Helper.plist sudo rm /Library/LaunchDaemons/eu.exelban.Stats.SMC.Helper.plist sudo rm /Library/PrivilegedHelperTools/eu.exelban.Stats.SMC.Helper +sudo rm $HOME/Library/Application Support/Stats diff --git a/Stats.xcodeproj/project.pbxproj b/Stats.xcodeproj/project.pbxproj index 8b14daeb..7d5e3858 100644 --- a/Stats.xcodeproj/project.pbxproj +++ b/Stats.xcodeproj/project.pbxproj @@ -24,6 +24,25 @@ 5C23BC0A29A0EDA300DBA990 /* portal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C23BC0929A0EDA300DBA990 /* portal.swift */; }; 5C23BC0C29A10BE000DBA990 /* portal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C23BC0B29A10BE000DBA990 /* portal.swift */; }; 5C23BC1029A3B5AE00DBA990 /* portal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C23BC0F29A3B5AE00DBA990 /* portal.swift */; }; + 5C4E8BA12B6EEE8E00F148B6 /* lldb.m in Sources */ = {isa = PBXBuildFile; fileRef = 5C4E8BA02B6EEE8E00F148B6 /* lldb.m */; }; + 5C4E8BB12B6EEEE800F148B6 /* filter_policy.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C4E8BA22B6EEEE800F148B6 /* filter_policy.h */; }; + 5C4E8BB22B6EEEE800F148B6 /* export.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C4E8BA32B6EEEE800F148B6 /* export.h */; }; + 5C4E8BB32B6EEEE800F148B6 /* slice.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C4E8BA42B6EEEE800F148B6 /* slice.h */; }; + 5C4E8BB42B6EEEE800F148B6 /* write_batch.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C4E8BA52B6EEEE800F148B6 /* write_batch.h */; }; + 5C4E8BB52B6EEEE800F148B6 /* status.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C4E8BA62B6EEEE800F148B6 /* status.h */; }; + 5C4E8BB62B6EEEE800F148B6 /* iterator.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C4E8BA72B6EEEE800F148B6 /* iterator.h */; }; + 5C4E8BB72B6EEEE800F148B6 /* table_builder.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C4E8BA82B6EEEE800F148B6 /* table_builder.h */; }; + 5C4E8BB82B6EEEE800F148B6 /* env.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C4E8BA92B6EEEE800F148B6 /* env.h */; }; + 5C4E8BB92B6EEEE800F148B6 /* comparator.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C4E8BAA2B6EEEE800F148B6 /* comparator.h */; }; + 5C4E8BBA2B6EEEE800F148B6 /* c.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C4E8BAB2B6EEEE800F148B6 /* c.h */; }; + 5C4E8BBB2B6EEEE800F148B6 /* options.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C4E8BAC2B6EEEE800F148B6 /* options.h */; }; + 5C4E8BBC2B6EEEE800F148B6 /* table.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C4E8BAD2B6EEEE800F148B6 /* table.h */; }; + 5C4E8BBD2B6EEEE800F148B6 /* cache.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C4E8BAE2B6EEEE800F148B6 /* cache.h */; }; + 5C4E8BBE2B6EEEE800F148B6 /* dumpfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C4E8BAF2B6EEEE800F148B6 /* dumpfile.h */; }; + 5C4E8BBF2B6EEEE800F148B6 /* db.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C4E8BB02B6EEEE800F148B6 /* db.h */; }; + 5C4E8BC42B6EF65E00F148B6 /* libleveldb.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C4E8BC32B6EF65E00F148B6 /* libleveldb.a */; }; + 5C4E8BC72B6EF98800F148B6 /* DB.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C4E8BC62B6EF98800F148B6 /* DB.swift */; }; + 5C4E8BE92B71031A00F148B6 /* Kit.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C4E8BE82B7102A700F148B6 /* Kit.h */; settings = {ATTRIBUTES = (Private, ); }; }; 5C5647F82A3F6B100098FFE9 /* Telemetry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C5647F72A3F6B100098FFE9 /* Telemetry.swift */; }; 5C621D822B4770D6004ED7AF /* process.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C621D812B4770D6004ED7AF /* process.swift */; }; 5C8E001029269C7F0027C75A /* protocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CFE493829265055000F2856 /* protocol.swift */; }; @@ -37,7 +56,7 @@ 5CF2211B2B1F8CEF006C583F /* notifications.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CF2211A2B1F8CEF006C583F /* notifications.swift */; }; 5CFE492A29264DF1000F2856 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CFE492929264DF1000F2856 /* main.swift */; }; 5CFE493929265055000F2856 /* protocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CFE493829265055000F2856 /* protocol.swift */; }; - 5CFE493D2926513E000F2856 /* eu.exelban.Stats.SMC.Helper in CopyFiles */ = {isa = PBXBuildFile; fileRef = 5CFE492729264DF1000F2856 /* eu.exelban.Stats.SMC.Helper */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; + 5CFE493D2926513E000F2856 /* eu.exelban.Stats.SMC.Helper in Copy Files */ = {isa = PBXBuildFile; fileRef = 5CFE492729264DF1000F2856 /* eu.exelban.Stats.SMC.Helper */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; 5CFE494229265418000F2856 /* uninstall.sh in Resources */ = {isa = PBXBuildFile; fileRef = 5CFE494129265418000F2856 /* uninstall.sh */; }; 5CFE494429265421000F2856 /* changelog.py in Resources */ = {isa = PBXBuildFile; fileRef = 5CFE494329265421000F2856 /* changelog.py */; }; 5EE8037F29C36BDD0063D37D /* portal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5EE8037E29C36BDD0063D37D /* portal.swift */; }; @@ -316,14 +335,15 @@ ); runOnlyForDeploymentPostprocessing = 1; }; - 5CFE493C29265130000F2856 /* CopyFiles */ = { + 5CFE493C29265130000F2856 /* Copy Files */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; dstPath = Contents/Library/LaunchServices; dstSubfolderSpec = 1; files = ( - 5CFE493D2926513E000F2856 /* eu.exelban.Stats.SMC.Helper in CopyFiles */, + 5CFE493D2926513E000F2856 /* eu.exelban.Stats.SMC.Helper in Copy Files */, ); + name = "Copy Files"; runOnlyForDeploymentPostprocessing = 0; }; 9A46BF89266D7CFA001A1117 /* CopyFiles */ = { @@ -404,6 +424,26 @@ 5C23BC0929A0EDA300DBA990 /* portal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = portal.swift; sourceTree = ""; }; 5C23BC0B29A10BE000DBA990 /* portal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = portal.swift; sourceTree = ""; }; 5C23BC0F29A3B5AE00DBA990 /* portal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = portal.swift; sourceTree = ""; }; + 5C4E8B9F2B6EEE6D00F148B6 /* lldb.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = lldb.h; sourceTree = ""; }; + 5C4E8BA02B6EEE8E00F148B6 /* lldb.m */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; path = lldb.m; sourceTree = ""; }; + 5C4E8BA22B6EEEE800F148B6 /* filter_policy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = filter_policy.h; sourceTree = ""; }; + 5C4E8BA32B6EEEE800F148B6 /* export.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = export.h; sourceTree = ""; }; + 5C4E8BA42B6EEEE800F148B6 /* slice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = slice.h; sourceTree = ""; }; + 5C4E8BA52B6EEEE800F148B6 /* write_batch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = write_batch.h; sourceTree = ""; }; + 5C4E8BA62B6EEEE800F148B6 /* status.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = status.h; sourceTree = ""; }; + 5C4E8BA72B6EEEE800F148B6 /* iterator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iterator.h; sourceTree = ""; }; + 5C4E8BA82B6EEEE800F148B6 /* table_builder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = table_builder.h; sourceTree = ""; }; + 5C4E8BA92B6EEEE800F148B6 /* env.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = env.h; sourceTree = ""; }; + 5C4E8BAA2B6EEEE800F148B6 /* comparator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = comparator.h; sourceTree = ""; }; + 5C4E8BAB2B6EEEE800F148B6 /* c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = c.h; sourceTree = ""; }; + 5C4E8BAC2B6EEEE800F148B6 /* options.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = options.h; sourceTree = ""; }; + 5C4E8BAD2B6EEEE800F148B6 /* table.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = table.h; sourceTree = ""; }; + 5C4E8BAE2B6EEEE800F148B6 /* cache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cache.h; sourceTree = ""; }; + 5C4E8BAF2B6EEEE800F148B6 /* dumpfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dumpfile.h; sourceTree = ""; }; + 5C4E8BB02B6EEEE800F148B6 /* db.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = db.h; sourceTree = ""; }; + 5C4E8BC32B6EF65E00F148B6 /* libleveldb.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libleveldb.a; sourceTree = ""; }; + 5C4E8BC62B6EF98800F148B6 /* DB.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DB.swift; sourceTree = ""; }; + 5C4E8BE82B7102A700F148B6 /* Kit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Kit.h; sourceTree = ""; }; 5C5647F72A3F6B100098FFE9 /* Telemetry.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Telemetry.swift; sourceTree = ""; }; 5C621D812B4770D6004ED7AF /* process.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = process.swift; sourceTree = ""; }; 5C9F90A02A76B30500D41748 /* et */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = et; path = et.lproj/Localizable.strings; sourceTree = ""; }; @@ -614,6 +654,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 5C4E8BC42B6EF65E00F148B6 /* libleveldb.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -710,6 +751,39 @@ path = Clock; sourceTree = ""; }; + 5C4E8B562B6EE10700F148B6 /* lldb */ = { + isa = PBXGroup; + children = ( + 5C4E8BC02B6EEF8C00F148B6 /* include */, + 5C4E8BC32B6EF65E00F148B6 /* libleveldb.a */, + 5C4E8BA02B6EEE8E00F148B6 /* lldb.m */, + 5C4E8B9F2B6EEE6D00F148B6 /* lldb.h */, + ); + path = lldb; + sourceTree = ""; + }; + 5C4E8BC02B6EEF8C00F148B6 /* include */ = { + isa = PBXGroup; + children = ( + 5C4E8BAB2B6EEEE800F148B6 /* c.h */, + 5C4E8BAE2B6EEEE800F148B6 /* cache.h */, + 5C4E8BAA2B6EEEE800F148B6 /* comparator.h */, + 5C4E8BB02B6EEEE800F148B6 /* db.h */, + 5C4E8BAF2B6EEEE800F148B6 /* dumpfile.h */, + 5C4E8BA92B6EEEE800F148B6 /* env.h */, + 5C4E8BA32B6EEEE800F148B6 /* export.h */, + 5C4E8BA22B6EEEE800F148B6 /* filter_policy.h */, + 5C4E8BA72B6EEEE800F148B6 /* iterator.h */, + 5C4E8BAC2B6EEEE800F148B6 /* options.h */, + 5C4E8BA42B6EEEE800F148B6 /* slice.h */, + 5C4E8BA62B6EEEE800F148B6 /* status.h */, + 5C4E8BA82B6EEEE800F148B6 /* table_builder.h */, + 5C4E8BAD2B6EEEE800F148B6 /* table.h */, + 5C4E8BA52B6EEEE800F148B6 /* write_batch.h */, + ); + path = include; + sourceTree = ""; + }; 5CFE492829264DF1000F2856 /* Helper */ = { isa = PBXGroup; children = ( @@ -789,6 +863,7 @@ 9A28498D2666AE3400EC1F6D /* module */, 9AA81547266A9ACA008C01D0 /* plugins */, 9A46BF1E266D6DD0001A1117 /* scripts */, + 5C4E8B562B6EE10700F148B6 /* lldb */, 9A28481B2666AB3500EC1F6D /* constants.swift */, 9A28481A2666AB3500EC1F6D /* extensions.swift */, 9A28481D2666AB3600EC1F6D /* helpers.swift */, @@ -820,6 +895,7 @@ 9A2848642666ABA500EC1F6D /* Supporting Files */ = { isa = PBXGroup; children = ( + 5C4E8BE82B7102A700F148B6 /* Kit.h */, 9A2848882666AC0100EC1F6D /* Assets.xcassets */, 9A28493E2666AD2A00EC1F6D /* Info.plist */, ); @@ -967,6 +1043,7 @@ 9A5A8446271895B700BC40A4 /* Reachability.swift */, 9A302613286A2A3B00B41D57 /* Repeater.swift */, 5C5647F72A3F6B100098FFE9 /* Telemetry.swift */, + 5C4E8BC62B6EF98800F148B6 /* DB.swift */, ); path = plugins; sourceTree = ""; @@ -1076,6 +1153,22 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + 5C4E8BE92B71031A00F148B6 /* Kit.h in Headers */, + 5C4E8BBF2B6EEEE800F148B6 /* db.h in Headers */, + 5C4E8BB12B6EEEE800F148B6 /* filter_policy.h in Headers */, + 5C4E8BBE2B6EEEE800F148B6 /* dumpfile.h in Headers */, + 5C4E8BB42B6EEEE800F148B6 /* write_batch.h in Headers */, + 5C4E8BB62B6EEEE800F148B6 /* iterator.h in Headers */, + 5C4E8BB82B6EEEE800F148B6 /* env.h in Headers */, + 5C4E8BB72B6EEEE800F148B6 /* table_builder.h in Headers */, + 5C4E8BBD2B6EEEE800F148B6 /* cache.h in Headers */, + 5C4E8BBC2B6EEEE800F148B6 /* table.h in Headers */, + 5C4E8BB52B6EEEE800F148B6 /* status.h in Headers */, + 5C4E8BB92B6EEEE800F148B6 /* comparator.h in Headers */, + 5C4E8BBB2B6EEEE800F148B6 /* options.h in Headers */, + 5C4E8BB32B6EEEE800F148B6 /* slice.h in Headers */, + 5C4E8BBA2B6EEEE800F148B6 /* c.h in Headers */, + 5C4E8BB22B6EEEE800F148B6 /* export.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1199,7 +1292,7 @@ 9AECEF3D24ACF98800DB95D4 /* Copy Files */, 9A88E2672659002E00E2B7B0 /* ShellScript */, 9A46BF89266D7CFA001A1117 /* CopyFiles */, - 5CFE493C29265130000F2856 /* CopyFiles */, + 5CFE493C29265130000F2856 /* Copy Files */, ); buildRules = ( ); @@ -1439,7 +1532,7 @@ New, ); LastSwiftUpdateCheck = 1410; - LastUpgradeCheck = 1510; + LastUpgradeCheck = 1520; ORGANIZATIONNAME = "Serhiy Mytrovtsiy"; TargetAttributes = { 5C22299C29CCB3C400F00E69 = { @@ -1770,6 +1863,7 @@ 9A28477A2666AA5000EC1F6D /* settings.swift in Sources */, 9A28475F2666AA2700EC1F6D /* LineChart.swift in Sources */, 9A302614286A2A3B00B41D57 /* Repeater.swift in Sources */, + 5C4E8BA12B6EEE8E00F148B6 /* lldb.m in Sources */, 9A28480E2666AB3000EC1F6D /* Updater.swift in Sources */, 9A5A8447271895B700BC40A4 /* Reachability.swift in Sources */, 9A2847622666AA2700EC1F6D /* Label.swift in Sources */, @@ -1781,6 +1875,7 @@ 9A2847632666AA2700EC1F6D /* Mini.swift in Sources */, 5CF2210D2B1E7EAF006C583F /* notifications.swift in Sources */, 9A6EEBBE2685259500897371 /* Logger.swift in Sources */, + 5C4E8BC72B6EF98800F148B6 /* DB.swift in Sources */, 9A2847602666AA2700EC1F6D /* NetworkChart.swift in Sources */, 5C23BC0429A014AC00DBA990 /* portal.swift in Sources */, 9A2847792666AA5000EC1F6D /* module.swift in Sources */, @@ -2497,8 +2592,10 @@ "@executable_path/../Frameworks", "@loader_path/Frameworks", ); + LIBRARY_SEARCH_PATHS = "$(SRCROOT)/Kit/lldb"; MACOSX_DEPLOYMENT_TARGET = 10.15; MARKETING_VERSION = 1.0; + OTHER_LDFLAGS = "-w"; PRODUCT_BUNDLE_IDENTIFIER = eu.exelban.Stats.Kit; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -2532,8 +2629,10 @@ "@executable_path/../Frameworks", "@loader_path/Frameworks", ); + LIBRARY_SEARCH_PATHS = "$(SRCROOT)/Kit/lldb"; MACOSX_DEPLOYMENT_TARGET = 10.15; MARKETING_VERSION = 1.0; + OTHER_LDFLAGS = "-w"; PRODUCT_BUNDLE_IDENTIFIER = eu.exelban.Stats.Kit; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; PROVISIONING_PROFILE_SPECIFIER = ""; diff --git a/Stats.xcodeproj/xcshareddata/xcschemes/SMC.xcscheme b/Stats.xcodeproj/xcshareddata/xcschemes/SMC.xcscheme index 421837a1..9b2fa516 100644 --- a/Stats.xcodeproj/xcshareddata/xcschemes/SMC.xcscheme +++ b/Stats.xcodeproj/xcshareddata/xcschemes/SMC.xcscheme @@ -1,6 +1,6 @@