diff --git a/patches/mfplat-streaming-support/0009-winegstreamer-Add-a-GstPad-wrapping-the-media-source.patch b/patches/mfplat-streaming-support/0001-winegstreamer-Add-a-GstPad-wrapping-the-media-source.patch similarity index 87% rename from patches/mfplat-streaming-support/0009-winegstreamer-Add-a-GstPad-wrapping-the-media-source.patch rename to patches/mfplat-streaming-support/0001-winegstreamer-Add-a-GstPad-wrapping-the-media-source.patch index 1134f3ca..07e36e44 100644 --- a/patches/mfplat-streaming-support/0009-winegstreamer-Add-a-GstPad-wrapping-the-media-source.patch +++ b/patches/mfplat-streaming-support/0001-winegstreamer-Add-a-GstPad-wrapping-the-media-source.patch @@ -1,18 +1,19 @@ -From 34ca87dde0bd4e3cab92aaf674903791de20bdc0 Mon Sep 17 00:00:00 2001 +From 139b483754aee0188f68109dc593df6eb9e083c4 Mon Sep 17 00:00:00 2001 From: Derek Lesho Date: Mon, 30 Mar 2020 14:19:35 -0500 -Subject: [PATCH 09/54] winegstreamer: Add a GstPad wrapping the media source's +Subject: [PATCH 01/52] winegstreamer: Add a GstPad wrapping the media source's bytestream. Signed-off-by: Derek Lesho --- dlls/winegstreamer/gst_cbs.c | 58 ++++++++ dlls/winegstreamer/gst_cbs.h | 12 +- - dlls/winegstreamer/media_source.c | 237 +++++++++++++++++++++++++++++- - 3 files changed, 302 insertions(+), 5 deletions(-) + dlls/winegstreamer/main.c | 3 + + dlls/winegstreamer/media_source.c | 219 +++++++++++++++++++++++++++++- + 4 files changed, 288 insertions(+), 4 deletions(-) diff --git a/dlls/winegstreamer/gst_cbs.c b/dlls/winegstreamer/gst_cbs.c -index bf7103b160..dfe33dd627 100644 +index bf7103b1606..8f48368c96a 100644 --- a/dlls/winegstreamer/gst_cbs.c +++ b/dlls/winegstreamer/gst_cbs.c @@ -49,6 +49,8 @@ static void CALLBACK perform_cb(TP_CALLBACK_INSTANCE *instance, void *user) @@ -84,9 +85,8 @@ index bf7103b160..dfe33dd627 100644 + + return cbdata.u.event_src_data.ret; +} -\ No newline at end of file diff --git a/dlls/winegstreamer/gst_cbs.h b/dlls/winegstreamer/gst_cbs.h -index 4725f23ad1..10e999feea 100644 +index 4725f23ad1a..10e999feea7 100644 --- a/dlls/winegstreamer/gst_cbs.h +++ b/dlls/winegstreamer/gst_cbs.h @@ -43,7 +43,12 @@ enum CB_TYPE { @@ -121,11 +121,28 @@ index 4725f23ad1..10e999feea 100644 +gboolean process_bytestream_pad_event_wrapper(GstPad *pad, GstObject *parent, GstEvent *event) DECLSPEC_HIDDEN; #endif +diff --git a/dlls/winegstreamer/main.c b/dlls/winegstreamer/main.c +index 2872710b3e2..4ca371d58bd 100644 +--- a/dlls/winegstreamer/main.c ++++ b/dlls/winegstreamer/main.c +@@ -146,6 +146,9 @@ HRESULT WINAPI DllGetClassObject(REFCLSID clsid, REFIID iid, void **out) + + TRACE("clsid %s, iid %s, out %p.\n", debugstr_guid(clsid), debugstr_guid(iid), out); + ++ if (!init_gstreamer()) ++ return CLASS_E_CLASSNOTAVAILABLE; ++ + if (SUCCEEDED(hr = mfplat_get_class_object(clsid, iid, out))) + return hr; + diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c -index 09a40a0620..48119e4a89 100644 +index 84ecf305d4c..6b3bd4a7869 100644 --- a/dlls/winegstreamer/media_source.c +++ b/dlls/winegstreamer/media_source.c -@@ -1,4 +1,9 @@ +@@ -17,7 +17,12 @@ + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" + +#include @@ -135,7 +152,7 @@ index 09a40a0620..48119e4a89 100644 #include -@@ -8,6 +13,7 @@ +@@ -27,6 +32,7 @@ #include "mfapi.h" #include "mferror.h" #include "mfidl.h" @@ -143,32 +160,16 @@ index 09a40a0620..48119e4a89 100644 #include "wine/debug.h" #include "wine/heap.h" -@@ -15,11 +21,24 @@ - - WINE_DEFAULT_DEBUG_CHANNEL(mfplat); - -+static struct source_desc -+{ -+ GstStaticCaps bytestream_caps; -+} source_descs[] = -+{ -+ {/*SOURCE_TYPE_MPEG_4*/ -+ GST_STATIC_CAPS("video/quicktime"), -+ } -+}; -+ - struct media_source - { +@@ -39,6 +45,8 @@ struct media_source IMFMediaSource IMFMediaSource_iface; LONG ref; -+ enum source_type type; IMFMediaEventQueue *event_queue; + IMFByteStream *byte_stream; + GstPad *my_src; enum { SOURCE_OPENING, -@@ -35,6 +54,154 @@ static inline struct media_source *impl_from_IMFMediaSource(IMFMediaSource *ifac +@@ -52,6 +60,154 @@ static inline struct media_source *impl_from_IMFMediaSource(IMFMediaSource *ifac return CONTAINING_RECORD(iface, struct media_source, IMFMediaSource_iface); } @@ -259,12 +260,12 @@ index 09a40a0620..48119e4a89 100644 + } + case GST_QUERY_CAPS: + { ++ GstStaticCaps any = GST_STATIC_CAPS_ANY; + GstCaps *caps, *filter; + ++ caps = gst_static_caps_get(&any); + gst_query_parse_caps(query, &filter); + -+ caps = gst_static_caps_get(&source_descs[source->type].bytestream_caps); -+ + if (filter) { + GstCaps* filtered; + filtered = gst_caps_intersect_full( @@ -323,36 +324,28 @@ index 09a40a0620..48119e4a89 100644 static HRESULT WINAPI media_source_QueryInterface(IMFMediaSource *iface, REFIID riid, void **out) { struct media_source *source = impl_from_IMFMediaSource(iface); -@@ -187,13 +354,20 @@ static HRESULT WINAPI media_source_Pause(IMFMediaSource *iface) +@@ -211,8 +367,12 @@ static HRESULT WINAPI media_source_Shutdown(IMFMediaSource *iface) - FIXME("(%p): stub\n", source); + source->state = SOURCE_SHUTDOWN; -+ if (source->state == SOURCE_SHUTDOWN) -+ return MF_E_SHUTDOWN; -+ - return E_NOTIMPL; - } - - static HRESULT media_source_teardown(struct media_source *source) - { + if (source->my_src) + gst_object_unref(GST_OBJECT(source->my_src)); if (source->event_queue) - IMFMediaEventQueue_Release(source->event_queue); + IMFMediaEventQueue_Shutdown(source->event_queue); + if (source->byte_stream) + IMFByteStream_Release(source->byte_stream); return S_OK; } -@@ -227,19 +401,35 @@ static const IMFMediaSourceVtbl IMFMediaSource_vtbl = +@@ -236,19 +396,34 @@ static const IMFMediaSourceVtbl IMFMediaSource_vtbl = - static HRESULT media_source_constructor(IMFByteStream *bytestream, enum source_type type, struct media_source **out_media_source) + static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_source **out_media_source) { + GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE( + "mf_src", + GST_PAD_SRC, + GST_PAD_ALWAYS, -+ source_descs[type].bytestream_caps); ++ GST_STATIC_CAPS_ANY); + struct media_source *object = heap_alloc_zero(sizeof(*object)); HRESULT hr; @@ -362,7 +355,6 @@ index 09a40a0620..48119e4a89 100644 + object->IMFMediaSource_iface.lpVtbl = &IMFMediaSource_vtbl; + object->ref = 1; -+ object->type = type; + object->byte_stream = bytestream; + IMFByteStream_AddRef(bytestream); + @@ -383,21 +375,10 @@ index 09a40a0620..48119e4a89 100644 *out_media_source = object; return S_OK; -@@ -249,6 +439,7 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, enum source_t +@@ -717,3 +892,41 @@ HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj) - media_source_teardown(object); - heap_free(object); -+ *out_media_source = NULL; return hr; } - -@@ -712,4 +903,42 @@ HRESULT container_stream_handler_construct(REFIID riid, void **obj, enum source_ - IMFByteStreamHandler_Release(&this->IMFByteStreamHandler_iface); - - return hr; --} -\ No newline at end of file -+} + +/* helper for callback forwarding */ +void perform_cb_media_source(struct cb_data *cbdata) diff --git a/patches/mfplat-streaming-support/0011-winegstreamer-Use-the-demuxer-to-establish-IMFMediaS.patch b/patches/mfplat-streaming-support/0002-winegstreamer-Use-decodebin-to-initialize-media-stre.patch similarity index 63% rename from patches/mfplat-streaming-support/0011-winegstreamer-Use-the-demuxer-to-establish-IMFMediaS.patch rename to patches/mfplat-streaming-support/0002-winegstreamer-Use-decodebin-to-initialize-media-stre.patch index 07777e5b..74604376 100644 --- a/patches/mfplat-streaming-support/0011-winegstreamer-Use-the-demuxer-to-establish-IMFMediaS.patch +++ b/patches/mfplat-streaming-support/0002-winegstreamer-Use-decodebin-to-initialize-media-stre.patch @@ -1,24 +1,38 @@ -From ebb9f982f78533993b773b896cf8b542a301b104 Mon Sep 17 00:00:00 2001 +From 27ea26494dfa10570c1d2c838660e2169ac9add3 Mon Sep 17 00:00:00 2001 From: Derek Lesho -Date: Mon, 20 Apr 2020 13:02:23 -0500 -Subject: [PATCH] winegstreamer: Use the demuxer to establish IMFMediaStreams. +Date: Tue, 31 Mar 2020 13:34:57 -0500 +Subject: [PATCH 02/52] winegstreamer: Use decodebin to initialize media + streams. Signed-off-by: Derek Lesho --- - dlls/winegstreamer/gst_cbs.c | 44 ++++ - dlls/winegstreamer/gst_cbs.h | 13 + - dlls/winegstreamer/media_source.c | 407 ++++++++++++++++++++++++++++++ - 3 files changed, 464 insertions(+) + dlls/winegstreamer/gst_cbs.c | 45 ++++ + dlls/winegstreamer/gst_cbs.h | 8 + + dlls/winegstreamer/media_source.c | 416 +++++++++++++++++++++++++++++- + 3 files changed, 468 insertions(+), 1 deletion(-) diff --git a/dlls/winegstreamer/gst_cbs.c b/dlls/winegstreamer/gst_cbs.c -index cf49745f1d..d2d36aeb86 100644 +index 8f48368c96a..4755f5b42f1 100644 --- a/dlls/winegstreamer/gst_cbs.c +++ b/dlls/winegstreamer/gst_cbs.c -@@ -372,3 +372,47 @@ GstBusSyncReply watch_source_bus_wrapper(GstBus *bus, GstMessage *message, gpoin +@@ -359,3 +359,48 @@ gboolean process_bytestream_pad_event_wrapper(GstPad *pad, GstObject *parent, Gs - return cbdata.u.watch_bus_data.ret; + return cbdata.u.event_src_data.ret; } + ++GstBusSyncReply watch_source_bus_wrapper(GstBus *bus, GstMessage *message, gpointer user) ++{ ++ struct cb_data cbdata = { WATCH_SOURCE_BUS }; ++ ++ cbdata.u.watch_bus_data.bus = bus; ++ cbdata.u.watch_bus_data.msg = message; ++ cbdata.u.watch_bus_data.user = user; ++ ++ call_cb(&cbdata); ++ ++ return cbdata.u.watch_bus_data.ret; ++} ++ +void source_stream_added_wrapper(GstElement *bin, GstPad *pad, gpointer user) +{ + struct cb_data cbdata = { SOURCE_STREAM_ADDED }; @@ -50,61 +64,36 @@ index cf49745f1d..d2d36aeb86 100644 + + call_cb(&cbdata); +} -+ -+GstFlowReturn stream_new_sample_wrapper(GstElement *appsink, gpointer user) -+{ -+ struct cb_data cbdata = { STREAM_NEW_SAMPLE }; -+ -+ cbdata.u.new_sample_data.appsink = appsink; -+ cbdata.u.new_sample_data.user = user; -+ -+ call_cb(&cbdata); -+ -+ return cbdata.u.new_sample_data.ret; -+} -\ No newline at end of file diff --git a/dlls/winegstreamer/gst_cbs.h b/dlls/winegstreamer/gst_cbs.h -index 0d7acaf0b8..106368a064 100644 +index 10e999feea7..d87cc8c21e9 100644 --- a/dlls/winegstreamer/gst_cbs.h +++ b/dlls/winegstreamer/gst_cbs.h -@@ -49,6 +49,10 @@ enum CB_TYPE { +@@ -48,6 +48,10 @@ enum CB_TYPE { + QUERY_BYTESTREAM, ACTIVATE_BYTESTREAM_PAD_MODE, PROCESS_BYTESTREAM_PAD_EVENT, - WATCH_SOURCE_BUS, ++ WATCH_SOURCE_BUS, + SOURCE_STREAM_ADDED, + SOURCE_STREAM_REMOVED, + SOURCE_ALL_STREAMS, -+ STREAM_NEW_SAMPLE, MEDIA_SOURCE_MAX, }; -@@ -134,6 +138,11 @@ struct cb_data { - GstQuery *query; - gboolean ret; - } query_sink_data; -+ struct new_sample_data { -+ GstElement *appsink; -+ gpointer user; -+ GstFlowReturn ret; -+ } new_sample_data; - } u; - - int finished; -@@ -166,5 +175,9 @@ gboolean query_bytestream_wrapper(GstPad *pad, GstObject *parent, GstQuery *quer +@@ -164,5 +168,9 @@ GstFlowReturn pull_from_bytestream_wrapper(GstPad *pad, GstObject *parent, guint + gboolean query_bytestream_wrapper(GstPad *pad, GstObject *parent, GstQuery *query) DECLSPEC_HIDDEN; gboolean activate_bytestream_pad_mode_wrapper(GstPad *pad, GstObject *parent, GstPadMode mode, gboolean activate) DECLSPEC_HIDDEN; gboolean process_bytestream_pad_event_wrapper(GstPad *pad, GstObject *parent, GstEvent *event) DECLSPEC_HIDDEN; - GstBusSyncReply watch_source_bus_wrapper(GstBus *bus, GstMessage *message, gpointer user) DECLSPEC_HIDDEN; ++GstBusSyncReply watch_source_bus_wrapper(GstBus *bus, GstMessage *message, gpointer user) DECLSPEC_HIDDEN; +void source_stream_added_wrapper(GstElement *bin, GstPad *pad, gpointer user) DECLSPEC_HIDDEN; +void source_stream_removed_wrapper(GstElement *element, GstPad *pad, gpointer user) DECLSPEC_HIDDEN; +void source_all_streams_wrapper(GstElement *element, gpointer user) DECLSPEC_HIDDEN; -+GstFlowReturn stream_new_sample_wrapper(GstElement *appsink, gpointer user) DECLSPEC_HIDDEN; #endif diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c -index e1f5c77375..192550688d 100644 +index 6b3bd4a7869..29af2b72def 100644 --- a/dlls/winegstreamer/media_source.c +++ b/dlls/winegstreamer/media_source.c -@@ -5,6 +5,7 @@ +@@ -24,6 +24,7 @@ #include "gst_private.h" #include "gst_cbs.h" @@ -112,9 +101,9 @@ index e1f5c77375..192550688d 100644 #include #define COBJMACROS -@@ -31,6 +32,26 @@ static struct source_desc - } - }; +@@ -40,21 +41,48 @@ + + WINE_DEFAULT_DEBUG_CHANNEL(mfplat); +struct media_stream +{ @@ -122,16 +111,12 @@ index e1f5c77375..192550688d 100644 + LONG ref; + struct media_source *parent_source; + IMFMediaEventQueue *event_queue; -+ IMFStreamDescriptor *descriptor; + GstElement *appsink; + GstPad *their_src, *my_sink; -+ /* usually reflects state of source */ + enum + { ++ STREAM_STUB, + STREAM_INACTIVE, -+ STREAM_ENABLED, -+ STREAM_PAUSED, -+ STREAM_RUNNING, + STREAM_SHUTDOWN, + } state; +}; @@ -139,8 +124,20 @@ index e1f5c77375..192550688d 100644 struct media_source { IMFMediaSource IMFMediaSource_iface; -@@ -52,13 +73,32 @@ struct media_source - SOURCE_RUNNING, + LONG ref; + IMFMediaEventQueue *event_queue; + IMFByteStream *byte_stream; +- GstPad *my_src; ++ struct media_stream **streams; ++ ULONG stream_count; ++ GstBus *bus; ++ GstElement *container; ++ GstElement *decodebin; ++ GstPad *my_src, *their_sink; + enum + { + SOURCE_OPENING, + SOURCE_STOPPED, SOURCE_SHUTDOWN, } state; + HANDLE all_streams_event; @@ -154,125 +151,39 @@ index e1f5c77375..192550688d 100644 static inline struct media_source *impl_from_IMFMediaSource(IMFMediaSource *iface) { return CONTAINING_RECORD(iface, struct media_source, IMFMediaSource_iface); +@@ -208,6 +236,243 @@ static gboolean process_bytestream_pad_event(GstPad *pad, GstObject *parent, Gst + return TRUE; } -+/* inactive stream sample discarder */ -+static GstFlowReturn stream_new_sample(GstElement *appsink, gpointer user) -+{ -+ struct media_stream *stream = (struct media_stream *) user; -+ GstSample *discard_sample; -+ -+ TRACE("(%p) got sample\n", stream); -+ -+ g_signal_emit_by_name(stream->appsink, "pull-sample", &discard_sample); -+ gst_sample_unref(discard_sample); -+ return GST_FLOW_OK; -+} -+ - GstFlowReturn pull_from_bytestream(GstPad *pad, GstObject *parent, guint64 ofs, guint len, - GstBuffer **buf) - { -@@ -238,6 +278,315 @@ GstBusSyncReply watch_source_bus(GstBus *bus, GstMessage *message, gpointer user - return GST_BUS_PASS; - } - -+static HRESULT media_stream_constructor(struct media_source *source, GstPad *pad, DWORD stream_id, struct media_stream **out_stream); -+static void source_stream_added(GstElement *element, GstPad *pad, gpointer user) ++GstBusSyncReply watch_source_bus(GstBus *bus, GstMessage *message, gpointer user) +{ + struct media_source *source = (struct media_source *) user; -+ struct media_stream **new_stream_array; -+ struct media_stream *stream; -+ gchar *g_stream_id; -+ DWORD stream_id; -+ unsigned int i; ++ gchar *dbg_info = NULL; ++ GError *err = NULL; + -+ /* Most/All seen randomly calculate the initial part of the stream id, the last three digits are the only deterministic part */ -+ g_stream_id = gst_pad_get_stream_id(pad); -+ sscanf(strstr(g_stream_id, "/"), "/%03u", &stream_id); -+ g_free(g_stream_id); ++ TRACE("source %p message type %s\n", source, GST_MESSAGE_TYPE_NAME(message)); + -+ TRACE("stream-id: %u\n", stream_id); -+ -+ /* find existing stream */ -+ for (i = 0; i < source->stream_count; i++) ++ switch (message->type) + { -+ DWORD existing_stream_id; -+ IMFStreamDescriptor *descriptor = source->streams[i]->descriptor; -+ -+ if (FAILED(IMFStreamDescriptor_GetStreamIdentifier(descriptor, &existing_stream_id))) -+ goto leave; -+ -+ if (existing_stream_id == stream_id) -+ { -+ struct media_stream *existing_stream = source->streams[i]; -+ GstPadLinkReturn ret; -+ -+ TRACE("Found existing stream %p\n", existing_stream); -+ -+ if (!existing_stream->my_sink) -+ { -+ ERR("Couldn't find our sink\n"); -+ goto leave; -+ } -+ -+ existing_stream->their_src = pad; -+ gst_pad_set_element_private(pad, existing_stream); -+ -+ if ((ret = gst_pad_link(existing_stream->their_src, existing_stream->my_sink)) != GST_PAD_LINK_OK) -+ { -+ ERR("Error linking demuxer to stream %p, err = %d\n", existing_stream, ret); -+ } -+ gst_element_sync_state_with_parent(existing_stream->appsink); -+ -+ goto leave; -+ } ++ case GST_MESSAGE_ERROR: ++ gst_message_parse_error(message, &err, &dbg_info); ++ ERR("%s: %s\n", GST_OBJECT_NAME(message->src), err->message); ++ ERR("%s\n", dbg_info); ++ g_error_free(err); ++ g_free(dbg_info); ++ break; ++ case GST_MESSAGE_WARNING: ++ gst_message_parse_warning(message, &err, &dbg_info); ++ WARN("%s: %s\n", GST_OBJECT_NAME(message->src), err->message); ++ WARN("%s\n", dbg_info); ++ g_error_free(err); ++ g_free(dbg_info); ++ break; ++ default: ++ break; + } + -+ if (FAILED(media_stream_constructor(source, pad, stream_id, &stream))) -+ { -+ goto leave; -+ } -+ -+ if (!(new_stream_array = heap_realloc(source->streams, (source->stream_count + 1) * (sizeof(*new_stream_array))))) -+ { -+ ERR("Failed to add stream to source\n"); -+ goto leave; -+ } -+ -+ source->streams = new_stream_array; -+ source->streams[source->stream_count++] = stream; -+ -+ leave: -+ return; -+} -+ -+static void source_stream_removed(GstElement *element, GstPad *pad, gpointer user) -+{ -+ struct media_stream *stream; -+ -+ if (gst_pad_get_direction(pad) != GST_PAD_SRC) -+ return; -+ -+ stream = (struct media_stream *) gst_pad_get_element_private(pad); -+ -+ if (stream) -+ { -+ TRACE("Stream %p of Source %p removed\n", stream, stream->parent_source); -+ -+ assert (stream->their_src == pad); -+ -+ gst_pad_unlink(stream->their_src, stream->my_sink); -+ -+ stream->their_src = NULL; -+ gst_pad_set_element_private(pad, NULL); -+ } -+} -+ -+static void source_all_streams(GstElement *element, gpointer user) -+{ -+ struct media_source *source = (struct media_source *) user; -+ -+ SetEvent(source->all_streams_event); ++ return GST_BUS_PASS; +} + +static HRESULT WINAPI media_stream_QueryInterface(IMFMediaStream *iface, REFIID riid, void **out) @@ -318,13 +229,8 @@ index e1f5c77375..192550688d 100644 + + if (!ref) + { -+ if (stream->their_src) -+ gst_object_unref(GST_OBJECT(stream->their_src)); + if (stream->my_sink) + gst_object_unref(GST_OBJECT(stream->my_sink)); -+ -+ if (stream->descriptor) -+ IMFStreamDescriptor_Release(stream->descriptor); + if (stream->event_queue) + IMFMediaEventQueue_Release(stream->event_queue); + if (stream->parent_source) @@ -435,7 +341,8 @@ index e1f5c77375..192550688d 100644 + media_stream_RequestSample +}; + -+static HRESULT media_stream_constructor(struct media_source *source, GstPad *pad, DWORD stream_id, struct media_stream **out_stream) ++/* creates a stub stream */ ++static HRESULT new_media_stream(struct media_source *source, GstPad *pad, DWORD stream_id, struct media_stream **out_stream) +{ + struct media_stream *object = heap_alloc_zero(sizeof(*object)); + HRESULT hr; @@ -449,7 +356,7 @@ index e1f5c77375..192550688d 100644 + object->parent_source = source; + object->their_src = pad; + -+ object->state = STREAM_INACTIVE; ++ object->state = STREAM_STUB; + + if (FAILED(hr = MFCreateEventQueue(&object->event_queue))) + goto fail; @@ -463,19 +370,19 @@ index e1f5c77375..192550688d 100644 + + g_object_set(object->appsink, "emit-signals", TRUE, NULL); + g_object_set(object->appsink, "sync", FALSE, NULL); -+ g_object_set(object->appsink, "async", FALSE, NULL); /* <- This allows us interact with the bin w/o prerolling */ -+ g_signal_connect(object->appsink, "new-sample", G_CALLBACK(stream_new_sample_wrapper), object); ++ g_object_set(object->appsink, "max-buffers", 5, NULL); ++ g_object_set(object->appsink, "wait-on-eos", FALSE, NULL); + + object->my_sink = gst_element_get_static_pad(object->appsink, "sink"); -+ gst_pad_set_element_private(pad, object); ++ gst_pad_set_element_private(object->my_sink, object); + + gst_pad_link(object->their_src, object->my_sink); + + gst_element_sync_state_with_parent(object->appsink); + + TRACE("->(%p)\n", object); -+ + *out_stream = object; ++ + return S_OK; + + fail: @@ -488,20 +395,27 @@ index e1f5c77375..192550688d 100644 static HRESULT WINAPI media_source_QueryInterface(IMFMediaSource *iface, REFIID riid, void **out) { struct media_source *source = impl_from_IMFMediaSource(iface); -@@ -398,6 +747,8 @@ static HRESULT WINAPI media_source_Pause(IMFMediaSource *iface) +@@ -367,13 +632,34 @@ static HRESULT WINAPI media_source_Shutdown(IMFMediaSource *iface) - static HRESULT media_source_teardown(struct media_source *source) - { -+ unsigned int i; + source->state = SOURCE_SHUTDOWN; + ++ if (source->container) ++ { ++ gst_element_set_state(source->container, GST_STATE_NULL); ++ gst_object_unref(GST_OBJECT(source->container)); ++ } + if (source->my_src) gst_object_unref(GST_OBJECT(source->my_src)); - if (source->their_sink) -@@ -412,6 +763,18 @@ static HRESULT media_source_teardown(struct media_source *source) ++ if (source->their_sink) ++ gst_object_unref(GST_OBJECT(source->their_sink)); ++ + if (source->event_queue) + IMFMediaEventQueue_Shutdown(source->event_queue); if (source->byte_stream) IMFByteStream_Release(source->byte_stream); -+ for (i = 0; i < source->stream_count; i++) ++ for (unsigned int i = 0; i < source->stream_count; i++) + { + source->streams[i]->state = STREAM_SHUTDOWN; + IMFMediaStream_Release(&source->streams[i]->IMFMediaStream_iface); @@ -516,29 +430,126 @@ index e1f5c77375..192550688d 100644 return S_OK; } -@@ -464,6 +827,7 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, enum source_t - object->type = type; +@@ -394,6 +680,63 @@ static const IMFMediaSourceVtbl IMFMediaSource_vtbl = + media_source_Shutdown, + }; + ++static void source_stream_added(GstElement *element, GstPad *pad, gpointer user) ++{ ++ struct media_source *source = (struct media_source *) user; ++ struct media_stream **new_stream_array; ++ struct media_stream *stream; ++ gchar *g_stream_id; ++ DWORD stream_id; ++ ++ if (gst_pad_get_direction(pad) != GST_PAD_SRC) ++ return; ++ ++ /* Most/All seen randomly calculate the initial part of the stream id, the last three digits are the only deterministic part */ ++ g_stream_id = GST_PAD_NAME(pad); ++ sscanf(strstr(g_stream_id, "_"), "_%u", &stream_id); ++ ++ TRACE("stream-id: %u\n", stream_id); ++ ++ if (FAILED(new_media_stream(source, pad, stream_id, &stream))) ++ { ++ goto leave; ++ } ++ ++ if (!(new_stream_array = heap_realloc(source->streams, (source->stream_count + 1) * (sizeof(*new_stream_array))))) ++ { ++ ERR("Failed to add stream to source\n"); ++ goto leave; ++ } ++ ++ source->streams = new_stream_array; ++ source->streams[source->stream_count++] = stream; ++ ++ leave: ++ return; ++} ++ ++static void source_stream_removed(GstElement *element, GstPad *pad, gpointer user) ++{ ++ struct media_source *source = (struct media_source *)user; ++ ++ for (unsigned int i = 0; i < source->stream_count; i++) ++ { ++ struct media_stream *stream = source->streams[i]; ++ if (stream->their_src != pad) ++ continue; ++ stream->their_src = NULL; ++ if (stream->state != STREAM_INACTIVE) ++ stream->state = STREAM_INACTIVE; ++ } ++} ++ ++static void source_all_streams(GstElement *element, gpointer user) ++{ ++ struct media_source *source = (struct media_source *) user; ++ ++ SetEvent(source->all_streams_event); ++} ++ + static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_source **out_media_source) + { + GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE( +@@ -404,6 +747,7 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_ + + struct media_source *object = heap_alloc_zero(sizeof(*object)); + HRESULT hr; ++ int ret; + + if (!object) + return E_OUTOFMEMORY; +@@ -412,10 +756,16 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_ + object->ref = 1; object->byte_stream = bytestream; IMFByteStream_AddRef(bytestream); + object->all_streams_event = CreateEventA(NULL, FALSE, FALSE, NULL); if (FAILED(hr = MFCreateEventQueue(&object->event_queue))) goto fail; -@@ -509,6 +873,10 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, enum source_t - } - gst_bin_add(GST_BIN(object->container), object->demuxer); -+ g_signal_connect(object->demuxer, "pad-added", G_CALLBACK(source_stream_added_wrapper), object); -+ g_signal_connect(object->demuxer, "pad-removed", G_CALLBACK(source_stream_removed_wrapper), object); -+ g_signal_connect(object->demuxer, "no-more-pads", G_CALLBACK(source_all_streams_wrapper), object); ++ object->container = gst_bin_new(NULL); ++ object->bus = gst_bus_new(); ++ gst_bus_set_sync_handler(object->bus, watch_source_bus_wrapper, object, NULL); ++ gst_element_set_bus(object->container, object->bus); + - object->their_sink = gst_element_get_static_pad(object->demuxer, "sink"); - - if ((ret = gst_pad_link(object->my_src, object->their_sink)) < 0) -@@ -518,6 +886,21 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, enum source_t - goto fail; - } + object->my_src = gst_pad_new_from_static_template(&src_template, "mf-src"); + gst_pad_set_element_private(object->my_src, object); + gst_pad_set_getrange_function(object->my_src, pull_from_bytestream_wrapper); +@@ -423,6 +773,46 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_ + gst_pad_set_activatemode_function(object->my_src, activate_bytestream_pad_mode_wrapper); + gst_pad_set_event_function(object->my_src, process_bytestream_pad_event_wrapper); ++ object->decodebin = gst_element_factory_make("decodebin", NULL); ++ if (!(object->decodebin)) ++ { ++ WARN("Failed to create decodebin for source\n"); ++ hr = E_OUTOFMEMORY; ++ goto fail; ++ } ++ /* the appsinks determine the maximum amount of buffering instead, this means that if one stream isn't read, a leak will happen, like on windows */ ++ g_object_set(object->decodebin, "max-size-buffers", 0, NULL); ++ g_object_set(object->decodebin, "max-size-time", G_GUINT64_CONSTANT(0), NULL); ++ g_object_set(object->decodebin, "max-size-bytes", 0, NULL); ++ ++ gst_bin_add(GST_BIN(object->container), object->decodebin); ++ ++ g_signal_connect(object->decodebin, "pad-added", G_CALLBACK(source_stream_added_wrapper), object); ++ g_signal_connect(object->decodebin, "pad-removed", G_CALLBACK(source_stream_removed_wrapper), object); ++ g_signal_connect(object->decodebin, "no-more-pads", G_CALLBACK(source_all_streams_wrapper), object); ++ ++ object->their_sink = gst_element_get_static_pad(object->decodebin, "sink"); ++ ++ if ((ret = gst_pad_link(object->my_src, object->their_sink)) < 0) ++ { ++ WARN("Failed to link our bytestream pad to the demuxer input\n"); ++ hr = E_OUTOFMEMORY; ++ goto fail; ++ } ++ + object->state = SOURCE_OPENING; + + gst_element_set_state(object->container, GST_STATE_PAUSED); @@ -551,16 +562,20 @@ index e1f5c77375..192550688d 100644 + } + + WaitForSingleObject(object->all_streams_event, INFINITE); -+ -+ gst_element_set_state(object->container, GST_STATE_READY); + object->state = SOURCE_STOPPED; *out_media_source = object; -@@ -1032,6 +1415,30 @@ void perform_cb_media_source(struct cb_data *cbdata) - cbdata->u.watch_bus_data.ret = watch_source_bus(data->bus, data->msg, data->user); +@@ -923,6 +1313,30 @@ void perform_cb_media_source(struct cb_data *cbdata) + cbdata->u.event_src_data.ret = process_bytestream_pad_event(data->pad, data->parent, data->event); break; } ++ case WATCH_SOURCE_BUS: ++ { ++ struct watch_bus_data *data = &cbdata->u.watch_bus_data; ++ cbdata->u.watch_bus_data.ret = watch_source_bus(data->bus, data->msg, data->user); ++ break; ++ } + case SOURCE_STREAM_ADDED: + { + struct pad_added_data *data = &cbdata->u.pad_added_data; @@ -578,12 +593,6 @@ index e1f5c77375..192550688d 100644 + struct no_more_pads_data *data = &cbdata->u.no_more_pads_data; + source_all_streams(data->element, data->user); + break; -+ } -+ case STREAM_NEW_SAMPLE: -+ { -+ struct new_sample_data *data = &cbdata->u.new_sample_data; -+ cbdata->u.new_sample_data.ret = stream_new_sample(data->appsink, data->user); -+ break; + } default: { diff --git a/patches/mfplat-streaming-support/0003-winegstreamer-Implement-IMFMediaStream-GetStreamDesc.patch b/patches/mfplat-streaming-support/0003-winegstreamer-Implement-IMFMediaStream-GetStreamDesc.patch new file mode 100644 index 00000000..d917c4d2 --- /dev/null +++ b/patches/mfplat-streaming-support/0003-winegstreamer-Implement-IMFMediaStream-GetStreamDesc.patch @@ -0,0 +1,555 @@ +From 2bbf345d820cfb52620bfbde10ce5d920854baf1 Mon Sep 17 00:00:00 2001 +From: Derek Lesho +Date: Tue, 31 Mar 2020 11:11:05 -0500 +Subject: [PATCH 03/52] winegstreamer: Implement + IMFMediaStream::GetStreamDescriptor. + +Signed-off-by: Derek Lesho +--- + dlls/winegstreamer/gst_cbs.c | 13 ++ + dlls/winegstreamer/gst_cbs.h | 8 ++ + dlls/winegstreamer/gst_private.h | 5 + + dlls/winegstreamer/media_source.c | 137 +++++++++++++++++++- + dlls/winegstreamer/mfplat.c | 208 ++++++++++++++++++++++++++++++ + 5 files changed, 368 insertions(+), 3 deletions(-) + +diff --git a/dlls/winegstreamer/gst_cbs.c b/dlls/winegstreamer/gst_cbs.c +index 4755f5b42f1..e56c987eb38 100644 +--- a/dlls/winegstreamer/gst_cbs.c ++++ b/dlls/winegstreamer/gst_cbs.c +@@ -404,3 +404,16 @@ void source_all_streams_wrapper(GstElement *element, gpointer user) + + call_cb(&cbdata); + } ++ ++GstPadProbeReturn caps_listener_wrapper(GstPad *pad, GstPadProbeInfo *info, gpointer user) ++{ ++ struct cb_data cbdata = { STREAM_PAD_EVENT }; ++ ++ cbdata.u.pad_probe_data.pad = pad; ++ cbdata.u.pad_probe_data.info = info; ++ cbdata.u.pad_probe_data.user = user; ++ ++ call_cb(&cbdata); ++ ++ return cbdata.u.pad_probe_data.ret; ++} +diff --git a/dlls/winegstreamer/gst_cbs.h b/dlls/winegstreamer/gst_cbs.h +index d87cc8c21e9..7173c09746e 100644 +--- a/dlls/winegstreamer/gst_cbs.h ++++ b/dlls/winegstreamer/gst_cbs.h +@@ -52,6 +52,7 @@ enum CB_TYPE { + SOURCE_STREAM_ADDED, + SOURCE_STREAM_REMOVED, + SOURCE_ALL_STREAMS, ++ STREAM_PAD_EVENT, + MEDIA_SOURCE_MAX, + }; + +@@ -137,6 +138,12 @@ struct cb_data { + GstQuery *query; + gboolean ret; + } query_sink_data; ++ struct pad_probe_data { ++ GstPad *pad; ++ GstPadProbeInfo *info; ++ gpointer user; ++ GstPadProbeReturn ret; ++ } pad_probe_data; + } u; + + int finished; +@@ -172,5 +179,6 @@ GstBusSyncReply watch_source_bus_wrapper(GstBus *bus, GstMessage *message, gpoin + void source_stream_added_wrapper(GstElement *bin, GstPad *pad, gpointer user) DECLSPEC_HIDDEN; + void source_stream_removed_wrapper(GstElement *element, GstPad *pad, gpointer user) DECLSPEC_HIDDEN; + void source_all_streams_wrapper(GstElement *element, gpointer user) DECLSPEC_HIDDEN; ++GstPadProbeReturn caps_listener_wrapper(GstPad *pad, GstPadProbeInfo *info, gpointer user); + + #endif +diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h +index ef07d3591e7..86392eea4e3 100644 +--- a/dlls/winegstreamer/gst_private.h ++++ b/dlls/winegstreamer/gst_private.h +@@ -36,6 +36,7 @@ + #include "winuser.h" + #include "dshow.h" + #include "strmif.h" ++#include "mfobjects.h" + #include "wine/heap.h" + #include "wine/strmbase.h" + +@@ -54,6 +55,10 @@ void start_dispatch_thread(void) DECLSPEC_HIDDEN; + + extern HRESULT mfplat_get_class_object(REFCLSID rclsid, REFIID riid, void **obj) DECLSPEC_HIDDEN; + ++HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj) DECLSPEC_HIDDEN; ++GstCaps *make_mf_compatible_caps(GstCaps *caps); ++IMFMediaType *mf_media_type_from_caps(GstCaps *caps); ++ + HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj) DECLSPEC_HIDDEN; + + #endif /* __GST_PRIVATE_INCLUDED__ */ +diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c +index 29af2b72def..345b1fe4528 100644 +--- a/dlls/winegstreamer/media_source.c ++++ b/dlls/winegstreamer/media_source.c +@@ -47,14 +47,19 @@ struct media_stream + LONG ref; + struct media_source *parent_source; + IMFMediaEventQueue *event_queue; ++ IMFStreamDescriptor *descriptor; + GstElement *appsink; + GstPad *their_src, *my_sink; ++ GstCaps *their_caps; + enum + { + STREAM_STUB, + STREAM_INACTIVE, + STREAM_SHUTDOWN, + } state; ++ /* used when in STUB state: */ ++ DWORD stream_id; ++ HANDLE caps_event; + }; + + struct media_source +@@ -312,6 +317,8 @@ static ULONG WINAPI media_stream_Release(IMFMediaStream *iface) + { + if (stream->my_sink) + gst_object_unref(GST_OBJECT(stream->my_sink)); ++ if (stream->descriptor) ++ IMFStreamDescriptor_Release(stream->descriptor); + if (stream->event_queue) + IMFMediaEventQueue_Release(stream->event_queue); + if (stream->parent_source) +@@ -393,7 +400,10 @@ static HRESULT WINAPI media_stream_GetStreamDescriptor(IMFMediaStream* iface, IM + if (stream->state == STREAM_SHUTDOWN) + return MF_E_SHUTDOWN; + +- return E_NOTIMPL; ++ IMFStreamDescriptor_AddRef(stream->descriptor); ++ *descriptor = stream->descriptor; ++ ++ return S_OK; + } + + static HRESULT WINAPI media_stream_RequestSample(IMFMediaStream *iface, IUnknown *token) +@@ -436,9 +446,12 @@ static HRESULT new_media_stream(struct media_source *source, GstPad *pad, DWORD + IMFMediaSource_AddRef(&source->IMFMediaSource_iface); + object->parent_source = source; + object->their_src = pad; ++ object->stream_id = stream_id; + + object->state = STREAM_STUB; + ++ object->caps_event = CreateEventA(NULL, TRUE, FALSE, NULL); ++ + if (FAILED(hr = MFCreateEventQueue(&object->event_queue))) + goto fail; + +@@ -455,10 +468,10 @@ static HRESULT new_media_stream(struct media_source *source, GstPad *pad, DWORD + g_object_set(object->appsink, "wait-on-eos", FALSE, NULL); + + object->my_sink = gst_element_get_static_pad(object->appsink, "sink"); +- gst_pad_set_element_private(object->my_sink, object); +- + gst_pad_link(object->their_src, object->my_sink); + ++ gst_pad_add_probe(object->my_sink, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM, caps_listener_wrapper, object, NULL); ++ + gst_element_sync_state_with_parent(object->appsink); + + TRACE("->(%p)\n", object); +@@ -473,6 +486,43 @@ static HRESULT new_media_stream(struct media_source *source, GstPad *pad, DWORD + return hr; + } + ++static HRESULT media_stream_init_desc(struct media_stream *stream) ++{ ++ HRESULT hr; ++ IMFMediaTypeHandler *type_handler; ++ IMFMediaType *stream_type = NULL; ++ ++ stream->their_caps = gst_caps_fixate(stream->their_caps); ++ ++ stream_type = mf_media_type_from_caps(stream->their_caps); ++ gst_caps_unref(stream->their_caps); ++ if (!stream_type) ++ { ++ hr = E_FAIL; ++ goto fail; ++ } ++ ++ if (FAILED(hr = MFCreateStreamDescriptor(stream->stream_id, 1, &stream_type, &stream->descriptor))) ++ goto fail; ++ ++ if (FAILED(hr = IMFStreamDescriptor_GetMediaTypeHandler(stream->descriptor, &type_handler))) ++ goto fail; ++ ++ if (FAILED(hr = IMFMediaTypeHandler_SetCurrentMediaType(type_handler, stream_type))) ++ goto fail; ++ ++ IMFMediaTypeHandler_Release(type_handler); ++ ++ stream->state = STREAM_INACTIVE; ++ ++ return S_OK; ++ fail: ++ ERR("media stream initialization failed with %x\n", hr); ++ if (type_handler) ++ IMFMediaTypeHandler_Release(type_handler); ++ return hr; ++} ++ + static HRESULT WINAPI media_source_QueryInterface(IMFMediaSource *iface, REFIID riid, void **out) + { + struct media_source *source = impl_from_IMFMediaSource(iface); +@@ -680,6 +730,23 @@ static const IMFMediaSourceVtbl IMFMediaSource_vtbl = + media_source_Shutdown, + }; + ++/* If this callback is extended to use any significant win32 APIs, a wrapper function ++ should be added */ ++gboolean stream_found(GstElement *bin, GstPad *pad, GstCaps *caps, gpointer user) ++{ ++ GstCaps *target_caps; ++ ++ /* if the stream can be converted into an MF compatible type, we'll go that route ++ otherwise, we'll rely on decodebin for the whole process */ ++ ++ if ((target_caps = make_mf_compatible_caps(caps))) ++ { ++ gst_caps_unref(target_caps); ++ return FALSE; ++ } ++ return TRUE; ++} ++ + static void source_stream_added(GstElement *element, GstPad *pad, gpointer user) + { + struct media_source *source = (struct media_source *) user; +@@ -697,6 +764,36 @@ static void source_stream_added(GstElement *element, GstPad *pad, gpointer user) + + TRACE("stream-id: %u\n", stream_id); + ++ /* This codepath is currently never triggered, as we don't need to ever restart the gstreamer pipeline. It is retained in ++ case this becomes necessary in the future, for example in a case where different media types require different ++ post-processing elements. */ ++ for (unsigned int i = 0; i < source->stream_count; i++) ++ { ++ DWORD existing_stream_id; ++ IMFStreamDescriptor *descriptor = source->streams[i]->descriptor; ++ ++ if (source->streams[i]->state == STREAM_STUB) ++ continue; ++ ++ if (FAILED(IMFStreamDescriptor_GetStreamIdentifier(descriptor, &existing_stream_id))) ++ goto leave; ++ ++ if (existing_stream_id == stream_id) ++ { ++ struct media_stream *existing_stream = source->streams[i]; ++ GstPadLinkReturn ret; ++ ++ TRACE("Found existing stream %p\n", existing_stream); ++ ++ existing_stream->their_src = pad; ++ ++ if ((ret = gst_pad_link(existing_stream->their_src, existing_stream->my_sink)) != GST_PAD_LINK_OK) ++ ERR("Error linking decodebin pad to stream %p, err = %d\n", existing_stream, ret); ++ ++ goto leave; ++ } ++ } ++ + if (FAILED(new_media_stream(source, pad, stream_id, &stream))) + { + goto leave; +@@ -737,6 +834,26 @@ static void source_all_streams(GstElement *element, gpointer user) + SetEvent(source->all_streams_event); + } + ++static GstPadProbeReturn caps_listener(GstPad *pad, GstPadProbeInfo *info, gpointer user) ++{ ++ struct media_stream *stream = (struct media_stream *) user; ++ GstEvent *event = gst_pad_probe_info_get_event(info); ++ ++ if (GST_EVENT_TYPE(event) == GST_EVENT_CAPS) ++ { ++ GstCaps *caps; ++ TRACE("got caps for stream %p\n", stream); ++ ++ gst_event_parse_caps(event, &caps); ++ stream->their_caps = gst_caps_copy(caps); ++ SetEvent(stream->caps_event); ++ ++ return GST_PAD_PROBE_REMOVE; ++ } ++ ++ return GST_PAD_PROBE_OK; ++} ++ + static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_source **out_media_source) + { + GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE( +@@ -787,6 +904,8 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_ + + gst_bin_add(GST_BIN(object->container), object->decodebin); + ++ if(!GetEnvironmentVariableA("MF_DECODE_IN_SOURCE", NULL, 0)) ++ g_signal_connect(object->decodebin, "autoplug-continue", G_CALLBACK(stream_found), object); + g_signal_connect(object->decodebin, "pad-added", G_CALLBACK(source_stream_added_wrapper), object); + g_signal_connect(object->decodebin, "pad-removed", G_CALLBACK(source_stream_removed_wrapper), object); + g_signal_connect(object->decodebin, "no-more-pads", G_CALLBACK(source_all_streams_wrapper), object); +@@ -812,6 +931,12 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_ + } + + WaitForSingleObject(object->all_streams_event, INFINITE); ++ for (unsigned int i = 0; i < object->stream_count; i++) ++ { ++ WaitForSingleObject(object->streams[i]->caps_event, INFINITE); ++ if (FAILED(hr = media_stream_init_desc(object->streams[i]))) ++ goto fail; ++ } + + object->state = SOURCE_STOPPED; + +@@ -1337,6 +1462,12 @@ void perform_cb_media_source(struct cb_data *cbdata) + source_all_streams(data->element, data->user); + break; + } ++ case STREAM_PAD_EVENT: ++ { ++ struct pad_probe_data *data = &cbdata->u.pad_probe_data; ++ cbdata->u.pad_probe_data.ret = caps_listener(data->pad, data->info, data->user); ++ break; ++ } + default: + { + ERR("Wrong callback forwarder called\n"); +diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c +index c996f06211e..3667bc3cc38 100644 +--- a/dlls/winegstreamer/mfplat.c ++++ b/dlls/winegstreamer/mfplat.c +@@ -16,6 +16,11 @@ + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + ++#include "config.h" ++#include ++ ++#include "gst_private.h" ++ + #include + + #include "gst_private.h" +@@ -436,3 +441,206 @@ HRESULT mfplat_get_class_object(REFCLSID rclsid, REFIID riid, void **obj) + + return CLASS_E_CLASSNOTAVAILABLE; + } ++ ++const static struct ++{ ++ const GUID *subtype; ++ GstVideoFormat format; ++} ++uncompressed_formats[] = ++{ ++ {&MFVideoFormat_ARGB32, GST_VIDEO_FORMAT_BGRA}, ++ {&MFVideoFormat_RGB32, GST_VIDEO_FORMAT_BGRx}, ++ {&MFVideoFormat_RGB24, GST_VIDEO_FORMAT_BGR}, ++ {&MFVideoFormat_RGB565, GST_VIDEO_FORMAT_BGR16}, ++ {&MFVideoFormat_RGB555, GST_VIDEO_FORMAT_BGR15}, ++}; ++ ++/* caps will be modified to represent the exact type needed for the format */ ++static IMFMediaType* transform_to_media_type(GstCaps *caps) ++{ ++ IMFMediaType *media_type; ++ GstStructure *info; ++ const char *mime_type; ++ ++ if (TRACE_ON(mfplat)) ++ { ++ gchar *human_readable = gst_caps_to_string(caps); ++ TRACE("caps = %s\n", debugstr_a(human_readable)); ++ g_free(human_readable); ++ } ++ ++ if (FAILED(MFCreateMediaType(&media_type))) ++ { ++ return NULL; ++ } ++ ++ info = gst_caps_get_structure(caps, 0); ++ mime_type = gst_structure_get_name(info); ++ ++ if (!(strncmp(mime_type, "video", 5))) ++ { ++ GstVideoInfo video_info; ++ ++ if (!(gst_video_info_from_caps(&video_info, caps))) ++ { ++ return NULL; ++ } ++ ++ IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video); ++ ++ IMFMediaType_SetUINT64(media_type, &MF_MT_FRAME_SIZE, ((UINT64)video_info.width << 32) | video_info.height); ++ ++ IMFMediaType_SetUINT64(media_type, &MF_MT_FRAME_RATE, ((UINT64)video_info.fps_n << 32) | video_info.fps_d); ++ ++ if (!(strcmp(mime_type, "video/x-raw"))) ++ { ++ GUID fourcc_subtype = MFVideoFormat_Base; ++ unsigned int i; ++ ++ IMFMediaType_SetUINT32(media_type, &MF_MT_COMPRESSED, FALSE); ++ ++ /* First try FOURCC */ ++ if ((fourcc_subtype.Data1 = gst_video_format_to_fourcc(video_info.finfo->format))) ++ { ++ IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &fourcc_subtype); ++ } ++ else ++ { ++ for (i = 0; i < ARRAY_SIZE(uncompressed_formats); i++) ++ { ++ if (uncompressed_formats[i].format == video_info.finfo->format) ++ { ++ IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, uncompressed_formats[i].subtype); ++ break; ++ } ++ } ++ if (i == ARRAY_SIZE(uncompressed_formats)) ++ FIXME("Unrecognized format.\n"); ++ } ++ } ++ else ++ { ++ FIXME("Unrecognized video format %s\n", mime_type); ++ IMFMediaType_Release(media_type); ++ return NULL; ++ } ++ } ++ else if (!(strncmp(mime_type, "audio", 5))) ++ { ++ gint rate, channels, bitrate; ++ guint64 channel_mask; ++ IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio); ++ ++ if (gst_structure_get_int(info, "rate", &rate)) ++ IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, rate); ++ ++ if (gst_structure_get_int(info, "channels", &channels)) ++ IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_NUM_CHANNELS, channels); ++ ++ if (gst_structure_get(info, "channel-mask", GST_TYPE_BITMASK, &channel_mask, NULL)) ++ IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_CHANNEL_MASK, (DWORD)channel_mask); ++ ++ if (gst_structure_get_int(info, "bitrate", &bitrate)) ++ IMFMediaType_SetUINT32(media_type, &MF_MT_AVG_BITRATE, bitrate); ++ ++ if (!(strcmp(mime_type, "audio/x-raw"))) ++ { ++ const char *format; ++ if ((format = gst_structure_get_string(info, "format"))) ++ { ++ char type; ++ unsigned int bits_per_sample; ++ char endian[2]; ++ char new_format[6]; ++ if ((strlen(format) > 5) || (sscanf(format, "%c%u%2c", &type, &bits_per_sample, endian) < 2)) ++ { ++ FIXME("Unhandled audio format %s\n", format); ++ IMFMediaType_Release(media_type); ++ return NULL; ++ } ++ ++ if (type == 'F') ++ { ++ IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFAudioFormat_Float); ++ } ++ else if (type == 'U' || type == 'S') ++ { ++ IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFAudioFormat_PCM); ++ if (bits_per_sample == 8) ++ type = 'U'; ++ else ++ type = 'S'; ++ } ++ else ++ { ++ FIXME("Unrecognized audio format: %s\n", format); ++ IMFMediaType_Release(media_type); ++ return NULL; ++ } ++ ++ IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_BITS_PER_SAMPLE, bits_per_sample); ++ ++ if (endian[0] == 'B') ++ endian[0] = 'L'; ++ ++ sprintf(new_format, "%c%u%.2s", type, bits_per_sample, bits_per_sample > 8 ? endian : 0); ++ gst_caps_set_simple(caps, "format", G_TYPE_STRING, new_format, NULL); ++ } ++ else ++ { ++ ERR("Failed to get audio format\n"); ++ } ++ } ++ else ++ { ++ FIXME("Unrecognized audio format %s\n", mime_type); ++ IMFMediaType_Release(media_type); ++ return NULL; ++ } ++ } ++ else ++ { ++ IMFMediaType_Release(media_type); ++ return NULL; ++ } ++ ++ return media_type; ++} ++ ++/* returns NULL if doesn't match exactly */ ++IMFMediaType *mf_media_type_from_caps(GstCaps *caps) ++{ ++ GstCaps *writeable_caps; ++ IMFMediaType *ret; ++ ++ writeable_caps = gst_caps_copy(caps); ++ ret = transform_to_media_type(writeable_caps); ++ ++ if (!(gst_caps_is_equal(caps, writeable_caps))) ++ { ++ IMFMediaType_Release(ret); ++ ret = NULL; ++ } ++ gst_caps_unref(writeable_caps); ++ return ret; ++} ++ ++GstCaps *make_mf_compatible_caps(GstCaps *caps) ++{ ++ GstCaps *ret; ++ IMFMediaType *media_type; ++ ++ ret = gst_caps_copy(caps); ++ ++ if ((media_type = transform_to_media_type(ret))) ++ IMFMediaType_Release(media_type); ++ ++ if (!media_type) ++ { ++ gst_caps_unref(ret); ++ return NULL; ++ } ++ ++ return ret; ++} +-- +2.28.0 + diff --git a/patches/mfplat-streaming-support/0004-mf-tests-Sink-objects-are-stream-sinks-not-media-sin.patch b/patches/mfplat-streaming-support/0004-mf-tests-Sink-objects-are-stream-sinks-not-media-sin.patch deleted file mode 100644 index cac434c9..00000000 --- a/patches/mfplat-streaming-support/0004-mf-tests-Sink-objects-are-stream-sinks-not-media-sin.patch +++ /dev/null @@ -1,50 +0,0 @@ -From a78920ed5d799815126b294c4ecf0b039cf5671c Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Sergio=20G=C3=B3mez=20Del=20Real?= - -Date: Wed, 1 Apr 2020 16:11:05 -0500 -Subject: [PATCH 04/54] mf/tests: Sink objects are stream sinks, not media - sinks. -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Signed-off-by: Sergio Gómez Del Real ---- - dlls/mf/tests/mf.c | 7 +++++-- - 1 file changed, 5 insertions(+), 2 deletions(-) - -diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c -index aa2c5199b9..9e190388ee 100644 ---- a/dlls/mf/tests/mf.c -+++ b/dlls/mf/tests/mf.c -@@ -1400,6 +1400,7 @@ static void test_topology_loader(void) - IMFPresentationDescriptor *pd; - IMFSourceResolver *resolver; - IMFActivate *sink_activate; -+ IMFStreamSink *stream_sink; - unsigned int count, value; - IMFMediaType *media_type; - IMFStreamDescriptor *sd; -@@ -1512,7 +1513,10 @@ todo_wine - hr = IMFActivate_ActivateObject(sink_activate, &IID_IMFMediaSink, (void **)&sink); - ok(hr == S_OK, "Failed to activate, hr %#x.\n", hr); - -- hr = IMFTopologyNode_SetObject(sink_node, (IUnknown *)sink); -+ hr = IMFMediaSink_GetStreamSinkByIndex(sink, 0, &stream_sink); -+ ok(hr == S_OK, "Failed to get stream sink, hr %#x.\n", hr); -+ -+ hr = IMFTopologyNode_SetObject(sink_node, (IUnknown *)stream_sink); - ok(hr == S_OK, "Failed to set object, hr %#x.\n", hr); - - hr = IMFTopology_GetCount(topology, &count); -@@ -1520,7 +1524,6 @@ todo_wine - ok(count == 0, "Unexpected count %u.\n", count); - - hr = IMFTopoLoader_Load(loader, topology, &full_topology, NULL); --todo_wine - ok(hr == S_OK, "Failed to resolve topology, hr %#x.\n", hr); - ok(full_topology != topology, "Unexpected instance.\n"); - --- -2.28.0 - diff --git a/patches/mfplat-streaming-support/0004-winegstreamer-Insert-parser-into-pipeline-to-rectify.patch b/patches/mfplat-streaming-support/0004-winegstreamer-Insert-parser-into-pipeline-to-rectify.patch new file mode 100644 index 00000000..fd203154 --- /dev/null +++ b/patches/mfplat-streaming-support/0004-winegstreamer-Insert-parser-into-pipeline-to-rectify.patch @@ -0,0 +1,169 @@ +From c8effecf2d89b5169b03f4d71243729b68d4c3ba Mon Sep 17 00:00:00 2001 +From: Derek Lesho +Date: Tue, 31 Mar 2020 15:11:31 -0500 +Subject: [PATCH 04/52] winegstreamer: Insert parser into pipeline to rectify + type differences. + +Signed-off-by: Derek Lesho +--- + dlls/winegstreamer/media_source.c | 130 +++++++++++++++++++++++++++++- + 1 file changed, 127 insertions(+), 3 deletions(-) + +diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c +index 345b1fe4528..f1e8c5799f7 100644 +--- a/dlls/winegstreamer/media_source.c ++++ b/dlls/winegstreamer/media_source.c +@@ -432,6 +432,122 @@ static const IMFMediaStreamVtbl media_stream_vtbl = + media_stream_RequestSample + }; + ++/* There are two paths this function can take. ++ 1) In the first path, we are acting as a real media source, purely demuxing the input data, ++ in whichever format it may be in, and passing it along. However, there can be different ways ++ to interpret the same streams. Subtypes in MF usually carry an implicit meaning, so we define ++ what caps an IMFMediaType corresponds to in mfplat.c, and insert a parser between decodebin ++ and the appsink, which usually can resolve these differences. As an example, MFVideoFormat_H264 ++ implies stream-format=byte-stream, and inserting h264parse can transform stream-format=avc ++ into stream-format=byte-stream. ++ 2) In the second path, we are dealing with x-raw output from decodebin. In this case, we just ++ have to setup a chain of elements which should hopefully allow transformations to any IMFMediaType ++ the user throws at us through gstreamer's caps negotiation.*/ ++static HRESULT media_stream_align_with_mf(struct media_stream *stream) ++{ ++ GstCaps *source_caps = NULL; ++ GstCaps *target_caps = NULL; ++ HRESULT hr = E_FAIL; ++ ++ if (!(source_caps = gst_pad_query_caps(stream->their_src, NULL))) ++ goto done; ++ ++ if (TRACE_ON(mfplat)) ++ { ++ gchar *source_caps_str = gst_caps_to_string(source_caps); ++ TRACE("source caps %s\n", debugstr_a(source_caps_str)); ++ g_free(source_caps_str); ++ } ++ ++ if (!strcmp(gst_structure_get_name(gst_caps_get_structure(source_caps, 0)), "video/x-raw") || ++ !strcmp(gst_structure_get_name(gst_caps_get_structure(source_caps, 0)), "audio/x-raw")) ++ { ++ stream->my_sink = gst_element_get_static_pad(stream->appsink, "sink"); ++ g_object_set(stream->appsink, "caps", source_caps, NULL); ++ assert(gst_pad_link(stream->their_src, stream->my_sink) == GST_PAD_LINK_OK); ++ } ++ else ++ { ++ GstElement *parser = NULL; ++ ++ assert(gst_caps_is_fixed(source_caps)); ++ ++ if (!(target_caps = make_mf_compatible_caps(source_caps))) ++ goto done; ++ ++ if (TRACE_ON(mfplat)) ++ { ++ gchar *target_caps_str = gst_caps_to_string(target_caps); ++ TRACE("target caps %s\n", debugstr_a(target_caps_str)); ++ g_free(target_caps_str); ++ } ++ ++ g_object_set(stream->appsink, "caps", target_caps, NULL); ++ ++ if (!(gst_caps_is_equal(source_caps, target_caps))) ++ { ++ GList *parser_list_one, *parser_list_two; ++ GstElementFactory *parser_factory; ++ ++ parser_list_one = gst_element_factory_list_get_elements(GST_ELEMENT_FACTORY_TYPE_PARSER, 1); ++ ++ parser_list_two = gst_element_factory_list_filter(parser_list_one, source_caps, GST_PAD_SINK, 0); ++ gst_plugin_feature_list_free(parser_list_one); ++ parser_list_one = parser_list_two; ++ ++ parser_list_two = gst_element_factory_list_filter(parser_list_one, target_caps, GST_PAD_SRC, 0); ++ gst_plugin_feature_list_free(parser_list_one); ++ parser_list_one = parser_list_two; ++ ++ if (!(g_list_length(parser_list_one))) ++ { ++ gst_plugin_feature_list_free(parser_list_one); ++ ERR("Failed to find parser for stream\n"); ++ hr = E_FAIL; ++ goto done; ++ } ++ ++ parser_factory = g_list_first(parser_list_one)->data; ++ TRACE("Found parser %s.\n", GST_ELEMENT_NAME(parser_factory)); ++ ++ parser = gst_element_factory_create(parser_factory, NULL); ++ ++ gst_plugin_feature_list_free(parser_list_one); ++ ++ if (!parser) ++ { ++ hr = E_FAIL; ++ goto done; ++ } ++ ++ gst_bin_add(GST_BIN(stream->parent_source->container), parser); ++ ++ assert(gst_pad_link(stream->their_src, gst_element_get_static_pad(parser, "sink")) == GST_PAD_LINK_OK); ++ ++ assert(gst_element_link(parser, stream->appsink)); ++ ++ gst_element_sync_state_with_parent(parser); ++ } ++ else ++ { ++ assert(gst_pad_link(stream->their_src, gst_element_get_static_pad(stream->appsink, "sink")) == GST_PAD_LINK_OK); ++ } ++ ++ stream->my_sink = gst_element_get_static_pad(parser ? parser : stream->appsink, "sink"); ++ } ++ ++ hr = S_OK; ++ ++ done: ++ if (source_caps) ++ gst_caps_unref(source_caps); ++ if (target_caps) ++ gst_caps_unref(target_caps); ++ ++ return hr; ++} ++ ++ + /* creates a stub stream */ + static HRESULT new_media_stream(struct media_source *source, GstPad *pad, DWORD stream_id, struct media_stream **out_stream) + { +@@ -467,8 +583,7 @@ static HRESULT new_media_stream(struct media_source *source, GstPad *pad, DWORD + g_object_set(object->appsink, "max-buffers", 5, NULL); + g_object_set(object->appsink, "wait-on-eos", FALSE, NULL); + +- object->my_sink = gst_element_get_static_pad(object->appsink, "sink"); +- gst_pad_link(object->their_src, object->my_sink); ++ media_stream_align_with_mf(object); + + gst_pad_add_probe(object->my_sink, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM, caps_listener_wrapper, object, NULL); + +@@ -494,7 +609,16 @@ static HRESULT media_stream_init_desc(struct media_stream *stream) + + stream->their_caps = gst_caps_fixate(stream->their_caps); + +- stream_type = mf_media_type_from_caps(stream->their_caps); ++ if (strcmp(gst_structure_get_name(gst_caps_get_structure(stream->their_caps, 0)), "video/x-raw") && ++ strcmp(gst_structure_get_name(gst_caps_get_structure(stream->their_caps, 0)), "audio/x-raw")) ++ { ++ GstCaps *compatible_caps = make_mf_compatible_caps(stream->their_caps); ++ stream_type = mf_media_type_from_caps(compatible_caps); ++ gst_caps_unref(compatible_caps); ++ } ++ else ++ stream_type = mf_media_type_from_caps(stream->their_caps); ++ + gst_caps_unref(stream->their_caps); + if (!stream_type) + { +-- +2.28.0 + diff --git a/patches/mfplat-streaming-support/0005-mf-tests-Add-tests-for-the-topology-loader.patch b/patches/mfplat-streaming-support/0005-mf-tests-Add-tests-for-the-topology-loader.patch deleted file mode 100644 index cd219b86..00000000 --- a/patches/mfplat-streaming-support/0005-mf-tests-Add-tests-for-the-topology-loader.patch +++ /dev/null @@ -1,499 +0,0 @@ -From dfb5190b00ce04f7ac0c811cb6350af37826015e Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Sergio=20G=C3=B3mez=20Del=20Real?= - -Date: Wed, 1 Apr 2020 16:11:06 -0500 -Subject: [PATCH 05/54] mf/tests: Add tests for the topology loader. -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Signed-off-by: Sergio Gómez Del Real ---- - dlls/mf/tests/mf.c | 435 ++++++++++++++++++++++++++++++++++++++++++++- - 1 file changed, 433 insertions(+), 2 deletions(-) - -diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c -index 9e190388ee..8691ef55c9 100644 ---- a/dlls/mf/tests/mf.c -+++ b/dlls/mf/tests/mf.c -@@ -1392,26 +1392,169 @@ static const IMFSampleGrabberSinkCallbackVtbl test_grabber_callback_vtbl = - test_grabber_callback_OnShutdown, - }; - -+static HRESULT WINAPI test_media_source_QueryInterface(IMFMediaSource *iface, REFIID riid, void **out) -+{ -+ if (IsEqualIID(riid, &IID_IMFMediaSource) || -+ IsEqualIID(riid, &IID_IMFMediaEventGenerator) || -+ IsEqualIID(riid, &IID_IUnknown)) -+ { -+ *out = iface; -+ IUnknown_AddRef((IUnknown*)*out); -+ return S_OK; -+ } -+ -+ *out = NULL; -+ return E_NOINTERFACE; -+} -+ -+static ULONG WINAPI test_media_source_AddRef(IMFMediaSource *iface) -+{ -+ return 2; -+} -+ -+static ULONG WINAPI test_media_source_Release(IMFMediaSource *iface) -+{ -+ return 1; -+} -+ -+static HRESULT WINAPI test_media_source_GetEvent(IMFMediaSource *iface, DWORD flags, IMFMediaEvent **event) -+{ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI test_media_source_BeginGetEvent(IMFMediaSource *iface, IMFAsyncCallback *callback, IUnknown *state) -+{ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI test_media_source_EndGetEvent(IMFMediaSource *iface, IMFAsyncResult *result, IMFMediaEvent **event) -+{ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI test_media_source_QueueEvent(IMFMediaSource *iface, MediaEventType event_type, REFGUID ext_type, -+ HRESULT hr, const PROPVARIANT *value) -+{ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI test_media_source_GetCharacteristics(IMFMediaSource *iface, DWORD *characteristics) -+{ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI test_media_source_CreatePresentationDescriptor(IMFMediaSource *iface, IMFPresentationDescriptor **descriptor) -+{ -+ HRESULT hr; -+ -+ IMFPresentationDescriptor *pd; -+ IMFMediaType *mediatypes[3]; -+ IMFStreamDescriptor *sd[2]; -+ -+ if (FAILED(hr = MFCreateMediaType(&mediatypes[0]))) -+ return hr; -+ if (FAILED(hr = IMFMediaType_SetGUID(mediatypes[0], &MF_MT_MAJOR_TYPE, &MFMediaType_Video))) -+ return hr; -+ if (FAILED(hr = IMFMediaType_SetGUID(mediatypes[0], &MF_MT_SUBTYPE, &MFVideoFormat_YUY2))) -+ return hr; -+ if (FAILED(hr = MFCreateMediaType(&mediatypes[1]))) -+ return hr; -+ if (FAILED(hr = IMFMediaType_SetGUID(mediatypes[1], &MF_MT_MAJOR_TYPE, &MFMediaType_Audio))) -+ return hr; -+ if (FAILED(hr = IMFMediaType_SetGUID(mediatypes[1], &MF_MT_SUBTYPE, &MFAudioFormat_MP3))) -+ return hr; -+ if (FAILED(hr = IMFMediaType_SetUINT32(mediatypes[1], &MF_MT_AUDIO_SAMPLES_PER_SECOND, 32000))) -+ return hr; -+ if (FAILED(hr = IMFMediaType_SetUINT32(mediatypes[1], &MF_MT_AUDIO_NUM_CHANNELS, 2))) -+ return hr; -+ if (FAILED(hr = IMFMediaType_SetUINT32(mediatypes[1], &MF_MT_AUDIO_PREFER_WAVEFORMATEX, 1))) -+ return hr; -+ if (FAILED(hr = MFCreateMediaType(&mediatypes[2]))) -+ return hr; -+ if (FAILED(hr = IMFMediaType_SetGUID(mediatypes[2], &MF_MT_MAJOR_TYPE, &MFMediaType_Audio))) -+ return hr; -+ if (FAILED(hr = IMFMediaType_SetGUID(mediatypes[2], &MF_MT_SUBTYPE, &MFAudioFormat_PCM))) -+ return hr; -+ if (FAILED(hr = MFCreateStreamDescriptor(0, 3, mediatypes, &sd[0]))) -+ return hr; -+ if (FAILED(hr = MFCreateStreamDescriptor(1, 3, mediatypes, &sd[1]))) -+ return hr; -+ if (FAILED(hr = MFCreatePresentationDescriptor(2, sd, &pd))) -+ return hr; -+ *descriptor = pd; -+ -+ IMFMediaType_Release(mediatypes[0]); -+ IMFMediaType_Release(mediatypes[1]); -+ IMFMediaType_Release(mediatypes[2]); -+ IMFStreamDescriptor_Release(sd[0]); -+ IMFStreamDescriptor_Release(sd[1]); -+ -+ return S_OK; -+} -+ -+static HRESULT WINAPI test_media_source_Start(IMFMediaSource *iface, IMFPresentationDescriptor *descriptor, -+ const GUID *time_format, const PROPVARIANT *start_position) -+{ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI test_media_source_Stop(IMFMediaSource *iface) -+{ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI test_media_source_Pause(IMFMediaSource *iface) -+{ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI test_media_source_Shutdown(IMFMediaSource *iface) -+{ -+ return S_OK; -+} -+ -+static const IMFMediaSourceVtbl test_media_source_vtbl = -+{ -+ test_media_source_QueryInterface, -+ test_media_source_AddRef, -+ test_media_source_Release, -+ test_media_source_GetEvent, -+ test_media_source_BeginGetEvent, -+ test_media_source_EndGetEvent, -+ test_media_source_QueueEvent, -+ test_media_source_GetCharacteristics, -+ test_media_source_CreatePresentationDescriptor, -+ test_media_source_Start, -+ test_media_source_Stop, -+ test_media_source_Pause, -+ test_media_source_Shutdown, -+}; -+ - static void test_topology_loader(void) - { - IMFSampleGrabberSinkCallback test_grabber_callback = { &test_grabber_callback_vtbl }; -+ IMFMediaSource test_media_source = { &test_media_source_vtbl }; - IMFTopology *topology, *topology2, *full_topology; - IMFTopologyNode *src_node, *sink_node; -+ IMFMediaType *media_type, *current_media_type; - IMFPresentationDescriptor *pd; - IMFSourceResolver *resolver; - IMFActivate *sink_activate; - IMFStreamSink *stream_sink; - unsigned int count, value; -- IMFMediaType *media_type; -+ IMFMediaTypeHandler *mth; - IMFStreamDescriptor *sd; -+ UINT32 enum_src, method; - MF_OBJECT_TYPE obj_type; - IMFMediaSource *source; - IMFTopoLoader *loader; - IMFByteStream *stream; - IMFAttributes *attr; - IMFMediaSink *sink; -+ WORD node_count; - WCHAR *filename; - BOOL selected; -+ DWORD flags; - HRESULT hr; - GUID guid; - -@@ -1527,6 +1670,9 @@ todo_wine - ok(hr == S_OK, "Failed to resolve topology, hr %#x.\n", hr); - ok(full_topology != topology, "Unexpected instance.\n"); - -+ IMFTopology_GetNodeCount(full_topology, &node_count); -+ ok(node_count == 2, "Topology node count is %#x.\n", node_count); -+ - hr = IMFTopology_GetCount(topology, &count); - ok(hr == S_OK, "Failed to get attribute count, hr %#x.\n", hr); - ok(count == 0, "Unexpected count %u.\n", count); -@@ -1553,10 +1699,295 @@ todo_wine { - - IMFTopology_Release(topology2); - IMFTopology_Release(full_topology); -+ IMFByteStream_Release(stream); -+ IMFStreamDescriptor_Release(sd); -+ -+ /* test with stream deselected */ -+ IMFPresentationDescriptor_GetStreamDescriptorCount(pd, &count); -+ ok(count == 1, "Unexpected stream descriptor count.\n"); -+ hr = IMFPresentationDescriptor_DeselectStream(pd, 0); -+ ok(hr == S_OK, "Failed to deselect stream, hr %#x.\n", hr); -+ hr = IMFTopoLoader_Load(loader, topology, &full_topology, NULL); -+ ok(hr == S_OK, "Failed to resolve topology, hr %#x.\n", hr); -+ IMFTopologyNode_Release(src_node); -+ hr = IMFTopology_GetNode(full_topology, 0, &src_node); -+ ok(hr == S_OK, "Failed to get full topology source node, hr %#x.\n", hr); -+ IMFPresentationDescriptor_Release(pd); -+ hr = IMFTopologyNode_GetUnknown(src_node, &MF_TOPONODE_PRESENTATION_DESCRIPTOR, &IID_IMFPresentationDescriptor, (void **)&pd); -+ ok(hr == S_OK, "Failed to get presentation descriptor, hr %#x.\n", hr); -+ IMFStreamDescriptor_Release(sd); -+ IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd, 0, &selected, &sd); -+ ok(hr == S_OK, "Failed to get stream descriptor, hr %#x.\n", hr); -+ ok(!selected, "Stream should not be selected\n."); - -+ IMFPresentationDescriptor_Release(pd); -+ IMFTopologyNode_Release(src_node); -+ IMFTopology_Release(full_topology); -+ IMFTopology_Release(topology); - IMFMediaSource_Release(source); - IMFSourceResolver_Release(resolver); -- IMFByteStream_Release(stream); -+ -+ /* test source stream with various media types */ -+ /* first, test default behavior; MF_TOPOLOGY_ENUMERATE_SOURCE_TYPES not set */ -+ hr = MFCreateTopology(&topology); -+ ok(hr == S_OK, "Failed to create topology, hr %#x.\n", hr); -+ -+ hr = IMFMediaSource_CreatePresentationDescriptor(&test_media_source, &pd); -+ ok(hr == S_OK, "Failed to create descriptor, hr %#x.\n", hr); -+ -+ hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd, 0, &selected, &sd); -+ ok(hr == S_OK, "Failed to get stream descriptor, hr %#x.\n", hr); -+ -+ hr = IMFStreamDescriptor_GetMediaTypeHandler(sd, &mth); -+ ok(hr == S_OK, "Failed to get media type handler, hr %#x.\n", hr); -+ hr = IMFMediaTypeHandler_GetCurrentMediaType(mth, &media_type); -+ ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr); -+ -+ hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &src_node); -+ ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr); -+ -+ hr = IMFTopologyNode_SetUnknown(src_node, &MF_TOPONODE_SOURCE, (IUnknown *)&test_media_source); -+ ok(hr == S_OK, "Failed to set node source, hr %#x.\n", hr); -+ hr = IMFTopologyNode_SetUnknown(src_node, &MF_TOPONODE_PRESENTATION_DESCRIPTOR, (IUnknown *)pd); -+ ok(hr == S_OK, "Failed to set node pd, hr %#x.\n", hr); -+ hr = IMFTopologyNode_SetUnknown(src_node, &MF_TOPONODE_STREAM_DESCRIPTOR, (IUnknown *)sd); -+ ok(hr == S_OK, "Failed to set node sd, hr %#x.\n", hr); -+ -+ hr = IMFTopology_AddNode(topology, src_node); -+ ok(hr == S_OK, "Failed to add a node, hr %#x.\n", hr); -+ -+ hr = MFCreateMediaType(&media_type); -+ ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr); -+ -+ hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio); -+ ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr); -+ hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFAudioFormat_PCM); -+ ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr); -+ -+ hr = MFCreateSampleGrabberSinkActivate(media_type, &test_grabber_callback, &sink_activate); -+ ok(hr == S_OK, "Failed to create grabber sink, hr %#x.\n", hr); -+ IMFMediaType_Release(media_type); -+ -+ hr = IMFActivate_ActivateObject(sink_activate, &IID_IMFMediaSink, (void **)&sink); -+ ok(hr == S_OK, "Failed to activate, hr %#x.\n", hr); -+ -+ hr = IMFMediaSink_GetStreamSinkByIndex(sink, 0, &stream_sink); -+ ok(hr == S_OK, "Failed to get stream sink, hr %#x.\n", hr); -+ -+ hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &sink_node); -+ ok(hr == S_OK, "Failed to create output node, hr %#x.\n", hr); -+ -+ hr = IMFTopologyNode_SetObject(sink_node, (IUnknown *)stream_sink); -+ ok(hr == S_OK, "Failed to set object, hr %#x.\n", hr); -+ -+ hr = IMFTopology_AddNode(topology, sink_node); -+ ok(hr == S_OK, "Failed to add sink node, hr %#x.\n", hr); -+ -+ hr = IMFTopologyNode_ConnectOutput(src_node, 0, sink_node, 0); -+ ok(hr == S_OK, "Failed to connect nodes, hr %#x.\n", hr); -+ -+ hr = IMFTopology_GetUINT32(topology, &MF_TOPOLOGY_ENUMERATE_SOURCE_TYPES, &enum_src); -+ ok(hr == MF_E_ATTRIBUTENOTFOUND, "Attribute should not be set\n."); -+ /* if no current media type set, loader uses first index exclusively */ -+ hr = IMFTopoLoader_Load(loader, topology, &full_topology, NULL); -+todo_wine -+ /* when major types differ, error is MF_E_TOPO_CODEC_NOT_FOUND */ -+ ok(hr == MF_E_TOPO_CODEC_NOT_FOUND, "Unexpected hr %#x.\n", hr); -+ -+ hr = IMFMediaTypeHandler_GetMediaTypeByIndex(mth, 2, &media_type); -+ ok(hr == S_OK, "Failed getting media type, hr %#x.\n", hr); -+ -+ /* setting current media type overrides previous behavior; tries with it, and only with it */ -+ hr = IMFMediaTypeHandler_SetCurrentMediaType(mth, media_type); -+ ok(hr == S_OK, "Failed setting current media type, hr %#x.\n", hr); -+ -+ hr = IMFTopoLoader_Load(loader, topology, &full_topology, NULL); -+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr); -+ -+ hr = IMFTopology_GetNodeCount(full_topology, &node_count); -+ ok(hr == S_OK, "Failed to get node count, hr %#x.\n", hr); -+ ok(node_count == 2, "Unexpected node count.\n"); -+ -+ hr = IMFMediaTypeHandler_GetMediaTypeByIndex(mth, 1, &media_type); -+ ok(hr == S_OK, "Failed getting media type, hr %#x.\n", hr); -+ -+ hr = IMFMediaTypeHandler_SetCurrentMediaType(mth, media_type); -+ ok(hr == S_OK, "Failed setting current media type, hr %#x.\n", hr); -+ -+ hr = IMFTopoLoader_Load(loader, topology, &full_topology, NULL); -+ ok(hr == S_OK, "Failed to resolve topology, hr %#x.\n", hr); -+ -+ hr = IMFTopology_GetNodeCount(full_topology, &node_count); -+ ok(hr == S_OK, "Failed to get node count, hr %#x.\n", hr); -+todo_wine -+ ok(node_count == 3, "Unexpected node count.\n"); -+ -+ IMFTopology_Release(full_topology); -+ -+ /* now test with MF_TOPOLOGY_ENUMERATE_SOURCE_TYPES set on topology */ -+ hr = IMFTopology_SetUINT32(topology, &MF_TOPOLOGY_ENUMERATE_SOURCE_TYPES, 1); -+ ok(hr == S_OK, "Failed setting attribute\n."); -+ hr = IMFMediaTypeHandler_GetMediaTypeByIndex(mth, 2, &media_type); -+ ok(hr == S_OK, "Failed getting media type, hr %#x.\n", hr); -+ -+ /* first, if MF_CONNECT_RESOLVE_INDEPENDENT_OUTPUTTYPES is not set on source */ -+ IMFTopologyNode_GetUINT32(src_node, &MF_TOPONODE_CONNECT_METHOD, &method); -+ ok(hr == S_OK, "Attribute should be set\n."); -+ IMFTopologyNode_SetUINT32(src_node, &MF_TOPONODE_CONNECT_METHOD, method & ~MF_CONNECT_RESOLVE_INDEPENDENT_OUTPUTTYPES); -+ ok(hr == S_OK, "Failed setting attribute %#x\n.", hr); -+ -+ hr = IMFTopoLoader_Load(loader, topology, &full_topology, NULL); -+ ok(hr == S_OK, "Failed to resolve topology, hr %#x.\n", hr); -+ -+ hr = IMFTopology_GetNodeCount(full_topology, &node_count); -+ ok(hr == S_OK, "Failed to get node count, hr %#x.\n", hr); -+ ok(node_count == 2, "Unexpected node count.\n"); -+ IMFTopologyNode_Release(src_node); -+ hr = IMFTopology_GetNode(full_topology, 0, &src_node); -+ ok(hr == S_OK, "Failed to get node, hr %#x.\n", hr); -+ IMFStreamDescriptor_Release(sd); -+ hr = IMFTopologyNode_GetUnknown(src_node, &MF_TOPONODE_STREAM_DESCRIPTOR, &IID_IMFStreamDescriptor, (void **)&sd); -+ ok(hr == S_OK, "Failed to get stream descriptor, hr %#x.\n", hr); -+ IMFMediaTypeHandler_Release(mth); -+ hr = IMFStreamDescriptor_GetMediaTypeHandler(sd, &mth); -+ ok(hr == S_OK, "Failed to get media type handler, hr %#x.\n", hr); -+ hr = IMFMediaTypeHandler_GetCurrentMediaType(mth, ¤t_media_type); -+ ok(hr == S_OK, "Failed to get current media type, hr %#x.\n", hr); -+ hr = IMFMediaType_IsEqual(current_media_type, media_type, &flags); -+todo_wine { -+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr); -+ ok(flags & MF_MEDIATYPE_EQUAL_FORMAT_DATA, "Types should be equal.\n"); -+} -+ -+ IMFMediaType_Release(media_type); -+ IMFMediaType_Release(current_media_type); -+ IMFMediaTypeHandler_Release(mth); -+ IMFStreamSink_Release(stream_sink); -+ IMFMediaSink_Release(sink); -+ IMFActivate_Release(sink_activate); -+ IMFStreamDescriptor_Release(sd); -+ -+ /* add second branch with a valid first branch */ -+ hr = IMFTopology_SetUINT32(topology, &MF_TOPOLOGY_ENUMERATE_SOURCE_TYPES, 0); -+ ok(hr == S_OK, "Failed setting attribute\n."); -+ IMFTopologyNode_Release(src_node); -+ hr = IMFTopology_GetNode(topology, 0, &src_node); -+ ok(hr == S_OK, "Failed to get node, hr %#x.\n", hr); -+ hr = IMFTopologyNode_GetUnknown(src_node, &MF_TOPONODE_STREAM_DESCRIPTOR, &IID_IMFStreamDescriptor, (void **)&sd); -+ ok(hr == S_OK, "Failed to get stream descriptor, hr %#x.\n", hr); -+ hr = IMFStreamDescriptor_GetMediaTypeHandler(sd, &mth); -+ ok(hr == S_OK, "Failed to get media type handler, hr %#x.\n", hr); -+ hr = IMFMediaTypeHandler_GetMediaTypeByIndex(mth, 1, &media_type); -+ ok(hr == S_OK, "Failed getting media type, hr %#x.\n", hr); -+ hr = IMFMediaTypeHandler_SetCurrentMediaType(mth, media_type); -+ ok(hr == S_OK, "Failed setting current media type, hr %#x.\n", hr); -+ -+ hr = IMFTopoLoader_Load(loader, topology, &full_topology, NULL); -+ ok(hr == S_OK, "Failed to resolve topology, hr %#x.\n", hr); -+ -+ IMFTopology_Release(full_topology); -+ -+ IMFStreamDescriptor_Release(sd); -+ hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd, 1, &selected, &sd); -+ ok(hr == S_OK, "Failed to get stream descriptor, hr %#x.\n", hr); -+ -+ hr = IMFStreamDescriptor_GetMediaTypeHandler(sd, &mth); -+ ok(hr == S_OK, "Failed to get media type handler, hr %#x.\n", hr); -+ hr = IMFMediaTypeHandler_GetCurrentMediaType(mth, &media_type); -+ ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr); -+ -+ IMFTopologyNode_Release(src_node); -+ hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &src_node); -+ ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr); -+ -+ hr = IMFTopologyNode_SetUnknown(src_node, &MF_TOPONODE_SOURCE, (IUnknown *)&test_media_source); -+ ok(hr == S_OK, "Failed to set node source, hr %#x.\n", hr); -+ hr = IMFTopologyNode_SetUnknown(src_node, &MF_TOPONODE_PRESENTATION_DESCRIPTOR, (IUnknown *)pd); -+ ok(hr == S_OK, "Failed to set node pd, hr %#x.\n", hr); -+ hr = IMFTopologyNode_SetUnknown(src_node, &MF_TOPONODE_STREAM_DESCRIPTOR, (IUnknown *)sd); -+ ok(hr == S_OK, "Failed to set node sd, hr %#x.\n", hr); -+ -+ hr = IMFTopology_AddNode(topology, src_node); -+ ok(hr == S_OK, "Failed to add a node, hr %#x.\n", hr); -+ -+ hr = MFCreateMediaType(&media_type); -+ ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr); -+ -+ hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio); -+ ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr); -+ hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFAudioFormat_PCM); -+ ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr); -+ -+ hr = MFCreateSampleGrabberSinkActivate(media_type, &test_grabber_callback, &sink_activate); -+ ok(hr == S_OK, "Failed to create grabber sink, hr %#x.\n", hr); -+ IMFMediaType_Release(media_type); -+ -+ hr = IMFActivate_ActivateObject(sink_activate, &IID_IMFMediaSink, (void **)&sink); -+ ok(hr == S_OK, "Failed to activate, hr %#x.\n", hr); -+ -+ hr = IMFMediaSink_GetStreamSinkByIndex(sink, 0, &stream_sink); -+ ok(hr == S_OK, "Failed to get stream sink, hr %#x.\n", hr); -+ -+ hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &sink_node); -+ ok(hr == S_OK, "Failed to create output node, hr %#x.\n", hr); -+ -+ hr = IMFTopologyNode_SetObject(sink_node, (IUnknown *)stream_sink); -+ ok(hr == S_OK, "Failed to set object, hr %#x.\n", hr); -+ -+ hr = IMFTopology_AddNode(topology, sink_node); -+ ok(hr == S_OK, "Failed to add sink node, hr %#x.\n", hr); -+ -+ hr = IMFTopology_GetNodeCount(topology, &node_count); -+ ok(hr == S_OK, "Failed to get node count, hr %#x.\n", hr); -+ ok(node_count == 4, "Unexpected node count.\n"); -+ -+ hr = IMFTopoLoader_Load(loader, topology, &full_topology, NULL); -+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr); -+ -+ /* unconnected nodes in partial topology are discarded */ -+ hr = IMFTopology_GetNodeCount(full_topology, &node_count); -+ ok(hr == S_OK, "Failed to get node count, hr %#x.\n", hr); -+todo_wine -+ ok(node_count == 3, "Unexpected node count %d.\n", node_count); -+ -+ IMFTopology_Release(full_topology); -+ -+ /* connect nodes for second branch */ -+ hr = IMFTopologyNode_ConnectOutput(src_node, 0, sink_node, 0); -+ ok(hr == S_OK, "Failed to connect nodes, hr %#x.\n", hr); -+ -+ /* all branches must have valid media types */ -+ hr = IMFTopoLoader_Load(loader, topology, &full_topology, NULL); -+todo_wine -+ ok(hr == MF_E_TOPO_CODEC_NOT_FOUND, "Unexpected hr %#x.\n", hr); -+ -+ /* set valid media type for second branch */ -+ hr = IMFMediaTypeHandler_GetMediaTypeByIndex(mth, 1, &media_type); -+ ok(hr == S_OK, "Failed getting media type, hr %#x.\n", hr); -+ -+ hr = IMFMediaTypeHandler_SetCurrentMediaType(mth, media_type); -+ ok(hr == S_OK, "Failed setting current media type, hr %#x.\n", hr); -+ -+ hr = IMFTopoLoader_Load(loader, topology, &full_topology, NULL); -+ ok(hr == S_OK, "Failed to resolve topology, hr %#x.\n", hr); -+ -+ hr = IMFTopology_GetNodeCount(full_topology, &node_count); -+ ok(hr == S_OK, "Failed to get node count, hr %#x.\n", hr); -+todo_wine -+ ok(node_count == 6, "Unexpected node count %d.\n", node_count); -+ -+ IMFTopology_Release(full_topology); -+ IMFMediaType_Release(media_type); -+ IMFTopologyNode_Release(src_node); -+ IMFTopologyNode_Release(sink_node); -+ IMFMediaTypeHandler_Release(mth); -+ IMFStreamSink_Release(stream_sink); -+ IMFMediaSink_Release(sink); -+ IMFActivate_Release(sink_activate); -+ IMFStreamDescriptor_Release(sd); -+ -+ IMFPresentationDescriptor_Release(pd); -+ IMFTopology_Release(topology); - IMFTopoLoader_Release(loader); - - hr = MFShutdown(); --- -2.28.0 - diff --git a/patches/mfplat-streaming-support/0005-winegstreamer-Insert-videoconvert-into-decoded-video.patch b/patches/mfplat-streaming-support/0005-winegstreamer-Insert-videoconvert-into-decoded-video.patch new file mode 100644 index 00000000..1c5e6795 --- /dev/null +++ b/patches/mfplat-streaming-support/0005-winegstreamer-Insert-videoconvert-into-decoded-video.patch @@ -0,0 +1,164 @@ +From 862d76c09ef0005d40e63b271a03c98874f78828 Mon Sep 17 00:00:00 2001 +From: Derek Lesho +Date: Tue, 25 Aug 2020 17:35:49 -0500 +Subject: [PATCH 05/52] winegstreamer: Insert videoconvert into decoded-video + streams. + +Signed-off-by: Derek Lesho +--- + dlls/winegstreamer/media_source.c | 104 ++++++++++++++++++++++++++---- + 1 file changed, 91 insertions(+), 13 deletions(-) + +diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c +index f1e8c5799f7..209753608b6 100644 +--- a/dlls/winegstreamer/media_source.c ++++ b/dlls/winegstreamer/media_source.c +@@ -459,8 +459,22 @@ static HRESULT media_stream_align_with_mf(struct media_stream *stream) + g_free(source_caps_str); + } + +- if (!strcmp(gst_structure_get_name(gst_caps_get_structure(source_caps, 0)), "video/x-raw") || +- !strcmp(gst_structure_get_name(gst_caps_get_structure(source_caps, 0)), "audio/x-raw")) ++ if (!strcmp(gst_structure_get_name(gst_caps_get_structure(source_caps, 0)), "video/x-raw")) ++ { ++ GstElement *videoconvert = gst_element_factory_make("videoconvert", NULL); ++ ++ gst_bin_add(GST_BIN(stream->parent_source->container), videoconvert); ++ ++ stream->my_sink = gst_element_get_static_pad(videoconvert, "sink"); ++ ++ assert(gst_pad_link(stream->their_src, stream->my_sink) == GST_PAD_LINK_OK); ++ assert(gst_element_link(videoconvert, stream->appsink)); ++ ++ gst_element_sync_state_with_parent(videoconvert); ++ ++ g_object_set(stream->appsink, "caps", source_caps, NULL); ++ } ++ else if(!strcmp(gst_structure_get_name(gst_caps_get_structure(source_caps, 0)), "audio/x-raw")) + { + stream->my_sink = gst_element_get_static_pad(stream->appsink, "sink"); + g_object_set(stream->appsink, "caps", source_caps, NULL); +@@ -605,45 +619,109 @@ static HRESULT media_stream_init_desc(struct media_stream *stream) + { + HRESULT hr; + IMFMediaTypeHandler *type_handler; ++ IMFMediaType **stream_types = NULL; + IMFMediaType *stream_type = NULL; ++ DWORD type_count = 0; ++ unsigned int i; + + stream->their_caps = gst_caps_fixate(stream->their_caps); + +- if (strcmp(gst_structure_get_name(gst_caps_get_structure(stream->their_caps, 0)), "video/x-raw") && +- strcmp(gst_structure_get_name(gst_caps_get_structure(stream->their_caps, 0)), "audio/x-raw")) ++ if (!strcmp(gst_structure_get_name(gst_caps_get_structure(stream->their_caps, 0)), "video/x-raw")) + { +- GstCaps *compatible_caps = make_mf_compatible_caps(stream->their_caps); +- stream_type = mf_media_type_from_caps(compatible_caps); +- gst_caps_unref(compatible_caps); ++ GstElementFactory *videoconvert_factory = gst_element_factory_find("videoconvert"); ++ /* output every format supported by videoconvert */ ++ const GList *template_list = gst_element_factory_get_static_pad_templates(videoconvert_factory); ++ for (;template_list; template_list = template_list->next) ++ { ++ GstStaticPadTemplate *template = (GstStaticPadTemplate *)template_list->data; ++ GstCaps *src_caps; ++ GValueArray *formats; ++ if (template->direction != GST_PAD_SRC) ++ continue; ++ src_caps = gst_static_pad_template_get_caps(template); ++ gst_structure_get_list(gst_caps_get_structure(src_caps, 0), "format", &formats); ++ type_count = formats->n_values; ++ stream_types = heap_alloc( sizeof(IMFMediaType*) * type_count ); ++ for (i = 0; i < formats->n_values; i++) ++ { ++ GValue *format = g_value_array_get_nth(formats, i); ++ GstCaps *modified_caps = gst_caps_copy(stream->their_caps); ++ gst_caps_set_value(modified_caps, "format", format); ++ stream_types[i] = mf_media_type_from_caps(modified_caps); ++ gst_caps_unref(modified_caps); ++ if (!stream_types[i]) ++ { ++ i--; ++ type_count--; ++ } ++ } ++ g_value_array_free(formats); ++ gst_caps_unref(src_caps); ++ break; ++ } + } +- else ++ else if (!strcmp(gst_structure_get_name(gst_caps_get_structure(stream->their_caps, 0)), "audio/x-raw")) ++ { + stream_type = mf_media_type_from_caps(stream->their_caps); ++ if (stream_type) ++ { ++ stream_types = &stream_type; ++ type_count = 1; ++ } ++ } ++ else ++ { ++ GstCaps *compatible_caps = make_mf_compatible_caps(stream->their_caps); ++ if (compatible_caps) ++ { ++ stream_type = mf_media_type_from_caps(compatible_caps); ++ gst_caps_unref(compatible_caps); ++ if (stream_type) ++ { ++ stream_types = &stream_type; ++ type_count = 1; ++ } ++ } ++ } + + gst_caps_unref(stream->their_caps); +- if (!stream_type) ++ ++ if (!type_count) + { ++ ERR("Failed to establish an IMFMediaType from any of the possible stream caps!\n"); + hr = E_FAIL; + goto fail; + } + +- if (FAILED(hr = MFCreateStreamDescriptor(stream->stream_id, 1, &stream_type, &stream->descriptor))) ++ if (FAILED(hr = MFCreateStreamDescriptor(stream->stream_id, type_count, stream_types, &stream->descriptor))) + goto fail; + + if (FAILED(hr = IMFStreamDescriptor_GetMediaTypeHandler(stream->descriptor, &type_handler))) + goto fail; + +- if (FAILED(hr = IMFMediaTypeHandler_SetCurrentMediaType(type_handler, stream_type))) ++ if (FAILED(hr = IMFMediaTypeHandler_SetCurrentMediaType(type_handler, stream_types[0]))) + goto fail; + +- IMFMediaTypeHandler_Release(type_handler); +- + stream->state = STREAM_INACTIVE; + ++ IMFMediaTypeHandler_Release(type_handler); ++ for (i = 0; i < type_count; i++) ++ IMFMediaType_Release(stream_types[i]); ++ if (stream_types != &stream_type) ++ heap_free(stream_types); ++ + return S_OK; + fail: + ERR("media stream initialization failed with %x\n", hr); + if (type_handler) + IMFMediaTypeHandler_Release(type_handler); ++ if (stream_types) ++ { ++ for (i = 0; i < type_count; i++) ++ IMFMediaType_Release(stream_types[i]); ++ if (stream_types != &stream_type) ++ heap_free(stream_types); ++ } + return hr; + } + +-- +2.28.0 + diff --git a/patches/mfplat-streaming-support/0006-winegstreamer-Insert-audioconvert-into-decoded-audio.patch b/patches/mfplat-streaming-support/0006-winegstreamer-Insert-audioconvert-into-decoded-audio.patch new file mode 100644 index 00000000..de51b7f4 --- /dev/null +++ b/patches/mfplat-streaming-support/0006-winegstreamer-Insert-audioconvert-into-decoded-audio.patch @@ -0,0 +1,39 @@ +From 35f58b2470a342db3fe665549ac1983b4877157a Mon Sep 17 00:00:00 2001 +From: Derek Lesho +Date: Tue, 25 Aug 2020 17:37:28 -0500 +Subject: [PATCH 06/52] winegstreamer: Insert audioconvert into decoded audio + streams. + +Signed-off-by: Derek Lesho +--- + dlls/winegstreamer/media_source.c | 13 +++++++++++-- + 1 file changed, 11 insertions(+), 2 deletions(-) + +diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c +index 209753608b6..66cfdbdc0fd 100644 +--- a/dlls/winegstreamer/media_source.c ++++ b/dlls/winegstreamer/media_source.c +@@ -476,9 +476,18 @@ static HRESULT media_stream_align_with_mf(struct media_stream *stream) + } + else if(!strcmp(gst_structure_get_name(gst_caps_get_structure(source_caps, 0)), "audio/x-raw")) + { +- stream->my_sink = gst_element_get_static_pad(stream->appsink, "sink"); +- g_object_set(stream->appsink, "caps", source_caps, NULL); ++ GstElement *audioconvert = gst_element_factory_make("audioconvert", NULL); ++ ++ gst_bin_add(GST_BIN(stream->parent_source->container), audioconvert); ++ ++ stream->my_sink = gst_element_get_static_pad(audioconvert, "sink"); ++ + assert(gst_pad_link(stream->their_src, stream->my_sink) == GST_PAD_LINK_OK); ++ assert(gst_element_link(audioconvert, stream->appsink)); ++ ++ gst_element_sync_state_with_parent(audioconvert); ++ ++ g_object_set(stream->appsink, "caps", source_caps, NULL); + } + else + { +-- +2.28.0 + diff --git a/patches/mfplat-streaming-support/0013-winegstreamer-Translate-H.264-caps-to-attributes.patch b/patches/mfplat-streaming-support/0007-winegstreamer-Translate-H.264-caps-to-attributes.patch similarity index 89% rename from patches/mfplat-streaming-support/0013-winegstreamer-Translate-H.264-caps-to-attributes.patch rename to patches/mfplat-streaming-support/0007-winegstreamer-Translate-H.264-caps-to-attributes.patch index ce3de3dd..7e8562ac 100644 --- a/patches/mfplat-streaming-support/0013-winegstreamer-Translate-H.264-caps-to-attributes.patch +++ b/patches/mfplat-streaming-support/0007-winegstreamer-Translate-H.264-caps-to-attributes.patch @@ -1,15 +1,15 @@ -From 483ebc1d94c11b675fa17d22c7b5fe04d3d3381f Mon Sep 17 00:00:00 2001 +From 0cb401346e8c106fad5cf1cd4d9364e7508d282b Mon Sep 17 00:00:00 2001 From: Derek Lesho Date: Tue, 24 Mar 2020 16:00:26 -0500 -Subject: [PATCH] winegstreamer: Translate H.264 caps to attributes. +Subject: [PATCH 07/52] winegstreamer: Translate H.264 caps to attributes. Signed-off-by: Derek Lesho --- - dlls/winegstreamer/mfplat.c | 68 +++++++++++++++++++++++++++++++++++++ - 1 file changed, 68 insertions(+) + dlls/winegstreamer/mfplat.c | 67 +++++++++++++++++++++++++++++++++++++ + 1 file changed, 67 insertions(+) diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c -index 90eb583c4a..e0ef5e16db 100644 +index 3667bc3cc38..77a2dad093a 100644 --- a/dlls/winegstreamer/mfplat.c +++ b/dlls/winegstreamer/mfplat.c @@ -26,6 +26,7 @@ @@ -20,14 +20,13 @@ index 90eb583c4a..e0ef5e16db 100644 #include "wine/debug.h" #include "wine/heap.h" -@@ -525,6 +526,73 @@ static IMFMediaType* transform_to_media_type(GstCaps *caps) +@@ -519,6 +520,72 @@ static IMFMediaType* transform_to_media_type(GstCaps *caps) FIXME("Unrecognized format.\n"); } } + else if (!(strcmp(mime_type, "video/x-h264"))) + { + const char *profile, *level; -+ unsigned int i; + + IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFVideoFormat_H264); + IMFMediaType_SetUINT32(media_type, &MF_MT_COMPRESSED, TRUE); @@ -85,15 +84,15 @@ index 90eb583c4a..e0ef5e16db 100644 + } + gst_caps_set_simple(caps, "stream-format", G_TYPE_STRING, "byte-stream", NULL); + gst_caps_set_simple(caps, "alignment", G_TYPE_STRING, "au", NULL); -+ for (i = 0; i < gst_caps_get_size(caps); i++) ++ for (unsigned int i = 0; i < gst_caps_get_size(caps); i++) + { + GstStructure *structure = gst_caps_get_structure (caps, i); + gst_structure_remove_field(structure, "codec_data"); + } + } else + { FIXME("Unrecognized video format %s\n", mime_type); - } -- 2.28.0 diff --git a/patches/mfplat-streaming-support/0014-winegstreamer-Translate-WMV-caps-to-attributes.patch b/patches/mfplat-streaming-support/0008-winegstreamer-Translate-WMV-caps-to-attributes.patch similarity index 90% rename from patches/mfplat-streaming-support/0014-winegstreamer-Translate-WMV-caps-to-attributes.patch rename to patches/mfplat-streaming-support/0008-winegstreamer-Translate-WMV-caps-to-attributes.patch index 6105110a..5a693bac 100644 --- a/patches/mfplat-streaming-support/0014-winegstreamer-Translate-WMV-caps-to-attributes.patch +++ b/patches/mfplat-streaming-support/0008-winegstreamer-Translate-WMV-caps-to-attributes.patch @@ -1,7 +1,7 @@ -From 3c23e1570ad895c52069c895a3e50353730d20c1 Mon Sep 17 00:00:00 2001 +From 966b172363a8a3e22f9f5585cd41590f6c799b36 Mon Sep 17 00:00:00 2001 From: Derek Lesho Date: Tue, 24 Mar 2020 16:01:20 -0500 -Subject: [PATCH 14/54] winegstreamer: Translate WMV caps to attributes. +Subject: [PATCH 08/52] winegstreamer: Translate WMV caps to attributes. Signed-off-by: Derek Lesho --- @@ -9,10 +9,10 @@ Signed-off-by: Derek Lesho 1 file changed, 51 insertions(+) diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c -index 1b37e1cc90..96195c887c 100644 +index 77a2dad093a..3963d97041d 100644 --- a/dlls/winegstreamer/mfplat.c +++ b/dlls/winegstreamer/mfplat.c -@@ -463,6 +463,24 @@ uncompressed_formats[] = +@@ -457,6 +457,24 @@ uncompressed_formats[] = {&MFVideoFormat_RGB555, GST_VIDEO_FORMAT_BGR15}, }; @@ -37,7 +37,7 @@ index 1b37e1cc90..96195c887c 100644 /* caps will be modified to represent the exact type needed for the format */ static IMFMediaType* transform_to_media_type(GstCaps *caps) { -@@ -592,6 +610,39 @@ static IMFMediaType* transform_to_media_type(GstCaps *caps) +@@ -586,6 +604,39 @@ static IMFMediaType* transform_to_media_type(GstCaps *caps) gst_structure_remove_field(structure, "codec_data"); } } @@ -75,8 +75,8 @@ index 1b37e1cc90..96195c887c 100644 + codec_data_to_user_data(info, media_type); + } else + { FIXME("Unrecognized video format %s\n", mime_type); - } -- 2.28.0 diff --git a/patches/mfplat-streaming-support/0015-winegstreamer-Translate-AAC-caps-to-attributes.patch b/patches/mfplat-streaming-support/0009-winegstreamer-Translate-AAC-caps-to-attributes.patch similarity index 91% rename from patches/mfplat-streaming-support/0015-winegstreamer-Translate-AAC-caps-to-attributes.patch rename to patches/mfplat-streaming-support/0009-winegstreamer-Translate-AAC-caps-to-attributes.patch index c285e817..889a2849 100644 --- a/patches/mfplat-streaming-support/0015-winegstreamer-Translate-AAC-caps-to-attributes.patch +++ b/patches/mfplat-streaming-support/0009-winegstreamer-Translate-AAC-caps-to-attributes.patch @@ -1,18 +1,18 @@ -From 13019300d005d7bcea386435894841a7154231e9 Mon Sep 17 00:00:00 2001 +From 8cf90bd8896f33646211c5ca6b2b18930789a2b2 Mon Sep 17 00:00:00 2001 From: Derek Lesho Date: Tue, 24 Mar 2020 16:02:27 -0500 -Subject: [PATCH 15/54] winegstreamer: Translate AAC caps to attributes. +Subject: [PATCH 09/52] winegstreamer: Translate AAC caps to attributes. Signed-off-by: Derek Lesho --- - dlls/winegstreamer/mfplat.c | 107 ++++++++++++++++++++++++++++++++++++ - 1 file changed, 107 insertions(+) + dlls/winegstreamer/mfplat.c | 108 ++++++++++++++++++++++++++++++++++++ + 1 file changed, 108 insertions(+) diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c -index 96195c887c..ecb5de8b88 100644 +index 3963d97041d..4cff74f2d41 100644 --- a/dlls/winegstreamer/mfplat.c +++ b/dlls/winegstreamer/mfplat.c -@@ -463,6 +463,15 @@ uncompressed_formats[] = +@@ -457,6 +457,15 @@ uncompressed_formats[] = {&MFVideoFormat_RGB555, GST_VIDEO_FORMAT_BGR15}, }; @@ -28,7 +28,7 @@ index 96195c887c..ecb5de8b88 100644 static void codec_data_to_user_data(GstStructure *structure, IMFMediaType *type) { const GValue *codec_data; -@@ -708,6 +717,104 @@ static IMFMediaType* transform_to_media_type(GstCaps *caps) +@@ -710,6 +719,105 @@ static IMFMediaType* transform_to_media_type(GstCaps *caps) ERR("Failed to get audio format\n"); } } @@ -52,6 +52,7 @@ index 96195c887c..ecb5de8b88 100644 + struct aac_user_data *user_data = NULL; + + IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFAudioFormat_AAC); ++ IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_BITS_PER_SAMPLE, 16); + + codec_data = gst_structure_get_value(info, "codec_data"); + if (codec_data) @@ -131,8 +132,8 @@ index 96195c887c..ecb5de8b88 100644 + } + } else + { FIXME("Unrecognized audio format %s\n", mime_type); - } -- 2.28.0 diff --git a/patches/mfplat-streaming-support/0010-winegstreamer-Find-an-appropriate-demuxer-for-the-so.patch b/patches/mfplat-streaming-support/0010-winegstreamer-Find-an-appropriate-demuxer-for-the-so.patch deleted file mode 100644 index 32052cd8..00000000 --- a/patches/mfplat-streaming-support/0010-winegstreamer-Find-an-appropriate-demuxer-for-the-so.patch +++ /dev/null @@ -1,221 +0,0 @@ -From 42170f6bd111e333694f4122e38944c5f87ac1f2 Mon Sep 17 00:00:00 2001 -From: Derek Lesho -Date: Tue, 31 Mar 2020 13:34:57 -0500 -Subject: [PATCH 10/54] winegstreamer: Find an appropriate demuxer for the - source. - -We can add a path later which uses decodebin as the demuxer, for use with formats not supported on windows. (like Theora) - -Signed-off-by: Derek Lesho ---- - dlls/winegstreamer/gst_cbs.c | 15 ++++- - dlls/winegstreamer/gst_cbs.h | 2 + - dlls/winegstreamer/media_source.c | 99 ++++++++++++++++++++++++++++++- - 3 files changed, 114 insertions(+), 2 deletions(-) - -diff --git a/dlls/winegstreamer/gst_cbs.c b/dlls/winegstreamer/gst_cbs.c -index dfe33dd627..cf49745f1d 100644 ---- a/dlls/winegstreamer/gst_cbs.c -+++ b/dlls/winegstreamer/gst_cbs.c -@@ -358,4 +358,17 @@ gboolean process_bytestream_pad_event_wrapper(GstPad *pad, GstObject *parent, Gs - call_cb(&cbdata); - - return cbdata.u.event_src_data.ret; --} -\ No newline at end of file -+} -+ -+GstBusSyncReply watch_source_bus_wrapper(GstBus *bus, GstMessage *message, gpointer user) -+{ -+ struct cb_data cbdata = { WATCH_SOURCE_BUS }; -+ -+ cbdata.u.watch_bus_data.bus = bus; -+ cbdata.u.watch_bus_data.msg = message; -+ cbdata.u.watch_bus_data.user = user; -+ -+ call_cb(&cbdata); -+ -+ return cbdata.u.watch_bus_data.ret; -+} -diff --git a/dlls/winegstreamer/gst_cbs.h b/dlls/winegstreamer/gst_cbs.h -index 10e999feea..0d7acaf0b8 100644 ---- a/dlls/winegstreamer/gst_cbs.h -+++ b/dlls/winegstreamer/gst_cbs.h -@@ -48,6 +48,7 @@ enum CB_TYPE { - QUERY_BYTESTREAM, - ACTIVATE_BYTESTREAM_PAD_MODE, - PROCESS_BYTESTREAM_PAD_EVENT, -+ WATCH_SOURCE_BUS, - MEDIA_SOURCE_MAX, - }; - -@@ -164,5 +165,6 @@ GstFlowReturn pull_from_bytestream_wrapper(GstPad *pad, GstObject *parent, guint - gboolean query_bytestream_wrapper(GstPad *pad, GstObject *parent, GstQuery *query) DECLSPEC_HIDDEN; - gboolean activate_bytestream_pad_mode_wrapper(GstPad *pad, GstObject *parent, GstPadMode mode, gboolean activate) DECLSPEC_HIDDEN; - gboolean process_bytestream_pad_event_wrapper(GstPad *pad, GstObject *parent, GstEvent *event) DECLSPEC_HIDDEN; -+GstBusSyncReply watch_source_bus_wrapper(GstBus *bus, GstMessage *message, gpointer user) DECLSPEC_HIDDEN; - - #endif -diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c -index 48119e4a89..e1f5c77375 100644 ---- a/dlls/winegstreamer/media_source.c -+++ b/dlls/winegstreamer/media_source.c -@@ -38,7 +38,12 @@ struct media_source - enum source_type type; - IMFMediaEventQueue *event_queue; - IMFByteStream *byte_stream; -- GstPad *my_src; -+ struct media_stream **streams; -+ ULONG stream_count; -+ GstBus *bus; -+ GstElement *container; -+ GstElement *demuxer; -+ GstPad *my_src, *their_sink; - enum - { - SOURCE_OPENING, -@@ -202,6 +207,37 @@ static gboolean process_bytestream_pad_event(GstPad *pad, GstObject *parent, Gst - return TRUE; - } - -+GstBusSyncReply watch_source_bus(GstBus *bus, GstMessage *message, gpointer user) -+{ -+ struct media_source *source = (struct media_source *) user; -+ gchar *dbg_info = NULL; -+ GError *err = NULL; -+ -+ TRACE("source %p message type %s\n", source, GST_MESSAGE_TYPE_NAME(message)); -+ -+ switch (message->type) -+ { -+ case GST_MESSAGE_ERROR: -+ gst_message_parse_error(message, &err, &dbg_info); -+ ERR("%s: %s\n", GST_OBJECT_NAME(message->src), err->message); -+ ERR("%s\n", dbg_info); -+ g_error_free(err); -+ g_free(dbg_info); -+ break; -+ case GST_MESSAGE_WARNING: -+ gst_message_parse_warning(message, &err, &dbg_info); -+ WARN("%s: %s\n", GST_OBJECT_NAME(message->src), err->message); -+ WARN("%s\n", dbg_info); -+ g_error_free(err); -+ g_free(dbg_info); -+ break; -+ default: -+ break; -+ } -+ -+ return GST_BUS_PASS; -+} -+ - static HRESULT WINAPI media_source_QueryInterface(IMFMediaSource *iface, REFIID riid, void **out) - { - struct media_source *source = impl_from_IMFMediaSource(iface); -@@ -364,6 +400,13 @@ static HRESULT media_source_teardown(struct media_source *source) - { - if (source->my_src) - gst_object_unref(GST_OBJECT(source->my_src)); -+ if (source->their_sink) -+ gst_object_unref(GST_OBJECT(source->their_sink)); -+ if (source->container) -+ { -+ gst_element_set_state(source->container, GST_STATE_NULL); -+ gst_object_unref(GST_OBJECT(source->container)); -+ } - if (source->event_queue) - IMFMediaEventQueue_Release(source->event_queue); - if (source->byte_stream) -@@ -408,7 +451,10 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, enum source_t - source_descs[type].bytestream_caps); - - struct media_source *object = heap_alloc_zero(sizeof(*object)); -+ GList *demuxer_list_one, *demuxer_list_two; -+ GstElementFactory *demuxer_factory = NULL; - HRESULT hr; -+ int ret; - - if (!object) - return E_OUTOFMEMORY; -@@ -422,6 +468,11 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, enum source_t - if (FAILED(hr = MFCreateEventQueue(&object->event_queue))) - goto fail; - -+ object->container = gst_bin_new(NULL); -+ object->bus = gst_bus_new(); -+ gst_bus_set_sync_handler(object->bus, watch_source_bus_wrapper, object, NULL); -+ gst_element_set_bus(object->container, object->bus); -+ - object->my_src = gst_pad_new_from_static_template(&src_template, "mf-src"); - gst_pad_set_element_private(object->my_src, object); - gst_pad_set_getrange_function(object->my_src, pull_from_bytestream_wrapper); -@@ -429,6 +480,44 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, enum source_t - gst_pad_set_activatemode_function(object->my_src, activate_bytestream_pad_mode_wrapper); - gst_pad_set_event_function(object->my_src, process_bytestream_pad_event_wrapper); - -+ /* Find demuxer */ -+ demuxer_list_one = gst_element_factory_list_get_elements(GST_ELEMENT_FACTORY_TYPE_DEMUXER, 1); -+ -+ demuxer_list_two = gst_element_factory_list_filter(demuxer_list_one, gst_static_caps_get(&source_descs[type].bytestream_caps), GST_PAD_SINK, 0); -+ gst_plugin_feature_list_free(demuxer_list_one); -+ -+ if (!(g_list_length(demuxer_list_two))) -+ { -+ ERR("Failed to find demuxer for source.\n"); -+ gst_plugin_feature_list_free(demuxer_list_two); -+ hr = E_FAIL; -+ goto fail; -+ } -+ -+ demuxer_factory = g_list_first(demuxer_list_two)->data; -+ gst_object_ref(demuxer_factory); -+ gst_plugin_feature_list_free(demuxer_list_two); -+ -+ TRACE("Found demuxer %s.\n", GST_ELEMENT_NAME(demuxer_factory)); -+ -+ object->demuxer = gst_element_factory_create(demuxer_factory, NULL); -+ if (!(object->demuxer)) -+ { -+ WARN("Failed to create demuxer for source\n"); -+ hr = E_OUTOFMEMORY; -+ goto fail; -+ } -+ gst_bin_add(GST_BIN(object->container), object->demuxer); -+ -+ object->their_sink = gst_element_get_static_pad(object->demuxer, "sink"); -+ -+ if ((ret = gst_pad_link(object->my_src, object->their_sink)) < 0) -+ { -+ WARN("Failed to link our bytestream pad to the demuxer input\n"); -+ hr = E_OUTOFMEMORY; -+ goto fail; -+ } -+ - object->state = SOURCE_STOPPED; - - *out_media_source = object; -@@ -437,6 +526,8 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, enum source_t - fail: - WARN("Failed to construct MFMediaSource, hr %#x.\n", hr); - -+ if (demuxer_factory) -+ gst_object_unref(demuxer_factory); - media_source_teardown(object); - heap_free(object); - *out_media_source = NULL; -@@ -935,6 +1026,12 @@ void perform_cb_media_source(struct cb_data *cbdata) - cbdata->u.event_src_data.ret = process_bytestream_pad_event(data->pad, data->parent, data->event); - break; - } -+ case WATCH_SOURCE_BUS: -+ { -+ struct watch_bus_data *data = &cbdata->u.watch_bus_data; -+ cbdata->u.watch_bus_data.ret = watch_source_bus(data->bus, data->msg, data->user); -+ break; -+ } - default: - { - ERR("Wrong callback forwarder called\n"); --- -2.28.0 - diff --git a/patches/mfplat-streaming-support/0016-winegstreamer-Translate-MPEG-4-Section-2-caps-to-att.patch b/patches/mfplat-streaming-support/0010-winegstreamer-Translate-MPEG-4-Section-2-caps-to-att.patch similarity index 83% rename from patches/mfplat-streaming-support/0016-winegstreamer-Translate-MPEG-4-Section-2-caps-to-att.patch rename to patches/mfplat-streaming-support/0010-winegstreamer-Translate-MPEG-4-Section-2-caps-to-att.patch index 1d7bf7ca..19c33544 100644 --- a/patches/mfplat-streaming-support/0016-winegstreamer-Translate-MPEG-4-Section-2-caps-to-att.patch +++ b/patches/mfplat-streaming-support/0010-winegstreamer-Translate-MPEG-4-Section-2-caps-to-att.patch @@ -1,7 +1,7 @@ -From f1afd8f222ee3f552368117ef85953a90464f719 Mon Sep 17 00:00:00 2001 +From 2100ecb112e69962c11e4d5c841cc0ab003db6bb Mon Sep 17 00:00:00 2001 From: Derek Lesho Date: Wed, 25 Mar 2020 13:36:19 -0500 -Subject: [PATCH 16/54] winegstreamer: Translate MPEG-4 Section-2 caps to +Subject: [PATCH 10/52] winegstreamer: Translate MPEG-4 Section-2 caps to attributes. Signed-off-by: Derek Lesho @@ -10,10 +10,10 @@ Signed-off-by: Derek Lesho 1 file changed, 16 insertions(+) diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c -index ecb5de8b88..c45cfacc08 100644 +index 4cff74f2d41..f99e5c6636d 100644 --- a/dlls/winegstreamer/mfplat.c +++ b/dlls/winegstreamer/mfplat.c -@@ -652,6 +652,22 @@ static IMFMediaType* transform_to_media_type(GstCaps *caps) +@@ -646,6 +646,22 @@ static IMFMediaType* transform_to_media_type(GstCaps *caps) codec_data_to_user_data(info, media_type); } @@ -34,8 +34,8 @@ index ecb5de8b88..c45cfacc08 100644 + } + } else + { FIXME("Unrecognized video format %s\n", mime_type); - } -- 2.28.0 diff --git a/patches/mfplat-streaming-support/0017-winegstreamer-Translate-WMA-caps-to-attributes.patch b/patches/mfplat-streaming-support/0011-winegstreamer-Translate-WMA-caps-to-attributes.patch similarity index 86% rename from patches/mfplat-streaming-support/0017-winegstreamer-Translate-WMA-caps-to-attributes.patch rename to patches/mfplat-streaming-support/0011-winegstreamer-Translate-WMA-caps-to-attributes.patch index 8add0d9c..489a8641 100644 --- a/patches/mfplat-streaming-support/0017-winegstreamer-Translate-WMA-caps-to-attributes.patch +++ b/patches/mfplat-streaming-support/0011-winegstreamer-Translate-WMA-caps-to-attributes.patch @@ -1,7 +1,7 @@ -From bf38004a42ba81f27e8edc65c1c04cab3cfccf14 Mon Sep 17 00:00:00 2001 +From 8b3eaedb9bb5ce6813f45e2553c657133d80718f Mon Sep 17 00:00:00 2001 From: Derek Lesho Date: Tue, 12 May 2020 17:05:41 -0500 -Subject: [PATCH 17/54] winegstreamer: Translate WMA caps to attributes. +Subject: [PATCH 11/52] winegstreamer: Translate WMA caps to attributes. Signed-off-by: Derek Lesho --- @@ -9,10 +9,10 @@ Signed-off-by: Derek Lesho 1 file changed, 24 insertions(+) diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c -index c45cfacc08..fe187e6cd1 100644 +index f99e5c6636d..2a8c2050ff9 100644 --- a/dlls/winegstreamer/mfplat.c +++ b/dlls/winegstreamer/mfplat.c -@@ -831,6 +831,30 @@ static IMFMediaType* transform_to_media_type(GstCaps *caps) +@@ -834,6 +834,30 @@ static IMFMediaType* transform_to_media_type(GstCaps *caps) FIXME("Unhandled mpegversion %d\n", mpeg_version); } } @@ -41,8 +41,8 @@ index c45cfacc08..fe187e6cd1 100644 + codec_data_to_user_data(info, media_type); + } else + { FIXME("Unrecognized audio format %s\n", mime_type); - } -- 2.28.0 diff --git a/patches/mfplat-streaming-support/0018-winegstreamer-Implement-IMFMediaSource-CreatePresent.patch b/patches/mfplat-streaming-support/0012-winegstreamer-Implement-IMFMediaSource-CreatePresent.patch similarity index 63% rename from patches/mfplat-streaming-support/0018-winegstreamer-Implement-IMFMediaSource-CreatePresent.patch rename to patches/mfplat-streaming-support/0012-winegstreamer-Implement-IMFMediaSource-CreatePresent.patch index 6af947c9..b50ec252 100644 --- a/patches/mfplat-streaming-support/0018-winegstreamer-Implement-IMFMediaSource-CreatePresent.patch +++ b/patches/mfplat-streaming-support/0012-winegstreamer-Implement-IMFMediaSource-CreatePresent.patch @@ -1,20 +1,20 @@ -From 9aad2524a0610d3df313e508617831415a0f5f02 Mon Sep 17 00:00:00 2001 +From 50c496fa883c7a3fae0e991b7bcc96136a77a3df Mon Sep 17 00:00:00 2001 From: Derek Lesho Date: Tue, 31 Mar 2020 11:21:21 -0500 -Subject: [PATCH] winegstreamer: Implement +Subject: [PATCH 12/52] winegstreamer: Implement IMFMediaSource::CreatePresentationDescriptor. Signed-off-by: Derek Lesho --- - dlls/mfplat/tests/mfplat.c | 8 +++---- - dlls/winegstreamer/media_source.c | 37 +++++++++++++++++++++++++++++-- - 2 files changed, 39 insertions(+), 6 deletions(-) + dlls/mfplat/tests/mfplat.c | 9 ++++---- + dlls/winegstreamer/media_source.c | 36 +++++++++++++++++++++++++++++-- + 2 files changed, 38 insertions(+), 7 deletions(-) diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c -index af7e0d0459..8fef44181c 100644 +index 309f7b669a4..72d06e31880 100644 --- a/dlls/mfplat/tests/mfplat.c +++ b/dlls/mfplat/tests/mfplat.c -@@ -529,10 +529,7 @@ static void test_source_resolver(void) +@@ -576,10 +576,7 @@ static void test_source_resolver(void) ok(obj_type == MF_OBJECT_MEDIASOURCE, "got %d\n", obj_type); hr = IMFMediaSource_CreatePresentationDescriptor(mediasource, &descriptor); @@ -25,7 +25,7 @@ index af7e0d0459..8fef44181c 100644 ok(descriptor != NULL, "got %p\n", descriptor); hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(descriptor, 0, &selected, &sd); -@@ -560,7 +557,10 @@ todo_wine +@@ -607,7 +604,10 @@ todo_wine var.vt = VT_EMPTY; hr = IMFMediaSource_Start(mediasource, descriptor, &GUID_NULL, &var); @@ -36,7 +36,7 @@ index af7e0d0459..8fef44181c 100644 get_event((IMFMediaEventGenerator *)mediasource, MENewStream, &var); ok(var.vt == VT_UNKNOWN, "Unexpected value type %u from MENewStream event.\n", var.vt); -@@ -623,10 +623,10 @@ todo_wine +@@ -670,11 +670,10 @@ todo_wine get_event((IMFMediaEventGenerator *)mediasource, MEEndOfPresentation, NULL); @@ -45,22 +45,23 @@ index af7e0d0459..8fef44181c 100644 IMFPresentationDescriptor_Release(descriptor); -skip_source_tests: +- hr = IMFMediaSource_Shutdown(mediasource); ok(hr == S_OK, "Unexpected hr %#x.\n", hr); diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c -index f0acfa2830..33af1a6068 100644 +index 66cfdbdc0fd..6c0c212a100 100644 --- a/dlls/winegstreamer/media_source.c +++ b/dlls/winegstreamer/media_source.c -@@ -61,6 +61,7 @@ struct media_source +@@ -70,6 +70,7 @@ struct media_source IMFByteStream *byte_stream; struct media_stream **streams; ULONG stream_count; + IMFPresentationDescriptor *pres_desc; GstBus *bus; GstElement *container; - GstElement *demuxer; -@@ -743,12 +744,19 @@ static HRESULT WINAPI media_source_CreatePresentationDescriptor(IMFMediaSource * + GstElement *decodebin; +@@ -837,12 +838,19 @@ static HRESULT WINAPI media_source_CreatePresentationDescriptor(IMFMediaSource * { struct media_source *source = impl_from_IMFMediaSource(iface); @@ -82,39 +83,31 @@ index f0acfa2830..33af1a6068 100644 } static HRESULT WINAPI media_source_Start(IMFMediaSource *iface, IMFPresentationDescriptor *descriptor, -@@ -801,6 +809,8 @@ static HRESULT media_source_teardown(struct media_source *source) - gst_element_set_state(source->container, GST_STATE_NULL); - gst_object_unref(GST_OBJECT(source->container)); - } +@@ -904,6 +912,8 @@ static HRESULT WINAPI media_source_Shutdown(IMFMediaSource *iface) + if (source->their_sink) + gst_object_unref(GST_OBJECT(source->their_sink)); + + if (source->pres_desc) + IMFPresentationDescriptor_Release(source->pres_desc); if (source->event_queue) - IMFMediaEventQueue_Release(source->event_queue); + IMFMediaEventQueue_Shutdown(source->event_queue); if (source->byte_stream) -@@ -850,6 +860,7 @@ static const IMFMediaSourceVtbl IMFMediaSource_vtbl = +@@ -1074,6 +1084,7 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_ + GST_STATIC_CAPS_ANY); - static HRESULT media_source_constructor(IMFByteStream *bytestream, enum source_type type, struct media_source **out_media_source) - { -+ unsigned int i; - GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE( - "mf_src", - GST_PAD_SRC, -@@ -859,6 +870,7 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, enum source_t struct media_source *object = heap_alloc_zero(sizeof(*object)); - GList *demuxer_list_one, *demuxer_list_two; - GstElementFactory *demuxer_factory = NULL; + IMFStreamDescriptor **descriptors = NULL; HRESULT hr; int ret; -@@ -942,6 +954,25 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, enum source_t - - WaitForSingleObject(object->all_streams_event, INFINITE); +@@ -1149,6 +1160,25 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_ + goto fail; + } + /* init presentation descriptor */ + + descriptors = heap_alloc(object->stream_count * sizeof(IMFStreamDescriptor*)); -+ for (i = 0; i < object->stream_count; i++) ++ for (unsigned int i = 0; i < object->stream_count; i++) + { + IMFMediaStream_GetStreamDescriptor(&object->streams[i]->IMFMediaStream_iface, &descriptors[i]); + } @@ -122,7 +115,7 @@ index f0acfa2830..33af1a6068 100644 + if (FAILED(MFCreatePresentationDescriptor(object->stream_count, descriptors, &object->pres_desc))) + goto fail; + -+ for (i = 0; i < object->stream_count; i++) ++ for (unsigned int i = 0; i < object->stream_count; i++) + { + IMFPresentationDescriptor_SelectStream(object->pres_desc, i); + IMFStreamDescriptor_Release(descriptors[i]); @@ -130,18 +123,18 @@ index f0acfa2830..33af1a6068 100644 + heap_free(descriptors); + descriptors = NULL; + - gst_element_set_state(object->container, GST_STATE_READY); - object->state = SOURCE_STOPPED; -@@ -954,6 +985,8 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, enum source_t - if (demuxer_factory) - gst_object_unref(demuxer_factory); + *out_media_source = object; +@@ -1157,6 +1187,8 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_ + fail: + WARN("Failed to construct MFMediaSource, hr %#x.\n", hr); + + if (descriptors) + heap_free(descriptors); - media_source_teardown(object); - heap_free(object); - *out_media_source = NULL; + IMFMediaSource_Release(&object->IMFMediaSource_iface); + return hr; + } -- 2.28.0 diff --git a/patches/mfplat-streaming-support/0012-winegstreamer-Implement-IMFMediaStream-GetStreamDesc.patch b/patches/mfplat-streaming-support/0012-winegstreamer-Implement-IMFMediaStream-GetStreamDesc.patch deleted file mode 100644 index f37c6f18..00000000 --- a/patches/mfplat-streaming-support/0012-winegstreamer-Implement-IMFMediaStream-GetStreamDesc.patch +++ /dev/null @@ -1,327 +0,0 @@ -From c8d76047c38b229c76f6ecd810e0fdb2f73ee788 Mon Sep 17 00:00:00 2001 -From: Derek Lesho -Date: Tue, 31 Mar 2020 11:11:05 -0500 -Subject: [PATCH 12/54] winegstreamer: Implement - IMFMediaStream::GetStreamDescriptor. - -Signed-off-by: Derek Lesho ---- - dlls/winegstreamer/gst_private.h | 4 + - dlls/winegstreamer/media_source.c | 45 ++++++- - dlls/winegstreamer/mfplat.c | 196 ++++++++++++++++++++++++++++++ - 3 files changed, 244 insertions(+), 1 deletion(-) - -diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h -index 71ca429088..780cf1b02f 100644 ---- a/dlls/winegstreamer/gst_private.h -+++ b/dlls/winegstreamer/gst_private.h -@@ -36,6 +36,7 @@ - #include "winuser.h" - #include "dshow.h" - #include "strmif.h" -+#include "mfobjects.h" - #include "wine/heap.h" - #include "wine/strmbase.h" - -@@ -54,6 +55,9 @@ void start_dispatch_thread(void) DECLSPEC_HIDDEN; - - extern HRESULT mfplat_get_class_object(REFCLSID rclsid, REFIID riid, void **obj) DECLSPEC_HIDDEN; - -+GstCaps *make_mf_compatible_caps(GstCaps *caps); -+IMFMediaType *mf_media_type_from_caps(GstCaps *caps); -+ - enum source_type - { - SOURCE_TYPE_MPEG_4, -diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c -index 8335c64338..a654d555bc 100644 ---- a/dlls/winegstreamer/media_source.c -+++ b/dlls/winegstreamer/media_source.c -@@ -507,7 +507,10 @@ static HRESULT WINAPI media_stream_GetStreamDescriptor(IMFMediaStream* iface, IM - if (stream->state == STREAM_SHUTDOWN) - return MF_E_SHUTDOWN; - -- return E_NOTIMPL; -+ IMFStreamDescriptor_AddRef(stream->descriptor); -+ *descriptor = stream->descriptor; -+ -+ return S_OK; - } - - static HRESULT WINAPI media_stream_RequestSample(IMFMediaStream *iface, IUnknown *token) -@@ -539,6 +542,9 @@ static const IMFMediaStreamVtbl media_stream_vtbl = - static HRESULT media_stream_constructor(struct media_source *source, GstPad *pad, DWORD stream_id, struct media_stream **out_stream) - { - struct media_stream *object = heap_alloc_zero(sizeof(*object)); -+ IMFMediaTypeHandler *type_handler = NULL; -+ IMFMediaType *stream_type = NULL; -+ GstCaps *caps = NULL; - HRESULT hr; - - TRACE("(%p %p)->(%p)\n", source, pad, out_stream); -@@ -567,6 +573,36 @@ static HRESULT media_stream_constructor(struct media_source *source, GstPad *pad - g_object_set(object->appsink, "async", FALSE, NULL); /* <- This allows us interact with the bin w/o prerolling */ - g_signal_connect(object->appsink, "new-sample", G_CALLBACK(stream_new_sample_wrapper), object); - -+ if (!(caps = gst_pad_query_caps(pad, NULL))) -+ goto fail; -+ -+ if (TRACE_ON(mfplat)) -+ { -+ gchar *caps_str = gst_caps_to_string(caps); -+ TRACE("caps %s\n", debugstr_a(caps_str)); -+ g_free(caps_str); -+ } -+ -+ if (!(stream_type = mf_media_type_from_caps(caps))) -+ goto fail; -+ -+ gst_caps_unref(caps); -+ caps = NULL; -+ -+ if (FAILED(hr = MFCreateStreamDescriptor(stream_id, 1, &stream_type, &object->descriptor))) -+ goto fail; -+ -+ if (FAILED(hr = IMFStreamDescriptor_GetMediaTypeHandler(object->descriptor, &type_handler))) -+ goto fail; -+ -+ if (FAILED(hr = IMFMediaTypeHandler_SetCurrentMediaType(type_handler, stream_type))) -+ goto fail; -+ -+ IMFMediaTypeHandler_Release(type_handler); -+ type_handler = NULL; -+ IMFMediaType_Release(stream_type); -+ stream_type = NULL; -+ - object->my_sink = gst_element_get_static_pad(object->appsink, "sink"); - gst_pad_set_element_private(pad, object); - -@@ -582,6 +618,13 @@ static HRESULT media_stream_constructor(struct media_source *source, GstPad *pad - fail: - WARN("Failed to construct media stream, hr %#x.\n", hr); - -+ if (caps) -+ gst_caps_unref(caps); -+ if (stream_type) -+ IMFMediaType_Release(stream_type); -+ if (type_handler) -+ IMFMediaTypeHandler_Release(type_handler); -+ - IMFMediaStream_Release(&object->IMFMediaStream_iface); - return hr; - } -diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c -index 16e55247de..90eb583c4a 100644 ---- a/dlls/winegstreamer/mfplat.c -+++ b/dlls/winegstreamer/mfplat.c -@@ -16,6 +16,11 @@ - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -+#include "config.h" -+#include -+ -+#include "gst_private.h" -+ - #include - - #include "gst_private.h" -@@ -442,3 +447,194 @@ HRESULT mfplat_get_class_object(REFCLSID rclsid, REFIID riid, void **obj) - - return CLASS_E_CLASSNOTAVAILABLE; - } -+ -+const static struct -+{ -+ const GUID *subtype; -+ GstVideoFormat format; -+} -+uncompressed_formats[] = -+{ -+ {&MFVideoFormat_ARGB32, GST_VIDEO_FORMAT_BGRA}, -+ {&MFVideoFormat_RGB32, GST_VIDEO_FORMAT_BGRx}, -+ {&MFVideoFormat_RGB24, GST_VIDEO_FORMAT_BGR}, -+ {&MFVideoFormat_RGB565, GST_VIDEO_FORMAT_BGR16}, -+ {&MFVideoFormat_RGB555, GST_VIDEO_FORMAT_BGR15}, -+}; -+ -+/* caps will be modified to represent the exact type needed for the format */ -+static IMFMediaType* transform_to_media_type(GstCaps *caps) -+{ -+ IMFMediaType *media_type; -+ GstStructure *info; -+ const char *mime_type; -+ -+ if (TRACE_ON(mfplat)) -+ { -+ gchar *human_readable = gst_caps_to_string(caps); -+ TRACE("caps = %s\n", debugstr_a(human_readable)); -+ g_free(human_readable); -+ } -+ -+ if (FAILED(MFCreateMediaType(&media_type))) -+ { -+ return NULL; -+ } -+ -+ info = gst_caps_get_structure(caps, 0); -+ mime_type = gst_structure_get_name(info); -+ -+ if (!(strncmp(mime_type, "video", 5))) -+ { -+ GstVideoInfo video_info; -+ -+ if (!(gst_video_info_from_caps(&video_info, caps))) -+ { -+ return NULL; -+ } -+ -+ IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video); -+ -+ IMFMediaType_SetUINT64(media_type, &MF_MT_FRAME_SIZE, ((UINT64)video_info.width << 32) | video_info.height); -+ -+ IMFMediaType_SetUINT64(media_type, &MF_MT_FRAME_RATE, ((UINT64)video_info.fps_n << 32) | video_info.fps_d); -+ -+ if (!(strcmp(mime_type, "video/x-raw"))) -+ { -+ GUID fourcc_subtype = MFVideoFormat_Base; -+ unsigned int i; -+ -+ IMFMediaType_SetUINT32(media_type, &MF_MT_COMPRESSED, FALSE); -+ -+ /* First try FOURCC */ -+ if ((fourcc_subtype.Data1 = gst_video_format_to_fourcc(video_info.finfo->format))) -+ { -+ IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &fourcc_subtype); -+ } -+ else -+ { -+ for (i = 0; i < ARRAY_SIZE(uncompressed_formats); i++) -+ { -+ if (uncompressed_formats[i].format == video_info.finfo->format) -+ { -+ IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, uncompressed_formats[i].subtype); -+ break; -+ } -+ } -+ if (i == ARRAY_SIZE(uncompressed_formats)) -+ FIXME("Unrecognized format.\n"); -+ } -+ } -+ else -+ FIXME("Unrecognized video format %s\n", mime_type); -+ } -+ else if (!(strncmp(mime_type, "audio", 5))) -+ { -+ gint rate, channels, bitrate; -+ IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio); -+ -+ if (gst_structure_get_int(info, "rate", &rate)) -+ IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, rate); -+ -+ if (gst_structure_get_int(info, "channels", &channels)) -+ IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_NUM_CHANNELS, channels); -+ -+ if (gst_structure_get_int(info, "bitrate", &bitrate)) -+ IMFMediaType_SetUINT32(media_type, &MF_MT_AVG_BITRATE, bitrate); -+ -+ if (!(strcmp(mime_type, "audio/x-raw"))) -+ { -+ const char *format; -+ if ((format = gst_structure_get_string(info, "format"))) -+ { -+ char type; -+ unsigned int bits_per_sample; -+ char endian[2]; -+ char new_format[6]; -+ if ((strlen(format) > 5) || (sscanf(format, "%c%u%2c", &type, &bits_per_sample, endian) < 2)) -+ { -+ FIXME("Unhandled audio format %s\n", format); -+ IMFMediaType_Release(media_type); -+ return NULL; -+ } -+ -+ if (type == 'F') -+ { -+ IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFAudioFormat_Float); -+ } -+ else if (type == 'U' || type == 'S') -+ { -+ IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFAudioFormat_PCM); -+ if (bits_per_sample == 8) -+ type = 'U'; -+ else -+ type = 'S'; -+ } -+ else -+ { -+ FIXME("Unrecognized audio format: %s\n", format); -+ IMFMediaType_Release(media_type); -+ return NULL; -+ } -+ -+ IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_BITS_PER_SAMPLE, bits_per_sample); -+ -+ if (endian[0] == 'B') -+ endian[0] = 'L'; -+ -+ sprintf(new_format, "%c%u%.2s", type, bits_per_sample, bits_per_sample > 8 ? endian : 0); -+ gst_caps_set_simple(caps, "format", G_TYPE_STRING, new_format, NULL); -+ } -+ else -+ { -+ ERR("Failed to get audio format\n"); -+ } -+ } -+ else -+ FIXME("Unrecognized audio format %s\n", mime_type); -+ } -+ else -+ { -+ IMFMediaType_Release(media_type); -+ return NULL; -+ } -+ -+ return media_type; -+} -+ -+/* returns NULL if doesn't match exactly */ -+IMFMediaType *mf_media_type_from_caps(GstCaps *caps) -+{ -+ GstCaps *writeable_caps; -+ IMFMediaType *ret; -+ -+ writeable_caps = gst_caps_copy(caps); -+ ret = transform_to_media_type(writeable_caps); -+ -+ if (!(gst_caps_is_equal(caps, writeable_caps))) -+ { -+ IMFMediaType_Release(ret); -+ ret = NULL; -+ } -+ gst_caps_unref(writeable_caps); -+ return ret; -+} -+ -+GstCaps *make_mf_compatible_caps(GstCaps *caps) -+{ -+ GstCaps *ret; -+ IMFMediaType *media_type; -+ -+ ret = gst_caps_copy(caps); -+ -+ if ((media_type = transform_to_media_type(ret))) -+ IMFMediaType_Release(media_type); -+ -+ if (!media_type) -+ { -+ gst_caps_unref(ret); -+ return NULL; -+ } -+ -+ return ret; -+} -\ No newline at end of file --- -2.28.0 - diff --git a/patches/mfplat-streaming-support/0026-winegstreamer-Introduce-IMFMediaType-GstCaps-convert.patch b/patches/mfplat-streaming-support/0013-winegstreamer-Introduce-IMFMediaType-GstCaps-convert.patch similarity index 85% rename from patches/mfplat-streaming-support/0026-winegstreamer-Introduce-IMFMediaType-GstCaps-convert.patch rename to patches/mfplat-streaming-support/0013-winegstreamer-Introduce-IMFMediaType-GstCaps-convert.patch index 18fcf6cc..55a104e4 100644 --- a/patches/mfplat-streaming-support/0026-winegstreamer-Introduce-IMFMediaType-GstCaps-convert.patch +++ b/patches/mfplat-streaming-support/0013-winegstreamer-Introduce-IMFMediaType-GstCaps-convert.patch @@ -1,35 +1,36 @@ -From 32b23b1380f44a6c3106e0e789e31c5cbed94b5e Mon Sep 17 00:00:00 2001 +From 309bf9ba18c12e8f6eb9a29c7455983fa7bf3603 Mon Sep 17 00:00:00 2001 From: Derek Lesho Date: Tue, 24 Mar 2020 16:15:35 -0500 -Subject: [PATCH 26/54] winegstreamer: Introduce IMFMediaType -> GstCaps +Subject: [PATCH 13/52] winegstreamer: Introduce IMFMediaType -> GstCaps converter. Signed-off-by: Derek Lesho --- dlls/winegstreamer/gst_private.h | 1 + - dlls/winegstreamer/mfplat.c | 145 +++++++++++++++++++++++++++++++ - 2 files changed, 146 insertions(+) + dlls/winegstreamer/mfplat.c | 149 +++++++++++++++++++++++++++++++ + 2 files changed, 150 insertions(+) diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h -index 823e023f52..20d3beef02 100644 +index 86392eea4e3..d0628cc8df3 100644 --- a/dlls/winegstreamer/gst_private.h +++ b/dlls/winegstreamer/gst_private.h -@@ -57,6 +57,7 @@ extern HRESULT mfplat_get_class_object(REFCLSID rclsid, REFIID riid, void **obj) - +@@ -58,6 +58,7 @@ extern HRESULT mfplat_get_class_object(REFCLSID rclsid, REFIID riid, void **obj) + HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj) DECLSPEC_HIDDEN; GstCaps *make_mf_compatible_caps(GstCaps *caps); IMFMediaType *mf_media_type_from_caps(GstCaps *caps); +GstCaps *caps_from_mf_media_type(IMFMediaType *type); - IMFSample *mf_sample_from_gst_buffer(GstBuffer *in); - enum source_type + HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj) DECLSPEC_HIDDEN; + diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c -index e09309fd4d..ba2a32e610 100644 +index 2a8c2050ff9..648cdd23421 100644 --- a/dlls/winegstreamer/mfplat.c +++ b/dlls/winegstreamer/mfplat.c -@@ -904,6 +904,151 @@ GstCaps *make_mf_compatible_caps(GstCaps *caps) +@@ -910,3 +910,152 @@ GstCaps *make_mf_compatible_caps(GstCaps *caps) + return ret; } - ++ +GstCaps *caps_from_mf_media_type(IMFMediaType *type) +{ + GUID major_type; @@ -116,7 +117,7 @@ index e09309fd4d..ba2a32e610 100644 + } + else if (IsEqualGUID(&major_type, &MFMediaType_Audio)) + { -+ DWORD rate, channels, bitrate; ++ DWORD rate, channels, channel_mask, bitrate; + + if (IsEqualGUID(&subtype, &MFAudioFormat_Float)) + { @@ -162,6 +163,10 @@ index e09309fd4d..ba2a32e610 100644 + { + gst_caps_set_simple(output, "channels", G_TYPE_INT, channels, NULL); + } ++ if (SUCCEEDED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_CHANNEL_MASK, &channel_mask))) ++ { ++ gst_caps_set_simple(output, "channel-mask", GST_TYPE_BITMASK, (guint64) channel_mask, NULL); ++ } + + if (SUCCEEDED(IMFMediaType_GetUINT32(type, &MF_MT_AVG_BITRATE, &bitrate))) + { @@ -174,10 +179,6 @@ index e09309fd4d..ba2a32e610 100644 + FIXME("Unrecognized major type %s\n", debugstr_guid(&major_type)); + return NULL; +} -+ - /* IMFSample = GstBuffer - IMFBuffer = GstMemory */ - -- 2.28.0 diff --git a/patches/mfplat-streaming-support/0027-winegstreamer-Translate-H.264-attributes-to-caps.patch b/patches/mfplat-streaming-support/0014-winegstreamer-Translate-H.264-attributes-to-caps.patch similarity index 93% rename from patches/mfplat-streaming-support/0027-winegstreamer-Translate-H.264-attributes-to-caps.patch rename to patches/mfplat-streaming-support/0014-winegstreamer-Translate-H.264-attributes-to-caps.patch index 02285f46..0906c7ff 100644 --- a/patches/mfplat-streaming-support/0027-winegstreamer-Translate-H.264-attributes-to-caps.patch +++ b/patches/mfplat-streaming-support/0014-winegstreamer-Translate-H.264-attributes-to-caps.patch @@ -1,7 +1,7 @@ -From c60414ceb49b5ff025a101b9ffdf0aa665b0cf2c Mon Sep 17 00:00:00 2001 +From 98ccb2c72d763514c1e3232e93dab697bede4cad Mon Sep 17 00:00:00 2001 From: Derek Lesho Date: Tue, 24 Mar 2020 16:18:40 -0500 -Subject: [PATCH 27/54] winegstreamer: Translate H.264 attributes to caps. +Subject: [PATCH 14/52] winegstreamer: Translate H.264 attributes to caps. Signed-off-by: Derek Lesho --- @@ -9,10 +9,10 @@ Signed-off-by: Derek Lesho 1 file changed, 48 insertions(+) diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c -index ba2a32e610..26ad75584d 100644 +index 648cdd23421..bc0259f2a64 100644 --- a/dlls/winegstreamer/mfplat.c +++ b/dlls/winegstreamer/mfplat.c -@@ -973,6 +973,54 @@ GstCaps *caps_from_mf_media_type(IMFMediaType *type) +@@ -980,6 +980,54 @@ GstCaps *caps_from_mf_media_type(IMFMediaType *type) } } diff --git a/patches/mfplat-streaming-support/0028-winegstreamer-Translate-WMV-attributes-to-caps.patch b/patches/mfplat-streaming-support/0015-winegstreamer-Translate-WMV-attributes-to-caps.patch similarity index 51% rename from patches/mfplat-streaming-support/0028-winegstreamer-Translate-WMV-attributes-to-caps.patch rename to patches/mfplat-streaming-support/0015-winegstreamer-Translate-WMV-attributes-to-caps.patch index 6707c3ed..e41e7f4f 100644 --- a/patches/mfplat-streaming-support/0028-winegstreamer-Translate-WMV-attributes-to-caps.patch +++ b/patches/mfplat-streaming-support/0015-winegstreamer-Translate-WMV-attributes-to-caps.patch @@ -1,18 +1,18 @@ -From 79ffdf47055128475526a432b175362bbbaf57da Mon Sep 17 00:00:00 2001 +From 884a00b050f17191a7c48364de4e55e5fcc17cc9 Mon Sep 17 00:00:00 2001 From: Derek Lesho Date: Tue, 24 Mar 2020 16:20:17 -0500 -Subject: [PATCH 28/54] winegstreamer: Translate WMV attributes to caps. +Subject: [PATCH 15/52] winegstreamer: Translate WMV attributes to caps. Signed-off-by: Derek Lesho --- - dlls/winegstreamer/mfplat.c | 24 ++++++++++++++++++++++++ - 1 file changed, 24 insertions(+) + dlls/winegstreamer/mfplat.c | 51 +++++++++++++++++++++++++++++++++++++ + 1 file changed, 51 insertions(+) diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c -index 26ad75584d..f5b44f9214 100644 +index bc0259f2a64..a9abffedcd0 100644 --- a/dlls/winegstreamer/mfplat.c +++ b/dlls/winegstreamer/mfplat.c -@@ -904,6 +904,21 @@ GstCaps *make_mf_compatible_caps(GstCaps *caps) +@@ -911,6 +911,21 @@ GstCaps *make_mf_compatible_caps(GstCaps *caps) return ret; } @@ -34,10 +34,37 @@ index 26ad75584d..f5b44f9214 100644 GstCaps *caps_from_mf_media_type(IMFMediaType *type) { GUID major_type; -@@ -1021,6 +1036,15 @@ GstCaps *caps_from_mf_media_type(IMFMediaType *type) +@@ -1028,6 +1043,42 @@ GstCaps *caps_from_mf_media_type(IMFMediaType *type) gst_caps_set_simple(output, "level", G_TYPE_STRING, level, NULL); } } ++ else if (IsEqualGUID(&subtype, &MFVideoFormat_WMV1)) ++ { ++ output = gst_caps_new_empty_simple("video/x-wmv"); ++ gst_caps_set_simple(output, "format", G_TYPE_STRING, "WMV1", NULL); ++ ++ gst_caps_set_simple(output, "wmvversion", G_TYPE_INT, 1, NULL); ++ ++ user_data_to_codec_data(type, output); ++ } ++ else if (IsEqualGUID(&subtype, &MFVideoFormat_WMV2)) ++ { ++ output = gst_caps_new_empty_simple("video/x-wmv"); ++ gst_caps_set_simple(output, "format", G_TYPE_STRING, "WMV2", NULL); ++ ++ gst_caps_set_simple(output, "wmvversion", G_TYPE_INT, 2, NULL); ++ ++ user_data_to_codec_data(type, output); ++ } ++ else if (IsEqualGUID(&subtype, &MFVideoFormat_WMV3)) ++ { ++ output = gst_caps_new_empty_simple("video/x-wmv"); ++ gst_caps_set_simple(output, "format", G_TYPE_STRING, "WMV3", NULL); ++ ++ gst_caps_set_simple(output, "wmvversion", G_TYPE_INT, 3, NULL); ++ ++ user_data_to_codec_data(type, output); ++ } + else if (IsEqualGUID(&subtype, &MFVideoFormat_WVC1)) + { + output = gst_caps_new_empty_simple("video/x-wmv"); diff --git a/patches/mfplat-streaming-support/0029-winegstreamer-Translate-AAC-attributes-to-caps.patch b/patches/mfplat-streaming-support/0016-winegstreamer-Translate-AAC-attributes-to-caps.patch similarity index 94% rename from patches/mfplat-streaming-support/0029-winegstreamer-Translate-AAC-attributes-to-caps.patch rename to patches/mfplat-streaming-support/0016-winegstreamer-Translate-AAC-attributes-to-caps.patch index c934c912..d9d845f6 100644 --- a/patches/mfplat-streaming-support/0029-winegstreamer-Translate-AAC-attributes-to-caps.patch +++ b/patches/mfplat-streaming-support/0016-winegstreamer-Translate-AAC-attributes-to-caps.patch @@ -1,7 +1,7 @@ -From f94f3362a246e5f1f476f6a51465424e1ae6d7c7 Mon Sep 17 00:00:00 2001 +From 7fd3f66161894a1242d43b6abd54e65ed6831270 Mon Sep 17 00:00:00 2001 From: Derek Lesho Date: Tue, 21 Apr 2020 10:31:02 -0500 -Subject: [PATCH 29/54] winegstreamer: Translate AAC attributes to caps. +Subject: [PATCH 16/52] winegstreamer: Translate AAC attributes to caps. Signed-off-by: Derek Lesho --- @@ -9,10 +9,10 @@ Signed-off-by: Derek Lesho 1 file changed, 66 insertions(+) diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c -index f5b44f9214..7e96e6af20 100644 +index a9abffedcd0..75d8e338128 100644 --- a/dlls/winegstreamer/mfplat.c +++ b/dlls/winegstreamer/mfplat.c -@@ -1094,6 +1094,72 @@ GstCaps *caps_from_mf_media_type(IMFMediaType *type) +@@ -1128,6 +1128,72 @@ GstCaps *caps_from_mf_media_type(IMFMediaType *type) return NULL; } } diff --git a/patches/mfplat-streaming-support/0030-winegstreamer-Translate-MPEG-4-Section-2-attributes-.patch b/patches/mfplat-streaming-support/0017-winegstreamer-Translate-MPEG-4-Section-2-attributes-.patch similarity index 66% rename from patches/mfplat-streaming-support/0030-winegstreamer-Translate-MPEG-4-Section-2-attributes-.patch rename to patches/mfplat-streaming-support/0017-winegstreamer-Translate-MPEG-4-Section-2-attributes-.patch index 4446f9d1..dbab3b69 100644 --- a/patches/mfplat-streaming-support/0030-winegstreamer-Translate-MPEG-4-Section-2-attributes-.patch +++ b/patches/mfplat-streaming-support/0017-winegstreamer-Translate-MPEG-4-Section-2-attributes-.patch @@ -1,19 +1,19 @@ -From 8bd70d8a970af6e9a31158fa57085918ee57817c Mon Sep 17 00:00:00 2001 +From f15f0c3530b20cff7de1e3295d2b7978e9b0d2c7 Mon Sep 17 00:00:00 2001 From: Derek Lesho Date: Mon, 11 May 2020 16:03:09 -0500 -Subject: [PATCH 30/54] winegstreamer: Translate MPEG-4 Section-2 attributes to +Subject: [PATCH 17/52] winegstreamer: Translate MPEG-4 Section-2 attributes to caps. Signed-off-by: Derek Lesho --- - dlls/winegstreamer/mfplat.c | 7 +++++++ - 1 file changed, 7 insertions(+) + dlls/winegstreamer/mfplat.c | 8 ++++++++ + 1 file changed, 8 insertions(+) diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c -index 7e96e6af20..c7d6e4806a 100644 +index 75d8e338128..b7fa283133c 100644 --- a/dlls/winegstreamer/mfplat.c +++ b/dlls/winegstreamer/mfplat.c -@@ -1045,6 +1045,13 @@ GstCaps *caps_from_mf_media_type(IMFMediaType *type) +@@ -1079,6 +1079,14 @@ GstCaps *caps_from_mf_media_type(IMFMediaType *type) user_data_to_codec_data(type, output); } @@ -21,6 +21,7 @@ index 7e96e6af20..c7d6e4806a 100644 + { + output = gst_caps_new_empty_simple("video/mpeg"); + gst_caps_set_simple(output, "mpegversion", G_TYPE_INT, 4, NULL); ++ gst_caps_set_simple(output, "systemstream", G_TYPE_BOOLEAN, FALSE, NULL); + + user_data_to_codec_data(type, output); + } diff --git a/patches/mfplat-streaming-support/0031-winegstreamer-Translate-WMA-attributes-to-caps.patch b/patches/mfplat-streaming-support/0018-winegstreamer-Translate-WMA-attributes-to-caps.patch similarity index 84% rename from patches/mfplat-streaming-support/0031-winegstreamer-Translate-WMA-attributes-to-caps.patch rename to patches/mfplat-streaming-support/0018-winegstreamer-Translate-WMA-attributes-to-caps.patch index 1327b45b..5877ab3e 100644 --- a/patches/mfplat-streaming-support/0031-winegstreamer-Translate-WMA-attributes-to-caps.patch +++ b/patches/mfplat-streaming-support/0018-winegstreamer-Translate-WMA-attributes-to-caps.patch @@ -1,7 +1,7 @@ -From e73bfd928bb2a0e02fe6243013132b0e63b27a52 Mon Sep 17 00:00:00 2001 +From ccb8ad4ef7bc35a62f7ec58d4ce591f6e2678598 Mon Sep 17 00:00:00 2001 From: Derek Lesho Date: Tue, 12 May 2020 17:05:59 -0500 -Subject: [PATCH 31/54] winegstreamer: Translate WMA attributes to caps. +Subject: [PATCH 18/52] winegstreamer: Translate WMA attributes to caps. Signed-off-by: Derek Lesho --- @@ -9,10 +9,10 @@ Signed-off-by: Derek Lesho 1 file changed, 15 insertions(+) diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c -index c7d6e4806a..86f0f79630 100644 +index b7fa283133c..b291b21e8b5 100644 --- a/dlls/winegstreamer/mfplat.c +++ b/dlls/winegstreamer/mfplat.c -@@ -1167,6 +1167,21 @@ GstCaps *caps_from_mf_media_type(IMFMediaType *type) +@@ -1202,6 +1202,21 @@ GstCaps *caps_from_mf_media_type(IMFMediaType *type) CoTaskMemFree(user_data); } } diff --git a/patches/mfplat-streaming-support/0019-winegstreamer-Implement-IMFMediaSource-Start.patch b/patches/mfplat-streaming-support/0019-winegstreamer-Implement-IMFMediaSource-Start.patch index 9b6fa36f..21da0204 100644 --- a/patches/mfplat-streaming-support/0019-winegstreamer-Implement-IMFMediaSource-Start.patch +++ b/patches/mfplat-streaming-support/0019-winegstreamer-Implement-IMFMediaSource-Start.patch @@ -1,19 +1,19 @@ -From 5de8cd0751587ad6efe73f6b8cde6829a14d1203 Mon Sep 17 00:00:00 2001 +From d883eb8c94f0778d4ef955480a3862d575f7130a Mon Sep 17 00:00:00 2001 From: Derek Lesho Date: Tue, 31 Mar 2020 15:10:03 -0500 -Subject: [PATCH] winegstreamer: Implement IMFMediaSource::Start. +Subject: [PATCH 19/52] winegstreamer: Implement IMFMediaSource::Start. Signed-off-by: Derek Lesho --- dlls/mfplat/tests/mfplat.c | 8 +- - dlls/winegstreamer/media_source.c | 285 +++++++++++++++++++++++++++++- - 2 files changed, 286 insertions(+), 7 deletions(-) + dlls/winegstreamer/media_source.c | 313 +++++++++++++++++++++++++++++- + 2 files changed, 314 insertions(+), 7 deletions(-) diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c -index 8fef44181c..c26c40d531 100644 +index 72d06e31880..e6a1694a11f 100644 --- a/dlls/mfplat/tests/mfplat.c +++ b/dlls/mfplat/tests/mfplat.c -@@ -557,10 +557,7 @@ static void test_source_resolver(void) +@@ -604,10 +604,7 @@ static void test_source_resolver(void) var.vt = VT_EMPTY; hr = IMFMediaSource_Start(mediasource, descriptor, &GUID_NULL, &var); @@ -24,7 +24,7 @@ index 8fef44181c..c26c40d531 100644 get_event((IMFMediaEventGenerator *)mediasource, MENewStream, &var); ok(var.vt == VT_UNKNOWN, "Unexpected value type %u from MENewStream event.\n", var.vt); -@@ -578,10 +575,13 @@ todo_wine +@@ -625,10 +622,13 @@ todo_wine hr = IMFMediaStream_RequestSample(video_stream, NULL); if (i == sample_count) break; @@ -38,7 +38,7 @@ index 8fef44181c..c26c40d531 100644 for (i = 0; i < sample_count; ++i) { -@@ -619,11 +619,11 @@ todo_wine +@@ -666,11 +666,11 @@ todo_wine hr = IMFMediaStream_RequestSample(video_stream, NULL); ok(hr == MF_E_END_OF_STREAM, "Unexpected hr %#x.\n", hr); @@ -52,13 +52,18 @@ index 8fef44181c..c26c40d531 100644 IMFPresentationDescriptor_Release(descriptor); diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c -index 33af1a6068..e5bf4d2b5d 100644 +index 6c0c212a100..c893664fbec 100644 --- a/dlls/winegstreamer/media_source.c +++ b/dlls/winegstreamer/media_source.c -@@ -50,12 +50,36 @@ struct media_stream - STREAM_RUNNING, +@@ -56,16 +56,41 @@ struct media_stream + STREAM_STUB, + STREAM_INACTIVE, STREAM_SHUTDOWN, ++ STREAM_RUNNING, } state; + /* used when in STUB state: */ + DWORD stream_id; + HANDLE caps_event; + BOOL eos; +}; + @@ -89,10 +94,18 @@ index 33af1a6068..e5bf4d2b5d 100644 + IMFAsyncCallback async_commands_callback; LONG ref; + DWORD async_commands_queue; - enum source_type type; IMFMediaEventQueue *event_queue; IMFByteStream *byte_stream; -@@ -87,6 +111,238 @@ static inline struct media_source *impl_from_IMFMediaSource(IMFMediaSource *ifac + struct media_stream **streams; +@@ -79,6 +104,7 @@ struct media_source + { + SOURCE_OPENING, + SOURCE_STOPPED, ++ SOURCE_RUNNING, + SOURCE_SHUTDOWN, + } state; + HANDLE all_streams_event; +@@ -94,6 +120,264 @@ static inline struct media_source *impl_from_IMFMediaSource(IMFMediaSource *ifac return CONTAINING_RECORD(iface, struct media_source, IMFMediaSource_iface); } @@ -202,12 +215,11 @@ index 33af1a6068..e5bf4d2b5d 100644 +{ + ULONG sd_count; + IMFStreamDescriptor *ret; -+ unsigned int i; + + if (FAILED(IMFPresentationDescriptor_GetStreamDescriptorCount(pres_desc, &sd_count))) + return NULL; + -+ for (i = 0; i < sd_count; i++) ++ for (unsigned int i = 0; i < sd_count; i++) + { + DWORD stream_id; + @@ -226,23 +238,29 @@ index 33af1a6068..e5bf4d2b5d 100644 +{ + PROPVARIANT *position = &command->u.start.position; + BOOL seek_message = source->state != SOURCE_STOPPED && position->vt != VT_EMPTY; -+ unsigned int i; + -+ /* we can't seek until the pipeline is in a valid state */ + gst_element_set_state(source->container, GST_STATE_PAUSED); + assert(gst_element_get_state(source->container, NULL, NULL, -1) == GST_STATE_CHANGE_SUCCESS); -+ if (source->state == SOURCE_STOPPED) ++ ++ /* seek to beginning on stop->play */ ++ if (source->state == SOURCE_STOPPED && position->vt == VT_EMPTY) + { -+ WaitForSingleObject(source->all_streams_event, INFINITE); ++ position->vt = VT_I8; ++ position->u.hVal.QuadPart = 0; + } + -+ for (i = 0; i < source->stream_count; i++) ++ for (unsigned int i = 0; i < source->stream_count; i++) + { + struct media_stream *stream; + IMFStreamDescriptor *sd; ++ IMFMediaTypeHandler *mth; ++ IMFMediaType *current_mt; ++ GstCaps *current_caps; ++ GstCaps *prev_caps; + DWORD stream_id; + BOOL was_active; + BOOL selected; ++ BOOL changed_caps; + + stream = source->streams[i]; + @@ -253,6 +271,29 @@ index 33af1a6068..e5bf4d2b5d 100644 + + was_active = stream->state != STREAM_INACTIVE; + ++ stream->state = selected ? STREAM_RUNNING : STREAM_INACTIVE; ++ ++ if (selected) ++ { ++ IMFStreamDescriptor_GetMediaTypeHandler(stream->descriptor, &mth); ++ IMFMediaTypeHandler_GetCurrentMediaType(mth, ¤t_mt); ++ current_caps = caps_from_mf_media_type(current_mt); ++ g_object_get(stream->appsink, "caps", &prev_caps, NULL); ++ changed_caps = !gst_caps_is_equal(prev_caps, current_caps); ++ ++ if (changed_caps) ++ { ++ g_object_set(stream->appsink, "caps", current_caps, NULL); ++ GstEvent *reconfigure_event = gst_event_new_reconfigure(); ++ gst_pad_push_event(gst_element_get_static_pad(stream->appsink, "sink"), reconfigure_event); ++ } ++ ++ gst_caps_unref(current_caps); ++ gst_caps_unref(prev_caps); ++ IMFMediaType_Release(current_mt); ++ IMFMediaTypeHandler_Release(mth); ++ } ++ + if (position->vt != VT_EMPTY) + { + GstEvent *seek_event = gst_event_new_seek(1.0, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, @@ -265,8 +306,6 @@ index 33af1a6068..e5bf4d2b5d 100644 + stream->eos = FALSE; + } + -+ stream->state = selected ? STREAM_RUNNING : STREAM_INACTIVE; -+ + if (selected) + { + TRACE("Stream %u (%p) selected\n", i, stream); @@ -328,10 +367,10 @@ index 33af1a6068..e5bf4d2b5d 100644 + source_async_commands_Invoke, +}; + - /* inactive stream sample discarder */ - static GstFlowReturn stream_new_sample(GstElement *appsink, gpointer user) + GstFlowReturn pull_from_bytestream(GstPad *pad, GstObject *parent, guint64 ofs, guint len, + GstBuffer **buf) { -@@ -760,16 +1016,32 @@ static HRESULT WINAPI media_source_CreatePresentationDescriptor(IMFMediaSource * +@@ -854,16 +1138,32 @@ static HRESULT WINAPI media_source_CreatePresentationDescriptor(IMFMediaSource * } static HRESULT WINAPI media_source_Start(IMFMediaSource *iface, IMFPresentationDescriptor *descriptor, @@ -367,7 +406,7 @@ index 33af1a6068..e5bf4d2b5d 100644 } static HRESULT WINAPI media_source_Stop(IMFMediaSource *iface) -@@ -828,6 +1100,9 @@ static HRESULT media_source_teardown(struct media_source *source) +@@ -931,6 +1231,9 @@ static HRESULT WINAPI media_source_Shutdown(IMFMediaSource *iface) if (source->all_streams_event) CloseHandle(source->all_streams_event); @@ -377,15 +416,15 @@ index 33af1a6068..e5bf4d2b5d 100644 return S_OK; } -@@ -878,6 +1153,7 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, enum source_t +@@ -1092,6 +1395,7 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_ return E_OUTOFMEMORY; object->IMFMediaSource_iface.lpVtbl = &IMFMediaSource_vtbl; + object->async_commands_callback.lpVtbl = &source_async_commands_callback_vtbl; object->ref = 1; - object->type = type; object->byte_stream = bytestream; -@@ -887,6 +1163,9 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, enum source_t + IMFByteStream_AddRef(bytestream); +@@ -1100,6 +1404,9 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_ if (FAILED(hr = MFCreateEventQueue(&object->event_queue))) goto fail; diff --git a/patches/mfplat-streaming-support/0021-winegstreamer-Implement-IMFMediaStream-RequestSample.patch b/patches/mfplat-streaming-support/0020-winegstreamer-Implement-IMFMediaStream-RequestSample.patch similarity index 78% rename from patches/mfplat-streaming-support/0021-winegstreamer-Implement-IMFMediaStream-RequestSample.patch rename to patches/mfplat-streaming-support/0020-winegstreamer-Implement-IMFMediaStream-RequestSample.patch index b9933a59..2a75ba03 100644 --- a/patches/mfplat-streaming-support/0021-winegstreamer-Implement-IMFMediaStream-RequestSample.patch +++ b/patches/mfplat-streaming-support/0020-winegstreamer-Implement-IMFMediaStream-RequestSample.patch @@ -1,21 +1,21 @@ -From 0911c65f0087651e7d84b447783dd48f50218450 Mon Sep 17 00:00:00 2001 +From 366946876d7a53f80d91749f290f511294415cf5 Mon Sep 17 00:00:00 2001 From: Derek Lesho Date: Wed, 25 Mar 2020 10:43:03 -0500 -Subject: [PATCH] winegstreamer: Implement IMFMediaStream::RequestSample. +Subject: [PATCH 20/52] winegstreamer: Implement IMFMediaStream::RequestSample. Signed-off-by: Derek Lesho --- - dlls/mfplat/tests/mfplat.c | 4 - + dlls/mfplat/tests/mfplat.c | 4 -- dlls/winegstreamer/gst_private.h | 1 + - dlls/winegstreamer/media_source.c | 118 ++++++++++++++++++++++++++++-- - dlls/winegstreamer/mfplat.c | 91 +++++++++++++++++++++++ - 4 files changed, 205 insertions(+), 9 deletions(-) + dlls/winegstreamer/media_source.c | 108 +++++++++++++++++++++++++++++- + dlls/winegstreamer/mfplat.c | 90 +++++++++++++++++++++++++ + 4 files changed, 198 insertions(+), 5 deletions(-) diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c -index c26c40d531..a9408c998c 100644 +index e6a1694a11f..6dd2c3cbe96 100644 --- a/dlls/mfplat/tests/mfplat.c +++ b/dlls/mfplat/tests/mfplat.c -@@ -575,13 +575,10 @@ static void test_source_resolver(void) +@@ -622,13 +622,10 @@ static void test_source_resolver(void) hr = IMFMediaStream_RequestSample(video_stream, NULL); if (i == sample_count) break; @@ -29,7 +29,7 @@ index c26c40d531..a9408c998c 100644 for (i = 0; i < sample_count; ++i) { -@@ -622,7 +619,6 @@ todo_wine +@@ -669,7 +666,6 @@ todo_wine get_event((IMFMediaEventGenerator *)mediasource, MEEndOfPresentation, NULL); @@ -38,22 +38,22 @@ index c26c40d531..a9408c998c 100644 IMFMediaTypeHandler_Release(handler); IMFPresentationDescriptor_Release(descriptor); diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h -index 780cf1b02f..823e023f52 100644 +index d0628cc8df3..664733c74cd 100644 --- a/dlls/winegstreamer/gst_private.h +++ b/dlls/winegstreamer/gst_private.h -@@ -57,6 +57,7 @@ extern HRESULT mfplat_get_class_object(REFCLSID rclsid, REFIID riid, void **obj) - +@@ -59,6 +59,7 @@ HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj) DECLSPEC_HI GstCaps *make_mf_compatible_caps(GstCaps *caps); IMFMediaType *mf_media_type_from_caps(GstCaps *caps); + GstCaps *caps_from_mf_media_type(IMFMediaType *type); +IMFSample *mf_sample_from_gst_buffer(GstBuffer *in); - enum source_type - { + HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj) DECLSPEC_HIDDEN; + diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c -index a412786d33..46e85626a0 100644 +index c893664fbec..15ad1796563 100644 --- a/dlls/winegstreamer/media_source.c +++ b/dlls/winegstreamer/media_source.c -@@ -56,6 +56,7 @@ struct media_stream +@@ -67,6 +67,7 @@ struct media_stream enum source_async_op { SOURCE_ASYNC_START, @@ -61,7 +61,7 @@ index a412786d33..46e85626a0 100644 }; struct source_async_command -@@ -71,6 +72,11 @@ struct source_async_command +@@ -82,6 +83,11 @@ struct source_async_command GUID format; PROPVARIANT position; } start; @@ -73,17 +73,16 @@ index a412786d33..46e85626a0 100644 } u; }; -@@ -306,6 +312,78 @@ static HRESULT start_pipeline(struct media_source *source, struct source_async_c +@@ -341,6 +347,78 @@ static HRESULT start_pipeline(struct media_source *source, struct source_async_c return S_OK; } +static void dispatch_end_of_presentation(struct media_source *source) +{ + PROPVARIANT empty = {.vt = VT_EMPTY}; -+ unsigned int i; + + /* A stream has ended, check whether all have */ -+ for (i = 0; i < source->stream_count; i++) ++ for (unsigned int i = 0; i < source->stream_count; i++) + { + struct media_stream *stream = source->streams[i]; + @@ -124,7 +123,7 @@ index a412786d33..46e85626a0 100644 + TRACE("sample info %s\n", debugstr_a(sample_info_str)); + g_free(sample_info_str); + } -+ TRACE("PTS = %lu DTS = %llu\n", GST_BUFFER_PTS(buffer), GST_BUFFER_DTS(buffer)); ++ TRACE("PTS = %lu DTS = %lu\n", GST_BUFFER_PTS(buffer), GST_BUFFER_DTS(buffer)); + } + + sample = mf_sample_from_gst_buffer(buffer); @@ -134,6 +133,7 @@ index a412786d33..46e85626a0 100644 + IMFSample_SetUnknown(sample, &MFSampleExtension_Token, token); + + IMFMediaEventQueue_QueueEventParamUnk(stream->event_queue, MEMediaSample, &GUID_NULL, S_OK, (IUnknown *)sample); ++ IMFSample_Release(sample); + } + + g_object_get(stream->appsink, "eos", &stream->eos, NULL); @@ -152,7 +152,7 @@ index a412786d33..46e85626a0 100644 static HRESULT WINAPI source_async_commands_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result) { struct media_source *source = impl_from_async_commands_callback_IMFAsyncCallback(iface); -@@ -325,6 +403,9 @@ static HRESULT WINAPI source_async_commands_Invoke(IMFAsyncCallback *iface, IMFA +@@ -360,6 +438,9 @@ static HRESULT WINAPI source_async_commands_Invoke(IMFAsyncCallback *iface, IMFA case SOURCE_ASYNC_START: start_pipeline(source, command); break; @@ -162,26 +162,7 @@ index a412786d33..46e85626a0 100644 default: ; } -@@ -347,12 +428,14 @@ static const IMFAsyncCallbackVtbl source_async_commands_callback_vtbl = - static GstFlowReturn stream_new_sample(GstElement *appsink, gpointer user) - { - struct media_stream *stream = (struct media_stream *) user; -- GstSample *discard_sample; - -- TRACE("(%p) got sample\n", stream); -+ if (stream->state == STREAM_INACTIVE) -+ { -+ GstSample *discard_sample; -+ g_signal_emit_by_name(stream->appsink, "pull-sample", &discard_sample); -+ gst_sample_unref(discard_sample); -+ } - -- g_signal_emit_by_name(stream->appsink, "pull-sample", &discard_sample); -- gst_sample_unref(discard_sample); - return GST_FLOW_OK; - } - -@@ -773,13 +856,37 @@ static HRESULT WINAPI media_stream_GetStreamDescriptor(IMFMediaStream* iface, IM +@@ -694,13 +775,37 @@ static HRESULT WINAPI media_stream_GetStreamDescriptor(IMFMediaStream* iface, IM static HRESULT WINAPI media_stream_RequestSample(IMFMediaStream *iface, IUnknown *token) { struct media_stream *stream = impl_from_IMFMediaStream(iface); @@ -194,7 +175,7 @@ index a412786d33..46e85626a0 100644 return MF_E_SHUTDOWN; - return E_NOTIMPL; -+ if (stream->state == STREAM_INACTIVE || stream->state == STREAM_ENABLED) ++ if (stream->state == STREAM_INACTIVE) + { + WARN("Stream isn't active\n"); + return MF_E_MEDIA_SOURCE_WRONGSTATE; @@ -220,23 +201,22 @@ index a412786d33..46e85626a0 100644 } static const IMFMediaStreamVtbl media_stream_vtbl = -@@ -901,6 +1008,7 @@ static HRESULT media_stream_constructor(struct media_source *source, GstPad *pad - object->their_src = pad; +@@ -873,6 +978,7 @@ static HRESULT new_media_stream(struct media_source *source, GstPad *pad, DWORD + object->stream_id = stream_id; - object->state = STREAM_INACTIVE; + object->state = STREAM_STUB; + object->eos = FALSE; - if (FAILED(hr = MFCreateEventQueue(&object->event_queue))) - goto fail; + object->caps_event = CreateEventA(NULL, TRUE, FALSE, NULL); + diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c -index fa24bcb8d9..5ba9495939 100644 +index b291b21e8b5..839f337538d 100644 --- a/dlls/winegstreamer/mfplat.c +++ b/dlls/winegstreamer/mfplat.c -@@ -903,4 +903,95 @@ GstCaps *make_mf_compatible_caps(GstCaps *caps) - } - - return ret; -+} +@@ -1247,3 +1247,93 @@ GstCaps *caps_from_mf_media_type(IMFMediaType *type) + FIXME("Unrecognized major type %s\n", debugstr_guid(&major_type)); + return NULL; + } + +/* IMFSample = GstBuffer + IMFBuffer = GstMemory */ @@ -253,7 +233,6 @@ index fa24bcb8d9..5ba9495939 100644 + LONGLONG duration, time; + int buffer_count; + HRESULT hr; -+ unsigned int i; + + if (FAILED(hr = MFCreateSample(&out))) + goto fail; @@ -269,7 +248,7 @@ index fa24bcb8d9..5ba9495939 100644 + + buffer_count = gst_buffer_n_memory(gst_buffer); + -+ for (i = 0; i < buffer_count; i++) ++ for (unsigned int i = 0; i < buffer_count; i++) + { + GstMemory *memory = gst_buffer_get_memory(gst_buffer, i); + IMFMediaBuffer *mf_buffer = NULL; @@ -327,8 +306,7 @@ index fa24bcb8d9..5ba9495939 100644 + ERR("Failed to copy IMFSample to GstBuffer, hr = %#x\n", hr); + IMFSample_Release(out); + return NULL; - } -\ No newline at end of file ++} -- 2.28.0 diff --git a/patches/mfplat-streaming-support/0020-winegstreamer-Insert-parser-into-pipeline-to-rectify.patch b/patches/mfplat-streaming-support/0020-winegstreamer-Insert-parser-into-pipeline-to-rectify.patch deleted file mode 100644 index e3d9321d..00000000 --- a/patches/mfplat-streaming-support/0020-winegstreamer-Insert-parser-into-pipeline-to-rectify.patch +++ /dev/null @@ -1,179 +0,0 @@ -From cb6513ea1aafad23b5c16ddb6fc287e9a0bf8a0c Mon Sep 17 00:00:00 2001 -From: Derek Lesho -Date: Tue, 31 Mar 2020 15:11:31 -0500 -Subject: [PATCH 20/54] winegstreamer: Insert parser into pipeline to rectify - type differences. - -It's probably better to use caps negotiation here, but this seemed simpler for now. - -Signed-off-by: Derek Lesho ---- - dlls/winegstreamer/media_source.c | 114 ++++++++++++++++++++++++------ - 1 file changed, 91 insertions(+), 23 deletions(-) - -diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c -index abf0cfd56f..cb247adcef 100644 ---- a/dlls/winegstreamer/media_source.c -+++ b/dlls/winegstreamer/media_source.c -@@ -578,7 +578,6 @@ static void source_stream_added(GstElement *element, GstPad *pad, gpointer user) - { - ERR("Error linking demuxer to stream %p, err = %d\n", existing_stream, ret); - } -- gst_element_sync_state_with_parent(existing_stream->appsink); - - goto leave; - } -@@ -794,12 +793,99 @@ static const IMFMediaStreamVtbl media_stream_vtbl = - media_stream_RequestSample - }; - -+/* TODO: Use gstreamer caps negotiation */ -+/* connects their_src to appsink */ -+static HRESULT media_stream_align_with_mf(struct media_stream *stream, IMFMediaType **stream_type) -+{ -+ GstCaps *source_caps = NULL; -+ GstCaps *target_caps = NULL; -+ GstElement *parser = NULL; -+ HRESULT hr = E_FAIL; -+ -+ if (!(source_caps = gst_pad_query_caps(stream->their_src, NULL))) -+ goto done; -+ if (!(target_caps = make_mf_compatible_caps(source_caps))) -+ goto done; -+ -+ if (TRACE_ON(mfplat)) -+ { -+ gchar *source_caps_str = gst_caps_to_string(source_caps), *target_caps_str = gst_caps_to_string(target_caps); -+ TRACE("source caps %s\ntarget caps %s\n", debugstr_a(source_caps_str), debugstr_a(target_caps_str)); -+ g_free(source_caps_str); -+ g_free(target_caps_str); -+ } -+ -+ g_object_set(stream->appsink, "caps", target_caps, NULL); -+ -+ if (!(gst_caps_is_equal(source_caps, target_caps))) -+ { -+ GList *parser_list_one, *parser_list_two; -+ GstElementFactory *parser_factory; -+ -+ parser_list_one = gst_element_factory_list_get_elements(GST_ELEMENT_FACTORY_TYPE_PARSER, 1); -+ -+ parser_list_two = gst_element_factory_list_filter(parser_list_one, source_caps, GST_PAD_SINK, 0); -+ gst_plugin_feature_list_free(parser_list_one); -+ parser_list_one = parser_list_two; -+ -+ parser_list_two = gst_element_factory_list_filter(parser_list_one, target_caps, GST_PAD_SRC, 0); -+ gst_plugin_feature_list_free(parser_list_one); -+ parser_list_one = parser_list_two; -+ -+ if (!(g_list_length(parser_list_one))) -+ { -+ gst_plugin_feature_list_free(parser_list_one); -+ ERR("Failed to find parser for stream\n"); -+ hr = E_FAIL; -+ goto done; -+ } -+ -+ parser_factory = g_list_first(parser_list_one)->data; -+ TRACE("Found parser %s.\n", GST_ELEMENT_NAME(parser_factory)); -+ -+ parser = gst_element_factory_create(parser_factory, NULL); -+ -+ gst_plugin_feature_list_free(parser_list_one); -+ -+ if (!parser) -+ { -+ hr = E_FAIL; -+ goto done; -+ } -+ -+ gst_bin_add(GST_BIN(stream->parent_source->container), parser); -+ -+ assert(gst_pad_link(stream->their_src, gst_element_get_static_pad(parser, "sink")) == GST_PAD_LINK_OK); -+ -+ assert(gst_element_link(parser, stream->appsink)); -+ -+ gst_element_sync_state_with_parent(parser); -+ } -+ else -+ { -+ assert(gst_pad_link(stream->their_src, gst_element_get_static_pad(stream->appsink, "sink")) == GST_PAD_LINK_OK); -+ } -+ -+ stream->my_sink = gst_element_get_static_pad(parser ? parser : stream->appsink, "sink"); -+ -+ *stream_type = mf_media_type_from_caps(target_caps); -+ -+ hr = S_OK; -+ -+ done: -+ if (source_caps) -+ gst_caps_unref(source_caps); -+ if (target_caps) -+ gst_caps_unref(target_caps); -+ -+ return hr; -+} -+ - static HRESULT media_stream_constructor(struct media_source *source, GstPad *pad, DWORD stream_id, struct media_stream **out_stream) - { - struct media_stream *object = heap_alloc_zero(sizeof(*object)); - IMFMediaTypeHandler *type_handler = NULL; - IMFMediaType *stream_type = NULL; -- GstCaps *caps = NULL; - HRESULT hr; - - TRACE("(%p %p)->(%p)\n", source, pad, out_stream); -@@ -828,22 +914,9 @@ static HRESULT media_stream_constructor(struct media_source *source, GstPad *pad - g_object_set(object->appsink, "async", FALSE, NULL); /* <- This allows us interact with the bin w/o prerolling */ - g_signal_connect(object->appsink, "new-sample", G_CALLBACK(stream_new_sample_wrapper), object); - -- if (!(caps = gst_pad_query_caps(pad, NULL))) -+ if (FAILED(hr = media_stream_align_with_mf(object, &stream_type))) - goto fail; - -- if (TRACE_ON(mfplat)) -- { -- gchar *caps_str = gst_caps_to_string(caps); -- TRACE("caps %s\n", debugstr_a(caps_str)); -- g_free(caps_str); -- } -- -- if (!(stream_type = mf_media_type_from_caps(caps))) -- goto fail; -- -- gst_caps_unref(caps); -- caps = NULL; -- - if (FAILED(hr = MFCreateStreamDescriptor(stream_id, 1, &stream_type, &object->descriptor))) - goto fail; - -@@ -858,23 +931,18 @@ static HRESULT media_stream_constructor(struct media_source *source, GstPad *pad - IMFMediaType_Release(stream_type); - stream_type = NULL; - -- object->my_sink = gst_element_get_static_pad(object->appsink, "sink"); -- gst_pad_set_element_private(pad, object); -- -- gst_pad_link(object->their_src, object->my_sink); -+ gst_pad_set_element_private(object->their_src, object); - - gst_element_sync_state_with_parent(object->appsink); - - TRACE("->(%p)\n", object); -- - *out_stream = object; -+ - return S_OK; - - fail: - WARN("Failed to construct media stream, hr %#x.\n", hr); - -- if (caps) -- gst_caps_unref(caps); - if (stream_type) - IMFMediaType_Release(stream_type); - if (type_handler) --- -2.28.0 - diff --git a/patches/mfplat-streaming-support/0022-winegstreamer-Implement-IMFMediaSource-GetCharacteri.patch b/patches/mfplat-streaming-support/0021-winegstreamer-Implement-IMFMediaSource-GetCharacteri.patch similarity index 82% rename from patches/mfplat-streaming-support/0022-winegstreamer-Implement-IMFMediaSource-GetCharacteri.patch rename to patches/mfplat-streaming-support/0021-winegstreamer-Implement-IMFMediaSource-GetCharacteri.patch index 63fe11a0..b97a5a84 100644 --- a/patches/mfplat-streaming-support/0022-winegstreamer-Implement-IMFMediaSource-GetCharacteri.patch +++ b/patches/mfplat-streaming-support/0021-winegstreamer-Implement-IMFMediaSource-GetCharacteri.patch @@ -1,7 +1,7 @@ -From ffaf4ac88336833aa64b83b9edcd0c23b3f1bdbb Mon Sep 17 00:00:00 2001 +From 625df79a05531671aeea9947ccd393372d32f6c1 Mon Sep 17 00:00:00 2001 From: Derek Lesho Date: Tue, 31 Mar 2020 15:15:07 -0500 -Subject: [PATCH 22/54] winegstreamer: Implement +Subject: [PATCH 21/52] winegstreamer: Implement IMFMediaSource::GetCharacteristics. Signed-off-by: Derek Lesho @@ -10,10 +10,10 @@ Signed-off-by: Derek Lesho 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c -index b6f2fcc8fa..675ee9bd20 100644 +index 15ad1796563..b163472947b 100644 --- a/dlls/winegstreamer/media_source.c +++ b/dlls/winegstreamer/media_source.c -@@ -1160,12 +1160,14 @@ static HRESULT WINAPI media_source_GetCharacteristics(IMFMediaSource *iface, DWO +@@ -1216,12 +1216,14 @@ static HRESULT WINAPI media_source_GetCharacteristics(IMFMediaSource *iface, DWO { struct media_source *source = impl_from_IMFMediaSource(iface); diff --git a/patches/mfplat-streaming-support/0023-winegstreamer-Calculate-the-MF_PD_DURATION-of-the-me.patch b/patches/mfplat-streaming-support/0022-winegstreamer-Calculate-the-MF_PD_DURATION-of-the-me.patch similarity index 83% rename from patches/mfplat-streaming-support/0023-winegstreamer-Calculate-the-MF_PD_DURATION-of-the-me.patch rename to patches/mfplat-streaming-support/0022-winegstreamer-Calculate-the-MF_PD_DURATION-of-the-me.patch index af444129..3a3530dc 100644 --- a/patches/mfplat-streaming-support/0023-winegstreamer-Calculate-the-MF_PD_DURATION-of-the-me.patch +++ b/patches/mfplat-streaming-support/0022-winegstreamer-Calculate-the-MF_PD_DURATION-of-the-me.patch @@ -1,8 +1,8 @@ -From 1d89dafdbc1c1d4df93121e41354d4607811a27b Mon Sep 17 00:00:00 2001 +From 516f67ab33c1b418fa621a059ce0a5576b92cac1 Mon Sep 17 00:00:00 2001 From: Derek Lesho Date: Tue, 31 Mar 2020 15:15:50 -0500 -Subject: [PATCH] winegstreamer: Calculate the MF_PD_DURATION of the media - source's PD. +Subject: [PATCH 22/52] winegstreamer: Calculate the MF_PD_DURATION of the + media source's PD. Signed-off-by: Derek Lesho --- @@ -10,10 +10,10 @@ Signed-off-by: Derek Lesho 1 file changed, 40 insertions(+) diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c -index 230aa8a9f6..2039115dfe 100644 +index b163472947b..9c546bc4ac5 100644 --- a/dlls/winegstreamer/media_source.c +++ b/dlls/winegstreamer/media_source.c -@@ -1430,6 +1430,46 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, enum source_t +@@ -1594,6 +1594,46 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_ heap_free(descriptors); descriptors = NULL; @@ -34,7 +34,7 @@ index 230aa8a9f6..2039115dfe 100644 + IMFAttributes_Release(byte_stream_attributes); + } + -+ for (i = 0; i < object->stream_count; i++) ++ for (unsigned int i = 0; i < object->stream_count; i++) + { + GstQuery *query = gst_query_new_duration(GST_FORMAT_TIME); + if (gst_pad_query(object->streams[i]->their_src, query)) @@ -57,9 +57,9 @@ index 230aa8a9f6..2039115dfe 100644 + IMFPresentationDescriptor_SetUINT64(object->pres_desc, &MF_PD_DURATION, total_pres_time / 100); + } + - gst_element_set_state(object->container, GST_STATE_READY); - object->state = SOURCE_STOPPED; + + *out_media_source = object; -- 2.28.0 diff --git a/patches/mfplat-streaming-support/0024-tools-Add-support-for-multiple-parent-directories.patch b/patches/mfplat-streaming-support/0023-tools-Add-support-for-multiple-parent-directories.patch similarity index 94% rename from patches/mfplat-streaming-support/0024-tools-Add-support-for-multiple-parent-directories.patch rename to patches/mfplat-streaming-support/0023-tools-Add-support-for-multiple-parent-directories.patch index 8fc9b592..98a2ed48 100644 --- a/patches/mfplat-streaming-support/0024-tools-Add-support-for-multiple-parent-directories.patch +++ b/patches/mfplat-streaming-support/0023-tools-Add-support-for-multiple-parent-directories.patch @@ -1,7 +1,7 @@ -From 97507c173539685376d1cad7782529b8394d7cd0 Mon Sep 17 00:00:00 2001 +From 7824e15960e00ffb11adae1a1e683aa1487f6317 Mon Sep 17 00:00:00 2001 From: Derek Lesho Date: Wed, 29 Jan 2020 15:37:39 -0600 -Subject: [PATCH 24/54] tools: Add support for multiple parent directories. +Subject: [PATCH 23/52] tools: Add support for multiple parent directories. Signed-off-by: Derek Lesho --- @@ -10,7 +10,7 @@ Signed-off-by: Derek Lesho 2 files changed, 49 insertions(+), 26 deletions(-) diff --git a/tools/make_makefiles b/tools/make_makefiles -index c18fa90e2d..1e34a280a4 100755 +index c18fa90e2d3..1e34a280a40 100755 --- a/tools/make_makefiles +++ b/tools/make_makefiles @@ -231,14 +231,14 @@ sub parse_makefile($) @@ -91,17 +91,17 @@ index c18fa90e2d..1e34a280a4 100755 } diff --git a/tools/makedep.c b/tools/makedep.c -index 825458156f..f76747e00a 100644 +index 4bd20d469d6..a67add38afa 100644 --- a/tools/makedep.c +++ b/tools/makedep.c -@@ -183,6 +183,7 @@ struct makefile - struct strarray install_lib; +@@ -184,6 +184,7 @@ struct makefile struct strarray install_dev; struct strarray extra_targets; -+ struct strarray parent_dirs; struct strarray extra_imports; ++ struct strarray parent_dirs; struct list sources; struct list includes; + const char *base_dir; @@ -191,7 +192,6 @@ struct makefile const char *obj_dir; const char *top_src_dir; @@ -140,7 +140,7 @@ index 825458156f..f76747e00a 100644 } if (ret) *filename = src_dir_path( make, path ); -@@ -4271,13 +4280,13 @@ static void load_sources( struct makefile *make ) +@@ -4275,13 +4284,13 @@ static void load_sources( struct makefile *make ) strarray_set_value( &make->vars, "top_srcdir", top_src_dir_path( make, "" )); strarray_set_value( &make->vars, "srcdir", src_dir_path( make, "" )); @@ -155,7 +155,7 @@ index 825458156f..f76747e00a 100644 make->programs = get_expanded_make_var_array( make, "PROGRAMS" ); make->scripts = get_expanded_make_var_array( make, "SCRIPTS" ); make->imports = get_expanded_make_var_array( make, "IMPORTS" ); -@@ -4322,8 +4331,11 @@ static void load_sources( struct makefile *make ) +@@ -4326,8 +4335,11 @@ static void load_sources( struct makefile *make ) strarray_add( &make->include_args, strmake( "-I%s", obj_dir_path( make, "" ))); if (make->src_dir) strarray_add( &make->include_args, strmake( "-I%s", make->src_dir )); diff --git a/patches/mfplat-streaming-support/0025-mf-Introduce-handler-helper.patch b/patches/mfplat-streaming-support/0024-mf-Introduce-handler-helper.patch similarity index 87% rename from patches/mfplat-streaming-support/0025-mf-Introduce-handler-helper.patch rename to patches/mfplat-streaming-support/0024-mf-Introduce-handler-helper.patch index a24d4928..ab26a84c 100644 --- a/patches/mfplat-streaming-support/0025-mf-Introduce-handler-helper.patch +++ b/patches/mfplat-streaming-support/0024-mf-Introduce-handler-helper.patch @@ -1,7 +1,7 @@ -From e59d4b4a0867077b49e9172f2d27faeea54835d0 Mon Sep 17 00:00:00 2001 +From 8b0d448ce8e7c3698f7b77dd687fea0676c392c7 Mon Sep 17 00:00:00 2001 From: Derek Lesho Date: Wed, 29 Jan 2020 15:30:49 -0600 -Subject: [PATCH 25/54] mf: Introduce handler helper. +Subject: [PATCH 24/52] mf: Introduce handler helper. Signed-off-by: Derek Lesho --- @@ -16,20 +16,20 @@ Signed-off-by: Derek Lesho create mode 100644 dlls/mf/handler.h diff --git a/dlls/mf/Makefile.in b/dlls/mf/Makefile.in -index b64cdb4a64..f5261e64cd 100644 +index b64cdb4a64d..c0a4a876e0b 100644 --- a/dlls/mf/Makefile.in +++ b/dlls/mf/Makefile.in -@@ -5,6 +5,7 @@ IMPORTS = advapi32 mfplat ole32 uuid mfuuid strmiids - EXTRADLLFLAGS = -mno-cygwin +@@ -6,6 +6,7 @@ EXTRADLLFLAGS = -mno-cygwin C_SRCS = \ -+ handler.c \ evr.c \ ++ handler.c \ main.c \ samplegrabber.c \ + sar.c \ diff --git a/dlls/mf/handler.c b/dlls/mf/handler.c new file mode 100644 -index 0000000000..da40049377 +index 00000000000..da40049377e --- /dev/null +++ b/dlls/mf/handler.c @@ -0,0 +1,360 @@ @@ -396,7 +396,7 @@ index 0000000000..da40049377 \ No newline at end of file diff --git a/dlls/mf/handler.h b/dlls/mf/handler.h new file mode 100644 -index 0000000000..fbebd26e8d +index 00000000000..fbebd26e8d0 --- /dev/null +++ b/dlls/mf/handler.h @@ -0,0 +1,30 @@ @@ -432,7 +432,7 @@ index 0000000000..fbebd26e8d +HRESULT handler_cancel_object_creation(struct handler *handler, IUnknown *cancel_cookie); \ No newline at end of file diff --git a/dlls/mf/main.c b/dlls/mf/main.c -index 5326425813..ebcaef4cad 100644 +index 53264258137..ebcaef4cad3 100644 --- a/dlls/mf/main.c +++ b/dlls/mf/main.c @@ -27,6 +27,7 @@ @@ -913,7 +913,7 @@ index 5326425813..ebcaef4cad 100644 return hr; } diff --git a/dlls/winegstreamer/Makefile.in b/dlls/winegstreamer/Makefile.in -index e578d194f7..f2e8749445 100644 +index e578d194f7f..f2e87494459 100644 --- a/dlls/winegstreamer/Makefile.in +++ b/dlls/winegstreamer/Makefile.in @@ -3,12 +3,13 @@ IMPORTS = strmiids uuid ole32 mfuuid @@ -932,10 +932,10 @@ index e578d194f7..f2e8749445 100644 media_source.c \ mediatype.c \ diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c -index 5811baf0c0..c30b5e9ef0 100644 +index 9c546bc4ac5..ca799446ad8 100644 --- a/dlls/winegstreamer/media_source.c +++ b/dlls/winegstreamer/media_source.c -@@ -4,6 +4,7 @@ +@@ -23,6 +23,7 @@ #include "gst_private.h" #include "gst_cbs.h" @@ -943,11 +943,11 @@ index 5811baf0c0..c30b5e9ef0 100644 #include #include -@@ -1485,22 +1486,12 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, enum source_t +@@ -1648,21 +1649,11 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_ + return hr; + } - /* IMFByteStreamHandler */ - --struct container_stream_handler_result +-struct winegstreamer_stream_handler_result -{ - struct list entry; - IMFAsyncResult *result; @@ -955,43 +955,42 @@ index 5811baf0c0..c30b5e9ef0 100644 - IUnknown *object; -}; - - struct container_stream_handler + struct winegstreamer_stream_handler { IMFByteStreamHandler IMFByteStreamHandler_iface; - IMFAsyncCallback IMFAsyncCallback_iface; LONG refcount; - enum source_type type; - struct list results; - CRITICAL_SECTION cs; + struct handler handler; }; - static struct container_stream_handler *impl_from_IMFByteStreamHandler(IMFByteStreamHandler *iface) -@@ -1508,11 +1499,6 @@ static struct container_stream_handler *impl_from_IMFByteStreamHandler(IMFByteSt - return CONTAINING_RECORD(iface, struct container_stream_handler, IMFByteStreamHandler_iface); + static struct winegstreamer_stream_handler *impl_from_IMFByteStreamHandler(IMFByteStreamHandler *iface) +@@ -1670,11 +1661,6 @@ static struct winegstreamer_stream_handler *impl_from_IMFByteStreamHandler(IMFBy + return CONTAINING_RECORD(iface, struct winegstreamer_stream_handler, IMFByteStreamHandler_iface); } --static struct container_stream_handler *impl_from_IMFAsyncCallback(IMFAsyncCallback *iface) +-static struct winegstreamer_stream_handler *impl_from_IMFAsyncCallback(IMFAsyncCallback *iface) -{ -- return CONTAINING_RECORD(iface, struct container_stream_handler, IMFAsyncCallback_iface); +- return CONTAINING_RECORD(iface, struct winegstreamer_stream_handler, IMFAsyncCallback_iface); -} - - static HRESULT WINAPI container_stream_handler_QueryInterface(IMFByteStreamHandler *iface, REFIID riid, void **obj) + static HRESULT WINAPI winegstreamer_stream_handler_QueryInterface(IMFByteStreamHandler *iface, REFIID riid, void **obj) { TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj); -@@ -1542,248 +1528,44 @@ static ULONG WINAPI container_stream_handler_AddRef(IMFByteStreamHandler *iface) +@@ -1704,248 +1690,44 @@ static ULONG WINAPI winegstreamer_stream_handler_AddRef(IMFByteStreamHandler *if - static ULONG WINAPI container_stream_handler_Release(IMFByteStreamHandler *iface) + static ULONG WINAPI winegstreamer_stream_handler_Release(IMFByteStreamHandler *iface) { -- struct container_stream_handler *handler = impl_from_IMFByteStreamHandler(iface); +- struct winegstreamer_stream_handler *handler = impl_from_IMFByteStreamHandler(iface); - ULONG refcount = InterlockedDecrement(&handler->refcount); -- struct container_stream_handler_result *result, *next; +- struct winegstreamer_stream_handler_result *result, *next; - - TRACE("%p, refcount %u.\n", iface, refcount); - - if (!refcount) - { -- LIST_FOR_EACH_ENTRY_SAFE(result, next, &handler->results, struct container_stream_handler_result, entry) +- LIST_FOR_EACH_ENTRY_SAFE(result, next, &handler->results, struct winegstreamer_stream_handler_result, entry) - { - list_remove(&result->entry); - IMFAsyncResult_Release(result->result); @@ -1052,7 +1051,7 @@ index 5811baf0c0..c30b5e9ef0 100644 -{ - struct create_object_context *context = impl_from_IUnknown(iface); - ULONG refcount = InterlockedDecrement(&context->refcount); -+ struct container_stream_handler *this = impl_from_IMFByteStreamHandler(iface); ++ struct winegstreamer_stream_handler *this = impl_from_IMFByteStreamHandler(iface); + ULONG refcount = InterlockedDecrement(&this->refcount); TRACE("%p, refcount %u.\n", iface, refcount); @@ -1097,10 +1096,10 @@ index 5811baf0c0..c30b5e9ef0 100644 - return ret; -} - - static HRESULT WINAPI container_stream_handler_BeginCreateObject(IMFByteStreamHandler *iface, IMFByteStream *stream, const WCHAR *url, DWORD flags, + static HRESULT WINAPI winegstreamer_stream_handler_BeginCreateObject(IMFByteStreamHandler *iface, IMFByteStream *stream, const WCHAR *url, DWORD flags, IPropertyStore *props, IUnknown **cancel_cookie, IMFAsyncCallback *callback, IUnknown *state) { - struct container_stream_handler *this = impl_from_IMFByteStreamHandler(iface); + struct winegstreamer_stream_handler *this = impl_from_IMFByteStreamHandler(iface); - struct create_object_context *context; - IMFAsyncResult *caller, *item; - HRESULT hr; @@ -1159,18 +1158,18 @@ index 5811baf0c0..c30b5e9ef0 100644 + return handler_begin_create_object(&this->handler, stream, url, flags, props, cancel_cookie, callback, state); } - static HRESULT WINAPI container_stream_handler_EndCreateObject(IMFByteStreamHandler *iface, IMFAsyncResult *result, + static HRESULT WINAPI winegstreamer_stream_handler_EndCreateObject(IMFByteStreamHandler *iface, IMFAsyncResult *result, MF_OBJECT_TYPE *obj_type, IUnknown **object) { - struct container_stream_handler *this = impl_from_IMFByteStreamHandler(iface); -- struct container_stream_handler_result *found = NULL, *cur; + struct winegstreamer_stream_handler *this = impl_from_IMFByteStreamHandler(iface); +- struct winegstreamer_stream_handler_result *found = NULL, *cur; - HRESULT hr; TRACE("%p, %p, %p, %p.\n", iface, result, obj_type, object); - - EnterCriticalSection(&this->cs); - -- LIST_FOR_EACH_ENTRY(cur, &this->results, struct container_stream_handler_result, entry) +- LIST_FOR_EACH_ENTRY(cur, &this->results, struct winegstreamer_stream_handler_result, entry) - { - if (result == cur->result) - { @@ -1201,16 +1200,16 @@ index 5811baf0c0..c30b5e9ef0 100644 + return handler_end_create_object(&this->handler, result, obj_type, object); } - static HRESULT WINAPI container_stream_handler_CancelObjectCreation(IMFByteStreamHandler *iface, IUnknown *cancel_cookie) + static HRESULT WINAPI winegstreamer_stream_handler_CancelObjectCreation(IMFByteStreamHandler *iface, IUnknown *cancel_cookie) { - struct container_stream_handler *this = impl_from_IMFByteStreamHandler(iface); -- struct container_stream_handler_result *found = NULL, *cur; + struct winegstreamer_stream_handler *this = impl_from_IMFByteStreamHandler(iface); +- struct winegstreamer_stream_handler_result *found = NULL, *cur; TRACE("%p, %p.\n", iface, cancel_cookie); - - EnterCriticalSection(&this->cs); - -- LIST_FOR_EACH_ENTRY(cur, &this->results, struct container_stream_handler_result, entry) +- LIST_FOR_EACH_ENTRY(cur, &this->results, struct winegstreamer_stream_handler_result, entry) - { - if (cancel_cookie == (IUnknown *)cur->result) - { @@ -1234,12 +1233,12 @@ index 5811baf0c0..c30b5e9ef0 100644 + return handler_cancel_object_creation(&this->handler, cancel_cookie); } - static HRESULT WINAPI container_stream_handler_GetMaxNumberOfBytesRequiredForResolution(IMFByteStreamHandler *iface, QWORD *bytes) -@@ -1803,47 +1585,16 @@ static const IMFByteStreamHandlerVtbl container_stream_handler_vtbl = - container_stream_handler_GetMaxNumberOfBytesRequiredForResolution, + static HRESULT WINAPI winegstreamer_stream_handler_GetMaxNumberOfBytesRequiredForResolution(IMFByteStreamHandler *iface, QWORD *bytes) +@@ -1965,47 +1747,16 @@ static const IMFByteStreamHandlerVtbl winegstreamer_stream_handler_vtbl = + winegstreamer_stream_handler_GetMaxNumberOfBytesRequiredForResolution, }; --static HRESULT WINAPI container_stream_handler_callback_QueryInterface(IMFAsyncCallback *iface, REFIID riid, void **obj) +-static HRESULT WINAPI winegstreamer_stream_handler_callback_QueryInterface(IMFAsyncCallback *iface, REFIID riid, void **obj) -{ - if (IsEqualIID(riid, &IID_IMFAsyncCallback) || - IsEqualIID(riid, &IID_IUnknown)) @@ -1254,25 +1253,25 @@ index 5811baf0c0..c30b5e9ef0 100644 - return E_NOINTERFACE; -} - --static ULONG WINAPI container_stream_handler_callback_AddRef(IMFAsyncCallback *iface) +-static ULONG WINAPI winegstreamer_stream_handler_callback_AddRef(IMFAsyncCallback *iface) -{ -- struct container_stream_handler *handler = impl_from_IMFAsyncCallback(iface); +- struct winegstreamer_stream_handler *handler = impl_from_IMFAsyncCallback(iface); - return IMFByteStreamHandler_AddRef(&handler->IMFByteStreamHandler_iface); -} - --static ULONG WINAPI container_stream_handler_callback_Release(IMFAsyncCallback *iface) +-static ULONG WINAPI winegstreamer_stream_handler_callback_Release(IMFAsyncCallback *iface) -{ -- struct container_stream_handler *handler = impl_from_IMFAsyncCallback(iface); +- struct winegstreamer_stream_handler *handler = impl_from_IMFAsyncCallback(iface); - return IMFByteStreamHandler_Release(&handler->IMFByteStreamHandler_iface); -} - --static HRESULT WINAPI container_stream_handler_callback_GetParameters(IMFAsyncCallback *iface, DWORD *flags, DWORD *queue) +-static HRESULT WINAPI winegstreamer_stream_handler_callback_GetParameters(IMFAsyncCallback *iface, DWORD *flags, DWORD *queue) -{ - return E_NOTIMPL; -} - --static HRESULT container_stream_handler_create_object(struct container_stream_handler *This, WCHAR *url, IMFByteStream *stream, DWORD flags, -+static HRESULT container_stream_handler_create_object(struct handler *handler, WCHAR *url, IMFByteStream *stream, DWORD flags, +-static HRESULT winegstreamer_stream_handler_create_object(struct winegstreamer_stream_handler *This, WCHAR *url, IMFByteStream *stream, DWORD flags, ++static HRESULT winegstreamer_stream_handler_create_object(struct handler *handler, WCHAR *url, IMFByteStream *stream, DWORD flags, IPropertyStore *props, IUnknown **out_object, MF_OBJECT_TYPE *out_obj_type) { - TRACE("(%p %s %p %u %p %p %p)\n", This, debugstr_w(url), stream, flags, props, out_object, out_obj_type); @@ -1282,18 +1281,18 @@ index 5811baf0c0..c30b5e9ef0 100644 { HRESULT hr; struct media_source *new_source; -+ struct container_stream_handler *This = CONTAINING_RECORD(handler, struct container_stream_handler, handler); ++ struct winegstreamer_stream_handler *This = CONTAINING_RECORD(handler, struct winegstreamer_stream_handler, handler); - if (FAILED(hr = media_source_constructor(stream, This->type, &new_source))) + if (FAILED(hr = media_source_constructor(stream, &new_source))) return hr; -@@ -1862,64 +1613,6 @@ static HRESULT container_stream_handler_create_object(struct container_stream_ha +@@ -2024,64 +1775,6 @@ static HRESULT winegstreamer_stream_handler_create_object(struct winegstreamer_s } } --static HRESULT WINAPI container_stream_handler_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result) +-static HRESULT WINAPI winegstreamer_stream_handler_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result) -{ -- struct container_stream_handler *handler = impl_from_IMFAsyncCallback(iface); -- struct container_stream_handler_result *handler_result; +- struct winegstreamer_stream_handler *handler = impl_from_IMFAsyncCallback(iface); +- struct winegstreamer_stream_handler_result *handler_result; - MF_OBJECT_TYPE obj_type = MF_OBJECT_INVALID; - IUnknown *object = NULL, *context_object; - struct create_object_context *context; @@ -1310,7 +1309,7 @@ index 5811baf0c0..c30b5e9ef0 100644 - - context = impl_from_IUnknown(context_object); - -- hr = container_stream_handler_create_object(handler, context->url, context->stream, context->flags, context->props, &object, &obj_type); +- hr = winegstreamer_stream_handler_create_object(handler, context->url, context->stream, context->flags, context->props, &object, &obj_type); - - handler_result = heap_alloc(sizeof(*handler_result)); - if (handler_result) @@ -1339,29 +1338,28 @@ index 5811baf0c0..c30b5e9ef0 100644 - return S_OK; -} - --static const IMFAsyncCallbackVtbl container_stream_handler_callback_vtbl = +-static const IMFAsyncCallbackVtbl winegstreamer_stream_handler_callback_vtbl = -{ -- container_stream_handler_callback_QueryInterface, -- container_stream_handler_callback_AddRef, -- container_stream_handler_callback_Release, -- container_stream_handler_callback_GetParameters, -- container_stream_handler_callback_Invoke, +- winegstreamer_stream_handler_callback_QueryInterface, +- winegstreamer_stream_handler_callback_AddRef, +- winegstreamer_stream_handler_callback_Release, +- winegstreamer_stream_handler_callback_GetParameters, +- winegstreamer_stream_handler_callback_Invoke, -}; - - HRESULT container_stream_handler_construct(REFIID riid, void **obj, enum source_type type) + HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj) { - struct container_stream_handler *this; -@@ -1931,12 +1624,10 @@ HRESULT container_stream_handler_construct(REFIID riid, void **obj, enum source_ + struct winegstreamer_stream_handler *this; +@@ -2093,11 +1786,9 @@ HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj) if (!this) return E_OUTOFMEMORY; - list_init(&this->results); - InitializeCriticalSection(&this->cs); -+ handler_construct(&this->handler, container_stream_handler_create_object); ++ handler_construct(&this->handler, winegstreamer_stream_handler_create_object); - this->type = type; - this->IMFByteStreamHandler_iface.lpVtbl = &container_stream_handler_vtbl; -- this->IMFAsyncCallback_iface.lpVtbl = &container_stream_handler_callback_vtbl; + this->IMFByteStreamHandler_iface.lpVtbl = &winegstreamer_stream_handler_vtbl; +- this->IMFAsyncCallback_iface.lpVtbl = &winegstreamer_stream_handler_callback_vtbl; this->refcount = 1; hr = IMFByteStreamHandler_QueryInterface(&this->IMFByteStreamHandler_iface, riid, obj); diff --git a/patches/mfplat-streaming-support/0032-Introduce-IMFSample-GstBuffer-converter.patch b/patches/mfplat-streaming-support/0025-Introduce-IMFSample-GstBuffer-converter.patch similarity index 83% rename from patches/mfplat-streaming-support/0032-Introduce-IMFSample-GstBuffer-converter.patch rename to patches/mfplat-streaming-support/0025-Introduce-IMFSample-GstBuffer-converter.patch index a0fd11db..501e1578 100644 --- a/patches/mfplat-streaming-support/0032-Introduce-IMFSample-GstBuffer-converter.patch +++ b/patches/mfplat-streaming-support/0025-Introduce-IMFSample-GstBuffer-converter.patch @@ -1,35 +1,34 @@ -From e7f979743dec4e3753b7625a728c003625c24af2 Mon Sep 17 00:00:00 2001 +From bc33134566348dbd02788a8a203cd0b815056c06 Mon Sep 17 00:00:00 2001 From: Derek Lesho Date: Wed, 25 Mar 2020 10:43:27 -0500 -Subject: [PATCH] Introduce IMFSample -> GstBuffer converter. +Subject: [PATCH 25/52] Introduce IMFSample -> GstBuffer converter. Signed-off-by: Derek Lesho --- dlls/winegstreamer/gst_private.h | 1 + - dlls/winegstreamer/mfplat.c | 75 ++++++++++++++++++++++++++++++++ - 2 files changed, 76 insertions(+) + dlls/winegstreamer/mfplat.c | 74 ++++++++++++++++++++++++++++++++ + 2 files changed, 75 insertions(+) diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h -index 20d3beef02..258df0d040 100644 +index 664733c74cd..d0737442cc3 100644 --- a/dlls/winegstreamer/gst_private.h +++ b/dlls/winegstreamer/gst_private.h -@@ -59,6 +59,7 @@ GstCaps *make_mf_compatible_caps(GstCaps *caps); +@@ -60,6 +60,7 @@ GstCaps *make_mf_compatible_caps(GstCaps *caps); IMFMediaType *mf_media_type_from_caps(GstCaps *caps); GstCaps *caps_from_mf_media_type(IMFMediaType *type); IMFSample *mf_sample_from_gst_buffer(GstBuffer *in); +GstBuffer *gst_buffer_from_mf_sample(IMFSample *in); - enum source_type - { + HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj) DECLSPEC_HIDDEN; + diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c -index 8bffb6387e..fe8ba885e9 100644 +index 839f337538d..ae5dcc31825 100644 --- a/dlls/winegstreamer/mfplat.c +++ b/dlls/winegstreamer/mfplat.c -@@ -1299,4 +1299,79 @@ IMFSample* mf_sample_from_gst_buffer(GstBuffer *gst_buffer) - ERR("Failed to copy IMFSample to GstBuffer, hr = %#x\n", hr); +@@ -1337,3 +1337,77 @@ IMFSample* mf_sample_from_gst_buffer(GstBuffer *gst_buffer) IMFSample_Release(out); return NULL; -+} + } + +GstBuffer* gst_buffer_from_mf_sample(IMFSample *mf_sample) +{ @@ -38,7 +37,6 @@ index 8bffb6387e..fe8ba885e9 100644 + LONGLONG duration, time; + DWORD buffer_count; + HRESULT hr; -+ unsigned int i; + + if (FAILED(hr = IMFSample_GetSampleDuration(mf_sample, &duration))) + goto fail; @@ -52,7 +50,7 @@ index 8bffb6387e..fe8ba885e9 100644 + if (FAILED(hr = IMFSample_GetBufferCount(mf_sample, &buffer_count))) + goto fail; + -+ for (i = 0; i < buffer_count; i++) ++ for (unsigned int i = 0; i < buffer_count; i++) + { + DWORD buffer_max_size, buffer_size; + GstMapInfo map_info; @@ -104,8 +102,7 @@ index 8bffb6387e..fe8ba885e9 100644 + IMFMediaBuffer_Release(mf_buffer); + gst_buffer_unref(out); + return NULL; - } -\ No newline at end of file ++} -- 2.28.0 diff --git a/patches/mfplat-streaming-support/0035-Miscellaneous.patch b/patches/mfplat-streaming-support/0026-winegstreamer-Implement-decoder-MFT-on-gstreamer.patch similarity index 76% rename from patches/mfplat-streaming-support/0035-Miscellaneous.patch rename to patches/mfplat-streaming-support/0026-winegstreamer-Implement-decoder-MFT-on-gstreamer.patch index 55eee08a..cdf012fa 100644 --- a/patches/mfplat-streaming-support/0035-Miscellaneous.patch +++ b/patches/mfplat-streaming-support/0026-winegstreamer-Implement-decoder-MFT-on-gstreamer.patch @@ -1,251 +1,212 @@ -From 8d1b452fa4bd1967187eb82e12b95f3289ab514b Mon Sep 17 00:00:00 2001 +From f01c8a6745cefd98198e0401a359302aba45ba57 Mon Sep 17 00:00:00 2001 From: Derek Lesho -Date: Mon, 16 Mar 2020 15:27:27 -0500 -Subject: [PATCH] Miscellaneous +Date: Mon, 16 Mar 2020 12:09:39 -0500 +Subject: [PATCH 26/52] winegstreamer: Implement decoder MFT on gstreamer. --- - dlls/mfreadwrite/reader.c | 12 +- - dlls/winegstreamer/gst_cbs.c | 9 + - dlls/winegstreamer/media_source.c | 114 ++- - dlls/winegstreamer/mf_decode.c | 1324 +++++++++++++++++++++++++++++ - 4 files changed, 1456 insertions(+), 3 deletions(-) + dlls/winegstreamer/Makefile.in | 1 + + dlls/winegstreamer/gst_cbs.c | 65 + + dlls/winegstreamer/gst_cbs.h | 23 + + dlls/winegstreamer/gst_private.h | 7 + + dlls/winegstreamer/main.c | 3 +- + dlls/winegstreamer/mf_decode.c | 1321 ++++++++++++++++++ + dlls/winegstreamer/mfplat.c | 118 +- + dlls/winegstreamer/winegstreamer_classes.idl | 12 + + include/mfidl.idl | 2 + + 9 files changed, 1550 insertions(+), 2 deletions(-) create mode 100644 dlls/winegstreamer/mf_decode.c -diff --git a/dlls/mfreadwrite/reader.c b/dlls/mfreadwrite/reader.c -index 3b1dcbb963..f8c03e62d3 100644 ---- a/dlls/mfreadwrite/reader.c -+++ b/dlls/mfreadwrite/reader.c -@@ -1596,6 +1596,7 @@ static HRESULT source_reader_create_decoder_for_stream(struct source_reader *rea - { - MFT_REGISTER_TYPE_INFO in_type, out_type; - CLSID *clsids, mft_clsid, category; -+ BOOL decoder_found = FALSE; - unsigned int i = 0, count; - IMFMediaType *input_type; - HRESULT hr; -@@ -1642,12 +1643,21 @@ static HRESULT source_reader_create_decoder_for_stream(struct source_reader *rea - } - - } -+ else if (!decoder_found) -+ { -+ /* see if there are other decoders for this stream */ -+ if (SUCCEEDED(MFTEnum(category, 0, &in_type, NULL, NULL, &clsids, &count)) && count) -+ { -+ decoder_found = TRUE; -+ CoTaskMemFree(clsids); -+ } -+ } - } - - IMFMediaType_Release(input_type); - } - -- return MF_E_TOPO_CODEC_NOT_FOUND; -+ return decoder_found ? MF_E_INVALIDREQUEST : MF_E_TOPO_CODEC_NOT_FOUND; - } - - static HRESULT WINAPI src_reader_SetCurrentMediaType(IMFSourceReader *iface, DWORD index, DWORD *reserved, +diff --git a/dlls/winegstreamer/Makefile.in b/dlls/winegstreamer/Makefile.in +index f2e87494459..e2af4085827 100644 +--- a/dlls/winegstreamer/Makefile.in ++++ b/dlls/winegstreamer/Makefile.in +@@ -13,6 +13,7 @@ C_SRCS = \ + main.c \ + media_source.c \ + mediatype.c \ ++ mf_decode.c \ + mfplat.c \ + pin.c \ + qualitycontrol.c \ diff --git a/dlls/winegstreamer/gst_cbs.c b/dlls/winegstreamer/gst_cbs.c -index e392f4526f..598cd85c1e 100644 +index e56c987eb38..0c0d0a26100 100644 --- a/dlls/winegstreamer/gst_cbs.c +++ b/dlls/winegstreamer/gst_cbs.c -@@ -18,6 +18,9 @@ - - #include "config.h" - -+#include -+#include -+ - #include - - #include "objbase.h" -@@ -53,6 +56,12 @@ static void CALLBACK perform_cb(TP_CALLBACK_INSTANCE *instance, void *user) +@@ -51,6 +51,8 @@ static void CALLBACK perform_cb(TP_CALLBACK_INSTANCE *instance, void *user) + perform_cb_gstdemux(cbdata); + else if (cbdata->type < MEDIA_SOURCE_MAX) perform_cb_media_source(cbdata); - else if (cbdata->type < MF_DECODE_MAX) - perform_cb_mf_decode(cbdata); -+ else -+ { -+ fprintf(stderr, "No handler registered for callback\n"); -+ assert(0); -+ } -+ ++ else if (cbdata->type < MF_DECODE_MAX) ++ perform_cb_mf_decode(cbdata); pthread_mutex_lock(&cbdata->lock); cbdata->finished = 1; -diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c -index e0a1624951..40f7828e50 100644 ---- a/dlls/winegstreamer/media_source.c -+++ b/dlls/winegstreamer/media_source.c -@@ -84,6 +84,8 @@ struct source_async_command - struct media_source - { - IMFMediaSource IMFMediaSource_iface; -+ IMFGetService IMFGetService_iface; -+ IMFSeekInfo IMFSeekInfo_iface; - IMFAsyncCallback async_commands_callback; - LONG ref; - DWORD async_commands_queue; -@@ -118,6 +120,16 @@ static inline struct media_source *impl_from_IMFMediaSource(IMFMediaSource *ifac - return CONTAINING_RECORD(iface, struct media_source, IMFMediaSource_iface); - } +@@ -417,3 +419,66 @@ GstPadProbeReturn caps_listener_wrapper(GstPad *pad, GstPadProbeInfo *info, gpoi -+static inline struct media_source *impl_from_IMFGetService(IMFGetService *iface) + return cbdata.u.pad_probe_data.ret; + } ++ ++gboolean activate_push_mode_wrapper(GstPad *pad, GstObject *parent, GstPadMode mode, gboolean activate) +{ -+ return CONTAINING_RECORD(iface, struct media_source, IMFGetService_iface); ++ struct cb_data cbdata = { ACTIVATE_PUSH_MODE }; ++ ++ cbdata.u.activate_mode_data.pad = pad; ++ cbdata.u.activate_mode_data.parent = parent; ++ cbdata.u.activate_mode_data.mode = mode; ++ cbdata.u.activate_mode_data.activate = activate; ++ ++ call_cb(&cbdata); ++ ++ return cbdata.u.query_function_data.ret; +} + -+static inline struct media_source *impl_from_IMFSeekInfo(IMFSeekInfo *iface) ++gboolean query_input_src_wrapper(GstPad *pad, GstObject *parent, GstQuery *query) +{ -+ return CONTAINING_RECORD(iface, struct media_source, IMFSeekInfo_iface); ++ struct cb_data cbdata = { QUERY_INPUT_SRC }; ++ ++ cbdata.u.query_function_data.pad = pad; ++ cbdata.u.query_function_data.parent = parent; ++ cbdata.u.query_function_data.query = query; ++ ++ call_cb(&cbdata); ++ ++ return cbdata.u.query_function_data.ret; +} + - static inline struct media_source *impl_from_async_commands_callback_IMFAsyncCallback(IMFAsyncCallback *iface) - { - return CONTAINING_RECORD(iface, struct media_source, async_commands_callback); -@@ -1076,6 +1088,10 @@ static HRESULT WINAPI media_source_QueryInterface(IMFMediaSource *iface, REFIID - { - *out = &source->IMFMediaSource_iface; - } -+ else if(IsEqualIID(riid, &IID_IMFGetService)) -+ { -+ *out = &source->IMFGetService_iface; -+ } - else - { - FIXME("(%s, %p)\n", debugstr_guid(riid), out); -@@ -1170,7 +1186,7 @@ static HRESULT WINAPI media_source_GetCharacteristics(IMFMediaSource *iface, DWO - if (source->state == SOURCE_SHUTDOWN) - return MF_E_SHUTDOWN; - -- *characteristics = MFMEDIASOURCE_CAN_SEEK; -+ *characteristics = MFMEDIASOURCE_CAN_SEEK | MFMEDIASOURCE_CAN_PAUSE; - - return S_OK; - } -@@ -1312,6 +1328,99 @@ static const IMFMediaSourceVtbl IMFMediaSource_vtbl = - media_source_Shutdown, ++GstBusSyncReply watch_decoder_bus_wrapper(GstBus *bus, GstMessage *message, gpointer user) ++{ ++ struct cb_data cbdata = { WATCH_DECODER_BUS }; ++ ++ cbdata.u.watch_bus_data.bus = bus; ++ cbdata.u.watch_bus_data.msg = message; ++ cbdata.u.watch_bus_data.user = user; ++ ++ call_cb(&cbdata); ++ ++ return cbdata.u.watch_bus_data.ret; ++} ++ ++void decoder_pad_added_wrapper(GstElement *element, GstPad *pad, gpointer user) ++{ ++ struct cb_data cbdata = { DECODER_PAD_ADDED }; ++ ++ cbdata.u.pad_added_data.element = element; ++ cbdata.u.pad_added_data.pad = pad; ++ cbdata.u.pad_added_data.user = user; ++ ++ call_cb(&cbdata); ++} ++ ++GstFlowReturn decoder_new_sample_wrapper(GstElement *appsink, gpointer user) ++{ ++ struct cb_data cbdata = {DECODER_NEW_SAMPLE}; ++ ++ cbdata.u.new_sample_data.appsink = appsink; ++ cbdata.u.new_sample_data.user = user; ++ ++ call_cb(&cbdata); ++ ++ return cbdata.u.new_sample_data.ret; ++} +diff --git a/dlls/winegstreamer/gst_cbs.h b/dlls/winegstreamer/gst_cbs.h +index 7173c09746e..7dc60f961ba 100644 +--- a/dlls/winegstreamer/gst_cbs.h ++++ b/dlls/winegstreamer/gst_cbs.h +@@ -54,6 +54,12 @@ enum CB_TYPE { + SOURCE_ALL_STREAMS, + STREAM_PAD_EVENT, + MEDIA_SOURCE_MAX, ++ ACTIVATE_PUSH_MODE, ++ QUERY_INPUT_SRC, ++ DECODER_NEW_SAMPLE, ++ WATCH_DECODER_BUS, ++ DECODER_PAD_ADDED, ++ MF_DECODE_MAX, }; -+static HRESULT WINAPI source_get_service_QueryInterface(IMFGetService *iface, REFIID riid, void **obj) -+{ -+ struct media_source *source = impl_from_IMFGetService(iface); -+ return IMFMediaSource_QueryInterface(&source->IMFMediaSource_iface, riid, obj); -+} -+ -+static ULONG WINAPI source_get_service_AddRef(IMFGetService *iface) -+{ -+ struct media_source *source = impl_from_IMFGetService(iface); -+ return IMFMediaSource_AddRef(&source->IMFMediaSource_iface); -+} -+ -+static ULONG WINAPI source_get_service_Release(IMFGetService *iface) -+{ -+ struct media_source *source = impl_from_IMFGetService(iface); -+ return IMFMediaSource_Release(&source->IMFMediaSource_iface); -+} -+ -+static HRESULT WINAPI source_get_service_GetService(IMFGetService *iface, REFGUID service, REFIID riid, void **obj) -+{ -+ struct media_source *source = impl_from_IMFGetService(iface); -+ -+ TRACE("(%p)->(%s, %s, %p)\n", source, debugstr_guid(service), debugstr_guid(riid), obj); -+ -+ if (source->state == SOURCE_SHUTDOWN) -+ return MF_E_SHUTDOWN; -+ -+ *obj = NULL; -+ -+ if (IsEqualIID(service, &MF_SCRUBBING_SERVICE)) -+ { -+ if (IsEqualIID(riid, &IID_IMFSeekInfo)) -+ { -+ *obj = &source->IMFSeekInfo_iface; -+ } -+ } -+ -+ if (*obj) -+ IUnknown_AddRef((IUnknown*) *obj); -+ -+ return *obj ? S_OK : E_NOINTERFACE; -+} -+ -+static const IMFGetServiceVtbl IMFGetService_vtbl = -+{ -+ source_get_service_QueryInterface, -+ source_get_service_AddRef, -+ source_get_service_Release, -+ source_get_service_GetService, -+}; -+ -+static HRESULT WINAPI source_seek_info_QueryInterface(IMFSeekInfo *iface, REFIID riid, void **obj) -+{ -+ struct media_source *source = impl_from_IMFSeekInfo(iface); -+ return IMFMediaSource_QueryInterface(&source->IMFMediaSource_iface, riid, obj); -+} -+ -+static ULONG WINAPI source_seek_info_AddRef(IMFSeekInfo *iface) -+{ -+ struct media_source *source = impl_from_IMFSeekInfo(iface); -+ return IMFMediaSource_AddRef(&source->IMFMediaSource_iface); -+} -+ -+static ULONG WINAPI source_seek_info_Release(IMFSeekInfo *iface) -+{ -+ struct media_source *source = impl_from_IMFSeekInfo(iface); -+ return IMFMediaSource_Release(&source->IMFMediaSource_iface); -+} -+ -+static HRESULT WINAPI source_seek_info_GetNearestKeyFrames(IMFSeekInfo *iface, const GUID *format, -+ const PROPVARIANT *position, PROPVARIANT *prev_frame, PROPVARIANT *next_frame) -+{ -+ struct media_source *source = impl_from_IMFSeekInfo(iface); -+ -+ FIXME("(%p)->(%s, %p, %p, %p) - semi-stub\n", source, debugstr_guid(format), position, prev_frame, next_frame); -+ -+ if (source->state == SOURCE_SHUTDOWN) -+ return MF_E_SHUTDOWN; -+ -+ PropVariantCopy(prev_frame, position); -+ PropVariantCopy(next_frame, position); -+ -+ return S_OK; -+} -+ -+static const IMFSeekInfoVtbl IMFSeekInfo_vtbl = -+{ -+ source_seek_info_QueryInterface, -+ source_seek_info_AddRef, -+ source_seek_info_Release, -+ source_seek_info_GetNearestKeyFrames, -+}; -+ - static HRESULT media_source_constructor(IMFByteStream *bytestream, enum source_type type, struct media_source **out_media_source) - { - unsigned int i; -@@ -1332,6 +1441,8 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, enum source_t - return E_OUTOFMEMORY; + struct cb_data { +@@ -144,6 +150,17 @@ struct cb_data { + gpointer user; + GstPadProbeReturn ret; + } pad_probe_data; ++ struct chain_data { ++ GstPad *pad; ++ GstObject *parent; ++ GstBuffer *buffer; ++ GstFlowReturn ret; ++ } chain_data; ++ struct new_sample_data { ++ GstElement *appsink; ++ gpointer user; ++ GstFlowReturn ret; ++ } new_sample_data; + } u; - object->IMFMediaSource_iface.lpVtbl = &IMFMediaSource_vtbl; -+ object->IMFGetService_iface.lpVtbl = &IMFGetService_vtbl; -+ object->IMFSeekInfo_iface.lpVtbl = &IMFSeekInfo_vtbl; - object->async_commands_callback.lpVtbl = &source_async_commands_callback_vtbl; - object->ref = 1; - object->type = type; -@@ -1431,7 +1542,6 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, enum source_t - heap_free(descriptors); - descriptors = NULL; + int finished; +@@ -155,6 +172,7 @@ struct cb_data { + void mark_wine_thread(void) DECLSPEC_HIDDEN; + void perform_cb_gstdemux(struct cb_data *data) DECLSPEC_HIDDEN; + void perform_cb_media_source(struct cb_data *data) DECLSPEC_HIDDEN; ++void perform_cb_mf_decode(struct cb_data *data) DECLSPEC_HIDDEN; -- /* miscelaneous presentation descriptor setup */ - { - IMFAttributes *byte_stream_attributes; - gint64 total_pres_time = 0; + GstBusSyncReply watch_bus_wrapper(GstBus *bus, GstMessage *msg, gpointer user) DECLSPEC_HIDDEN; + void existing_new_pad_wrapper(GstElement *bin, GstPad *pad, gpointer user) DECLSPEC_HIDDEN; +@@ -180,5 +198,10 @@ void source_stream_added_wrapper(GstElement *bin, GstPad *pad, gpointer user) DE + void source_stream_removed_wrapper(GstElement *element, GstPad *pad, gpointer user) DECLSPEC_HIDDEN; + void source_all_streams_wrapper(GstElement *element, gpointer user) DECLSPEC_HIDDEN; + GstPadProbeReturn caps_listener_wrapper(GstPad *pad, GstPadProbeInfo *info, gpointer user); ++gboolean activate_push_mode_wrapper(GstPad *pad, GstObject *parent, GstPadMode mode, gboolean activate) DECLSPEC_HIDDEN; ++gboolean query_input_src_wrapper(GstPad *pad, GstObject *parent, GstQuery *query) DECLSPEC_HIDDEN; ++GstBusSyncReply watch_decoder_bus_wrapper(GstBus *bus, GstMessage *message, gpointer user) DECLSPEC_HIDDEN; ++GstFlowReturn decoder_new_sample_wrapper(GstElement *appsink, gpointer user) DECLSPEC_HIDDEN; ++void decoder_pad_added_wrapper(GstElement *element, GstPad *Pad, gpointer user) DECLSPEC_HIDDEN; + + #endif +diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h +index d0737442cc3..5ff412c8e47 100644 +--- a/dlls/winegstreamer/gst_private.h ++++ b/dlls/winegstreamer/gst_private.h +@@ -53,6 +53,7 @@ BOOL init_gstreamer(void) DECLSPEC_HIDDEN; + + void start_dispatch_thread(void) DECLSPEC_HIDDEN; + ++extern HRESULT mfplat_DllRegisterServer(void) DECLSPEC_HIDDEN; + extern HRESULT mfplat_get_class_object(REFCLSID rclsid, REFIID riid, void **obj) DECLSPEC_HIDDEN; + + HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj) DECLSPEC_HIDDEN; +@@ -62,6 +63,12 @@ GstCaps *caps_from_mf_media_type(IMFMediaType *type); + IMFSample *mf_sample_from_gst_buffer(GstBuffer *in); + GstBuffer *gst_buffer_from_mf_sample(IMFSample *in); + ++enum decoder_type ++{ ++ DECODER_TYPE_H264, ++ DECODER_TYPE_AAC, ++}; ++HRESULT generic_decoder_construct(REFIID riid, void **obj, enum decoder_type) DECLSPEC_HIDDEN; + HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj) DECLSPEC_HIDDEN; + + #endif /* __GST_PRIVATE_INCLUDED__ */ +diff --git a/dlls/winegstreamer/main.c b/dlls/winegstreamer/main.c +index 4ca371d58bd..385c5550235 100644 +--- a/dlls/winegstreamer/main.c ++++ b/dlls/winegstreamer/main.c +@@ -368,7 +368,8 @@ HRESULT WINAPI DllRegisterServer(void) + IFilterMapper2_RegisterFilter(mapper, &CLSID_WAVEParser, wave_parserW, NULL, NULL, NULL, ®_wave_parser); + + IFilterMapper2_Release(mapper); +- return S_OK; ++ ++ return mfplat_DllRegisterServer(); + } + + HRESULT WINAPI DllUnregisterServer(void) diff --git a/dlls/winegstreamer/mf_decode.c b/dlls/winegstreamer/mf_decode.c new file mode 100644 -index 0000000000..60ec6fc20b +index 00000000000..025af7b91ae --- /dev/null +++ b/dlls/winegstreamer/mf_decode.c -@@ -0,0 +1,1324 @@ +@@ -0,0 +1,1321 @@ +#include "config.h" + +#include @@ -271,7 +232,8 @@ index 0000000000..60ec6fc20b +/* keep in sync with mfplat.c's mft registrations */ + +const GUID *h264_input_types[] = {&MFVideoFormat_H264}; -+const GUID *h264_output_types[] = {&MFVideoFormat_I420, &MFVideoFormat_IYUV, &MFVideoFormat_NV12, &MFVideoFormat_YUY2, &MFVideoFormat_YV12}; ++/* NV12 comes first https://docs.microsoft.com/en-us/windows/win32/medfound/mft-decoder-expose-output-types-in-native-order. thanks to @vitorhnn */ ++const GUID *h264_output_types[] = {&MFVideoFormat_NV12, &MFVideoFormat_I420, &MFVideoFormat_IYUV, &MFVideoFormat_YUY2, &MFVideoFormat_YV12}; + +const GUID *aac_input_types[] = {&MFAudioFormat_AAC}; +const GUID *aac_output_types[] = {&MFAudioFormat_Float}; @@ -897,7 +859,6 @@ index 0000000000..60ec6fc20b + { + GUID major_type, subtype; + UINT64 unused; -+ unsigned int i; + + if (FAILED(hr = IMFMediaType_GetGUID(type, &MF_MT_MAJOR_TYPE, &major_type))) + return hr; @@ -913,7 +874,7 @@ index 0000000000..60ec6fc20b + return hr; + } + -+ for (i = 0; i < decoder_descs[decoder->type].input_types_count; i++) ++ for (unsigned int i = 0; i < decoder_descs[decoder->type].input_types_count; i++) + { + if (IsEqualGUID(&subtype, decoder_descs[decoder->type].input_types[i])) + break; @@ -966,7 +927,6 @@ index 0000000000..60ec6fc20b + { + GUID major_type, subtype; + UINT64 unused; -+ unsigned int i; + + /* validate the type */ + if (FAILED(hr = IMFMediaType_GetGUID(type, &MF_MT_MAJOR_TYPE, &major_type))) @@ -983,7 +943,7 @@ index 0000000000..60ec6fc20b + return MF_E_INVALIDTYPE; + } + -+ for (i = 0; i < decoder_descs[decoder->type].output_types_count; i++) ++ for (unsigned int i = 0; i < decoder_descs[decoder->type].output_types_count; i++) + { + if (IsEqualGUID(&subtype, decoder_descs[decoder->type].output_types[i])) + break; @@ -1230,7 +1190,7 @@ index 0000000000..60ec6fc20b + } + default: + { -+ ERR("Unhandled message type %x.\n", message); ++ WARN("Unhandled message type %x.\n", message); + hr = E_FAIL; + break; + } @@ -1263,7 +1223,6 @@ index 0000000000..60ec6fc20b + + drain = gst_query_new_drain(); + gst_pad_peer_query(decoder->input_src, drain); -+ gst_query_unref(drain); + + if (decoder->output_counter || decoder->draining) + { @@ -1296,7 +1255,6 @@ index 0000000000..60ec6fc20b + struct mf_decoder *decoder = impl_mf_decoder_from_IMFTransform(iface); + MFT_OUTPUT_DATA_BUFFER *relevant_buffer = NULL; + GstSample *buffer; -+ unsigned int i; + + TRACE("%p, %#x, %u, %p, %p,\n", iface, flags, count, samples, status); + @@ -1306,7 +1264,7 @@ index 0000000000..60ec6fc20b + if (!decoder->valid_state) + return MF_E_TRANSFORM_TYPE_NOT_SET; + -+ for (i = 0; i < count; i++) ++ for (unsigned int i = 0; i < count; i++) + { + MFT_OUTPUT_DATA_BUFFER *out_buffer = &samples[i]; + @@ -1570,6 +1528,186 @@ index 0000000000..60ec6fc20b + } + } +} +diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c +index ae5dcc31825..167f2a185be 100644 +--- a/dlls/winegstreamer/mfplat.c ++++ b/dlls/winegstreamer/mfplat.c +@@ -406,6 +406,16 @@ failed: + + static const GUID CLSID_GStreamerByteStreamHandler = {0x317df618, 0x5e5a, 0x468a, {0x9f, 0x15, 0xd8, 0x27, 0xa9, 0xa0, 0x81, 0x62}}; + ++static HRESULT h264_decoder_create(REFIID riid, void **ret) ++{ ++ return generic_decoder_construct(riid, ret, DECODER_TYPE_H264); ++} ++ ++static HRESULT aac_decoder_create(REFIID riid, void **ret) ++{ ++ return generic_decoder_construct(riid, ret, DECODER_TYPE_AAC); ++} ++ + static const struct class_object + { + const GUID *clsid; +@@ -415,6 +425,8 @@ class_objects[] = + { + { &CLSID_VideoProcessorMFT, &video_processor_create }, + { &CLSID_GStreamerByteStreamHandler, &winegstreamer_stream_handler_create }, ++ { &CLSID_CMSH264DecoderMFT, &h264_decoder_create }, ++ { &CLSID_CMSAACDecMFT, &aac_decoder_create }, + }; + + HRESULT mfplat_get_class_object(REFCLSID rclsid, REFIID riid, void **obj) +@@ -443,6 +455,111 @@ HRESULT mfplat_get_class_object(REFCLSID rclsid, REFIID riid, void **obj) + return CLASS_E_CLASSNOTAVAILABLE; + } + ++ ++static WCHAR h264decoderW[] = {'H','.','2','6','4',' ','D','e','c','o','d','e','r',0}; ++const GUID *h264_decoder_input_types[] = ++{ ++ &MFVideoFormat_H264, ++}; ++const GUID *h264_decoder_output_types[] = ++{ ++ &MFVideoFormat_NV12, ++ &MFVideoFormat_I420, ++ &MFVideoFormat_IYUV, ++ &MFVideoFormat_YUY2, ++ &MFVideoFormat_YV12, ++}; ++ ++static WCHAR aacdecoderW[] = {'A','A','C',' ','D','e','c','o','d','e','r',0}; ++const GUID *aac_decoder_input_types[] = ++{ ++ &MFAudioFormat_AAC, ++}; ++ ++const GUID *aac_decoder_output_types[] = ++{ ++ &MFAudioFormat_Float, ++ &MFAudioFormat_PCM, ++}; ++ ++static const struct mft ++{ ++ const GUID *clsid; ++ const GUID *category; ++ LPWSTR name; ++ const UINT32 flags; ++ const GUID *major_type; ++ const UINT32 input_types_count; ++ const GUID **input_types; ++ const UINT32 output_types_count; ++ const GUID **output_types; ++ IMFAttributes *attributes; ++} ++mfts[] = ++{ ++ { ++ &CLSID_CMSH264DecoderMFT, ++ &MFT_CATEGORY_VIDEO_DECODER, ++ h264decoderW, ++ MFT_ENUM_FLAG_SYNCMFT, ++ &MFMediaType_Video, ++ ARRAY_SIZE(h264_decoder_input_types), ++ h264_decoder_input_types, ++ ARRAY_SIZE(h264_decoder_output_types), ++ h264_decoder_output_types, ++ NULL ++ }, ++ { ++ &CLSID_CMSAACDecMFT, ++ &MFT_CATEGORY_AUDIO_DECODER, ++ aacdecoderW, ++ MFT_ENUM_FLAG_SYNCMFT, ++ &MFMediaType_Audio, ++ ARRAY_SIZE(aac_decoder_input_types), ++ aac_decoder_input_types, ++ ARRAY_SIZE(aac_decoder_output_types), ++ aac_decoder_output_types, ++ NULL ++ } ++}; ++ ++HRESULT mfplat_DllRegisterServer(void) ++{ ++ HRESULT hr; ++ ++ for (unsigned int i = 0; i < ARRAY_SIZE(mfts); i++) ++ { ++ const struct mft *cur = &mfts[i]; ++ ++ MFT_REGISTER_TYPE_INFO *input_types, *output_types; ++ input_types = heap_alloc(cur->input_types_count * sizeof(input_types[0])); ++ output_types = heap_alloc(cur->output_types_count * sizeof(output_types[0])); ++ for (unsigned int i = 0; i < cur->input_types_count; i++) ++ { ++ input_types[i].guidMajorType = *(cur->major_type); ++ input_types[i].guidSubtype = *(cur->input_types[i]); ++ } ++ for (unsigned int i = 0; i < cur->output_types_count; i++) ++ { ++ output_types[i].guidMajorType = *(cur->major_type); ++ output_types[i].guidSubtype = *(cur->output_types[i]); ++ } ++ ++ hr = MFTRegister(*(cur->clsid), *(cur->category), cur->name, cur->flags, cur->input_types_count, ++ input_types, cur->output_types_count, output_types, cur->attributes); ++ ++ heap_free(input_types); ++ heap_free(output_types); ++ ++ if (FAILED(hr)) ++ { ++ FIXME("Failed to register MFT, hr %#x\n", hr); ++ return hr; ++ } ++ } ++ return S_OK; ++} ++ + const static struct + { + const GUID *subtype; +@@ -461,7 +578,6 @@ struct aac_user_data + { + WORD payload_type; + WORD profile_level_indication; +- WORD struct_type; + WORD reserved; + /* audio-specific-config is stored here */ + }; +diff --git a/dlls/winegstreamer/winegstreamer_classes.idl b/dlls/winegstreamer/winegstreamer_classes.idl +index 1dc4ba9a10b..3f28b4ddec4 100644 +--- a/dlls/winegstreamer/winegstreamer_classes.idl ++++ b/dlls/winegstreamer/winegstreamer_classes.idl +@@ -61,3 +61,15 @@ coclass VideoProcessorMFT {} + uuid(317df618-5e5a-468a-9f15-d827a9a08162) + ] + coclass GStreamerByteStreamHandler {} ++ ++[ ++ threading(both), ++ uuid(62ce7e72-4c71-4d20-b15d-452831a87d9d) ++] ++coclass CMSH264DecoderMFT { } ++ ++[ ++ threading(both), ++ uuid(32d186a7-218f-4c75-8876-dd77273a8999) ++] ++coclass CMSAACDecMFT { } +diff --git a/include/mfidl.idl b/include/mfidl.idl +index 4ceeb707bd0..61c9a565415 100644 +--- a/include/mfidl.idl ++++ b/include/mfidl.idl +@@ -1241,3 +1241,5 @@ cpp_quote("EXTERN_GUID(MF_ACTIVATE_CUSTOM_VIDEO_PRESENTER_ACTIVATE, 0xba491365, + cpp_quote("EXTERN_GUID(MF_ACTIVATE_CUSTOM_VIDEO_PRESENTER_FLAGS, 0xba491366, 0xbe50, 0x451e, 0x95, 0xab, 0x6d, 0x4a, 0xcc, 0xc7, 0xda, 0xd8);") + + cpp_quote("EXTERN_GUID(CLSID_VideoProcessorMFT, 0x88753b26, 0x5b24, 0x49bd, 0xb2, 0xe7, 0xc, 0x44, 0x5c, 0x78, 0xc9, 0x82);") ++cpp_quote("EXTERN_GUID(CLSID_CMSH264DecoderMFT, 0x62ce7e72, 0x4c71, 0x4d20, 0xb1, 0x5d, 0x45, 0x28, 0x31, 0xa8, 0x7d, 0x9d);") ++cpp_quote("EXTERN_GUID(CLSID_CMSAACDecMFT, 0x32d186a7, 0x218f, 0x4c75, 0x88, 0x76, 0xdd, 0x77, 0x27, 0x3a, 0x89, 0x99);") -- 2.28.0 diff --git a/patches/mfplat-streaming-support/0034-mfreadwrite-Select-all-streams-when-creating-a-sourc.patch b/patches/mfplat-streaming-support/0027-mfreadwrite-Select-all-streams-when-creating-a-sourc.patch similarity index 79% rename from patches/mfplat-streaming-support/0034-mfreadwrite-Select-all-streams-when-creating-a-sourc.patch rename to patches/mfplat-streaming-support/0027-mfreadwrite-Select-all-streams-when-creating-a-sourc.patch index 469eca3c..5d0c043a 100644 --- a/patches/mfplat-streaming-support/0034-mfreadwrite-Select-all-streams-when-creating-a-sourc.patch +++ b/patches/mfplat-streaming-support/0027-mfreadwrite-Select-all-streams-when-creating-a-sourc.patch @@ -1,7 +1,7 @@ -From 5b5fb65ee4d8f7e8932076b4d8ee0eb1722f0058 Mon Sep 17 00:00:00 2001 +From 3f8659c74c63e1793000e82fa2a51e377bbc5f5e Mon Sep 17 00:00:00 2001 From: Derek Lesho Date: Mon, 23 Mar 2020 11:55:41 -0500 -Subject: [PATCH 34/54] mfreadwrite: Select all streams when creating a source +Subject: [PATCH 27/52] mfreadwrite: Select all streams when creating a source reader. --- @@ -9,7 +9,7 @@ Subject: [PATCH 34/54] mfreadwrite: Select all streams when creating a source 1 file changed, 4 insertions(+) diff --git a/dlls/mfreadwrite/reader.c b/dlls/mfreadwrite/reader.c -index 96a82b798a..3b1dcbb963 100644 +index 96a82b798ab..3b1dcbb9636 100644 --- a/dlls/mfreadwrite/reader.c +++ b/dlls/mfreadwrite/reader.c @@ -2120,6 +2120,10 @@ static HRESULT create_source_reader_from_source(IMFMediaSource *source, IMFAttri diff --git a/patches/mfplat-streaming-support/0028-Miscellaneous.patch b/patches/mfplat-streaming-support/0028-Miscellaneous.patch new file mode 100644 index 00000000..d0639468 --- /dev/null +++ b/patches/mfplat-streaming-support/0028-Miscellaneous.patch @@ -0,0 +1,317 @@ +From d37c836567ce0d6a280b265c6748a072e0e8814f Mon Sep 17 00:00:00 2001 +From: Derek Lesho +Date: Mon, 16 Mar 2020 15:27:27 -0500 +Subject: [PATCH 28/52] Miscellaneous + +--- + dlls/mfreadwrite/reader.c | 12 ++- + dlls/winegstreamer/gst_cbs.c | 20 ++--- + dlls/winegstreamer/gst_cbs.h | 1 - + dlls/winegstreamer/media_source.c | 137 +++++++++++++++++++++++++++++- + 4 files changed, 155 insertions(+), 15 deletions(-) + +diff --git a/dlls/mfreadwrite/reader.c b/dlls/mfreadwrite/reader.c +index 3b1dcbb9636..f8c03e62d35 100644 +--- a/dlls/mfreadwrite/reader.c ++++ b/dlls/mfreadwrite/reader.c +@@ -1596,6 +1596,7 @@ static HRESULT source_reader_create_decoder_for_stream(struct source_reader *rea + { + MFT_REGISTER_TYPE_INFO in_type, out_type; + CLSID *clsids, mft_clsid, category; ++ BOOL decoder_found = FALSE; + unsigned int i = 0, count; + IMFMediaType *input_type; + HRESULT hr; +@@ -1642,12 +1643,21 @@ static HRESULT source_reader_create_decoder_for_stream(struct source_reader *rea + } + + } ++ else if (!decoder_found) ++ { ++ /* see if there are other decoders for this stream */ ++ if (SUCCEEDED(MFTEnum(category, 0, &in_type, NULL, NULL, &clsids, &count)) && count) ++ { ++ decoder_found = TRUE; ++ CoTaskMemFree(clsids); ++ } ++ } + } + + IMFMediaType_Release(input_type); + } + +- return MF_E_TOPO_CODEC_NOT_FOUND; ++ return decoder_found ? MF_E_INVALIDREQUEST : MF_E_TOPO_CODEC_NOT_FOUND; + } + + static HRESULT WINAPI src_reader_SetCurrentMediaType(IMFSourceReader *iface, DWORD index, DWORD *reserved, +diff --git a/dlls/winegstreamer/gst_cbs.c b/dlls/winegstreamer/gst_cbs.c +index 0c0d0a26100..cf8f33a0272 100644 +--- a/dlls/winegstreamer/gst_cbs.c ++++ b/dlls/winegstreamer/gst_cbs.c +@@ -18,6 +18,9 @@ + + #include "config.h" + ++#include ++#include ++ + #include + + #include "objbase.h" +@@ -53,6 +56,12 @@ static void CALLBACK perform_cb(TP_CALLBACK_INSTANCE *instance, void *user) + perform_cb_media_source(cbdata); + else if (cbdata->type < MF_DECODE_MAX) + perform_cb_mf_decode(cbdata); ++ else ++ { ++ fprintf(stderr, "No handler registered for callback\n"); ++ assert(0); ++ } ++ + + pthread_mutex_lock(&cbdata->lock); + cbdata->finished = 1; +@@ -460,17 +469,6 @@ GstBusSyncReply watch_decoder_bus_wrapper(GstBus *bus, GstMessage *message, gpoi + return cbdata.u.watch_bus_data.ret; + } + +-void decoder_pad_added_wrapper(GstElement *element, GstPad *pad, gpointer user) +-{ +- struct cb_data cbdata = { DECODER_PAD_ADDED }; +- +- cbdata.u.pad_added_data.element = element; +- cbdata.u.pad_added_data.pad = pad; +- cbdata.u.pad_added_data.user = user; +- +- call_cb(&cbdata); +-} +- + GstFlowReturn decoder_new_sample_wrapper(GstElement *appsink, gpointer user) + { + struct cb_data cbdata = {DECODER_NEW_SAMPLE}; +diff --git a/dlls/winegstreamer/gst_cbs.h b/dlls/winegstreamer/gst_cbs.h +index 7dc60f961ba..c6aa94d1632 100644 +--- a/dlls/winegstreamer/gst_cbs.h ++++ b/dlls/winegstreamer/gst_cbs.h +@@ -202,6 +202,5 @@ gboolean activate_push_mode_wrapper(GstPad *pad, GstObject *parent, GstPadMode m + gboolean query_input_src_wrapper(GstPad *pad, GstObject *parent, GstQuery *query) DECLSPEC_HIDDEN; + GstBusSyncReply watch_decoder_bus_wrapper(GstBus *bus, GstMessage *message, gpointer user) DECLSPEC_HIDDEN; + GstFlowReturn decoder_new_sample_wrapper(GstElement *appsink, gpointer user) DECLSPEC_HIDDEN; +-void decoder_pad_added_wrapper(GstElement *element, GstPad *Pad, gpointer user) DECLSPEC_HIDDEN; + + #endif +diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c +index ca799446ad8..919f46fd714 100644 +--- a/dlls/winegstreamer/media_source.c ++++ b/dlls/winegstreamer/media_source.c +@@ -95,6 +95,8 @@ struct source_async_command + struct media_source + { + IMFMediaSource IMFMediaSource_iface; ++ IMFGetService IMFGetService_iface; ++ IMFSeekInfo IMFSeekInfo_iface; + IMFAsyncCallback async_commands_callback; + LONG ref; + DWORD async_commands_queue; +@@ -127,6 +129,16 @@ static inline struct media_source *impl_from_IMFMediaSource(IMFMediaSource *ifac + return CONTAINING_RECORD(iface, struct media_source, IMFMediaSource_iface); + } + ++static inline struct media_source *impl_from_IMFGetService(IMFGetService *iface) ++{ ++ return CONTAINING_RECORD(iface, struct media_source, IMFGetService_iface); ++} ++ ++static inline struct media_source *impl_from_IMFSeekInfo(IMFSeekInfo *iface) ++{ ++ return CONTAINING_RECORD(iface, struct media_source, IMFSeekInfo_iface); ++} ++ + static inline struct media_source *impl_from_async_commands_callback_IMFAsyncCallback(IMFAsyncCallback *iface) + { + return CONTAINING_RECORD(iface, struct media_source, async_commands_callback); +@@ -564,6 +576,11 @@ static gboolean query_bytestream(GstPad *pad, GstObject *parent, GstQuery *query + gst_caps_unref(caps); + return TRUE; + } ++ case GST_QUERY_LATENCY: ++ { ++ gst_query_set_latency(query, FALSE, 0, 0); ++ return TRUE; ++ } + default: + { + WARN("Unhandled query type %s\n", GST_QUERY_TYPE_NAME(query)); +@@ -632,6 +649,23 @@ GstBusSyncReply watch_source_bus(GstBus *bus, GstMessage *message, gpointer user + g_error_free(err); + g_free(dbg_info); + break; ++ case GST_MESSAGE_TAG: ++ { ++ GstTagList *tag_list; ++ gchar *printable; ++ gst_message_parse_tag(message, &tag_list); ++ if (tag_list) ++ { ++ printable = gst_tag_list_to_string(tag_list); ++ if (printable) ++ { ++ TRACE("tag test: %s\n", debugstr_a(printable)); ++ g_free(printable); ++ } ++ } ++ ++ break; ++ } + default: + break; + } +@@ -1138,6 +1172,10 @@ static HRESULT WINAPI media_source_QueryInterface(IMFMediaSource *iface, REFIID + { + *out = &source->IMFMediaSource_iface; + } ++ else if(IsEqualIID(riid, &IID_IMFGetService)) ++ { ++ *out = &source->IMFGetService_iface; ++ } + else + { + FIXME("(%s, %p)\n", debugstr_guid(riid), out); +@@ -1222,7 +1260,7 @@ static HRESULT WINAPI media_source_GetCharacteristics(IMFMediaSource *iface, DWO + if (source->state == SOURCE_SHUTDOWN) + return MF_E_SHUTDOWN; + +- *characteristics = MFMEDIASOURCE_CAN_SEEK; ++ *characteristics = MFMEDIASOURCE_CAN_SEEK | MFMEDIASOURCE_CAN_PAUSE; + + return S_OK; + } +@@ -1363,6 +1401,99 @@ static const IMFMediaSourceVtbl IMFMediaSource_vtbl = + media_source_Shutdown, + }; + ++static HRESULT WINAPI source_get_service_QueryInterface(IMFGetService *iface, REFIID riid, void **obj) ++{ ++ struct media_source *source = impl_from_IMFGetService(iface); ++ return IMFMediaSource_QueryInterface(&source->IMFMediaSource_iface, riid, obj); ++} ++ ++static ULONG WINAPI source_get_service_AddRef(IMFGetService *iface) ++{ ++ struct media_source *source = impl_from_IMFGetService(iface); ++ return IMFMediaSource_AddRef(&source->IMFMediaSource_iface); ++} ++ ++static ULONG WINAPI source_get_service_Release(IMFGetService *iface) ++{ ++ struct media_source *source = impl_from_IMFGetService(iface); ++ return IMFMediaSource_Release(&source->IMFMediaSource_iface); ++} ++ ++static HRESULT WINAPI source_get_service_GetService(IMFGetService *iface, REFGUID service, REFIID riid, void **obj) ++{ ++ struct media_source *source = impl_from_IMFGetService(iface); ++ ++ TRACE("(%p)->(%s, %s, %p)\n", source, debugstr_guid(service), debugstr_guid(riid), obj); ++ ++ if (source->state == SOURCE_SHUTDOWN) ++ return MF_E_SHUTDOWN; ++ ++ *obj = NULL; ++ ++ if (IsEqualIID(service, &MF_SCRUBBING_SERVICE)) ++ { ++ if (IsEqualIID(riid, &IID_IMFSeekInfo)) ++ { ++ *obj = &source->IMFSeekInfo_iface; ++ } ++ } ++ ++ if (*obj) ++ IUnknown_AddRef((IUnknown*) *obj); ++ ++ return *obj ? S_OK : E_NOINTERFACE; ++} ++ ++static const IMFGetServiceVtbl IMFGetService_vtbl = ++{ ++ source_get_service_QueryInterface, ++ source_get_service_AddRef, ++ source_get_service_Release, ++ source_get_service_GetService, ++}; ++ ++static HRESULT WINAPI source_seek_info_QueryInterface(IMFSeekInfo *iface, REFIID riid, void **obj) ++{ ++ struct media_source *source = impl_from_IMFSeekInfo(iface); ++ return IMFMediaSource_QueryInterface(&source->IMFMediaSource_iface, riid, obj); ++} ++ ++static ULONG WINAPI source_seek_info_AddRef(IMFSeekInfo *iface) ++{ ++ struct media_source *source = impl_from_IMFSeekInfo(iface); ++ return IMFMediaSource_AddRef(&source->IMFMediaSource_iface); ++} ++ ++static ULONG WINAPI source_seek_info_Release(IMFSeekInfo *iface) ++{ ++ struct media_source *source = impl_from_IMFSeekInfo(iface); ++ return IMFMediaSource_Release(&source->IMFMediaSource_iface); ++} ++ ++static HRESULT WINAPI source_seek_info_GetNearestKeyFrames(IMFSeekInfo *iface, const GUID *format, ++ const PROPVARIANT *position, PROPVARIANT *prev_frame, PROPVARIANT *next_frame) ++{ ++ struct media_source *source = impl_from_IMFSeekInfo(iface); ++ ++ FIXME("(%p)->(%s, %p, %p, %p) - semi-stub\n", source, debugstr_guid(format), position, prev_frame, next_frame); ++ ++ if (source->state == SOURCE_SHUTDOWN) ++ return MF_E_SHUTDOWN; ++ ++ PropVariantCopy(prev_frame, position); ++ PropVariantCopy(next_frame, position); ++ ++ return S_OK; ++} ++ ++static const IMFSeekInfoVtbl IMFSeekInfo_vtbl = ++{ ++ source_seek_info_QueryInterface, ++ source_seek_info_AddRef, ++ source_seek_info_Release, ++ source_seek_info_GetNearestKeyFrames, ++}; ++ + /* If this callback is extended to use any significant win32 APIs, a wrapper function + should be added */ + gboolean stream_found(GstElement *bin, GstPad *pad, GstCaps *caps, gpointer user) +@@ -1504,6 +1635,8 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_ + return E_OUTOFMEMORY; + + object->IMFMediaSource_iface.lpVtbl = &IMFMediaSource_vtbl; ++ object->IMFGetService_iface.lpVtbl = &IMFGetService_vtbl; ++ object->IMFSeekInfo_iface.lpVtbl = &IMFSeekInfo_vtbl; + object->async_commands_callback.lpVtbl = &source_async_commands_callback_vtbl; + object->ref = 1; + object->byte_stream = bytestream; +@@ -1595,7 +1728,6 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_ + heap_free(descriptors); + descriptors = NULL; + +- /* miscelaneous presentation descriptor setup */ + { + IMFAttributes *byte_stream_attributes; + gint64 total_pres_time = 0; +@@ -1612,6 +1744,7 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_ + IMFAttributes_Release(byte_stream_attributes); + } + ++ /* TODO: consider streams which don't start at T=0 */ + for (unsigned int i = 0; i < object->stream_count; i++) + { + GstQuery *query = gst_query_new_duration(GST_FORMAT_TIME); +-- +2.28.0 + diff --git a/patches/mfplat-streaming-support/0036-WMV.patch b/patches/mfplat-streaming-support/0029-WMV.patch similarity index 52% rename from patches/mfplat-streaming-support/0036-WMV.patch rename to patches/mfplat-streaming-support/0029-WMV.patch index e40cc8b2..face1309 100644 --- a/patches/mfplat-streaming-support/0036-WMV.patch +++ b/patches/mfplat-streaming-support/0029-WMV.patch @@ -1,55 +1,33 @@ -From 9a72ebab1d3dd0fdbe06a61ba473f019695477fe Mon Sep 17 00:00:00 2001 +From 827be0fc103c7439b64429e0063c57be4c1f3616 Mon Sep 17 00:00:00 2001 From: Derek Lesho Date: Wed, 25 Mar 2020 19:07:11 -0500 -Subject: [PATCH 36/54] WMV +Subject: [PATCH 29/52] WMV --- - dlls/winegstreamer/gst_private.h | 2 + - dlls/winegstreamer/media_source.c | 3 ++ + dlls/winegstreamer/gst_private.h | 1 + dlls/winegstreamer/mf_decode.c | 10 +++++ - dlls/winegstreamer/mfplat.c | 47 ++++++++++++++++++++ - dlls/winegstreamer/winegstreamer.rgs | 12 +++++ - dlls/winegstreamer/winegstreamer_classes.idl | 12 +++++ + dlls/winegstreamer/mfplat.c | 40 ++++++++++++++++++++ + dlls/winegstreamer/winegstreamer_classes.idl | 6 +++ include/mfidl.idl | 2 + - 7 files changed, 88 insertions(+) + 5 files changed, 59 insertions(+) diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h -index 6e25b895ff..0b61bc9e3c 100644 +index 5ff412c8e47..8651e3440e4 100644 --- a/dlls/winegstreamer/gst_private.h +++ b/dlls/winegstreamer/gst_private.h -@@ -66,11 +66,13 @@ enum decoder_type +@@ -67,6 +67,7 @@ enum decoder_type { DECODER_TYPE_H264, DECODER_TYPE_AAC, + DECODER_TYPE_WMV, }; - HRESULT generic_decoder_construct(REFIID riid, void **obj, enum decoder_type); - enum source_type - { - SOURCE_TYPE_MPEG_4, -+ SOURCE_TYPE_ASF, - }; - HRESULT container_stream_handler_construct(REFIID riid, void **obj, enum source_type); - -diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c -index 308b98c5e6..c66e211faf 100644 ---- a/dlls/winegstreamer/media_source.c -+++ b/dlls/winegstreamer/media_source.c -@@ -30,6 +30,9 @@ static struct source_desc - { - {/*SOURCE_TYPE_MPEG_4*/ - GST_STATIC_CAPS("video/quicktime"), -+ }, -+ {/*SOURCE_TYPE_ASF*/ -+ GST_STATIC_CAPS("video/x-ms-asf"), - } - }; - + HRESULT generic_decoder_construct(REFIID riid, void **obj, enum decoder_type) DECLSPEC_HIDDEN; + HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj) DECLSPEC_HIDDEN; diff --git a/dlls/winegstreamer/mf_decode.c b/dlls/winegstreamer/mf_decode.c -index f5d9a83cd4..21b310a996 100644 +index 025af7b91ae..7f2dfc8f292 100644 --- a/dlls/winegstreamer/mf_decode.c +++ b/dlls/winegstreamer/mf_decode.c -@@ -28,6 +28,9 @@ const GUID *h264_output_types[] = {&MFVideoFormat_I420, &MFVideoFormat_IYUV, &MF +@@ -29,6 +29,9 @@ const GUID *h264_output_types[] = {&MFVideoFormat_NV12, &MFVideoFormat_I420, &MF const GUID *aac_input_types[] = {&MFAudioFormat_AAC}; const GUID *aac_output_types[] = {&MFAudioFormat_Float}; @@ -59,7 +37,7 @@ index f5d9a83cd4..21b310a996 100644 static struct decoder_desc { const GUID *major_type; -@@ -50,6 +53,13 @@ static struct decoder_desc +@@ -51,6 +54,13 @@ static struct decoder_desc ARRAY_SIZE(aac_input_types), aac_output_types, ARRAY_SIZE(aac_output_types), @@ -74,10 +52,10 @@ index f5d9a83cd4..21b310a996 100644 }; diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c -index aaef966a5b..e1735a5f82 100644 +index 167f2a185be..3e5925e32d2 100644 --- a/dlls/winegstreamer/mfplat.c +++ b/dlls/winegstreamer/mfplat.c -@@ -414,11 +414,21 @@ static HRESULT aac_decoder_create(REFIID riid, void **ret) +@@ -416,6 +416,10 @@ static HRESULT aac_decoder_create(REFIID riid, void **ret) return generic_decoder_construct(riid, ret, DECODER_TYPE_AAC); } @@ -85,31 +63,18 @@ index aaef966a5b..e1735a5f82 100644 +{ + return generic_decoder_construct(riid, ret, DECODER_TYPE_WMV); +} -+ - static HRESULT mp4_stream_handler_create(REFIID riid, void **ret) - { - return container_stream_handler_construct(riid, ret, SOURCE_TYPE_MPEG_4); - } - -+static HRESULT asf_stream_handler_create(REFIID riid, void **ret) -+{ -+ return container_stream_handler_construct(riid, ret, SOURCE_TYPE_ASF); -+} -+ static const struct class_object { const GUID *clsid; -@@ -429,7 +439,9 @@ class_objects[] = - { &CLSID_VideoProcessorMFT, &video_processor_create }, +@@ -427,6 +431,7 @@ class_objects[] = + { &CLSID_GStreamerByteStreamHandler, &winegstreamer_stream_handler_create }, { &CLSID_CMSH264DecoderMFT, &h264_decoder_create }, { &CLSID_CMSAACDecMFT, &aac_decoder_create }, + { &CLSID_CWMVDecMediaObject, &wmv_decoder_create }, - { &CLSID_MPEG4ByteStreamHandler, &mp4_stream_handler_create }, -+ { &CLSID_ASFByteStreamHandler, &asf_stream_handler_create }, }; HRESULT mfplat_get_class_object(REFCLSID rclsid, REFIID riid, void **obj) -@@ -488,6 +500,29 @@ const GUID *aac_decoder_output_types[] = +@@ -482,6 +487,29 @@ const GUID *aac_decoder_output_types[] = &MFAudioFormat_PCM, }; @@ -139,7 +104,7 @@ index aaef966a5b..e1735a5f82 100644 static const struct mft { const GUID *clsid; -@@ -526,6 +561,18 @@ mfts[] = +@@ -520,6 +548,18 @@ mfts[] = ARRAY_SIZE(aac_decoder_output_types), aac_decoder_output_types, NULL @@ -158,63 +123,26 @@ index aaef966a5b..e1735a5f82 100644 } }; -diff --git a/dlls/winegstreamer/winegstreamer.rgs b/dlls/winegstreamer/winegstreamer.rgs -index 0bc26761e9..9dbbca1c80 100644 ---- a/dlls/winegstreamer/winegstreamer.rgs -+++ b/dlls/winegstreamer/winegstreamer.rgs -@@ -23,6 +23,10 @@ HKLM - { - NoRemove 'ByteStreamHandlers' - { -+ '.asf' -+ { -+ val '{41457294-644C-4298-A28A-BD69F2C0CF3B}' = s 'ASF Byte Stream Handler' -+ } - '.m4v' - { - val '{271C3902-6095-4c45-A22F-20091816EE9E}' = s 'MPEG4 Byte Stream Handler' -@@ -31,6 +35,14 @@ HKLM - { - val '{271C3902-6095-4c45-A22F-20091816EE9E}' = s 'MPEG4 Byte Stream Handler' - } -+ '.wma' -+ { -+ val '{41457294-644C-4298-A28A-BD69F2C0CF3B}' = s 'ASF Byte Stream Handler' -+ } -+ '.wmv' -+ { -+ val '{41457294-644C-4298-A28A-BD69F2C0CF3B}' = s 'ASF Byte Stream Handler' -+ } - 'video/m4v' - { - val '{271C3902-6095-4c45-A22F-20091816EE9E}' = s 'MPEG4 Byte Stream Handler' diff --git a/dlls/winegstreamer/winegstreamer_classes.idl b/dlls/winegstreamer/winegstreamer_classes.idl -index ee8090cf4a..376e08c418 100644 +index 3f28b4ddec4..f9b0158fa6a 100644 --- a/dlls/winegstreamer/winegstreamer_classes.idl +++ b/dlls/winegstreamer/winegstreamer_classes.idl -@@ -73,3 +73,15 @@ coclass CMSH264DecoderMFT { } +@@ -73,3 +73,9 @@ coclass CMSH264DecoderMFT { } uuid(32d186a7-218f-4c75-8876-dd77273a8999) ] coclass CMSAACDecMFT { } + +[ + threading(both), -+ uuid(41457294-644c-4298-a28a-BD69F2C0CF3B) -+] -+coclass ASFByteStreamHandler {} -+ -+[ -+ threading(both), + uuid(82d353df-90bd-4382-8bc2-3f6192b76e34) +] +coclass CLSID_CWMVDecMediaObject {} -\ No newline at end of file diff --git a/include/mfidl.idl b/include/mfidl.idl -index f7092dfa6c..ce3707ba50 100644 +index 61c9a565415..0885e4e3007 100644 --- a/include/mfidl.idl +++ b/include/mfidl.idl -@@ -1244,3 +1244,5 @@ cpp_quote("EXTERN_GUID(CLSID_VideoProcessorMFT, 0x88753b26, 0x5b24, 0x49bd, 0xb2 - cpp_quote("EXTERN_GUID(CLSID_MPEG4ByteStreamHandler, 0x271c3902, 0x6095, 0x4c45, 0xa2, 0x2f, 0x20, 0x09, 0x18, 0x16, 0xee, 0x9e);") +@@ -1243,3 +1243,5 @@ cpp_quote("EXTERN_GUID(MF_ACTIVATE_CUSTOM_VIDEO_PRESENTER_FLAGS, 0xba491366, 0xb + cpp_quote("EXTERN_GUID(CLSID_VideoProcessorMFT, 0x88753b26, 0x5b24, 0x49bd, 0xb2, 0xe7, 0xc, 0x44, 0x5c, 0x78, 0xc9, 0x82);") cpp_quote("EXTERN_GUID(CLSID_CMSH264DecoderMFT, 0x62ce7e72, 0x4c71, 0x4d20, 0xb1, 0x5d, 0x45, 0x28, 0x31, 0xa8, 0x7d, 0x9d);") cpp_quote("EXTERN_GUID(CLSID_CMSAACDecMFT, 0x32d186a7, 0x218f, 0x4c75, 0x88, 0x76, 0xdd, 0x77, 0x27, 0x3a, 0x89, 0x99);") +cpp_quote("EXTERN_GUID(CLSID_ASFByteStreamHandler, 0x41457294, 0x644c, 0x4298, 0xa2, 0x8a, 0xbd, 0x69, 0xf2, 0xc0, 0xcf, 0x3b);") diff --git a/patches/mfplat-streaming-support/0037-mf-Ask-for-more-samples-from-upstream-node-when-upon.patch b/patches/mfplat-streaming-support/0030-mf-Ask-for-more-samples-from-upstream-node-when-upon.patch similarity index 82% rename from patches/mfplat-streaming-support/0037-mf-Ask-for-more-samples-from-upstream-node-when-upon.patch rename to patches/mfplat-streaming-support/0030-mf-Ask-for-more-samples-from-upstream-node-when-upon.patch index bcf04d06..5eafebb6 100644 --- a/patches/mfplat-streaming-support/0037-mf-Ask-for-more-samples-from-upstream-node-when-upon.patch +++ b/patches/mfplat-streaming-support/0030-mf-Ask-for-more-samples-from-upstream-node-when-upon.patch @@ -1,7 +1,7 @@ -From 478ac7d5e467e93a7a71ce1c8b2ebb227d89e034 Mon Sep 17 00:00:00 2001 +From 399609086d4527338991fae58e915da26c35ab7b Mon Sep 17 00:00:00 2001 From: Derek Lesho Date: Thu, 2 Apr 2020 15:42:18 -0500 -Subject: [PATCH 37/54] mf: Ask for more samples from upstream node when upon +Subject: [PATCH 30/52] mf: Ask for more samples from upstream node when upon MF_E_TRANSFORM_NEED_MORE_INPUT --- @@ -9,10 +9,10 @@ Subject: [PATCH 37/54] mf: Ask for more samples from upstream node when upon 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/dlls/mf/session.c b/dlls/mf/session.c -index e2a6b868ca..748df396d7 100644 +index a1b54b7080e..5bbbfe7d43e 100644 --- a/dlls/mf/session.c +++ b/dlls/mf/session.c -@@ -2451,6 +2451,8 @@ static HRESULT transform_node_pull_samples(struct topo_node *node) +@@ -2503,6 +2503,8 @@ static HRESULT transform_node_pull_samples(struct topo_node *node) return hr; } @@ -21,7 +21,7 @@ index e2a6b868ca..748df396d7 100644 static void session_deliver_sample_to_node(struct media_session *session, IMFTopologyNode *node, unsigned int input, IMFSample *sample) { -@@ -2523,7 +2525,14 @@ static void session_deliver_sample_to_node(struct media_session *session, IMFTop +@@ -2575,7 +2577,14 @@ static void session_deliver_sample_to_node(struct media_session *session, IMFTop WARN("Drain command failed for transform, hr %#x.\n", hr); } diff --git a/patches/mfplat-streaming-support/0040-winegstreamer-Implement-IMFMedisStream-GetMediaSourc.patch b/patches/mfplat-streaming-support/0031-winegstreamer-Implement-IMFMedisStream-GetMediaSourc.patch similarity index 81% rename from patches/mfplat-streaming-support/0040-winegstreamer-Implement-IMFMedisStream-GetMediaSourc.patch rename to patches/mfplat-streaming-support/0031-winegstreamer-Implement-IMFMedisStream-GetMediaSourc.patch index 51a026d5..abdae591 100644 --- a/patches/mfplat-streaming-support/0040-winegstreamer-Implement-IMFMedisStream-GetMediaSourc.patch +++ b/patches/mfplat-streaming-support/0031-winegstreamer-Implement-IMFMedisStream-GetMediaSourc.patch @@ -1,7 +1,7 @@ -From 47d4811b9feead9bd1f4acbba67170d30561aa89 Mon Sep 17 00:00:00 2001 +From 5f2a5bce733fbe36f776d4bf4d823f6c7bc804ad Mon Sep 17 00:00:00 2001 From: Derek Lesho Date: Thu, 2 Apr 2020 15:46:25 -0500 -Subject: [PATCH 40/54] winegstreamer: Implement +Subject: [PATCH 31/52] winegstreamer: Implement IMFMedisStream::GetMediaSource. --- @@ -9,10 +9,10 @@ Subject: [PATCH 40/54] winegstreamer: Implement 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c -index c66e211faf..11b28176fd 100644 +index 919f46fd714..f0a654d1fa4 100644 --- a/dlls/winegstreamer/media_source.c +++ b/dlls/winegstreamer/media_source.c -@@ -842,12 +842,15 @@ static HRESULT WINAPI media_stream_GetMediaSource(IMFMediaStream *iface, IMFMedi +@@ -784,12 +784,15 @@ static HRESULT WINAPI media_stream_GetMediaSource(IMFMediaStream *iface, IMFMedi { struct media_stream *stream = impl_from_IMFMediaStream(iface); diff --git a/patches/mfplat-streaming-support/0041-Expose-PCM-output-type-on-AAC-decoder.patch b/patches/mfplat-streaming-support/0032-Expose-PCM-output-type-on-AAC-decoder.patch similarity index 71% rename from patches/mfplat-streaming-support/0041-Expose-PCM-output-type-on-AAC-decoder.patch rename to patches/mfplat-streaming-support/0032-Expose-PCM-output-type-on-AAC-decoder.patch index 82568e93..3575fc82 100644 --- a/patches/mfplat-streaming-support/0041-Expose-PCM-output-type-on-AAC-decoder.patch +++ b/patches/mfplat-streaming-support/0032-Expose-PCM-output-type-on-AAC-decoder.patch @@ -1,18 +1,18 @@ -From a88773344facfd8e308f5feb6f69e12c334690e6 Mon Sep 17 00:00:00 2001 +From 5c4b42745f37fbe626bdc540eca0e3fbe03fa9b2 Mon Sep 17 00:00:00 2001 From: Derek Lesho Date: Fri, 3 Apr 2020 11:12:33 -0500 -Subject: [PATCH 41/54] Expose PCM output type on AAC decoder. +Subject: [PATCH 32/52] Expose PCM output type on AAC decoder. --- dlls/winegstreamer/mf_decode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dlls/winegstreamer/mf_decode.c b/dlls/winegstreamer/mf_decode.c -index 21b310a996..7fe216d67d 100644 +index 7f2dfc8f292..34bcde27a91 100644 --- a/dlls/winegstreamer/mf_decode.c +++ b/dlls/winegstreamer/mf_decode.c -@@ -26,7 +26,7 @@ const GUID *h264_input_types[] = {&MFVideoFormat_H264}; - const GUID *h264_output_types[] = {&MFVideoFormat_I420, &MFVideoFormat_IYUV, &MFVideoFormat_NV12, &MFVideoFormat_YUY2, &MFVideoFormat_YV12}; +@@ -27,7 +27,7 @@ const GUID *h264_input_types[] = {&MFVideoFormat_H264}; + const GUID *h264_output_types[] = {&MFVideoFormat_NV12, &MFVideoFormat_I420, &MFVideoFormat_IYUV, &MFVideoFormat_YUY2, &MFVideoFormat_YV12}; const GUID *aac_input_types[] = {&MFAudioFormat_AAC}; -const GUID *aac_output_types[] = {&MFAudioFormat_Float}; diff --git a/patches/mfplat-streaming-support/0043-mfplat-Add-I420-format-information.patch b/patches/mfplat-streaming-support/0033-mfplat-Add-I420-format-information.patch similarity index 82% rename from patches/mfplat-streaming-support/0043-mfplat-Add-I420-format-information.patch rename to patches/mfplat-streaming-support/0033-mfplat-Add-I420-format-information.patch index 137aec63..2e86ee6d 100644 --- a/patches/mfplat-streaming-support/0043-mfplat-Add-I420-format-information.patch +++ b/patches/mfplat-streaming-support/0033-mfplat-Add-I420-format-information.patch @@ -1,7 +1,7 @@ -From ba51cc01a42eb3cca95495afc42c68b7ec726ad8 Mon Sep 17 00:00:00 2001 +From 6e418d70ca7aa8e5e9468a1bdbcfc1ebec510f26 Mon Sep 17 00:00:00 2001 From: Derek Lesho Date: Fri, 1 May 2020 11:46:26 -0500 -Subject: [PATCH 43/54] mfplat: Add I420 format information. +Subject: [PATCH 33/52] mfplat: Add I420 format information. Signed-off-by: Derek Lesho --- @@ -9,7 +9,7 @@ Signed-off-by: Derek Lesho 1 file changed, 1 insertion(+) diff --git a/dlls/mfplat/mediatype.c b/dlls/mfplat/mediatype.c -index 5eaa4fdd08..db789c4f8e 100644 +index 5eaa4fdd08d..db789c4f8e0 100644 --- a/dlls/mfplat/mediatype.c +++ b/dlls/mfplat/mediatype.c @@ -2238,6 +2238,7 @@ static const struct uncompressed_video_format video_formats[] = diff --git a/patches/mfplat-streaming-support/0033-winegstreamer-Implement-decoder-MFT-on-gstreamer.patch b/patches/mfplat-streaming-support/0033-winegstreamer-Implement-decoder-MFT-on-gstreamer.patch deleted file mode 100644 index ced67c58..00000000 --- a/patches/mfplat-streaming-support/0033-winegstreamer-Implement-decoder-MFT-on-gstreamer.patch +++ /dev/null @@ -1,387 +0,0 @@ -From 57240613380e0ea13b3adb0d2beada6e6528a0d5 Mon Sep 17 00:00:00 2001 -From: Derek Lesho -Date: Mon, 16 Mar 2020 12:09:39 -0500 -Subject: [PATCH] winegstreamer: Implement decoder MFT on gstreamer. - ---- - dlls/winegstreamer/Makefile.in | 1 + - dlls/winegstreamer/gst_cbs.c | 65 ++++++++++ - dlls/winegstreamer/gst_cbs.h | 18 +++ - dlls/winegstreamer/gst_private.h | 7 ++ - dlls/winegstreamer/main.c | 3 +- - dlls/winegstreamer/mfplat.c | 120 ++++++++++++++++++- - dlls/winegstreamer/winegstreamer_classes.idl | 12 ++ - include/mfidl.idl | 4 +- - 8 files changed, 227 insertions(+), 3 deletions(-) - -diff --git a/dlls/winegstreamer/Makefile.in b/dlls/winegstreamer/Makefile.in -index f2e8749445..e2af408582 100644 ---- a/dlls/winegstreamer/Makefile.in -+++ b/dlls/winegstreamer/Makefile.in -@@ -13,6 +13,7 @@ C_SRCS = \ - main.c \ - media_source.c \ - mediatype.c \ -+ mf_decode.c \ - mfplat.c \ - pin.c \ - qualitycontrol.c \ -diff --git a/dlls/winegstreamer/gst_cbs.c b/dlls/winegstreamer/gst_cbs.c -index d2d36aeb86..e392f4526f 100644 ---- a/dlls/winegstreamer/gst_cbs.c -+++ b/dlls/winegstreamer/gst_cbs.c -@@ -51,6 +51,8 @@ static void CALLBACK perform_cb(TP_CALLBACK_INSTANCE *instance, void *user) - perform_cb_gstdemux(cbdata); - else if (cbdata->type < MEDIA_SOURCE_MAX) - perform_cb_media_source(cbdata); -+ else if (cbdata->type < MF_DECODE_MAX) -+ perform_cb_mf_decode(cbdata); - - pthread_mutex_lock(&cbdata->lock); - cbdata->finished = 1; -@@ -414,5 +416,68 @@ GstFlowReturn stream_new_sample_wrapper(GstElement *appsink, gpointer user) - - call_cb(&cbdata); - -+ return cbdata.u.new_sample_data.ret; -+} -+ -+gboolean activate_push_mode_wrapper(GstPad *pad, GstObject *parent, GstPadMode mode, gboolean activate) -+{ -+ struct cb_data cbdata = { ACTIVATE_PUSH_MODE }; -+ -+ cbdata.u.activate_mode_data.pad = pad; -+ cbdata.u.activate_mode_data.parent = parent; -+ cbdata.u.activate_mode_data.mode = mode; -+ cbdata.u.activate_mode_data.activate = activate; -+ -+ call_cb(&cbdata); -+ -+ return cbdata.u.query_function_data.ret; -+} -+ -+gboolean query_input_src_wrapper(GstPad *pad, GstObject *parent, GstQuery *query) -+{ -+ struct cb_data cbdata = { QUERY_INPUT_SRC }; -+ -+ cbdata.u.query_function_data.pad = pad; -+ cbdata.u.query_function_data.parent = parent; -+ cbdata.u.query_function_data.query = query; -+ -+ call_cb(&cbdata); -+ -+ return cbdata.u.query_function_data.ret; -+} -+ -+GstBusSyncReply watch_decoder_bus_wrapper(GstBus *bus, GstMessage *message, gpointer user) -+{ -+ struct cb_data cbdata = { WATCH_DECODER_BUS }; -+ -+ cbdata.u.watch_bus_data.bus = bus; -+ cbdata.u.watch_bus_data.msg = message; -+ cbdata.u.watch_bus_data.user = user; -+ -+ call_cb(&cbdata); -+ -+ return cbdata.u.watch_bus_data.ret; -+} -+ -+void decoder_pad_added_wrapper(GstElement *element, GstPad *pad, gpointer user) -+{ -+ struct cb_data cbdata = { DECODER_PAD_ADDED }; -+ -+ cbdata.u.pad_added_data.element = element; -+ cbdata.u.pad_added_data.pad = pad; -+ cbdata.u.pad_added_data.user = user; -+ -+ call_cb(&cbdata); -+} -+ -+GstFlowReturn decoder_new_sample_wrapper(GstElement *appsink, gpointer user) -+{ -+ struct cb_data cbdata = {DECODER_NEW_SAMPLE}; -+ -+ cbdata.u.new_sample_data.appsink = appsink; -+ cbdata.u.new_sample_data.user = user; -+ -+ call_cb(&cbdata); -+ - return cbdata.u.new_sample_data.ret; - } -\ No newline at end of file -diff --git a/dlls/winegstreamer/gst_cbs.h b/dlls/winegstreamer/gst_cbs.h -index 106368a064..a35d6d8830 100644 ---- a/dlls/winegstreamer/gst_cbs.h -+++ b/dlls/winegstreamer/gst_cbs.h -@@ -54,6 +54,12 @@ enum CB_TYPE { - SOURCE_ALL_STREAMS, - STREAM_NEW_SAMPLE, - MEDIA_SOURCE_MAX, -+ ACTIVATE_PUSH_MODE, -+ QUERY_INPUT_SRC, -+ DECODER_NEW_SAMPLE, -+ WATCH_DECODER_BUS, -+ DECODER_PAD_ADDED, -+ MF_DECODE_MAX, - }; - - struct cb_data { -@@ -143,6 +149,12 @@ struct cb_data { - gpointer user; - GstFlowReturn ret; - } new_sample_data; -+ struct chain_data { -+ GstPad *pad; -+ GstObject *parent; -+ GstBuffer *buffer; -+ GstFlowReturn ret; -+ } chain_data; - } u; - - int finished; -@@ -154,6 +166,7 @@ struct cb_data { - void mark_wine_thread(void) DECLSPEC_HIDDEN; - void perform_cb_gstdemux(struct cb_data *data) DECLSPEC_HIDDEN; - void perform_cb_media_source(struct cb_data *data) DECLSPEC_HIDDEN; -+void perform_cb_mf_decode(struct cb_data *data) DECLSPEC_HIDDEN; - - GstBusSyncReply watch_bus_wrapper(GstBus *bus, GstMessage *msg, gpointer user) DECLSPEC_HIDDEN; - void existing_new_pad_wrapper(GstElement *bin, GstPad *pad, gpointer user) DECLSPEC_HIDDEN; -@@ -179,5 +192,10 @@ void source_stream_added_wrapper(GstElement *bin, GstPad *pad, gpointer user) DE - void source_stream_removed_wrapper(GstElement *element, GstPad *pad, gpointer user) DECLSPEC_HIDDEN; - void source_all_streams_wrapper(GstElement *element, gpointer user) DECLSPEC_HIDDEN; - GstFlowReturn stream_new_sample_wrapper(GstElement *appsink, gpointer user) DECLSPEC_HIDDEN; -+gboolean activate_push_mode_wrapper(GstPad *pad, GstObject *parent, GstPadMode mode, gboolean activate) DECLSPEC_HIDDEN; -+gboolean query_input_src_wrapper(GstPad *pad, GstObject *parent, GstQuery *query) DECLSPEC_HIDDEN; -+GstBusSyncReply watch_decoder_bus_wrapper(GstBus *bus, GstMessage *message, gpointer user) DECLSPEC_HIDDEN; -+GstFlowReturn decoder_new_sample_wrapper(GstElement *appsink, gpointer user) DECLSPEC_HIDDEN; -+void decoder_pad_added_wrapper(GstElement *element, GstPad *Pad, gpointer user) DECLSPEC_HIDDEN; - - #endif -diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h -index 258df0d040..6e25b895ff 100644 ---- a/dlls/winegstreamer/gst_private.h -+++ b/dlls/winegstreamer/gst_private.h -@@ -53,6 +53,7 @@ BOOL init_gstreamer(void) DECLSPEC_HIDDEN; - - void start_dispatch_thread(void) DECLSPEC_HIDDEN; - -+extern HRESULT mfplat_DllRegisterServer(void) DECLSPEC_HIDDEN; - extern HRESULT mfplat_get_class_object(REFCLSID rclsid, REFIID riid, void **obj) DECLSPEC_HIDDEN; - - GstCaps *make_mf_compatible_caps(GstCaps *caps); -@@ -61,6 +62,12 @@ GstCaps *caps_from_mf_media_type(IMFMediaType *type); - IMFSample *mf_sample_from_gst_buffer(GstBuffer *in); - GstBuffer *gst_buffer_from_mf_sample(IMFSample *in); - -+enum decoder_type -+{ -+ DECODER_TYPE_H264, -+ DECODER_TYPE_AAC, -+}; -+HRESULT generic_decoder_construct(REFIID riid, void **obj, enum decoder_type); - enum source_type - { - SOURCE_TYPE_MPEG_4, -diff --git a/dlls/winegstreamer/main.c b/dlls/winegstreamer/main.c -index 2872710b3e..12ca11fa6c 100644 ---- a/dlls/winegstreamer/main.c -+++ b/dlls/winegstreamer/main.c -@@ -365,7 +365,8 @@ HRESULT WINAPI DllRegisterServer(void) - IFilterMapper2_RegisterFilter(mapper, &CLSID_WAVEParser, wave_parserW, NULL, NULL, NULL, ®_wave_parser); - - IFilterMapper2_Release(mapper); -- return S_OK; -+ -+ return mfplat_DllRegisterServer(); - } - - HRESULT WINAPI DllUnregisterServer(void) -diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c -index fe8ba885e9..31881399a9 100644 ---- a/dlls/winegstreamer/mfplat.c -+++ b/dlls/winegstreamer/mfplat.c -@@ -404,6 +404,16 @@ failed: - return hr; - } - -+static HRESULT h264_decoder_create(REFIID riid, void **ret) -+{ -+ return generic_decoder_construct(riid, ret, DECODER_TYPE_H264); -+} -+ -+static HRESULT aac_decoder_create(REFIID riid, void **ret) -+{ -+ return generic_decoder_construct(riid, ret, DECODER_TYPE_AAC); -+} -+ - static HRESULT mp4_stream_handler_create(REFIID riid, void **ret) - { - return container_stream_handler_construct(riid, ret, SOURCE_TYPE_MPEG_4); -@@ -417,6 +427,8 @@ static const struct class_object - class_objects[] = - { - { &CLSID_VideoProcessorMFT, &video_processor_create }, -+ { &CLSID_CMSH264DecoderMFT, &h264_decoder_create }, -+ { &CLSID_CMSAACDecMFT, &aac_decoder_create }, - { &CLSID_MPEG4ByteStreamHandler, &mp4_stream_handler_create }, - }; - -@@ -449,6 +461,113 @@ HRESULT mfplat_get_class_object(REFCLSID rclsid, REFIID riid, void **obj) - return CLASS_E_CLASSNOTAVAILABLE; - } - -+ -+static WCHAR h264decoderW[] = {'H','.','2','6','4',' ','D','e','c','o','d','e','r',0}; -+const GUID *h264_decoder_input_types[] = -+{ -+ &MFVideoFormat_H264, -+}; -+const GUID *h264_decoder_output_types[] = -+{ -+ &MFVideoFormat_I420, -+ &MFVideoFormat_IYUV, -+ &MFVideoFormat_NV12, -+ &MFVideoFormat_YUY2, -+ &MFVideoFormat_YV12, -+}; -+ -+static WCHAR aacdecoderW[] = {'A','A','C',' ','D','e','c','o','d','e','r',0}; -+const GUID *aac_decoder_input_types[] = -+{ -+ &MFAudioFormat_AAC, -+}; -+ -+const GUID *aac_decoder_output_types[] = -+{ -+ &MFAudioFormat_Float, -+ &MFAudioFormat_PCM, -+}; -+ -+static const struct mft -+{ -+ const GUID *clsid; -+ const GUID *category; -+ LPWSTR name; -+ const UINT32 flags; -+ const GUID *major_type; -+ const UINT32 input_types_count; -+ const GUID **input_types; -+ const UINT32 output_types_count; -+ const GUID **output_types; -+ IMFAttributes *attributes; -+} -+mfts[] = -+{ -+ { -+ &CLSID_CMSH264DecoderMFT, -+ &MFT_CATEGORY_VIDEO_DECODER, -+ h264decoderW, -+ MFT_ENUM_FLAG_SYNCMFT, -+ &MFMediaType_Video, -+ ARRAY_SIZE(h264_decoder_input_types), -+ h264_decoder_input_types, -+ ARRAY_SIZE(h264_decoder_output_types), -+ h264_decoder_output_types, -+ NULL -+ }, -+ { -+ &CLSID_CMSAACDecMFT, -+ &MFT_CATEGORY_AUDIO_DECODER, -+ aacdecoderW, -+ MFT_ENUM_FLAG_SYNCMFT, -+ &MFMediaType_Audio, -+ ARRAY_SIZE(aac_decoder_input_types), -+ aac_decoder_input_types, -+ ARRAY_SIZE(aac_decoder_output_types), -+ aac_decoder_output_types, -+ NULL -+ } -+}; -+ -+HRESULT mfplat_DllRegisterServer(void) -+{ -+ HRESULT hr; -+ unsigned int i; -+ -+ for (i = 0; i < ARRAY_SIZE(mfts); i++) -+ { -+ const struct mft *cur = &mfts[i]; -+ unsigned int j, k; -+ -+ MFT_REGISTER_TYPE_INFO *input_types, *output_types; -+ input_types = heap_alloc(cur->input_types_count * sizeof(input_types[0])); -+ output_types = heap_alloc(cur->output_types_count * sizeof(output_types[0])); -+ for (j = 0; j < cur->input_types_count; j++) -+ { -+ input_types[j].guidMajorType = *(cur->major_type); -+ input_types[j].guidSubtype = *(cur->input_types[j]); -+ } -+ for (k = 0; k < cur->output_types_count; k++) -+ { -+ output_types[k].guidMajorType = *(cur->major_type); -+ output_types[k].guidSubtype = *(cur->output_types[k]); -+ } -+ -+ hr = MFTRegister(*(cur->clsid), *(cur->category), cur->name, cur->flags, cur->input_types_count, -+ input_types, cur->output_types_count, output_types, cur->attributes); -+ -+ heap_free(input_types); -+ heap_free(output_types); -+ -+ if (FAILED(hr)) -+ { -+ FIXME("Failed to register MFT, hr %#x\n", hr); -+ return hr; -+ } -+ } -+ return S_OK; -+} -+ - const static struct - { - const GUID *subtype; -@@ -467,7 +586,6 @@ struct aac_user_data - { - WORD payload_type; - WORD profile_level_indication; -- WORD struct_type; - WORD reserved; - /* audio-specific-config is stored here */ - }; -diff --git a/dlls/winegstreamer/winegstreamer_classes.idl b/dlls/winegstreamer/winegstreamer_classes.idl -index 997a28b052..ee8090cf4a 100644 ---- a/dlls/winegstreamer/winegstreamer_classes.idl -+++ b/dlls/winegstreamer/winegstreamer_classes.idl -@@ -61,3 +61,15 @@ coclass VideoProcessorMFT {} - uuid(271c3902-6095-4c45-a22f-20091816ee9e) - ] - coclass MPEG4ByteStreamHandler {} -+ -+[ -+ threading(both), -+ uuid(62ce7e72-4c71-4d20-b15d-452831a87d9d) -+] -+coclass CMSH264DecoderMFT { } -+ -+[ -+ threading(both), -+ uuid(32d186a7-218f-4c75-8876-dd77273a8999) -+] -+coclass CMSAACDecMFT { } -diff --git a/include/mfidl.idl b/include/mfidl.idl -index fc13dfba7a..f7092dfa6c 100644 ---- a/include/mfidl.idl -+++ b/include/mfidl.idl -@@ -1241,4 +1241,6 @@ cpp_quote("EXTERN_GUID(MF_ACTIVATE_CUSTOM_VIDEO_PRESENTER_ACTIVATE, 0xba491365, - cpp_quote("EXTERN_GUID(MF_ACTIVATE_CUSTOM_VIDEO_PRESENTER_FLAGS, 0xba491366, 0xbe50, 0x451e, 0x95, 0xab, 0x6d, 0x4a, 0xcc, 0xc7, 0xda, 0xd8);") - - cpp_quote("EXTERN_GUID(CLSID_VideoProcessorMFT, 0x88753b26, 0x5b24, 0x49bd, 0xb2, 0xe7, 0xc, 0x44, 0x5c, 0x78, 0xc9, 0x82);") --cpp_quote("EXTERN_GUID(CLSID_MPEG4ByteStreamHandler, 0x271c3902, 0x6095, 0x4c45, 0xa2, 0x2f, 0x20, 0x09, 0x18, 0x16, 0xee, 0x9e);") -\ No newline at end of file -+cpp_quote("EXTERN_GUID(CLSID_MPEG4ByteStreamHandler, 0x271c3902, 0x6095, 0x4c45, 0xa2, 0x2f, 0x20, 0x09, 0x18, 0x16, 0xee, 0x9e);") -+cpp_quote("EXTERN_GUID(CLSID_CMSH264DecoderMFT, 0x62ce7e72, 0x4c71, 0x4d20, 0xb1, 0x5d, 0x45, 0x28, 0x31, 0xa8, 0x7d, 0x9d);") -+cpp_quote("EXTERN_GUID(CLSID_CMSAACDecMFT, 0x32d186a7, 0x218f, 0x4c75, 0x88, 0x76, 0xdd, 0x77, 0x27, 0x3a, 0x89, 0x99);") --- -2.28.0 - diff --git a/patches/mfplat-streaming-support/0044-winegstreamer-Implement-Color-Converter-MFT.patch b/patches/mfplat-streaming-support/0034-winegstreamer-Implement-Color-Converter-MFT.patch similarity index 93% rename from patches/mfplat-streaming-support/0044-winegstreamer-Implement-Color-Converter-MFT.patch rename to patches/mfplat-streaming-support/0034-winegstreamer-Implement-Color-Converter-MFT.patch index 132d9778..66356946 100644 --- a/patches/mfplat-streaming-support/0044-winegstreamer-Implement-Color-Converter-MFT.patch +++ b/patches/mfplat-streaming-support/0034-winegstreamer-Implement-Color-Converter-MFT.patch @@ -1,20 +1,20 @@ -From 532b311a83c2796e3014c11fe45f9f60e39736ee Mon Sep 17 00:00:00 2001 +From e37aca973f33356cbf1a4098d70a5ba4277be059 Mon Sep 17 00:00:00 2001 From: Derek Lesho Date: Fri, 1 May 2020 13:20:49 -0500 -Subject: [PATCH] winegstreamer: Implement Color Converter MFT. +Subject: [PATCH 34/52] winegstreamer: Implement Color Converter MFT. Signed-off-by: Derek Lesho --- dlls/winegstreamer/Makefile.in | 1 + - dlls/winegstreamer/colorconvert.c | 707 +++++++++++++++++++ + dlls/winegstreamer/colorconvert.c | 704 +++++++++++++++++++ dlls/winegstreamer/gst_private.h | 2 + - dlls/winegstreamer/mfplat.c | 35 + - dlls/winegstreamer/winegstreamer_classes.idl | 8 +- - 5 files changed, 752 insertions(+), 1 deletion(-) + dlls/winegstreamer/mfplat.c | 36 + + dlls/winegstreamer/winegstreamer_classes.idl | 6 + + 5 files changed, 749 insertions(+) create mode 100644 dlls/winegstreamer/colorconvert.c diff --git a/dlls/winegstreamer/Makefile.in b/dlls/winegstreamer/Makefile.in -index e2af408582..a266b0a95e 100644 +index e2af4085827..a266b0a95e4 100644 --- a/dlls/winegstreamer/Makefile.in +++ b/dlls/winegstreamer/Makefile.in @@ -6,6 +6,7 @@ EXTRALIBS = $(GSTREAMER_LIBS) $(PTHREAD_LIBS) @@ -27,10 +27,10 @@ index e2af408582..a266b0a95e 100644 gstdemux.c \ diff --git a/dlls/winegstreamer/colorconvert.c b/dlls/winegstreamer/colorconvert.c new file mode 100644 -index 0000000000..502ff52e56 +index 00000000000..f01373907ee --- /dev/null +++ b/dlls/winegstreamer/colorconvert.c -@@ -0,0 +1,707 @@ +@@ -0,0 +1,704 @@ +#include "config.h" +#include + @@ -46,7 +46,7 @@ index 0000000000..502ff52e56 + +WINE_DEFAULT_DEBUG_CHANNEL(mfplat); + -+const GUID *raw_types[] = { ++static const GUID *raw_types[] = { + &MFVideoFormat_RGB24, + &MFVideoFormat_RGB32, + &MFVideoFormat_RGB555, @@ -349,7 +349,6 @@ index 0000000000..502ff52e56 + { + GUID major_type, subtype; + BOOL found = FALSE; -+ unsigned int i; + + if (FAILED(IMFMediaType_GetGUID(type, &MF_MT_MAJOR_TYPE, &major_type))) + return MF_E_INVALIDTYPE; @@ -359,7 +358,7 @@ index 0000000000..502ff52e56 + if (!(IsEqualGUID(&major_type, &MFMediaType_Video))) + return MF_E_INVALIDTYPE; + -+ for (i = 0; i < ARRAY_SIZE(raw_types); i++) ++ for (unsigned int i = 0; i < ARRAY_SIZE(raw_types); i++) + { + UINT64 unused; + @@ -422,7 +421,6 @@ index 0000000000..502ff52e56 + + if (type) + { -+ unsigned int i; + /* validate the type */ + + if (FAILED(IMFMediaType_GetGUID(type, &MF_MT_MAJOR_TYPE, &major_type))) @@ -435,7 +433,7 @@ index 0000000000..502ff52e56 + if (!(IsEqualGUID(&major_type, &MFMediaType_Video))) + return MF_E_INVALIDTYPE; + -+ for (i = 0; i < ARRAY_SIZE(raw_types); i++) ++ for (unsigned int i = 0; i < ARRAY_SIZE(raw_types); i++) + { + if (IsEqualGUID(&subtype, raw_types[i])) + break; @@ -522,7 +520,7 @@ index 0000000000..502ff52e56 +{ + FIXME("%p, %u.\n", iface, message); + -+ return E_NOTIMPL; ++ return S_OK; +} + +static HRESULT WINAPI color_converter_ProcessInput(IMFTransform *iface, DWORD id, IMFSample *sample, DWORD flags) @@ -584,14 +582,13 @@ index 0000000000..502ff52e56 + MFT_OUTPUT_DATA_BUFFER *relevant_buffer = NULL; + GstSample *sample; + HRESULT hr = S_OK; -+ unsigned int i; + + TRACE("%p, %#x, %u, %p, %p.\n", iface, flags, count, samples, status); + + if (flags) + WARN("Unsupported flags %#x\n", flags); + -+ for (i = 0; i < count; i++) ++ for (unsigned int i = 0; i < count; i++) + { + MFT_OUTPUT_DATA_BUFFER *out_buffer = &samples[i]; + @@ -740,38 +737,39 @@ index 0000000000..502ff52e56 +} \ No newline at end of file diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h -index 0b61bc9e3c..b855d650dc 100644 +index 8651e3440e4..c41f231f35f 100644 --- a/dlls/winegstreamer/gst_private.h +++ b/dlls/winegstreamer/gst_private.h -@@ -76,4 +76,6 @@ enum source_type - }; - HRESULT container_stream_handler_construct(REFIID riid, void **obj, enum source_type); +@@ -72,4 +72,6 @@ enum decoder_type + HRESULT generic_decoder_construct(REFIID riid, void **obj, enum decoder_type) DECLSPEC_HIDDEN; + HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj) DECLSPEC_HIDDEN; +HRESULT color_converter_create(REFIID riid, void **ret); + #endif /* __GST_PRIVATE_INCLUDED__ */ diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c -index 68071fccf9..e63b4dcb2f 100644 +index 3e5925e32d2..429a2cfda1c 100644 --- a/dlls/winegstreamer/mfplat.c +++ b/dlls/winegstreamer/mfplat.c -@@ -429,6 +429,8 @@ static HRESULT asf_stream_handler_create(REFIID riid, void **ret) - return container_stream_handler_construct(riid, ret, SOURCE_TYPE_ASF); +@@ -420,6 +420,9 @@ static HRESULT wmv_decoder_create(REFIID riid, void **ret) + { + return generic_decoder_construct(riid, ret, DECODER_TYPE_WMV); } - ++ +static GUID CLSID_CColorConvertDMO = {0x98230571,0x0087,0x4204,{0xb0,0x20,0x32,0x82,0x53,0x8e,0x57,0xd3}}; + static const struct class_object { const GUID *clsid; -@@ -442,6 +444,7 @@ class_objects[] = +@@ -432,6 +435,7 @@ class_objects[] = + { &CLSID_CMSH264DecoderMFT, &h264_decoder_create }, + { &CLSID_CMSAACDecMFT, &aac_decoder_create }, { &CLSID_CWMVDecMediaObject, &wmv_decoder_create }, - { &CLSID_MPEG4ByteStreamHandler, &mp4_stream_handler_create }, - { &CLSID_ASFByteStreamHandler, &asf_stream_handler_create }, + { &CLSID_CColorConvertDMO, &color_converter_create }, }; HRESULT mfplat_get_class_object(REFCLSID rclsid, REFIID riid, void **obj) -@@ -473,6 +476,26 @@ HRESULT mfplat_get_class_object(REFCLSID rclsid, REFIID riid, void **obj) +@@ -460,6 +464,26 @@ HRESULT mfplat_get_class_object(REFCLSID rclsid, REFIID riid, void **obj) return CLASS_E_CLASSNOTAVAILABLE; } @@ -798,7 +796,7 @@ index 68071fccf9..e63b4dcb2f 100644 static WCHAR h264decoderW[] = {'H','.','2','6','4',' ','D','e','c','o','d','e','r',0}; const GUID *h264_decoder_input_types[] = -@@ -538,6 +561,18 @@ static const struct mft +@@ -525,6 +549,18 @@ static const struct mft } mfts[] = { @@ -818,23 +816,19 @@ index 68071fccf9..e63b4dcb2f 100644 &CLSID_CMSH264DecoderMFT, &MFT_CATEGORY_VIDEO_DECODER, diff --git a/dlls/winegstreamer/winegstreamer_classes.idl b/dlls/winegstreamer/winegstreamer_classes.idl -index 376e08c418..d933d40cfd 100644 +index f9b0158fa6a..1556b6cff9f 100644 --- a/dlls/winegstreamer/winegstreamer_classes.idl +++ b/dlls/winegstreamer/winegstreamer_classes.idl -@@ -84,4 +84,10 @@ coclass ASFByteStreamHandler {} - threading(both), +@@ -79,3 +79,9 @@ coclass CMSAACDecMFT { } uuid(82d353df-90bd-4382-8bc2-3f6192b76e34) ] --coclass CLSID_CWMVDecMediaObject {} -\ No newline at end of file -+coclass CLSID_CWMVDecMediaObject {} + coclass CLSID_CWMVDecMediaObject {} + +[ + threading(both), + uuid(98230571-0087-4204-b020-3282538e57d3) +] +coclass CColorConvertDMO { } -\ No newline at end of file -- 2.28.0 diff --git a/patches/mfplat-streaming-support/0045-HACK-Set-BPS-to-16-for-output-template.patch b/patches/mfplat-streaming-support/0035-HACK-Set-BPS-to-16-for-output-template.patch similarity index 73% rename from patches/mfplat-streaming-support/0045-HACK-Set-BPS-to-16-for-output-template.patch rename to patches/mfplat-streaming-support/0035-HACK-Set-BPS-to-16-for-output-template.patch index c1463e24..d672d846 100644 --- a/patches/mfplat-streaming-support/0045-HACK-Set-BPS-to-16-for-output-template.patch +++ b/patches/mfplat-streaming-support/0035-HACK-Set-BPS-to-16-for-output-template.patch @@ -1,17 +1,17 @@ -From 97211ce51e21d1b1fd7f6fe1bf442f0ce5152f7b Mon Sep 17 00:00:00 2001 +From b4985eaef1d9feb4c67b2b468a67bd550b68c545 Mon Sep 17 00:00:00 2001 From: Derek Lesho Date: Fri, 1 May 2020 22:36:02 -0500 -Subject: [PATCH 45/54] HACK: Set BPS to 16 for output template. +Subject: [PATCH 35/52] HACK: Set BPS to 16 for output template. --- dlls/winegstreamer/mf_decode.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/dlls/winegstreamer/mf_decode.c b/dlls/winegstreamer/mf_decode.c -index 7fe216d67d..c7e1bfb1a9 100644 +index 34bcde27a91..a86e9db410e 100644 --- a/dlls/winegstreamer/mf_decode.c +++ b/dlls/winegstreamer/mf_decode.c -@@ -321,6 +321,11 @@ static HRESULT WINAPI mf_decoder_GetOutputAvailableType(IMFTransform *iface, DWO +@@ -322,6 +322,11 @@ static HRESULT WINAPI mf_decoder_GetOutputAvailableType(IMFTransform *iface, DWO return hr; } diff --git a/patches/mfplat-streaming-support/0036-Improve-tests.patch b/patches/mfplat-streaming-support/0036-Improve-tests.patch new file mode 100644 index 00000000..d6b176d0 --- /dev/null +++ b/patches/mfplat-streaming-support/0036-Improve-tests.patch @@ -0,0 +1,5270 @@ +From 6d317b1d419627dd0894ee4e19e0f7e30e564f74 Mon Sep 17 00:00:00 2001 +From: Derek Lesho +Date: Mon, 9 Mar 2020 11:59:17 -0500 +Subject: [PATCH 36/52] Improve tests + +--- + dlls/mfplat/tests/mfplat.c | 244 +++++++++++++++++++++++++++-- + dlls/mfplat/tests/test.mp4 | Bin 1554 -> 121550 bytes + dlls/mfreadwrite/tests/mfplat.c | 116 ++++++++------ + dlls/mfreadwrite/tests/resource.rc | 4 +- + dlls/mfreadwrite/tests/test.mp4 | Bin 0 -> 121550 bytes + 5 files changed, 302 insertions(+), 62 deletions(-) + create mode 100644 dlls/mfreadwrite/tests/test.mp4 + +diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c +index 6dd2c3cbe96..03d474d62e8 100644 +--- a/dlls/mfplat/tests/mfplat.c ++++ b/dlls/mfplat/tests/mfplat.c +@@ -440,6 +440,9 @@ static BOOL get_event(IMFMediaEventGenerator *generator, MediaEventType expected + return TRUE; + } + ++static IMFSample *retrieved_h264_samples[60]; ++static IMFMediaType *compressed_h264_type; ++ + static void test_source_resolver(void) + { + struct test_callback callback = { { &test_create_from_url_callback_vtbl } }; +@@ -463,6 +466,7 @@ static void test_source_resolver(void) + PROPVARIANT var; + HRESULT hr; + GUID guid; ++ UINT64 frame_size, frame_rate; + + if (!pMFCreateSourceResolver) + { +@@ -596,12 +600,27 @@ static void test_source_resolver(void) + ok(hr == S_OK, "Failed to get current media type, hr %#x.\n", hr); + hr = IMFMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &guid); + ok(hr == S_OK, "Failed to get media sub type, hr %#x.\n", hr); +- ok(IsEqualGUID(&guid, &MFVideoFormat_M4S2), "Unexpected sub type %s.\n", debugstr_guid(&guid)); +- IMFMediaType_Release(media_type); ++ ok(IsEqualGUID(&guid, &MFVideoFormat_H264), "Unexpected sub type %s.\n", debugstr_guid(&guid)); ++ ++ hr = IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &frame_size); ++ ok(hr == S_OK, "Failed to get frame size, hr %#x.\n", hr); ++ ++ ok((frame_size >> 32) == 320, "Unexpected width %u.\n", (DWORD)(frame_size >> 32)); ++ ok((frame_size & 0xffffffff) == 240, "Unexpected height %u.\n", (DWORD)(frame_size & 0xffffffff)); ++ ++ hr = IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_RATE, &frame_rate); ++ ok(hr == S_OK, "Failed to get frame rate, hr %#x.\n", hr); ++ ++ ok((frame_rate >> 32) / (frame_rate & 0xffffffff) == 30, "Unexpected framerate %u/%u\n", ++ (DWORD)(frame_rate >> 32), (DWORD)(frame_rate & 0xffffffff)); + + hr = IMFPresentationDescriptor_SelectStream(descriptor, 0); + ok(hr == S_OK, "Failed to select video stream, hr %#x.\n", hr); + ++ compressed_h264_type = media_type; ++ IMFMediaTypeHandler_Release(handler); ++ IMFStreamDescriptor_Release(sd); ++ + var.vt = VT_EMPTY; + hr = IMFMediaSource_Start(mediasource, descriptor, &GUID_NULL, &var); + ok(hr == S_OK, "Failed to start media source, hr %#x.\n", hr); +@@ -612,9 +631,9 @@ static void test_source_resolver(void) + + get_event((IMFMediaEventGenerator *)mediasource, MESourceStarted, NULL); + +- /* Request samples, our file is 10 frames at 25fps */ ++ /* Request samples, our file is 60 frames at 30fps */ + get_event((IMFMediaEventGenerator *)video_stream, MEStreamStarted, NULL); +- sample_count = 10; ++ sample_count = 60; + + /* Request one beyond EOS, otherwise EndOfStream isn't queued. */ + for (i = 0; i <= sample_count; ++i) +@@ -630,9 +649,14 @@ static void test_source_resolver(void) + for (i = 0; i < sample_count; ++i) + { + static const LONGLONG MILLI_TO_100_NANO = 10000; +- LONGLONG duration, time; ++ static int once = 0; ++ LONGLONG duration; + DWORD buffer_count; + IMFSample *sample; ++ IMFMediaBuffer *buffer; ++ BYTE *buffer_data; ++ DWORD buffer_len; ++ BYTE nal_type = 0x00; + BOOL ret; + + ret = get_event((IMFMediaEventGenerator *)video_stream, MEMediaSample, &var); +@@ -643,19 +667,38 @@ static void test_source_resolver(void) + ok(var.vt == VT_UNKNOWN, "Unexpected value type %u from MEMediaSample event.\n", var.vt); + sample = (IMFSample *)var.punkVal; + +- hr = IMFSample_GetBufferCount(sample, &buffer_count); +- ok(hr == S_OK, "Failed to get buffer count, hr %#x.\n", hr); +- ok(buffer_count == 1, "Unexpected buffer count %u.\n", buffer_count); +- + hr = IMFSample_GetSampleDuration(sample, &duration); + ok(hr == S_OK, "Failed to get sample duration, hr %#x.\n", hr); +- ok(duration == 40 * MILLI_TO_100_NANO, "Unexpected duration %s.\n", wine_dbgstr_longlong(duration)); ++ ok(duration > 33 * MILLI_TO_100_NANO && duration < 34 *MILLI_TO_100_NANO, ++ "Unexpected duration %lu.\n", duration); + +- hr = IMFSample_GetSampleTime(sample, &time); +- ok(hr == S_OK, "Failed to get sample time, hr %#x.\n", hr); +- ok(time == i * 40 * MILLI_TO_100_NANO, "Unexpected time %s.\n", wine_dbgstr_longlong(time)); ++ hr = IMFSample_GetBufferCount(sample, &buffer_count); ++ ok(hr == S_OK, "Failed to get buffer count, hr %#x.\n", hr); ++ ok(buffer_count > 0, "Unexpected buffer count %u.\n", buffer_count); ++ ++ hr = IMFSample_GetBufferByIndex(sample, 0, &buffer); ++ ok (hr == S_OK, "Failed to get buffer from sample, hr %#x.\n", hr); ++ hr = IMFMediaBuffer_Lock(buffer, &buffer_data, NULL, &buffer_len); ++ ok (hr == S_OK, "Failed to lock buffer, hr %#x.\n", hr); ++ ok (buffer_len >= 4, "Size of first sample buffer < 4 bytes %u\n", buffer_len); ++ for (unsigned int k = 0; k < 5; k++) ++ { ++ ok (buffer_data[k] == 0x00 || buffer_data[k] == 0x01, "Invalid start prefix\n"); ++ if (buffer_data[k] == 0x01) ++ { ++ nal_type = buffer_data[k+1]; ++ break; ++ } ++ } ++ if (!once) ++ todo_wine ok(nal_type != 0x09, "Access Unit Delimeter NAL not expected.\n"); ++ if (nal_type == 0x09) ++ once = 1; ++ hr = IMFMediaBuffer_Unlock(buffer); ++ ok (hr == S_OK, "Failed to unlock buffer.\n"); ++ IMFMediaBuffer_Release(buffer); + +- IMFSample_Release(sample); ++ retrieved_h264_samples[i] = sample; + } + + if (i == sample_count) +@@ -713,6 +756,178 @@ static void test_source_resolver(void) + DeleteFileW(filename); + } + ++static void test_decoder(void) ++{ ++ IMFTransform *decoder; ++ DWORD in_min, in_max, out_min, out_max; ++ IMFMediaType *output_type = NULL; ++ MFT_INPUT_STREAM_INFO input_stream_info; ++ MFT_OUTPUT_STREAM_INFO output_stream_info; ++ DWORD input_counter, output_counter; ++ UINT64 frame_size, frame_rate; ++ LONGLONG last_sample_time = 0; ++ HRESULT hr; ++ ++ if (FAILED(CoCreateInstance(&CLSID_CMSH264DecoderMFT, NULL, CLSCTX_INPROC_SERVER, &IID_IMFTransform, (void**)&decoder))) ++ { ++ skip("Skipping decoder tests.\n"); ++ return; ++ } ++ ++ hr = IMFTransform_GetStreamLimits(decoder, &in_min, &in_max, &out_min, &out_max); ++ ok (hr == S_OK, "Failed to get stream limits, hr %#x\n", hr); ++ ok (in_min == 1 && in_max == 1 && out_min == 1 && out_max == 1, "Unexpected stream limits.\n"); ++ ++ hr = IMFTransform_GetStreamCount(decoder, &in_min, &out_min); ++ ok (hr == S_OK, "hr %#x\n", hr); ++ ++ for (unsigned int i = 0;;i++) ++ { ++ IMFMediaType *available_input_type = NULL; ++ GUID subtype; ++ ++ if (FAILED(hr = IMFTransform_GetInputAvailableType(decoder, 0, i, &available_input_type))) ++ break; ++ ++ if (FAILED(hr = IMFMediaType_GetGUID(available_input_type, &MF_MT_SUBTYPE, &subtype))) ++ { ++ IMFMediaType_Release(available_input_type); ++ break; ++ } ++ ++ if (IsEqualGUID(&subtype, &MFVideoFormat_H264)) ++ { ++ IMFMediaType_Release(available_input_type); ++ break; ++ } ++ ++ IMFMediaType_Release(available_input_type); ++ } ++ ok (hr == S_OK, "Didn't find MFVideoFormat_H264 as an input type.\n"); ++ ++ hr = IMFTransform_SetInputType(decoder, 0, compressed_h264_type, 0); ++ ok (hr == S_OK, "Failed to set input type, hr %#x.\n", hr); ++ ++ for (unsigned int i = 0;;i++) ++ { ++ IMFMediaType *available_output_type; ++ GUID subtype; ++ ++ if (FAILED(hr = IMFTransform_GetOutputAvailableType(decoder, 0, i, &available_output_type))) ++ break; ++ ++ if (FAILED(hr = IMFMediaType_GetGUID(available_output_type, &MF_MT_SUBTYPE, &subtype))) ++ { ++ IMFMediaType_Release(available_output_type); ++ break; ++ } ++ ++ if (IsEqualGUID(&subtype, &MFVideoFormat_NV12)) ++ { ++ output_type = available_output_type; ++ break; ++ } ++ ++ IMFMediaType_Release(available_output_type); ++ } ++ ok (hr == S_OK, "Didn't find MFVideoFormat_NV12 as an output type, hr %#x\n", hr); ++ ++ hr = IMFMediaType_GetUINT64(output_type, &MF_MT_FRAME_SIZE, &frame_size); ++ ok (hr == S_OK, "Failed to get output frame size, hr %#x.\n", hr); ++ ++ ok(frame_size >> 32 == 320, "Unexpected width %u.\n", (DWORD)(frame_size >> 32)); ++ ok((frame_size & 0xffffffff) == 240, "Unexpected height %u.\n", (DWORD)(frame_size & 0xffffffff)); ++ ++ hr = IMFMediaType_GetUINT64(output_type, &MF_MT_FRAME_RATE, &frame_rate); ++ ok (hr == S_OK, "Failed to get output frame rate, hr %#x.\n", hr); ++ ++ ok((frame_rate >> 32) / (frame_rate & 0xffffffff) == 30, "Unexpected framerate %u/%u\n", ++ (DWORD)(frame_rate >> 32), (DWORD)(frame_rate & 0xffffffff)); ++ ++ hr = IMFTransform_SetOutputType(decoder, 0, output_type, 0); ++ ok (hr == S_OK, "Failed to set output type, hr %#x.\n", hr); ++ ++ hr = IMFTransform_GetInputStreamInfo(decoder, 0, &input_stream_info); ++ ok (hr == S_OK, "hr %#x.\n"); ++ ++ hr = IMFTransform_GetOutputStreamInfo(decoder, 0, &output_stream_info); ++ ok (hr == S_OK, "hr = %#x.\n"); ++ ++ input_counter = 0; ++ output_counter = 0; ++ ++ hr = IMFTransform_ProcessMessage(decoder, MFT_MESSAGE_NOTIFY_BEGIN_STREAMING, 0); ++ ok (hr == S_OK, "hr %#x\n"); ++ ++ while (output_counter < 60 && input_counter < 60) ++ { ++ while (input_counter < 60) ++ { ++ IMFSample *sample = retrieved_h264_samples[input_counter]; ++ DWORD output_status; ++ ++ hr = IMFTransform_ProcessInput(decoder, 0, sample, 0); ++ ok (hr == S_OK || hr == MF_E_NOTACCEPTING, "Failed to input sample %u, hr %#x.\n", input_counter, hr); ++ if (hr == MF_E_NOTACCEPTING) ++ break; ++ input_counter++; ++ hr = IMFTransform_GetOutputStatus(decoder, &output_status); ++ ok(hr == S_OK, "hr %#x\n", hr); ++ if (output_status & MFT_OUTPUT_STATUS_SAMPLE_READY) ++ break; ++ } ++ if (input_counter == 60) ++ { ++ hr = IMFTransform_ProcessMessage(decoder, MFT_MESSAGE_COMMAND_DRAIN, 0); ++ ok (hr == S_OK, "hr %#x\n", hr); ++ } ++ while (output_counter < 60) ++ { ++ DWORD output_status = 0; ++ MFT_OUTPUT_DATA_BUFFER out_buffers[1]; ++ LONGLONG sample_time; ++ ++ out_buffers[0].dwStreamID = 0; ++ out_buffers[0].pSample = 0; ++ out_buffers[0].dwStatus = 0; ++ out_buffers[0].pEvents = NULL; ++ ++ if (!(output_stream_info.dwFlags & MFT_OUTPUT_STREAM_PROVIDES_SAMPLES)) ++ { ++ IMFMediaBuffer *buffer; ++ IMFSample *sample; ++ hr = MFCreateMemoryBuffer(output_stream_info.cbSize, &buffer); ++ ok(hr == S_OK, "hr %#x\n"); ++ hr = MFCreateSample(&sample); ++ ok(hr == S_OK, "hr %#x\n"); ++ hr = IMFSample_AddBuffer(sample, buffer); ++ ok(hr == S_OK, "hr %#x\n"); ++ out_buffers[0].pSample = sample; ++ } ++ ++ hr = IMFTransform_ProcessOutput(decoder, 0, 1, out_buffers, &output_status); ++ ok (out_buffers[0].pEvents == NULL, "Unexpected events.\n"); ++ ok (hr == S_OK || hr == MF_E_TRANSFORM_NEED_MORE_INPUT, "Failed to process output, sample %u, hr %#x.\n", output_counter, hr); ++ if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT) break; ++ ok (out_buffers[0].dwStatus == S_OK, "hr %#x\n", out_buffers[0].dwStatus); ++ hr = IMFSample_GetSampleTime(out_buffers[0].pSample, &sample_time); ++ ok (hr == S_OK, "hr %#x\n", hr); ++ if (last_sample_time) ++ { ++ ok ((sample_time - last_sample_time - 333333) < 10, "Unexpected sample time progression (%lu)->(%lu)\n", last_sample_time, sample_time); ++ } ++ last_sample_time = sample_time; ++ IMFSample_Release(out_buffers[0].pSample); ++ output_counter++; ++ } ++ } ++ ok (output_counter == 60, "Expected 60 output samples, got %u\n", output_counter); ++ ++ IMFMediaType_Release(output_type); ++ IMFMediaType_Release(compressed_h264_type); ++ IMFTransform_Release(decoder); ++} ++ + static void init_functions(void) + { + HMODULE mod = GetModuleHandleA("mfplat.dll"); +@@ -5539,6 +5754,7 @@ START_TEST(mfplat) + test_MFCreateMFByteStreamOnStream(); + test_system_memory_buffer(); + test_source_resolver(); ++ test_decoder(); + test_MFCreateAsyncResult(); + test_allocate_queue(); + test_MFCopyImage(); +diff --git a/dlls/mfplat/tests/test.mp4 b/dlls/mfplat/tests/test.mp4 +index a5bbca6bbf7692eab047050b79b8ccc83516e6b4..72bcc0d8f3eafac344bb2152438afb0c4c691338 100644 +GIT binary patch +literal 121550 +zcmX_lV{|56ux@PId1Fp&O>En?ZQHgdw(U%8+cqcW&3Ded_ebw8JXO2UYgO-VARr)s +zsk4W@g_E5P5D*B^fA^n@$-vc!(Z-&I5eNtf%GA-s1PFMs)5h4q`3F-20sj46u_Ny(oGSV^p82u~&8w+<6 +zW4-@8GX7ZTIU3lSneZ~Q0gTKY?Q9J6eoPqw&WQu-CIQHFYv^=KaM4a5i`Rv2gl{#@f!# +z%E0`G(ffZgMu3yGh0#we|4+aGuyy>OJ&Y`D44nUq!@}0t#L?Q|2lOL1w03bc@X#}| +zv#~dD{^5;&O62TlU}5{?;s@wx@E^w1(ZI&U>8DtRdiEYaw1qJ*(+_Q6Y+(Oi7KVC; +z76wlLZDQeQ@;`aGnOK;aI~)G!?Cec!^~~(-f3*KAwEr=+GV%EF&CA5f@PA1?8w=YX +z7T{!LVrydL;>^p!@L!mY2LF}R(ZtF8$K26K@BgR!pWe}k*T~TnU}N}G*Z#0}926N$XW`joJB?!{Tx11ZIwIm(Q*_~CCUPVp +z6C5G~4!%SqYID{gje`hJu*gr!rHZS;1+Hx!W-C5cI)-&^W!b6b0{U6Z#t^SQm3{2t +z(WY|;2ws`V>rXYGt5ogZRVJfNd8yl|wo&idM)3~a+5s^;$q*lDcRdR#)^L%~J-mEaXPFw%RWH}yKY +z+cPw(ycmN~b=p21L#tpM|7pl?fEGqp)eZ^JPOaGQEYl4+wX!|#&~TCf@!&Un7)n0_ +z6e|s79bt63WZ>%zi&&c9!r9fJGB3uo){L_lg0XgE!SIK-tec<;EukqwOY0|am4&3_ +zAB-C~ZZtL6=_{{6PZLZ~WU>m?b7}XjChQE-#DO*HxU_4v!SO4_f>(uQ%a;cH?!Rd> +z(5w0e)c&0AG*_@7_@JjvNLFIEYK(*ls`*BynMoczJQLw=Du0>T_#quhoeWBw8RB!X +ze2w7KOp4DkI-Ad>kx!qXl0XQye_ALNvqaAe5ljMcdl}aHiHC|%goDacJ$0#rL2@em +zV*)sK!9Rc1m;Di%GP1rUei47XKv18frG!Y{<%$CekM#_HKw=m_n +za~=o|+P9Nymw2QIw(TYiw;p+(!tz>=n?cK7huK)YSNGP+@AyYv(+8pFfg91(jcBx8 +z|BG!wU>fcja+BQEbsY`Q&zDY*4A-EAS%0>5&SWY;swXB+wQ$14NiTEW1hVXr(JnJ6 +z77+DsM=M@TS_83YA7$8p(RvN`vT^$%!=5tZFb1ZI;-u +zWI6B$MoAb%me68YP~%C-6Gvig$gw74rM~cew1FZv05wf|YG&`bOHL+-<}bE*UnTAS +zb%}%;NT+5##vMJ=NL&@{QPwXSxO>p3Hq76vUC1;l5q{UKiEE|MDFMG?G&^m0^7Nar +z)MEp{;K-U&p3Xj8pilZvNkK6?N8CGW*J=J5r{n2i+pUF{vYf&#wIX}b1<%GUnei*E +zq@OGmA}sMgYc{GU5q#JB9GN3=U?LpZUvAr|wA-xDoES`v)af_wMlQ9b8TcjfQGahW +z=3+xf#d^5Wq7Q2rO(Grfj1nq#nG-leh3p|2iv=!IF?`HC+(V^SF$s-Is~S|QLa%hE +zr?j&8tciqFT+Wc>`Yw>ytilm1VyljA6?&HoJIs&QT7$yMa&+`mXS#=;9UKejXb7m- +zPV;wm)h*CcRtBS|-lLr{)rGh}pty`OuVxi~3mk$e;J7j5kj(*?E7PFdpAQl_KT`dn +zm*IPJn}Pb*g-AyD68q`Pb-&`Ok(`SR*TP%4izcb|v~JCo&lot=)G_JNs)SHxw}1*- +zT2b`1@h7(24cl7}&0g3}>618%r1UiPX@km@?oo&J0*JHJKY +z*ADpJp&YiZK_;?;T4hdo(M`8#<}i06@zGTRcgLc>O;;m$q8-XfD`jSP2$W3{lXVe> +zxFhR4KjD&$okH77tEx^T$k9LOyUX(31I%BezLb@#@vu#WiB$d_X2PpgFkU+4E&K)g +za9daUX~#ZtD>`W%a6}%9DAdkplgZ7{nmuj2yie+xC2lz=gaIvlH5?&4>lK8=HnWqn% +z{%-Bh +zsx@awKRo<19F!2d&k$?u;k)fK!*$nr^b}uvxRH21e$%M*F_6Qi=W5-NIFDMd_ER(a +zqZ9LY=!^NF<`*h%jC+*aG@gYU@AN&Gf|VUCT+JP66aq^U37eKB=R@CQ?$IC)GAQTx +z4)y+V=vR~$sj8zO`Wp;jBw93aZwG03c36Lz()+NdQJ6dk^@e0XcZeBwAo3!fmv5^? +z5JK|Ph}nay5xYZ%kiYp96dwM2q8dc2H>+T@6k{{M8|k?$E1v3&oW+~_^jNzPG3dgR +zG_0(14AUpmP8%1jM5~){izbrd3vtd>?2H2DZC^s3;>I(O^%H}~A&KCd@LZAww#s3=0zDL|t_2?Q;<{R^GrOi>wTsx%4A=xvLL**+&V +z&fg&W%}^n))zEKkmZPmzI?((TlwU!EJ9jyAT*SLY%ru~McXq1!Y~1#=KS8eCCu*Yq +znX*jH1@;=7c&i=)7efc>n3fyg1j17?8BzPi*yv)Sf_r*!o`c3a`WlbvN#j5&{qWC$ +z@7l=4I@5M1ltOfDA5o2;U7qSV`HQed3C_ilOWJ;7Y`#k+m_V8~8a9U*SX1{ae*_}? +z2G_HVz>R;`RJpSIA&LpzNK3q5KV@8IoO*{U@5Lcp3sH6q{B544%0RE$=ym__8qc1{ +zSZ#acDq~E!YhY%rja?=ZCRxY$bpC_qFftb3TViS3wRCF| +z9Q>kEwdOdxF9oMC6j>7;xXmRhop4ViLHJwDFhNCZ3XfOqnml73rss<`o2bh>{$R$u +zuEpfo@Lrwm9?tS#!EqeO3O-IHxDA(5E(pJP>C30GK92jg+&m#33Z*<7;%cnh*ht@z +zF-J1np}O+yhc`QxI`dg2eO)AJP$laU-LGPaw}vSr(Q4^=sS}S;J;Ci#h@+v?(LW{O +zDoRqXoE%f>+iWPdiF~^W({qy4P#Mme^2s4l=dBwp-&L`y3(f+!>j@4jl^g^v}{6s*Hzb!0)N60tujwLVDLXhgA +zm>Y%03V6=*qK3IEuJHF`LI?BgtEFB*Sfk%&vCA(CSkXpI2bG6mmC@m}3eo0FxeCIs$2ehUM|FpvBfuhL+=u=xnSVL$bfmAoQgz@lZBGXkUGXvE +z&$QGRUN~t-%PN$VuA_8ZtI865WTPk_{#vp~;6Vgo_?o%I_fh6z4eQe>AeUB(9Ab_w +zJJdnE*e9~WAojbJtLfuf3_119EvB!i*tHRE@&f0>F1a&_d2o+`OHx#DPb9N5iPb1N +z82w~wcyNVu;IE_MtFh7)Pk!+>r+DuQUaY5CK2o{Dxxt`ury)^S+M)i2qg4T +z!5_{LDD@U)p_iNccS+v0k4pazw*a(1pjk^cj|;N9M>G;@_;Q1Z+(2oQEn-NMzEqD(92Mr +zmZ~dlimZ$&#E<_=&H5DrCq +zC@ioO9@L&zt?3HC)EG6g63swR*(^4(IVqD*i>%Z;ZOV{4ee6&sBkf +zb9i{wc!8pZy|H}1=giJ*7{%Em66{AHfyN~5BQM9V9 +zArQ0VfkpacERo0tP0`IgXFRA_J)UFiMa}cq2Xke)(IEN}`7YdK5lGw1fo+PsO*&3> +zgx|SkpE=_?tvm~Q_Q;nO-~CA9(6akES`(%Pq@b}fBKW{0JU#E;$YKvQS1ip)XwYi7 +z#JO%2Pey2K~ED-x8Q +zx@jFh$pQ}r>yu^$CHQ(SBMK(GJF0w;m$BK2IXU%(l=2hauNXXD=(EQx*(w^HL?!A( +z8u%l|f5dH+Gh!4$Kr9mBUU$4gBmmlWnMeKUBgs~%affbmKZJPMxJH}i<@Ww4J?ojJ +z|8Z|XgYOxO$}N@ZS#mGD6ua7tUrNOH$`V)DzqwqnB8&myKAx61YP0NrBr(JRX^8DZ +zuh59tB}&O3>_J}z5=1d1SN-mb>S|Lpy;6AhJ-%W6)Ol3pxbCI6JH2Xe!`I+mwqm`B^_ksJ=A8i& +z(f`=qNyjw3aBRz9`;xcze2vdCl4Hd);(v>}re+*C2Z6Lqq=0_d7eFYkKb1WqyDTi9 +zr2I&)8^QDdy;aQFtU)%CA|&E9z(ps5i89pCZ)nG^d +zf|ClZW?Ph!xS@Op6QkuYK*~z$)&b|?4BL6g*6KJmhU7`m$Vv%9EMIE&)|)IcrMZj? +zmQ^;Rf*ji#x?N;RTy!bN2dM4d7W*Th_%oZ4OpbS8U}IgZ#E65to8m#kF}h8V5RMILv~r +za*cC7F6q;ksS_ic_m^1>2Sjvy!EBR5(@o7KgzIQJoX{c8RGzxHSsYV|M6R&jPG}$P +zQ;0=TQZ~@}H!n^=a*4xbo??*E1*8g1oq-~AeI0=*78Foo5%{*Q%PgQ|bOb=QlLox& +z4xv0Q3a}-_6^U}d0kxYr)MRq-ZDq#4eVRsJ?x}Y>`i2UIdsVfJnTW`CP`Q=N^SNzW +z8r3}!yDCxjZR(FiP&0%m^u)ITe)-L|+s7Qz1cCILMZ-Div2vpOvtIE6_lwI*B>R0mh3zkyMji)zrihiOcz_o>xCIty;Ne>iWt|u()^7+ +zTQfw#H=>;4bmOB}v14YL{5q>n5WK^l<2NhRW=)>&itS3bu~fJpWZ*yudmx>YU(U_k +zYwP;ROT(J?#zN@G5{QZFenr`7e$ljo=OD?qQP4qv9BiME`4$|4?!VM)>135y09vB} +z%k2W$EW`#R +zn#r3LxX{q85WtO0b=SH)Qu}W(Thnh~=)PK9Ah)^8_qQfcA!}6;uqbz)P6FP&ZfH!% +z0yiGlW?sP}C!I~F+m-QOy**z;dy=M>YvWCj+i#g)a~)h--cWFXxaW=^jJ^jRc^x+P +z9+^0+XhV>UmPic6D_?itDeL_(wPvk>o$9#7^m*J +zR^COI-R4(W8rRz0*#OaHoOd^oj+e7Q%G2HmT5#EEC18Dy(Ja}l0)JeS% +zfw985&4akrc%GtU<0FpQI{udh-hHOn9&NYjk~g_o3-zW#)2e4jE|rt6${>57I)->3 +z@vwmbH_v#*4=U^;fns+H5n5z +z@QFFnBH_9;JWysB681$^5(q%zD4E7h00p@w=D9Bl8#}jI|WsEvl +zsS?VmS%s$EAp6J~Z#H!ve~O|fpG%e|xTtn1u!n)NJ@ +ztH(Nc{h7kCz_|v_f_{A01e+W5XNuIMW2g2Ys5y*m=W$_UN#tDxcP|%j%_vm+FPoa5NmHVQMJ*#nFp;F797w3-D9cQh<># +zQi5j@4_Fe~vrcQZnWXDD+WA0)P)_g14_eC!}w8I%B$z +zd#BHTk?B?5rMx^4ITjz!u5nk9fdr56_N5>M> +zh%An>{hFFG8g%>cHr~drhHj@tv&Sl0Zbszx9$pPL$`ce$~HJGC(YI>J4f01gD!kJ=f +z!0#e0j5FDHxRW^T#1xTnO`TeRWszJ);3Bj3I<=GjeF;KgK+rKx!YtW*SsqB0_dsZo +zMekvimJ=u1AP48~!c!++$XZ-NE=ZUoA=T?MfD8p+_vm%)074YO11orPVJ@Fx2pvzU +z1-5dnX>oN!_DP8#l8gq<^m)cMseplPmVApji5W1Q{RP7n$leS(|JhN)ob*IN_3Z1< +z4E|NCzh`G*Nn0F5L3ont_1=;K +zdW4(Kuo#^-{)jl?x#+JNa3|#{%i+(5oa0J&=y^>*8lC)+^o}}2$&J|nL^Dv>nk7Xi +z_q-91&ZAbp7Xe7cQ<$stqHx|{urrl8oY5EGswoRnxz5pRqhvzbfts!$qZ&Syu9~6F +znEE9KCxUkbjz<-Df*l9zs*rh< +zU)b2)P8bG?KKy*VR9}8tB=W)3337;8dseNm7SdNI@%Z`;6G%+wJ!pSQ5t*#`>d2Z^ +zjzpSM|CR)-e&;Ahq4wK-$e`AhH^GDlN{E(_Eu&1o*4Nq@2Qk-%GFdH)?Zv66uuk>% +z`a}u1z||HFB3*DynMpNW&SiysKEVHZj?Rg}>wM2B%`vwp+s;{i6sx4!_@204WIc#T +zt6bJtSra+K)hd^4i&2O6E#pl;lo)nnckl0;AXQ+*MQ&YT(b{0DT9IV1>y{yh=W5bz +zf8uPH{U(-^lKNY^S|zX;pIj3)(U~E?@8u^n>Qo=;_H}64aIzEte{=p+B*%NX~ +z#5v1iD6R7h#l%_pCGpC?E$JZPf4q5rf{{UK1D+PN?t@(Ze0obCORD0D+$;iGwxt#$ +zzv!<<3&j2+t-1<6VJfWACt4gYaPTx@II-Z9rYKe_SdytV##xaeXa`F7*+i@jfOFWo +ze%gc#qyq+3VI-sv6knC=&!MgIzzQX3yf_cnO*+caPY4GoWnOCv<41R#X+hl-!16cn +z=7Uz`q-ezER|3EUL`ruWH;)ig753mX3_F4KT^@0dtR;y0yt8I$*7e_>b}@F^$X4X- +z+=RTC1<=2e6*yABI;?mj42oNxbM0;p@B4&(^g4u5sU5WwCQ+jjAIz5FDU_-A_V(C3 +zGY!&l?VD~UCo#CX^(FI*1qWC536qED*08WIBoPS3M#uFhp+`br*r?7-485f75ggS8 +z_96UY44h_lZ@Ddka@O>+P+WHb_qV`)ZDzCr|%<57DXSjG4Zrvi@@ABFhk1xia`f>JQL +z94038Ysp2td`Gj7+p!f6T0|v!t1>S(^kOs}-Zm!_v_~q00Cuq7G6+EXU8GImn!9b7 +z5coyF@-46yzFCbt$1}vv)Y@?PGm*W4bB!zo{eZxR38VAe-9JoKguOxlV8s3?pvH0z +zSzh%}V^fdJ{fpls10u}_sYZ$EZS=>fTe^^4aBP{9m#KdXeB-dlF%{IiNxFjvS93|* +z`k6=i(4vUkTyP*5j0;kbXudhKq{HyQIYJ*9BYbv@eZUK+p0hJ)$=(X%1l3LIU+(PJ +z^(_NU_EA0}DvwebQ(dNuGg=E741O9u3pmG$*)#4bgtStz-OX1nF@eN8pNFuKOUJgR7wBafjE9Y{hR10)@p +zl_yu^=)K9_d&s??EOtBhUk;kw1O*GJc9F~>X0Xnq4jhaP!`XPeP<9rn*A{iJz?6v* +z(Kzn#eNpig?nEBfGr{={)z5;ej&3M0OMK3sHIUmt1nGhp*x~sgAA1y7PnwlR+IRoe +zQ?n#Q48@L3PMcsG3;81OiAz%RCvlE0%0Cmn*@f+>>*^6;7O*YEN|y)E0dg4pTIxXM +zHXu`K2_d0Q&1kV<)7a5xEsD(3(=gD<{VQHYH6@yu48dL_HuaL>k|seZv8)!62fn^Z +zkI5Btoj@2A>i~kWiLK+LxsB>;PkK(~UAoRC3&T=Is^M(gclw7aF-EuFTHV +zyp)#f`D}|`dQkfPsnB#8IUcWz+G_h{h$}J+K8}^$4~?wY@Gr4mPrcr1p0ruR`}=@X +zREqP6vo8sx%UK4iy_;`A);%sLt2-1u*Ci^hr{-UtgTXKVU9Eo?&(D#+g1*Rg7+&bK +z`SZBQ!AnxS!MGA@ZJSVi^<&>5zue-nu%C-qD&T%a!!UbvM8YWAiYLOKlN!ah@JKlq +ziu*ld083RRSi-DAmVW;uV&iAwUeT%C{JfAj*ReQ&FB+CMVaitFAPEMvPy7-72E@yC +z4duq7w7%7$q!c^32F>U*Kq-!y$bo(; +ziQMj|9Q1oOn?tUvar4Se8X-v+DPp;8- +zdY5&Vq$x+1aR(&Lw#L9UyVa{n_#OQqepkF6T&~o#ZrjTse18<@!>f*KI7L2*0XIxK +z#?J?#>+NpZ>91kHl%=nMKSvj0mq!w(49fV2y?2aLagWyw*DdxbKZ;bP@U(ddD9BUk +z3~gC`?J5hz*?)Xdi$>h*(**gN=g#tm4rqLb$F&h&CD*Y3;&H2`d1q>k^gg<_BEx1x +zL#JY>oDOkT4}VxhY!Z3&_aB4aqLtcis(xEat^J7(xRX_xvNy~Dptk7Oy3|VRdon!^ +z1W~|IGTJJq)<(n$qdWVO)hxmpDlZ_lzEk}!AcJ#aR@VMb_I54X2-2J +z$txf1IHqRAX^v$bCiYG@<`&PP!7Aw}zLJViP^^S3V@bfT_NyaaEypnNXrw_}{01n= +z8?8)4G}oG4cw-+F^9tX3-O-9EB2V2zzSj9{y?l`<|3<++)fDHV3Gsd1TaJD3u@_-k +z2clFAe5NViF6VWTJtWxXn7T@yzP6i5| +zoa=!^zkOAsj&#&Ox~@T-AbV0!_$*VjBKP+1sE;En|0NVTXSzfary4cIzpj3wKuF7n +z=y<=P07bTAE@Lr&ZJ@;)V5rbZ05xk+V+^2-q&AX?* +zvyA~USu?9c<=ipyrNhQcCBe23`p3=Hj~WbT7UzPAFh1#%>RDAD7 +z +zmltv{x$?(z^km5n77 +zz7KMh5cHmYGX>SNqA1rSHp1_@;fZ}BufNR-EHx4X=gqPvUiWN&K7)yK}ZsvML +zB#h4T-Ng~W>4;FsIhyxGn1lf6!2PDgm7%K(sf2jUL@yK3C{>0 +zi_%iZ2JYg$qoOzi+h`gNs}=Xvl;JGqCmt3f#~kS#SQl~X=+KpNgE1Ewm~#5Ce|d`U +zV|&c5P=NHtZ}oN$xO-oaSI>KJ6v!L2-CVV%ta&>z9<3_SolB5ib)5FyiDyL?Qmrg% +zbUZNSpdh6W)4z#tBWHG%@69jgEVa?X_||8KTu4S(F{N0TF*1C#bu-98>lQz-DPC)1 +zvz?5~=R$iU(Ohca;5e@1>=sL5;#d$+ghyufm#8>&dRqD^7+yE~RX_+m!PXk +z<@2p~DXvdD6xz6RR;amNpADE<%OVyuqZk?Co=rON(yu_F4hlx=-U@kjp`KA6>ugza +zXDsCd{rzISO1KZw>|#ycWShfowrxhJJ<)p7uI$}`o!Bzpb&L;M#ldWi0aYah6B6W= +z+jQ@L1*lvGj-CjXc{Af)WF$)=jT|0>^?G3 +zb=RyUy0z|B{pR=wZ&$qGH#;uUsL2429~fo)eRif!6k`;-S~+e~aE%Y@;Cr1mp*Qji +zdg0)!#5y4}Fd>b^SRF!6J(AM%T*21wlPe=l6+|Zhh(|g4`BN7N@)?Q@Zo?dEi<;vy +zgisJ&a9bJ$o|W$GJ>*(2;IJ^8F4YyR1^iN|}7iBEzM>I*7pKAeS4)9 +zS7#d!y?iT-khN+ZmWiy +zee>1#z@AV6ltL1mqJcKKSBmpN6b=Y+75x!h5CDwMa0!xB2>w|!pim6N=ez0u#8R8up!c;#$VoioUGm0w?Bis`7i8M5WqlFl1S{Xg8F(Szg`Mr?H8hw# +z)c-BvpN0dUV_*h`qsVyPw$S+0LQtiQJ3~H^*@b4^*(Vp^WpS@WV>6{WdyD6M!Jddo +z8jJM7u-1VF-MrDTt-ox$rFwJUHWkU3glHCFJjZGcb*D0g?z(@RDk*!fYDAUIec2F; +zPSkmg=VQCOg%@n3n?a=5?liwwy^n`j~j87ck+2M;g39+mX7GXvg@ +z`IWCkEpoB9zAK +zupBAla=UiQ>EvyNepn8y5S7$Pbr~Zfyq9`18G5sHhLpE@ +zq#eZcO0IM(r54fPrHAG$e#1+ES{4$$(B^)QFR~V%K}EJv_BJ~HropQSi`QjxPy(-e +zQKA8VU)xrcD%{Y6g0tgUrehDknBx9q(>zV{(+TAngKd+3XfD}aXiO6m--sPT(}E7a +zsG2(FyuH&=6PaBrP~*Bc{T&eqjGG#k!qtFIWH)s(X;UI_f85T6cy~3&7Hkfg%tN_^ +z$oh?;a=zW!JtKsBo%&qMb89*x*S^8qO^YaGqERY*2f=o;E +z4Fp=3^5hJ!nGZrpvp;yUs9F%b?KaHJUg>#?f9M^27&2b#S+KH2S}Zwq+jMB$0PRv6POT4$!lhvt{jQa~MSi0MUjD-g>gtd7 +zOfSbRtXD4T?d#$0AV3*W{WE0?2IAO>WWvfqa$7h&ZJG?Z+V>8R#LO=4238vT4+QHpjXy4 +zBVKrV8AnLu3nlV=)P+Z9DalH~7NhkVXh@%<7ao$F;%t`}97kmxN`(oeneG*Px$T7Q +z29=isfZ6ImkqCSCIx*S36sc+&mjqNgmQB<)woa+@?cs2P)DBF_FuI-`IQyb&z^>PUfM|F0eam;5Y}?Ym(l1c=U`wy} +z)(ECLT|Q+}?fGoz*i6c1%`^w!yjFTd$Q$DWNgN_2$7VL<3AfJ +zfCY+drQgs!07n^XKG8#9q$ww0ba)#jIV{$AE?h@OQzdN$RNN~*+ZC~Vwknu*Qy@|0 +z`)!*XABKu5cV!wU`CT50+f5XN@)#ws2~5MD9zEt#DwGkz(=Qi!2 +zY5l)1rC9kr4jhR+2P*>>?z_QeIuK|wvUyE*O~660AbHuYm@#}Xi+k!ZLUWBjqBKhH +zf|VHl`Y`B}x~o-S8#_>UwfdLkEJ_p***d3(h;fk)%rZgKLHvVwot|i`ep_hLTQoW_ +z(EDDVp_|!yjRwLtb%1}Lu_7Z92Rr|&fHi_Z}2pMNVTnKMYnB6P3zJDe+_mmK9%`k#Pik&bAXf%6~8Q%~kJ&a?=Nuln#MY +zwM2LbYsrCd3^xEM$4Yz!-%AtGlQ!FMz7IY>w6KwHXKMeRh=myr;3Y9t0B# +zX86)KUK?iGvLEXxw%Fa8zR;!dOy&JrS@%Q!fMQ461*#v{;2~2Vtxl)~c6}7fE3G|- +zCrNa-Sz7bt91{E*%J8r)qKe@i0tjkEM=Q&Xkbpbw-Q-^4UU+pFVLX+hWF|I7veR&0bvD6{7yvf)zZ!IMW_Gd-YH_bLQekS6zZ43;#0+qZpIg} +zQX&Jj1k2b%^qa*Vj@L +zyq2O_;{tX01S+rR+E*uI_cY|c*zT4Dl3woUV?i0tG1R!!jtR5E!oonA1wJ)5e+>8i +z3*IYt6e1?N7eZ{)RVcogl()VpkoV?1wMM$kF&j^^K18=#Yp$Ewc70vU5_b--L1uo~8Ooj-GL9H1^B@@7yV?ONN +zCyX7hUA@|V4>`~L+I%-!aP3jvE~ZKw#Fjjxnb+*bFl$Lq|GRM{EgUZ0ep)LX2kdiA +z^_*Vt21;n9w_+;$bm|?VENH0%YZ7NyJW7+LlmAH4#NH?tDg6EnzkrKu9QW2=`n$0# +zDhMN~qC$U{vhHiPtR#8i9z}Auqf3Y_cuOLzRZ3+ko?=^%qh2)qx-0jJd1r&cLawLI +zhBhRE`sVnbb@8xqC)6`0Y1^W1ak`^>D~C;*Ky=3l#EN;DvprfyM@2NpCh@Bv)3jTs +zqX>5!BXFE|psy1T55tzCvG-fjNm7#ZUoA08T&E8Yqti3J-Bx74GUx*Y+?3@w$I1~A +z(eksd7tPP;4+hRH{`nma1U4AZt42~Ylz*M4RZ`;*YDRk$ui=KSF2`E_d87b5Fw6f_ +zGh(&x%E+QD_x|o3HYe4UdY{J*S1ZmG&C=sx7eNYGaMSj4P-8Oj*F(wXv#7-!rHKkm +zC6e}INh=KR4Lo-YJ2TeQ{n;VA%M-4~v`9|T7N7O*MBlhW<-kAk}tk$j9Okb70mS1LNSzFP`K>obO?q`duRQYM_wK&Bp +z5**}B)oA@Xt-*l>2)@xV5$rqNC> +zc1Jh|PM0%PMjz+$KSq2!f0{`?eKbRChsljMMssd88-JT-Fql)%V@eoTa~bje0)F?~ +zZO4HP|Md8f+8N)kzSQL^=SOl&1=n9A9ERg;jH +zCy)5roRoZyC#Hy!480^D0DuU~KEpqp- +z1^H;jG5Tu1KKqIchacFZ3L5Tc?!a=U;<1FeoCxzo79#Fh$DM2~Td*{(Q^bunoDMYN +zR7q?A$gzk6P4VtnWcGOCEw}H@q0>2-yew*+4ss5R5pJ}~7c4Jdo_(41!-QYOT!i!A +zD2X4+1ZD4^U$O@k+U6@%`^QnwF(P5PKQmaT;-nZN+1OG^qu9F7aQrf?oJx(8i*WcM +zX-5W&6fFiUg^544(5)z*vz?YLVe?Iac)mhXq3vV75K@`2Z8iAZ?TA(RCQUU4>27ZW +z$5c*4xUsREI0^=iN4^L|i%0e}<2tPpR|aro9qeK{YP?^hZr&FQBUVn-Ii#;7o|U4l +z<18*N&TU&|E;n!Eqctt|I{&$-xoN8i)Ps7lCXVAJH^H(#RNFh2FNEcPdo~Yx_&`#c +z;xd-`fu}VfECsEkq|y5<_`lkaUANTn$)3sg4}Q@O +zh@Vl1X!u!nh>MYS<7dx?;*DY)@h1uzIMP^f{o-xvN+>t02RGvDMFEF2*Ezw6-k}v8 +zhXzITQ8T4ZItw#Yh7NlsyamZ}ot40z_g_f}kfyf0s+MzW<>E0kz6)2a);Lqh*{D%#af0KupO@Y+2P# +zxXU<{I2oXE>;C|AK#ad=S>H2|y;x%mwfgOsff+MGNwUB?tO=$8pgzNw4rPSJF0+ho +zs*{Wg8Q18MNapr(yhB(jA%Faa8l~dts#`stdsr3YU(90E+^Uc*`oRStt9nQ-%Yt-d +zRsW47BLsNIX#(zjDQson*iZO=E^GDVV|3mGr;+$>vWf;k1xCSJ({Igc9s}wV_lqF! +zzd(V|p3rwhNIHHBO1J4W&uf=H#>XmA3W7ETO#r6KJjBzE`alhjfX`w)2dZRW_4+2K +zXh{rGDz5pf1g)21G{7q0m>JT}^i}Y({>@qh`-4o&cyM!M8a!jJ!Ni#IWdzop;nv?L +zA|3E>3!cY4uJLmE1fA{*1;1$0`Zd7_6O>4{DA%wd;IjihgQ!fo +zHQ4`aW@v!=Q2?#E8vPJY0}O}b?{tG`S+jC9qu`M^f;tzXeqH_BKGY`AT2!No#2#=*_-iE3i;RB578Ha;ZGA2i%6naul%G63%BqRsmPWrkY1F+ +z+=Z}D*Fyxz0UzugHG^c=K3%S`A8E{LR5W{$c3Es&H~TXzkHS`1WdbwZqpl_^V8iye(Nn3>c2iIJcY>G!^{h+t|9e4iiAl~0tCC1mxRR<+Ea4QG<}h{LsguM +z<81hUUXVO(oA-m;dya&R*2(}RlP5ffn63r%GG7Gv3xT_R#^OVZ;L~}Ns0opdqXkAk +zCNkT?xaU%rGB@tLa$KG)rp-gki=<4(JDT( +z?mhn=I97ZgZ_#%`!ybOGPN!&ih)`Zhn?9Qg7`Mv@Wow$V;^!3Jl{`WgBD}USa4RPY +zBp4krR-foqv5EOXb&ja_3q!L+Ga%%WO42K`{_P)Kk0fR=Jlm4|HlAdcYTd8eiu&(O +zV6-{Ofxe)jd-J+K{3vJ1000Mj0iLI7LVo}R%3Q-L{Nba32z@}%sg8v6QgvHtQE#O4 +zQt@X@k3lwduL=?CK$;S+`|7Hc)MNxa$W$bg7A4#0lujq +z5_`h3aoatNXk$!TB{FZ@CJ~h65@fA)a7!;Sc7`@pZUx{zEl29d{dG6hii*9p4xNZTuS5 +z-xCX}y6E0zE&(%perM_3XaUsP`0g^ockOc3H&Dj%NPOW>O2C)kMVTt)nC7=wOBG&~ +z9W5xI&t@w*VgaT^$uE0i?>%G?9*4Q?BskvnhB_H +zcZ}n1aS*@`c+6lCUaojb^zW(`+E>TZgHoNr2ltS;P$d;ixpd9AIkIX!$cw&#-$t+x +zUKZ0o$W7o&H|xqhGjEw|bjn58u$Xc($<$#9XrE2;DFq)4Ce;s?ds^NQTSFjVJcn^5fDBPr`$ +zlO;q{{=#?brl59|n(XnC)k<{ci#g-A0!o4bMF`N63oq6^s1bgT1A0hB-%B|1)cQ=& +z5E$-JCHqgRHU~gW6!DP&%aJB!W4fo5a_qTB)<*&*F_b!N6khzp!y(4c!pR$q +z_e0G?nb$&LyK6ps`Lc*S>V>ObP?q`NGco#Z4i2!`bVMYyzdKbp(D1vQ>M%x5RbF)6^>ENx!0r?Qp7ghILM3C(j +z+;q`q2Mze?n)Gr9HSMc*krQ#e4IO?y4ucp8Wsa|rlziItM^y6S0kadx@XKQ8a$?I_6%4mGKJ-xH6d!i=SmpS+7<3=V!$5j$kSGw`j;P94GJi7Cu74n<-t5W3g&1^7u6Kq|z@%ZVp +zCCu5Q91B^aiog_ftJ&LQr2N=6@e<^@u4dp9y`1K9KjU6l=|u34No)YnguV8wKoljT +z7%(oLu85$v0GIx)X?Hix(W)vJ?cjudUU*PX(^``ud{jR4erdCE6U$dA^>nW?vbVh} +zUuTz9f5x(Ia{lf +zPwBb`O@ZknrpE*B%l_f+D-Wpegd?FdH7*?4FUYv~xV2_%lNUG{piKmQ$$2{Zs$(Nj +z@$BX%e2Lek4svCDD)G>+22Ba= +z-csA~UqIi;uhai5kgKC(s*?t) +zxHLgT;%*GD;7WB;OA_2asC~FkahP5xZ$tN|=6z5oQMV_e6{<0Wfu@OI*Opf>Vx_>W +zw?u_ARC-InL!5vBH_qt@j{`-)g$KC5RBXW0*-gFmLP>VhD0a{^6~?iDO}+~Mz6WIn +z&U$*G7ih@Q?jPzmxVw(*VbLlTSbr$tP|}to!78b-ZN}o|iQ5xGLZMCOaI{mqy4ol5 +zX;fLx)~AEpTRM`9gkOMP_FFq`5Qnr`qVX2fK+Qk`4U(108WgTzSO|^VmDs4;U$T)$ +zsQPHW9LqnVP0TxDfqs8CY9OR +zm7(~01!KHa$BL-Ow@sUtKKG_ecwHyKF3>k=Dh*uXl*?>OS^R%)_`&Sk0?QkV`e?PS +z_;Ps4tyRx4cXg-eMu)-ogwR&@)_r=zn_Y;9i1`w`u0HVlpG_7g_nHFn*>#~6369Cau#Az +zmOxd@2qLt3W+MfU$B;dMa`Kr)TCs1q&mFgKNE~42pAf+8V3`c5AdjS@#nHJy{gfjo +z9>a0>5Zn}`U5v^vI{gMR;n!%n)Z@SF<)y&wh|bgtr`(qA)#75HW&nJ7lH#~rRw+E5 +z%!wSNsJ@1SO$%e22_}{!O~`tI{6`eZ{F0@1mmh_O +z@ibs-NykBF*)JfA#=JIWt3TQ&SBqO$Kp28ed6$OK8gZwxD2%=F|i-}QoN_XQreov +z5h3ieUcV-q%T?Kv!>Zx}S%VC9?fCL-%}(bQ@?9gD(=b{{;gI4k$y;Nz<2#KpLgsd4YEVZRRs;oCZ%<*tv`HB<6~PfMkbw?3SCgjSetP45($!p`@t?L}u>c +zk;RO`riOl*d+l5teWyx-WFM|-k6v3XYkz@lxFcWcDAVtcbPNp%Smr7uKLr8y9fQrP +zjSr5FTmW}$&@fz9TUC|)LpisT9AJ2b;k(tNj +zDKz%sLd4DeQ$IxT@JislyF)*Y-&|F1CkRe(8Z>mrE*W*~Kd%ifX@$i59;ef6K(C88 +z77~;sef}*G+Hb=lwIIs>G7TsJVvwp)T`i`bu!v^RJ;?-uT1s$WkrlDqx&>Puxz3t@ +z3ByaDdoY08w@1TQ+LUsO>f}_O627h$H +zxG7I?F3(ET*5FP1H6n_zYQv${O`QhWBr<@=$fo%8mg3}Nl9N2*smy{A$E|P8A=6Vz +zqG7tRHnuAif@~&xjbsh%cGOpjIW=Wk1y~+6tGchRD$y#;dixNmVDg|G7Dm`}nwG^5 +z@!@XZYNTx8kiUd3uZIwL!DOo&H}zIq~$lN<}ca{13Gj%MXE +z99xNzdR=?tz!K?hfhO(P*~e}5I#j8ZasOq?GhAQXl|NU8QY76AU(38TB~zQ@XxNm{ +zy(VlMOzO1?dWprybD4|4NG9;!Y%Y_1P8#r^FvB-#hUH5Flw~(f=#--u1X*sG(2$6} +zDN-*K@$|wXfZk5}H+}&n0Uh^`n2cwL$Z!&9Ongith%^^6{f~pngyw7kmG+)e8j?A2 +z-~-@|k{iuxU_I<=F=2p#R!~um-jeqHzg@wI=iXk!CPj*sJRs6=QJJF81tUvfefwYw +zHVMZ6>9escSBGvZv$s6L^HFX1E-%}RiTTb8a1=TgimAG-ZbxE&g0?q~|B43AI7C}z +zE9T=L$tOqRxC?bW88lvg7wbX@9v}v!S7@!$eC3$J$koqyQQGKgiVzo{L)UyFv=zVW|<%pq~e9xc@kA%(-(8AhqmVGrN@6Gy6F7SV*~wP&QX7=RUUlMD?=-CGt+sTUx{P!_8=;lNpEKgB0tO2k +zCGn2QDB4K_L;xqWst9%OgD9AzPuz142!1)#ySdHH1(+A$B^gIv5gmw +zPF`OuvC#rj`-nYQ<5AKbu88k*Kxk$AKMtu@KoDYRXvlvHcH%%Mcv(TNf_=vThKC(5 +z5t3D3Yygh#I)$zFDe +zyC$IE(zeRhwn>aM6%8cSAaAH?#UhmI*%x-c4?i+OPcxE6^G)Ew(P`&v$32C;|F~`9 +zGSDw11-CsxsV+Z}jo!V|J4IorkX)pl2drsvYVLfgv2M8;%?Y4@tycQ@Fwhn^9EcJT +z;!2o1LalEv`06991ziiRhlTXrchG!Skv%?eq7ZQ!Kw7qlR>WWCRn#4}d&&E-(K@vR +zjJcSTb`B@P#JA`PBuPL0CEv?0AfR9*2YGcbN;P8{_yKuQK&1`VW8BUa6hO34@jB1I +zfBL(VaxOg*?0O66n*Te|+N0{pZna=P)kLfXXjo0XD>dyzSE-!BNhTunhk|vC*YrjA +zsw|HrCRHGugI!F4yYqDy9KQc{hufA^J|350Yz!_}1Rdl`1t%mp@`$Wd@&i- +zPZhc%r~pf*Di<+}RHlhxqRefRaI%h~p0}s3Jr(zQUc6!Y*(h)$Q-to9<>O7Pt+XZ% +z+EG|b@ZH$KzeCoVi%)$e3S}Cw)5ejx>$EW5LeeK->wVbUb4@zOcZcCL$g6I;X}F$3 +z8Ja_m2G~i&wh>ODXlo%eu0CH{vDEy#XemSQ)6ZWlaz45mio~8|5n)4z6(m*H!9qMp +zCH0@Fr8UOBLc5KrOI120E4mZK8rF97lIBAX7Hs376V#&}4=ay8+5eieL+wp|WzxqU +ze3g|n<$9OBlcF()@L8)eHIYmZ&&g`mPnF>Vv$>1QnX3x+U4PdVlp`w=yZbyz+ +zgF|OH_rgLCzXM1X5Kl!CKTOFk?g +zRAI;CxDf_T)-44h3YL;z4TjVw!kn=m-NCQr{L} +z1Vc{Bv{9|-{dILYr(UDwjMwxpxTrIyWUqwZgjE|l;Lnr^(vGL^LYE13CSxmNF1VI} +zB8Yhmby%apPFt+7(a}e~;UnmwoDq7oUYO?~>0>hxfI8&XD*D_F>B>vq$FHCH?MIx} +zYRmlg2J1xNRrpzZ=swL;TD_LyNe`1Tzni6G8+~9dEzbs_{?5!Aix>U4Vpd`%@~(q@)K1RbY)?2@*9avdqj +zS3TR!EK`v`1++e>O&_3;Hsu+IoC0$Qh!_=6Wt%kDE`=`~I@W&YUq6Vg@tv*}KWccA +zO-?C0Cm@^)mRoU?wzb(ZsF(Pow2fX@zRa?PQ%tHG{dcLhvEwS6Ezl4K{ZTpXZ-Dl{ +zSSliH)$|vFI&|uKZL3N3VI0sn4_wlM%TY#apYXD!i={DGwb~vHV7A0nbREogF~J={ +zyd3 +z$+E`@XVlY#h4M)WWjhrQmwr}T$AH-ko3kMyTp~(ouhNvpg@xd!eTOB?5xpFJa{n^Q +z4SdA81kYn|5qWO2*<)~Hf(Vp1^lksC5QSEYxTDGEY|tE36H;&1a`YJ +zVH6SCQ&Iqin4YKUCT-kZ@@T?>hJ<+~J%DZc@wqT43p)FLSd$JKw9SEF4SM4 +zG_e*=f(>)Cy~{$42Ym{%Exy{^d=k_(-pV8*$h1~WqOEDmVKg1E&Ndv0TBl4z!fOn~ +zV<@}YM6icHwdqL_H7awqG!qj-@v}Azk8uxFxmhYvEcLvC2mDk35(mWQ!}6#{4%x$+ +zyMKJ1++pcXUtPh6#A7N#kUM0+VC=_-vwHI?0%BtQ+!+;JTTfvTTB%PKAE$36;{atZwLo-IzVK=MTo40~d%%>w^=?S6kL6e;0r +z*swKV$*QUg{MALbA&8?G*qUD0i?fIN*-6pI9`4({@(E5e4P+;Th594(sD@FHzO882 +z-J-2SZ>h1ywP*n5?t9kB)^Q5z()NI{BV%>+0hhF4rGrtB!)2>L#!BXR+eE9S7QL3G +zf06$B_Xu;cL-K=rVk-MK?cnw4b4w9a^e1=cgXeT2pB_#W3B3&Tg^CgL1QTRW`(GbP +zcF%k`1`PNnQL5~TNT>NZlN1wLsf<;_X*rb>L6PNZ=hZ5vZ#HUgQHdtDx0+e615z$| +z+a_WuzkxE09}of*fATipk&TD6!S}D@!z{D?0!)h2vbXCcA!hG$ts$=;US?<>y2$>| +zu)Rf?mc;8CkTK{&k& +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 +z;oSg1k*vum2Bp4q{RL7BXg|46T&{~~d(a;p +zM+18ys$wKBLh+WZvDK_{wgA-$<5hCBq~VUP;;vK}92;)?03_t<;f4Gf-d0Y%Zc@vZ +zN$@csVZLk${Kx6ea(2=cT;u%zXvhAkk9@l`;>2zVou;QFoL5H|6~DwOUAE2jmtcgK +z4gdfL|3RAYNvJ_=nM??8|Nf_h00f(j!MN$nVIIE#4$S{{=U9ubV97#}rx*~4PW5HS +zb%q0a{EqpRjxhlleR<3a-6vp1hZS5IgsTkyheS4utMs}4ck|M|NDJt1{@nKHss6HW +z?c>&Av7;ua8U7tw=Wi@$AGV` +zuc^cdM5`Y9XIS|zkEQ`zkN8)$Jw{0zCZ^td>Gb{IVnn-jV1`_1-OFR +zhSV&AK@pUW#+7Eny>@LaftsMp2<{0hNV +z?B!8bMt%l4T;VVWD-UBDG_S9SmA7z2S{P{6>ra)OjewXEQ)>=$=<%s79&#Fj#5}EJ +zywU*M+1@`|aG95#&Bt+Im!{FxrGvQk=K;@4VQo~u&e9!)5wGFBPW^Pu70zl~_T~FJ +zC-rUyJ;*-*=Oe0}|NH`4i5JRawI4p27bzifmjYnl=bYyxX4GWpsSaJBzV2CR!1)~6 +zH_bMPB!Tv&Ir_&N95T>Ce5}EyB#rDG7aLD&$l(7Zcopxz68xpy+t?d-A<6+h%@Gp(IkA8-c=R)d(^9(Z8eK}z4 +z4)(r~LEybCGwKk|?u3R{^Rn~nUC_&x%c7@E_nS}?H?2`(Hz*#C2}A)?(_1yCwo2*z +z=h_3BY5ru?_}`c~e96;7E2%^(8!!yr#W8Y8Fd;yyPlcXXYf{M9lF&H#T!vTj;JI9? +z8(7WaK2N&<5+pWn;;XcdXlgBZ-Lyp%UF2HRUY{=ad2o^hxlR}fL?d0Jw<~oM!h&3f +zhS%T2rtj0cW@rgI!M>;~Qi34EP9vdrLY&}iKfYP=;egI={l^vdb|Lb|VMF6964bX_ +zn#IUQV&zX&e`hZjQ%)G4H&C`N<4#KvX2Y(ewY*UwrA(*SA)!XGSyKm=k=iyl8zblI +z?z!MOYU$}vw8tV6FK+x2>s@|E{IwEVnc+t*nfGh~A20lNdlNST^!g?!qS?hH*LtuT +zHXhRgc;#SPP}?3Ks3ZlZX&&ojaGn0kKnsY%PlYwO_qQJ*S%s82hJ!=P +zkuuB3n_KWq1&zer?Kb +z?TLb7D(E&Jp`N#HZBv2~o{F2TmqH#*xw}kSb>)*E?mR_9JZL`+rJg}tj#SC&!NcgJ +zfeOK>TwN)H{T~M1&201gteu$SUZE}4iP=zg#%uo_fuNfpFx0lUBuHL>708CZ`Xh-a +zsIXyG*}zGb2SiE+648d#KCyq8kE1#4#6JGv{b%r8%PpOkV|6t8wa+TnxvQHbnvBhF +z%*PAp+RMPH1~+=d{7HGHVL4$lLEwzbugDs-bh)w&kE$Q{bDmb39yk^1&EX6brSRBw +z5ufYCFx&rnL!TUg><^OfYc(+GmjfmyZeYlq-~+Yxs8(pODrYb7?-*Wqjy(^nk6;o>RoP0YR-dF0Mt%|`qa?m#ar(*wIk16Wv +zfk|CYYg3;mQ|$x=gKS1bt5W!WJOJtmS1;a!ULE>j=vS=aJp*oRngtGT7%qe9q4EMi=04qRuTvKukLc>c>6OYqJdfoZb +za!8Vo9xxX^JT>A10ln_f3P=_$SZXh{XsIn9+PJ54zMFk}ifWajJu7wbuL>piaoj-4 +z7x7$${0+|QgINTVd+pvB=8{UdVE8E7q6D7WjR=YWYTf)L%R%)K1!~GjSmgR +z7dEs>i2I|55^P1UgzaOjRB%Vt^+?QpdDEYpfBAWnW^RDkWD7uD0eH!?ZdRC(Q$go+ +zt$S-TA`z$46v`vZAIl`_>cK}oPGMbn1LA$|E`>JS4a_C5NC4g`8gP|PDf-mET^P;d +zK~tdM8yExJI#emyeNgKT>iFIlh8*9e1u`f;#bLgtG6*V`rc+WRkF0>=K36D*$Y-TA+jGAP=3it$t2 +z(c{+KIoIO+n7`%}qin}AFB&9fkHF<)vrmSD2HLk6RXZ~j4NPWPJLd9doHtV`<) +z!JtU^d{lf@2i9%HtCW>WRTfU?%9t_m^wha1yUC_&(d3enA;ZTY!6Ovp3-^P!|F#h3 +zlv)}>&kVW7vQW2}dkyc)i$i5qBkGE%3tuu!3|6(s-l8#iNXr5Zp@HdDIy4 +zM>5}HUCEcUTP6Wk-q%6IdmBw=N%Q)d+-yK4ens2t?@_D)b2+~e_Jn5et+a>28|sh +z9-7cILwpiQ1Xn-q`1WYb2a@HE44c^Xz>z*jbIIaH|Dkn23V`gV&uOdTh1*OSWqEwEzh(KO&})6-`kS +zF>sjjFwvTgyG;Zv$yqYL_~rvA+Tb0AJJH%T({;}|s;}PD1cPZxWO}|%cDn*bhx14u +z49qxyM(7-T|Dz0Fd5ioWR74qqkDVl|?x`48t;ZN0WRN1al%YTrA&?y+!T{8HY5nlj +z?I>&Y<%gHbGuE@Ju4WBF^n>1jDq4W&P +z4zMHIiI5=~h?~eae)rug`I88@A@0rO>xSN^l&9iG=-VYGkqI(nV1JA{{BqK(IH1H&@0Pt!^_8wvt;t;fhD@81F-Q}(gH +zi?qfdv6m)!z{9Ki=I4mR7n8zLaTJxPO5J+?KHFESiyn*;MvLA)y~|jwFC+pOX~+HB +z&~_TgZl0NRqoyINasPzLxTFw~5{CHb95yB8BN-fb=CJ*79cE&Jy!T&VZ4t~ZjYvaM +zg48a~NpWkx#+=y{-*ll$#8|Yu#HW7fE7#c^ChW@ef~97})v%r>w!8n_eA3t00dbNp +z@N>6O5ehHkYsi_P$y&z1BuQo!!+xi7PC`X8D{sv0xWokFZzUTuiyEyzK8f>9h~}-{ +zR-kGMwk{L+UcXu_26s#kbdcS9fmdQz}80MV%>;z^wC-2qZ#%>7%g)pwu= +zoxNkbqQH*8iI1ftAJnSvQGVaZ!n`enz%`W^_Rcqe6-Uo6%z(UB+=O%FGw%iN?}Asd +zf!=b2zKY~dniN|(^l<-8gOiB1T-Oc&pmRi +zid)R9t>%^Cmjfx&` +zqaLu1si{S`ZVEayo(f(%aZRRF6h0s!39GM<1bIf~+m)Sx@jIHmXvVNrk@3(#M +z>@Nk&i@zanZ$W@Jzbo@j^J%Jeflj+n{qTsabg?CmdE(nz@tqX8000Mv0iP{&LVo}R +z$_y~Qz(=qK00@3`@GOsV51;%%Ml60Yo7i=Hq?JB*2YhwH9+8ky%LPC&PCl61b6VmY +zVf$VuNeZ04nQ +zs!z0u9C1_`Ty;T@bckOmM+%$(e1H8G;h^wIU&upHUK8FpZx``Z3*W~uDq^k*E7tOm5QM%gdLWild`9OhHd4U>h^lmJv~)NGD^dTZc=@ehx{8?o{Ax9=@m9^mVQvoo;m9&-AVFi76GbcgEx&#Qja +zQh9)0Y~;=Mt~Po^@X``WW@R7-u`s2EFmV5<8eri{s}p5lz6AiYVEIJ^y#KZvi?8$Y +z#*-x}nGj3h!~%ZiEc4ivDbVTh!)~BP_JAiU@q<5JWm;Gs1!mfzL9u@}-K0mTs}n-H +zqZLR#bTPECkP5`#zunAG=N`<4Pz2OiQZQ?jUe>{x@1x!^B-^mMNq5s&HMr5hZRJ(Z`Y52;K@U?&;q(AX$X4elZ3V?)>oh7iS#B{vr +zffZfDQPTI}eePINRSoRvi{+B(FiA)T+`ntltXRE)QHkjThGu;AYAHQ#$5lid_X{C< +z4>pg|L*^y<>-*9aIO(&6d7zt`j4Bzy(t{d5x5_EZ)&To^ff +z|H0ERe(CX7fPXnFS?#K_=DU33$U{1oSs$I$ZjutBpQdEmJ@fW?Z3%Zy$$gUS;5{Or +zO8Q6$BZq%hojUL;PEl5!`ICC&wYv;#_aCYWQ&?Mb+CMO&vWp{pPbB=snhO`!E}o^p +zo;IMM?_yeIfF(4CaY`MbX#qJUzXf{;?!*-$9jrOwuSB(Nyff#bPP-r0zDjcEUi9P( +zWD(SNl|v@>uP$cNmfMVL>u2m{2CNhXAb%Yo`gok%I@Sz5sV)Ca*Lp7-1PN81KQbNO +zcp!~A{aPd)pZ?9BeUP=klQ%;f6PE#gQ6A8pgv(aTc@-~E%|$yUZ6Y*RBR@7=Sk!F> +zNN{xL(zAN3x8Uc%Nkj6En7MJ>zL(3Y +ztY-#~#w=v1r1YS{T-~foE$<>k+vTYKvgm7)RlAUNPH9aZcHo`2WR28q1)Et?pH +z@-Nbf+wHI~ZbDk=fLa*~6J;H)f#QWPkX1;dUe0(lt6Ke1lOf|Jk4i|WH(wOD#ky9^ +zyYAf$A~Y4Xn?CwTR~Gc@Vby%>Wi77KzxOc)@p&1~Fi|!JmPT)#Xz@|#As&y9Y+tX% +zuuqkVBSY^P#~TopHeP0))xe#w6LZ_|V12vCT?dU&&FIh$OWTWQ{EM4MCH%;9VR2$s +zg3W`rDJU;qRgaIOmPK7v&pZuJeukCiVN}2)bbK3|uNgd+Mgmn>tQEB|u=*Lt8(d+s +z20RM93`_uA)jaMTqo-9AupX@c_`$@U_f|Kk6<9*c(6&kA7?$#}bf{z;QGz(m8kiBZ45{e#bNFeYF6ZG& +z*}+#_>2o5VI(l^HoB^n1ajf^H~}SsvYtWWca`6L`^jQM?(P +z4OuKHQFnipDyxTga2)fvVm|zP2?chO*^>X;h@_g`z0<`U5f*<5DtH)Ea1oSV5cuiI +zNO3l^B6rFGm?+kYr4N0}H#)BU(BYQR+33JEyvq*KZNJ482Bhq5(&PC}Bmow^vy({? +zGT!y+{>^b6c_8k_FYb{`B{@oM@ZHh*BHv+@w7p!NW0N3Idql^!ZQHgzJGO1xwr$%x +zwr$(Ct!z?n@*#iXcHKJX=|+!CI9GD>ylOEW6$H2|n%Or@R86+GW4J&1(}{gv9j7@n +zv6hh~Q0QQS>b_Y~x+bSMi+jcSbzliA%dMDZ^Jg`#1i0>B6bAz4(f{XE`0;>Z6 +zHt%4eKdXRO01msq~(dX_;KN$XVK2FII48j2X|d6I)io80&1pFZAB{iK@*NXoC0t^A)m +zw7Y~mLiiY+K9Akc-R~|-ypC&a!f(KKrT|QPPvU2;m_|Fzdf4)5&`wphW+%C69wxD6 +z5iZ0TPq$vogX@WTB&+}o6G$~` +z7Mw?|ZDc`t;YWT4LN?!$hLN#84OO{_^|n}xCLgOy_5MFy91mlmKtzGIUL9<{+p6i;+5 +ziMGW;^gE$e`QzhDHF7@rMa-8DW0q{(gS`DEA!DEflA{Qa#h<;;35MbT`L2_luO|~# +z-{=jBnjpu-n+y^3oyPAeOg=oI<#EkkCDPc4Z6>fOU3tX5P0`M1$tfJfw1{3`I8jH9 +z%dYQA8ox~#?!pVhckL;?)cs%c9vq$wENbm`er|gBDy``fxfcA~5-IUI(_Y2&l7K3! +zMJbnBiODWq9^rhH25$fm#i@xed4>1reXLnDAS +zs+g|)DmSb{^|80m_IlJUjX&pv{COVhMfn>Oz-krP>>pDhqH>Wh5B%Ct?N#*zQUQ#Z +zE>Dj5CJe>YwO#3PhGGmh=Bi5AvhMFuTbTd*SDA|nW`WG0F}(nmSPa|^PXEcHgDluH +z8Hdcx@DpciRo^1oqwG$4p)x1alUCV*7y%MnN|8?VO+vK5X$5@L4rLxk{Ky>^$H>l3 +zsb3VQ4pFg9wS^zn5((Vf!xq~IZrdmxRXh8+Q|qbh{95V_+eUaX(%=8I|G@mxF!=y+ +z8WY=|+c#kS(dm!9qz!rHwqV9O7~A`)W?qR#L8Q2$!O9{+iRPn_h{zIPPqc_*rY@Y% +z*3vEWVat>%c6~6gs21Jk+<2$sOJygZPeagIXw#V;UCrv#u3-LhxLJB5-kUSH=RqJr +z)^yqk;a<3HUmnF!cjS$!bK$u((1J>~Fi +z`{~LWn-%}5h*69;J?ifSiA4uAQP-&Xa>U&G;#!hzHP&U@AB;8)O{7~?uXeC}TjOR5iyvkFHhgKk_-E%Xe>yAr+*IF< +zT(?E*`AisYS91C29xO;L;KpHB+KvXT;;SFKs14u!tb+)j^Z;-n8k1{x4<N3<#rzMP}&+%g`Sv9iLohu6yNrw0o0DQ-1 +zc-_WA0c7%Obtxg@Vp}PMMUA|)&{8L+YOou;EwJ(JoreIq1?00;i7zQ9rkzBJ8#Q}M +zml+*S>bp4CwW|e1M}9Ie1^NJ+(q0#R@DXwyimqr9!g<!lj~Cq$0+1s3*1INt+ZO+pvW=h8H*`Z}ewm(2lMs_u>S7zBECr3Ze<`K? +zdNji^nhGeFmHOpEAp%iboX7a*C8bL{qNfrX8|E~G)9(CB;by@smjB1YV}W2#{<=)+ +z1JhR2x(>VEmG@$zF`2FydZ%P*bTHw_hB;Z0vRG9du4JbBfSLPB0 +z&kT>E0hdBvWR&-~=dXrT{uU>5%65Q!w7gL9%qQWC*rt(`vk*_bOTK3r?&l{VSyQFV +z%y)(g2m9`%b=2z8UjB5w>+d4NerM^Wg$5nEUgp{MnF|A&cf_u3tUBH)Y54m*2PD35 +zyIg?k$g(vs++B|0N(;W2z+`Q+Zx*jj#3RD%|E&b9oVaCoj%+#=-&{a41{2wb|KKT7 +zqnX(-R-|bP{`KSsO0VE72hi5DD+Nh1srlp;T{W>rO(qGl0rK@1D@T}WOuH_00OIhr +zk|p$J=|ODLp0*@s# +zgQ)h0=}9vkqD}B>WqKrMp+#*Rg?+2Oir(ReQ0jDFmeLe!)WVN2@ +zTF%3HwisVo=2-fl2P+r#-2$!*uyBm6@%2}@kDNjJF~OZLt+7;v8$_+nt+dQxDi7jT +z?(#0&UzruEk5CB0YuXkwHqe&}2iI{_HX&^8<4bLmG0Ew`*8A=C*wgB$8pygeHio$P +zY!#Z$SbG01IY(#k$o%t7gNpl2k8K^D7#fX-^jA7#`zSV?Sj;p`V(3S$i +zYF$tFc~G~9Wtm8mgZo6zt;Ujyg|}xjGH?<*3vM4JqTkp2wy`iuFFptANZVqvMsIq^ +zL)?MyWZbhX7hoy+io~7dBJ8T2H88P5`%kAP3s(35NXv(mbp^QUr`hpwl#cGnJfU=0 +z6&H?yj%0IfIuA711jXmfUhq7_#2%K#ToW_Pi* +znu+S!Wc9h$mtRcY@zX3k)#>tiUobBGNx_$vxDw{aTwIdCuLN*6to$$4ubL&)&-?B{t!-LIr=(DJ2N@0;LlV< +zoI%Szzu8PFRu#X;@jaS<#q$l+kj?JkyN31gw;&kUK;`8Jq*BMczyQKFi*GHn>fEA& +zenUgRFnjFXEH*9t;UQcvIt +zFi1)xigTTo!KX^p9WeaZ0@W-xjjvV=|4QyI66W?N8%Ia*9TiEWlKyE4yibYlY;;}* +z)(yg7!~Rfr6@cUn3g;h%;T_Rg=AC?HdnSyfU_IgMu(2YFbou7T+!?3bkn(Kv;A)vf%FQG^v4569FKH{++mo +z30iKxiF`Qp^H{FbH76eW>>qN*_aR`S0~a010#^X;ew!%a{gh1H2ahz$xy~o`@xfHo +zB@B{(*!13`HV&ZD>~7Fm)MDSRh`A4N^w7q9NU;Tp?EC71*>whGe03_t2$tblzyRH1 +z4w)0f3dFa?27R4X4Qz1VbH~hydeIO5jeSJ`qorr3p!Dbv*3=M0m+lP&B3Y$pU?G3A +zk#U0X+)}=1HyQ8bsLxMvk&i8|Ncca;2O~gt)?>h5jRn+z&)Hnhosn>YBPseXyUlTZ +zea@B6eOq~F+}n~ZEXJkav`9U82lP|{{;X>80yce{XJ^4rFR~+XkDgv;6!`pwA<(GaNHlMQ)Y?HS~w8W8@iMFwsCg +z*aBiJcv?C^Sz)cTx`eg@=TJWLmtvx6av7F(?6tMRjbbED=*G-sod{#lE8(}VeSaz6 +zi!V7?;CVNr?gdg}hnvxc8)j<;W%~D`{Ht2Q6wFinUy7~%f)PLo=-UUvr!ju@4c+WE +z^!`-K5QC-NTKOiC;FbJx?7CXSjsqg4`O!1eMHGYYBwTDpq1 +zYEy5uH8Rr|M@v@pjmd2f!C%6ITxSsRcUW1Hj@p@=OZSHwNRo!wR9F@6@8AvjEX_rNyPG!%j57baB +zNo{}ArmWh%3}#|WTdVy@bESIwL9|g261L3Dl!DqZTUNlT1CMD0jx6qy!L4~u9@wYu +zGsKRHmt9t)?Ut(rC*N0nJF|qh$ps?;PXCd1_6DI5QMdFyKEP|Ax@d9n=@cTrOkH>z +z-K_`PA{giE!&P}}@JkV(p$GMGFhZdf9%+i7XpAAJd7)U)%AmB!>=k|`L$ZTIu%tjH +zH4z+smcR~2#|%C#HsN=>G`z+<3XLZqnozG25#IuzeH8Z6Yec7Rg+$I_j_RJ|J(8bn +z=CFJv8FQSd0=QCCD@zjvS%@43rkrPIS-Gx_A>9gy<|D52?`w6?CIr=CtV>BYRd~2S&7uwobF=sY)$* +z%wYU`p}15{C^|&3_f}5-!OB96JPszJCp0PiXK6N=bEDlMS*#jO^G2&^8dCUK)g2Uj +z!xumERlqE@L0rOy3bVZ8tZindMSi#U+~F*SOcTg)D0D!wrIY|>LA1yrH5X-{debC^ +zA^XM6{vIQvgZkZXx0-FGk7fy85CL#OTY}8X?iBKn2AI(HTpmq>LyfmfyRQqKh|zLb +z9T4O1+kJ@_2F=7*IbhM=l6glR{;IY^gKb$^ZTa+k3-tE*+q+=~Uo^Zspau3)94))Z +z<;a46M3Al5NAD8j(OR$0XdQL?7bJ=H9up=4$1}1>IohIBhZ43ilu&#YVuwN98N_LV +z+6s`bQ(P;jPsohqs~p2|gJp!>0U_N;MDQG@0Pl<)@=-rUWV6|V_89lpqqj7DE9EUy +z04&C4ia4JuM-BzBC0+p9)VKLn#3VayR#Nzb#8p28ZV5r29MWiem(hjVgsuL-I%g1# +zGmkK4shS{v)wm^WgxO#*WaTuy#oj3rJpVZ=AFcf{L^HLvjH@6uW5J{LOixbLV7;AYaGSdhOh%g;E +zQ_8=h{KmaXWBcp}ntQGf`)=|=4S@QKH2f1HbpQ)aop?Cr3t$2GM`}+tO|ODy@|H*; +z?P{L`P>Ex*s@VLHN;R$<_ho=n*Vg-<&c6F9%uC0qBQm!8ZmL6ygkB{{pjGGPBz2); +z3Fc?zqsv5-6%eZckO+Qn+@#uR +z6zbl+8Y7Vb+};o}_0BTPL1)?cQ|an3GgPAWJt3QbV3tGG#IVCPM<=Ig@4f(5biE)y +zD|(1m;BxWQ6#9`r_%8vc&(8r8SJQU>J#*0NxEa`2@d$V6&;*YMzB{xos&2o!9-rv} +zulTxm^RlisTW5|~yRiNs^jub%C4C{l7-I!`ZVhR@B^mo-d}bklp+Z{fS=?arZ8*b6sxonQ^2ppRjvbNpB$#&Trrz%cKWAq+~3(<_;ixi93trBiVu|sWh +zdY)v~A4)E@iowjmaU^E*nS$2apvgow41j%U{P@ +z1S34OHanig_zg46ib1MrcVxd%C!DB;Bpy!%F#Q?>wmZ?4vT|*)0CSvtvK}bIm~%j2 +zjxfd+Ml?Qz#C12t_)<`(VVDb}HinoZXq~qj&~m{WV!o_9&hx!h +z*0@~7*%KrWPCGODex_OEEqq<4oVpf1ywIgLg0E^m5T1|Lfk6ET;o$NLaJd{c8H?N6 +zwM%y+uk^bcTQfX>WZi`;yOEH4E)(>f*yEXas8fa(ak;t-m_}V0r`P+{E&jq}o70p_ +zI3PD@t7CTS3XBa1o`rUV`~QCR`G9#2|H0hW?p8#}=KlXM_k{|nT~r>Mym(-WT@%$K +zA>O$5+@pIog2*-drDzc+*qMx)%I}6IYzUJ0?A9E0lQHQdG~({{7HnSTnUM8+JVSco +zb2c?#NB21t+4hXC;kv3@Elo{JJBL!}4lW6;|3BO^$O7K@%&mpTw;cccQPo%+!Q1{V +z$A3~9fVI+!;id=CeL~s^Yglhd3?t|@EGO_#h($tUVALWu@s1OS+2UWdxl+C19xq9Y +z77hB;2JCKKQ%)~F+m=BMAhV0ffu22sGQHFz;NfYv>Ds=MCozv^0(z!j|4+gEPIWY% +z1c%)Qg<{$xgWR*P*`W{oF@ynjfkv+Hdu?9?U{2s-x(^JyOK0VjfCi=m{N|8Bux&GC +z)fkFc5qi!w@Nods8Eh4B@vgw7K@`=&PUe%cMp`g55~jX`F|Arfv-J@qoECqJHo +z9(q_YK}g|kyJy!36k1O_Ay=+M1hzvAd=+++sX;)nI0~}Upl`Xi?LfI+a}4i2Cb)nE +z!(QfhFuKRXT~~WJq<=gW>3jjY6yk5>2$Us2qi#S_f2p(IPg6CL|1@-93zZ; +zz{+Tlcs>-!=;M}nwR8epwG{_31^oaMtKk$14ir}LE%ic>OplO6~UTjh{cQz5Xp@>;u`E4J<}+2iekrA0iYawM2kWwEI?fu +zaw?g%Rs|9FhM(pfCe#lxqx^NM+1ED#q$;Hn%Dq>nX-75FhC_w>M%|bk=U0RGB{s59 +z9LcE^d0i6oJx$qLy0C!LET5HaoB(OGbubohkO_V=U?3i?A+CRcu!}p=ldp$81IA`1f2jTk +z_Nd4TPzw-%tSvcb>T%>3wax(C9z5Lyk|ri3JM)VO8=SpX^h +zcD!VYF^_7#EY$@;&fink4}-V!&#BZL)k4PKI3za3e$+E*soB#H9Es^|=8c%IDqv}> +zN-hlg(ZP#XRJ2Y!HQMDR2MD|jDL7LZx@8IpOAHoYN-DCK_+!d+gSl;8hL;JDd_tfU +zvcAMtWE#}wtyOsno^X@dl>I0>rLYG3Q0~J{aX^YBc^o;P=3nTYs~iI +z1=q}a7gm)OV;BbMasRo^)lM_Hu()Hbhl%FsdzTbE#!Osb~Blzx2orXjdJ?oYNeP#fA+dcL>D%XQP-hKX(GS1-!*y +zU$q(ZRVm;vL0_#xrFV^DT=OvlpXnei3M9{jQGY2mlKYU?yp?{~&{qjzk9G$!eMP8+ +z*X#21_{Mj)d;McvP;pw-tp7rSBZqp!Dpt- +z#(01;`A@A6X$G>^YlX;>pJ=hI$&tR5{MCZsqF7tD$83)10I8!L3eI$I+x)#|viWVt +zpfi1(o0PCu)tgr02TA`ml!d^PG1k&5BFDjIBwLqp3f1#K$Zx*FT8gg~lf5PaWr6Og +zr_MJ>^JiRW+XNAtN=H#0eLqE}r)zt?+Zs&`RiucRa5TLO1m_9&T0{_n-U2lB53Z#8 +zc6tChbeBbF5R&sT)^iFDk^3ZMTkty?BY46Kf#z?7V338aTmAdy2h&BoNmlTRqS{9H +z4SN$t*ucv3kb123BD4&JRJ2|&>&u*3ijF7O?E4YdR!8qglPgyJ!gW4TB_Y-X+l(iP +zpNcm7H<4f?8n#Ddy*-N)_T7MPko9UUhar0iOr-%C#Q!Oxk1B>vCIXwgBvmh{&(dEC +zBo1pY+=Y>_5Ge)JhXxRQ&WBz!tuAG>F&^#bVr(i%8$d4su1!M<9=cvj`?Ngi#b2W& +zL&k}-HbIt-Hd)K%4bH4oF({`Owj7vq;~UAYJYY?{hfzUTcNL<(IEEQD@4qk6ya4l@ +z{)c~$NM*ljzn5=hQ}%)Iy74ZwyZ~WKz%`a@q5YUi&wMP7EcgJk=pf!#4q4U1lHSdS +zGXgR}Y(3&D#|`<^`$@TK6&gE9_2H%0K22V2SUkq}1EHlU$Y%!A$hnPC2A9dJDfA3f +z_dioWx5TTP +zj_;rql%n7iqgj1x)$JW+<#D;5h*SbTykXeM +zCB}O#`Qs>Zstx`Or8(i;X6ue%w2g!8Y67)?AA~GLjOJ|w5qdqC;o;(`MU+dfH`KO_ +z>3H}grqD%-jZV6JbYPDxpW;=7-^ei!#|4j;UJhYXKk4a&O1Eq$K+*CkKaUz~^)WvX +z(JZ9g0kT0ry^76CB8<(^$27lNF$~Nh#X|U-PnU}*$r>^A0xX9CCu}9V!(PRs0zVYo +zsP~+rm-l`2jqS==(B?OakHKHtI!59_7C>x88dk}`q;Hz|0hR2u0W-D+1@u$D!HM4S +zft(5{K!b!qfUs!vD)nH0D2{!f#X}28I9nTi2?V==2Wc_}VtU^ge#-z9V3nK}(Tk5> +zrHFngNYh6Ofz<(ZW`m_vPr&TtpdUbh83VHoEWpq^2c|vnv4ZD;ys?Cna>X(K +zGx(-&$qE|H2zdt;K79mEi`d8)+T9loJ(fdL_zp$qecPf%NLlxLVci-lkUG-{$jH!G~)x00JHJ_x=H11Dt9=0)&NXzd;haQVMs!=v2B~`@(N+t +zR5x~tPzOIFsL4_&+A2hG>F-w3F9C$uNC3NqnVG;R1(qJfgnBuqav3 +zh`6STbD1dJhu*KISoJa%#*cfHaUyHsVPL+P@nG>@;wVO24KGm*s6UdS{weC?^rO|I&oZ!8U~%9B(lwwR%_ZD^cS+<2%w>Fw{>O)@T97r +zE#f2g=dGuJel3kd)>1mHiW9>PwL8AJ;29EsF6LkuGcc~KZxHt1a@YkU@!C{+ +z41gBCa^coNN0y0Fr6g-`3+356%p}3+@|1pn$W0zK6hYbJ=CS*CR6=#NH6U>~n{AB{ +z9oAi#l_!MZI?!VYwRITs|;s!ZCw{_n1Jm9T~5q?NY9Dr(fD +zs{pK3Fq4DLQl+`LiQ0D#{>UWDMTL`}Wk?2Myx*am#A_U%8_#oL@-T?CdMlw!J#4rj +zD}YaMGm&Z5)PHz1fW!hhayrV6w8-# +zpL_z`5zK$vdna#Ee)s&vWpp3*$4<6#h)qL=j5a~72t~9ogXZ#-_5F^}u-_4)2uro( +zUVcgRL#O$zlD1xwJ@rXEgPC#MPYAFPhJC^4{L=H+aU!tf`om{A7*gX;0%(LEV<=TRcz#tB+IX~0w$lrU6Z*k{}%Trbv +zc0iq~%B;HR-DN2{vUJ|MhTm{k(Q6xQEni3 +z_SU!I0=Iq?L(i2j!-Nr{u6`YoVjgSP2yUFuB~=ng(aJ&p!O21}6QOw=Cq2y9wuXf- +z2Rmxx^^8M%V%I`FRCZIRo9P>_b{#{3k!k~gSCQ2e8<#2 +z_6m9;JpjO>gFc^EE=J9R$>(gr5U>$d50n3n!ZuJ5(aCb0%* +z#-aClYUSK?*vrdb;m96&|I>Pvk%wMz0~LYUIBOS7oZ~hc0NwSv%q!jyAOvWFU|PmW +z6KdjA9P;=H!*voc=P#LLtL>bn=AqrRQ@G=n5;D>Q`t>C^-M$ofv>vwhRw1Ku7uw@} +z^yI6N9?$KEU!?Gb2Fou>{-#y-LTX6vu_ir2;R94m*Ph;*BGdYZC`NTaY4HPs-oyp8 +z1{UB8bMsfzl#>R~!=zxNT}2764#O^XirqKoFm)W}YLlN?-w)Qbi?>a*N!P4f;_G%H +z3kz&d&cz4|w0DAZYO`Ktpn*0PclBqwHA +z$R89sk<&ygSyu@6N5n6*&}nAa?I_?Fr%uyb8K!?VY*=@=kn4HT0996nLt!amwMqXJ +zR^jj3B<(=MWx18CI!gfchc}q8#d?{nVWk|dXKnRD)vt76Mv*7DGI-1)w9!>#4?5t-8RVmyQWE;k9OFM!b5~%fnTYdm)S^5xOhXdk@do$6j_q>Gu%n&1_ +zvS^^Lxx`%{pnDS-ySL1l+u}jUwX$Zny)Do7QrZIN!N8YnRWat|NALUl64IX2MRNLz +zS}0X}nBE3KW=LaSS^${q1J03iN#swgqFt)&*<*QdgPG}nD%1C+lP&#QkhdngavLbM +zuAARR!C)Wzy#|rMbustoLfNzy`5-0P=qKtZ-nSgxqAz0~G=q|@SZNk-z= +zn&U#cN!{*&h8Kyp&i!3nh*f!s^GJd)h+w7=Cz>d`7dNwN&cP#{$kp-CGQFbfbNEnZ +z821wv5@h*IvL9#rjwy(hx052XJUn|;jS`h{%hXJ=#O$gr;AXkVu=#O?%7!mHuwJzw +zNE?2U9b=e`2s%MrS^KaRGWwii}Oy +zr-@S$v|Ba*$}Gwbs^O+^TMZURQ04Wkl8M&`9$#f#xP*3IvmkibeL~G61ZswF%u=U=q7-SYdA3IIw+@7 +z61?Krz@STHoL7O89@PD*Av|8_uM91tK0NV-^mw>;J%A_jUB5a&MX){A++ftdDfq_r +z&~u7w9KY&3o0ka|^%|JuL#9S+LVz~PFD7;zXfu;qBb*p$zsy;z8D5OIODaUWrtie! +zS>UUWmy?6+CIH2$);-uARnBL{q1{JwLg!|7x* +ztiAdo^NmRaM}z?QFf1hH&E|r+?H!5FYNY0#isc;IFg9&?cwO+xAPp}@xI?A7No!|v +z5vZYzR`I3LSm9tRNqHNZQN+=T>twmaFIjb_1Jc#12ye`gdaC*BXV9_a^iMb6Grhl4 +z+n*IBacu0Z3=zFt{7n!LNHE;j4g}IihOrGGfu~{aWh<#KrxCx-HkURwy8o^>XygAx +zHK1kCZ6)1xuf{OD->_~cU{|lwVdt1R+wQEp7BnQrYu0w>l=>Vr7d +zBp);{TQz5;U*o)^4in@q+MU~GvSd88%zb1y5>SFXma?ZeAVYnfdBQmIu&sMic-v<6 +zY0!J2%G99-p5_R%XoPuk4TPw(4Faf}c-IY-ZJCzR)uRmLH;Ea&kH{Eg^&z1>^D=Kg +z$y;E^!V7F|CJ5WIs?&PT74jCQM!u2pi}6(epVGVosv@2O%wqT7oXd@OP~&1`0mya+ +z_yI&VTUbjp7gHC|vZgjIetzsaQGk#XY`Q8jNp$YVbqr_c2dXq5S=YWJKTu{@_)AWlN?-YZ^@^LoQlCcfMz>rW5Qu?E=a546a9a$q*qqq(Sa4;zaE% +z5Wu+x6v?j3J}E_f9E;&kmU7*4+7s`lxwfb=aIz$>PFwa?bj0^3eYWOmohqMrPfa?L +zH4fG@;Sa(h7Fi$-?ZlKTYtsuEg;Jl}Odi58g-Jo4mHJC8E>xUD25Gtc_{lTjiiF#bY`~xcO*5ywx +z%HWOj1f$AS(|&GF5CIk+G{T7}#PW9pSDLbqqWSqjA0zkf!a#^FoaJ3Uaxqu(mxIWw +ztf*RH2X|e22Z>v+K+%s<7s6mc5^3cp*o89*2uS1D&!*U7>(=UJxc<(ma7JE+N&ihI +zV@u`@x9~0QR~VF>Ir=I$pX#4G4D-v_4y?D1-aYR-P31%%f}|=sBoSNZQ)hk!=aYWTKMBh_~m2 +z+g@Nu-2_0{a$vFnuJ&x6Nruksc~K?kmf_KMn8kAMABcp7bNIwfCXQ;bU60?IHayzh +z0!R1Uw1ez1sT06XUnu~_+U~;e-U2)vVD}GQHk(rT{u~(Xng&l*zB$2-8L<_j9)NPD26fV25v;ocKxtn+<4tmf)%8_ +zHxOfonKIdeKH4a{G-%B_x6Y*NR47J9*@*9Z#W2XDCvr3bdA=Zvi*)&~dB7wKluhP6 +z<5G>E;BoTmq=)3d`80?$>*U3TMHO9S#_-XoC@!MR8CnL4sJLqw9Q+l2^EQ^j|8B0C +zqACVQ(`KPG2WtV;;Im?1(SQM~H6ZOtgaQ4^QYpxW@--Ok4$M1gXAM3ZEic^H%5fNS24C<0?$Z~h>( +zHw6wbe{ouSuE+bbNXo$0fetGlKlLL>rmgXKZ4PnIk?j@Jzx35KVQICeY`I$ak039DbWeu0Gh6z)=g_}hyD?ZOiSfJj +z*7Li<{?kBks{o#_h!kM`h}hp)X#lZ1GRL5LPQ*fZ0DRd$XA}&M`wylZz1ta@`A920 +zJsIFv@OjXjTJN8L9n|4G)ca`kQB5?Wu6EmTWlC3kKKBlOpScq)9oy11=AkC8gx(}e?p8u9ke@{Z~|#-V}-P^!j3_G;eg@7 +z-!72x;l +zMOANe!yrAoaGZeo^g@3(eT&v7zw@ILg8$QQ%WCN>+%tj~;EeZ_Eo|fMA^BB4K7@Fu +zWsT$sRT7N_Pud+j`dXHMF39tZ{9wXzEIbo6#b`BPH+VgTe2{*7>OMyt1~!G~GCy2B +zWRSA$_jqp7!$8!7?F6J>8m_z|Mldji3c{o=AXp +zqW6%#RrmlF=na>k%xB_=P__-f{Ix4nmJ?E8*R#M%h8IrCS +zRinpm!Qu@zsAWSRoC9TnsvY2dB3F8X5AQ8Tl^9qtk-8GLhtFscjVCaTc+Z5deRAsR +zPy_}r&Zh#J)9)!L4o3M;ey)5>){R4n*uf7hiUrj=weKqEs#0bV7y+D%w~~QM1X0O)5EAL@MwUh7N>yUhmrk{3+`)uY@Z2Um)(%bzaY`xu +zBZC^e7JK}h+PSj=Z_BI6gy|vupRj}52U6zo-F_4mND#HBp~1N`N9Q&~s{fPkR)D(6 +z*HKIrRo&UJ?l7sJ7$7$0PJUp{Ec +zrK+t8Ywlm-M*!wE|A$#WHNI(URRaW%y9jxof0tLQN7Deqm@F4UdH`#xae^%7Xei9c +zO9tMzI%aKYPwn57DhBkQtV+>~|D>a*5{)d!@7LmgrA>U{=`ll@sAm82#tZ5vE)Vm~ +zlS7cLqn@l^`EO&_8xT>G*KcNZ<@u;Ym54rHK9iiwO;~^yGww&rMF~Qb|(IVB9F%~(32|BwOpf?jnnNTVq32TuzK +z(oxo3%a;2reEqQei;~oF2$#|Z4TNwH0>6ld +z(NYyhkbN82Gm4b}6^s>Ol2iN(2uagNQ5|)t4{Wm|QBHw76&XtaKy4E=TL?Q!i=FJ1 +zku`+=t?kJOFOI!~M0|hEcmOUXX5J_@S2QnqCm1~eugRNLPoW6NntbX_l4UF21k?`7 +zUhDJm)BF<%t8%MWF0wtjc-|@(n@l70dzUb{o_qnu4M8tJlC)g6xRVev`Zp5>_i<9} +zD*JbB$;cTl%po_7SNz$>I>?&5^J8`Z^uyYgT(L!71C4^I9}VjTSKpbDY3&+d1M^75 +zByWRpxbd#kY1F{V`3Pkh{Z;?395#3h0>;>pUHa85a_;>TwYhsY(hD{zU3t+8kC3vB +zN*iCXX71lZx@}MI^i3@0guj +z`^4_JV-@s^#7}7Wgq-J|fZUJA;5Bp1K%{Tj?uLypRwL!>^dc`W@j0j^Tx)>~#XK^H +z2svcr^y!^P-wCBTK-M$u){O}nO}!q(Mf(LSpZNjmsgiEQ2cxz)=n(Q#Y@iVt20hYk +z6T(Miw;Ir9#XwO=ieZ}&OoecPhO&j{QH0AFTQpwIn{!5BEX>x{}z&lKceOhIs1 +zecEEcN`VX)5Z7R$$vNo>V$)0Nt#T7wFs82K;KMsMLCkxHZBpM4lEFOhVfY?-%n)0} +zYM4(*Ip6fDcQM^1%Kl6}?jwf2=Rf7EqNephl@9c@I)w+va9S7VM#Tk{GXJ*FRDMVr +z@Ngql&~xtHrhHJx0YX3|&S=FBpMMuE48?!D_og{%fBtybG= +zy1B% +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 +z97}r67cz!Z)hS#_`Hc|KMPK6_?(| +zMf#E3G#SSbo?>kXoU3jL21Rhw2zvB?nTbO)${U?gtW&q&G;FT9K@(vb?06kag_&=l +z;yk!h4*&HW{Dj>pG7T}(+>5q!K~bHvL*NcH^F1zTVi8;Q8S4ua?ZsxpOD5?Waa1$w +z%;1DGj9R$?-=Mb;z7BEYNco#J5J{u1uP9w@#}si~Jraro%*tSiN^5eb8{$ZxOR?Bm;9Y +zC?*14+8+D`SrgXE4S*D(OC2WbgnyZ~Ir2~$$f^>#@Ol>AS#(z8umAuD`9YuBMHMV7 +z{{RE6Szqv=$7D#>077##{k|-@cC70bFKkNU&}ZQhf`qJI&KKST7t0THgh=&Rn|{ +zeptAR{6A+kx}H8=@~SXRpff8wbsE#`F&sGp0?^En`;*feL#|v(zhAdR={J+tRSoac +zYGPh>;c%=W*52ZbH`XGBGxR|Q=TH;lBE(;RD>{ZNjV#0!XQvg9``K3fI(`Oqk{IHo +z-lMO=zzwWp`ptXPF&eN#~})fqrm&<3g*Y@n&b +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 +zKt7!>lZ=2wx?P}J+LParE2_vu +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 +zs^*!SfgxNh8PD8Es+4~i!@MR +zeTo328jvWfUN@1N3R`c4I=iy59^f>QvM5l&!zKxrx=uXHj_#~I#t<~Eww!62aL6C0 +z(huAsRSDs&hsavwAw^m_d-qN>!Jh17R2n>>db6K0;EI`0+8YKYeM=y~=xfqZOT=Suxe(l_GXZrRH8UG#8T;I2tm_x!dO`n`6%|4Qqb452%P})^F>bm(0GZncR +zZnon!f-&wy?4IZ$^g_WdW{omz$Kv?!&?$rkM6hV=segz(eZ@#a4?D>S&Rwc!?aU`i +zEHtYn#xiZpCbt>~qMmfRmbKBVwjO}BkZA}37)WN_@&tjlW_;FZmrudH|U5`EfdG_RxSRs1^sMKH2 +zV>!R`B?-(8M*MQ@wF(6%$*$#9z}V*)@S29n7p(y&0eTMfHE&=bOE3tmHS~_}Z}0sz +zeD$S^VGJ%uK@e8=nZsPrw27=5U_$ENFDjMFlBzX}L!H|8ZY<0`nR5#iS+x47%plI$ +zPiVo>_dQSH)@O4dC)S~)jN)+K;FEU^UEMgY7QWUdSlwL_&F4;cR>9~E+>;~b)blZ4 +z2?nMz`!ZS50*$G5X|-ku(brl`4bR==9F@7&z41e5q`W3o$L5n +z1>q0y+Yevc=z%FJmC(D(*J!Jttk4Gq&{u0vab0j>h%~{>>u@|yq$|3ZeUqOSAK0#4 +zS}#jUSa*eOcjvCm1!bT=T#b<5vGi?(lvU&@!Zv_tgMWTA2$u?sZiIhVuQn!ngbBDN +z>4!iIR`X3H6HbH>0U{Pqrw)6)1T@2)Rq={aqBXY|$f@P!El@YIwGusnW-rDPZ=M`% +zQ|8C4A0xW_zTf*1P%`$JwzIt|6!No1gmUy79z+hD4E(G?%hAa&k8J?(4Sn67fq|u{ +z1gMaQ)T~5J&M8>z9hleIk2XHlz;oqrqxJs-Fzy&6l1LSKp4D#8EiUK`8r;5N)<2x4=$i9 +zfd%_K!ZQk4wUAt^CdOFYK{dJnLkH{v#=Rb7G|0d5TOMSUC+k^aDQ)r1h_O9%eWb;x +zTSg?OpuwQh!hIj4zp@Bd*5OH0T{3p-vQJ+|IS%De-)RI5Hk{Coy +z>w3qk7o|ki_&UGmkOOki8w8@hI`Mf +zw{_h&;ur*KV +z+J$JvOAo{l4)(cW@;#`0iox-VdV;ntshv>*0Z~sBnrs#o6po0?BE|~faHrjBmZyh3 +z%e8$3q?XENaWP*&T@|Fm=pRrQEdU?Ibn^KlL~hTVE#xtE4nmjhTYNOXx!+w+r2|j; +z&1E1xwJ7vQIbC`|?%WCNH2sZhnjch=RMr1JZeLrx7(L-hgU6-`Mt86JU43>+sCLuaPE1TenF^-LFXAI|; +zZc-XNtn=~IB;ZFq9oC3ve)8g-AvVB)&s-jE*R|Sr&i5Sr*J+)Wb~y9(s>y`F226S07n8s^5>z4>K7R1XR8jE`iL5U`fwtI$7Lfk +zmlNa98jZDaTN2Ya7_U_Y2*S=`)8=cnSOe=Aii_!eGK~B>D +zJ-n1!UGeLl7vAPatRNp1+&a!{n|fO`|EGB;lT3T^;*7>N4|<+?;5;FsG#qgbRc#tN +ztq-;q*m)c=3V{Fs2lzpr9z_)_EB^okty${a5gR8PSOE#ok=+IV`*s3YJv#5MQ28jP +zdaTNPCWKcfp>R8c6|pqtvHfSslJ4NQ4{60i13Q{bx9=_y71+vL*t&rE>E5a8cfYvx +z7ixhW!N~uDU#CB!oG8%I)ZYEi%{}El9G_1V7Fo;&>CKzGk+7p$l=@F@@j{MC;X#( +z*!i)Z93V31lGg;zp}k=03{j}@zRq1AkV}htsCE}V4=#Zhc+;8_vcc29k~sSzoUZFW +zPS(Fw*WfrMvZITX(sUFyL`1pnE&0ryunmq9e^Q32kRNbN28q +z8of7)7pnR3cPfyZ>gWV*cb|$teOv6f1VD9JDiV3omA_4gnhRJB7-^^(8D{M<6( +zHNV8_mGgCLdk47L@#;6vHrTjY-9w%`eRYSvEFYeusA`Z0h08wu5X(tRkBCg{vhnv@ +zOAB?pD;AOoqUB95n<#gWGIE%SAOGmFX%G1Bhwla1js;qznPPKtl-a4Ur1Sqm?l{%S +zG_30NCyw5bB2qlcJcS${K6c!Y3F#XOuT)2RL?*&} +zs>&;TFElDu3UIDg)ZUdpcBsVV2*oJD1XB5^%p!G8zsuZJ)-f*2UU2dmljr{nShnfN +zp_g27bJTP*K(aNs5;98+=jWe7J0^m$iPRDOO+LG2#hlPExz&eu=%-jtBu37T8$SFEM`1m@ +zHW~#FdcHD0MALV)vj`(-I0=ZM2=cvP_e>_SyJ#a=eY{v0?_EIaVTB|kTZ +z8@n=}3|bJTFEud0AAGz)LUf9U78(@mJ(C@DhQg8f9=SvJ3v`I+A}TaBB*`N}0%fmm +z1vRfkeX*e8<`+x+P|+DqwJAj|l}dVhHo_VjI^vJ#5&#*Pdf~zD<0iGm)3FODAm2UU +z_X?*vlQRl3qbaTOokr?ks>^_dGqYjv5j4=u9FmMt6>h!5+ihuWixcS@O2c2~SDlN# +z^0w;Q8|GIU7nL->C<8qZk}ma~R>IiXBFrR=rQ8J$qU8jqw|^o*(}BS$lCNocg$UK~ +z9cNm|v$q+vq5=qGi<)n6&OPrmGHTJ*-5PEgI@hJFiy3W9oV0R^;W1BS#K6rr%W!@= +zCwI*bU%NG0fwEC?{p{&zp&NM-E8i~}(SAUxB}!X1Y!UK^@IH#vI97FKsfBas_B8dL +zcPW0!UUGnbiadGmMl2KcfVGE0F;V=;vUf5Gj@tLxC1S>o{T9QWm%^;?${-1JPC|WA +zXpE)ZmTWrL4%LIYu)-t8zHqsUK+5c-6k77~FjU +z-9OHh`@U?ZI$k!4S9(4q*;)hk17bh^Aqp{^L+GuC06>Yk^QFX+b_w21q8{)^tr)C6 +zd@S?Q@yz>tcg_#HS$t5b_m3eIFocK0#`jsKA+`hL5!?BdHY*neNOlg?j2WzeR<01d +z`(wTWf;qSV!`_9Cwr65P37FQfxMVg+ +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 +zFj~-E$F^a~0KLct>?{C=qVA5}k&8p0q* +z!_yR8wb~mz-cSp&>#u+ZxLM?UlTkJBCUy8!$wb?g?&th-C?Rg>R)+({aF~vuJeM(B +zpDrx)qpJ|WK^=C%W!9e&LmNQ6rzPcB`-|~gyfi$Wa@-aP`Ma)wj&enOK$^)00sTi) +zXTs&wZ}2kOH1loqQ-|4sctXa26M_7()D-6r^w6P3C=vna+jS +zVzFD#VzQ3&HMCmeCSTwm&jlX#Z`?@k1DwzQW$$Aq-Kg?W*Y$U{t +zxYj4ydSEMD&KaD2)fu|D)J(|{5-9;+^r*CE2YC`E6|j-6sQy!4aCjo3qJzh?cb&>P +zo+F*0jj#7x7J{XrOLy?nbZYK;r?ep@h4?Bz2otn?@d&|zn<3kBZoS95t|wpJe^)(Q +z)t1<C!CKa +zGkOL+%pch#d*5OBYe-dUYvYxxs#+G)l?c00Xx2Xu3rTknPBuk2DNR|Phb{1y!Zft!1`msK8%8K&2$kj{M{P0O0h2_jmF(}Q!U +z)z4ubjxJfU6`c*7hRZWU=T%v@{xKt?$~4UJ-*b8x#r|54^9#a_e8>rDf}p^11$7EJ +zIJ8-Q75U}lWS&}L(glHcc+-Rbpv7plmUDg4J^56}Ks-vl3S`66tt{pUse;`Fq56P_ +z=1Uh$krzYAK;?0aG5!bSVZlt2|Hp{O48+Is7wZZDy2AOflW+mo2kpT{<1rQUv2QeV +z{#<@CR5=>33`$hhtSFmLNoQlzl+L+7S}rO>Q#E1X()blp8Y@Ij(acVMZGIScQ>Z(L +z_2ezqP+G7!fCxHRI#Cl5+uTo0V6~Cwvb9(1SviX%?VBTKo3auAFpV?S`h>m@8;dZ{ +z!K~b~_4R8i#1&kVL~os4PiIFXKNEf8-6Xm*lmF8}GIXUs=sEt*(ksNpRu*@->j0I) +zM?GIR?u-98A~WO&4w +zEh1e%lX>fM-y0@n=|-$)Cfm_&dzh6UQ&w3<@khM+6k3_k(|Q8z)Y*T04pLn~1MlyW +z8A!j&QXtiVDK_JpBb|-jh!uwRggG1Y)~Qrh@c0O|S*sK2hh_T*{B`XJD#mfaKD%~! +zkoXt25MXel9#>c4vyE2I;V@D&G=VI@SGfF+joT`2*g+xvh>C6UJ%xLNCoR28EHvoF +zZ9N~|AbA>3nng9)CA3gGM0R^Z37M}8*G@XAgql+$*f6vZy<~4tS*)mR%xbm_KuF1U +zjm!gk$?ae-v=d`Sb)H4Db~Z$~IT&*3ECS@1!Hm$G%vEHBNAx-2)Cfwyze0F}jt`cI +z6`S58kYz}0+GqfE;VbG(&^=X?^;0 +zv>Cp2{~Jboah4v{yNY$6)_mjsSr4*gH&Ya@2w4+HRPBL2Ghl&^%$0Efg~dzob$!|)*?HDW9G4akDzhdo@uj&GYt!8AT*(9joy$P# +z3IH{o>WR$5OpmRBP6B-q??U`LT{rB^fg4(mrtVUSjEL74=33lEfbSPqz|E+Leh=7e +zkpEGZIBX*mPqAmIMBJ2i*9}FfQy->w>+-LdE-ScfNv{VAEA539E6L@~=zW{_fQW1k +z@a*3S3slyq06)cs#jm3P)Clt#Ou=5P`zVXTJjL&|(j#GU4tVrNJ_Bd);mFT9kA<6w +zoQxJPQB7`_QQB)C-I28uEl;txVy2`<9ld;A;JIK_$3E|GRBhUx(h6*H?#Ee2oC}@S +zdtZ3e)l^NGbeLJ3&(cNimh^ujtpWuh8)nNfZJxBnd%m@kBWZ+E#qQ5z%0KFa5OqCN +z<*82#ZwA!jL-IvBGxBUbV2W+1@CX}OAy*Ss=|iEf)q^^`RC$L82L${2W35H}fC868 +zo76Xk{q@ukti0rzs{5~AH3O0M;RA5n*h4H63B7q>$M8~kdQ@T-b9?&QpI>$F+8It? +zd*^IGTukB#@6_*LB`0%iK-gZehV+$1PW!fgJV$|RjtpD8R3$1AU;(0BI_ELJpA%2H +z)vu^ZqgzLG+nN)pI-EJBQFu38u>QQpp1Jp(z`lD0-B)?+yYD5dWy|YWny}(5a0Fl% +zqGoNhk#29q@GKBwO=N((0Cm!cd)+8s^w9(}(l)`4hax2u{Z8z8D4x>f#GUnJihch`y61%uwf8g +zO#bRp0lOD~E%&9NfBsLJX`1p+hub%>S+-UJ%N5{wa-zZqSxYvrgmh6vG+ITqNn7#u +zoTlqW8Rg8#LZhSOEgJfA+fu_R?q*^BV4BWhr5IF-=Q3Jz;$7R(Wta$`-lvNQ2k`6R*m6w +z8v`FVk@aINrFCWtTp?M~EvgIbNHsvl;qYjN%V+vPtzs33s&cHw=I`3QkbBkC_gK4X +zM0l%dY}C*~O5uSFa9ZgHy6Q(A_ZnwDPY}J+Q$r-&G9{3l4`=Y$&b{~^0T75;)k#=1 +z@AnV_C@bVoLi3ujju%YIOv6}Rk4~MMIjz2Gh0=~Vr4wry=Z^nfJ&vljF?4CaC=c=> +z(?4aaUce_MOgH51z4yfDsVv?zn-KwlNeB($%AtY6) +zR;L2=bh_YUqvr-b23tzgE$12uqCTCVaBY)Alh8PyG$xuwy_VCko}LQn>-3BiZY_t% +zyg+|}i!#@N%8CJuku)8^0>Kn(P4_w_g)oYy6g$j$hqBSuf}$>awYWFPu9^w}>T4ao +z1cepNyKM^IFq;|~agJF&Z+Dh>2uwksw}gjUa{YHH>ztE2@2yu=Xru^I>q@*{ITu_$ +z*vjIR{g|Lf<1O2RM_;|H^1&6I&|l*B1`l{}~ +z0}vn8+TvnpBb*Sq^>W|gN`s<38lG-GCncliv{oMad#$2&&`is5I4rfn;$dlE~v8?$m4?(?|0|V$jhfE +zKN2AqpvzT%Hw6n&EAkyq7$toV=VoxCY-T+JUTCoBscdN^Gk+r4J5!1IPc!S@CSNWK +zgEFF-R*hu2eRFiDIs@l(x?{<$=6$mTso(n>RlgwBZE|HsNxa2+!ux4c^TKpA3|Rx_ +zKy{kt=uRmh$Q)gy3% +zE=%bWG?a^#7_5`RDQj(+bqgTfOfw>U>&6w5#)LyX@$3ob`KS4O;gA9owE +zs{6VODA*P=rY^4{J +zkj=&7j(D44=x}U+Na^LE;KbW)m57ovPg5gZHb>*Iywc!d=pt9I<$7P`fqD}a^jh>8 +z@xtzZxjV*Sr=d=)wNRFJiK81Uwx&Z(Cu~Bs!==INQ-E%q9>~EH+QI||2S5Z! +zWX30nUn)w>`YhT}M+r`a2?L;Ud`2T|136nYG&Q +z>_v`NoG3C#&oTg%+jOWNVFp^w<5c`(<6VBb~do4l<5 +zK<$u$9`(94Y +zL|0$$h810y*+jI_*%Z*4_QPXrla__QqU{3B!#^f_CHjNtklJJl%W4*<4O6wxaMq`Y +z5(6xqtNo|vp&^H()sa3m7E3=6qD8*j{~j%#5PGO9aRQC?VaWWDBGXEbG5$LLRaAOX +zK>*)R_kzUZ)Iig9xv>lw2&TWdoh+@{F`4D=l%|&Ee@HwyA+!%3=nc> +z*Z1siiGF*~Sf*}A;Z7H8*QD4BYsRT^gtSBPzoIyF;@YYa +zb|ntMaYZRaQ%I=&Zyb-|iAAq;jxlPSH!mYJ_<^i9J8WCLv9et1v}vNSbN4lsz4^`P +zL!;>QYgUgv83U`F?o~kyxWFwl`*F0p|>W-+M~DN!c7dG!`;`)?+p72c;f +z)h~+KoLUvuea_Rulk)z@6e0=$##^x^&-6-gb84Ah+>|w>&-AzfH%GGvEXqI7afaJr +zGwVUH*8yKYjpk9-tB-rn*-Pkmw6m+dc+`wN1Ny1T;P +zK`$il29L{H(z)fxGI^m3(8S)taj2V}u!mPNE+UIN2j|>^mVa$29xi%E{)!?Ykx*{- +zSdb@zPH)NoYH+j>thY1w@2}oHb7P>|` +zJcOK_<*Se5<;f(dCpvir3hKm(9uwbbx`HQ+&%}=Lwcu~#<5gD0aF@eSTSpup$*WB) +ztuI7q%Pmyibo1PY@O?A;_(s`O1zITrGf5^19U`d}=o3pA0JE;}_}H~`4=s@^#sR4# +z_yw>=N9bMU)rMUbxkfDOBCRHrm%gfCrkgY9^I>)XAw6Kn?Se-zK2Kc1I#_^ocMHnmkt@ydnuJEm|HYmTB`==LOq-udAp}b^tAIc(GPC5Z6XepLaV^;ih6qdMG17b?j +znIURMgoM&k)utVHTl(8=&1AEQVmF+O-toV`5ZRN+s+rnFE><$|mpc*)uDb-B +zdOZ%vPXj({a`OsPXVX5%#cz)>fiuK9hkp*1v*+*Kp*RtnF>WXQq@BGw-ReEa%lhfh +zAU)B|vNeUqRD07U(-%N6{fA&ZWtNX^wF97d_o68!!*q;VwT$xu3rr$D=*4#o7w)Nw +zq0s(S-G^q;=eLyl*ASiE{@|sNMXPuGOc5V;RIAAa!s`Tqhv +zDKjv-E5vAKIX^w+z8Hcxva=jIQVf%p*-`S$lJD;~gjPml@Fb%Z+CKV +z(TBkSFk6kK-a*Pj=?&!CrPGL$sgb2F;3f3}ICX>kvswFxlq40VWL_dpPUTr_>KO?7 +zsHezJvYP|5AK%^tG*OAjt=1>0UM{qnENH+6^B26Tt%FtqTib|5ZzW6Wa~8hjF+r+K +zJuGj9oi});t^c;i>Sp-WQ+J?)0@?hMg8E-aIHH|6}Z7qXjLwL!8 +zLe@azH9}`GnQV$K>H>lXNCXd8gH9Ndt@hzUT13lX=@F4$Vf9LG7vs>^A2krZHdL+B +zv01ZXLTL*j561)Sw27SI;KEd(q|qk>7{n80S|ZW*&o%@vL5SJw(ew#3v@ogELgNBY& +zUN;6*8!u@SZB-jd%_=lK +ze;QQ>Ny^unljSuhw?66~KzObfraVABciQaIcMnfMnqho4-~3?Pq^|KjEH8{veiSzx +zzi=K#`4=~=p^l&GU@i8*Mh3Rp3}ELN5zD#&`{;wg{*W6Urtb{~zaSi%>ZB<4)LIo8b*RTM>Q|lpEA<18lv-MKjpJI)k3mh&LDRn1H(?$p#QU9>)lX +z@WG<8VXMU7FHH^)5J93Q^wQb`ksVeqS5Y!L3+GWLo`>T1XZpE(wZ^@*`^LDdilR!? +ztJXxC_$0VfS&Jkzw7w4f#})$bm~3Fv*GR#5KMgpsJ|soL^ew0x`7-n?p0r76TBLpY +z3l(oYTx&`9S&AyiZNODT3EJMPy_~2HKpi$F)UTP(5C*5Qu*QuCuWVNP&VhFO;z+U$ +zUZ-EiP$uaZAzA5)-wElDEGP4N6a`5NHtCH&!)0$QYXLD;i-EJHnVb68=&)aJ0M=3$ +z&AuNQbFOt|2hT!2>BD(h+g74p_`_StuX|TKd#Fq@X)Ba>!nlxzg9F@)V86@6zK@=> +z!Z~d5l?b8l3ov@|IUyAcu`)A81YtZh{(w2wP338fwxJGe^M_0Gb~!--T7 +zVi?`$)jwTtPGj#qi|HLy-xT?juXe6GTBq~TPw1E=#`O+vDwA;PijDcI$J0z8;|uN& +zy4tTU)?7b^!fDlLT&eI=Bt0Ma6>xd>;`>Ae)X0MrZ2^G}%f#d&W3a19k=b3*Rg13o +zRX`qj7;gY*`?m$?-IGDFI*gu!3bs?irQ?Ts~$ +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 +z#3LEreOY)9tEke4eEVvFoar3pPDx +zYNs9;H_>d|sXGo%!SDK#S1RvYnTOFz)dLIqv^v2PQsXSKaPssW=;2CZIzf;@gCsY;}Ylr2izXjvkpi5TU0q-rQR1*b|$hDpvbU +zIF{psK$+1!3AMI@f+QyP-utYF)C@mC%26!vcsT0hKi*PkTd@nvRfLGwQ`JdXQCe)I +z>M<-qNZ#>P-zfkcNh@Z3S2(QbHX7)02kxI!f-TVizPO6FJZ}(N$P(mQ>PkrB*TFh% +zTlR+vs*rC`kBn$BQye+$^NQs9jA7XlvQ(LulOGbj@sH?t4A}68@G_M@BSgGt!%?lni02dUL=xav+ +zh1}YCZQfikaf}^5*R`Cj!$^;*%;En9jX-k0Yagt`J)~fF;wd}>4iC4h6qD#WkG;|$ +z>ZP2%`60>IgT#vGtPFSH!+LSNIg97bRRkZb1s +zFH|R|)h=y1=8jl$HM#+QY^F^zWv5>YXNyK+VuopJD?d;*S@sy3*zG_z3Kq25lDrun +z7*?%l;@uB%SX)5LtM@$;5umPr4CBJKxxFa;{P08KrNvS&nQc(S3oT3B=ZQq) +z6(qqn48Pqf^3+A;#m;7tFzREdy0C{W920 +z1jemq=gX~1uCDzDj2>L`1a75GT38T+zux0jp9AV2R +z?PbfCos%mjVOvG%Me(RGdi5<7fHq%yi-MP#`XcOZJpbcOl^&&&;d0Unq6c*wzx`b+ +z7SW*~DSk?=vKyWx+=27?xLCEeR>;%eypbroc8HYTj(fs9WqVvWMqMX(mD;xqd2gzQ +z`QF4H5qDfAR6`M*ooPPuWm>d-j`}B+vSIhv(Ux)&)_LA__&A4s!GGgadF++ad|`B* +z3aa(o=tbE;Z0pcv_Yi@8O}nU@B8;wkO)1wmfsDUWAD$LGj`C|xkHx*V3W(J)8#5r?GXREBno}@=r!K?bfd{)c;#J%fQy)#uVq6XHH)1M09;)sb-Ub-4jcFSv(x~l)ZYF*N +zP?RHBUq_cBdR%?tZp|z*?DhoCOO?lQ?;jTd5S>w)I`2vtMu%3$`s9j>r>Z*Cgl4u6 +z4z77*x{Qw#8J+~%wq*N!oFRG0GSW>Cxvm1!!8R$k=QLj$dGenwor71 +z*u&r>B*McyO!J23P%@-o4X?J?vMCIC3aBaK#jlaWEY79A&332mzRX`22o7au&3@1h +zmXuE|Rzl&$RDwNr42i3Jt~)^Z&c$s+0NA+yJq6nUQXd!vX>219+coOF1@A0d@g{F? +z5P~h0Ec`E={dUzAYUb=SotX?al^IeTtGn@ev}I;9enh(%x%<~A6nG=BmsxiZvq)GTD_y53o7 +z!xN-U$$3jCzUpC&s<5sG!k}PbS}r=4KK+=DirUwo6GXu&)4e)T+z}7uJz$*+U?BV) +zKn8KP`>&C)k00)lM@?PiWw6x|wX8vS$?%lc|EUI0PRpgyO$HjWIOk=@-bjNtsr_!h +z6?Gffs6GWa)BEg>qMSbp!!cB9YDG>IZc=&wvpDVd*5C57w@=kuhH{nXoFlQe$rzen +zWyWV+JSY;^hKAM*Auo_TuxlGQ&UI}Epia`i8Kvq6ZlD^I>JnVuEjy<7M4o=0{eNNX +zk=PJ>+HKCdrF%k#>+QiQ)S!hmizoBW*|(VZFKr=4N;7x*n7)U1&+c$!{s?$7q*J_Z +zjyXqV3U2%l!jN0v1azzYaKj_Pm{l@vS&Z*2mv<&sgzGFUi@jma|~dE^;Sfiv2gqv&l#*Z}&113>*BF +zFr%q;|4=S-8|Zx6g*+OXH%vq%1>NT!2FffdFsU?i<5E%^S^z=AK1J~U+{>NaRk)R6 +z6m#mlM%(&jjPg{LRef!?p+{B6s$_lR5*(h8hLR4i-4Z9Y78aFa*#Chnp +zZ61mozB-+HlmB7 +zyEDKLy&@iVNkdCmkh>3k__NE^jJRBE<}z(XZFgMk`MVoMX3|@ft?7&qfskJ?)9IK# +zG9qC6@rlo0QqE^-cWFNljs$-%GuN3zK7kFRRZ`Qt +z#~H5%pPP>~HP=Dgo7JUDSB1vK03t@ErJHSgcYB!~nUBR20r06>$^G~bcqc(7s&m=< +z$HrYvcay2c;o2FOcFB*D4_uG(fkQ +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 +z{Z&USV!VF~9E-u+#P!T$&~J$U1}0 +zOu1i4suggXXeUfu!jRih(D@rH^wP;m>u-i{melvd7tIfAcq=MMow<%O+OV@0 +zS|~%iy>=q0gj~h)RdkbkLiGNqoDvcWv#mwGd36b7M&V6EW2wzGl220^lrLlGFX> +zdz5o_+%SP0J~fXn@c4%Ex%FGBBba&&VR1xQ`*DU@1JaxuRJicITT%Q; +zcSx!cAII>RcF+aUU_Q0PtmCVH6Q5m57aF3TV5?H=?@IPs+(0g_`;uPeKEqkoIID3Y +z7#1AvNizpD&L>m2EB`Hqwb`~Naibc_;}rM3kjUvx2?u_o-4RBfzanMf&~qKazHwG5 +zq_OAcVn-TfgHX3ikO=Cu!lm>Xj~sLljnGfdUN1T8AisGngRXi7Wwra!Y)NDcyK6;L +z_js21q=zaXqlx%r(IX(UOvuZf~|=(j^^|aqkBr +zer=W$>CI-78cc+7vqgi@m?SRBbyF&Uk4}9YW_hhI6y&giBK`}dM7WY^7>tpw)?Pi& +z+!^a&av5P-q9+ps|K6`^TwKaK69h_l5!!bX0ks4I&#GWnKmB^r=cT`g_D*{&kT+^ +z#5^8H;U?DAAU4isevL|DOv$*TF8!eas7XCsas*sbLctc5;S~gDoIBIJobX?;Sz+Ne +z0~eg-3T|%lJP$lss^2lkhLU{x_{8$G9NVtO%iOlW#t)W8%1D`= +z=daU)+0+1F<`R5k3qZJi{&2x4({I6rkN~ij65YBuJe%L!WH*tUpFx}sx@ciX3up82 +z2<$(HzMdLg4zJK-#O?*|I`K27@+UvoDd+-$Xxr?9KUb>)ac{NupDCpL;SK@CD*9aQ +zKP-AF-zaslhttRMNAHDreyI_D3Y!p(clvdKaz4vBdcZ7^$lU~JCS`BQK? +zw~$;_?th_SK1KOPY=f3hSG|salT&(B?#u22!5Orj9KCL#zs(##0OW*rGibJcBaU*I +z&aE1jaLoV=N^oBHUDmY4-Y}Q{cj{(~nckdGaW}yoV_dCI6>&hYht^T?;Vg(cJWl*u +zFxBBJe%Ro_ven`x1uqRVM}{{Jf89qmU1+$t^5jRG4)B=9sZ>Gs*J_I!?qsf&^0<l=q)W +zu%W(@kS5%zZ~Nx%QJz1c%_as!UZ&&~2_)Qi6-)a6W)rbS8H}PisDJnUq?$+iUa#@& +zhKPRd!~P!~Ks!o&jy-~XTW6ggY8y?TF)G`xQ9)^&ryc@xt+z!yZtxh0>rl!&w0@h_ +zz9iSAMq~h|8@LY?Ys31Lc&Z~-0yh2=lIIQf8Yc_<#0%q44=JPPTp4+Q5Mxh +zAf@B7eaHEHROO$Eip2zfRa-pckqrx9Z8i%Cgrdn21ez;2|2(l@xB{{3HiKQNsNHpO +z-NM7F@0g)i0RU8#7kIcYg*6WjxS4A)9+)2VO3Mee)&yRILt>^|hBhevvRCVjik!(* +zH?kIECNoh|zbJRJF^yi3Dbi9U*Y`*tj$3tak_K+l@muXK+eqZP95SC8<046Evo$aE +z{QNxiyEYgv*lupyq0KGj8~1@94`p<6#jf}+{7`IMhX6b{jz^Q-oLptKAQ%knGQlZ$ +z6L}A)^x#6vKlG5Kgt7-=#&-8S*Z)aKXVJqhP@}!N(9?XJga=!drokR-nw{b-^2`^AAU6 +zbRD?D{Q68MkP32K +z+GB&3+oBa@Dt*~7o?c<$*tTHw;ch1j;`#T~=M+J`0TEV;zUghZl$E`ETiaSiV~wJ% +z?D@s=#A(z8Su`o%sAHaK^=!=?xkYu|H~W~_?E8g0OV;rQz}^Ud&RA8 +z7b9A8SWGvV7|dn4P$;0%$kN5%!jTTs8^I0WkqiP0hm%II>{p*W`u81Y1R~@x3b{9M +z&Ce@ms1cXmd3R=DlihR55PbP^*1Lpq4!OSvE^REY831-Tri!q0V?eeWEHI>9qMR0X +zeeJOO2R1?5vI$Ga%aAwIO}xK2$arI(Y>M#e5B*cFQ1tt(ZgFu1)2TInwJ;)k(awku +zCB1|6r${NfAXbfHOIE%|%an=$Vu7@SHs%o`C@L1G;Lv(B3AcE4|&epV!Jm>r$@@|qYc`BX=?WvvU1cOeeE@=L`B&pY?Ay_YUe*K<4 +zZlc&9QaSjTAl>PHedt&4?!cJaYyi>3Q!#kKUuTIaEc2|*>L{sBk(<#+c +zR0&lyj`Fq^sDVSnU6p{)sOP=-Z-?kU(%5tTZemjhIu8)x2_Xn)CK}u1*dP&S +zl1-{dnB8}c6nglzt;qBh;=r?t9;vRsh>V%jrUCd6{dzjOCHG;4zRVz44M^Qr^2>5GGC!$21H9Iz`j>#3Ve@Kr^Q>c){$$YC>52I~uW7|@5$k^dfRPMJ +zzcT*II(b$loLPuxo?w|t;)16S);!ZVo{ +zeL#FxWZ#%=+7H>-26yaq=zv5bXlbwZhp6`?HL-y;yh|GDeG@4UgI3|HQ7k^f^1s)o +zlK4rJ?U4+JwNFcMGUgjb7!3i6T~nX^xbgMIdN9g9ys*3CVk_^+)|I>?|t2B6xh)X0;MbW2~<>^a2mz +zT_AEYP=^llR=rEDyg}*JqF%DP26gT?q`C48gJPX(31YWTmdaJJrG!1U3q`vqsOU(N +z4oRK_^3IRswk%`i=WPnyA*UGSlv&G`W>=rg6!qSUoYu(KuScB8fvR_Vd&G&LqPl2k +zhYIpW79#a+#}$rjKds>rXd}F!7h0XLNyxh;IBF-1;&bhtbiDdS1LNTpS;96m6oHi3 +z{)VsFZcuk4OT@a{6>>lV2SDp=vdWnPUB~%q~mP&&6A+tr2pPh198!~+_B0E +zj&S&vv`6Ht1`kAYN@q+t(1j#0?|w9 +zScIt*C3sR|W^Z2;0a-p8JI89-?XU=)mSLkNj3+w!A(hyN&C{T_VCn|?xmv^G#zxR5 +zu4nv#air&L1$O-0VR00ZsuhT4F>ELn+)mbd!I$B<1qLw-b7DsOE9)_@2YN+!Q$Sh( +zDl3hV7*X?90_l=oS9$8!>_q2NVH5j(U(@a+BgFujbj%CR!z2v%)u&9z_TQRkts0Ml +zaNPve5=xBNi^)hh*3B=gDAo&>JTk2mXlV}98|((LGPZk+qk~t86jp1$Hs?@_LrvSE +z5SO48Ap6yN%oZwni7H(mDPiDt#1AD_>8@%5`p0Y5;g==Rw%ky9Je253r +z;+hN!R|j3UE^Yxl)4_LnBF4K_bx(W8v!=C4&VM6pkXCWiHTot2^eN}S6eUI6yF0d- +z^iwCP%Z?h6ze%cU>~n4aD`QX#yC`;bT8}Eiq&5|6>Yn)zeiF8eQTH+XQjqBH(0T^H +z4#;5|o8Eu4YPi>?>aDu*R>y971-lwjW`YV_fua~H;yt4>7q*5*JXP(o!A&bKOhO1> +zY_8f{;D;+h>VUO_+#IXu8Y7bIyY$}(;0)g^a;{u>hB6;o7E4m#Qbhg!U?r)~=xZ1r +z)ysB9I`-8g@luO2yv^VB)k5aK9LoaFUFlEY0Yw@fsQ0CrCdeeG`D4XrRqj1HoR8!x +z;cgeWm@$ozxuI;_!C%|-%L5j#=59e3-(LMtErypXTa9u(!NdaR_j~WtJPb$-P|63z +ztY1iWsi9q(;ldlmMTrti%WU=KY(2g+md*r*kY|UV<#pDb +zj7t0FO*FVHzIp^2-EP46UKXyf@mo+>QbeMO41ptESRICtiHKYOAs{z3O4|&XQ{p-& +zBH;0ZmbD50w8i&|`W1k;2t??xUMcxu0y9Y$E6rB?M}Mm8g!%9B#khDMrs!(kHOj^c +z0K%11Kn+Nw#?q^v1c-SItzXU3Fkj!SDBE1+Eq*pnV0>4}xlG4#h}2xfHJ~xg{a9U! +z17XuG2Mnjc4laWfFMHptr%sAoVcYw)ia~-&b;KlvRS_Qm00)5qpDlDke*gr^3~Wlt +z`g6{h03q@DP2kw@0DHOmK=+ItI3cWok-PTQN(-Q~=f|7IjE`N@wI1is(h}=|ZmX@8 +zwcY6T20F>-15jj>1~($++gK9Thc#u*Hu}GV|Nd#_nuiBtm253wzJT!prPKw(u5i!c +z{~&Q4&g;w8glHfzC1teS(>0E=ieMZx!=cr&ypFw_tmFgAyPOxvC7%1mq)QV=3h?X( +zH>kg=uNg_(V5Y&&iYy@ZI0}(x +zsb5mL)h0W(rpaFAq<$}w20MHRsBdd!VYtmZSskPk5i=}|Zp&Im&8k1q!PLJz4v+4! +zQK49~zl%?%ldQ$(>R=}^{@}Rb!p^Hpv4`eR&O@#{5o9Q!q?>H2cQ|zH5I_3G9JaF& +z(XunVk^qNE#Djp>uqAT#i{N7VEP8jbeB>hA$BliJK4-R`l|vi*J+e+ZlWVH9h@l5; +z#|G*dB5<6GUbr9w1M=z!cUkWBChE#{k;_U}G2QIq@Jp;PON?YIw|~Mm-;gZOSw46M +zmV$u9nJMLg^9qWWkTAPelT$o#`Xb=o2^ro-oP*(y%Y$~uO*?f*_pqfcLnVbV4 +z;8ixU#2S{hCi<}4W}(sq(O^XBNCY`v*rJwSf}3OeK2(Lb0!b@DEz{VkAWP +zlz5yJhDW@Y{PxYqNUT(I8Z{Ji;|evoy@a(Kv@^WRDs;_o0CI6MC{1!HDX~7EE2FUm +zZJeBsD?MrlOO}G3trbt+G$R#JU+TKNX5ayz16PBeaXdux8T;V_y9M0OT1^$`zipY9 +z#S*z6bV<+M>V^76+XOU>l&}N8XAR3?ZwHX<$*7nGZf%rzGg;NYXaonyw6YQRJ*1KL^MTK5~!@Oj3f(0}%>W7QN6^|A-a8Ri^gX>-SK<-&;x +z1wc|0r*}_Anj`5#=exFs$+zAphznEOJ#H==1H+Nl+!r-KLQE{h{ihj_LCbG)I|xhH +zJv<;uM&Au`qBNuASSDs`TJy6qcC_EZv|#IAg8^c}QnA4RCtvr~VywI7SzFR0$)E`w +z5J~L*wk(TGzVOmnTPy#D`MQgNK96;)hH&mE2js@pY0{k>p}LrN4|mFGeE8tCIl&74 +zd*1w^{6IcdyK%6&?+-U}Je{pJUvNS*rd!7=Gt2%#O;~XVACM*)NJBWD%$DX!>#KnZ +zDeTtc?ARW_UxQ%>mV{@2AvX&8*W-Rd5PGE +zyZcy}=XI}DG3%np>_ocB0wt1SV@1@h;Kd;ZA9Cj^sBroqfHva0Qjs7|%iyv}NSv6l_XYZ2}l-yrQWW~|K4kg9HW}P78k3L;f$b?8 +z-Cfj@pW40Z9146&MljXx--NEY+mdc%O`!>yn{lmifS?%Y04n@1`NbOA?qj^;wQXy6AOFm!~bqU>VLFRRu4X#dSn10d@@h&I~SiOAPCfCzs*-r`_hlF&FrQIaDe{3|A&YJYD5psQ&1NNLf4~as&gMSZtK7e5}aLmV~uLN#A%r&wP-jlv|@Z>RU)_V5IHK`l7Y>-Cj6a90?i!AR1I7wmpQAErS3AFMUQ#54i6A?3KILmTMX3nxmHTJ2d6)QGqgvnLBsMf%1}Ywg +zbM3#11LVYkw8GHmC=swOLx5^((d}ZWiPibC1D*Ppyz*&+SbH5u4aq3d3;)PjDpp7P +z8K!V?Y|HARzDF!oXv~L{v020$D8AT(JTb1|kSxFr7Q~-Y3pLNjBO36n2O<~4%GNZ= +zLQI&XEg4e^QgsB$)e!F7WfB0A0cwZzLnsgDn}0OGud@(%(((M1OZFViL$O}OF9QJL +zgWbA3qq=U@NiaFqFE-h+t?R` +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 +z#({L)W*go +zTy(+6q6c9S=t7g|hb`~PGCjRMY$#qAv$_Xu1y{J*lZ_ +zpDySz$Mio?Csz5sYYhrb`Mq|(nFu6E;I;#kJtL2{2pQhM}|pW18gw9sQO +zk!;4JK}wn!8g@2G+oAUxkdU|3jKleDl7)ao6hh6s=VC4Nt&>a~_5gFHKy)R#tBhl+ +zZs|mkqACiTr!%5=#afO+wo>av6B#Lhp8Qy6Y?w@Si64TMwF+qa`T(BT%p4(8QfOT7 +zfBSOg0Z+G9d{bhEKs%;(E!iQDeNtp6L&q%Qc#R?;THI^>s)gEA6`NRvh-tL0Xx$f4 +zYuu#V+yOrBb(lF57>$erfsyslCgR@WT5;6rqKBer(Z>3~42yliCbMyxE!G_+seC?9 +z=dX@0>$%U>y_)`FU>cbtyo6vNrv78$i-5zZ+;U#rU +z2U*n!vo?S7x*1xO;puVryIY7EdY?qt&N1Ocb8H*TLSIiJKEvBoRD@WV4$5MGn>TMg +ztW>aX9K@7Hp=HDhP_nfhHe%WMmT3Wn*z{LQ5)XwlBgf-eMQTuR$Y0l+q|((@Y=yeZ +zUa7#1kX+AMbTnYif(ZehsjwjyEh +z!mBSNcI^%-iZB$?k&tU)vznv#rUi49H^67>GQF&JnOHwByp?CxN_84dTRwM;8w;+hfI6 +z2}Sl>_@<{L-bT`8Os43NnVXXH@qKu8GvI=3jK`X?}b0zwQ +zk^+73z>y=J?8lh +zOGc2F?){gcswd{#kRwVRfWh-V>Fee`FIK2@Khaos--mC=>l|&{BVW7@NJF8j!9gQbZc+imN7 +zy{jt=v)DZbLcE)#cuf5J7MIUDUTQke^uf;axQG*AS!R_H@^?nzba1g%*8`3gjb}Nm +zyuAt;#@DRsnE6sw*Rv2#AJinrT;2-83P|B1y#$?7Jr6rqS`|-MQp~2BG}S(X6AQetKT?CE=M=tx>4LxcxP8wDRG`SPWbj*b7RAz841;NWjh^15 +zUDRtM#Q|f|OKI5Y-z_zReeL0Y_SY8>gLK3JU2h*;2x&k;G)>obO~;MwOF|7Dgj$i$ +zMsNWgR2TN(ZQ+_YTkj{&(4e_0{I8y#xmOje+iG@Fo@<-&=?5oo*1xw{#QbCSWvqv} +zI;&FDtr|(lhHUuA%_8ogRRTR^?Wg4cf4PHi@MVz6<0gBS-Qj-n|srur+ +zIk-Bw`W48j-rl4Y5i)w)565HKPKO#O$vJYR$4%pYQeIW8Y72PUV +zU^huzrqx1O~~n<>Jd?jl>JCtZ+Tx +z=*d)*tXLlAGg`w&<)zVuA_?C?!qZKA$V1!p6Wy8!^FSOq=fm2^5)2(PWKm1<0lOSe +zvq)>eYM|V=-t0)#9KMxE5#;c0xJ*t_r|y&Vnc-j3hL^4BXC881A^h^|RmP+iW)RfN +z!Z#0atPck})6M{OonghK{;r-vxC;ji0CkwiKjn;QeY@SU7TV5r=biqb^5;A&b!9jy +zk~FUyAve;xR+ACy4j1*sP-NAUBY8SN=;XQ;=6%&qijqa^6$Sg8a7- +zI2B#%Jlr)?qm|O#qW0s<-_qtAytMZKJmrya4kyRsY3J{=d+P!A?sAa@9$uCPI_!K4*aC%heW8(+*N*BUyJtvxWI98RjR^BtLeBXSbA&HKo +z%(Bx^U*x+B%sc0w^zR%MLnyR9W@x?l-6gUcJy +z-@4LIkixr!ARm#qN^q|t$dbk)_g%s->#;)5!alde`%DE9@c6&2xUyy^I{SM@$BOX&PJrCeN+55nu2q<_dv^%nQS1s`XDNaNcUyA1a4?Tt|JUIp}_=_$^05P5_9YKN!vP&9XQu4pez6k=pGEm14C}x*Gd2opfjH{Au +zzaD?pGt#~F2LA!kvmAt-=MJI%`cJ`4r^xx7-^a-Qiw~!#AR}L^-rawVpm3S^3W+tg +z?-1kLPul*EQ~~)kZt2%XW4nz8+aC7`%eU(@7Y-WGlST}^t4#g)3sU_@AvB-EOOk_? +zl8I#5&mODN@@xo5RZVWDToNdjjp5Ck=&5gQXZ-<(@W~B=(Iox!$M+eRY2cn_iAepi +zB1)E$RP*}KuYtMp_j14RZudU&YuSDU9~&%U4bzYGBVd@#i`95?i=u!CSS%vZuHHWe +zCM+@uhq2G*H?6BZF3qrWCNm3Uza-xQt|cEq&m|qbu43Q9wxY0JE~);-W{)I_5p5zr +z?#5EPxF|lH_F6q%t*N8w*Bf~ypg#OlgO2P4dbze(1%@sx#@rW&fbLh9obZ{xUk_%L +zhZV`ai-WNdIuw3%wc3Zq{u+=P*>7^`#{6-~i)$H*FUt&me;X&WwjiP6;|i^=U4Cn01!zp4%d=KQ^G1(0Q~cRCRy}IHiQ6k-nZ6DC6{hs@z6F;uLG6?TI877D~TE(F~?A{vT0tS +z2IED~^+0-%TXM_U)hgYA000Mj0iSVnLVo}R$_)Fs$GkymAOatDAVI6Ee!jg7h>a8V +zq53~&V@iT2sX7_0W6SoC9a4%YVt +z4us>Orv2x#=7Q)^ef)0@ZmYkFe=^m}Uc5eJ$?K}$D^XmHJ(+Mn+CCVV9rZoGE&|1q +z{IP&wV2uK`iFILILQ~J?-9~E!T9_-~b_G3m%$xZjVbNc4*<31wv@=E!wix=VAncRYS8(li{|ns`r`!k8TB(t*6trlYY>1J4z-!cPw3aI6 +z)t)8vKxE*9`G_44%mSW7r)!2&q(L_(I6iiJ?RXvmRPkTjx^Am^x61$M +zV0&JzubfK;@O$@eam2fv+Mnhu$IL6vbD35hNq4<8R{Pk`tK+U8oYV`*BEUx;M@0T% +zbw6Z!jz`2K)Xs0GR61XiWc<0|=o0Z{ab5|ZD0<^-y=Xg4zP4e#(tI$vI&_2VoMIxO +zynF;?v-wSo3z1F8v&W8TuN|wb#-JSr*ULONu+Crz>Vfuj#EGW$>9QL!9u9diG$CUP +zssC8wC_yWNi0*kUi&UpUBFQW4n@q?(aNroCdKf|^4&xqTJj}UPTY=CQ0KYTIuf0jC +zUEp55vNN|k4(-9%jB#}^LUrvp#o`m+#r1W{=YW>si`E-ZCJSP9+jQ*XvkvDsQvP6&5)8=)#6vsz +zc}V(5Nd=|4v(ZOU-ZgLot>Kj!pO*_AcBE|0YTx=75|DXg=f2HO^yo+i +z4pih9CQdGjqw%~+UI?cfNX#u8>#2R>*fFcA^BYVt=YK)n5b|4e-M3Xoq7L`~7pqE+ +zN^y{;Xl1WrO=lzlXTwKnAx +zxaYyH0|{#Mc;v;%lA9MEqBPFDT)R?o>CpM_r9?O?9p|Os>-*}#H9Ja+QF-0{@^BvW +zyU8mk4o2dbnZ$Qbr0%!eY;)Y`au<%`o8pjWVvs15-Goj`-{}y|NaBklUW^CKRL(Z+ +z9c8ZPj6UN89gDBrw@q@)cQKNoaYq0;z*mmjqcjv| +zjUu0MWVaUNGGt7$bIx_+0lf(7khPZJV9?Z4DFgY?@pDrxTdKz@w78Kcco9(*pI@as +zD&OStbGyTP4z1eE0^g~b5@HB6g0aOt1EfloA8ODyY}WOPC`lQLorHCoVP$+9tmVIC +zH#EeYH61z!yhA`z-q^((6#B4UBCmF4pNv}6dZuJd8SQ{w`uK4UP +zTZ}&sTk`qYUbpJTeJX91oTZrwnJjU#Bqq6o)E6{U;^ZB5DqNzvmvCK&0||ws@+)p#tyd1He@jsR4okMqnzj2ovHzD|+?4!b}wH;Eep +zxRUcPD`kwOY-DUr=5% +zQN*g6&|V)&`vgLJm~QMJ-~p_)ZnR*-%f-JBSnzf{){S^YyDpN*??)4&If9r~{lSh# +z@7+{y0ooF0t`f2E%>|rg3`e^7e8O?iw+$WcKazCf6lCi4S_6}R3rUbLR^_uQ2*QLM +zJ^914f=;uX`SATVR1l{;%AShh0c(EeWrkW@3mC8HGu!JE^?z1MN(33agAP3d{j%f{ +z=srt}5ZUuPgEArcgKZW-Kc$Vw3>1#Ww?sMadDBp9C;PdLSdAh40oTk-xBhrn!=CDJ +z9x@HsYupdHm0AHPPsS5{auD9-Lw95sbud-G-9f@Fh>(8IHvkW6Kk~!;3n!t(LA_PKSAf +zDI&c6a6y0|>gG3PIB8A#IBb*#H#qlmJ8rv5@>y{5A28z`>zlss1)MYxrf6o3sXWmyov9G?7_ +z4vVUb0FR~SP6;{&>qXdfITRW)<-?rr=Kt;+VG`2q!O?VZ{$ceewOttvD|)8A9MO70 +zlVw}-8%Ypr$ZIOiHbEK~?Lz;SA6ct4WN3^S7GIxrPbdxheCWJwP8gtzY3`z*=giSNIc}Z$ZJN*pAI4%8+eFu^e0!?DhCax?_JCq1tgnKj= +zb9F1>Uy(#wfU`!iy0QUPfR;Y-aO%HDnNxa;>XKJ*rFR>6438@5Dt19qqiY3f?bVPq +zaZWwv*|lgAsW(OFEH1Bco<-tbbc&7*H96@l54*pFInhl7WL(h}u0kZHO14A1V`urh +z+Z9Bv72jw_{hW_^$sOUE9Z(Ydz#yhC0H==H?yrB&*mFVU&S1YJ*q$C4blYouDm0vN +zm75EtGhWVG*rYdi9}Fx>HLuRDDdDQqT(8s#;8oa2rW>-~mP|@d2{t~-dFr^ce0Jb< +zu_^y?2*{DgtHy85zlF!GEFS9f{1*-0C6o +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 +z%)Gk5wS~ +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 +zOhW2SP&ePSmy9Z +zRm*s%*lkNk6M4mUPFbSO)M-?CmqP7-@sl-HM%GmBv3HA)I0$Gy$8%F +z-L5GH^TU(;!0N#06tGGFh~Y2V%SoJ|`5aLGdTUm0UsEeB=Wc(^DlY^K7>F(*d=G8} +z&O_st_<2i4%?FA{jxz-_nAD;EBuD0X9S8x)JHo-6u;IC1_w3I(ijI7{(CT`XWfp2O +z`&J3pBGLw{~~4fBXN#39HYCkRepN!Ge$wFL@0?>J0){LF;WrbC#V +z%#oLHGXSkt3Z#N;2d3*ng|kF|!2kdUj{%>zYC?Yi1j-CDa5N5o&aeU#C`{R1`~%+h7T0Y-Tqwxc*M`kn0H`K^TzP%=avk5*#i*a(ZJ1 +zXq6V}c++L99L^l@>-?h8;#ZrT-w$4dm0v +zd(1lc?ot6S0drixfSg^#Rm+ge?977Ufi)^{xTsq8U1dEXuU0*RT(!?%a-1H$GwS+5 +zb;0hKH2L6eEx?z>lpG;h7MEM&QX@F++H8CIwRt7#fKK&$S4kKbJWvVZazvMbF~C9` +zTATz8io9I&Imj|Ej}q!zij-0mwc#V_%qgbIl0QvA1)#7va|^GTptN~C(l|;m+Lj>9 +zEe*y!%(WLYwteYUkx7UiN2iwHVg&W +zJx=4g>@#Q=<;#T3i@9PjaZqGEYGf`SXt0qRuRhuO +z6b#`o`jk2CU%Dq$P`)T?bTlE?+ITmmTnv&l&=SrCLVO{f;Wu>6F4w_zl3Umsr)FqX +z6xevl%sOqk899>8VZ(^cY_lws_TfaW%<)+MYUF^Ef{{IyX?yuS{JCbe22a)DrmPQF +zCB538Q@BVHFJ_Hq|Kq(mcU!i>ZPQ(etZuu&;EKd~BddzufQJJG@B~(YYIk$R1xq#% +z!jjCVl*|!|PiFM%qDPu43Gkh_s(uv;P9SNK?#$PX6%yQ$7H?&m*>ZRde_ngbq%tgY_Xt|psXXrhr>ZFA{fR{$Ti +z9%;x=6$wNc<&EcGRedG9d>htQ3bcw7zJ&w0aoOw?D;8VYO=!+#wjrT2wC{gVuI~FS +zw#w8+*|3%1J;(*`rX~X3{Qx!s6NcrHohDt7@d0}HQQ6Bm@>HNf{AkOdWiLPlZ~){e?WfX{5dnl`Aq3l+HA)UHK_wK20yt%+NrcmE0f%vb&aG3Jk4*3b +zPTsq9;XlE@B6O>s_Fn8ZbXL=M}YMBN_4^e}4osfgE{4*2?7i*cSDr5ztVDUZd-Lw8C0w>st!?R6AH9%XlU5fI29~EuBu+`n0>@aaJ%#1BK?k +zA&)hbL<|gF($y@CH^j6zTU_LF4@0-OfMrcJf)AH+(q)ppvT(VRjZm%(0_Wgwwp=7? +zr%UIY;^`Qva=Zy-69cQHvUx$(IS2i@z*d$_C~63{;FCmrf=hdZDKhuMcgE6-tH8OI +zk+3mNiK+r6(UI~k$3$$Z>)5p8F~JT0jSqk~QIXCaK-w4i|N042#5-(;lcKiM-Udt2 +z2m6)l80Ul1$!RSwWsF;wLmI7;#V3fxOne#UN7j^T)XW|nK|i;!p0R|tr95NBn3mWp +zCoYt%?y~jE`kyZRI^zW59_Vkx!%9N$ov9TbaevDQW{wl$Z{=SKU~6$Nu~&ZubKY`v +zFJ~>5Eqo_O3u+jBi$52|3z&%?*2571nUh4O_eBuJm(po;}$DAz$%vm-n5t- +zN@SPh6!1arbfYq3-n=l2dy<_LqnFDfHp&3(1m{rlz9d?cR!|@mMmy#KI{lXVPR%-_ +zplX-<^*+(RHb +z4T9wNTAS`EUk7`KuqX3zB3;Ko*8r*Yb~a5acI*_ug=_XAa%VD<f&6BHZ!>LP@;|{@ahe^o&)GYXz9V`v2Yae{e8`;v!SzEL)FW@vuAZXGR498R000M*L7Tfts6lL*ObAc^ +z{qX<*t!?Ik<`JLaZ2%iVA^{~mB2@!z9*B(N#xoa{zG+$wizbWv7Qp3U-f3L#G+P%>_G3(drIL +zkm*~l`-N!TTH0{Uz%$jwr8mrV&il``;g4k_ +zPcn*mBt5be1T_v!y?UEo1uYJuhNs|Clpx1rPi{~1oFtn_&NwpKf +zMYsSx6S7#UUZ$`>p6^e0@l&41njY~2b5Oy4VW(QcR7|Ew4bPEh@?SDdO%lCbesOMj +z<&HR6F#_BZ`Tt9#EY)*08vF4z+~W1DlB-+Jd@jKe(&e0d%En1Lb^u^o-zy>6w~g6m +z#?Z~`Z@AoB&uZYMyRqabHWhy5i4D0R#>Wd~;=${!o{Nwvw +z%d2xuK#NQ%48PNvsgE{zAY~cc8B=r}>#1p5>zl +z=xM$Ws-frL9w=sE1W&E;AIWyILv8$^g*g%fMh;*+i~(<6+SIN3Cd|2fSy|k4`4*yI +zxD`2GO?7aNU^!=DLgE)W{;beAb8J-v0$X>)#uo_@$MepCnj6B&kQn*MAQ%a3rZXIq +z`<81UV5b5ic>2e)Agw`TVL9!XtBqRpHS{01n*AOgw1s^wb5@?v6Y~M +zZ$8)sMJ$F`*JDK!_cAhCcj*+K+^Kz@?&r!P>a=M8N;shIDqYY$NQ9OA1|k4l=SlmY0B9XzzdT_Za{#v<+Y{)fWv{feYXssY)tHYE7j +zl`Ga!sF{OeEE_nfCT5zxIe%}Q*~>@<2;I+e!Z-owTTRDSc(gF$?QJMyMCpCj9{8*i9pt= +zAD+h-V(&v-C~lbHFP`!3(JvqXUlsk5PI+{-A-foYA{aFLrBPk(5qfPxi(>%$JT!J% +zJwhUo$|Sbad8#BW8LI-ypkU#`#`J`z<|d{N9C!BVH#)F8@O+zXk;=;ZMIFflE}a!4Uidn9ed +zzWWbVy&CVS8i^z{3eD;rBLG~cGQOQhw#!YQ2Um+=m%wgm6BX)g1Axm9X$x|QKfn4k +zUtXZm+o-S(Uc}r|Ud1)L?xEufRer1biXPIZP(M^?TuMF9zSz!w%WQB4sOryj+MKcX +zO_Sm&@Wuo?N@L;EgBE<=pW6(qt6ak$B!O@4zo~V{Opy3tleg2FE#`}9FSfEuM&gxl +z1twuO_l-Oy(I*I;@_tq)^+pV~u915Wr+R(J$5gQRwQC}sZ86g60^qi^5->zuiFWN>^;=Zkw;vEB +zM-h;al#rAb1`$D8LIIJK9=e9^W@rRKN~BXdq@_DVN?-`-?ryke(D%OYeed@VxIf(W +z%;&7V_KLmFUeB!aJagupEv_(Gf(`9&;=My?1{M)4B@mx``y~{WI>oQnOiV2E@G)weUs;`$EH3u +z&^xVsFvcU;o3UvZjRIy2%YBf;PoLniAVvS+xO;^x6pGl(*_*3O3JG(GG+4rjx_p0h +zC9kB*QSSBGn@Hz0QPsHIOkSb>DKFgc*awGE&Mmzcy@a}QRWrW=QFVF@2k91>P0G(C +zkT^NmOrW;*=@A;Q9-AlN3=OiZ$Hl1ptnc`w!{sRRv)=2dTv?p#n8lk?Yo9x*w1Uem +zx}AMzo5p6J4SF5D(+Pw%Y;HfZe +z&!R%p?~gNPg9t<9C5F3XlLk`aI1u-5zK58N;t>kUXM +z+2xKcA!}u@_V&x9ogK+D#nD+DC!S+Xq~oW)iii#A3rx~*bWXUATboE0+h~NwZ@!U$ +z?7H7o@SZ*I>ff*(!g}06QM^c$OyTVcoXfW|q~Vn(V*<>YpB*03v0>t0~{cpej^32`S}fmx^>dgAt;k}$Jq_m_lY +zd{$x3RW*_E(DBo-@IgF3pxx-yh{zdQIDL`pV2FRl?(k{i2yUF%DoAr+;?GG3;nvRz +zD4=QMQ2Hi3pKp)Osh>rFZTzITSU8uCh@Rs-{tC|~beRHpV@Z4SYXWl=dHn!Tuz&%HaytQ45KU_!T~zR0*8iZrVd89Ht=P`>;&)r9EvryfI*ZTOKY +zK{n%6Z0DCyQe{qXq?P5@i}4zGeupDsLO(Js<`FXm@TSl{Gmq4`?;<<}&S+^t$?Dvy +z_yfaGNfTS!E3b1m#TbP6;c%h +zHqP^RB24#18yP^g7rl_Bj6Z*UtfKn#Vb^)fn7f$xE}gpTp-viY!zstE4k4x?8?3c& +z>&)IF1r?s!E16{F7M6Dy*$<-~6h%y`Ich68B))rpRd;Ro(o83^cAW$ +z)8v7i`8&Hx@cg9p*2IfQ;!x5%1Ed)x6NT@kRL4-M6Dwl|xA!0rTHxlZ#9R?2<01yt +zdtx4EWf|4^VpXjle|#&lTYDn=&QSd$EPNZiuT__^v%CnVH8s5(u2!;*H5f>6V)9eG +zM359>|6*LmqK+}CXBKlHv_Wl6!Eiu5THQv*?BQ1(l}A)P2bhUcStBpw(CNh#1(O?D +z%|1>$PoU8hsmA1eXx$xfdENT)Wd{Rss7cq+^$&Ee&aIhs{FJzpXcqx0Uf7|k3rzDR +zQPTSt>3taD?wC(XeOWBrs$Fh7rFHKiiCctI +zbAtPznw%W>26#x3X(jY%3%o$hAT?|sEEcjbKP2HQIIe0c +zFc(?P_4)M`&p^nu92og5O8pGFtk)#U4qzo#xxSuc{mc*KK26=;Ys9HpQac&|?j9<} +zU4p)gzG18}xWD?1Yvaj9c@^7bl$7uVrE-sbK+d6amtw=IVp9{suO}6L_%+?8j9R0- +z@MC*0Wi!E1o2OZF8bVEHXYfj9h;CMpwJe4br*ijtTb!%eAe(nm7)6Gh!nv;iZCyOX +z0=+kU$v_7;SZJSOe6f}AZ56@oeJ_*{j?iFP)=s&?5A)zUH3_5l>)1{dU9@mnZ_m!_ +zTApl{?K#4o*ReCT60h}xi@3)LgicHYrZFVqR>YOen}QF!v~Sn1rAemMKS=UvUdW3~r%$_Yx*VpVA_v|>keQZ4*EoE%ez_vBMj_(O$z%*2-_oa1y +zqVQZOL=NNehL&BTln#tc23gO=WXccE4CNL^SqSEAGI~?>@{pMkvWnJwa#P9e6|_p9 +zBo)*sfV4eeMO@0D63-ZwCBr&;&|OF;W||(YSVk3_#9(eD_TW$w*V<_R@QxfQG{voSeKZOswSOaGa=2zvIvx;o$CIQ +z(QrYES4JB+ri+Cye;^X22Oqui1*mxUe1$+NR7UWA5}1@=w1;uIedKeuJm%JhL+MLg +z-dsIc?*l2J&-o(JL3}Ayr*A)fseIj +zHZP$>r4K17Z76@jY^y@>IQZ*>G2){H8Olc=_zHHNZDzuY%VPEgB)axAt>RhI+5`K~ +zZ%aNpFFKE3RZiJaVaCm-P^d~?u1^fA)^(jF;EP2&XFXnuQ_8xk$!@h_$g)d>^uv4M +z{1l?P@{1EhZ^1MbcScdxg2o^ +z68Mzbu-~~TGjc?vXyw=zciIX%e-J0p(LL1R#HNmBV{m0nVObC!!a7nD!?pL? +z@$Zdn8QFIwG4mLH3FoEcYBBr>GP*=)F*dCU9;!Ao(Yz^+{y~9nzN%WAcpVp#n$ka- +ze-Ug;EYJ9@ywe^vHuftzE<-}cmse~-O*>!o3x`yvsjB>7Zli4iKIaRTYxV(qtR56> +z>I?Ml4A|`&j6&|MN?V!q%-(U?3*$!$Q!ZwBswo-Cdr4olH#O<*+2$VYUmm0VG86Ja +zjfimhB{e{^KG!^5v`D_YoM$IE@d{%r*zCY@X2%pP8qv#2fzZHsJn21lx<6WPx8JC3 +zv^dFGuNZPrB++xdS^IQ~$G)aTZ7=N8+h(opQ42S1E)Oo_%3^YdcFMX>#>>>C+p^XZ +zJS2f7xuTPiy|D<6bgdc^y!>0*-}2WF$%w#%oMf-u?`DuZ1^#apY(B3E|B%Fdx$T#; +z7?L*%S!Jck`$>piBFJat4?Q+@-3B(zqu1MCcXS!i9NJl~qDlca6{5am>3&cx;l?A8 +z#du=4*K5Q@6k6f)Y~+Onu@{TMwhkUb0X$C}20Vs+A}i(Kf|ge|nqr$ZhN0 +zDrarWxX9*H$`NF4XD)jkDB~TMF +zHlFaFjdw30&*Y;&J#PkfFRQj3TGn7_dD7LliR^%GH0}n#_x$fz&-31_>36((y7hnWf*g3}vK*D*=ldYf&_$F+;7mo8jt??8eEV+6ZsQ=U;? +z!t5V93If=KLt8bJJ8jE@ecOn8p9ZUPCWVv3w(=9H% +zS99+tv690FO^rtr`5H-eAr!5dXLHUiv%U8q1Kd1!oezIWEjP772KJV(=Fh&++oySA42%g&xF9sedXMCahL{q)WQ +z0?|ekDpUJdG%(tBh^eml4k36V`GfQrV$9mKBW=-=?aewvBCFGy>jIW5wNU*Bd>z+4 +zOCw@C-x0zu)d!T)tNOvDU^*`l2z}kc%E|!*0-0Ml7()U654yDiT$=kqC?MqLZ~7ks +z(ETr2_;1Vq)ItTuyl-ctYX&Ia*_qvpdFvmBf1&~7{+s?a&VL#gMHq0}xpAa3fZEvt +zEph{MTf3W{o0%fxqWzgOT9^gYL>JIeTR{JP?$3a3C(zs08_&naP;;97c)Lw$YL;~;vUY-a9!Z-&I +z2*4ANNdfK+AmBI01d0a61%MC$NWW^ph63Oj004W8WB_{r!T0c1LWBgeJ` +zfQ)qlARIsx0Hh62ATV5k(+0j9`c{9|0J%OK0QBskcDevpw=lTjNcF>i79OBj+33Px +p$lCDV^w{Kgb))}cXN3$%0oA>6Mg|4R>N*%cfv|D$vvG28{1-l>vtIxJ + +literal 1554 +zcmZuxeN0nV6u<3bttg}g3M<<3v4A5C7=;cYskS&=aH+Gw(TQ=|2k#+BpKbac6$q26 +zgvfMZE^O--6L1NclR1flh8QLw4%rM5#eGC{R2Jv(j|s9(8MANazOwnmo#gkWzsJPV$oN<)LWX +zeE-6+iWMz`xAwzrc-v;{3ns3&Hgygab@co_v%sWh^~kxZdgv1 +zG$e27=y&X0FwfM)&vJ1wQfF>hX5`>p!|hca@;lG>BPmWrt3nUp`73 +z+Yr|+TbnzS=UsV1v;C6gviW|rw)-!S-=bHn;0v1+QGDC}Ia|1D&?ob%jF`h$Wc#Ew +zV;vf3`obS*$vM4L6xr#4wnKY06wGT*}wdIn7LW=}zVn#?n%4mVMz +zS*QG<-xMcs%$)a1n<6jX{=IjfF~joa!xMeyYRwY|Cr0Vm>*3w%uu#*`=0;_WapAn$ +zU<`El@AbuA79AjpWMkq|c1;#tZJ#~+J(2cx>Nm%BvdmP*5AP|wGW~$TESZLVhn6a1 +ztO^C+GL%>qKKRQs;^7r5rKP{`hCoZsRD*LTIOV>}^ +zv}Z#0Dsy%(f4!(s5zT+wRX-W1@{bU&DxT$gcYNB95Wz4GhZ`=WopD!CphZIb3Y&Tt +zN#HB;J~@EE6G4Pb;@qcgDO~ywITu+4q3v9iuqGi&TV#WEm&%fL{&(FFn1q2)5>0U| +zXbo*=;Rh207#4X2E~$c{DoKbWFx1ksXMtOViZ2NB(km#tOR(VMuB70{eJoZOI||7? +zl%2*olCwKs?)jSUa8_iOSD4dRa20SkU +zV;68rdYYqx4bH`mH}`KUjy7ccnDD_0CJHA@_=3toU_OwXamIR7Gqf9{35_wfE7@%h&<3n +zKs;bQARC}!xiSZ6ESNJ5P+CoKBNU0kHoiM#Wkq*n&-SMq0^0~2cD +TJ;x-N6hTeOp(eUDP!ruh^$B~# + +diff --git a/dlls/mfreadwrite/tests/mfplat.c b/dlls/mfreadwrite/tests/mfplat.c +index 8ed94289703..5e289d8d5bc 100644 +--- a/dlls/mfreadwrite/tests/mfplat.c ++++ b/dlls/mfreadwrite/tests/mfplat.c +@@ -622,10 +622,15 @@ static void test_source_reader(void) + return; + } + +- stream = get_resource_stream("test.wav"); ++ stream = get_resource_stream("test.mp4"); ++ ++ hr = IMFByteStream_QueryInterface(stream, &IID_IMFAttributes, (void **)&attributes); ++ ok(hr == S_OK, "got 0x%08x\n", hr); ++ hr = IMFAttributes_SetString(attributes, &MF_BYTESTREAM_CONTENT_TYPE, L"video/mp4"); ++ ok(hr == S_OK, "Failed to set string value, hr %#x.\n", hr); ++ IMFAttributes_Release(attributes); + + hr = MFCreateSourceReaderFromByteStream(stream, NULL, &reader); +-todo_wine + ok(hr == S_OK, "Failed to create source reader, hr %#x.\n", hr); + + if (FAILED(hr)) +@@ -641,14 +646,14 @@ todo_wine + IMFMediaSource_Release(source); + + /* Stream selection. */ +- hr = IMFSourceReader_GetStreamSelection(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, &selected); ++ hr = IMFSourceReader_GetStreamSelection(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM, &selected); + ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr); + + hr = IMFSourceReader_GetStreamSelection(reader, 100, &selected); + ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr); + + selected = FALSE; +- hr = IMFSourceReader_GetStreamSelection(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM, &selected); ++ hr = IMFSourceReader_GetStreamSelection(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, &selected); + ok(hr == S_OK, "Failed to get stream selection, hr %#x.\n", hr); + ok(selected, "Unexpected selection.\n"); + +@@ -657,17 +662,17 @@ todo_wine + ok(hr == S_OK, "Failed to get stream selection, hr %#x.\n", hr); + ok(selected, "Unexpected selection.\n"); + +- hr = IMFSourceReader_SetStreamSelection(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, TRUE); ++ hr = IMFSourceReader_SetStreamSelection(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM, TRUE); + ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr); + + hr = IMFSourceReader_SetStreamSelection(reader, 100, TRUE); + ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr); + +- hr = IMFSourceReader_SetStreamSelection(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM, FALSE); ++ hr = IMFSourceReader_SetStreamSelection(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, FALSE); + ok(hr == S_OK, "Failed to deselect a stream, hr %#x.\n", hr); + + selected = TRUE; +- hr = IMFSourceReader_GetStreamSelection(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM, &selected); ++ hr = IMFSourceReader_GetStreamSelection(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, &selected); + ok(hr == S_OK, "Failed to get stream selection, hr %#x.\n", hr); + ok(!selected, "Unexpected selection.\n"); + +@@ -675,43 +680,43 @@ todo_wine + ok(hr == S_OK, "Failed to deselect a stream, hr %#x.\n", hr); + + selected = FALSE; +- hr = IMFSourceReader_GetStreamSelection(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM, &selected); ++ hr = IMFSourceReader_GetStreamSelection(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, &selected); + ok(hr == S_OK, "Failed to get stream selection, hr %#x.\n", hr); + ok(selected, "Unexpected selection.\n"); + + /* Native media type. */ +- hr = IMFSourceReader_GetNativeMediaType(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, 0, &mediatype); ++ hr = IMFSourceReader_GetNativeMediaType(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM, 0, &mediatype); + ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr); + + hr = IMFSourceReader_GetNativeMediaType(reader, 100, 0, &mediatype); + ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr); + +- hr = IMFSourceReader_GetNativeMediaType(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM, 0, &mediatype); ++ hr = IMFSourceReader_GetNativeMediaType(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, 0, &mediatype); + ok(hr == S_OK, "Failed to get native mediatype, hr %#x.\n", hr); +- hr = IMFSourceReader_GetNativeMediaType(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM, 0, &mediatype2); ++ hr = IMFSourceReader_GetNativeMediaType(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, 0, &mediatype2); + ok(hr == S_OK, "Failed to get native mediatype, hr %#x.\n", hr); + ok(mediatype != mediatype2, "Unexpected media type instance.\n"); + IMFMediaType_Release(mediatype2); + IMFMediaType_Release(mediatype); + + /* MF_SOURCE_READER_CURRENT_TYPE_INDEX is Win8+ */ +- hr = IMFSourceReader_GetNativeMediaType(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM, ++ hr = IMFSourceReader_GetNativeMediaType(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, + MF_SOURCE_READER_CURRENT_TYPE_INDEX, &mediatype); + ok(hr == S_OK || broken(hr == MF_E_NO_MORE_TYPES), "Failed to get native mediatype, hr %#x.\n", hr); + if (SUCCEEDED(hr)) + IMFMediaType_Release(mediatype); + +- hr = IMFSourceReader_GetNativeMediaType(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM, 1, &mediatype); ++ hr = IMFSourceReader_GetNativeMediaType(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, 1, &mediatype); + ok(hr == MF_E_NO_MORE_TYPES, "Unexpected hr %#x.\n", hr); + + /* Current media type. */ +- hr = IMFSourceReader_GetCurrentMediaType(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, &mediatype); ++ hr = IMFSourceReader_GetCurrentMediaType(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM, &mediatype); + ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr); + + hr = IMFSourceReader_GetCurrentMediaType(reader, 100, &mediatype); + ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr); + +- hr = IMFSourceReader_GetCurrentMediaType(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM, &mediatype); ++ hr = IMFSourceReader_GetCurrentMediaType(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, &mediatype); + ok(hr == S_OK, "Failed to get current media type, hr %#x.\n", hr); + IMFMediaType_Release(mediatype); + +@@ -719,56 +724,70 @@ todo_wine + ok(hr == S_OK, "Failed to get current media type, hr %#x.\n", hr); + IMFMediaType_Release(mediatype); + +- hr = IMFSourceReader_ReadSample(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM, 0, &actual_index, &stream_flags, +- ×tamp, &sample); +- ok(hr == S_OK, "Failed to get a sample, hr %#x.\n", hr); +- ok(actual_index == 0, "Unexpected stream index %u\n", actual_index); +- ok(!stream_flags, "Unexpected stream flags %#x.\n", stream_flags); +- IMFSample_Release(sample); ++ hr = MFCreateMediaType(&mediatype); ++ ok (hr == S_OK, "Unexpected hr %#x.\n"); ++ hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Video); ++ ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr); ++ hr = IMFMediaType_SetGUID(mediatype, &MF_MT_SUBTYPE, &MFVideoFormat_NV12); ++ ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr); + +- /* There is no video stream. */ +- hr = IMFSourceReader_ReadSample(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, 0, &actual_index, &stream_flags, ++ hr = IMFSourceReader_SetCurrentMediaType(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, NULL, mediatype); ++ ++ IMFMediaType_Release(mediatype); ++ ++ for (unsigned int i = 0; i < 60; i++) ++ { ++ hr = IMFSourceReader_ReadSample(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, 0, &actual_index, &stream_flags, ++ ×tamp, &sample); ++ ok(hr == S_OK, "Failed to get a sample, hr %#x.\n", hr); ++ ok(actual_index == 0, "Unexpected stream index %u\n", actual_index); ++ ok(!stream_flags, "Unexpected stream flags %#x.\n", stream_flags); ++ IMFSample_Release(sample); ++ } ++ ++ /* There is no audio stream. */ ++ hr = IMFSourceReader_ReadSample(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM, 0, &actual_index, &stream_flags, + ×tamp, &sample); + ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr); +- ok(actual_index == MF_SOURCE_READER_FIRST_VIDEO_STREAM, "Unexpected stream index %u\n", actual_index); ++ ok(actual_index == MF_SOURCE_READER_FIRST_AUDIO_STREAM, "Unexpected stream index %u\n", actual_index); + ok(stream_flags == MF_SOURCE_READERF_ERROR, "Unexpected stream flags %#x.\n", stream_flags); + +- hr = IMFSourceReader_ReadSample(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, 0, NULL, &stream_flags, ×tamp, ++ hr = IMFSourceReader_ReadSample(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM, 0, NULL, &stream_flags, ×tamp, + &sample); + ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr); + +- hr = IMFSourceReader_ReadSample(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, 0, NULL, NULL, ×tamp, &sample); ++ hr = IMFSourceReader_ReadSample(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM, 0, NULL, NULL, ×tamp, &sample); + ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr); + +- hr = IMFSourceReader_ReadSample(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM, 0, &actual_index, &stream_flags, ++ hr = IMFSourceReader_ReadSample(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, 0, &actual_index, &stream_flags, + ×tamp, &sample); + ok(hr == S_OK, "Failed to get a sample, hr %#x.\n", hr); + ok(actual_index == 0, "Unexpected stream index %u\n", actual_index); + ok(stream_flags == MF_SOURCE_READERF_ENDOFSTREAM, "Unexpected stream flags %#x.\n", stream_flags); + ok(!sample, "Unexpected sample object.\n"); + +- hr = IMFSourceReader_ReadSample(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM, MF_SOURCE_READER_CONTROLF_DRAIN, ++ hr = IMFSourceReader_ReadSample(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, MF_SOURCE_READER_CONTROLF_DRAIN, + &actual_index, &stream_flags, ×tamp, &sample); + ok(hr == S_OK, "Failed to get a sample, hr %#x.\n", hr); + ok(actual_index == 0, "Unexpected stream index %u\n", actual_index); + ok(stream_flags == MF_SOURCE_READERF_ENDOFSTREAM, "Unexpected stream flags %#x.\n", stream_flags); + ok(!sample, "Unexpected sample object.\n"); + +- hr = IMFSourceReader_ReadSample(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM, MF_SOURCE_READER_CONTROLF_DRAIN, ++ hr = IMFSourceReader_ReadSample(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, MF_SOURCE_READER_CONTROLF_DRAIN, + &actual_index, &stream_flags, ×tamp, NULL); + ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr); + +- hr = IMFSourceReader_ReadSample(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM, MF_SOURCE_READER_CONTROLF_DRAIN, ++ hr = IMFSourceReader_ReadSample(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, MF_SOURCE_READER_CONTROLF_DRAIN, + &actual_index, NULL, ×tamp, &sample); + ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr); + +- hr = IMFSourceReader_ReadSample(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM, MF_SOURCE_READER_CONTROLF_DRAIN, ++ hr = IMFSourceReader_ReadSample(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, MF_SOURCE_READER_CONTROLF_DRAIN, + NULL, &stream_flags, ×tamp, &sample); + ok(hr == S_OK, "Failed to get a sample, hr %#x.\n", hr); + ok(stream_flags == MF_SOURCE_READERF_ENDOFSTREAM, "Unexpected stream flags %#x.\n", stream_flags); + ok(!sample, "Unexpected sample object.\n"); + +- hr = IMFSourceReader_ReadSample(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM, MF_SOURCE_READER_CONTROLF_DRAIN, ++ hr = IMFSourceReader_ReadSample(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, MF_SOURCE_READER_CONTROLF_DRAIN, + &actual_index, &stream_flags, NULL, &sample); + ok(hr == S_OK, "Failed to get a sample, hr %#x.\n", hr); + ok(actual_index == 0, "Unexpected stream index %u\n", actual_index); +@@ -777,26 +796,31 @@ todo_wine + + hr = IMFSourceReader_ReadSample(reader, MF_SOURCE_READER_ANY_STREAM, MF_SOURCE_READER_CONTROLF_DRAIN, + &actual_index, &stream_flags, NULL, &sample); +- ok(hr == S_OK, "Failed to get a sample, hr %#x.\n", hr); +- ok(actual_index == 0, "Unexpected stream index %u\n", actual_index); +- ok(stream_flags == MF_SOURCE_READERF_ENDOFSTREAM, "Unexpected stream flags %#x.\n", stream_flags); +- ok(!sample, "Unexpected sample object.\n"); ++ todo_wine ok(hr == S_OK, "Failed to get a sample, hr %#x.\n", hr); ++ if (hr == S_OK) ++ { ++ ok(actual_index == 0, "Unexpected stream index %u\n", actual_index); ++ ok(stream_flags == MF_SOURCE_READERF_ENDOFSTREAM, "Unexpected stream flags %#x.\n", stream_flags); ++ ok(!sample, "Unexpected sample object.\n"); ++ } + + /* Flush. */ + hr = IMFSourceReader_Flush(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM); +- ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr); +- +- hr = IMFSourceReader_Flush(reader, 100); +- ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr); ++ todo_wine ok(hr == S_OK, "Failed to flush stream, hr %#x.\n", hr); ++ if (hr == S_OK) ++ { ++ hr = IMFSourceReader_Flush(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM); ++ ok(hr == S_OK, "Failed to flush stream, hr %#x.\n", hr); + +- hr = IMFSourceReader_Flush(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM); +- ok(hr == S_OK, "Failed to flush stream, hr %#x.\n", hr); ++ hr = IMFSourceReader_Flush(reader, MF_SOURCE_READER_ALL_STREAMS); ++ ok(hr == S_OK, "Failed to flush all streams, hr %#x.\n", hr); + +- hr = IMFSourceReader_Flush(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM); +- ok(hr == S_OK, "Failed to flush stream, hr %#x.\n", hr); ++ hr = IMFSourceReader_Flush(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM); ++ ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr); + +- hr = IMFSourceReader_Flush(reader, MF_SOURCE_READER_ALL_STREAMS); +- ok(hr == S_OK, "Failed to flush all streams, hr %#x.\n", hr); ++ hr = IMFSourceReader_Flush(reader, 100); ++ ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr); ++ } + + IMFSourceReader_Release(reader); + +diff --git a/dlls/mfreadwrite/tests/resource.rc b/dlls/mfreadwrite/tests/resource.rc +index f54212a8c8f..5edf5254906 100644 +--- a/dlls/mfreadwrite/tests/resource.rc ++++ b/dlls/mfreadwrite/tests/resource.rc +@@ -18,5 +18,5 @@ + + #include "windef.h" + +-/* @makedep: test.wav */ +-test.wav RCDATA test.wav ++/* @makedep: test.mp4 */ ++test.mp4 RCDATA test.mp4 +diff --git a/dlls/mfreadwrite/tests/test.mp4 b/dlls/mfreadwrite/tests/test.mp4 +new file mode 100644 +index 0000000000000000000000000000000000000000..72bcc0d8f3eafac344bb2152438afb0c4c691338 +GIT binary patch +literal 121550 +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 +z{%-Bh +zsx@awKRo<19F!2d&k$?u;k)fK!*$nr^b}uvxRH21e$%M*F_6Qi=W5-NIFDMd_ER(a +zqZ9LY=!^NF<`*h%jC+*aG@gYU@AN&Gf|VUCT+JP66aq^U37eKB=R@CQ?$IC)GAQTx +z4)y+V=vR~$sj8zO`Wp;jBw93aZwG03c36Lz()+NdQJ6dk^@e0XcZeBwAo3!fmv5^? +z5JK|Ph}nay5xYZ%kiYp96dwM2q8dc2H>+T@6k{{M8|k?$E1v3&oW+~_^jNzPG3dgR +zG_0(14AUpmP8%1jM5~){izbrd3vtd>?2H2DZC^s3;>I(O^%H}~A&KCd@LZAww#s3=0zDL|t_2?Q;<{R^GrOi>wTsx%4A=xvLL**+&V +z&fg&W%}^n))zEKkmZPmzI?((TlwU!EJ9jyAT*SLY%ru~McXq1!Y~1#=KS8eCCu*Yq +znX*jH1@;=7c&i=)7efc>n3fyg1j17?8BzPi*yv)Sf_r*!o`c3a`WlbvN#j5&{qWC$ +z@7l=4I@5M1ltOfDA5o2;U7qSV`HQed3C_ilOWJ;7Y`#k+m_V8~8a9U*SX1{ae*_}? +z2G_HVz>R;`RJpSIA&LpzNK3q5KV@8IoO*{U@5Lcp3sH6q{B544%0RE$=ym__8qc1{ +zSZ#acDq~E!YhY%rja?=ZCRxY$bpC_qFftb3TViS3wRCF| +z9Q>kEwdOdxF9oMC6j>7;xXmRhop4ViLHJwDFhNCZ3XfOqnml73rss<`o2bh>{$R$u +zuEpfo@Lrwm9?tS#!EqeO3O-IHxDA(5E(pJP>C30GK92jg+&m#33Z*<7;%cnh*ht@z +zF-J1np}O+yhc`QxI`dg2eO)AJP$laU-LGPaw}vSr(Q4^=sS}S;J;Ci#h@+v?(LW{O +zDoRqXoE%f>+iWPdiF~^W({qy4P#Mme^2s4l=dBwp-&L`y3(f+!>j@4jl^g^v}{6s*Hzb!0)N60tujwLVDLXhgA +zm>Y%03V6=*qK3IEuJHF`LI?BgtEFB*Sfk%&vCA(CSkXpI2bG6mmC@m}3eo0FxeCIs$2ehUM|FpvBfuhL+=u=xnSVL$bfmAoQgz@lZBGXkUGXvE +z&$QGRUN~t-%PN$VuA_8ZtI865WTPk_{#vp~;6Vgo_?o%I_fh6z4eQe>AeUB(9Ab_w +zJJdnE*e9~WAojbJtLfuf3_119EvB!i*tHRE@&f0>F1a&_d2o+`OHx#DPb9N5iPb1N +z82w~wcyNVu;IE_MtFh7)Pk!+>r+DuQUaY5CK2o{Dxxt`ury)^S+M)i2qg4T +z!5_{LDD@U)p_iNccS+v0k4pazw*a(1pjk^cj|;N9M>G;@_;Q1Z+(2oQEn-NMzEqD(92Mr +zmZ~dlimZ$&#E<_=&H5DrCq +zC@ioO9@L&zt?3HC)EG6g63swR*(^4(IVqD*i>%Z;ZOV{4ee6&sBkf +zb9i{wc!8pZy|H}1=giJ*7{%Em66{AHfyN~5BQM9V9 +zArQ0VfkpacERo0tP0`IgXFRA_J)UFiMa}cq2Xke)(IEN}`7YdK5lGw1fo+PsO*&3> +zgx|SkpE=_?tvm~Q_Q;nO-~CA9(6akES`(%Pq@b}fBKW{0JU#E;$YKvQS1ip)XwYi7 +z#JO%2Pey2K~ED-x8Q +zx@jFh$pQ}r>yu^$CHQ(SBMK(GJF0w;m$BK2IXU%(l=2hauNXXD=(EQx*(w^HL?!A( +z8u%l|f5dH+Gh!4$Kr9mBUU$4gBmmlWnMeKUBgs~%affbmKZJPMxJH}i<@Ww4J?ojJ +z|8Z|XgYOxO$}N@ZS#mGD6ua7tUrNOH$`V)DzqwqnB8&myKAx61YP0NrBr(JRX^8DZ +zuh59tB}&O3>_J}z5=1d1SN-mb>S|Lpy;6AhJ-%W6)Ol3pxbCI6JH2Xe!`I+mwqm`B^_ksJ=A8i& +z(f`=qNyjw3aBRz9`;xcze2vdCl4Hd);(v>}re+*C2Z6Lqq=0_d7eFYkKb1WqyDTi9 +zr2I&)8^QDdy;aQFtU)%CA|&E9z(ps5i89pCZ)nG^d +zf|ClZW?Ph!xS@Op6QkuYK*~z$)&b|?4BL6g*6KJmhU7`m$Vv%9EMIE&)|)IcrMZj? +zmQ^;Rf*ji#x?N;RTy!bN2dM4d7W*Th_%oZ4OpbS8U}IgZ#E65to8m#kF}h8V5RMILv~r +za*cC7F6q;ksS_ic_m^1>2Sjvy!EBR5(@o7KgzIQJoX{c8RGzxHSsYV|M6R&jPG}$P +zQ;0=TQZ~@}H!n^=a*4xbo??*E1*8g1oq-~AeI0=*78Foo5%{*Q%PgQ|bOb=QlLox& +z4xv0Q3a}-_6^U}d0kxYr)MRq-ZDq#4eVRsJ?x}Y>`i2UIdsVfJnTW`CP`Q=N^SNzW +z8r3}!yDCxjZR(FiP&0%m^u)ITe)-L|+s7Qz1cCILMZ-Div2vpOvtIE6_lwI*B>R0mh3zkyMji)zrihiOcz_o>xCIty;Ne>iWt|u()^7+ +zTQfw#H=>;4bmOB}v14YL{5q>n5WK^l<2NhRW=)>&itS3bu~fJpWZ*yudmx>YU(U_k +zYwP;ROT(J?#zN@G5{QZFenr`7e$ljo=OD?qQP4qv9BiME`4$|4?!VM)>135y09vB} +z%k2W$EW`#R +zn#r3LxX{q85WtO0b=SH)Qu}W(Thnh~=)PK9Ah)^8_qQfcA!}6;uqbz)P6FP&ZfH!% +z0yiGlW?sP}C!I~F+m-QOy**z;dy=M>YvWCj+i#g)a~)h--cWFXxaW=^jJ^jRc^x+P +z9+^0+XhV>UmPic6D_?itDeL_(wPvk>o$9#7^m*J +zR^COI-R4(W8rRz0*#OaHoOd^oj+e7Q%G2HmT5#EEC18Dy(Ja}l0)JeS% +zfw985&4akrc%GtU<0FpQI{udh-hHOn9&NYjk~g_o3-zW#)2e4jE|rt6${>57I)->3 +z@vwmbH_v#*4=U^;fns+H5n5z +z@QFFnBH_9;JWysB681$^5(q%zD4E7h00p@w=D9Bl8#}jI|WsEvl +zsS?VmS%s$EAp6J~Z#H!ve~O|fpG%e|xTtn1u!n)NJ@ +ztH(Nc{h7kCz_|v_f_{A01e+W5XNuIMW2g2Ys5y*m=W$_UN#tDxcP|%j%_vm+FPoa5NmHVQMJ*#nFp;F797w3-D9cQh<># +zQi5j@4_Fe~vrcQZnWXDD+WA0)P)_g14_eC!}w8I%B$z +zd#BHTk?B?5rMx^4ITjz!u5nk9fdr56_N5>M> +zh%An>{hFFG8g%>cHr~drhHj@tv&Sl0Zbszx9$pPL$`ce$~HJGC(YI>J4f01gD!kJ=f +z!0#e0j5FDHxRW^T#1xTnO`TeRWszJ);3Bj3I<=GjeF;KgK+rKx!YtW*SsqB0_dsZo +zMekvimJ=u1AP48~!c!++$XZ-NE=ZUoA=T?MfD8p+_vm%)074YO11orPVJ@Fx2pvzU +z1-5dnX>oN!_DP8#l8gq<^m)cMseplPmVApji5W1Q{RP7n$leS(|JhN)ob*IN_3Z1< +z4E|NCzh`G*Nn0F5L3ont_1=;K +zdW4(Kuo#^-{)jl?x#+JNa3|#{%i+(5oa0J&=y^>*8lC)+^o}}2$&J|nL^Dv>nk7Xi +z_q-91&ZAbp7Xe7cQ<$stqHx|{urrl8oY5EGswoRnxz5pRqhvzbfts!$qZ&Syu9~6F +znEE9KCxUkbjz<-Df*l9zs*rh< +zU)b2)P8bG?KKy*VR9}8tB=W)3337;8dseNm7SdNI@%Z`;6G%+wJ!pSQ5t*#`>d2Z^ +zjzpSM|CR)-e&;Ahq4wK-$e`AhH^GDlN{E(_Eu&1o*4Nq@2Qk-%GFdH)?Zv66uuk>% +z`a}u1z||HFB3*DynMpNW&SiysKEVHZj?Rg}>wM2B%`vwp+s;{i6sx4!_@204WIc#T +zt6bJtSra+K)hd^4i&2O6E#pl;lo)nnckl0;AXQ+*MQ&YT(b{0DT9IV1>y{yh=W5bz +zf8uPH{U(-^lKNY^S|zX;pIj3)(U~E?@8u^n>Qo=;_H}64aIzEte{=p+B*%NX~ +z#5v1iD6R7h#l%_pCGpC?E$JZPf4q5rf{{UK1D+PN?t@(Ze0obCORD0D+$;iGwxt#$ +zzv!<<3&j2+t-1<6VJfWACt4gYaPTx@II-Z9rYKe_SdytV##xaeXa`F7*+i@jfOFWo +ze%gc#qyq+3VI-sv6knC=&!MgIzzQX3yf_cnO*+caPY4GoWnOCv<41R#X+hl-!16cn +z=7Uz`q-ezER|3EUL`ruWH;)ig753mX3_F4KT^@0dtR;y0yt8I$*7e_>b}@F^$X4X- +z+=RTC1<=2e6*yABI;?mj42oNxbM0;p@B4&(^g4u5sU5WwCQ+jjAIz5FDU_-A_V(C3 +zGY!&l?VD~UCo#CX^(FI*1qWC536qED*08WIBoPS3M#uFhp+`br*r?7-485f75ggS8 +z_96UY44h_lZ@Ddka@O>+P+WHb_qV`)ZDzCr|%<57DXSjG4Zrvi@@ABFhk1xia`f>JQL +z94038Ysp2td`Gj7+p!f6T0|v!t1>S(^kOs}-Zm!_v_~q00Cuq7G6+EXU8GImn!9b7 +z5coyF@-46yzFCbt$1}vv)Y@?PGm*W4bB!zo{eZxR38VAe-9JoKguOxlV8s3?pvH0z +zSzh%}V^fdJ{fpls10u}_sYZ$EZS=>fTe^^4aBP{9m#KdXeB-dlF%{IiNxFjvS93|* +z`k6=i(4vUkTyP*5j0;kbXudhKq{HyQIYJ*9BYbv@eZUK+p0hJ)$=(X%1l3LIU+(PJ +z^(_NU_EA0}DvwebQ(dNuGg=E741O9u3pmG$*)#4bgtStz-OX1nF@eN8pNFuKOUJgR7wBafjE9Y{hR10)@p +zl_yu^=)K9_d&s??EOtBhUk;kw1O*GJc9F~>X0Xnq4jhaP!`XPeP<9rn*A{iJz?6v* +z(Kzn#eNpig?nEBfGr{={)z5;ej&3M0OMK3sHIUmt1nGhp*x~sgAA1y7PnwlR+IRoe +zQ?n#Q48@L3PMcsG3;81OiAz%RCvlE0%0Cmn*@f+>>*^6;7O*YEN|y)E0dg4pTIxXM +zHXu`K2_d0Q&1kV<)7a5xEsD(3(=gD<{VQHYH6@yu48dL_HuaL>k|seZv8)!62fn^Z +zkI5Btoj@2A>i~kWiLK+LxsB>;PkK(~UAoRC3&T=Is^M(gclw7aF-EuFTHV +zyp)#f`D}|`dQkfPsnB#8IUcWz+G_h{h$}J+K8}^$4~?wY@Gr4mPrcr1p0ruR`}=@X +zREqP6vo8sx%UK4iy_;`A);%sLt2-1u*Ci^hr{-UtgTXKVU9Eo?&(D#+g1*Rg7+&bK +z`SZBQ!AnxS!MGA@ZJSVi^<&>5zue-nu%C-qD&T%a!!UbvM8YWAiYLOKlN!ah@JKlq +ziu*ld083RRSi-DAmVW;uV&iAwUeT%C{JfAj*ReQ&FB+CMVaitFAPEMvPy7-72E@yC +z4duq7w7%7$q!c^32F>U*Kq-!y$bo(; +ziQMj|9Q1oOn?tUvar4Se8X-v+DPp;8- +zdY5&Vq$x+1aR(&Lw#L9UyVa{n_#OQqepkF6T&~o#ZrjTse18<@!>f*KI7L2*0XIxK +z#?J?#>+NpZ>91kHl%=nMKSvj0mq!w(49fV2y?2aLagWyw*DdxbKZ;bP@U(ddD9BUk +z3~gC`?J5hz*?)Xdi$>h*(**gN=g#tm4rqLb$F&h&CD*Y3;&H2`d1q>k^gg<_BEx1x +zL#JY>oDOkT4}VxhY!Z3&_aB4aqLtcis(xEat^J7(xRX_xvNy~Dptk7Oy3|VRdon!^ +z1W~|IGTJJq)<(n$qdWVO)hxmpDlZ_lzEk}!AcJ#aR@VMb_I54X2-2J +z$txf1IHqRAX^v$bCiYG@<`&PP!7Aw}zLJViP^^S3V@bfT_NyaaEypnNXrw_}{01n= +z8?8)4G}oG4cw-+F^9tX3-O-9EB2V2zzSj9{y?l`<|3<++)fDHV3Gsd1TaJD3u@_-k +z2clFAe5NViF6VWTJtWxXn7T@yzP6i5| +zoa=!^zkOAsj&#&Ox~@T-AbV0!_$*VjBKP+1sE;En|0NVTXSzfary4cIzpj3wKuF7n +z=y<=P07bTAE@Lr&ZJ@;)V5rbZ05xk+V+^2-q&AX?* +zvyA~USu?9c<=ipyrNhQcCBe23`p3=Hj~WbT7UzPAFh1#%>RDAD7 +z +zmltv{x$?(z^km5n77 +zz7KMh5cHmYGX>SNqA1rSHp1_@;fZ}BufNR-EHx4X=gqPvUiWN&K7)yK}ZsvML +zB#h4T-Ng~W>4;FsIhyxGn1lf6!2PDgm7%K(sf2jUL@yK3C{>0 +zi_%iZ2JYg$qoOzi+h`gNs}=Xvl;JGqCmt3f#~kS#SQl~X=+KpNgE1Ewm~#5Ce|d`U +zV|&c5P=NHtZ}oN$xO-oaSI>KJ6v!L2-CVV%ta&>z9<3_SolB5ib)5FyiDyL?Qmrg% +zbUZNSpdh6W)4z#tBWHG%@69jgEVa?X_||8KTu4S(F{N0TF*1C#bu-98>lQz-DPC)1 +zvz?5~=R$iU(Ohca;5e@1>=sL5;#d$+ghyufm#8>&dRqD^7+yE~RX_+m!PXk +z<@2p~DXvdD6xz6RR;amNpADE<%OVyuqZk?Co=rON(yu_F4hlx=-U@kjp`KA6>ugza +zXDsCd{rzISO1KZw>|#ycWShfowrxhJJ<)p7uI$}`o!Bzpb&L;M#ldWi0aYah6B6W= +z+jQ@L1*lvGj-CjXc{Af)WF$)=jT|0>^?G3 +zb=RyUy0z|B{pR=wZ&$qGH#;uUsL2429~fo)eRif!6k`;-S~+e~aE%Y@;Cr1mp*Qji +zdg0)!#5y4}Fd>b^SRF!6J(AM%T*21wlPe=l6+|Zhh(|g4`BN7N@)?Q@Zo?dEi<;vy +zgisJ&a9bJ$o|W$GJ>*(2;IJ^8F4YyR1^iN|}7iBEzM>I*7pKAeS4)9 +zS7#d!y?iT-khN+ZmWiy +zee>1#z@AV6ltL1mqJcKKSBmpN6b=Y+75x!h5CDwMa0!xB2>w|!pim6N=ez0u#8R8up!c;#$VoioUGm0w?Bis`7i8M5WqlFl1S{Xg8F(Szg`Mr?H8hw# +z)c-BvpN0dUV_*h`qsVyPw$S+0LQtiQJ3~H^*@b4^*(Vp^WpS@WV>6{WdyD6M!Jddo +z8jJM7u-1VF-MrDTt-ox$rFwJUHWkU3glHCFJjZGcb*D0g?z(@RDk*!fYDAUIec2F; +zPSkmg=VQCOg%@n3n?a=5?liwwy^n`j~j87ck+2M;g39+mX7GXvg@ +z`IWCkEpoB9zAK +zupBAla=UiQ>EvyNepn8y5S7$Pbr~Zfyq9`18G5sHhLpE@ +zq#eZcO0IM(r54fPrHAG$e#1+ES{4$$(B^)QFR~V%K}EJv_BJ~HropQSi`QjxPy(-e +zQKA8VU)xrcD%{Y6g0tgUrehDknBx9q(>zV{(+TAngKd+3XfD}aXiO6m--sPT(}E7a +zsG2(FyuH&=6PaBrP~*Bc{T&eqjGG#k!qtFIWH)s(X;UI_f85T6cy~3&7Hkfg%tN_^ +z$oh?;a=zW!JtKsBo%&qMb89*x*S^8qO^YaGqERY*2f=o;E +z4Fp=3^5hJ!nGZrpvp;yUs9F%b?KaHJUg>#?f9M^27&2b#S+KH2S}Zwq+jMB$0PRv6POT4$!lhvt{jQa~MSi0MUjD-g>gtd7 +zOfSbRtXD4T?d#$0AV3*W{WE0?2IAO>WWvfqa$7h&ZJG?Z+V>8R#LO=4238vT4+QHpjXy4 +zBVKrV8AnLu3nlV=)P+Z9DalH~7NhkVXh@%<7ao$F;%t`}97kmxN`(oeneG*Px$T7Q +z29=isfZ6ImkqCSCIx*S36sc+&mjqNgmQB<)woa+@?cs2P)DBF_FuI-`IQyb&z^>PUfM|F0eam;5Y}?Ym(l1c=U`wy} +z)(ECLT|Q+}?fGoz*i6c1%`^w!yjFTd$Q$DWNgN_2$7VL<3AfJ +zfCY+drQgs!07n^XKG8#9q$ww0ba)#jIV{$AE?h@OQzdN$RNN~*+ZC~Vwknu*Qy@|0 +z`)!*XABKu5cV!wU`CT50+f5XN@)#ws2~5MD9zEt#DwGkz(=Qi!2 +zY5l)1rC9kr4jhR+2P*>>?z_QeIuK|wvUyE*O~660AbHuYm@#}Xi+k!ZLUWBjqBKhH +zf|VHl`Y`B}x~o-S8#_>UwfdLkEJ_p***d3(h;fk)%rZgKLHvVwot|i`ep_hLTQoW_ +z(EDDVp_|!yjRwLtb%1}Lu_7Z92Rr|&fHi_Z}2pMNVTnKMYnB6P3zJDe+_mmK9%`k#Pik&bAXf%6~8Q%~kJ&a?=Nuln#MY +zwM2LbYsrCd3^xEM$4Yz!-%AtGlQ!FMz7IY>w6KwHXKMeRh=myr;3Y9t0B# +zX86)KUK?iGvLEXxw%Fa8zR;!dOy&JrS@%Q!fMQ461*#v{;2~2Vtxl)~c6}7fE3G|- +zCrNa-Sz7bt91{E*%J8r)qKe@i0tjkEM=Q&Xkbpbw-Q-^4UU+pFVLX+hWF|I7veR&0bvD6{7yvf)zZ!IMW_Gd-YH_bLQekS6zZ43;#0+qZpIg} +zQX&Jj1k2b%^qa*Vj@L +zyq2O_;{tX01S+rR+E*uI_cY|c*zT4Dl3woUV?i0tG1R!!jtR5E!oonA1wJ)5e+>8i +z3*IYt6e1?N7eZ{)RVcogl()VpkoV?1wMM$kF&j^^K18=#Yp$Ewc70vU5_b--L1uo~8Ooj-GL9H1^B@@7yV?ONN +zCyX7hUA@|V4>`~L+I%-!aP3jvE~ZKw#Fjjxnb+*bFl$Lq|GRM{EgUZ0ep)LX2kdiA +z^_*Vt21;n9w_+;$bm|?VENH0%YZ7NyJW7+LlmAH4#NH?tDg6EnzkrKu9QW2=`n$0# +zDhMN~qC$U{vhHiPtR#8i9z}Auqf3Y_cuOLzRZ3+ko?=^%qh2)qx-0jJd1r&cLawLI +zhBhRE`sVnbb@8xqC)6`0Y1^W1ak`^>D~C;*Ky=3l#EN;DvprfyM@2NpCh@Bv)3jTs +zqX>5!BXFE|psy1T55tzCvG-fjNm7#ZUoA08T&E8Yqti3J-Bx74GUx*Y+?3@w$I1~A +z(eksd7tPP;4+hRH{`nma1U4AZt42~Ylz*M4RZ`;*YDRk$ui=KSF2`E_d87b5Fw6f_ +zGh(&x%E+QD_x|o3HYe4UdY{J*S1ZmG&C=sx7eNYGaMSj4P-8Oj*F(wXv#7-!rHKkm +zC6e}INh=KR4Lo-YJ2TeQ{n;VA%M-4~v`9|T7N7O*MBlhW<-kAk}tk$j9Okb70mS1LNSzFP`K>obO?q`duRQYM_wK&Bp +z5**}B)oA@Xt-*l>2)@xV5$rqNC> +zc1Jh|PM0%PMjz+$KSq2!f0{`?eKbRChsljMMssd88-JT-Fql)%V@eoTa~bje0)F?~ +zZO4HP|Md8f+8N)kzSQL^=SOl&1=n9A9ERg;jH +zCy)5roRoZyC#Hy!480^D0DuU~KEpqp- +z1^H;jG5Tu1KKqIchacFZ3L5Tc?!a=U;<1FeoCxzo79#Fh$DM2~Td*{(Q^bunoDMYN +zR7q?A$gzk6P4VtnWcGOCEw}H@q0>2-yew*+4ss5R5pJ}~7c4Jdo_(41!-QYOT!i!A +zD2X4+1ZD4^U$O@k+U6@%`^QnwF(P5PKQmaT;-nZN+1OG^qu9F7aQrf?oJx(8i*WcM +zX-5W&6fFiUg^544(5)z*vz?YLVe?Iac)mhXq3vV75K@`2Z8iAZ?TA(RCQUU4>27ZW +z$5c*4xUsREI0^=iN4^L|i%0e}<2tPpR|aro9qeK{YP?^hZr&FQBUVn-Ii#;7o|U4l +z<18*N&TU&|E;n!Eqctt|I{&$-xoN8i)Ps7lCXVAJH^H(#RNFh2FNEcPdo~Yx_&`#c +z;xd-`fu}VfECsEkq|y5<_`lkaUANTn$)3sg4}Q@O +zh@Vl1X!u!nh>MYS<7dx?;*DY)@h1uzIMP^f{o-xvN+>t02RGvDMFEF2*Ezw6-k}v8 +zhXzITQ8T4ZItw#Yh7NlsyamZ}ot40z_g_f}kfyf0s+MzW<>E0kz6)2a);Lqh*{D%#af0KupO@Y+2P# +zxXU<{I2oXE>;C|AK#ad=S>H2|y;x%mwfgOsff+MGNwUB?tO=$8pgzNw4rPSJF0+ho +zs*{Wg8Q18MNapr(yhB(jA%Faa8l~dts#`stdsr3YU(90E+^Uc*`oRStt9nQ-%Yt-d +zRsW47BLsNIX#(zjDQson*iZO=E^GDVV|3mGr;+$>vWf;k1xCSJ({Igc9s}wV_lqF! +zzd(V|p3rwhNIHHBO1J4W&uf=H#>XmA3W7ETO#r6KJjBzE`alhjfX`w)2dZRW_4+2K +zXh{rGDz5pf1g)21G{7q0m>JT}^i}Y({>@qh`-4o&cyM!M8a!jJ!Ni#IWdzop;nv?L +zA|3E>3!cY4uJLmE1fA{*1;1$0`Zd7_6O>4{DA%wd;IjihgQ!fo +zHQ4`aW@v!=Q2?#E8vPJY0}O}b?{tG`S+jC9qu`M^f;tzXeqH_BKGY`AT2!No#2#=*_-iE3i;RB578Ha;ZGA2i%6naul%G63%BqRsmPWrkY1F+ +z+=Z}D*Fyxz0UzugHG^c=K3%S`A8E{LR5W{$c3Es&H~TXzkHS`1WdbwZqpl_^V8iye(Nn3>c2iIJcY>G!^{h+t|9e4iiAl~0tCC1mxRR<+Ea4QG<}h{LsguM +z<81hUUXVO(oA-m;dya&R*2(}RlP5ffn63r%GG7Gv3xT_R#^OVZ;L~}Ns0opdqXkAk +zCNkT?xaU%rGB@tLa$KG)rp-gki=<4(JDT( +z?mhn=I97ZgZ_#%`!ybOGPN!&ih)`Zhn?9Qg7`Mv@Wow$V;^!3Jl{`WgBD}USa4RPY +zBp4krR-foqv5EOXb&ja_3q!L+Ga%%WO42K`{_P)Kk0fR=Jlm4|HlAdcYTd8eiu&(O +zV6-{Ofxe)jd-J+K{3vJ1000Mj0iLI7LVo}R%3Q-L{Nba32z@}%sg8v6QgvHtQE#O4 +zQt@X@k3lwduL=?CK$;S+`|7Hc)MNxa$W$bg7A4#0lujq +z5_`h3aoatNXk$!TB{FZ@CJ~h65@fA)a7!;Sc7`@pZUx{zEl29d{dG6hii*9p4xNZTuS5 +z-xCX}y6E0zE&(%perM_3XaUsP`0g^ockOc3H&Dj%NPOW>O2C)kMVTt)nC7=wOBG&~ +z9W5xI&t@w*VgaT^$uE0i?>%G?9*4Q?BskvnhB_H +zcZ}n1aS*@`c+6lCUaojb^zW(`+E>TZgHoNr2ltS;P$d;ixpd9AIkIX!$cw&#-$t+x +zUKZ0o$W7o&H|xqhGjEw|bjn58u$Xc($<$#9XrE2;DFq)4Ce;s?ds^NQTSFjVJcn^5fDBPr`$ +zlO;q{{=#?brl59|n(XnC)k<{ci#g-A0!o4bMF`N63oq6^s1bgT1A0hB-%B|1)cQ=& +z5E$-JCHqgRHU~gW6!DP&%aJB!W4fo5a_qTB)<*&*F_b!N6khzp!y(4c!pR$q +z_e0G?nb$&LyK6ps`Lc*S>V>ObP?q`NGco#Z4i2!`bVMYyzdKbp(D1vQ>M%x5RbF)6^>ENx!0r?Qp7ghILM3C(j +z+;q`q2Mze?n)Gr9HSMc*krQ#e4IO?y4ucp8Wsa|rlziItM^y6S0kadx@XKQ8a$?I_6%4mGKJ-xH6d!i=SmpS+7<3=V!$5j$kSGw`j;P94GJi7Cu74n<-t5W3g&1^7u6Kq|z@%ZVp +zCCu5Q91B^aiog_ftJ&LQr2N=6@e<^@u4dp9y`1K9KjU6l=|u34No)YnguV8wKoljT +z7%(oLu85$v0GIx)X?Hix(W)vJ?cjudUU*PX(^``ud{jR4erdCE6U$dA^>nW?vbVh} +zUuTz9f5x(Ia{lf +zPwBb`O@ZknrpE*B%l_f+D-Wpegd?FdH7*?4FUYv~xV2_%lNUG{piKmQ$$2{Zs$(Nj +z@$BX%e2Lek4svCDD)G>+22Ba= +z-csA~UqIi;uhai5kgKC(s*?t) +zxHLgT;%*GD;7WB;OA_2asC~FkahP5xZ$tN|=6z5oQMV_e6{<0Wfu@OI*Opf>Vx_>W +zw?u_ARC-InL!5vBH_qt@j{`-)g$KC5RBXW0*-gFmLP>VhD0a{^6~?iDO}+~Mz6WIn +z&U$*G7ih@Q?jPzmxVw(*VbLlTSbr$tP|}to!78b-ZN}o|iQ5xGLZMCOaI{mqy4ol5 +zX;fLx)~AEpTRM`9gkOMP_FFq`5Qnr`qVX2fK+Qk`4U(108WgTzSO|^VmDs4;U$T)$ +zsQPHW9LqnVP0TxDfqs8CY9OR +zm7(~01!KHa$BL-Ow@sUtKKG_ecwHyKF3>k=Dh*uXl*?>OS^R%)_`&Sk0?QkV`e?PS +z_;Ps4tyRx4cXg-eMu)-ogwR&@)_r=zn_Y;9i1`w`u0HVlpG_7g_nHFn*>#~6369Cau#Az +zmOxd@2qLt3W+MfU$B;dMa`Kr)TCs1q&mFgKNE~42pAf+8V3`c5AdjS@#nHJy{gfjo +z9>a0>5Zn}`U5v^vI{gMR;n!%n)Z@SF<)y&wh|bgtr`(qA)#75HW&nJ7lH#~rRw+E5 +z%!wSNsJ@1SO$%e22_}{!O~`tI{6`eZ{F0@1mmh_O +z@ibs-NykBF*)JfA#=JIWt3TQ&SBqO$Kp28ed6$OK8gZwxD2%=F|i-}QoN_XQreov +z5h3ieUcV-q%T?Kv!>Zx}S%VC9?fCL-%}(bQ@?9gD(=b{{;gI4k$y;Nz<2#KpLgsd4YEVZRRs;oCZ%<*tv`HB<6~PfMkbw?3SCgjSetP45($!p`@t?L}u>c +zk;RO`riOl*d+l5teWyx-WFM|-k6v3XYkz@lxFcWcDAVtcbPNp%Smr7uKLr8y9fQrP +zjSr5FTmW}$&@fz9TUC|)LpisT9AJ2b;k(tNj +zDKz%sLd4DeQ$IxT@JislyF)*Y-&|F1CkRe(8Z>mrE*W*~Kd%ifX@$i59;ef6K(C88 +z77~;sef}*G+Hb=lwIIs>G7TsJVvwp)T`i`bu!v^RJ;?-uT1s$WkrlDqx&>Puxz3t@ +z3ByaDdoY08w@1TQ+LUsO>f}_O627h$H +zxG7I?F3(ET*5FP1H6n_zYQv${O`QhWBr<@=$fo%8mg3}Nl9N2*smy{A$E|P8A=6Vz +zqG7tRHnuAif@~&xjbsh%cGOpjIW=Wk1y~+6tGchRD$y#;dixNmVDg|G7Dm`}nwG^5 +z@!@XZYNTx8kiUd3uZIwL!DOo&H}zIq~$lN<}ca{13Gj%MXE +z99xNzdR=?tz!K?hfhO(P*~e}5I#j8ZasOq?GhAQXl|NU8QY76AU(38TB~zQ@XxNm{ +zy(VlMOzO1?dWprybD4|4NG9;!Y%Y_1P8#r^FvB-#hUH5Flw~(f=#--u1X*sG(2$6} +zDN-*K@$|wXfZk5}H+}&n0Uh^`n2cwL$Z!&9Ongith%^^6{f~pngyw7kmG+)e8j?A2 +z-~-@|k{iuxU_I<=F=2p#R!~um-jeqHzg@wI=iXk!CPj*sJRs6=QJJF81tUvfefwYw +zHVMZ6>9escSBGvZv$s6L^HFX1E-%}RiTTb8a1=TgimAG-ZbxE&g0?q~|B43AI7C}z +zE9T=L$tOqRxC?bW88lvg7wbX@9v}v!S7@!$eC3$J$koqyQQGKgiVzo{L)UyFv=zVW|<%pq~e9xc@kA%(-(8AhqmVGrN@6Gy6F7SV*~wP&QX7=RUUlMD?=-CGt+sTUx{P!_8=;lNpEKgB0tO2k +zCGn2QDB4K_L;xqWst9%OgD9AzPuz142!1)#ySdHH1(+A$B^gIv5gmw +zPF`OuvC#rj`-nYQ<5AKbu88k*Kxk$AKMtu@KoDYRXvlvHcH%%Mcv(TNf_=vThKC(5 +z5t3D3Yygh#I)$zFDe +zyC$IE(zeRhwn>aM6%8cSAaAH?#UhmI*%x-c4?i+OPcxE6^G)Ew(P`&v$32C;|F~`9 +zGSDw11-CsxsV+Z}jo!V|J4IorkX)pl2drsvYVLfgv2M8;%?Y4@tycQ@Fwhn^9EcJT +z;!2o1LalEv`06991ziiRhlTXrchG!Skv%?eq7ZQ!Kw7qlR>WWCRn#4}d&&E-(K@vR +zjJcSTb`B@P#JA`PBuPL0CEv?0AfR9*2YGcbN;P8{_yKuQK&1`VW8BUa6hO34@jB1I +zfBL(VaxOg*?0O66n*Te|+N0{pZna=P)kLfXXjo0XD>dyzSE-!BNhTunhk|vC*YrjA +zsw|HrCRHGugI!F4yYqDy9KQc{hufA^J|350Yz!_}1Rdl`1t%mp@`$Wd@&i- +zPZhc%r~pf*Di<+}RHlhxqRefRaI%h~p0}s3Jr(zQUc6!Y*(h)$Q-to9<>O7Pt+XZ% +z+EG|b@ZH$KzeCoVi%)$e3S}Cw)5ejx>$EW5LeeK->wVbUb4@zOcZcCL$g6I;X}F$3 +z8Ja_m2G~i&wh>ODXlo%eu0CH{vDEy#XemSQ)6ZWlaz45mio~8|5n)4z6(m*H!9qMp +zCH0@Fr8UOBLc5KrOI120E4mZK8rF97lIBAX7Hs376V#&}4=ay8+5eieL+wp|WzxqU +ze3g|n<$9OBlcF()@L8)eHIYmZ&&g`mPnF>Vv$>1QnX3x+U4PdVlp`w=yZbyz+ +zgF|OH_rgLCzXM1X5Kl!CKTOFk?g +zRAI;CxDf_T)-44h3YL;z4TjVw!kn=m-NCQr{L} +z1Vc{Bv{9|-{dILYr(UDwjMwxpxTrIyWUqwZgjE|l;Lnr^(vGL^LYE13CSxmNF1VI} +zB8Yhmby%apPFt+7(a}e~;UnmwoDq7oUYO?~>0>hxfI8&XD*D_F>B>vq$FHCH?MIx} +zYRmlg2J1xNRrpzZ=swL;TD_LyNe`1Tzni6G8+~9dEzbs_{?5!Aix>U4Vpd`%@~(q@)K1RbY)?2@*9avdqj +zS3TR!EK`v`1++e>O&_3;Hsu+IoC0$Qh!_=6Wt%kDE`=`~I@W&YUq6Vg@tv*}KWccA +zO-?C0Cm@^)mRoU?wzb(ZsF(Pow2fX@zRa?PQ%tHG{dcLhvEwS6Ezl4K{ZTpXZ-Dl{ +zSSliH)$|vFI&|uKZL3N3VI0sn4_wlM%TY#apYXD!i={DGwb~vHV7A0nbREogF~J={ +zyd3 +z$+E`@XVlY#h4M)WWjhrQmwr}T$AH-ko3kMyTp~(ouhNvpg@xd!eTOB?5xpFJa{n^Q +z4SdA81kYn|5qWO2*<)~Hf(Vp1^lksC5QSEYxTDGEY|tE36H;&1a`YJ +zVH6SCQ&Iqin4YKUCT-kZ@@T?>hJ<+~J%DZc@wqT43p)FLSd$JKw9SEF4SM4 +zG_e*=f(>)Cy~{$42Ym{%Exy{^d=k_(-pV8*$h1~WqOEDmVKg1E&Ndv0TBl4z!fOn~ +zV<@}YM6icHwdqL_H7awqG!qj-@v}Azk8uxFxmhYvEcLvC2mDk35(mWQ!}6#{4%x$+ +zyMKJ1++pcXUtPh6#A7N#kUM0+VC=_-vwHI?0%BtQ+!+;JTTfvTTB%PKAE$36;{atZwLo-IzVK=MTo40~d%%>w^=?S6kL6e;0r +z*swKV$*QUg{MALbA&8?G*qUD0i?fIN*-6pI9`4({@(E5e4P+;Th594(sD@FHzO882 +z-J-2SZ>h1ywP*n5?t9kB)^Q5z()NI{BV%>+0hhF4rGrtB!)2>L#!BXR+eE9S7QL3G +zf06$B_Xu;cL-K=rVk-MK?cnw4b4w9a^e1=cgXeT2pB_#W3B3&Tg^CgL1QTRW`(GbP +zcF%k`1`PNnQL5~TNT>NZlN1wLsf<;_X*rb>L6PNZ=hZ5vZ#HUgQHdtDx0+e615z$| +z+a_WuzkxE09}of*fATipk&TD6!S}D@!z{D?0!)h2vbXCcA!hG$ts$=;US?<>y2$>| +zu)Rf?mc;8CkTK{&k& +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 +z;oSg1k*vum2Bp4q{RL7BXg|46T&{~~d(a;p +zM+18ys$wKBLh+WZvDK_{wgA-$<5hCBq~VUP;;vK}92;)?03_t<;f4Gf-d0Y%Zc@vZ +zN$@csVZLk${Kx6ea(2=cT;u%zXvhAkk9@l`;>2zVou;QFoL5H|6~DwOUAE2jmtcgK +z4gdfL|3RAYNvJ_=nM??8|Nf_h00f(j!MN$nVIIE#4$S{{=U9ubV97#}rx*~4PW5HS +zb%q0a{EqpRjxhlleR<3a-6vp1hZS5IgsTkyheS4utMs}4ck|M|NDJt1{@nKHss6HW +z?c>&Av7;ua8U7tw=Wi@$AGV` +zuc^cdM5`Y9XIS|zkEQ`zkN8)$Jw{0zCZ^td>Gb{IVnn-jV1`_1-OFR +zhSV&AK@pUW#+7Eny>@LaftsMp2<{0hNV +z?B!8bMt%l4T;VVWD-UBDG_S9SmA7z2S{P{6>ra)OjewXEQ)>=$=<%s79&#Fj#5}EJ +zywU*M+1@`|aG95#&Bt+Im!{FxrGvQk=K;@4VQo~u&e9!)5wGFBPW^Pu70zl~_T~FJ +zC-rUyJ;*-*=Oe0}|NH`4i5JRawI4p27bzifmjYnl=bYyxX4GWpsSaJBzV2CR!1)~6 +zH_bMPB!Tv&Ir_&N95T>Ce5}EyB#rDG7aLD&$l(7Zcopxz68xpy+t?d-A<6+h%@Gp(IkA8-c=R)d(^9(Z8eK}z4 +z4)(r~LEybCGwKk|?u3R{^Rn~nUC_&x%c7@E_nS}?H?2`(Hz*#C2}A)?(_1yCwo2*z +z=h_3BY5ru?_}`c~e96;7E2%^(8!!yr#W8Y8Fd;yyPlcXXYf{M9lF&H#T!vTj;JI9? +z8(7WaK2N&<5+pWn;;XcdXlgBZ-Lyp%UF2HRUY{=ad2o^hxlR}fL?d0Jw<~oM!h&3f +zhS%T2rtj0cW@rgI!M>;~Qi34EP9vdrLY&}iKfYP=;egI={l^vdb|Lb|VMF6964bX_ +zn#IUQV&zX&e`hZjQ%)G4H&C`N<4#KvX2Y(ewY*UwrA(*SA)!XGSyKm=k=iyl8zblI +z?z!MOYU$}vw8tV6FK+x2>s@|E{IwEVnc+t*nfGh~A20lNdlNST^!g?!qS?hH*LtuT +zHXhRgc;#SPP}?3Ks3ZlZX&&ojaGn0kKnsY%PlYwO_qQJ*S%s82hJ!=P +zkuuB3n_KWq1&zer?Kb +z?TLb7D(E&Jp`N#HZBv2~o{F2TmqH#*xw}kSb>)*E?mR_9JZL`+rJg}tj#SC&!NcgJ +zfeOK>TwN)H{T~M1&201gteu$SUZE}4iP=zg#%uo_fuNfpFx0lUBuHL>708CZ`Xh-a +zsIXyG*}zGb2SiE+648d#KCyq8kE1#4#6JGv{b%r8%PpOkV|6t8wa+TnxvQHbnvBhF +z%*PAp+RMPH1~+=d{7HGHVL4$lLEwzbugDs-bh)w&kE$Q{bDmb39yk^1&EX6brSRBw +z5ufYCFx&rnL!TUg><^OfYc(+GmjfmyZeYlq-~+Yxs8(pODrYb7?-*Wqjy(^nk6;o>RoP0YR-dF0Mt%|`qa?m#ar(*wIk16Wv +zfk|CYYg3;mQ|$x=gKS1bt5W!WJOJtmS1;a!ULE>j=vS=aJp*oRngtGT7%qe9q4EMi=04qRuTvKukLc>c>6OYqJdfoZb +za!8Vo9xxX^JT>A10ln_f3P=_$SZXh{XsIn9+PJ54zMFk}ifWajJu7wbuL>piaoj-4 +z7x7$${0+|QgINTVd+pvB=8{UdVE8E7q6D7WjR=YWYTf)L%R%)K1!~GjSmgR +z7dEs>i2I|55^P1UgzaOjRB%Vt^+?QpdDEYpfBAWnW^RDkWD7uD0eH!?ZdRC(Q$go+ +zt$S-TA`z$46v`vZAIl`_>cK}oPGMbn1LA$|E`>JS4a_C5NC4g`8gP|PDf-mET^P;d +zK~tdM8yExJI#emyeNgKT>iFIlh8*9e1u`f;#bLgtG6*V`rc+WRkF0>=K36D*$Y-TA+jGAP=3it$t2 +z(c{+KIoIO+n7`%}qin}AFB&9fkHF<)vrmSD2HLk6RXZ~j4NPWPJLd9doHtV`<) +z!JtU^d{lf@2i9%HtCW>WRTfU?%9t_m^wha1yUC_&(d3enA;ZTY!6Ovp3-^P!|F#h3 +zlv)}>&kVW7vQW2}dkyc)i$i5qBkGE%3tuu!3|6(s-l8#iNXr5Zp@HdDIy4 +zM>5}HUCEcUTP6Wk-q%6IdmBw=N%Q)d+-yK4ens2t?@_D)b2+~e_Jn5et+a>28|sh +z9-7cILwpiQ1Xn-q`1WYb2a@HE44c^Xz>z*jbIIaH|Dkn23V`gV&uOdTh1*OSWqEwEzh(KO&})6-`kS +zF>sjjFwvTgyG;Zv$yqYL_~rvA+Tb0AJJH%T({;}|s;}PD1cPZxWO}|%cDn*bhx14u +z49qxyM(7-T|Dz0Fd5ioWR74qqkDVl|?x`48t;ZN0WRN1al%YTrA&?y+!T{8HY5nlj +z?I>&Y<%gHbGuE@Ju4WBF^n>1jDq4W&P +z4zMHIiI5=~h?~eae)rug`I88@A@0rO>xSN^l&9iG=-VYGkqI(nV1JA{{BqK(IH1H&@0Pt!^_8wvt;t;fhD@81F-Q}(gH +zi?qfdv6m)!z{9Ki=I4mR7n8zLaTJxPO5J+?KHFESiyn*;MvLA)y~|jwFC+pOX~+HB +z&~_TgZl0NRqoyINasPzLxTFw~5{CHb95yB8BN-fb=CJ*79cE&Jy!T&VZ4t~ZjYvaM +zg48a~NpWkx#+=y{-*ll$#8|Yu#HW7fE7#c^ChW@ef~97})v%r>w!8n_eA3t00dbNp +z@N>6O5ehHkYsi_P$y&z1BuQo!!+xi7PC`X8D{sv0xWokFZzUTuiyEyzK8f>9h~}-{ +zR-kGMwk{L+UcXu_26s#kbdcS9fmdQz}80MV%>;z^wC-2qZ#%>7%g)pwu= +zoxNkbqQH*8iI1ftAJnSvQGVaZ!n`enz%`W^_Rcqe6-Uo6%z(UB+=O%FGw%iN?}Asd +zf!=b2zKY~dniN|(^l<-8gOiB1T-Oc&pmRi +zid)R9t>%^Cmjfx&` +zqaLu1si{S`ZVEayo(f(%aZRRF6h0s!39GM<1bIf~+m)Sx@jIHmXvVNrk@3(#M +z>@Nk&i@zanZ$W@Jzbo@j^J%Jeflj+n{qTsabg?CmdE(nz@tqX8000Mv0iP{&LVo}R +z$_y~Qz(=qK00@3`@GOsV51;%%Ml60Yo7i=Hq?JB*2YhwH9+8ky%LPC&PCl61b6VmY +zVf$VuNeZ04nQ +zs!z0u9C1_`Ty;T@bckOmM+%$(e1H8G;h^wIU&upHUK8FpZx``Z3*W~uDq^k*E7tOm5QM%gdLWild`9OhHd4U>h^lmJv~)NGD^dTZc=@ehx{8?o{Ax9=@m9^mVQvoo;m9&-AVFi76GbcgEx&#Qja +zQh9)0Y~;=Mt~Po^@X``WW@R7-u`s2EFmV5<8eri{s}p5lz6AiYVEIJ^y#KZvi?8$Y +z#*-x}nGj3h!~%ZiEc4ivDbVTh!)~BP_JAiU@q<5JWm;Gs1!mfzL9u@}-K0mTs}n-H +zqZLR#bTPECkP5`#zunAG=N`<4Pz2OiQZQ?jUe>{x@1x!^B-^mMNq5s&HMr5hZRJ(Z`Y52;K@U?&;q(AX$X4elZ3V?)>oh7iS#B{vr +zffZfDQPTI}eePINRSoRvi{+B(FiA)T+`ntltXRE)QHkjThGu;AYAHQ#$5lid_X{C< +z4>pg|L*^y<>-*9aIO(&6d7zt`j4Bzy(t{d5x5_EZ)&To^ff +z|H0ERe(CX7fPXnFS?#K_=DU33$U{1oSs$I$ZjutBpQdEmJ@fW?Z3%Zy$$gUS;5{Or +zO8Q6$BZq%hojUL;PEl5!`ICC&wYv;#_aCYWQ&?Mb+CMO&vWp{pPbB=snhO`!E}o^p +zo;IMM?_yeIfF(4CaY`MbX#qJUzXf{;?!*-$9jrOwuSB(Nyff#bPP-r0zDjcEUi9P( +zWD(SNl|v@>uP$cNmfMVL>u2m{2CNhXAb%Yo`gok%I@Sz5sV)Ca*Lp7-1PN81KQbNO +zcp!~A{aPd)pZ?9BeUP=klQ%;f6PE#gQ6A8pgv(aTc@-~E%|$yUZ6Y*RBR@7=Sk!F> +zNN{xL(zAN3x8Uc%Nkj6En7MJ>zL(3Y +ztY-#~#w=v1r1YS{T-~foE$<>k+vTYKvgm7)RlAUNPH9aZcHo`2WR28q1)Et?pH +z@-Nbf+wHI~ZbDk=fLa*~6J;H)f#QWPkX1;dUe0(lt6Ke1lOf|Jk4i|WH(wOD#ky9^ +zyYAf$A~Y4Xn?CwTR~Gc@Vby%>Wi77KzxOc)@p&1~Fi|!JmPT)#Xz@|#As&y9Y+tX% +zuuqkVBSY^P#~TopHeP0))xe#w6LZ_|V12vCT?dU&&FIh$OWTWQ{EM4MCH%;9VR2$s +zg3W`rDJU;qRgaIOmPK7v&pZuJeukCiVN}2)bbK3|uNgd+Mgmn>tQEB|u=*Lt8(d+s +z20RM93`_uA)jaMTqo-9AupX@c_`$@U_f|Kk6<9*c(6&kA7?$#}bf{z;QGz(m8kiBZ45{e#bNFeYF6ZG& +z*}+#_>2o5VI(l^HoB^n1ajf^H~}SsvYtWWca`6L`^jQM?(P +z4OuKHQFnipDyxTga2)fvVm|zP2?chO*^>X;h@_g`z0<`U5f*<5DtH)Ea1oSV5cuiI +zNO3l^B6rFGm?+kYr4N0}H#)BU(BYQR+33JEyvq*KZNJ482Bhq5(&PC}Bmow^vy({? +zGT!y+{>^b6c_8k_FYb{`B{@oM@ZHh*BHv+@w7p!NW0N3Idql^!ZQHgzJGO1xwr$%x +zwr$(Ct!z?n@*#iXcHKJX=|+!CI9GD>ylOEW6$H2|n%Or@R86+GW4J&1(}{gv9j7@n +zv6hh~Q0QQS>b_Y~x+bSMi+jcSbzliA%dMDZ^Jg`#1i0>B6bAz4(f{XE`0;>Z6 +zHt%4eKdXRO01msq~(dX_;KN$XVK2FII48j2X|d6I)io80&1pFZAB{iK@*NXoC0t^A)m +zw7Y~mLiiY+K9Akc-R~|-ypC&a!f(KKrT|QPPvU2;m_|Fzdf4)5&`wphW+%C69wxD6 +z5iZ0TPq$vogX@WTB&+}o6G$~` +z7Mw?|ZDc`t;YWT4LN?!$hLN#84OO{_^|n}xCLgOy_5MFy91mlmKtzGIUL9<{+p6i;+5 +ziMGW;^gE$e`QzhDHF7@rMa-8DW0q{(gS`DEA!DEflA{Qa#h<;;35MbT`L2_luO|~# +z-{=jBnjpu-n+y^3oyPAeOg=oI<#EkkCDPc4Z6>fOU3tX5P0`M1$tfJfw1{3`I8jH9 +z%dYQA8ox~#?!pVhckL;?)cs%c9vq$wENbm`er|gBDy``fxfcA~5-IUI(_Y2&l7K3! +zMJbnBiODWq9^rhH25$fm#i@xed4>1reXLnDAS +zs+g|)DmSb{^|80m_IlJUjX&pv{COVhMfn>Oz-krP>>pDhqH>Wh5B%Ct?N#*zQUQ#Z +zE>Dj5CJe>YwO#3PhGGmh=Bi5AvhMFuTbTd*SDA|nW`WG0F}(nmSPa|^PXEcHgDluH +z8Hdcx@DpciRo^1oqwG$4p)x1alUCV*7y%MnN|8?VO+vK5X$5@L4rLxk{Ky>^$H>l3 +zsb3VQ4pFg9wS^zn5((Vf!xq~IZrdmxRXh8+Q|qbh{95V_+eUaX(%=8I|G@mxF!=y+ +z8WY=|+c#kS(dm!9qz!rHwqV9O7~A`)W?qR#L8Q2$!O9{+iRPn_h{zIPPqc_*rY@Y% +z*3vEWVat>%c6~6gs21Jk+<2$sOJygZPeagIXw#V;UCrv#u3-LhxLJB5-kUSH=RqJr +z)^yqk;a<3HUmnF!cjS$!bK$u((1J>~Fi +z`{~LWn-%}5h*69;J?ifSiA4uAQP-&Xa>U&G;#!hzHP&U@AB;8)O{7~?uXeC}TjOR5iyvkFHhgKk_-E%Xe>yAr+*IF< +zT(?E*`AisYS91C29xO;L;KpHB+KvXT;;SFKs14u!tb+)j^Z;-n8k1{x4<N3<#rzMP}&+%g`Sv9iLohu6yNrw0o0DQ-1 +zc-_WA0c7%Obtxg@Vp}PMMUA|)&{8L+YOou;EwJ(JoreIq1?00;i7zQ9rkzBJ8#Q}M +zml+*S>bp4CwW|e1M}9Ie1^NJ+(q0#R@DXwyimqr9!g<!lj~Cq$0+1s3*1INt+ZO+pvW=h8H*`Z}ewm(2lMs_u>S7zBECr3Ze<`K? +zdNji^nhGeFmHOpEAp%iboX7a*C8bL{qNfrX8|E~G)9(CB;by@smjB1YV}W2#{<=)+ +z1JhR2x(>VEmG@$zF`2FydZ%P*bTHw_hB;Z0vRG9du4JbBfSLPB0 +z&kT>E0hdBvWR&-~=dXrT{uU>5%65Q!w7gL9%qQWC*rt(`vk*_bOTK3r?&l{VSyQFV +z%y)(g2m9`%b=2z8UjB5w>+d4NerM^Wg$5nEUgp{MnF|A&cf_u3tUBH)Y54m*2PD35 +zyIg?k$g(vs++B|0N(;W2z+`Q+Zx*jj#3RD%|E&b9oVaCoj%+#=-&{a41{2wb|KKT7 +zqnX(-R-|bP{`KSsO0VE72hi5DD+Nh1srlp;T{W>rO(qGl0rK@1D@T}WOuH_00OIhr +zk|p$J=|ODLp0*@s# +zgQ)h0=}9vkqD}B>WqKrMp+#*Rg?+2Oir(ReQ0jDFmeLe!)WVN2@ +zTF%3HwisVo=2-fl2P+r#-2$!*uyBm6@%2}@kDNjJF~OZLt+7;v8$_+nt+dQxDi7jT +z?(#0&UzruEk5CB0YuXkwHqe&}2iI{_HX&^8<4bLmG0Ew`*8A=C*wgB$8pygeHio$P +zY!#Z$SbG01IY(#k$o%t7gNpl2k8K^D7#fX-^jA7#`zSV?Sj;p`V(3S$i +zYF$tFc~G~9Wtm8mgZo6zt;Ujyg|}xjGH?<*3vM4JqTkp2wy`iuFFptANZVqvMsIq^ +zL)?MyWZbhX7hoy+io~7dBJ8T2H88P5`%kAP3s(35NXv(mbp^QUr`hpwl#cGnJfU=0 +z6&H?yj%0IfIuA711jXmfUhq7_#2%K#ToW_Pi* +znu+S!Wc9h$mtRcY@zX3k)#>tiUobBGNx_$vxDw{aTwIdCuLN*6to$$4ubL&)&-?B{t!-LIr=(DJ2N@0;LlV< +zoI%Szzu8PFRu#X;@jaS<#q$l+kj?JkyN31gw;&kUK;`8Jq*BMczyQKFi*GHn>fEA& +zenUgRFnjFXEH*9t;UQcvIt +zFi1)xigTTo!KX^p9WeaZ0@W-xjjvV=|4QyI66W?N8%Ia*9TiEWlKyE4yibYlY;;}* +z)(yg7!~Rfr6@cUn3g;h%;T_Rg=AC?HdnSyfU_IgMu(2YFbou7T+!?3bkn(Kv;A)vf%FQG^v4569FKH{++mo +z30iKxiF`Qp^H{FbH76eW>>qN*_aR`S0~a010#^X;ew!%a{gh1H2ahz$xy~o`@xfHo +zB@B{(*!13`HV&ZD>~7Fm)MDSRh`A4N^w7q9NU;Tp?EC71*>whGe03_t2$tblzyRH1 +z4w)0f3dFa?27R4X4Qz1VbH~hydeIO5jeSJ`qorr3p!Dbv*3=M0m+lP&B3Y$pU?G3A +zk#U0X+)}=1HyQ8bsLxMvk&i8|Ncca;2O~gt)?>h5jRn+z&)Hnhosn>YBPseXyUlTZ +zea@B6eOq~F+}n~ZEXJkav`9U82lP|{{;X>80yce{XJ^4rFR~+XkDgv;6!`pwA<(GaNHlMQ)Y?HS~w8W8@iMFwsCg +z*aBiJcv?C^Sz)cTx`eg@=TJWLmtvx6av7F(?6tMRjbbED=*G-sod{#lE8(}VeSaz6 +zi!V7?;CVNr?gdg}hnvxc8)j<;W%~D`{Ht2Q6wFinUy7~%f)PLo=-UUvr!ju@4c+WE +z^!`-K5QC-NTKOiC;FbJx?7CXSjsqg4`O!1eMHGYYBwTDpq1 +zYEy5uH8Rr|M@v@pjmd2f!C%6ITxSsRcUW1Hj@p@=OZSHwNRo!wR9F@6@8AvjEX_rNyPG!%j57baB +zNo{}ArmWh%3}#|WTdVy@bESIwL9|g261L3Dl!DqZTUNlT1CMD0jx6qy!L4~u9@wYu +zGsKRHmt9t)?Ut(rC*N0nJF|qh$ps?;PXCd1_6DI5QMdFyKEP|Ax@d9n=@cTrOkH>z +z-K_`PA{giE!&P}}@JkV(p$GMGFhZdf9%+i7XpAAJd7)U)%AmB!>=k|`L$ZTIu%tjH +zH4z+smcR~2#|%C#HsN=>G`z+<3XLZqnozG25#IuzeH8Z6Yec7Rg+$I_j_RJ|J(8bn +z=CFJv8FQSd0=QCCD@zjvS%@43rkrPIS-Gx_A>9gy<|D52?`w6?CIr=CtV>BYRd~2S&7uwobF=sY)$* +z%wYU`p}15{C^|&3_f}5-!OB96JPszJCp0PiXK6N=bEDlMS*#jO^G2&^8dCUK)g2Uj +z!xumERlqE@L0rOy3bVZ8tZindMSi#U+~F*SOcTg)D0D!wrIY|>LA1yrH5X-{debC^ +zA^XM6{vIQvgZkZXx0-FGk7fy85CL#OTY}8X?iBKn2AI(HTpmq>LyfmfyRQqKh|zLb +z9T4O1+kJ@_2F=7*IbhM=l6glR{;IY^gKb$^ZTa+k3-tE*+q+=~Uo^Zspau3)94))Z +z<;a46M3Al5NAD8j(OR$0XdQL?7bJ=H9up=4$1}1>IohIBhZ43ilu&#YVuwN98N_LV +z+6s`bQ(P;jPsohqs~p2|gJp!>0U_N;MDQG@0Pl<)@=-rUWV6|V_89lpqqj7DE9EUy +z04&C4ia4JuM-BzBC0+p9)VKLn#3VayR#Nzb#8p28ZV5r29MWiem(hjVgsuL-I%g1# +zGmkK4shS{v)wm^WgxO#*WaTuy#oj3rJpVZ=AFcf{L^HLvjH@6uW5J{LOixbLV7;AYaGSdhOh%g;E +zQ_8=h{KmaXWBcp}ntQGf`)=|=4S@QKH2f1HbpQ)aop?Cr3t$2GM`}+tO|ODy@|H*; +z?P{L`P>Ex*s@VLHN;R$<_ho=n*Vg-<&c6F9%uC0qBQm!8ZmL6ygkB{{pjGGPBz2); +z3Fc?zqsv5-6%eZckO+Qn+@#uR +z6zbl+8Y7Vb+};o}_0BTPL1)?cQ|an3GgPAWJt3QbV3tGG#IVCPM<=Ig@4f(5biE)y +zD|(1m;BxWQ6#9`r_%8vc&(8r8SJQU>J#*0NxEa`2@d$V6&;*YMzB{xos&2o!9-rv} +zulTxm^RlisTW5|~yRiNs^jub%C4C{l7-I!`ZVhR@B^mo-d}bklp+Z{fS=?arZ8*b6sxonQ^2ppRjvbNpB$#&Trrz%cKWAq+~3(<_;ixi93trBiVu|sWh +zdY)v~A4)E@iowjmaU^E*nS$2apvgow41j%U{P@ +z1S34OHanig_zg46ib1MrcVxd%C!DB;Bpy!%F#Q?>wmZ?4vT|*)0CSvtvK}bIm~%j2 +zjxfd+Ml?Qz#C12t_)<`(VVDb}HinoZXq~qj&~m{WV!o_9&hx!h +z*0@~7*%KrWPCGODex_OEEqq<4oVpf1ywIgLg0E^m5T1|Lfk6ET;o$NLaJd{c8H?N6 +zwM%y+uk^bcTQfX>WZi`;yOEH4E)(>f*yEXas8fa(ak;t-m_}V0r`P+{E&jq}o70p_ +zI3PD@t7CTS3XBa1o`rUV`~QCR`G9#2|H0hW?p8#}=KlXM_k{|nT~r>Mym(-WT@%$K +zA>O$5+@pIog2*-drDzc+*qMx)%I}6IYzUJ0?A9E0lQHQdG~({{7HnSTnUM8+JVSco +zb2c?#NB21t+4hXC;kv3@Elo{JJBL!}4lW6;|3BO^$O7K@%&mpTw;cccQPo%+!Q1{V +z$A3~9fVI+!;id=CeL~s^Yglhd3?t|@EGO_#h($tUVALWu@s1OS+2UWdxl+C19xq9Y +z77hB;2JCKKQ%)~F+m=BMAhV0ffu22sGQHFz;NfYv>Ds=MCozv^0(z!j|4+gEPIWY% +z1c%)Qg<{$xgWR*P*`W{oF@ynjfkv+Hdu?9?U{2s-x(^JyOK0VjfCi=m{N|8Bux&GC +z)fkFc5qi!w@Nods8Eh4B@vgw7K@`=&PUe%cMp`g55~jX`F|Arfv-J@qoECqJHo +z9(q_YK}g|kyJy!36k1O_Ay=+M1hzvAd=+++sX;)nI0~}Upl`Xi?LfI+a}4i2Cb)nE +z!(QfhFuKRXT~~WJq<=gW>3jjY6yk5>2$Us2qi#S_f2p(IPg6CL|1@-93zZ; +zz{+Tlcs>-!=;M}nwR8epwG{_31^oaMtKk$14ir}LE%ic>OplO6~UTjh{cQz5Xp@>;u`E4J<}+2iekrA0iYawM2kWwEI?fu +zaw?g%Rs|9FhM(pfCe#lxqx^NM+1ED#q$;Hn%Dq>nX-75FhC_w>M%|bk=U0RGB{s59 +z9LcE^d0i6oJx$qLy0C!LET5HaoB(OGbubohkO_V=U?3i?A+CRcu!}p=ldp$81IA`1f2jTk +z_Nd4TPzw-%tSvcb>T%>3wax(C9z5Lyk|ri3JM)VO8=SpX^h +zcD!VYF^_7#EY$@;&fink4}-V!&#BZL)k4PKI3za3e$+E*soB#H9Es^|=8c%IDqv}> +zN-hlg(ZP#XRJ2Y!HQMDR2MD|jDL7LZx@8IpOAHoYN-DCK_+!d+gSl;8hL;JDd_tfU +zvcAMtWE#}wtyOsno^X@dl>I0>rLYG3Q0~J{aX^YBc^o;P=3nTYs~iI +z1=q}a7gm)OV;BbMasRo^)lM_Hu()Hbhl%FsdzTbE#!Osb~Blzx2orXjdJ?oYNeP#fA+dcL>D%XQP-hKX(GS1-!*y +zU$q(ZRVm;vL0_#xrFV^DT=OvlpXnei3M9{jQGY2mlKYU?yp?{~&{qjzk9G$!eMP8+ +z*X#21_{Mj)d;McvP;pw-tp7rSBZqp!Dpt- +z#(01;`A@A6X$G>^YlX;>pJ=hI$&tR5{MCZsqF7tD$83)10I8!L3eI$I+x)#|viWVt +zpfi1(o0PCu)tgr02TA`ml!d^PG1k&5BFDjIBwLqp3f1#K$Zx*FT8gg~lf5PaWr6Og +zr_MJ>^JiRW+XNAtN=H#0eLqE}r)zt?+Zs&`RiucRa5TLO1m_9&T0{_n-U2lB53Z#8 +zc6tChbeBbF5R&sT)^iFDk^3ZMTkty?BY46Kf#z?7V338aTmAdy2h&BoNmlTRqS{9H +z4SN$t*ucv3kb123BD4&JRJ2|&>&u*3ijF7O?E4YdR!8qglPgyJ!gW4TB_Y-X+l(iP +zpNcm7H<4f?8n#Ddy*-N)_T7MPko9UUhar0iOr-%C#Q!Oxk1B>vCIXwgBvmh{&(dEC +zBo1pY+=Y>_5Ge)JhXxRQ&WBz!tuAG>F&^#bVr(i%8$d4su1!M<9=cvj`?Ngi#b2W& +zL&k}-HbIt-Hd)K%4bH4oF({`Owj7vq;~UAYJYY?{hfzUTcNL<(IEEQD@4qk6ya4l@ +z{)c~$NM*ljzn5=hQ}%)Iy74ZwyZ~WKz%`a@q5YUi&wMP7EcgJk=pf!#4q4U1lHSdS +zGXgR}Y(3&D#|`<^`$@TK6&gE9_2H%0K22V2SUkq}1EHlU$Y%!A$hnPC2A9dJDfA3f +z_dioWx5TTP +zj_;rql%n7iqgj1x)$JW+<#D;5h*SbTykXeM +zCB}O#`Qs>Zstx`Or8(i;X6ue%w2g!8Y67)?AA~GLjOJ|w5qdqC;o;(`MU+dfH`KO_ +z>3H}grqD%-jZV6JbYPDxpW;=7-^ei!#|4j;UJhYXKk4a&O1Eq$K+*CkKaUz~^)WvX +z(JZ9g0kT0ry^76CB8<(^$27lNF$~Nh#X|U-PnU}*$r>^A0xX9CCu}9V!(PRs0zVYo +zsP~+rm-l`2jqS==(B?OakHKHtI!59_7C>x88dk}`q;Hz|0hR2u0W-D+1@u$D!HM4S +zft(5{K!b!qfUs!vD)nH0D2{!f#X}28I9nTi2?V==2Wc_}VtU^ge#-z9V3nK}(Tk5> +zrHFngNYh6Ofz<(ZW`m_vPr&TtpdUbh83VHoEWpq^2c|vnv4ZD;ys?Cna>X(K +zGx(-&$qE|H2zdt;K79mEi`d8)+T9loJ(fdL_zp$qecPf%NLlxLVci-lkUG-{$jH!G~)x00JHJ_x=H11Dt9=0)&NXzd;haQVMs!=v2B~`@(N+t +zR5x~tPzOIFsL4_&+A2hG>F-w3F9C$uNC3NqnVG;R1(qJfgnBuqav3 +zh`6STbD1dJhu*KISoJa%#*cfHaUyHsVPL+P@nG>@;wVO24KGm*s6UdS{weC?^rO|I&oZ!8U~%9B(lwwR%_ZD^cS+<2%w>Fw{>O)@T97r +zE#f2g=dGuJel3kd)>1mHiW9>PwL8AJ;29EsF6LkuGcc~KZxHt1a@YkU@!C{+ +z41gBCa^coNN0y0Fr6g-`3+356%p}3+@|1pn$W0zK6hYbJ=CS*CR6=#NH6U>~n{AB{ +z9oAi#l_!MZI?!VYwRITs|;s!ZCw{_n1Jm9T~5q?NY9Dr(fD +zs{pK3Fq4DLQl+`LiQ0D#{>UWDMTL`}Wk?2Myx*am#A_U%8_#oL@-T?CdMlw!J#4rj +zD}YaMGm&Z5)PHz1fW!hhayrV6w8-# +zpL_z`5zK$vdna#Ee)s&vWpp3*$4<6#h)qL=j5a~72t~9ogXZ#-_5F^}u-_4)2uro( +zUVcgRL#O$zlD1xwJ@rXEgPC#MPYAFPhJC^4{L=H+aU!tf`om{A7*gX;0%(LEV<=TRcz#tB+IX~0w$lrU6Z*k{}%Trbv +zc0iq~%B;HR-DN2{vUJ|MhTm{k(Q6xQEni3 +z_SU!I0=Iq?L(i2j!-Nr{u6`YoVjgSP2yUFuB~=ng(aJ&p!O21}6QOw=Cq2y9wuXf- +z2Rmxx^^8M%V%I`FRCZIRo9P>_b{#{3k!k~gSCQ2e8<#2 +z_6m9;JpjO>gFc^EE=J9R$>(gr5U>$d50n3n!ZuJ5(aCb0%* +z#-aClYUSK?*vrdb;m96&|I>Pvk%wMz0~LYUIBOS7oZ~hc0NwSv%q!jyAOvWFU|PmW +z6KdjA9P;=H!*voc=P#LLtL>bn=AqrRQ@G=n5;D>Q`t>C^-M$ofv>vwhRw1Ku7uw@} +z^yI6N9?$KEU!?Gb2Fou>{-#y-LTX6vu_ir2;R94m*Ph;*BGdYZC`NTaY4HPs-oyp8 +z1{UB8bMsfzl#>R~!=zxNT}2764#O^XirqKoFm)W}YLlN?-w)Qbi?>a*N!P4f;_G%H +z3kz&d&cz4|w0DAZYO`Ktpn*0PclBqwHA +z$R89sk<&ygSyu@6N5n6*&}nAa?I_?Fr%uyb8K!?VY*=@=kn4HT0996nLt!amwMqXJ +zR^jj3B<(=MWx18CI!gfchc}q8#d?{nVWk|dXKnRD)vt76Mv*7DGI-1)w9!>#4?5t-8RVmyQWE;k9OFM!b5~%fnTYdm)S^5xOhXdk@do$6j_q>Gu%n&1_ +zvS^^Lxx`%{pnDS-ySL1l+u}jUwX$Zny)Do7QrZIN!N8YnRWat|NALUl64IX2MRNLz +zS}0X}nBE3KW=LaSS^${q1J03iN#swgqFt)&*<*QdgPG}nD%1C+lP&#QkhdngavLbM +zuAARR!C)Wzy#|rMbustoLfNzy`5-0P=qKtZ-nSgxqAz0~G=q|@SZNk-z= +zn&U#cN!{*&h8Kyp&i!3nh*f!s^GJd)h+w7=Cz>d`7dNwN&cP#{$kp-CGQFbfbNEnZ +z821wv5@h*IvL9#rjwy(hx052XJUn|;jS`h{%hXJ=#O$gr;AXkVu=#O?%7!mHuwJzw +zNE?2U9b=e`2s%MrS^KaRGWwii}Oy +zr-@S$v|Ba*$}Gwbs^O+^TMZURQ04Wkl8M&`9$#f#xP*3IvmkibeL~G61ZswF%u=U=q7-SYdA3IIw+@7 +z61?Krz@STHoL7O89@PD*Av|8_uM91tK0NV-^mw>;J%A_jUB5a&MX){A++ftdDfq_r +z&~u7w9KY&3o0ka|^%|JuL#9S+LVz~PFD7;zXfu;qBb*p$zsy;z8D5OIODaUWrtie! +zS>UUWmy?6+CIH2$);-uARnBL{q1{JwLg!|7x* +ztiAdo^NmRaM}z?QFf1hH&E|r+?H!5FYNY0#isc;IFg9&?cwO+xAPp}@xI?A7No!|v +z5vZYzR`I3LSm9tRNqHNZQN+=T>twmaFIjb_1Jc#12ye`gdaC*BXV9_a^iMb6Grhl4 +z+n*IBacu0Z3=zFt{7n!LNHE;j4g}IihOrGGfu~{aWh<#KrxCx-HkURwy8o^>XygAx +zHK1kCZ6)1xuf{OD->_~cU{|lwVdt1R+wQEp7BnQrYu0w>l=>Vr7d +zBp);{TQz5;U*o)^4in@q+MU~GvSd88%zb1y5>SFXma?ZeAVYnfdBQmIu&sMic-v<6 +zY0!J2%G99-p5_R%XoPuk4TPw(4Faf}c-IY-ZJCzR)uRmLH;Ea&kH{Eg^&z1>^D=Kg +z$y;E^!V7F|CJ5WIs?&PT74jCQM!u2pi}6(epVGVosv@2O%wqT7oXd@OP~&1`0mya+ +z_yI&VTUbjp7gHC|vZgjIetzsaQGk#XY`Q8jNp$YVbqr_c2dXq5S=YWJKTu{@_)AWlN?-YZ^@^LoQlCcfMz>rW5Qu?E=a546a9a$q*qqq(Sa4;zaE% +z5Wu+x6v?j3J}E_f9E;&kmU7*4+7s`lxwfb=aIz$>PFwa?bj0^3eYWOmohqMrPfa?L +zH4fG@;Sa(h7Fi$-?ZlKTYtsuEg;Jl}Odi58g-Jo4mHJC8E>xUD25Gtc_{lTjiiF#bY`~xcO*5ywx +z%HWOj1f$AS(|&GF5CIk+G{T7}#PW9pSDLbqqWSqjA0zkf!a#^FoaJ3Uaxqu(mxIWw +ztf*RH2X|e22Z>v+K+%s<7s6mc5^3cp*o89*2uS1D&!*U7>(=UJxc<(ma7JE+N&ihI +zV@u`@x9~0QR~VF>Ir=I$pX#4G4D-v_4y?D1-aYR-P31%%f}|=sBoSNZQ)hk!=aYWTKMBh_~m2 +z+g@Nu-2_0{a$vFnuJ&x6Nruksc~K?kmf_KMn8kAMABcp7bNIwfCXQ;bU60?IHayzh +z0!R1Uw1ez1sT06XUnu~_+U~;e-U2)vVD}GQHk(rT{u~(Xng&l*zB$2-8L<_j9)NPD26fV25v;ocKxtn+<4tmf)%8_ +zHxOfonKIdeKH4a{G-%B_x6Y*NR47J9*@*9Z#W2XDCvr3bdA=Zvi*)&~dB7wKluhP6 +z<5G>E;BoTmq=)3d`80?$>*U3TMHO9S#_-XoC@!MR8CnL4sJLqw9Q+l2^EQ^j|8B0C +zqACVQ(`KPG2WtV;;Im?1(SQM~H6ZOtgaQ4^QYpxW@--Ok4$M1gXAM3ZEic^H%5fNS24C<0?$Z~h>( +zHw6wbe{ouSuE+bbNXo$0fetGlKlLL>rmgXKZ4PnIk?j@Jzx35KVQICeY`I$ak039DbWeu0Gh6z)=g_}hyD?ZOiSfJj +z*7Li<{?kBks{o#_h!kM`h}hp)X#lZ1GRL5LPQ*fZ0DRd$XA}&M`wylZz1ta@`A920 +zJsIFv@OjXjTJN8L9n|4G)ca`kQB5?Wu6EmTWlC3kKKBlOpScq)9oy11=AkC8gx(}e?p8u9ke@{Z~|#-V}-P^!j3_G;eg@7 +z-!72x;l +zMOANe!yrAoaGZeo^g@3(eT&v7zw@ILg8$QQ%WCN>+%tj~;EeZ_Eo|fMA^BB4K7@Fu +zWsT$sRT7N_Pud+j`dXHMF39tZ{9wXzEIbo6#b`BPH+VgTe2{*7>OMyt1~!G~GCy2B +zWRSA$_jqp7!$8!7?F6J>8m_z|Mldji3c{o=AXp +zqW6%#RrmlF=na>k%xB_=P__-f{Ix4nmJ?E8*R#M%h8IrCS +zRinpm!Qu@zsAWSRoC9TnsvY2dB3F8X5AQ8Tl^9qtk-8GLhtFscjVCaTc+Z5deRAsR +zPy_}r&Zh#J)9)!L4o3M;ey)5>){R4n*uf7hiUrj=weKqEs#0bV7y+D%w~~QM1X0O)5EAL@MwUh7N>yUhmrk{3+`)uY@Z2Um)(%bzaY`xu +zBZC^e7JK}h+PSj=Z_BI6gy|vupRj}52U6zo-F_4mND#HBp~1N`N9Q&~s{fPkR)D(6 +z*HKIrRo&UJ?l7sJ7$7$0PJUp{Ec +zrK+t8Ywlm-M*!wE|A$#WHNI(URRaW%y9jxof0tLQN7Deqm@F4UdH`#xae^%7Xei9c +zO9tMzI%aKYPwn57DhBkQtV+>~|D>a*5{)d!@7LmgrA>U{=`ll@sAm82#tZ5vE)Vm~ +zlS7cLqn@l^`EO&_8xT>G*KcNZ<@u;Ym54rHK9iiwO;~^yGww&rMF~Qb|(IVB9F%~(32|BwOpf?jnnNTVq32TuzK +z(oxo3%a;2reEqQei;~oF2$#|Z4TNwH0>6ld +z(NYyhkbN82Gm4b}6^s>Ol2iN(2uagNQ5|)t4{Wm|QBHw76&XtaKy4E=TL?Q!i=FJ1 +zku`+=t?kJOFOI!~M0|hEcmOUXX5J_@S2QnqCm1~eugRNLPoW6NntbX_l4UF21k?`7 +zUhDJm)BF<%t8%MWF0wtjc-|@(n@l70dzUb{o_qnu4M8tJlC)g6xRVev`Zp5>_i<9} +zD*JbB$;cTl%po_7SNz$>I>?&5^J8`Z^uyYgT(L!71C4^I9}VjTSKpbDY3&+d1M^75 +zByWRpxbd#kY1F{V`3Pkh{Z;?395#3h0>;>pUHa85a_;>TwYhsY(hD{zU3t+8kC3vB +zN*iCXX71lZx@}MI^i3@0guj +z`^4_JV-@s^#7}7Wgq-J|fZUJA;5Bp1K%{Tj?uLypRwL!>^dc`W@j0j^Tx)>~#XK^H +z2svcr^y!^P-wCBTK-M$u){O}nO}!q(Mf(LSpZNjmsgiEQ2cxz)=n(Q#Y@iVt20hYk +z6T(Miw;Ir9#XwO=ieZ}&OoecPhO&j{QH0AFTQpwIn{!5BEX>x{}z&lKceOhIs1 +zecEEcN`VX)5Z7R$$vNo>V$)0Nt#T7wFs82K;KMsMLCkxHZBpM4lEFOhVfY?-%n)0} +zYM4(*Ip6fDcQM^1%Kl6}?jwf2=Rf7EqNephl@9c@I)w+va9S7VM#Tk{GXJ*FRDMVr +z@Ngql&~xtHrhHJx0YX3|&S=FBpMMuE48?!D_og{%fBtybG= +zy1B% +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 +z97}r67cz!Z)hS#_`Hc|KMPK6_?(| +zMf#E3G#SSbo?>kXoU3jL21Rhw2zvB?nTbO)${U?gtW&q&G;FT9K@(vb?06kag_&=l +z;yk!h4*&HW{Dj>pG7T}(+>5q!K~bHvL*NcH^F1zTVi8;Q8S4ua?ZsxpOD5?Waa1$w +z%;1DGj9R$?-=Mb;z7BEYNco#J5J{u1uP9w@#}si~Jraro%*tSiN^5eb8{$ZxOR?Bm;9Y +zC?*14+8+D`SrgXE4S*D(OC2WbgnyZ~Ir2~$$f^>#@Ol>AS#(z8umAuD`9YuBMHMV7 +z{{RE6Szqv=$7D#>077##{k|-@cC70bFKkNU&}ZQhf`qJI&KKST7t0THgh=&Rn|{ +zeptAR{6A+kx}H8=@~SXRpff8wbsE#`F&sGp0?^En`;*feL#|v(zhAdR={J+tRSoac +zYGPh>;c%=W*52ZbH`XGBGxR|Q=TH;lBE(;RD>{ZNjV#0!XQvg9``K3fI(`Oqk{IHo +z-lMO=zzwWp`ptXPF&eN#~})fqrm&<3g*Y@n&b +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 +zKt7!>lZ=2wx?P}J+LParE2_vu +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 +zs^*!SfgxNh8PD8Es+4~i!@MR +zeTo328jvWfUN@1N3R`c4I=iy59^f>QvM5l&!zKxrx=uXHj_#~I#t<~Eww!62aL6C0 +z(huAsRSDs&hsavwAw^m_d-qN>!Jh17R2n>>db6K0;EI`0+8YKYeM=y~=xfqZOT=Suxe(l_GXZrRH8UG#8T;I2tm_x!dO`n`6%|4Qqb452%P})^F>bm(0GZncR +zZnon!f-&wy?4IZ$^g_WdW{omz$Kv?!&?$rkM6hV=segz(eZ@#a4?D>S&Rwc!?aU`i +zEHtYn#xiZpCbt>~qMmfRmbKBVwjO}BkZA}37)WN_@&tjlW_;FZmrudH|U5`EfdG_RxSRs1^sMKH2 +zV>!R`B?-(8M*MQ@wF(6%$*$#9z}V*)@S29n7p(y&0eTMfHE&=bOE3tmHS~_}Z}0sz +zeD$S^VGJ%uK@e8=nZsPrw27=5U_$ENFDjMFlBzX}L!H|8ZY<0`nR5#iS+x47%plI$ +zPiVo>_dQSH)@O4dC)S~)jN)+K;FEU^UEMgY7QWUdSlwL_&F4;cR>9~E+>;~b)blZ4 +z2?nMz`!ZS50*$G5X|-ku(brl`4bR==9F@7&z41e5q`W3o$L5n +z1>q0y+Yevc=z%FJmC(D(*J!Jttk4Gq&{u0vab0j>h%~{>>u@|yq$|3ZeUqOSAK0#4 +zS}#jUSa*eOcjvCm1!bT=T#b<5vGi?(lvU&@!Zv_tgMWTA2$u?sZiIhVuQn!ngbBDN +z>4!iIR`X3H6HbH>0U{Pqrw)6)1T@2)Rq={aqBXY|$f@P!El@YIwGusnW-rDPZ=M`% +zQ|8C4A0xW_zTf*1P%`$JwzIt|6!No1gmUy79z+hD4E(G?%hAa&k8J?(4Sn67fq|u{ +z1gMaQ)T~5J&M8>z9hleIk2XHlz;oqrqxJs-Fzy&6l1LSKp4D#8EiUK`8r;5N)<2x4=$i9 +zfd%_K!ZQk4wUAt^CdOFYK{dJnLkH{v#=Rb7G|0d5TOMSUC+k^aDQ)r1h_O9%eWb;x +zTSg?OpuwQh!hIj4zp@Bd*5OH0T{3p-vQJ+|IS%De-)RI5Hk{Coy +z>w3qk7o|ki_&UGmkOOki8w8@hI`Mf +zw{_h&;ur*KV +z+J$JvOAo{l4)(cW@;#`0iox-VdV;ntshv>*0Z~sBnrs#o6po0?BE|~faHrjBmZyh3 +z%e8$3q?XENaWP*&T@|Fm=pRrQEdU?Ibn^KlL~hTVE#xtE4nmjhTYNOXx!+w+r2|j; +z&1E1xwJ7vQIbC`|?%WCNH2sZhnjch=RMr1JZeLrx7(L-hgU6-`Mt86JU43>+sCLuaPE1TenF^-LFXAI|; +zZc-XNtn=~IB;ZFq9oC3ve)8g-AvVB)&s-jE*R|Sr&i5Sr*J+)Wb~y9(s>y`F226S07n8s^5>z4>K7R1XR8jE`iL5U`fwtI$7Lfk +zmlNa98jZDaTN2Ya7_U_Y2*S=`)8=cnSOe=Aii_!eGK~B>D +zJ-n1!UGeLl7vAPatRNp1+&a!{n|fO`|EGB;lT3T^;*7>N4|<+?;5;FsG#qgbRc#tN +ztq-;q*m)c=3V{Fs2lzpr9z_)_EB^okty${a5gR8PSOE#ok=+IV`*s3YJv#5MQ28jP +zdaTNPCWKcfp>R8c6|pqtvHfSslJ4NQ4{60i13Q{bx9=_y71+vL*t&rE>E5a8cfYvx +z7ixhW!N~uDU#CB!oG8%I)ZYEi%{}El9G_1V7Fo;&>CKzGk+7p$l=@F@@j{MC;X#( +z*!i)Z93V31lGg;zp}k=03{j}@zRq1AkV}htsCE}V4=#Zhc+;8_vcc29k~sSzoUZFW +zPS(Fw*WfrMvZITX(sUFyL`1pnE&0ryunmq9e^Q32kRNbN28q +z8of7)7pnR3cPfyZ>gWV*cb|$teOv6f1VD9JDiV3omA_4gnhRJB7-^^(8D{M<6( +zHNV8_mGgCLdk47L@#;6vHrTjY-9w%`eRYSvEFYeusA`Z0h08wu5X(tRkBCg{vhnv@ +zOAB?pD;AOoqUB95n<#gWGIE%SAOGmFX%G1Bhwla1js;qznPPKtl-a4Ur1Sqm?l{%S +zG_30NCyw5bB2qlcJcS${K6c!Y3F#XOuT)2RL?*&} +zs>&;TFElDu3UIDg)ZUdpcBsVV2*oJD1XB5^%p!G8zsuZJ)-f*2UU2dmljr{nShnfN +zp_g27bJTP*K(aNs5;98+=jWe7J0^m$iPRDOO+LG2#hlPExz&eu=%-jtBu37T8$SFEM`1m@ +zHW~#FdcHD0MALV)vj`(-I0=ZM2=cvP_e>_SyJ#a=eY{v0?_EIaVTB|kTZ +z8@n=}3|bJTFEud0AAGz)LUf9U78(@mJ(C@DhQg8f9=SvJ3v`I+A}TaBB*`N}0%fmm +z1vRfkeX*e8<`+x+P|+DqwJAj|l}dVhHo_VjI^vJ#5&#*Pdf~zD<0iGm)3FODAm2UU +z_X?*vlQRl3qbaTOokr?ks>^_dGqYjv5j4=u9FmMt6>h!5+ihuWixcS@O2c2~SDlN# +z^0w;Q8|GIU7nL->C<8qZk}ma~R>IiXBFrR=rQ8J$qU8jqw|^o*(}BS$lCNocg$UK~ +z9cNm|v$q+vq5=qGi<)n6&OPrmGHTJ*-5PEgI@hJFiy3W9oV0R^;W1BS#K6rr%W!@= +zCwI*bU%NG0fwEC?{p{&zp&NM-E8i~}(SAUxB}!X1Y!UK^@IH#vI97FKsfBas_B8dL +zcPW0!UUGnbiadGmMl2KcfVGE0F;V=;vUf5Gj@tLxC1S>o{T9QWm%^;?${-1JPC|WA +zXpE)ZmTWrL4%LIYu)-t8zHqsUK+5c-6k77~FjU +z-9OHh`@U?ZI$k!4S9(4q*;)hk17bh^Aqp{^L+GuC06>Yk^QFX+b_w21q8{)^tr)C6 +zd@S?Q@yz>tcg_#HS$t5b_m3eIFocK0#`jsKA+`hL5!?BdHY*neNOlg?j2WzeR<01d +z`(wTWf;qSV!`_9Cwr65P37FQfxMVg+ +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 +zFj~-E$F^a~0KLct>?{C=qVA5}k&8p0q* +z!_yR8wb~mz-cSp&>#u+ZxLM?UlTkJBCUy8!$wb?g?&th-C?Rg>R)+({aF~vuJeM(B +zpDrx)qpJ|WK^=C%W!9e&LmNQ6rzPcB`-|~gyfi$Wa@-aP`Ma)wj&enOK$^)00sTi) +zXTs&wZ}2kOH1loqQ-|4sctXa26M_7()D-6r^w6P3C=vna+jS +zVzFD#VzQ3&HMCmeCSTwm&jlX#Z`?@k1DwzQW$$Aq-Kg?W*Y$U{t +zxYj4ydSEMD&KaD2)fu|D)J(|{5-9;+^r*CE2YC`E6|j-6sQy!4aCjo3qJzh?cb&>P +zo+F*0jj#7x7J{XrOLy?nbZYK;r?ep@h4?Bz2otn?@d&|zn<3kBZoS95t|wpJe^)(Q +z)t1<C!CKa +zGkOL+%pch#d*5OBYe-dUYvYxxs#+G)l?c00Xx2Xu3rTknPBuk2DNR|Phb{1y!Zft!1`msK8%8K&2$kj{M{P0O0h2_jmF(}Q!U +z)z4ubjxJfU6`c*7hRZWU=T%v@{xKt?$~4UJ-*b8x#r|54^9#a_e8>rDf}p^11$7EJ +zIJ8-Q75U}lWS&}L(glHcc+-Rbpv7plmUDg4J^56}Ks-vl3S`66tt{pUse;`Fq56P_ +z=1Uh$krzYAK;?0aG5!bSVZlt2|Hp{O48+Is7wZZDy2AOflW+mo2kpT{<1rQUv2QeV +z{#<@CR5=>33`$hhtSFmLNoQlzl+L+7S}rO>Q#E1X()blp8Y@Ij(acVMZGIScQ>Z(L +z_2ezqP+G7!fCxHRI#Cl5+uTo0V6~Cwvb9(1SviX%?VBTKo3auAFpV?S`h>m@8;dZ{ +z!K~b~_4R8i#1&kVL~os4PiIFXKNEf8-6Xm*lmF8}GIXUs=sEt*(ksNpRu*@->j0I) +zM?GIR?u-98A~WO&4w +zEh1e%lX>fM-y0@n=|-$)Cfm_&dzh6UQ&w3<@khM+6k3_k(|Q8z)Y*T04pLn~1MlyW +z8A!j&QXtiVDK_JpBb|-jh!uwRggG1Y)~Qrh@c0O|S*sK2hh_T*{B`XJD#mfaKD%~! +zkoXt25MXel9#>c4vyE2I;V@D&G=VI@SGfF+joT`2*g+xvh>C6UJ%xLNCoR28EHvoF +zZ9N~|AbA>3nng9)CA3gGM0R^Z37M}8*G@XAgql+$*f6vZy<~4tS*)mR%xbm_KuF1U +zjm!gk$?ae-v=d`Sb)H4Db~Z$~IT&*3ECS@1!Hm$G%vEHBNAx-2)Cfwyze0F}jt`cI +z6`S58kYz}0+GqfE;VbG(&^=X?^;0 +zv>Cp2{~Jboah4v{yNY$6)_mjsSr4*gH&Ya@2w4+HRPBL2Ghl&^%$0Efg~dzob$!|)*?HDW9G4akDzhdo@uj&GYt!8AT*(9joy$P# +z3IH{o>WR$5OpmRBP6B-q??U`LT{rB^fg4(mrtVUSjEL74=33lEfbSPqz|E+Leh=7e +zkpEGZIBX*mPqAmIMBJ2i*9}FfQy->w>+-LdE-ScfNv{VAEA539E6L@~=zW{_fQW1k +z@a*3S3slyq06)cs#jm3P)Clt#Ou=5P`zVXTJjL&|(j#GU4tVrNJ_Bd);mFT9kA<6w +zoQxJPQB7`_QQB)C-I28uEl;txVy2`<9ld;A;JIK_$3E|GRBhUx(h6*H?#Ee2oC}@S +zdtZ3e)l^NGbeLJ3&(cNimh^ujtpWuh8)nNfZJxBnd%m@kBWZ+E#qQ5z%0KFa5OqCN +z<*82#ZwA!jL-IvBGxBUbV2W+1@CX}OAy*Ss=|iEf)q^^`RC$L82L${2W35H}fC868 +zo76Xk{q@ukti0rzs{5~AH3O0M;RA5n*h4H63B7q>$M8~kdQ@T-b9?&QpI>$F+8It? +zd*^IGTukB#@6_*LB`0%iK-gZehV+$1PW!fgJV$|RjtpD8R3$1AU;(0BI_ELJpA%2H +z)vu^ZqgzLG+nN)pI-EJBQFu38u>QQpp1Jp(z`lD0-B)?+yYD5dWy|YWny}(5a0Fl% +zqGoNhk#29q@GKBwO=N((0Cm!cd)+8s^w9(}(l)`4hax2u{Z8z8D4x>f#GUnJihch`y61%uwf8g +zO#bRp0lOD~E%&9NfBsLJX`1p+hub%>S+-UJ%N5{wa-zZqSxYvrgmh6vG+ITqNn7#u +zoTlqW8Rg8#LZhSOEgJfA+fu_R?q*^BV4BWhr5IF-=Q3Jz;$7R(Wta$`-lvNQ2k`6R*m6w +z8v`FVk@aINrFCWtTp?M~EvgIbNHsvl;qYjN%V+vPtzs33s&cHw=I`3QkbBkC_gK4X +zM0l%dY}C*~O5uSFa9ZgHy6Q(A_ZnwDPY}J+Q$r-&G9{3l4`=Y$&b{~^0T75;)k#=1 +z@AnV_C@bVoLi3ujju%YIOv6}Rk4~MMIjz2Gh0=~Vr4wry=Z^nfJ&vljF?4CaC=c=> +z(?4aaUce_MOgH51z4yfDsVv?zn-KwlNeB($%AtY6) +zR;L2=bh_YUqvr-b23tzgE$12uqCTCVaBY)Alh8PyG$xuwy_VCko}LQn>-3BiZY_t% +zyg+|}i!#@N%8CJuku)8^0>Kn(P4_w_g)oYy6g$j$hqBSuf}$>awYWFPu9^w}>T4ao +z1cepNyKM^IFq;|~agJF&Z+Dh>2uwksw}gjUa{YHH>ztE2@2yu=Xru^I>q@*{ITu_$ +z*vjIR{g|Lf<1O2RM_;|H^1&6I&|l*B1`l{}~ +z0}vn8+TvnpBb*Sq^>W|gN`s<38lG-GCncliv{oMad#$2&&`is5I4rfn;$dlE~v8?$m4?(?|0|V$jhfE +zKN2AqpvzT%Hw6n&EAkyq7$toV=VoxCY-T+JUTCoBscdN^Gk+r4J5!1IPc!S@CSNWK +zgEFF-R*hu2eRFiDIs@l(x?{<$=6$mTso(n>RlgwBZE|HsNxa2+!ux4c^TKpA3|Rx_ +zKy{kt=uRmh$Q)gy3% +zE=%bWG?a^#7_5`RDQj(+bqgTfOfw>U>&6w5#)LyX@$3ob`KS4O;gA9owE +zs{6VODA*P=rY^4{J +zkj=&7j(D44=x}U+Na^LE;KbW)m57ovPg5gZHb>*Iywc!d=pt9I<$7P`fqD}a^jh>8 +z@xtzZxjV*Sr=d=)wNRFJiK81Uwx&Z(Cu~Bs!==INQ-E%q9>~EH+QI||2S5Z! +zWX30nUn)w>`YhT}M+r`a2?L;Ud`2T|136nYG&Q +z>_v`NoG3C#&oTg%+jOWNVFp^w<5c`(<6VBb~do4l<5 +zK<$u$9`(94Y +zL|0$$h810y*+jI_*%Z*4_QPXrla__QqU{3B!#^f_CHjNtklJJl%W4*<4O6wxaMq`Y +z5(6xqtNo|vp&^H()sa3m7E3=6qD8*j{~j%#5PGO9aRQC?VaWWDBGXEbG5$LLRaAOX +zK>*)R_kzUZ)Iig9xv>lw2&TWdoh+@{F`4D=l%|&Ee@HwyA+!%3=nc> +z*Z1siiGF*~Sf*}A;Z7H8*QD4BYsRT^gtSBPzoIyF;@YYa +zb|ntMaYZRaQ%I=&Zyb-|iAAq;jxlPSH!mYJ_<^i9J8WCLv9et1v}vNSbN4lsz4^`P +zL!;>QYgUgv83U`F?o~kyxWFwl`*F0p|>W-+M~DN!c7dG!`;`)?+p72c;f +z)h~+KoLUvuea_Rulk)z@6e0=$##^x^&-6-gb84Ah+>|w>&-AzfH%GGvEXqI7afaJr +zGwVUH*8yKYjpk9-tB-rn*-Pkmw6m+dc+`wN1Ny1T;P +zK`$il29L{H(z)fxGI^m3(8S)taj2V}u!mPNE+UIN2j|>^mVa$29xi%E{)!?Ykx*{- +zSdb@zPH)NoYH+j>thY1w@2}oHb7P>|` +zJcOK_<*Se5<;f(dCpvir3hKm(9uwbbx`HQ+&%}=Lwcu~#<5gD0aF@eSTSpup$*WB) +ztuI7q%Pmyibo1PY@O?A;_(s`O1zITrGf5^19U`d}=o3pA0JE;}_}H~`4=s@^#sR4# +z_yw>=N9bMU)rMUbxkfDOBCRHrm%gfCrkgY9^I>)XAw6Kn?Se-zK2Kc1I#_^ocMHnmkt@ydnuJEm|HYmTB`==LOq-udAp}b^tAIc(GPC5Z6XepLaV^;ih6qdMG17b?j +znIURMgoM&k)utVHTl(8=&1AEQVmF+O-toV`5ZRN+s+rnFE><$|mpc*)uDb-B +zdOZ%vPXj({a`OsPXVX5%#cz)>fiuK9hkp*1v*+*Kp*RtnF>WXQq@BGw-ReEa%lhfh +zAU)B|vNeUqRD07U(-%N6{fA&ZWtNX^wF97d_o68!!*q;VwT$xu3rr$D=*4#o7w)Nw +zq0s(S-G^q;=eLyl*ASiE{@|sNMXPuGOc5V;RIAAa!s`Tqhv +zDKjv-E5vAKIX^w+z8Hcxva=jIQVf%p*-`S$lJD;~gjPml@Fb%Z+CKV +z(TBkSFk6kK-a*Pj=?&!CrPGL$sgb2F;3f3}ICX>kvswFxlq40VWL_dpPUTr_>KO?7 +zsHezJvYP|5AK%^tG*OAjt=1>0UM{qnENH+6^B26Tt%FtqTib|5ZzW6Wa~8hjF+r+K +zJuGj9oi});t^c;i>Sp-WQ+J?)0@?hMg8E-aIHH|6}Z7qXjLwL!8 +zLe@azH9}`GnQV$K>H>lXNCXd8gH9Ndt@hzUT13lX=@F4$Vf9LG7vs>^A2krZHdL+B +zv01ZXLTL*j561)Sw27SI;KEd(q|qk>7{n80S|ZW*&o%@vL5SJw(ew#3v@ogELgNBY& +zUN;6*8!u@SZB-jd%_=lK +ze;QQ>Ny^unljSuhw?66~KzObfraVABciQaIcMnfMnqho4-~3?Pq^|KjEH8{veiSzx +zzi=K#`4=~=p^l&GU@i8*Mh3Rp3}ELN5zD#&`{;wg{*W6Urtb{~zaSi%>ZB<4)LIo8b*RTM>Q|lpEA<18lv-MKjpJI)k3mh&LDRn1H(?$p#QU9>)lX +z@WG<8VXMU7FHH^)5J93Q^wQb`ksVeqS5Y!L3+GWLo`>T1XZpE(wZ^@*`^LDdilR!? +ztJXxC_$0VfS&Jkzw7w4f#})$bm~3Fv*GR#5KMgpsJ|soL^ew0x`7-n?p0r76TBLpY +z3l(oYTx&`9S&AyiZNODT3EJMPy_~2HKpi$F)UTP(5C*5Qu*QuCuWVNP&VhFO;z+U$ +zUZ-EiP$uaZAzA5)-wElDEGP4N6a`5NHtCH&!)0$QYXLD;i-EJHnVb68=&)aJ0M=3$ +z&AuNQbFOt|2hT!2>BD(h+g74p_`_StuX|TKd#Fq@X)Ba>!nlxzg9F@)V86@6zK@=> +z!Z~d5l?b8l3ov@|IUyAcu`)A81YtZh{(w2wP338fwxJGe^M_0Gb~!--T7 +zVi?`$)jwTtPGj#qi|HLy-xT?juXe6GTBq~TPw1E=#`O+vDwA;PijDcI$J0z8;|uN& +zy4tTU)?7b^!fDlLT&eI=Bt0Ma6>xd>;`>Ae)X0MrZ2^G}%f#d&W3a19k=b3*Rg13o +zRX`qj7;gY*`?m$?-IGDFI*gu!3bs?irQ?Ts~$ +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 +z#3LEreOY)9tEke4eEVvFoar3pPDx +zYNs9;H_>d|sXGo%!SDK#S1RvYnTOFz)dLIqv^v2PQsXSKaPssW=;2CZIzf;@gCsY;}Ylr2izXjvkpi5TU0q-rQR1*b|$hDpvbU +zIF{psK$+1!3AMI@f+QyP-utYF)C@mC%26!vcsT0hKi*PkTd@nvRfLGwQ`JdXQCe)I +z>M<-qNZ#>P-zfkcNh@Z3S2(QbHX7)02kxI!f-TVizPO6FJZ}(N$P(mQ>PkrB*TFh% +zTlR+vs*rC`kBn$BQye+$^NQs9jA7XlvQ(LulOGbj@sH?t4A}68@G_M@BSgGt!%?lni02dUL=xav+ +zh1}YCZQfikaf}^5*R`Cj!$^;*%;En9jX-k0Yagt`J)~fF;wd}>4iC4h6qD#WkG;|$ +z>ZP2%`60>IgT#vGtPFSH!+LSNIg97bRRkZb1s +zFH|R|)h=y1=8jl$HM#+QY^F^zWv5>YXNyK+VuopJD?d;*S@sy3*zG_z3Kq25lDrun +z7*?%l;@uB%SX)5LtM@$;5umPr4CBJKxxFa;{P08KrNvS&nQc(S3oT3B=ZQq) +z6(qqn48Pqf^3+A;#m;7tFzREdy0C{W920 +z1jemq=gX~1uCDzDj2>L`1a75GT38T+zux0jp9AV2R +z?PbfCos%mjVOvG%Me(RGdi5<7fHq%yi-MP#`XcOZJpbcOl^&&&;d0Unq6c*wzx`b+ +z7SW*~DSk?=vKyWx+=27?xLCEeR>;%eypbroc8HYTj(fs9WqVvWMqMX(mD;xqd2gzQ +z`QF4H5qDfAR6`M*ooPPuWm>d-j`}B+vSIhv(Ux)&)_LA__&A4s!GGgadF++ad|`B* +z3aa(o=tbE;Z0pcv_Yi@8O}nU@B8;wkO)1wmfsDUWAD$LGj`C|xkHx*V3W(J)8#5r?GXREBno}@=r!K?bfd{)c;#J%fQy)#uVq6XHH)1M09;)sb-Ub-4jcFSv(x~l)ZYF*N +zP?RHBUq_cBdR%?tZp|z*?DhoCOO?lQ?;jTd5S>w)I`2vtMu%3$`s9j>r>Z*Cgl4u6 +z4z77*x{Qw#8J+~%wq*N!oFRG0GSW>Cxvm1!!8R$k=QLj$dGenwor71 +z*u&r>B*McyO!J23P%@-o4X?J?vMCIC3aBaK#jlaWEY79A&332mzRX`22o7au&3@1h +zmXuE|Rzl&$RDwNr42i3Jt~)^Z&c$s+0NA+yJq6nUQXd!vX>219+coOF1@A0d@g{F? +z5P~h0Ec`E={dUzAYUb=SotX?al^IeTtGn@ev}I;9enh(%x%<~A6nG=BmsxiZvq)GTD_y53o7 +z!xN-U$$3jCzUpC&s<5sG!k}PbS}r=4KK+=DirUwo6GXu&)4e)T+z}7uJz$*+U?BV) +zKn8KP`>&C)k00)lM@?PiWw6x|wX8vS$?%lc|EUI0PRpgyO$HjWIOk=@-bjNtsr_!h +z6?Gffs6GWa)BEg>qMSbp!!cB9YDG>IZc=&wvpDVd*5C57w@=kuhH{nXoFlQe$rzen +zWyWV+JSY;^hKAM*Auo_TuxlGQ&UI}Epia`i8Kvq6ZlD^I>JnVuEjy<7M4o=0{eNNX +zk=PJ>+HKCdrF%k#>+QiQ)S!hmizoBW*|(VZFKr=4N;7x*n7)U1&+c$!{s?$7q*J_Z +zjyXqV3U2%l!jN0v1azzYaKj_Pm{l@vS&Z*2mv<&sgzGFUi@jma|~dE^;Sfiv2gqv&l#*Z}&113>*BF +zFr%q;|4=S-8|Zx6g*+OXH%vq%1>NT!2FffdFsU?i<5E%^S^z=AK1J~U+{>NaRk)R6 +z6m#mlM%(&jjPg{LRef!?p+{B6s$_lR5*(h8hLR4i-4Z9Y78aFa*#Chnp +zZ61mozB-+HlmB7 +zyEDKLy&@iVNkdCmkh>3k__NE^jJRBE<}z(XZFgMk`MVoMX3|@ft?7&qfskJ?)9IK# +zG9qC6@rlo0QqE^-cWFNljs$-%GuN3zK7kFRRZ`Qt +z#~H5%pPP>~HP=Dgo7JUDSB1vK03t@ErJHSgcYB!~nUBR20r06>$^G~bcqc(7s&m=< +z$HrYvcay2c;o2FOcFB*D4_uG(fkQ +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 +z{Z&USV!VF~9E-u+#P!T$&~J$U1}0 +zOu1i4suggXXeUfu!jRih(D@rH^wP;m>u-i{melvd7tIfAcq=MMow<%O+OV@0 +zS|~%iy>=q0gj~h)RdkbkLiGNqoDvcWv#mwGd36b7M&V6EW2wzGl220^lrLlGFX> +zdz5o_+%SP0J~fXn@c4%Ex%FGBBba&&VR1xQ`*DU@1JaxuRJicITT%Q; +zcSx!cAII>RcF+aUU_Q0PtmCVH6Q5m57aF3TV5?H=?@IPs+(0g_`;uPeKEqkoIID3Y +z7#1AvNizpD&L>m2EB`Hqwb`~Naibc_;}rM3kjUvx2?u_o-4RBfzanMf&~qKazHwG5 +zq_OAcVn-TfgHX3ikO=Cu!lm>Xj~sLljnGfdUN1T8AisGngRXi7Wwra!Y)NDcyK6;L +z_js21q=zaXqlx%r(IX(UOvuZf~|=(j^^|aqkBr +zer=W$>CI-78cc+7vqgi@m?SRBbyF&Uk4}9YW_hhI6y&giBK`}dM7WY^7>tpw)?Pi& +z+!^a&av5P-q9+ps|K6`^TwKaK69h_l5!!bX0ks4I&#GWnKmB^r=cT`g_D*{&kT+^ +z#5^8H;U?DAAU4isevL|DOv$*TF8!eas7XCsas*sbLctc5;S~gDoIBIJobX?;Sz+Ne +z0~eg-3T|%lJP$lss^2lkhLU{x_{8$G9NVtO%iOlW#t)W8%1D`= +z=daU)+0+1F<`R5k3qZJi{&2x4({I6rkN~ij65YBuJe%L!WH*tUpFx}sx@ciX3up82 +z2<$(HzMdLg4zJK-#O?*|I`K27@+UvoDd+-$Xxr?9KUb>)ac{NupDCpL;SK@CD*9aQ +zKP-AF-zaslhttRMNAHDreyI_D3Y!p(clvdKaz4vBdcZ7^$lU~JCS`BQK? +zw~$;_?th_SK1KOPY=f3hSG|salT&(B?#u22!5Orj9KCL#zs(##0OW*rGibJcBaU*I +z&aE1jaLoV=N^oBHUDmY4-Y}Q{cj{(~nckdGaW}yoV_dCI6>&hYht^T?;Vg(cJWl*u +zFxBBJe%Ro_ven`x1uqRVM}{{Jf89qmU1+$t^5jRG4)B=9sZ>Gs*J_I!?qsf&^0<l=q)W +zu%W(@kS5%zZ~Nx%QJz1c%_as!UZ&&~2_)Qi6-)a6W)rbS8H}PisDJnUq?$+iUa#@& +zhKPRd!~P!~Ks!o&jy-~XTW6ggY8y?TF)G`xQ9)^&ryc@xt+z!yZtxh0>rl!&w0@h_ +zz9iSAMq~h|8@LY?Ys31Lc&Z~-0yh2=lIIQf8Yc_<#0%q44=JPPTp4+Q5Mxh +zAf@B7eaHEHROO$Eip2zfRa-pckqrx9Z8i%Cgrdn21ez;2|2(l@xB{{3HiKQNsNHpO +z-NM7F@0g)i0RU8#7kIcYg*6WjxS4A)9+)2VO3Mee)&yRILt>^|hBhevvRCVjik!(* +zH?kIECNoh|zbJRJF^yi3Dbi9U*Y`*tj$3tak_K+l@muXK+eqZP95SC8<046Evo$aE +z{QNxiyEYgv*lupyq0KGj8~1@94`p<6#jf}+{7`IMhX6b{jz^Q-oLptKAQ%knGQlZ$ +z6L}A)^x#6vKlG5Kgt7-=#&-8S*Z)aKXVJqhP@}!N(9?XJga=!drokR-nw{b-^2`^AAU6 +zbRD?D{Q68MkP32K +z+GB&3+oBa@Dt*~7o?c<$*tTHw;ch1j;`#T~=M+J`0TEV;zUghZl$E`ETiaSiV~wJ% +z?D@s=#A(z8Su`o%sAHaK^=!=?xkYu|H~W~_?E8g0OV;rQz}^Ud&RA8 +z7b9A8SWGvV7|dn4P$;0%$kN5%!jTTs8^I0WkqiP0hm%II>{p*W`u81Y1R~@x3b{9M +z&Ce@ms1cXmd3R=DlihR55PbP^*1Lpq4!OSvE^REY831-Tri!q0V?eeWEHI>9qMR0X +zeeJOO2R1?5vI$Ga%aAwIO}xK2$arI(Y>M#e5B*cFQ1tt(ZgFu1)2TInwJ;)k(awku +zCB1|6r${NfAXbfHOIE%|%an=$Vu7@SHs%o`C@L1G;Lv(B3AcE4|&epV!Jm>r$@@|qYc`BX=?WvvU1cOeeE@=L`B&pY?Ay_YUe*K<4 +zZlc&9QaSjTAl>PHedt&4?!cJaYyi>3Q!#kKUuTIaEc2|*>L{sBk(<#+c +zR0&lyj`Fq^sDVSnU6p{)sOP=-Z-?kU(%5tTZemjhIu8)x2_Xn)CK}u1*dP&S +zl1-{dnB8}c6nglzt;qBh;=r?t9;vRsh>V%jrUCd6{dzjOCHG;4zRVz44M^Qr^2>5GGC!$21H9Iz`j>#3Ve@Kr^Q>c){$$YC>52I~uW7|@5$k^dfRPMJ +zzcT*II(b$loLPuxo?w|t;)16S);!ZVo{ +zeL#FxWZ#%=+7H>-26yaq=zv5bXlbwZhp6`?HL-y;yh|GDeG@4UgI3|HQ7k^f^1s)o +zlK4rJ?U4+JwNFcMGUgjb7!3i6T~nX^xbgMIdN9g9ys*3CVk_^+)|I>?|t2B6xh)X0;MbW2~<>^a2mz +zT_AEYP=^llR=rEDyg}*JqF%DP26gT?q`C48gJPX(31YWTmdaJJrG!1U3q`vqsOU(N +z4oRK_^3IRswk%`i=WPnyA*UGSlv&G`W>=rg6!qSUoYu(KuScB8fvR_Vd&G&LqPl2k +zhYIpW79#a+#}$rjKds>rXd}F!7h0XLNyxh;IBF-1;&bhtbiDdS1LNTpS;96m6oHi3 +z{)VsFZcuk4OT@a{6>>lV2SDp=vdWnPUB~%q~mP&&6A+tr2pPh198!~+_B0E +zj&S&vv`6Ht1`kAYN@q+t(1j#0?|w9 +zScIt*C3sR|W^Z2;0a-p8JI89-?XU=)mSLkNj3+w!A(hyN&C{T_VCn|?xmv^G#zxR5 +zu4nv#air&L1$O-0VR00ZsuhT4F>ELn+)mbd!I$B<1qLw-b7DsOE9)_@2YN+!Q$Sh( +zDl3hV7*X?90_l=oS9$8!>_q2NVH5j(U(@a+BgFujbj%CR!z2v%)u&9z_TQRkts0Ml +zaNPve5=xBNi^)hh*3B=gDAo&>JTk2mXlV}98|((LGPZk+qk~t86jp1$Hs?@_LrvSE +z5SO48Ap6yN%oZwni7H(mDPiDt#1AD_>8@%5`p0Y5;g==Rw%ky9Je253r +z;+hN!R|j3UE^Yxl)4_LnBF4K_bx(W8v!=C4&VM6pkXCWiHTot2^eN}S6eUI6yF0d- +z^iwCP%Z?h6ze%cU>~n4aD`QX#yC`;bT8}Eiq&5|6>Yn)zeiF8eQTH+XQjqBH(0T^H +z4#;5|o8Eu4YPi>?>aDu*R>y971-lwjW`YV_fua~H;yt4>7q*5*JXP(o!A&bKOhO1> +zY_8f{;D;+h>VUO_+#IXu8Y7bIyY$}(;0)g^a;{u>hB6;o7E4m#Qbhg!U?r)~=xZ1r +z)ysB9I`-8g@luO2yv^VB)k5aK9LoaFUFlEY0Yw@fsQ0CrCdeeG`D4XrRqj1HoR8!x +z;cgeWm@$ozxuI;_!C%|-%L5j#=59e3-(LMtErypXTa9u(!NdaR_j~WtJPb$-P|63z +ztY1iWsi9q(;ldlmMTrti%WU=KY(2g+md*r*kY|UV<#pDb +zj7t0FO*FVHzIp^2-EP46UKXyf@mo+>QbeMO41ptESRICtiHKYOAs{z3O4|&XQ{p-& +zBH;0ZmbD50w8i&|`W1k;2t??xUMcxu0y9Y$E6rB?M}Mm8g!%9B#khDMrs!(kHOj^c +z0K%11Kn+Nw#?q^v1c-SItzXU3Fkj!SDBE1+Eq*pnV0>4}xlG4#h}2xfHJ~xg{a9U! +z17XuG2Mnjc4laWfFMHptr%sAoVcYw)ia~-&b;KlvRS_Qm00)5qpDlDke*gr^3~Wlt +z`g6{h03q@DP2kw@0DHOmK=+ItI3cWok-PTQN(-Q~=f|7IjE`N@wI1is(h}=|ZmX@8 +zwcY6T20F>-15jj>1~($++gK9Thc#u*Hu}GV|Nd#_nuiBtm253wzJT!prPKw(u5i!c +z{~&Q4&g;w8glHfzC1teS(>0E=ieMZx!=cr&ypFw_tmFgAyPOxvC7%1mq)QV=3h?X( +zH>kg=uNg_(V5Y&&iYy@ZI0}(x +zsb5mL)h0W(rpaFAq<$}w20MHRsBdd!VYtmZSskPk5i=}|Zp&Im&8k1q!PLJz4v+4! +zQK49~zl%?%ldQ$(>R=}^{@}Rb!p^Hpv4`eR&O@#{5o9Q!q?>H2cQ|zH5I_3G9JaF& +z(XunVk^qNE#Djp>uqAT#i{N7VEP8jbeB>hA$BliJK4-R`l|vi*J+e+ZlWVH9h@l5; +z#|G*dB5<6GUbr9w1M=z!cUkWBChE#{k;_U}G2QIq@Jp;PON?YIw|~Mm-;gZOSw46M +zmV$u9nJMLg^9qWWkTAPelT$o#`Xb=o2^ro-oP*(y%Y$~uO*?f*_pqfcLnVbV4 +z;8ixU#2S{hCi<}4W}(sq(O^XBNCY`v*rJwSf}3OeK2(Lb0!b@DEz{VkAWP +zlz5yJhDW@Y{PxYqNUT(I8Z{Ji;|evoy@a(Kv@^WRDs;_o0CI6MC{1!HDX~7EE2FUm +zZJeBsD?MrlOO}G3trbt+G$R#JU+TKNX5ayz16PBeaXdux8T;V_y9M0OT1^$`zipY9 +z#S*z6bV<+M>V^76+XOU>l&}N8XAR3?ZwHX<$*7nGZf%rzGg;NYXaonyw6YQRJ*1KL^MTK5~!@Oj3f(0}%>W7QN6^|A-a8Ri^gX>-SK<-&;x +z1wc|0r*}_Anj`5#=exFs$+zAphznEOJ#H==1H+Nl+!r-KLQE{h{ihj_LCbG)I|xhH +zJv<;uM&Au`qBNuASSDs`TJy6qcC_EZv|#IAg8^c}QnA4RCtvr~VywI7SzFR0$)E`w +z5J~L*wk(TGzVOmnTPy#D`MQgNK96;)hH&mE2js@pY0{k>p}LrN4|mFGeE8tCIl&74 +zd*1w^{6IcdyK%6&?+-U}Je{pJUvNS*rd!7=Gt2%#O;~XVACM*)NJBWD%$DX!>#KnZ +zDeTtc?ARW_UxQ%>mV{@2AvX&8*W-Rd5PGE +zyZcy}=XI}DG3%np>_ocB0wt1SV@1@h;Kd;ZA9Cj^sBroqfHva0Qjs7|%iyv}NSv6l_XYZ2}l-yrQWW~|K4kg9HW}P78k3L;f$b?8 +z-Cfj@pW40Z9146&MljXx--NEY+mdc%O`!>yn{lmifS?%Y04n@1`NbOA?qj^;wQXy6AOFm!~bqU>VLFRRu4X#dSn10d@@h&I~SiOAPCfCzs*-r`_hlF&FrQIaDe{3|A&YJYD5psQ&1NNLf4~as&gMSZtK7e5}aLmV~uLN#A%r&wP-jlv|@Z>RU)_V5IHK`l7Y>-Cj6a90?i!AR1I7wmpQAErS3AFMUQ#54i6A?3KILmTMX3nxmHTJ2d6)QGqgvnLBsMf%1}Ywg +zbM3#11LVYkw8GHmC=swOLx5^((d}ZWiPibC1D*Ppyz*&+SbH5u4aq3d3;)PjDpp7P +z8K!V?Y|HARzDF!oXv~L{v020$D8AT(JTb1|kSxFr7Q~-Y3pLNjBO36n2O<~4%GNZ= +zLQI&XEg4e^QgsB$)e!F7WfB0A0cwZzLnsgDn}0OGud@(%(((M1OZFViL$O}OF9QJL +zgWbA3qq=U@NiaFqFE-h+t?R` +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 +z#({L)W*go +zTy(+6q6c9S=t7g|hb`~PGCjRMY$#qAv$_Xu1y{J*lZ_ +zpDySz$Mio?Csz5sYYhrb`Mq|(nFu6E;I;#kJtL2{2pQhM}|pW18gw9sQO +zk!;4JK}wn!8g@2G+oAUxkdU|3jKleDl7)ao6hh6s=VC4Nt&>a~_5gFHKy)R#tBhl+ +zZs|mkqACiTr!%5=#afO+wo>av6B#Lhp8Qy6Y?w@Si64TMwF+qa`T(BT%p4(8QfOT7 +zfBSOg0Z+G9d{bhEKs%;(E!iQDeNtp6L&q%Qc#R?;THI^>s)gEA6`NRvh-tL0Xx$f4 +zYuu#V+yOrBb(lF57>$erfsyslCgR@WT5;6rqKBer(Z>3~42yliCbMyxE!G_+seC?9 +z=dX@0>$%U>y_)`FU>cbtyo6vNrv78$i-5zZ+;U#rU +z2U*n!vo?S7x*1xO;puVryIY7EdY?qt&N1Ocb8H*TLSIiJKEvBoRD@WV4$5MGn>TMg +ztW>aX9K@7Hp=HDhP_nfhHe%WMmT3Wn*z{LQ5)XwlBgf-eMQTuR$Y0l+q|((@Y=yeZ +zUa7#1kX+AMbTnYif(ZehsjwjyEh +z!mBSNcI^%-iZB$?k&tU)vznv#rUi49H^67>GQF&JnOHwByp?CxN_84dTRwM;8w;+hfI6 +z2}Sl>_@<{L-bT`8Os43NnVXXH@qKu8GvI=3jK`X?}b0zwQ +zk^+73z>y=J?8lh +zOGc2F?){gcswd{#kRwVRfWh-V>Fee`FIK2@Khaos--mC=>l|&{BVW7@NJF8j!9gQbZc+imN7 +zy{jt=v)DZbLcE)#cuf5J7MIUDUTQke^uf;axQG*AS!R_H@^?nzba1g%*8`3gjb}Nm +zyuAt;#@DRsnE6sw*Rv2#AJinrT;2-83P|B1y#$?7Jr6rqS`|-MQp~2BG}S(X6AQetKT?CE=M=tx>4LxcxP8wDRG`SPWbj*b7RAz841;NWjh^15 +zUDRtM#Q|f|OKI5Y-z_zReeL0Y_SY8>gLK3JU2h*;2x&k;G)>obO~;MwOF|7Dgj$i$ +zMsNWgR2TN(ZQ+_YTkj{&(4e_0{I8y#xmOje+iG@Fo@<-&=?5oo*1xw{#QbCSWvqv} +zI;&FDtr|(lhHUuA%_8ogRRTR^?Wg4cf4PHi@MVz6<0gBS-Qj-n|srur+ +zIk-Bw`W48j-rl4Y5i)w)565HKPKO#O$vJYR$4%pYQeIW8Y72PUV +zU^huzrqx1O~~n<>Jd?jl>JCtZ+Tx +z=*d)*tXLlAGg`w&<)zVuA_?C?!qZKA$V1!p6Wy8!^FSOq=fm2^5)2(PWKm1<0lOSe +zvq)>eYM|V=-t0)#9KMxE5#;c0xJ*t_r|y&Vnc-j3hL^4BXC881A^h^|RmP+iW)RfN +z!Z#0atPck})6M{OonghK{;r-vxC;ji0CkwiKjn;QeY@SU7TV5r=biqb^5;A&b!9jy +zk~FUyAve;xR+ACy4j1*sP-NAUBY8SN=;XQ;=6%&qijqa^6$Sg8a7- +zI2B#%Jlr)?qm|O#qW0s<-_qtAytMZKJmrya4kyRsY3J{=d+P!A?sAa@9$uCPI_!K4*aC%heW8(+*N*BUyJtvxWI98RjR^BtLeBXSbA&HKo +z%(Bx^U*x+B%sc0w^zR%MLnyR9W@x?l-6gUcJy +z-@4LIkixr!ARm#qN^q|t$dbk)_g%s->#;)5!alde`%DE9@c6&2xUyy^I{SM@$BOX&PJrCeN+55nu2q<_dv^%nQS1s`XDNaNcUyA1a4?Tt|JUIp}_=_$^05P5_9YKN!vP&9XQu4pez6k=pGEm14C}x*Gd2opfjH{Au +zzaD?pGt#~F2LA!kvmAt-=MJI%`cJ`4r^xx7-^a-Qiw~!#AR}L^-rawVpm3S^3W+tg +z?-1kLPul*EQ~~)kZt2%XW4nz8+aC7`%eU(@7Y-WGlST}^t4#g)3sU_@AvB-EOOk_? +zl8I#5&mODN@@xo5RZVWDToNdjjp5Ck=&5gQXZ-<(@W~B=(Iox!$M+eRY2cn_iAepi +zB1)E$RP*}KuYtMp_j14RZudU&YuSDU9~&%U4bzYGBVd@#i`95?i=u!CSS%vZuHHWe +zCM+@uhq2G*H?6BZF3qrWCNm3Uza-xQt|cEq&m|qbu43Q9wxY0JE~);-W{)I_5p5zr +z?#5EPxF|lH_F6q%t*N8w*Bf~ypg#OlgO2P4dbze(1%@sx#@rW&fbLh9obZ{xUk_%L +zhZV`ai-WNdIuw3%wc3Zq{u+=P*>7^`#{6-~i)$H*FUt&me;X&WwjiP6;|i^=U4Cn01!zp4%d=KQ^G1(0Q~cRCRy}IHiQ6k-nZ6DC6{hs@z6F;uLG6?TI877D~TE(F~?A{vT0tS +z2IED~^+0-%TXM_U)hgYA000Mj0iSVnLVo}R$_)Fs$GkymAOatDAVI6Ee!jg7h>a8V +zq53~&V@iT2sX7_0W6SoC9a4%YVt +z4us>Orv2x#=7Q)^ef)0@ZmYkFe=^m}Uc5eJ$?K}$D^XmHJ(+Mn+CCVV9rZoGE&|1q +z{IP&wV2uK`iFILILQ~J?-9~E!T9_-~b_G3m%$xZjVbNc4*<31wv@=E!wix=VAncRYS8(li{|ns`r`!k8TB(t*6trlYY>1J4z-!cPw3aI6 +z)t)8vKxE*9`G_44%mSW7r)!2&q(L_(I6iiJ?RXvmRPkTjx^Am^x61$M +zV0&JzubfK;@O$@eam2fv+Mnhu$IL6vbD35hNq4<8R{Pk`tK+U8oYV`*BEUx;M@0T% +zbw6Z!jz`2K)Xs0GR61XiWc<0|=o0Z{ab5|ZD0<^-y=Xg4zP4e#(tI$vI&_2VoMIxO +zynF;?v-wSo3z1F8v&W8TuN|wb#-JSr*ULONu+Crz>Vfuj#EGW$>9QL!9u9diG$CUP +zssC8wC_yWNi0*kUi&UpUBFQW4n@q?(aNroCdKf|^4&xqTJj}UPTY=CQ0KYTIuf0jC +zUEp55vNN|k4(-9%jB#}^LUrvp#o`m+#r1W{=YW>si`E-ZCJSP9+jQ*XvkvDsQvP6&5)8=)#6vsz +zc}V(5Nd=|4v(ZOU-ZgLot>Kj!pO*_AcBE|0YTx=75|DXg=f2HO^yo+i +z4pih9CQdGjqw%~+UI?cfNX#u8>#2R>*fFcA^BYVt=YK)n5b|4e-M3Xoq7L`~7pqE+ +zN^y{;Xl1WrO=lzlXTwKnAx +zxaYyH0|{#Mc;v;%lA9MEqBPFDT)R?o>CpM_r9?O?9p|Os>-*}#H9Ja+QF-0{@^BvW +zyU8mk4o2dbnZ$Qbr0%!eY;)Y`au<%`o8pjWVvs15-Goj`-{}y|NaBklUW^CKRL(Z+ +z9c8ZPj6UN89gDBrw@q@)cQKNoaYq0;z*mmjqcjv| +zjUu0MWVaUNGGt7$bIx_+0lf(7khPZJV9?Z4DFgY?@pDrxTdKz@w78Kcco9(*pI@as +zD&OStbGyTP4z1eE0^g~b5@HB6g0aOt1EfloA8ODyY}WOPC`lQLorHCoVP$+9tmVIC +zH#EeYH61z!yhA`z-q^((6#B4UBCmF4pNv}6dZuJd8SQ{w`uK4UP +zTZ}&sTk`qYUbpJTeJX91oTZrwnJjU#Bqq6o)E6{U;^ZB5DqNzvmvCK&0||ws@+)p#tyd1He@jsR4okMqnzj2ovHzD|+?4!b}wH;Eep +zxRUcPD`kwOY-DUr=5% +zQN*g6&|V)&`vgLJm~QMJ-~p_)ZnR*-%f-JBSnzf{){S^YyDpN*??)4&If9r~{lSh# +z@7+{y0ooF0t`f2E%>|rg3`e^7e8O?iw+$WcKazCf6lCi4S_6}R3rUbLR^_uQ2*QLM +zJ^914f=;uX`SATVR1l{;%AShh0c(EeWrkW@3mC8HGu!JE^?z1MN(33agAP3d{j%f{ +z=srt}5ZUuPgEArcgKZW-Kc$Vw3>1#Ww?sMadDBp9C;PdLSdAh40oTk-xBhrn!=CDJ +z9x@HsYupdHm0AHPPsS5{auD9-Lw95sbud-G-9f@Fh>(8IHvkW6Kk~!;3n!t(LA_PKSAf +zDI&c6a6y0|>gG3PIB8A#IBb*#H#qlmJ8rv5@>y{5A28z`>zlss1)MYxrf6o3sXWmyov9G?7_ +z4vVUb0FR~SP6;{&>qXdfITRW)<-?rr=Kt;+VG`2q!O?VZ{$ceewOttvD|)8A9MO70 +zlVw}-8%Ypr$ZIOiHbEK~?Lz;SA6ct4WN3^S7GIxrPbdxheCWJwP8gtzY3`z*=giSNIc}Z$ZJN*pAI4%8+eFu^e0!?DhCax?_JCq1tgnKj= +zb9F1>Uy(#wfU`!iy0QUPfR;Y-aO%HDnNxa;>XKJ*rFR>6438@5Dt19qqiY3f?bVPq +zaZWwv*|lgAsW(OFEH1Bco<-tbbc&7*H96@l54*pFInhl7WL(h}u0kZHO14A1V`urh +z+Z9Bv72jw_{hW_^$sOUE9Z(Ydz#yhC0H==H?yrB&*mFVU&S1YJ*q$C4blYouDm0vN +zm75EtGhWVG*rYdi9}Fx>HLuRDDdDQqT(8s#;8oa2rW>-~mP|@d2{t~-dFr^ce0Jb< +zu_^y?2*{DgtHy85zlF!GEFS9f{1*-0C6o +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 +z%)Gk5wS~ +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 +zOhW2SP&ePSmy9Z +zRm*s%*lkNk6M4mUPFbSO)M-?CmqP7-@sl-HM%GmBv3HA)I0$Gy$8%F +z-L5GH^TU(;!0N#06tGGFh~Y2V%SoJ|`5aLGdTUm0UsEeB=Wc(^DlY^K7>F(*d=G8} +z&O_st_<2i4%?FA{jxz-_nAD;EBuD0X9S8x)JHo-6u;IC1_w3I(ijI7{(CT`XWfp2O +z`&J3pBGLw{~~4fBXN#39HYCkRepN!Ge$wFL@0?>J0){LF;WrbC#V +z%#oLHGXSkt3Z#N;2d3*ng|kF|!2kdUj{%>zYC?Yi1j-CDa5N5o&aeU#C`{R1`~%+h7T0Y-Tqwxc*M`kn0H`K^TzP%=avk5*#i*a(ZJ1 +zXq6V}c++L99L^l@>-?h8;#ZrT-w$4dm0v +zd(1lc?ot6S0drixfSg^#Rm+ge?977Ufi)^{xTsq8U1dEXuU0*RT(!?%a-1H$GwS+5 +zb;0hKH2L6eEx?z>lpG;h7MEM&QX@F++H8CIwRt7#fKK&$S4kKbJWvVZazvMbF~C9` +zTATz8io9I&Imj|Ej}q!zij-0mwc#V_%qgbIl0QvA1)#7va|^GTptN~C(l|;m+Lj>9 +zEe*y!%(WLYwteYUkx7UiN2iwHVg&W +zJx=4g>@#Q=<;#T3i@9PjaZqGEYGf`SXt0qRuRhuO +z6b#`o`jk2CU%Dq$P`)T?bTlE?+ITmmTnv&l&=SrCLVO{f;Wu>6F4w_zl3Umsr)FqX +z6xevl%sOqk899>8VZ(^cY_lws_TfaW%<)+MYUF^Ef{{IyX?yuS{JCbe22a)DrmPQF +zCB538Q@BVHFJ_Hq|Kq(mcU!i>ZPQ(etZuu&;EKd~BddzufQJJG@B~(YYIk$R1xq#% +z!jjCVl*|!|PiFM%qDPu43Gkh_s(uv;P9SNK?#$PX6%yQ$7H?&m*>ZRde_ngbq%tgY_Xt|psXXrhr>ZFA{fR{$Ti +z9%;x=6$wNc<&EcGRedG9d>htQ3bcw7zJ&w0aoOw?D;8VYO=!+#wjrT2wC{gVuI~FS +zw#w8+*|3%1J;(*`rX~X3{Qx!s6NcrHohDt7@d0}HQQ6Bm@>HNf{AkOdWiLPlZ~){e?WfX{5dnl`Aq3l+HA)UHK_wK20yt%+NrcmE0f%vb&aG3Jk4*3b +zPTsq9;XlE@B6O>s_Fn8ZbXL=M}YMBN_4^e}4osfgE{4*2?7i*cSDr5ztVDUZd-Lw8C0w>st!?R6AH9%XlU5fI29~EuBu+`n0>@aaJ%#1BK?k +zA&)hbL<|gF($y@CH^j6zTU_LF4@0-OfMrcJf)AH+(q)ppvT(VRjZm%(0_Wgwwp=7? +zr%UIY;^`Qva=Zy-69cQHvUx$(IS2i@z*d$_C~63{;FCmrf=hdZDKhuMcgE6-tH8OI +zk+3mNiK+r6(UI~k$3$$Z>)5p8F~JT0jSqk~QIXCaK-w4i|N042#5-(;lcKiM-Udt2 +z2m6)l80Ul1$!RSwWsF;wLmI7;#V3fxOne#UN7j^T)XW|nK|i;!p0R|tr95NBn3mWp +zCoYt%?y~jE`kyZRI^zW59_Vkx!%9N$ov9TbaevDQW{wl$Z{=SKU~6$Nu~&ZubKY`v +zFJ~>5Eqo_O3u+jBi$52|3z&%?*2571nUh4O_eBuJm(po;}$DAz$%vm-n5t- +zN@SPh6!1arbfYq3-n=l2dy<_LqnFDfHp&3(1m{rlz9d?cR!|@mMmy#KI{lXVPR%-_ +zplX-<^*+(RHb +z4T9wNTAS`EUk7`KuqX3zB3;Ko*8r*Yb~a5acI*_ug=_XAa%VD<f&6BHZ!>LP@;|{@ahe^o&)GYXz9V`v2Yae{e8`;v!SzEL)FW@vuAZXGR498R000M*L7Tfts6lL*ObAc^ +z{qX<*t!?Ik<`JLaZ2%iVA^{~mB2@!z9*B(N#xoa{zG+$wizbWv7Qp3U-f3L#G+P%>_G3(drIL +zkm*~l`-N!TTH0{Uz%$jwr8mrV&il``;g4k_ +zPcn*mBt5be1T_v!y?UEo1uYJuhNs|Clpx1rPi{~1oFtn_&NwpKf +zMYsSx6S7#UUZ$`>p6^e0@l&41njY~2b5Oy4VW(QcR7|Ew4bPEh@?SDdO%lCbesOMj +z<&HR6F#_BZ`Tt9#EY)*08vF4z+~W1DlB-+Jd@jKe(&e0d%En1Lb^u^o-zy>6w~g6m +z#?Z~`Z@AoB&uZYMyRqabHWhy5i4D0R#>Wd~;=${!o{Nwvw +z%d2xuK#NQ%48PNvsgE{zAY~cc8B=r}>#1p5>zl +z=xM$Ws-frL9w=sE1W&E;AIWyILv8$^g*g%fMh;*+i~(<6+SIN3Cd|2fSy|k4`4*yI +zxD`2GO?7aNU^!=DLgE)W{;beAb8J-v0$X>)#uo_@$MepCnj6B&kQn*MAQ%a3rZXIq +z`<81UV5b5ic>2e)Agw`TVL9!XtBqRpHS{01n*AOgw1s^wb5@?v6Y~M +zZ$8)sMJ$F`*JDK!_cAhCcj*+K+^Kz@?&r!P>a=M8N;shIDqYY$NQ9OA1|k4l=SlmY0B9XzzdT_Za{#v<+Y{)fWv{feYXssY)tHYE7j +zl`Ga!sF{OeEE_nfCT5zxIe%}Q*~>@<2;I+e!Z-owTTRDSc(gF$?QJMyMCpCj9{8*i9pt= +zAD+h-V(&v-C~lbHFP`!3(JvqXUlsk5PI+{-A-foYA{aFLrBPk(5qfPxi(>%$JT!J% +zJwhUo$|Sbad8#BW8LI-ypkU#`#`J`z<|d{N9C!BVH#)F8@O+zXk;=;ZMIFflE}a!4Uidn9ed +zzWWbVy&CVS8i^z{3eD;rBLG~cGQOQhw#!YQ2Um+=m%wgm6BX)g1Axm9X$x|QKfn4k +zUtXZm+o-S(Uc}r|Ud1)L?xEufRer1biXPIZP(M^?TuMF9zSz!w%WQB4sOryj+MKcX +zO_Sm&@Wuo?N@L;EgBE<=pW6(qt6ak$B!O@4zo~V{Opy3tleg2FE#`}9FSfEuM&gxl +z1twuO_l-Oy(I*I;@_tq)^+pV~u915Wr+R(J$5gQRwQC}sZ86g60^qi^5->zuiFWN>^;=Zkw;vEB +zM-h;al#rAb1`$D8LIIJK9=e9^W@rRKN~BXdq@_DVN?-`-?ryke(D%OYeed@VxIf(W +z%;&7V_KLmFUeB!aJagupEv_(Gf(`9&;=My?1{M)4B@mx``y~{WI>oQnOiV2E@G)weUs;`$EH3u +z&^xVsFvcU;o3UvZjRIy2%YBf;PoLniAVvS+xO;^x6pGl(*_*3O3JG(GG+4rjx_p0h +zC9kB*QSSBGn@Hz0QPsHIOkSb>DKFgc*awGE&Mmzcy@a}QRWrW=QFVF@2k91>P0G(C +zkT^NmOrW;*=@A;Q9-AlN3=OiZ$Hl1ptnc`w!{sRRv)=2dTv?p#n8lk?Yo9x*w1Uem +zx}AMzo5p6J4SF5D(+Pw%Y;HfZe +z&!R%p?~gNPg9t<9C5F3XlLk`aI1u-5zK58N;t>kUXM +z+2xKcA!}u@_V&x9ogK+D#nD+DC!S+Xq~oW)iii#A3rx~*bWXUATboE0+h~NwZ@!U$ +z?7H7o@SZ*I>ff*(!g}06QM^c$OyTVcoXfW|q~Vn(V*<>YpB*03v0>t0~{cpej^32`S}fmx^>dgAt;k}$Jq_m_lY +zd{$x3RW*_E(DBo-@IgF3pxx-yh{zdQIDL`pV2FRl?(k{i2yUF%DoAr+;?GG3;nvRz +zD4=QMQ2Hi3pKp)Osh>rFZTzITSU8uCh@Rs-{tC|~beRHpV@Z4SYXWl=dHn!Tuz&%HaytQ45KU_!T~zR0*8iZrVd89Ht=P`>;&)r9EvryfI*ZTOKY +zK{n%6Z0DCyQe{qXq?P5@i}4zGeupDsLO(Js<`FXm@TSl{Gmq4`?;<<}&S+^t$?Dvy +z_yfaGNfTS!E3b1m#TbP6;c%h +zHqP^RB24#18yP^g7rl_Bj6Z*UtfKn#Vb^)fn7f$xE}gpTp-viY!zstE4k4x?8?3c& +z>&)IF1r?s!E16{F7M6Dy*$<-~6h%y`Ich68B))rpRd;Ro(o83^cAW$ +z)8v7i`8&Hx@cg9p*2IfQ;!x5%1Ed)x6NT@kRL4-M6Dwl|xA!0rTHxlZ#9R?2<01yt +zdtx4EWf|4^VpXjle|#&lTYDn=&QSd$EPNZiuT__^v%CnVH8s5(u2!;*H5f>6V)9eG +zM359>|6*LmqK+}CXBKlHv_Wl6!Eiu5THQv*?BQ1(l}A)P2bhUcStBpw(CNh#1(O?D +z%|1>$PoU8hsmA1eXx$xfdENT)Wd{Rss7cq+^$&Ee&aIhs{FJzpXcqx0Uf7|k3rzDR +zQPTSt>3taD?wC(XeOWBrs$Fh7rFHKiiCctI +zbAtPznw%W>26#x3X(jY%3%o$hAT?|sEEcjbKP2HQIIe0c +zFc(?P_4)M`&p^nu92og5O8pGFtk)#U4qzo#xxSuc{mc*KK26=;Ys9HpQac&|?j9<} +zU4p)gzG18}xWD?1Yvaj9c@^7bl$7uVrE-sbK+d6amtw=IVp9{suO}6L_%+?8j9R0- +z@MC*0Wi!E1o2OZF8bVEHXYfj9h;CMpwJe4br*ijtTb!%eAe(nm7)6Gh!nv;iZCyOX +z0=+kU$v_7;SZJSOe6f}AZ56@oeJ_*{j?iFP)=s&?5A)zUH3_5l>)1{dU9@mnZ_m!_ +zTApl{?K#4o*ReCT60h}xi@3)LgicHYrZFVqR>YOen}QF!v~Sn1rAemMKS=UvUdW3~r%$_Yx*VpVA_v|>keQZ4*EoE%ez_vBMj_(O$z%*2-_oa1y +zqVQZOL=NNehL&BTln#tc23gO=WXccE4CNL^SqSEAGI~?>@{pMkvWnJwa#P9e6|_p9 +zBo)*sfV4eeMO@0D63-ZwCBr&;&|OF;W||(YSVk3_#9(eD_TW$w*V<_R@QxfQG{voSeKZOswSOaGa=2zvIvx;o$CIQ +z(QrYES4JB+ri+Cye;^X22Oqui1*mxUe1$+NR7UWA5}1@=w1;uIedKeuJm%JhL+MLg +z-dsIc?*l2J&-o(JL3}Ayr*A)fseIj +zHZP$>r4K17Z76@jY^y@>IQZ*>G2){H8Olc=_zHHNZDzuY%VPEgB)axAt>RhI+5`K~ +zZ%aNpFFKE3RZiJaVaCm-P^d~?u1^fA)^(jF;EP2&XFXnuQ_8xk$!@h_$g)d>^uv4M +z{1l?P@{1EhZ^1MbcScdxg2o^ +z68Mzbu-~~TGjc?vXyw=zciIX%e-J0p(LL1R#HNmBV{m0nVObC!!a7nD!?pL? +z@$Zdn8QFIwG4mLH3FoEcYBBr>GP*=)F*dCU9;!Ao(Yz^+{y~9nzN%WAcpVp#n$ka- +ze-Ug;EYJ9@ywe^vHuftzE<-}cmse~-O*>!o3x`yvsjB>7Zli4iKIaRTYxV(qtR56> +z>I?Ml4A|`&j6&|MN?V!q%-(U?3*$!$Q!ZwBswo-Cdr4olH#O<*+2$VYUmm0VG86Ja +zjfimhB{e{^KG!^5v`D_YoM$IE@d{%r*zCY@X2%pP8qv#2fzZHsJn21lx<6WPx8JC3 +zv^dFGuNZPrB++xdS^IQ~$G)aTZ7=N8+h(opQ42S1E)Oo_%3^YdcFMX>#>>>C+p^XZ +zJS2f7xuTPiy|D<6bgdc^y!>0*-}2WF$%w#%oMf-u?`DuZ1^#apY(B3E|B%Fdx$T#; +z7?L*%S!Jck`$>piBFJat4?Q+@-3B(zqu1MCcXS!i9NJl~qDlca6{5am>3&cx;l?A8 +z#du=4*K5Q@6k6f)Y~+Onu@{TMwhkUb0X$C}20Vs+A}i(Kf|ge|nqr$ZhN0 +zDrarWxX9*H$`NF4XD)jkDB~TMF +zHlFaFjdw30&*Y;&J#PkfFRQj3TGn7_dD7LliR^%GH0}n#_x$fz&-31_>36((y7hnWf*g3}vK*D*=ldYf&_$F+;7mo8jt??8eEV+6ZsQ=U;? +z!t5V93If=KLt8bJJ8jE@ecOn8p9ZUPCWVv3w(=9H% +zS99+tv690FO^rtr`5H-eAr!5dXLHUiv%U8q1Kd1!oezIWEjP772KJV(=Fh&++oySA42%g&xF9sedXMCahL{q)WQ +z0?|ekDpUJdG%(tBh^eml4k36V`GfQrV$9mKBW=-=?aewvBCFGy>jIW5wNU*Bd>z+4 +zOCw@C-x0zu)d!T)tNOvDU^*`l2z}kc%E|!*0-0Ml7()U654yDiT$=kqC?MqLZ~7ks +z(ETr2_;1Vq)ItTuyl-ctYX&Ia*_qvpdFvmBf1&~7{+s?a&VL#gMHq0}xpAa3fZEvt +zEph{MTf3W{o0%fxqWzgOT9^gYL>JIeTR{JP?$3a3C(zs08_&naP;;97c)Lw$YL;~;vUY-a9!Z-&I +z2*4ANNdfK+AmBI01d0a61%MC$NWW^ph63Oj004W8WB_{r!T0c1LWBgeJ` +zfQ)qlARIsx0Hh62ATV5k(+0j9`c{9|0J%OK0QBskcDevpw=lTjNcF>i79OBj+33Px +p$lCDV^w{Kgb))}cXN3$%0oA>6Mg|4R>N*%cfv|D$vvG28{1-l>vtIxJ + +literal 0 +HcmV?d00001 + +-- +2.28.0 + diff --git a/patches/mfplat-streaming-support/0037-Revert-Improve-tests.patch b/patches/mfplat-streaming-support/0037-Revert-Improve-tests.patch new file mode 100644 index 00000000..a3dd5463 --- /dev/null +++ b/patches/mfplat-streaming-support/0037-Revert-Improve-tests.patch @@ -0,0 +1,5271 @@ +From 5e7790e37314e63183bed11cc5283b22383a2a41 Mon Sep 17 00:00:00 2001 +From: Derek Lesho +Date: Wed, 25 Mar 2020 13:58:36 -0500 +Subject: [PATCH 37/52] Revert "Improve tests" + +This reverts commit 603b1717a2b511a66d3be99ab5761d49cd5ef34d. +--- + dlls/mfplat/tests/mfplat.c | 244 ++--------------------------- + dlls/mfplat/tests/test.mp4 | Bin 121550 -> 1554 bytes + dlls/mfreadwrite/tests/mfplat.c | 116 ++++++-------- + dlls/mfreadwrite/tests/resource.rc | 4 +- + dlls/mfreadwrite/tests/test.mp4 | Bin 121550 -> 0 bytes + 5 files changed, 62 insertions(+), 302 deletions(-) + delete mode 100644 dlls/mfreadwrite/tests/test.mp4 + +diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c +index 03d474d62e8..6dd2c3cbe96 100644 +--- a/dlls/mfplat/tests/mfplat.c ++++ b/dlls/mfplat/tests/mfplat.c +@@ -440,9 +440,6 @@ static BOOL get_event(IMFMediaEventGenerator *generator, MediaEventType expected + return TRUE; + } + +-static IMFSample *retrieved_h264_samples[60]; +-static IMFMediaType *compressed_h264_type; +- + static void test_source_resolver(void) + { + struct test_callback callback = { { &test_create_from_url_callback_vtbl } }; +@@ -466,7 +463,6 @@ static void test_source_resolver(void) + PROPVARIANT var; + HRESULT hr; + GUID guid; +- UINT64 frame_size, frame_rate; + + if (!pMFCreateSourceResolver) + { +@@ -600,27 +596,12 @@ static void test_source_resolver(void) + ok(hr == S_OK, "Failed to get current media type, hr %#x.\n", hr); + hr = IMFMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &guid); + ok(hr == S_OK, "Failed to get media sub type, hr %#x.\n", hr); +- ok(IsEqualGUID(&guid, &MFVideoFormat_H264), "Unexpected sub type %s.\n", debugstr_guid(&guid)); +- +- hr = IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &frame_size); +- ok(hr == S_OK, "Failed to get frame size, hr %#x.\n", hr); +- +- ok((frame_size >> 32) == 320, "Unexpected width %u.\n", (DWORD)(frame_size >> 32)); +- ok((frame_size & 0xffffffff) == 240, "Unexpected height %u.\n", (DWORD)(frame_size & 0xffffffff)); +- +- hr = IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_RATE, &frame_rate); +- ok(hr == S_OK, "Failed to get frame rate, hr %#x.\n", hr); +- +- ok((frame_rate >> 32) / (frame_rate & 0xffffffff) == 30, "Unexpected framerate %u/%u\n", +- (DWORD)(frame_rate >> 32), (DWORD)(frame_rate & 0xffffffff)); ++ ok(IsEqualGUID(&guid, &MFVideoFormat_M4S2), "Unexpected sub type %s.\n", debugstr_guid(&guid)); ++ IMFMediaType_Release(media_type); + + hr = IMFPresentationDescriptor_SelectStream(descriptor, 0); + ok(hr == S_OK, "Failed to select video stream, hr %#x.\n", hr); + +- compressed_h264_type = media_type; +- IMFMediaTypeHandler_Release(handler); +- IMFStreamDescriptor_Release(sd); +- + var.vt = VT_EMPTY; + hr = IMFMediaSource_Start(mediasource, descriptor, &GUID_NULL, &var); + ok(hr == S_OK, "Failed to start media source, hr %#x.\n", hr); +@@ -631,9 +612,9 @@ static void test_source_resolver(void) + + get_event((IMFMediaEventGenerator *)mediasource, MESourceStarted, NULL); + +- /* Request samples, our file is 60 frames at 30fps */ ++ /* Request samples, our file is 10 frames at 25fps */ + get_event((IMFMediaEventGenerator *)video_stream, MEStreamStarted, NULL); +- sample_count = 60; ++ sample_count = 10; + + /* Request one beyond EOS, otherwise EndOfStream isn't queued. */ + for (i = 0; i <= sample_count; ++i) +@@ -649,14 +630,9 @@ static void test_source_resolver(void) + for (i = 0; i < sample_count; ++i) + { + static const LONGLONG MILLI_TO_100_NANO = 10000; +- static int once = 0; +- LONGLONG duration; ++ LONGLONG duration, time; + DWORD buffer_count; + IMFSample *sample; +- IMFMediaBuffer *buffer; +- BYTE *buffer_data; +- DWORD buffer_len; +- BYTE nal_type = 0x00; + BOOL ret; + + ret = get_event((IMFMediaEventGenerator *)video_stream, MEMediaSample, &var); +@@ -667,38 +643,19 @@ static void test_source_resolver(void) + ok(var.vt == VT_UNKNOWN, "Unexpected value type %u from MEMediaSample event.\n", var.vt); + sample = (IMFSample *)var.punkVal; + ++ hr = IMFSample_GetBufferCount(sample, &buffer_count); ++ ok(hr == S_OK, "Failed to get buffer count, hr %#x.\n", hr); ++ ok(buffer_count == 1, "Unexpected buffer count %u.\n", buffer_count); ++ + hr = IMFSample_GetSampleDuration(sample, &duration); + ok(hr == S_OK, "Failed to get sample duration, hr %#x.\n", hr); +- ok(duration > 33 * MILLI_TO_100_NANO && duration < 34 *MILLI_TO_100_NANO, +- "Unexpected duration %lu.\n", duration); ++ ok(duration == 40 * MILLI_TO_100_NANO, "Unexpected duration %s.\n", wine_dbgstr_longlong(duration)); + +- hr = IMFSample_GetBufferCount(sample, &buffer_count); +- ok(hr == S_OK, "Failed to get buffer count, hr %#x.\n", hr); +- ok(buffer_count > 0, "Unexpected buffer count %u.\n", buffer_count); +- +- hr = IMFSample_GetBufferByIndex(sample, 0, &buffer); +- ok (hr == S_OK, "Failed to get buffer from sample, hr %#x.\n", hr); +- hr = IMFMediaBuffer_Lock(buffer, &buffer_data, NULL, &buffer_len); +- ok (hr == S_OK, "Failed to lock buffer, hr %#x.\n", hr); +- ok (buffer_len >= 4, "Size of first sample buffer < 4 bytes %u\n", buffer_len); +- for (unsigned int k = 0; k < 5; k++) +- { +- ok (buffer_data[k] == 0x00 || buffer_data[k] == 0x01, "Invalid start prefix\n"); +- if (buffer_data[k] == 0x01) +- { +- nal_type = buffer_data[k+1]; +- break; +- } +- } +- if (!once) +- todo_wine ok(nal_type != 0x09, "Access Unit Delimeter NAL not expected.\n"); +- if (nal_type == 0x09) +- once = 1; +- hr = IMFMediaBuffer_Unlock(buffer); +- ok (hr == S_OK, "Failed to unlock buffer.\n"); +- IMFMediaBuffer_Release(buffer); ++ hr = IMFSample_GetSampleTime(sample, &time); ++ ok(hr == S_OK, "Failed to get sample time, hr %#x.\n", hr); ++ ok(time == i * 40 * MILLI_TO_100_NANO, "Unexpected time %s.\n", wine_dbgstr_longlong(time)); + +- retrieved_h264_samples[i] = sample; ++ IMFSample_Release(sample); + } + + if (i == sample_count) +@@ -756,178 +713,6 @@ static void test_source_resolver(void) + DeleteFileW(filename); + } + +-static void test_decoder(void) +-{ +- IMFTransform *decoder; +- DWORD in_min, in_max, out_min, out_max; +- IMFMediaType *output_type = NULL; +- MFT_INPUT_STREAM_INFO input_stream_info; +- MFT_OUTPUT_STREAM_INFO output_stream_info; +- DWORD input_counter, output_counter; +- UINT64 frame_size, frame_rate; +- LONGLONG last_sample_time = 0; +- HRESULT hr; +- +- if (FAILED(CoCreateInstance(&CLSID_CMSH264DecoderMFT, NULL, CLSCTX_INPROC_SERVER, &IID_IMFTransform, (void**)&decoder))) +- { +- skip("Skipping decoder tests.\n"); +- return; +- } +- +- hr = IMFTransform_GetStreamLimits(decoder, &in_min, &in_max, &out_min, &out_max); +- ok (hr == S_OK, "Failed to get stream limits, hr %#x\n", hr); +- ok (in_min == 1 && in_max == 1 && out_min == 1 && out_max == 1, "Unexpected stream limits.\n"); +- +- hr = IMFTransform_GetStreamCount(decoder, &in_min, &out_min); +- ok (hr == S_OK, "hr %#x\n", hr); +- +- for (unsigned int i = 0;;i++) +- { +- IMFMediaType *available_input_type = NULL; +- GUID subtype; +- +- if (FAILED(hr = IMFTransform_GetInputAvailableType(decoder, 0, i, &available_input_type))) +- break; +- +- if (FAILED(hr = IMFMediaType_GetGUID(available_input_type, &MF_MT_SUBTYPE, &subtype))) +- { +- IMFMediaType_Release(available_input_type); +- break; +- } +- +- if (IsEqualGUID(&subtype, &MFVideoFormat_H264)) +- { +- IMFMediaType_Release(available_input_type); +- break; +- } +- +- IMFMediaType_Release(available_input_type); +- } +- ok (hr == S_OK, "Didn't find MFVideoFormat_H264 as an input type.\n"); +- +- hr = IMFTransform_SetInputType(decoder, 0, compressed_h264_type, 0); +- ok (hr == S_OK, "Failed to set input type, hr %#x.\n", hr); +- +- for (unsigned int i = 0;;i++) +- { +- IMFMediaType *available_output_type; +- GUID subtype; +- +- if (FAILED(hr = IMFTransform_GetOutputAvailableType(decoder, 0, i, &available_output_type))) +- break; +- +- if (FAILED(hr = IMFMediaType_GetGUID(available_output_type, &MF_MT_SUBTYPE, &subtype))) +- { +- IMFMediaType_Release(available_output_type); +- break; +- } +- +- if (IsEqualGUID(&subtype, &MFVideoFormat_NV12)) +- { +- output_type = available_output_type; +- break; +- } +- +- IMFMediaType_Release(available_output_type); +- } +- ok (hr == S_OK, "Didn't find MFVideoFormat_NV12 as an output type, hr %#x\n", hr); +- +- hr = IMFMediaType_GetUINT64(output_type, &MF_MT_FRAME_SIZE, &frame_size); +- ok (hr == S_OK, "Failed to get output frame size, hr %#x.\n", hr); +- +- ok(frame_size >> 32 == 320, "Unexpected width %u.\n", (DWORD)(frame_size >> 32)); +- ok((frame_size & 0xffffffff) == 240, "Unexpected height %u.\n", (DWORD)(frame_size & 0xffffffff)); +- +- hr = IMFMediaType_GetUINT64(output_type, &MF_MT_FRAME_RATE, &frame_rate); +- ok (hr == S_OK, "Failed to get output frame rate, hr %#x.\n", hr); +- +- ok((frame_rate >> 32) / (frame_rate & 0xffffffff) == 30, "Unexpected framerate %u/%u\n", +- (DWORD)(frame_rate >> 32), (DWORD)(frame_rate & 0xffffffff)); +- +- hr = IMFTransform_SetOutputType(decoder, 0, output_type, 0); +- ok (hr == S_OK, "Failed to set output type, hr %#x.\n", hr); +- +- hr = IMFTransform_GetInputStreamInfo(decoder, 0, &input_stream_info); +- ok (hr == S_OK, "hr %#x.\n"); +- +- hr = IMFTransform_GetOutputStreamInfo(decoder, 0, &output_stream_info); +- ok (hr == S_OK, "hr = %#x.\n"); +- +- input_counter = 0; +- output_counter = 0; +- +- hr = IMFTransform_ProcessMessage(decoder, MFT_MESSAGE_NOTIFY_BEGIN_STREAMING, 0); +- ok (hr == S_OK, "hr %#x\n"); +- +- while (output_counter < 60 && input_counter < 60) +- { +- while (input_counter < 60) +- { +- IMFSample *sample = retrieved_h264_samples[input_counter]; +- DWORD output_status; +- +- hr = IMFTransform_ProcessInput(decoder, 0, sample, 0); +- ok (hr == S_OK || hr == MF_E_NOTACCEPTING, "Failed to input sample %u, hr %#x.\n", input_counter, hr); +- if (hr == MF_E_NOTACCEPTING) +- break; +- input_counter++; +- hr = IMFTransform_GetOutputStatus(decoder, &output_status); +- ok(hr == S_OK, "hr %#x\n", hr); +- if (output_status & MFT_OUTPUT_STATUS_SAMPLE_READY) +- break; +- } +- if (input_counter == 60) +- { +- hr = IMFTransform_ProcessMessage(decoder, MFT_MESSAGE_COMMAND_DRAIN, 0); +- ok (hr == S_OK, "hr %#x\n", hr); +- } +- while (output_counter < 60) +- { +- DWORD output_status = 0; +- MFT_OUTPUT_DATA_BUFFER out_buffers[1]; +- LONGLONG sample_time; +- +- out_buffers[0].dwStreamID = 0; +- out_buffers[0].pSample = 0; +- out_buffers[0].dwStatus = 0; +- out_buffers[0].pEvents = NULL; +- +- if (!(output_stream_info.dwFlags & MFT_OUTPUT_STREAM_PROVIDES_SAMPLES)) +- { +- IMFMediaBuffer *buffer; +- IMFSample *sample; +- hr = MFCreateMemoryBuffer(output_stream_info.cbSize, &buffer); +- ok(hr == S_OK, "hr %#x\n"); +- hr = MFCreateSample(&sample); +- ok(hr == S_OK, "hr %#x\n"); +- hr = IMFSample_AddBuffer(sample, buffer); +- ok(hr == S_OK, "hr %#x\n"); +- out_buffers[0].pSample = sample; +- } +- +- hr = IMFTransform_ProcessOutput(decoder, 0, 1, out_buffers, &output_status); +- ok (out_buffers[0].pEvents == NULL, "Unexpected events.\n"); +- ok (hr == S_OK || hr == MF_E_TRANSFORM_NEED_MORE_INPUT, "Failed to process output, sample %u, hr %#x.\n", output_counter, hr); +- if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT) break; +- ok (out_buffers[0].dwStatus == S_OK, "hr %#x\n", out_buffers[0].dwStatus); +- hr = IMFSample_GetSampleTime(out_buffers[0].pSample, &sample_time); +- ok (hr == S_OK, "hr %#x\n", hr); +- if (last_sample_time) +- { +- ok ((sample_time - last_sample_time - 333333) < 10, "Unexpected sample time progression (%lu)->(%lu)\n", last_sample_time, sample_time); +- } +- last_sample_time = sample_time; +- IMFSample_Release(out_buffers[0].pSample); +- output_counter++; +- } +- } +- ok (output_counter == 60, "Expected 60 output samples, got %u\n", output_counter); +- +- IMFMediaType_Release(output_type); +- IMFMediaType_Release(compressed_h264_type); +- IMFTransform_Release(decoder); +-} +- + static void init_functions(void) + { + HMODULE mod = GetModuleHandleA("mfplat.dll"); +@@ -5754,7 +5539,6 @@ START_TEST(mfplat) + test_MFCreateMFByteStreamOnStream(); + test_system_memory_buffer(); + test_source_resolver(); +- test_decoder(); + test_MFCreateAsyncResult(); + test_allocate_queue(); + test_MFCopyImage(); +diff --git a/dlls/mfplat/tests/test.mp4 b/dlls/mfplat/tests/test.mp4 +index 72bcc0d8f3eafac344bb2152438afb0c4c691338..a5bbca6bbf7692eab047050b79b8ccc83516e6b4 100644 +GIT binary patch +literal 1554 +zcmZuxeN0nV6u<3bttg}g3M<<3v4A5C7=;cYskS&=aH+Gw(TQ=|2k#+BpKbac6$q26 +zgvfMZE^O--6L1NclR1flh8QLw4%rM5#eGC{R2Jv(j|s9(8MANazOwnmo#gkWzsJPV$oN<)LWX +zeE-6+iWMz`xAwzrc-v;{3ns3&Hgygab@co_v%sWh^~kxZdgv1 +zG$e27=y&X0FwfM)&vJ1wQfF>hX5`>p!|hca@;lG>BPmWrt3nUp`73 +z+Yr|+TbnzS=UsV1v;C6gviW|rw)-!S-=bHn;0v1+QGDC}Ia|1D&?ob%jF`h$Wc#Ew +zV;vf3`obS*$vM4L6xr#4wnKY06wGT*}wdIn7LW=}zVn#?n%4mVMz +zS*QG<-xMcs%$)a1n<6jX{=IjfF~joa!xMeyYRwY|Cr0Vm>*3w%uu#*`=0;_WapAn$ +zU<`El@AbuA79AjpWMkq|c1;#tZJ#~+J(2cx>Nm%BvdmP*5AP|wGW~$TESZLVhn6a1 +ztO^C+GL%>qKKRQs;^7r5rKP{`hCoZsRD*LTIOV>}^ +zv}Z#0Dsy%(f4!(s5zT+wRX-W1@{bU&DxT$gcYNB95Wz4GhZ`=WopD!CphZIb3Y&Tt +zN#HB;J~@EE6G4Pb;@qcgDO~ywITu+4q3v9iuqGi&TV#WEm&%fL{&(FFn1q2)5>0U| +zXbo*=;Rh207#4X2E~$c{DoKbWFx1ksXMtOViZ2NB(km#tOR(VMuB70{eJoZOI||7? +zl%2*olCwKs?)jSUa8_iOSD4dRa20SkU +zV;68rdYYqx4bH`mH}`KUjy7ccnDD_0CJHA@_=3toU_OwXamIR7Gqf9{35_wfE7@%h&<3n +zKs;bQARC}!xiSZ6ESNJ5P+CoKBNU0kHoiM#Wkq*n&-SMq0^0~2cD +TJ;x-N6hTeOp(eUDP!ruh^$B~# + +literal 121550 +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 +z{%-Bh +zsx@awKRo<19F!2d&k$?u;k)fK!*$nr^b}uvxRH21e$%M*F_6Qi=W5-NIFDMd_ER(a +zqZ9LY=!^NF<`*h%jC+*aG@gYU@AN&Gf|VUCT+JP66aq^U37eKB=R@CQ?$IC)GAQTx +z4)y+V=vR~$sj8zO`Wp;jBw93aZwG03c36Lz()+NdQJ6dk^@e0XcZeBwAo3!fmv5^? +z5JK|Ph}nay5xYZ%kiYp96dwM2q8dc2H>+T@6k{{M8|k?$E1v3&oW+~_^jNzPG3dgR +zG_0(14AUpmP8%1jM5~){izbrd3vtd>?2H2DZC^s3;>I(O^%H}~A&KCd@LZAww#s3=0zDL|t_2?Q;<{R^GrOi>wTsx%4A=xvLL**+&V +z&fg&W%}^n))zEKkmZPmzI?((TlwU!EJ9jyAT*SLY%ru~McXq1!Y~1#=KS8eCCu*Yq +znX*jH1@;=7c&i=)7efc>n3fyg1j17?8BzPi*yv)Sf_r*!o`c3a`WlbvN#j5&{qWC$ +z@7l=4I@5M1ltOfDA5o2;U7qSV`HQed3C_ilOWJ;7Y`#k+m_V8~8a9U*SX1{ae*_}? +z2G_HVz>R;`RJpSIA&LpzNK3q5KV@8IoO*{U@5Lcp3sH6q{B544%0RE$=ym__8qc1{ +zSZ#acDq~E!YhY%rja?=ZCRxY$bpC_qFftb3TViS3wRCF| +z9Q>kEwdOdxF9oMC6j>7;xXmRhop4ViLHJwDFhNCZ3XfOqnml73rss<`o2bh>{$R$u +zuEpfo@Lrwm9?tS#!EqeO3O-IHxDA(5E(pJP>C30GK92jg+&m#33Z*<7;%cnh*ht@z +zF-J1np}O+yhc`QxI`dg2eO)AJP$laU-LGPaw}vSr(Q4^=sS}S;J;Ci#h@+v?(LW{O +zDoRqXoE%f>+iWPdiF~^W({qy4P#Mme^2s4l=dBwp-&L`y3(f+!>j@4jl^g^v}{6s*Hzb!0)N60tujwLVDLXhgA +zm>Y%03V6=*qK3IEuJHF`LI?BgtEFB*Sfk%&vCA(CSkXpI2bG6mmC@m}3eo0FxeCIs$2ehUM|FpvBfuhL+=u=xnSVL$bfmAoQgz@lZBGXkUGXvE +z&$QGRUN~t-%PN$VuA_8ZtI865WTPk_{#vp~;6Vgo_?o%I_fh6z4eQe>AeUB(9Ab_w +zJJdnE*e9~WAojbJtLfuf3_119EvB!i*tHRE@&f0>F1a&_d2o+`OHx#DPb9N5iPb1N +z82w~wcyNVu;IE_MtFh7)Pk!+>r+DuQUaY5CK2o{Dxxt`ury)^S+M)i2qg4T +z!5_{LDD@U)p_iNccS+v0k4pazw*a(1pjk^cj|;N9M>G;@_;Q1Z+(2oQEn-NMzEqD(92Mr +zmZ~dlimZ$&#E<_=&H5DrCq +zC@ioO9@L&zt?3HC)EG6g63swR*(^4(IVqD*i>%Z;ZOV{4ee6&sBkf +zb9i{wc!8pZy|H}1=giJ*7{%Em66{AHfyN~5BQM9V9 +zArQ0VfkpacERo0tP0`IgXFRA_J)UFiMa}cq2Xke)(IEN}`7YdK5lGw1fo+PsO*&3> +zgx|SkpE=_?tvm~Q_Q;nO-~CA9(6akES`(%Pq@b}fBKW{0JU#E;$YKvQS1ip)XwYi7 +z#JO%2Pey2K~ED-x8Q +zx@jFh$pQ}r>yu^$CHQ(SBMK(GJF0w;m$BK2IXU%(l=2hauNXXD=(EQx*(w^HL?!A( +z8u%l|f5dH+Gh!4$Kr9mBUU$4gBmmlWnMeKUBgs~%affbmKZJPMxJH}i<@Ww4J?ojJ +z|8Z|XgYOxO$}N@ZS#mGD6ua7tUrNOH$`V)DzqwqnB8&myKAx61YP0NrBr(JRX^8DZ +zuh59tB}&O3>_J}z5=1d1SN-mb>S|Lpy;6AhJ-%W6)Ol3pxbCI6JH2Xe!`I+mwqm`B^_ksJ=A8i& +z(f`=qNyjw3aBRz9`;xcze2vdCl4Hd);(v>}re+*C2Z6Lqq=0_d7eFYkKb1WqyDTi9 +zr2I&)8^QDdy;aQFtU)%CA|&E9z(ps5i89pCZ)nG^d +zf|ClZW?Ph!xS@Op6QkuYK*~z$)&b|?4BL6g*6KJmhU7`m$Vv%9EMIE&)|)IcrMZj? +zmQ^;Rf*ji#x?N;RTy!bN2dM4d7W*Th_%oZ4OpbS8U}IgZ#E65to8m#kF}h8V5RMILv~r +za*cC7F6q;ksS_ic_m^1>2Sjvy!EBR5(@o7KgzIQJoX{c8RGzxHSsYV|M6R&jPG}$P +zQ;0=TQZ~@}H!n^=a*4xbo??*E1*8g1oq-~AeI0=*78Foo5%{*Q%PgQ|bOb=QlLox& +z4xv0Q3a}-_6^U}d0kxYr)MRq-ZDq#4eVRsJ?x}Y>`i2UIdsVfJnTW`CP`Q=N^SNzW +z8r3}!yDCxjZR(FiP&0%m^u)ITe)-L|+s7Qz1cCILMZ-Div2vpOvtIE6_lwI*B>R0mh3zkyMji)zrihiOcz_o>xCIty;Ne>iWt|u()^7+ +zTQfw#H=>;4bmOB}v14YL{5q>n5WK^l<2NhRW=)>&itS3bu~fJpWZ*yudmx>YU(U_k +zYwP;ROT(J?#zN@G5{QZFenr`7e$ljo=OD?qQP4qv9BiME`4$|4?!VM)>135y09vB} +z%k2W$EW`#R +zn#r3LxX{q85WtO0b=SH)Qu}W(Thnh~=)PK9Ah)^8_qQfcA!}6;uqbz)P6FP&ZfH!% +z0yiGlW?sP}C!I~F+m-QOy**z;dy=M>YvWCj+i#g)a~)h--cWFXxaW=^jJ^jRc^x+P +z9+^0+XhV>UmPic6D_?itDeL_(wPvk>o$9#7^m*J +zR^COI-R4(W8rRz0*#OaHoOd^oj+e7Q%G2HmT5#EEC18Dy(Ja}l0)JeS% +zfw985&4akrc%GtU<0FpQI{udh-hHOn9&NYjk~g_o3-zW#)2e4jE|rt6${>57I)->3 +z@vwmbH_v#*4=U^;fns+H5n5z +z@QFFnBH_9;JWysB681$^5(q%zD4E7h00p@w=D9Bl8#}jI|WsEvl +zsS?VmS%s$EAp6J~Z#H!ve~O|fpG%e|xTtn1u!n)NJ@ +ztH(Nc{h7kCz_|v_f_{A01e+W5XNuIMW2g2Ys5y*m=W$_UN#tDxcP|%j%_vm+FPoa5NmHVQMJ*#nFp;F797w3-D9cQh<># +zQi5j@4_Fe~vrcQZnWXDD+WA0)P)_g14_eC!}w8I%B$z +zd#BHTk?B?5rMx^4ITjz!u5nk9fdr56_N5>M> +zh%An>{hFFG8g%>cHr~drhHj@tv&Sl0Zbszx9$pPL$`ce$~HJGC(YI>J4f01gD!kJ=f +z!0#e0j5FDHxRW^T#1xTnO`TeRWszJ);3Bj3I<=GjeF;KgK+rKx!YtW*SsqB0_dsZo +zMekvimJ=u1AP48~!c!++$XZ-NE=ZUoA=T?MfD8p+_vm%)074YO11orPVJ@Fx2pvzU +z1-5dnX>oN!_DP8#l8gq<^m)cMseplPmVApji5W1Q{RP7n$leS(|JhN)ob*IN_3Z1< +z4E|NCzh`G*Nn0F5L3ont_1=;K +zdW4(Kuo#^-{)jl?x#+JNa3|#{%i+(5oa0J&=y^>*8lC)+^o}}2$&J|nL^Dv>nk7Xi +z_q-91&ZAbp7Xe7cQ<$stqHx|{urrl8oY5EGswoRnxz5pRqhvzbfts!$qZ&Syu9~6F +znEE9KCxUkbjz<-Df*l9zs*rh< +zU)b2)P8bG?KKy*VR9}8tB=W)3337;8dseNm7SdNI@%Z`;6G%+wJ!pSQ5t*#`>d2Z^ +zjzpSM|CR)-e&;Ahq4wK-$e`AhH^GDlN{E(_Eu&1o*4Nq@2Qk-%GFdH)?Zv66uuk>% +z`a}u1z||HFB3*DynMpNW&SiysKEVHZj?Rg}>wM2B%`vwp+s;{i6sx4!_@204WIc#T +zt6bJtSra+K)hd^4i&2O6E#pl;lo)nnckl0;AXQ+*MQ&YT(b{0DT9IV1>y{yh=W5bz +zf8uPH{U(-^lKNY^S|zX;pIj3)(U~E?@8u^n>Qo=;_H}64aIzEte{=p+B*%NX~ +z#5v1iD6R7h#l%_pCGpC?E$JZPf4q5rf{{UK1D+PN?t@(Ze0obCORD0D+$;iGwxt#$ +zzv!<<3&j2+t-1<6VJfWACt4gYaPTx@II-Z9rYKe_SdytV##xaeXa`F7*+i@jfOFWo +ze%gc#qyq+3VI-sv6knC=&!MgIzzQX3yf_cnO*+caPY4GoWnOCv<41R#X+hl-!16cn +z=7Uz`q-ezER|3EUL`ruWH;)ig753mX3_F4KT^@0dtR;y0yt8I$*7e_>b}@F^$X4X- +z+=RTC1<=2e6*yABI;?mj42oNxbM0;p@B4&(^g4u5sU5WwCQ+jjAIz5FDU_-A_V(C3 +zGY!&l?VD~UCo#CX^(FI*1qWC536qED*08WIBoPS3M#uFhp+`br*r?7-485f75ggS8 +z_96UY44h_lZ@Ddka@O>+P+WHb_qV`)ZDzCr|%<57DXSjG4Zrvi@@ABFhk1xia`f>JQL +z94038Ysp2td`Gj7+p!f6T0|v!t1>S(^kOs}-Zm!_v_~q00Cuq7G6+EXU8GImn!9b7 +z5coyF@-46yzFCbt$1}vv)Y@?PGm*W4bB!zo{eZxR38VAe-9JoKguOxlV8s3?pvH0z +zSzh%}V^fdJ{fpls10u}_sYZ$EZS=>fTe^^4aBP{9m#KdXeB-dlF%{IiNxFjvS93|* +z`k6=i(4vUkTyP*5j0;kbXudhKq{HyQIYJ*9BYbv@eZUK+p0hJ)$=(X%1l3LIU+(PJ +z^(_NU_EA0}DvwebQ(dNuGg=E741O9u3pmG$*)#4bgtStz-OX1nF@eN8pNFuKOUJgR7wBafjE9Y{hR10)@p +zl_yu^=)K9_d&s??EOtBhUk;kw1O*GJc9F~>X0Xnq4jhaP!`XPeP<9rn*A{iJz?6v* +z(Kzn#eNpig?nEBfGr{={)z5;ej&3M0OMK3sHIUmt1nGhp*x~sgAA1y7PnwlR+IRoe +zQ?n#Q48@L3PMcsG3;81OiAz%RCvlE0%0Cmn*@f+>>*^6;7O*YEN|y)E0dg4pTIxXM +zHXu`K2_d0Q&1kV<)7a5xEsD(3(=gD<{VQHYH6@yu48dL_HuaL>k|seZv8)!62fn^Z +zkI5Btoj@2A>i~kWiLK+LxsB>;PkK(~UAoRC3&T=Is^M(gclw7aF-EuFTHV +zyp)#f`D}|`dQkfPsnB#8IUcWz+G_h{h$}J+K8}^$4~?wY@Gr4mPrcr1p0ruR`}=@X +zREqP6vo8sx%UK4iy_;`A);%sLt2-1u*Ci^hr{-UtgTXKVU9Eo?&(D#+g1*Rg7+&bK +z`SZBQ!AnxS!MGA@ZJSVi^<&>5zue-nu%C-qD&T%a!!UbvM8YWAiYLOKlN!ah@JKlq +ziu*ld083RRSi-DAmVW;uV&iAwUeT%C{JfAj*ReQ&FB+CMVaitFAPEMvPy7-72E@yC +z4duq7w7%7$q!c^32F>U*Kq-!y$bo(; +ziQMj|9Q1oOn?tUvar4Se8X-v+DPp;8- +zdY5&Vq$x+1aR(&Lw#L9UyVa{n_#OQqepkF6T&~o#ZrjTse18<@!>f*KI7L2*0XIxK +z#?J?#>+NpZ>91kHl%=nMKSvj0mq!w(49fV2y?2aLagWyw*DdxbKZ;bP@U(ddD9BUk +z3~gC`?J5hz*?)Xdi$>h*(**gN=g#tm4rqLb$F&h&CD*Y3;&H2`d1q>k^gg<_BEx1x +zL#JY>oDOkT4}VxhY!Z3&_aB4aqLtcis(xEat^J7(xRX_xvNy~Dptk7Oy3|VRdon!^ +z1W~|IGTJJq)<(n$qdWVO)hxmpDlZ_lzEk}!AcJ#aR@VMb_I54X2-2J +z$txf1IHqRAX^v$bCiYG@<`&PP!7Aw}zLJViP^^S3V@bfT_NyaaEypnNXrw_}{01n= +z8?8)4G}oG4cw-+F^9tX3-O-9EB2V2zzSj9{y?l`<|3<++)fDHV3Gsd1TaJD3u@_-k +z2clFAe5NViF6VWTJtWxXn7T@yzP6i5| +zoa=!^zkOAsj&#&Ox~@T-AbV0!_$*VjBKP+1sE;En|0NVTXSzfary4cIzpj3wKuF7n +z=y<=P07bTAE@Lr&ZJ@;)V5rbZ05xk+V+^2-q&AX?* +zvyA~USu?9c<=ipyrNhQcCBe23`p3=Hj~WbT7UzPAFh1#%>RDAD7 +z +zmltv{x$?(z^km5n77 +zz7KMh5cHmYGX>SNqA1rSHp1_@;fZ}BufNR-EHx4X=gqPvUiWN&K7)yK}ZsvML +zB#h4T-Ng~W>4;FsIhyxGn1lf6!2PDgm7%K(sf2jUL@yK3C{>0 +zi_%iZ2JYg$qoOzi+h`gNs}=Xvl;JGqCmt3f#~kS#SQl~X=+KpNgE1Ewm~#5Ce|d`U +zV|&c5P=NHtZ}oN$xO-oaSI>KJ6v!L2-CVV%ta&>z9<3_SolB5ib)5FyiDyL?Qmrg% +zbUZNSpdh6W)4z#tBWHG%@69jgEVa?X_||8KTu4S(F{N0TF*1C#bu-98>lQz-DPC)1 +zvz?5~=R$iU(Ohca;5e@1>=sL5;#d$+ghyufm#8>&dRqD^7+yE~RX_+m!PXk +z<@2p~DXvdD6xz6RR;amNpADE<%OVyuqZk?Co=rON(yu_F4hlx=-U@kjp`KA6>ugza +zXDsCd{rzISO1KZw>|#ycWShfowrxhJJ<)p7uI$}`o!Bzpb&L;M#ldWi0aYah6B6W= +z+jQ@L1*lvGj-CjXc{Af)WF$)=jT|0>^?G3 +zb=RyUy0z|B{pR=wZ&$qGH#;uUsL2429~fo)eRif!6k`;-S~+e~aE%Y@;Cr1mp*Qji +zdg0)!#5y4}Fd>b^SRF!6J(AM%T*21wlPe=l6+|Zhh(|g4`BN7N@)?Q@Zo?dEi<;vy +zgisJ&a9bJ$o|W$GJ>*(2;IJ^8F4YyR1^iN|}7iBEzM>I*7pKAeS4)9 +zS7#d!y?iT-khN+ZmWiy +zee>1#z@AV6ltL1mqJcKKSBmpN6b=Y+75x!h5CDwMa0!xB2>w|!pim6N=ez0u#8R8up!c;#$VoioUGm0w?Bis`7i8M5WqlFl1S{Xg8F(Szg`Mr?H8hw# +z)c-BvpN0dUV_*h`qsVyPw$S+0LQtiQJ3~H^*@b4^*(Vp^WpS@WV>6{WdyD6M!Jddo +z8jJM7u-1VF-MrDTt-ox$rFwJUHWkU3glHCFJjZGcb*D0g?z(@RDk*!fYDAUIec2F; +zPSkmg=VQCOg%@n3n?a=5?liwwy^n`j~j87ck+2M;g39+mX7GXvg@ +z`IWCkEpoB9zAK +zupBAla=UiQ>EvyNepn8y5S7$Pbr~Zfyq9`18G5sHhLpE@ +zq#eZcO0IM(r54fPrHAG$e#1+ES{4$$(B^)QFR~V%K}EJv_BJ~HropQSi`QjxPy(-e +zQKA8VU)xrcD%{Y6g0tgUrehDknBx9q(>zV{(+TAngKd+3XfD}aXiO6m--sPT(}E7a +zsG2(FyuH&=6PaBrP~*Bc{T&eqjGG#k!qtFIWH)s(X;UI_f85T6cy~3&7Hkfg%tN_^ +z$oh?;a=zW!JtKsBo%&qMb89*x*S^8qO^YaGqERY*2f=o;E +z4Fp=3^5hJ!nGZrpvp;yUs9F%b?KaHJUg>#?f9M^27&2b#S+KH2S}Zwq+jMB$0PRv6POT4$!lhvt{jQa~MSi0MUjD-g>gtd7 +zOfSbRtXD4T?d#$0AV3*W{WE0?2IAO>WWvfqa$7h&ZJG?Z+V>8R#LO=4238vT4+QHpjXy4 +zBVKrV8AnLu3nlV=)P+Z9DalH~7NhkVXh@%<7ao$F;%t`}97kmxN`(oeneG*Px$T7Q +z29=isfZ6ImkqCSCIx*S36sc+&mjqNgmQB<)woa+@?cs2P)DBF_FuI-`IQyb&z^>PUfM|F0eam;5Y}?Ym(l1c=U`wy} +z)(ECLT|Q+}?fGoz*i6c1%`^w!yjFTd$Q$DWNgN_2$7VL<3AfJ +zfCY+drQgs!07n^XKG8#9q$ww0ba)#jIV{$AE?h@OQzdN$RNN~*+ZC~Vwknu*Qy@|0 +z`)!*XABKu5cV!wU`CT50+f5XN@)#ws2~5MD9zEt#DwGkz(=Qi!2 +zY5l)1rC9kr4jhR+2P*>>?z_QeIuK|wvUyE*O~660AbHuYm@#}Xi+k!ZLUWBjqBKhH +zf|VHl`Y`B}x~o-S8#_>UwfdLkEJ_p***d3(h;fk)%rZgKLHvVwot|i`ep_hLTQoW_ +z(EDDVp_|!yjRwLtb%1}Lu_7Z92Rr|&fHi_Z}2pMNVTnKMYnB6P3zJDe+_mmK9%`k#Pik&bAXf%6~8Q%~kJ&a?=Nuln#MY +zwM2LbYsrCd3^xEM$4Yz!-%AtGlQ!FMz7IY>w6KwHXKMeRh=myr;3Y9t0B# +zX86)KUK?iGvLEXxw%Fa8zR;!dOy&JrS@%Q!fMQ461*#v{;2~2Vtxl)~c6}7fE3G|- +zCrNa-Sz7bt91{E*%J8r)qKe@i0tjkEM=Q&Xkbpbw-Q-^4UU+pFVLX+hWF|I7veR&0bvD6{7yvf)zZ!IMW_Gd-YH_bLQekS6zZ43;#0+qZpIg} +zQX&Jj1k2b%^qa*Vj@L +zyq2O_;{tX01S+rR+E*uI_cY|c*zT4Dl3woUV?i0tG1R!!jtR5E!oonA1wJ)5e+>8i +z3*IYt6e1?N7eZ{)RVcogl()VpkoV?1wMM$kF&j^^K18=#Yp$Ewc70vU5_b--L1uo~8Ooj-GL9H1^B@@7yV?ONN +zCyX7hUA@|V4>`~L+I%-!aP3jvE~ZKw#Fjjxnb+*bFl$Lq|GRM{EgUZ0ep)LX2kdiA +z^_*Vt21;n9w_+;$bm|?VENH0%YZ7NyJW7+LlmAH4#NH?tDg6EnzkrKu9QW2=`n$0# +zDhMN~qC$U{vhHiPtR#8i9z}Auqf3Y_cuOLzRZ3+ko?=^%qh2)qx-0jJd1r&cLawLI +zhBhRE`sVnbb@8xqC)6`0Y1^W1ak`^>D~C;*Ky=3l#EN;DvprfyM@2NpCh@Bv)3jTs +zqX>5!BXFE|psy1T55tzCvG-fjNm7#ZUoA08T&E8Yqti3J-Bx74GUx*Y+?3@w$I1~A +z(eksd7tPP;4+hRH{`nma1U4AZt42~Ylz*M4RZ`;*YDRk$ui=KSF2`E_d87b5Fw6f_ +zGh(&x%E+QD_x|o3HYe4UdY{J*S1ZmG&C=sx7eNYGaMSj4P-8Oj*F(wXv#7-!rHKkm +zC6e}INh=KR4Lo-YJ2TeQ{n;VA%M-4~v`9|T7N7O*MBlhW<-kAk}tk$j9Okb70mS1LNSzFP`K>obO?q`duRQYM_wK&Bp +z5**}B)oA@Xt-*l>2)@xV5$rqNC> +zc1Jh|PM0%PMjz+$KSq2!f0{`?eKbRChsljMMssd88-JT-Fql)%V@eoTa~bje0)F?~ +zZO4HP|Md8f+8N)kzSQL^=SOl&1=n9A9ERg;jH +zCy)5roRoZyC#Hy!480^D0DuU~KEpqp- +z1^H;jG5Tu1KKqIchacFZ3L5Tc?!a=U;<1FeoCxzo79#Fh$DM2~Td*{(Q^bunoDMYN +zR7q?A$gzk6P4VtnWcGOCEw}H@q0>2-yew*+4ss5R5pJ}~7c4Jdo_(41!-QYOT!i!A +zD2X4+1ZD4^U$O@k+U6@%`^QnwF(P5PKQmaT;-nZN+1OG^qu9F7aQrf?oJx(8i*WcM +zX-5W&6fFiUg^544(5)z*vz?YLVe?Iac)mhXq3vV75K@`2Z8iAZ?TA(RCQUU4>27ZW +z$5c*4xUsREI0^=iN4^L|i%0e}<2tPpR|aro9qeK{YP?^hZr&FQBUVn-Ii#;7o|U4l +z<18*N&TU&|E;n!Eqctt|I{&$-xoN8i)Ps7lCXVAJH^H(#RNFh2FNEcPdo~Yx_&`#c +z;xd-`fu}VfECsEkq|y5<_`lkaUANTn$)3sg4}Q@O +zh@Vl1X!u!nh>MYS<7dx?;*DY)@h1uzIMP^f{o-xvN+>t02RGvDMFEF2*Ezw6-k}v8 +zhXzITQ8T4ZItw#Yh7NlsyamZ}ot40z_g_f}kfyf0s+MzW<>E0kz6)2a);Lqh*{D%#af0KupO@Y+2P# +zxXU<{I2oXE>;C|AK#ad=S>H2|y;x%mwfgOsff+MGNwUB?tO=$8pgzNw4rPSJF0+ho +zs*{Wg8Q18MNapr(yhB(jA%Faa8l~dts#`stdsr3YU(90E+^Uc*`oRStt9nQ-%Yt-d +zRsW47BLsNIX#(zjDQson*iZO=E^GDVV|3mGr;+$>vWf;k1xCSJ({Igc9s}wV_lqF! +zzd(V|p3rwhNIHHBO1J4W&uf=H#>XmA3W7ETO#r6KJjBzE`alhjfX`w)2dZRW_4+2K +zXh{rGDz5pf1g)21G{7q0m>JT}^i}Y({>@qh`-4o&cyM!M8a!jJ!Ni#IWdzop;nv?L +zA|3E>3!cY4uJLmE1fA{*1;1$0`Zd7_6O>4{DA%wd;IjihgQ!fo +zHQ4`aW@v!=Q2?#E8vPJY0}O}b?{tG`S+jC9qu`M^f;tzXeqH_BKGY`AT2!No#2#=*_-iE3i;RB578Ha;ZGA2i%6naul%G63%BqRsmPWrkY1F+ +z+=Z}D*Fyxz0UzugHG^c=K3%S`A8E{LR5W{$c3Es&H~TXzkHS`1WdbwZqpl_^V8iye(Nn3>c2iIJcY>G!^{h+t|9e4iiAl~0tCC1mxRR<+Ea4QG<}h{LsguM +z<81hUUXVO(oA-m;dya&R*2(}RlP5ffn63r%GG7Gv3xT_R#^OVZ;L~}Ns0opdqXkAk +zCNkT?xaU%rGB@tLa$KG)rp-gki=<4(JDT( +z?mhn=I97ZgZ_#%`!ybOGPN!&ih)`Zhn?9Qg7`Mv@Wow$V;^!3Jl{`WgBD}USa4RPY +zBp4krR-foqv5EOXb&ja_3q!L+Ga%%WO42K`{_P)Kk0fR=Jlm4|HlAdcYTd8eiu&(O +zV6-{Ofxe)jd-J+K{3vJ1000Mj0iLI7LVo}R%3Q-L{Nba32z@}%sg8v6QgvHtQE#O4 +zQt@X@k3lwduL=?CK$;S+`|7Hc)MNxa$W$bg7A4#0lujq +z5_`h3aoatNXk$!TB{FZ@CJ~h65@fA)a7!;Sc7`@pZUx{zEl29d{dG6hii*9p4xNZTuS5 +z-xCX}y6E0zE&(%perM_3XaUsP`0g^ockOc3H&Dj%NPOW>O2C)kMVTt)nC7=wOBG&~ +z9W5xI&t@w*VgaT^$uE0i?>%G?9*4Q?BskvnhB_H +zcZ}n1aS*@`c+6lCUaojb^zW(`+E>TZgHoNr2ltS;P$d;ixpd9AIkIX!$cw&#-$t+x +zUKZ0o$W7o&H|xqhGjEw|bjn58u$Xc($<$#9XrE2;DFq)4Ce;s?ds^NQTSFjVJcn^5fDBPr`$ +zlO;q{{=#?brl59|n(XnC)k<{ci#g-A0!o4bMF`N63oq6^s1bgT1A0hB-%B|1)cQ=& +z5E$-JCHqgRHU~gW6!DP&%aJB!W4fo5a_qTB)<*&*F_b!N6khzp!y(4c!pR$q +z_e0G?nb$&LyK6ps`Lc*S>V>ObP?q`NGco#Z4i2!`bVMYyzdKbp(D1vQ>M%x5RbF)6^>ENx!0r?Qp7ghILM3C(j +z+;q`q2Mze?n)Gr9HSMc*krQ#e4IO?y4ucp8Wsa|rlziItM^y6S0kadx@XKQ8a$?I_6%4mGKJ-xH6d!i=SmpS+7<3=V!$5j$kSGw`j;P94GJi7Cu74n<-t5W3g&1^7u6Kq|z@%ZVp +zCCu5Q91B^aiog_ftJ&LQr2N=6@e<^@u4dp9y`1K9KjU6l=|u34No)YnguV8wKoljT +z7%(oLu85$v0GIx)X?Hix(W)vJ?cjudUU*PX(^``ud{jR4erdCE6U$dA^>nW?vbVh} +zUuTz9f5x(Ia{lf +zPwBb`O@ZknrpE*B%l_f+D-Wpegd?FdH7*?4FUYv~xV2_%lNUG{piKmQ$$2{Zs$(Nj +z@$BX%e2Lek4svCDD)G>+22Ba= +z-csA~UqIi;uhai5kgKC(s*?t) +zxHLgT;%*GD;7WB;OA_2asC~FkahP5xZ$tN|=6z5oQMV_e6{<0Wfu@OI*Opf>Vx_>W +zw?u_ARC-InL!5vBH_qt@j{`-)g$KC5RBXW0*-gFmLP>VhD0a{^6~?iDO}+~Mz6WIn +z&U$*G7ih@Q?jPzmxVw(*VbLlTSbr$tP|}to!78b-ZN}o|iQ5xGLZMCOaI{mqy4ol5 +zX;fLx)~AEpTRM`9gkOMP_FFq`5Qnr`qVX2fK+Qk`4U(108WgTzSO|^VmDs4;U$T)$ +zsQPHW9LqnVP0TxDfqs8CY9OR +zm7(~01!KHa$BL-Ow@sUtKKG_ecwHyKF3>k=Dh*uXl*?>OS^R%)_`&Sk0?QkV`e?PS +z_;Ps4tyRx4cXg-eMu)-ogwR&@)_r=zn_Y;9i1`w`u0HVlpG_7g_nHFn*>#~6369Cau#Az +zmOxd@2qLt3W+MfU$B;dMa`Kr)TCs1q&mFgKNE~42pAf+8V3`c5AdjS@#nHJy{gfjo +z9>a0>5Zn}`U5v^vI{gMR;n!%n)Z@SF<)y&wh|bgtr`(qA)#75HW&nJ7lH#~rRw+E5 +z%!wSNsJ@1SO$%e22_}{!O~`tI{6`eZ{F0@1mmh_O +z@ibs-NykBF*)JfA#=JIWt3TQ&SBqO$Kp28ed6$OK8gZwxD2%=F|i-}QoN_XQreov +z5h3ieUcV-q%T?Kv!>Zx}S%VC9?fCL-%}(bQ@?9gD(=b{{;gI4k$y;Nz<2#KpLgsd4YEVZRRs;oCZ%<*tv`HB<6~PfMkbw?3SCgjSetP45($!p`@t?L}u>c +zk;RO`riOl*d+l5teWyx-WFM|-k6v3XYkz@lxFcWcDAVtcbPNp%Smr7uKLr8y9fQrP +zjSr5FTmW}$&@fz9TUC|)LpisT9AJ2b;k(tNj +zDKz%sLd4DeQ$IxT@JislyF)*Y-&|F1CkRe(8Z>mrE*W*~Kd%ifX@$i59;ef6K(C88 +z77~;sef}*G+Hb=lwIIs>G7TsJVvwp)T`i`bu!v^RJ;?-uT1s$WkrlDqx&>Puxz3t@ +z3ByaDdoY08w@1TQ+LUsO>f}_O627h$H +zxG7I?F3(ET*5FP1H6n_zYQv${O`QhWBr<@=$fo%8mg3}Nl9N2*smy{A$E|P8A=6Vz +zqG7tRHnuAif@~&xjbsh%cGOpjIW=Wk1y~+6tGchRD$y#;dixNmVDg|G7Dm`}nwG^5 +z@!@XZYNTx8kiUd3uZIwL!DOo&H}zIq~$lN<}ca{13Gj%MXE +z99xNzdR=?tz!K?hfhO(P*~e}5I#j8ZasOq?GhAQXl|NU8QY76AU(38TB~zQ@XxNm{ +zy(VlMOzO1?dWprybD4|4NG9;!Y%Y_1P8#r^FvB-#hUH5Flw~(f=#--u1X*sG(2$6} +zDN-*K@$|wXfZk5}H+}&n0Uh^`n2cwL$Z!&9Ongith%^^6{f~pngyw7kmG+)e8j?A2 +z-~-@|k{iuxU_I<=F=2p#R!~um-jeqHzg@wI=iXk!CPj*sJRs6=QJJF81tUvfefwYw +zHVMZ6>9escSBGvZv$s6L^HFX1E-%}RiTTb8a1=TgimAG-ZbxE&g0?q~|B43AI7C}z +zE9T=L$tOqRxC?bW88lvg7wbX@9v}v!S7@!$eC3$J$koqyQQGKgiVzo{L)UyFv=zVW|<%pq~e9xc@kA%(-(8AhqmVGrN@6Gy6F7SV*~wP&QX7=RUUlMD?=-CGt+sTUx{P!_8=;lNpEKgB0tO2k +zCGn2QDB4K_L;xqWst9%OgD9AzPuz142!1)#ySdHH1(+A$B^gIv5gmw +zPF`OuvC#rj`-nYQ<5AKbu88k*Kxk$AKMtu@KoDYRXvlvHcH%%Mcv(TNf_=vThKC(5 +z5t3D3Yygh#I)$zFDe +zyC$IE(zeRhwn>aM6%8cSAaAH?#UhmI*%x-c4?i+OPcxE6^G)Ew(P`&v$32C;|F~`9 +zGSDw11-CsxsV+Z}jo!V|J4IorkX)pl2drsvYVLfgv2M8;%?Y4@tycQ@Fwhn^9EcJT +z;!2o1LalEv`06991ziiRhlTXrchG!Skv%?eq7ZQ!Kw7qlR>WWCRn#4}d&&E-(K@vR +zjJcSTb`B@P#JA`PBuPL0CEv?0AfR9*2YGcbN;P8{_yKuQK&1`VW8BUa6hO34@jB1I +zfBL(VaxOg*?0O66n*Te|+N0{pZna=P)kLfXXjo0XD>dyzSE-!BNhTunhk|vC*YrjA +zsw|HrCRHGugI!F4yYqDy9KQc{hufA^J|350Yz!_}1Rdl`1t%mp@`$Wd@&i- +zPZhc%r~pf*Di<+}RHlhxqRefRaI%h~p0}s3Jr(zQUc6!Y*(h)$Q-to9<>O7Pt+XZ% +z+EG|b@ZH$KzeCoVi%)$e3S}Cw)5ejx>$EW5LeeK->wVbUb4@zOcZcCL$g6I;X}F$3 +z8Ja_m2G~i&wh>ODXlo%eu0CH{vDEy#XemSQ)6ZWlaz45mio~8|5n)4z6(m*H!9qMp +zCH0@Fr8UOBLc5KrOI120E4mZK8rF97lIBAX7Hs376V#&}4=ay8+5eieL+wp|WzxqU +ze3g|n<$9OBlcF()@L8)eHIYmZ&&g`mPnF>Vv$>1QnX3x+U4PdVlp`w=yZbyz+ +zgF|OH_rgLCzXM1X5Kl!CKTOFk?g +zRAI;CxDf_T)-44h3YL;z4TjVw!kn=m-NCQr{L} +z1Vc{Bv{9|-{dILYr(UDwjMwxpxTrIyWUqwZgjE|l;Lnr^(vGL^LYE13CSxmNF1VI} +zB8Yhmby%apPFt+7(a}e~;UnmwoDq7oUYO?~>0>hxfI8&XD*D_F>B>vq$FHCH?MIx} +zYRmlg2J1xNRrpzZ=swL;TD_LyNe`1Tzni6G8+~9dEzbs_{?5!Aix>U4Vpd`%@~(q@)K1RbY)?2@*9avdqj +zS3TR!EK`v`1++e>O&_3;Hsu+IoC0$Qh!_=6Wt%kDE`=`~I@W&YUq6Vg@tv*}KWccA +zO-?C0Cm@^)mRoU?wzb(ZsF(Pow2fX@zRa?PQ%tHG{dcLhvEwS6Ezl4K{ZTpXZ-Dl{ +zSSliH)$|vFI&|uKZL3N3VI0sn4_wlM%TY#apYXD!i={DGwb~vHV7A0nbREogF~J={ +zyd3 +z$+E`@XVlY#h4M)WWjhrQmwr}T$AH-ko3kMyTp~(ouhNvpg@xd!eTOB?5xpFJa{n^Q +z4SdA81kYn|5qWO2*<)~Hf(Vp1^lksC5QSEYxTDGEY|tE36H;&1a`YJ +zVH6SCQ&Iqin4YKUCT-kZ@@T?>hJ<+~J%DZc@wqT43p)FLSd$JKw9SEF4SM4 +zG_e*=f(>)Cy~{$42Ym{%Exy{^d=k_(-pV8*$h1~WqOEDmVKg1E&Ndv0TBl4z!fOn~ +zV<@}YM6icHwdqL_H7awqG!qj-@v}Azk8uxFxmhYvEcLvC2mDk35(mWQ!}6#{4%x$+ +zyMKJ1++pcXUtPh6#A7N#kUM0+VC=_-vwHI?0%BtQ+!+;JTTfvTTB%PKAE$36;{atZwLo-IzVK=MTo40~d%%>w^=?S6kL6e;0r +z*swKV$*QUg{MALbA&8?G*qUD0i?fIN*-6pI9`4({@(E5e4P+;Th594(sD@FHzO882 +z-J-2SZ>h1ywP*n5?t9kB)^Q5z()NI{BV%>+0hhF4rGrtB!)2>L#!BXR+eE9S7QL3G +zf06$B_Xu;cL-K=rVk-MK?cnw4b4w9a^e1=cgXeT2pB_#W3B3&Tg^CgL1QTRW`(GbP +zcF%k`1`PNnQL5~TNT>NZlN1wLsf<;_X*rb>L6PNZ=hZ5vZ#HUgQHdtDx0+e615z$| +z+a_WuzkxE09}of*fATipk&TD6!S}D@!z{D?0!)h2vbXCcA!hG$ts$=;US?<>y2$>| +zu)Rf?mc;8CkTK{&k& +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 +z;oSg1k*vum2Bp4q{RL7BXg|46T&{~~d(a;p +zM+18ys$wKBLh+WZvDK_{wgA-$<5hCBq~VUP;;vK}92;)?03_t<;f4Gf-d0Y%Zc@vZ +zN$@csVZLk${Kx6ea(2=cT;u%zXvhAkk9@l`;>2zVou;QFoL5H|6~DwOUAE2jmtcgK +z4gdfL|3RAYNvJ_=nM??8|Nf_h00f(j!MN$nVIIE#4$S{{=U9ubV97#}rx*~4PW5HS +zb%q0a{EqpRjxhlleR<3a-6vp1hZS5IgsTkyheS4utMs}4ck|M|NDJt1{@nKHss6HW +z?c>&Av7;ua8U7tw=Wi@$AGV` +zuc^cdM5`Y9XIS|zkEQ`zkN8)$Jw{0zCZ^td>Gb{IVnn-jV1`_1-OFR +zhSV&AK@pUW#+7Eny>@LaftsMp2<{0hNV +z?B!8bMt%l4T;VVWD-UBDG_S9SmA7z2S{P{6>ra)OjewXEQ)>=$=<%s79&#Fj#5}EJ +zywU*M+1@`|aG95#&Bt+Im!{FxrGvQk=K;@4VQo~u&e9!)5wGFBPW^Pu70zl~_T~FJ +zC-rUyJ;*-*=Oe0}|NH`4i5JRawI4p27bzifmjYnl=bYyxX4GWpsSaJBzV2CR!1)~6 +zH_bMPB!Tv&Ir_&N95T>Ce5}EyB#rDG7aLD&$l(7Zcopxz68xpy+t?d-A<6+h%@Gp(IkA8-c=R)d(^9(Z8eK}z4 +z4)(r~LEybCGwKk|?u3R{^Rn~nUC_&x%c7@E_nS}?H?2`(Hz*#C2}A)?(_1yCwo2*z +z=h_3BY5ru?_}`c~e96;7E2%^(8!!yr#W8Y8Fd;yyPlcXXYf{M9lF&H#T!vTj;JI9? +z8(7WaK2N&<5+pWn;;XcdXlgBZ-Lyp%UF2HRUY{=ad2o^hxlR}fL?d0Jw<~oM!h&3f +zhS%T2rtj0cW@rgI!M>;~Qi34EP9vdrLY&}iKfYP=;egI={l^vdb|Lb|VMF6964bX_ +zn#IUQV&zX&e`hZjQ%)G4H&C`N<4#KvX2Y(ewY*UwrA(*SA)!XGSyKm=k=iyl8zblI +z?z!MOYU$}vw8tV6FK+x2>s@|E{IwEVnc+t*nfGh~A20lNdlNST^!g?!qS?hH*LtuT +zHXhRgc;#SPP}?3Ks3ZlZX&&ojaGn0kKnsY%PlYwO_qQJ*S%s82hJ!=P +zkuuB3n_KWq1&zer?Kb +z?TLb7D(E&Jp`N#HZBv2~o{F2TmqH#*xw}kSb>)*E?mR_9JZL`+rJg}tj#SC&!NcgJ +zfeOK>TwN)H{T~M1&201gteu$SUZE}4iP=zg#%uo_fuNfpFx0lUBuHL>708CZ`Xh-a +zsIXyG*}zGb2SiE+648d#KCyq8kE1#4#6JGv{b%r8%PpOkV|6t8wa+TnxvQHbnvBhF +z%*PAp+RMPH1~+=d{7HGHVL4$lLEwzbugDs-bh)w&kE$Q{bDmb39yk^1&EX6brSRBw +z5ufYCFx&rnL!TUg><^OfYc(+GmjfmyZeYlq-~+Yxs8(pODrYb7?-*Wqjy(^nk6;o>RoP0YR-dF0Mt%|`qa?m#ar(*wIk16Wv +zfk|CYYg3;mQ|$x=gKS1bt5W!WJOJtmS1;a!ULE>j=vS=aJp*oRngtGT7%qe9q4EMi=04qRuTvKukLc>c>6OYqJdfoZb +za!8Vo9xxX^JT>A10ln_f3P=_$SZXh{XsIn9+PJ54zMFk}ifWajJu7wbuL>piaoj-4 +z7x7$${0+|QgINTVd+pvB=8{UdVE8E7q6D7WjR=YWYTf)L%R%)K1!~GjSmgR +z7dEs>i2I|55^P1UgzaOjRB%Vt^+?QpdDEYpfBAWnW^RDkWD7uD0eH!?ZdRC(Q$go+ +zt$S-TA`z$46v`vZAIl`_>cK}oPGMbn1LA$|E`>JS4a_C5NC4g`8gP|PDf-mET^P;d +zK~tdM8yExJI#emyeNgKT>iFIlh8*9e1u`f;#bLgtG6*V`rc+WRkF0>=K36D*$Y-TA+jGAP=3it$t2 +z(c{+KIoIO+n7`%}qin}AFB&9fkHF<)vrmSD2HLk6RXZ~j4NPWPJLd9doHtV`<) +z!JtU^d{lf@2i9%HtCW>WRTfU?%9t_m^wha1yUC_&(d3enA;ZTY!6Ovp3-^P!|F#h3 +zlv)}>&kVW7vQW2}dkyc)i$i5qBkGE%3tuu!3|6(s-l8#iNXr5Zp@HdDIy4 +zM>5}HUCEcUTP6Wk-q%6IdmBw=N%Q)d+-yK4ens2t?@_D)b2+~e_Jn5et+a>28|sh +z9-7cILwpiQ1Xn-q`1WYb2a@HE44c^Xz>z*jbIIaH|Dkn23V`gV&uOdTh1*OSWqEwEzh(KO&})6-`kS +zF>sjjFwvTgyG;Zv$yqYL_~rvA+Tb0AJJH%T({;}|s;}PD1cPZxWO}|%cDn*bhx14u +z49qxyM(7-T|Dz0Fd5ioWR74qqkDVl|?x`48t;ZN0WRN1al%YTrA&?y+!T{8HY5nlj +z?I>&Y<%gHbGuE@Ju4WBF^n>1jDq4W&P +z4zMHIiI5=~h?~eae)rug`I88@A@0rO>xSN^l&9iG=-VYGkqI(nV1JA{{BqK(IH1H&@0Pt!^_8wvt;t;fhD@81F-Q}(gH +zi?qfdv6m)!z{9Ki=I4mR7n8zLaTJxPO5J+?KHFESiyn*;MvLA)y~|jwFC+pOX~+HB +z&~_TgZl0NRqoyINasPzLxTFw~5{CHb95yB8BN-fb=CJ*79cE&Jy!T&VZ4t~ZjYvaM +zg48a~NpWkx#+=y{-*ll$#8|Yu#HW7fE7#c^ChW@ef~97})v%r>w!8n_eA3t00dbNp +z@N>6O5ehHkYsi_P$y&z1BuQo!!+xi7PC`X8D{sv0xWokFZzUTuiyEyzK8f>9h~}-{ +zR-kGMwk{L+UcXu_26s#kbdcS9fmdQz}80MV%>;z^wC-2qZ#%>7%g)pwu= +zoxNkbqQH*8iI1ftAJnSvQGVaZ!n`enz%`W^_Rcqe6-Uo6%z(UB+=O%FGw%iN?}Asd +zf!=b2zKY~dniN|(^l<-8gOiB1T-Oc&pmRi +zid)R9t>%^Cmjfx&` +zqaLu1si{S`ZVEayo(f(%aZRRF6h0s!39GM<1bIf~+m)Sx@jIHmXvVNrk@3(#M +z>@Nk&i@zanZ$W@Jzbo@j^J%Jeflj+n{qTsabg?CmdE(nz@tqX8000Mv0iP{&LVo}R +z$_y~Qz(=qK00@3`@GOsV51;%%Ml60Yo7i=Hq?JB*2YhwH9+8ky%LPC&PCl61b6VmY +zVf$VuNeZ04nQ +zs!z0u9C1_`Ty;T@bckOmM+%$(e1H8G;h^wIU&upHUK8FpZx``Z3*W~uDq^k*E7tOm5QM%gdLWild`9OhHd4U>h^lmJv~)NGD^dTZc=@ehx{8?o{Ax9=@m9^mVQvoo;m9&-AVFi76GbcgEx&#Qja +zQh9)0Y~;=Mt~Po^@X``WW@R7-u`s2EFmV5<8eri{s}p5lz6AiYVEIJ^y#KZvi?8$Y +z#*-x}nGj3h!~%ZiEc4ivDbVTh!)~BP_JAiU@q<5JWm;Gs1!mfzL9u@}-K0mTs}n-H +zqZLR#bTPECkP5`#zunAG=N`<4Pz2OiQZQ?jUe>{x@1x!^B-^mMNq5s&HMr5hZRJ(Z`Y52;K@U?&;q(AX$X4elZ3V?)>oh7iS#B{vr +zffZfDQPTI}eePINRSoRvi{+B(FiA)T+`ntltXRE)QHkjThGu;AYAHQ#$5lid_X{C< +z4>pg|L*^y<>-*9aIO(&6d7zt`j4Bzy(t{d5x5_EZ)&To^ff +z|H0ERe(CX7fPXnFS?#K_=DU33$U{1oSs$I$ZjutBpQdEmJ@fW?Z3%Zy$$gUS;5{Or +zO8Q6$BZq%hojUL;PEl5!`ICC&wYv;#_aCYWQ&?Mb+CMO&vWp{pPbB=snhO`!E}o^p +zo;IMM?_yeIfF(4CaY`MbX#qJUzXf{;?!*-$9jrOwuSB(Nyff#bPP-r0zDjcEUi9P( +zWD(SNl|v@>uP$cNmfMVL>u2m{2CNhXAb%Yo`gok%I@Sz5sV)Ca*Lp7-1PN81KQbNO +zcp!~A{aPd)pZ?9BeUP=klQ%;f6PE#gQ6A8pgv(aTc@-~E%|$yUZ6Y*RBR@7=Sk!F> +zNN{xL(zAN3x8Uc%Nkj6En7MJ>zL(3Y +ztY-#~#w=v1r1YS{T-~foE$<>k+vTYKvgm7)RlAUNPH9aZcHo`2WR28q1)Et?pH +z@-Nbf+wHI~ZbDk=fLa*~6J;H)f#QWPkX1;dUe0(lt6Ke1lOf|Jk4i|WH(wOD#ky9^ +zyYAf$A~Y4Xn?CwTR~Gc@Vby%>Wi77KzxOc)@p&1~Fi|!JmPT)#Xz@|#As&y9Y+tX% +zuuqkVBSY^P#~TopHeP0))xe#w6LZ_|V12vCT?dU&&FIh$OWTWQ{EM4MCH%;9VR2$s +zg3W`rDJU;qRgaIOmPK7v&pZuJeukCiVN}2)bbK3|uNgd+Mgmn>tQEB|u=*Lt8(d+s +z20RM93`_uA)jaMTqo-9AupX@c_`$@U_f|Kk6<9*c(6&kA7?$#}bf{z;QGz(m8kiBZ45{e#bNFeYF6ZG& +z*}+#_>2o5VI(l^HoB^n1ajf^H~}SsvYtWWca`6L`^jQM?(P +z4OuKHQFnipDyxTga2)fvVm|zP2?chO*^>X;h@_g`z0<`U5f*<5DtH)Ea1oSV5cuiI +zNO3l^B6rFGm?+kYr4N0}H#)BU(BYQR+33JEyvq*KZNJ482Bhq5(&PC}Bmow^vy({? +zGT!y+{>^b6c_8k_FYb{`B{@oM@ZHh*BHv+@w7p!NW0N3Idql^!ZQHgzJGO1xwr$%x +zwr$(Ct!z?n@*#iXcHKJX=|+!CI9GD>ylOEW6$H2|n%Or@R86+GW4J&1(}{gv9j7@n +zv6hh~Q0QQS>b_Y~x+bSMi+jcSbzliA%dMDZ^Jg`#1i0>B6bAz4(f{XE`0;>Z6 +zHt%4eKdXRO01msq~(dX_;KN$XVK2FII48j2X|d6I)io80&1pFZAB{iK@*NXoC0t^A)m +zw7Y~mLiiY+K9Akc-R~|-ypC&a!f(KKrT|QPPvU2;m_|Fzdf4)5&`wphW+%C69wxD6 +z5iZ0TPq$vogX@WTB&+}o6G$~` +z7Mw?|ZDc`t;YWT4LN?!$hLN#84OO{_^|n}xCLgOy_5MFy91mlmKtzGIUL9<{+p6i;+5 +ziMGW;^gE$e`QzhDHF7@rMa-8DW0q{(gS`DEA!DEflA{Qa#h<;;35MbT`L2_luO|~# +z-{=jBnjpu-n+y^3oyPAeOg=oI<#EkkCDPc4Z6>fOU3tX5P0`M1$tfJfw1{3`I8jH9 +z%dYQA8ox~#?!pVhckL;?)cs%c9vq$wENbm`er|gBDy``fxfcA~5-IUI(_Y2&l7K3! +zMJbnBiODWq9^rhH25$fm#i@xed4>1reXLnDAS +zs+g|)DmSb{^|80m_IlJUjX&pv{COVhMfn>Oz-krP>>pDhqH>Wh5B%Ct?N#*zQUQ#Z +zE>Dj5CJe>YwO#3PhGGmh=Bi5AvhMFuTbTd*SDA|nW`WG0F}(nmSPa|^PXEcHgDluH +z8Hdcx@DpciRo^1oqwG$4p)x1alUCV*7y%MnN|8?VO+vK5X$5@L4rLxk{Ky>^$H>l3 +zsb3VQ4pFg9wS^zn5((Vf!xq~IZrdmxRXh8+Q|qbh{95V_+eUaX(%=8I|G@mxF!=y+ +z8WY=|+c#kS(dm!9qz!rHwqV9O7~A`)W?qR#L8Q2$!O9{+iRPn_h{zIPPqc_*rY@Y% +z*3vEWVat>%c6~6gs21Jk+<2$sOJygZPeagIXw#V;UCrv#u3-LhxLJB5-kUSH=RqJr +z)^yqk;a<3HUmnF!cjS$!bK$u((1J>~Fi +z`{~LWn-%}5h*69;J?ifSiA4uAQP-&Xa>U&G;#!hzHP&U@AB;8)O{7~?uXeC}TjOR5iyvkFHhgKk_-E%Xe>yAr+*IF< +zT(?E*`AisYS91C29xO;L;KpHB+KvXT;;SFKs14u!tb+)j^Z;-n8k1{x4<N3<#rzMP}&+%g`Sv9iLohu6yNrw0o0DQ-1 +zc-_WA0c7%Obtxg@Vp}PMMUA|)&{8L+YOou;EwJ(JoreIq1?00;i7zQ9rkzBJ8#Q}M +zml+*S>bp4CwW|e1M}9Ie1^NJ+(q0#R@DXwyimqr9!g<!lj~Cq$0+1s3*1INt+ZO+pvW=h8H*`Z}ewm(2lMs_u>S7zBECr3Ze<`K? +zdNji^nhGeFmHOpEAp%iboX7a*C8bL{qNfrX8|E~G)9(CB;by@smjB1YV}W2#{<=)+ +z1JhR2x(>VEmG@$zF`2FydZ%P*bTHw_hB;Z0vRG9du4JbBfSLPB0 +z&kT>E0hdBvWR&-~=dXrT{uU>5%65Q!w7gL9%qQWC*rt(`vk*_bOTK3r?&l{VSyQFV +z%y)(g2m9`%b=2z8UjB5w>+d4NerM^Wg$5nEUgp{MnF|A&cf_u3tUBH)Y54m*2PD35 +zyIg?k$g(vs++B|0N(;W2z+`Q+Zx*jj#3RD%|E&b9oVaCoj%+#=-&{a41{2wb|KKT7 +zqnX(-R-|bP{`KSsO0VE72hi5DD+Nh1srlp;T{W>rO(qGl0rK@1D@T}WOuH_00OIhr +zk|p$J=|ODLp0*@s# +zgQ)h0=}9vkqD}B>WqKrMp+#*Rg?+2Oir(ReQ0jDFmeLe!)WVN2@ +zTF%3HwisVo=2-fl2P+r#-2$!*uyBm6@%2}@kDNjJF~OZLt+7;v8$_+nt+dQxDi7jT +z?(#0&UzruEk5CB0YuXkwHqe&}2iI{_HX&^8<4bLmG0Ew`*8A=C*wgB$8pygeHio$P +zY!#Z$SbG01IY(#k$o%t7gNpl2k8K^D7#fX-^jA7#`zSV?Sj;p`V(3S$i +zYF$tFc~G~9Wtm8mgZo6zt;Ujyg|}xjGH?<*3vM4JqTkp2wy`iuFFptANZVqvMsIq^ +zL)?MyWZbhX7hoy+io~7dBJ8T2H88P5`%kAP3s(35NXv(mbp^QUr`hpwl#cGnJfU=0 +z6&H?yj%0IfIuA711jXmfUhq7_#2%K#ToW_Pi* +znu+S!Wc9h$mtRcY@zX3k)#>tiUobBGNx_$vxDw{aTwIdCuLN*6to$$4ubL&)&-?B{t!-LIr=(DJ2N@0;LlV< +zoI%Szzu8PFRu#X;@jaS<#q$l+kj?JkyN31gw;&kUK;`8Jq*BMczyQKFi*GHn>fEA& +zenUgRFnjFXEH*9t;UQcvIt +zFi1)xigTTo!KX^p9WeaZ0@W-xjjvV=|4QyI66W?N8%Ia*9TiEWlKyE4yibYlY;;}* +z)(yg7!~Rfr6@cUn3g;h%;T_Rg=AC?HdnSyfU_IgMu(2YFbou7T+!?3bkn(Kv;A)vf%FQG^v4569FKH{++mo +z30iKxiF`Qp^H{FbH76eW>>qN*_aR`S0~a010#^X;ew!%a{gh1H2ahz$xy~o`@xfHo +zB@B{(*!13`HV&ZD>~7Fm)MDSRh`A4N^w7q9NU;Tp?EC71*>whGe03_t2$tblzyRH1 +z4w)0f3dFa?27R4X4Qz1VbH~hydeIO5jeSJ`qorr3p!Dbv*3=M0m+lP&B3Y$pU?G3A +zk#U0X+)}=1HyQ8bsLxMvk&i8|Ncca;2O~gt)?>h5jRn+z&)Hnhosn>YBPseXyUlTZ +zea@B6eOq~F+}n~ZEXJkav`9U82lP|{{;X>80yce{XJ^4rFR~+XkDgv;6!`pwA<(GaNHlMQ)Y?HS~w8W8@iMFwsCg +z*aBiJcv?C^Sz)cTx`eg@=TJWLmtvx6av7F(?6tMRjbbED=*G-sod{#lE8(}VeSaz6 +zi!V7?;CVNr?gdg}hnvxc8)j<;W%~D`{Ht2Q6wFinUy7~%f)PLo=-UUvr!ju@4c+WE +z^!`-K5QC-NTKOiC;FbJx?7CXSjsqg4`O!1eMHGYYBwTDpq1 +zYEy5uH8Rr|M@v@pjmd2f!C%6ITxSsRcUW1Hj@p@=OZSHwNRo!wR9F@6@8AvjEX_rNyPG!%j57baB +zNo{}ArmWh%3}#|WTdVy@bESIwL9|g261L3Dl!DqZTUNlT1CMD0jx6qy!L4~u9@wYu +zGsKRHmt9t)?Ut(rC*N0nJF|qh$ps?;PXCd1_6DI5QMdFyKEP|Ax@d9n=@cTrOkH>z +z-K_`PA{giE!&P}}@JkV(p$GMGFhZdf9%+i7XpAAJd7)U)%AmB!>=k|`L$ZTIu%tjH +zH4z+smcR~2#|%C#HsN=>G`z+<3XLZqnozG25#IuzeH8Z6Yec7Rg+$I_j_RJ|J(8bn +z=CFJv8FQSd0=QCCD@zjvS%@43rkrPIS-Gx_A>9gy<|D52?`w6?CIr=CtV>BYRd~2S&7uwobF=sY)$* +z%wYU`p}15{C^|&3_f}5-!OB96JPszJCp0PiXK6N=bEDlMS*#jO^G2&^8dCUK)g2Uj +z!xumERlqE@L0rOy3bVZ8tZindMSi#U+~F*SOcTg)D0D!wrIY|>LA1yrH5X-{debC^ +zA^XM6{vIQvgZkZXx0-FGk7fy85CL#OTY}8X?iBKn2AI(HTpmq>LyfmfyRQqKh|zLb +z9T4O1+kJ@_2F=7*IbhM=l6glR{;IY^gKb$^ZTa+k3-tE*+q+=~Uo^Zspau3)94))Z +z<;a46M3Al5NAD8j(OR$0XdQL?7bJ=H9up=4$1}1>IohIBhZ43ilu&#YVuwN98N_LV +z+6s`bQ(P;jPsohqs~p2|gJp!>0U_N;MDQG@0Pl<)@=-rUWV6|V_89lpqqj7DE9EUy +z04&C4ia4JuM-BzBC0+p9)VKLn#3VayR#Nzb#8p28ZV5r29MWiem(hjVgsuL-I%g1# +zGmkK4shS{v)wm^WgxO#*WaTuy#oj3rJpVZ=AFcf{L^HLvjH@6uW5J{LOixbLV7;AYaGSdhOh%g;E +zQ_8=h{KmaXWBcp}ntQGf`)=|=4S@QKH2f1HbpQ)aop?Cr3t$2GM`}+tO|ODy@|H*; +z?P{L`P>Ex*s@VLHN;R$<_ho=n*Vg-<&c6F9%uC0qBQm!8ZmL6ygkB{{pjGGPBz2); +z3Fc?zqsv5-6%eZckO+Qn+@#uR +z6zbl+8Y7Vb+};o}_0BTPL1)?cQ|an3GgPAWJt3QbV3tGG#IVCPM<=Ig@4f(5biE)y +zD|(1m;BxWQ6#9`r_%8vc&(8r8SJQU>J#*0NxEa`2@d$V6&;*YMzB{xos&2o!9-rv} +zulTxm^RlisTW5|~yRiNs^jub%C4C{l7-I!`ZVhR@B^mo-d}bklp+Z{fS=?arZ8*b6sxonQ^2ppRjvbNpB$#&Trrz%cKWAq+~3(<_;ixi93trBiVu|sWh +zdY)v~A4)E@iowjmaU^E*nS$2apvgow41j%U{P@ +z1S34OHanig_zg46ib1MrcVxd%C!DB;Bpy!%F#Q?>wmZ?4vT|*)0CSvtvK}bIm~%j2 +zjxfd+Ml?Qz#C12t_)<`(VVDb}HinoZXq~qj&~m{WV!o_9&hx!h +z*0@~7*%KrWPCGODex_OEEqq<4oVpf1ywIgLg0E^m5T1|Lfk6ET;o$NLaJd{c8H?N6 +zwM%y+uk^bcTQfX>WZi`;yOEH4E)(>f*yEXas8fa(ak;t-m_}V0r`P+{E&jq}o70p_ +zI3PD@t7CTS3XBa1o`rUV`~QCR`G9#2|H0hW?p8#}=KlXM_k{|nT~r>Mym(-WT@%$K +zA>O$5+@pIog2*-drDzc+*qMx)%I}6IYzUJ0?A9E0lQHQdG~({{7HnSTnUM8+JVSco +zb2c?#NB21t+4hXC;kv3@Elo{JJBL!}4lW6;|3BO^$O7K@%&mpTw;cccQPo%+!Q1{V +z$A3~9fVI+!;id=CeL~s^Yglhd3?t|@EGO_#h($tUVALWu@s1OS+2UWdxl+C19xq9Y +z77hB;2JCKKQ%)~F+m=BMAhV0ffu22sGQHFz;NfYv>Ds=MCozv^0(z!j|4+gEPIWY% +z1c%)Qg<{$xgWR*P*`W{oF@ynjfkv+Hdu?9?U{2s-x(^JyOK0VjfCi=m{N|8Bux&GC +z)fkFc5qi!w@Nods8Eh4B@vgw7K@`=&PUe%cMp`g55~jX`F|Arfv-J@qoECqJHo +z9(q_YK}g|kyJy!36k1O_Ay=+M1hzvAd=+++sX;)nI0~}Upl`Xi?LfI+a}4i2Cb)nE +z!(QfhFuKRXT~~WJq<=gW>3jjY6yk5>2$Us2qi#S_f2p(IPg6CL|1@-93zZ; +zz{+Tlcs>-!=;M}nwR8epwG{_31^oaMtKk$14ir}LE%ic>OplO6~UTjh{cQz5Xp@>;u`E4J<}+2iekrA0iYawM2kWwEI?fu +zaw?g%Rs|9FhM(pfCe#lxqx^NM+1ED#q$;Hn%Dq>nX-75FhC_w>M%|bk=U0RGB{s59 +z9LcE^d0i6oJx$qLy0C!LET5HaoB(OGbubohkO_V=U?3i?A+CRcu!}p=ldp$81IA`1f2jTk +z_Nd4TPzw-%tSvcb>T%>3wax(C9z5Lyk|ri3JM)VO8=SpX^h +zcD!VYF^_7#EY$@;&fink4}-V!&#BZL)k4PKI3za3e$+E*soB#H9Es^|=8c%IDqv}> +zN-hlg(ZP#XRJ2Y!HQMDR2MD|jDL7LZx@8IpOAHoYN-DCK_+!d+gSl;8hL;JDd_tfU +zvcAMtWE#}wtyOsno^X@dl>I0>rLYG3Q0~J{aX^YBc^o;P=3nTYs~iI +z1=q}a7gm)OV;BbMasRo^)lM_Hu()Hbhl%FsdzTbE#!Osb~Blzx2orXjdJ?oYNeP#fA+dcL>D%XQP-hKX(GS1-!*y +zU$q(ZRVm;vL0_#xrFV^DT=OvlpXnei3M9{jQGY2mlKYU?yp?{~&{qjzk9G$!eMP8+ +z*X#21_{Mj)d;McvP;pw-tp7rSBZqp!Dpt- +z#(01;`A@A6X$G>^YlX;>pJ=hI$&tR5{MCZsqF7tD$83)10I8!L3eI$I+x)#|viWVt +zpfi1(o0PCu)tgr02TA`ml!d^PG1k&5BFDjIBwLqp3f1#K$Zx*FT8gg~lf5PaWr6Og +zr_MJ>^JiRW+XNAtN=H#0eLqE}r)zt?+Zs&`RiucRa5TLO1m_9&T0{_n-U2lB53Z#8 +zc6tChbeBbF5R&sT)^iFDk^3ZMTkty?BY46Kf#z?7V338aTmAdy2h&BoNmlTRqS{9H +z4SN$t*ucv3kb123BD4&JRJ2|&>&u*3ijF7O?E4YdR!8qglPgyJ!gW4TB_Y-X+l(iP +zpNcm7H<4f?8n#Ddy*-N)_T7MPko9UUhar0iOr-%C#Q!Oxk1B>vCIXwgBvmh{&(dEC +zBo1pY+=Y>_5Ge)JhXxRQ&WBz!tuAG>F&^#bVr(i%8$d4su1!M<9=cvj`?Ngi#b2W& +zL&k}-HbIt-Hd)K%4bH4oF({`Owj7vq;~UAYJYY?{hfzUTcNL<(IEEQD@4qk6ya4l@ +z{)c~$NM*ljzn5=hQ}%)Iy74ZwyZ~WKz%`a@q5YUi&wMP7EcgJk=pf!#4q4U1lHSdS +zGXgR}Y(3&D#|`<^`$@TK6&gE9_2H%0K22V2SUkq}1EHlU$Y%!A$hnPC2A9dJDfA3f +z_dioWx5TTP +zj_;rql%n7iqgj1x)$JW+<#D;5h*SbTykXeM +zCB}O#`Qs>Zstx`Or8(i;X6ue%w2g!8Y67)?AA~GLjOJ|w5qdqC;o;(`MU+dfH`KO_ +z>3H}grqD%-jZV6JbYPDxpW;=7-^ei!#|4j;UJhYXKk4a&O1Eq$K+*CkKaUz~^)WvX +z(JZ9g0kT0ry^76CB8<(^$27lNF$~Nh#X|U-PnU}*$r>^A0xX9CCu}9V!(PRs0zVYo +zsP~+rm-l`2jqS==(B?OakHKHtI!59_7C>x88dk}`q;Hz|0hR2u0W-D+1@u$D!HM4S +zft(5{K!b!qfUs!vD)nH0D2{!f#X}28I9nTi2?V==2Wc_}VtU^ge#-z9V3nK}(Tk5> +zrHFngNYh6Ofz<(ZW`m_vPr&TtpdUbh83VHoEWpq^2c|vnv4ZD;ys?Cna>X(K +zGx(-&$qE|H2zdt;K79mEi`d8)+T9loJ(fdL_zp$qecPf%NLlxLVci-lkUG-{$jH!G~)x00JHJ_x=H11Dt9=0)&NXzd;haQVMs!=v2B~`@(N+t +zR5x~tPzOIFsL4_&+A2hG>F-w3F9C$uNC3NqnVG;R1(qJfgnBuqav3 +zh`6STbD1dJhu*KISoJa%#*cfHaUyHsVPL+P@nG>@;wVO24KGm*s6UdS{weC?^rO|I&oZ!8U~%9B(lwwR%_ZD^cS+<2%w>Fw{>O)@T97r +zE#f2g=dGuJel3kd)>1mHiW9>PwL8AJ;29EsF6LkuGcc~KZxHt1a@YkU@!C{+ +z41gBCa^coNN0y0Fr6g-`3+356%p}3+@|1pn$W0zK6hYbJ=CS*CR6=#NH6U>~n{AB{ +z9oAi#l_!MZI?!VYwRITs|;s!ZCw{_n1Jm9T~5q?NY9Dr(fD +zs{pK3Fq4DLQl+`LiQ0D#{>UWDMTL`}Wk?2Myx*am#A_U%8_#oL@-T?CdMlw!J#4rj +zD}YaMGm&Z5)PHz1fW!hhayrV6w8-# +zpL_z`5zK$vdna#Ee)s&vWpp3*$4<6#h)qL=j5a~72t~9ogXZ#-_5F^}u-_4)2uro( +zUVcgRL#O$zlD1xwJ@rXEgPC#MPYAFPhJC^4{L=H+aU!tf`om{A7*gX;0%(LEV<=TRcz#tB+IX~0w$lrU6Z*k{}%Trbv +zc0iq~%B;HR-DN2{vUJ|MhTm{k(Q6xQEni3 +z_SU!I0=Iq?L(i2j!-Nr{u6`YoVjgSP2yUFuB~=ng(aJ&p!O21}6QOw=Cq2y9wuXf- +z2Rmxx^^8M%V%I`FRCZIRo9P>_b{#{3k!k~gSCQ2e8<#2 +z_6m9;JpjO>gFc^EE=J9R$>(gr5U>$d50n3n!ZuJ5(aCb0%* +z#-aClYUSK?*vrdb;m96&|I>Pvk%wMz0~LYUIBOS7oZ~hc0NwSv%q!jyAOvWFU|PmW +z6KdjA9P;=H!*voc=P#LLtL>bn=AqrRQ@G=n5;D>Q`t>C^-M$ofv>vwhRw1Ku7uw@} +z^yI6N9?$KEU!?Gb2Fou>{-#y-LTX6vu_ir2;R94m*Ph;*BGdYZC`NTaY4HPs-oyp8 +z1{UB8bMsfzl#>R~!=zxNT}2764#O^XirqKoFm)W}YLlN?-w)Qbi?>a*N!P4f;_G%H +z3kz&d&cz4|w0DAZYO`Ktpn*0PclBqwHA +z$R89sk<&ygSyu@6N5n6*&}nAa?I_?Fr%uyb8K!?VY*=@=kn4HT0996nLt!amwMqXJ +zR^jj3B<(=MWx18CI!gfchc}q8#d?{nVWk|dXKnRD)vt76Mv*7DGI-1)w9!>#4?5t-8RVmyQWE;k9OFM!b5~%fnTYdm)S^5xOhXdk@do$6j_q>Gu%n&1_ +zvS^^Lxx`%{pnDS-ySL1l+u}jUwX$Zny)Do7QrZIN!N8YnRWat|NALUl64IX2MRNLz +zS}0X}nBE3KW=LaSS^${q1J03iN#swgqFt)&*<*QdgPG}nD%1C+lP&#QkhdngavLbM +zuAARR!C)Wzy#|rMbustoLfNzy`5-0P=qKtZ-nSgxqAz0~G=q|@SZNk-z= +zn&U#cN!{*&h8Kyp&i!3nh*f!s^GJd)h+w7=Cz>d`7dNwN&cP#{$kp-CGQFbfbNEnZ +z821wv5@h*IvL9#rjwy(hx052XJUn|;jS`h{%hXJ=#O$gr;AXkVu=#O?%7!mHuwJzw +zNE?2U9b=e`2s%MrS^KaRGWwii}Oy +zr-@S$v|Ba*$}Gwbs^O+^TMZURQ04Wkl8M&`9$#f#xP*3IvmkibeL~G61ZswF%u=U=q7-SYdA3IIw+@7 +z61?Krz@STHoL7O89@PD*Av|8_uM91tK0NV-^mw>;J%A_jUB5a&MX){A++ftdDfq_r +z&~u7w9KY&3o0ka|^%|JuL#9S+LVz~PFD7;zXfu;qBb*p$zsy;z8D5OIODaUWrtie! +zS>UUWmy?6+CIH2$);-uARnBL{q1{JwLg!|7x* +ztiAdo^NmRaM}z?QFf1hH&E|r+?H!5FYNY0#isc;IFg9&?cwO+xAPp}@xI?A7No!|v +z5vZYzR`I3LSm9tRNqHNZQN+=T>twmaFIjb_1Jc#12ye`gdaC*BXV9_a^iMb6Grhl4 +z+n*IBacu0Z3=zFt{7n!LNHE;j4g}IihOrGGfu~{aWh<#KrxCx-HkURwy8o^>XygAx +zHK1kCZ6)1xuf{OD->_~cU{|lwVdt1R+wQEp7BnQrYu0w>l=>Vr7d +zBp);{TQz5;U*o)^4in@q+MU~GvSd88%zb1y5>SFXma?ZeAVYnfdBQmIu&sMic-v<6 +zY0!J2%G99-p5_R%XoPuk4TPw(4Faf}c-IY-ZJCzR)uRmLH;Ea&kH{Eg^&z1>^D=Kg +z$y;E^!V7F|CJ5WIs?&PT74jCQM!u2pi}6(epVGVosv@2O%wqT7oXd@OP~&1`0mya+ +z_yI&VTUbjp7gHC|vZgjIetzsaQGk#XY`Q8jNp$YVbqr_c2dXq5S=YWJKTu{@_)AWlN?-YZ^@^LoQlCcfMz>rW5Qu?E=a546a9a$q*qqq(Sa4;zaE% +z5Wu+x6v?j3J}E_f9E;&kmU7*4+7s`lxwfb=aIz$>PFwa?bj0^3eYWOmohqMrPfa?L +zH4fG@;Sa(h7Fi$-?ZlKTYtsuEg;Jl}Odi58g-Jo4mHJC8E>xUD25Gtc_{lTjiiF#bY`~xcO*5ywx +z%HWOj1f$AS(|&GF5CIk+G{T7}#PW9pSDLbqqWSqjA0zkf!a#^FoaJ3Uaxqu(mxIWw +ztf*RH2X|e22Z>v+K+%s<7s6mc5^3cp*o89*2uS1D&!*U7>(=UJxc<(ma7JE+N&ihI +zV@u`@x9~0QR~VF>Ir=I$pX#4G4D-v_4y?D1-aYR-P31%%f}|=sBoSNZQ)hk!=aYWTKMBh_~m2 +z+g@Nu-2_0{a$vFnuJ&x6Nruksc~K?kmf_KMn8kAMABcp7bNIwfCXQ;bU60?IHayzh +z0!R1Uw1ez1sT06XUnu~_+U~;e-U2)vVD}GQHk(rT{u~(Xng&l*zB$2-8L<_j9)NPD26fV25v;ocKxtn+<4tmf)%8_ +zHxOfonKIdeKH4a{G-%B_x6Y*NR47J9*@*9Z#W2XDCvr3bdA=Zvi*)&~dB7wKluhP6 +z<5G>E;BoTmq=)3d`80?$>*U3TMHO9S#_-XoC@!MR8CnL4sJLqw9Q+l2^EQ^j|8B0C +zqACVQ(`KPG2WtV;;Im?1(SQM~H6ZOtgaQ4^QYpxW@--Ok4$M1gXAM3ZEic^H%5fNS24C<0?$Z~h>( +zHw6wbe{ouSuE+bbNXo$0fetGlKlLL>rmgXKZ4PnIk?j@Jzx35KVQICeY`I$ak039DbWeu0Gh6z)=g_}hyD?ZOiSfJj +z*7Li<{?kBks{o#_h!kM`h}hp)X#lZ1GRL5LPQ*fZ0DRd$XA}&M`wylZz1ta@`A920 +zJsIFv@OjXjTJN8L9n|4G)ca`kQB5?Wu6EmTWlC3kKKBlOpScq)9oy11=AkC8gx(}e?p8u9ke@{Z~|#-V}-P^!j3_G;eg@7 +z-!72x;l +zMOANe!yrAoaGZeo^g@3(eT&v7zw@ILg8$QQ%WCN>+%tj~;EeZ_Eo|fMA^BB4K7@Fu +zWsT$sRT7N_Pud+j`dXHMF39tZ{9wXzEIbo6#b`BPH+VgTe2{*7>OMyt1~!G~GCy2B +zWRSA$_jqp7!$8!7?F6J>8m_z|Mldji3c{o=AXp +zqW6%#RrmlF=na>k%xB_=P__-f{Ix4nmJ?E8*R#M%h8IrCS +zRinpm!Qu@zsAWSRoC9TnsvY2dB3F8X5AQ8Tl^9qtk-8GLhtFscjVCaTc+Z5deRAsR +zPy_}r&Zh#J)9)!L4o3M;ey)5>){R4n*uf7hiUrj=weKqEs#0bV7y+D%w~~QM1X0O)5EAL@MwUh7N>yUhmrk{3+`)uY@Z2Um)(%bzaY`xu +zBZC^e7JK}h+PSj=Z_BI6gy|vupRj}52U6zo-F_4mND#HBp~1N`N9Q&~s{fPkR)D(6 +z*HKIrRo&UJ?l7sJ7$7$0PJUp{Ec +zrK+t8Ywlm-M*!wE|A$#WHNI(URRaW%y9jxof0tLQN7Deqm@F4UdH`#xae^%7Xei9c +zO9tMzI%aKYPwn57DhBkQtV+>~|D>a*5{)d!@7LmgrA>U{=`ll@sAm82#tZ5vE)Vm~ +zlS7cLqn@l^`EO&_8xT>G*KcNZ<@u;Ym54rHK9iiwO;~^yGww&rMF~Qb|(IVB9F%~(32|BwOpf?jnnNTVq32TuzK +z(oxo3%a;2reEqQei;~oF2$#|Z4TNwH0>6ld +z(NYyhkbN82Gm4b}6^s>Ol2iN(2uagNQ5|)t4{Wm|QBHw76&XtaKy4E=TL?Q!i=FJ1 +zku`+=t?kJOFOI!~M0|hEcmOUXX5J_@S2QnqCm1~eugRNLPoW6NntbX_l4UF21k?`7 +zUhDJm)BF<%t8%MWF0wtjc-|@(n@l70dzUb{o_qnu4M8tJlC)g6xRVev`Zp5>_i<9} +zD*JbB$;cTl%po_7SNz$>I>?&5^J8`Z^uyYgT(L!71C4^I9}VjTSKpbDY3&+d1M^75 +zByWRpxbd#kY1F{V`3Pkh{Z;?395#3h0>;>pUHa85a_;>TwYhsY(hD{zU3t+8kC3vB +zN*iCXX71lZx@}MI^i3@0guj +z`^4_JV-@s^#7}7Wgq-J|fZUJA;5Bp1K%{Tj?uLypRwL!>^dc`W@j0j^Tx)>~#XK^H +z2svcr^y!^P-wCBTK-M$u){O}nO}!q(Mf(LSpZNjmsgiEQ2cxz)=n(Q#Y@iVt20hYk +z6T(Miw;Ir9#XwO=ieZ}&OoecPhO&j{QH0AFTQpwIn{!5BEX>x{}z&lKceOhIs1 +zecEEcN`VX)5Z7R$$vNo>V$)0Nt#T7wFs82K;KMsMLCkxHZBpM4lEFOhVfY?-%n)0} +zYM4(*Ip6fDcQM^1%Kl6}?jwf2=Rf7EqNephl@9c@I)w+va9S7VM#Tk{GXJ*FRDMVr +z@Ngql&~xtHrhHJx0YX3|&S=FBpMMuE48?!D_og{%fBtybG= +zy1B% +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 +z97}r67cz!Z)hS#_`Hc|KMPK6_?(| +zMf#E3G#SSbo?>kXoU3jL21Rhw2zvB?nTbO)${U?gtW&q&G;FT9K@(vb?06kag_&=l +z;yk!h4*&HW{Dj>pG7T}(+>5q!K~bHvL*NcH^F1zTVi8;Q8S4ua?ZsxpOD5?Waa1$w +z%;1DGj9R$?-=Mb;z7BEYNco#J5J{u1uP9w@#}si~Jraro%*tSiN^5eb8{$ZxOR?Bm;9Y +zC?*14+8+D`SrgXE4S*D(OC2WbgnyZ~Ir2~$$f^>#@Ol>AS#(z8umAuD`9YuBMHMV7 +z{{RE6Szqv=$7D#>077##{k|-@cC70bFKkNU&}ZQhf`qJI&KKST7t0THgh=&Rn|{ +zeptAR{6A+kx}H8=@~SXRpff8wbsE#`F&sGp0?^En`;*feL#|v(zhAdR={J+tRSoac +zYGPh>;c%=W*52ZbH`XGBGxR|Q=TH;lBE(;RD>{ZNjV#0!XQvg9``K3fI(`Oqk{IHo +z-lMO=zzwWp`ptXPF&eN#~})fqrm&<3g*Y@n&b +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 +zKt7!>lZ=2wx?P}J+LParE2_vu +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 +zs^*!SfgxNh8PD8Es+4~i!@MR +zeTo328jvWfUN@1N3R`c4I=iy59^f>QvM5l&!zKxrx=uXHj_#~I#t<~Eww!62aL6C0 +z(huAsRSDs&hsavwAw^m_d-qN>!Jh17R2n>>db6K0;EI`0+8YKYeM=y~=xfqZOT=Suxe(l_GXZrRH8UG#8T;I2tm_x!dO`n`6%|4Qqb452%P})^F>bm(0GZncR +zZnon!f-&wy?4IZ$^g_WdW{omz$Kv?!&?$rkM6hV=segz(eZ@#a4?D>S&Rwc!?aU`i +zEHtYn#xiZpCbt>~qMmfRmbKBVwjO}BkZA}37)WN_@&tjlW_;FZmrudH|U5`EfdG_RxSRs1^sMKH2 +zV>!R`B?-(8M*MQ@wF(6%$*$#9z}V*)@S29n7p(y&0eTMfHE&=bOE3tmHS~_}Z}0sz +zeD$S^VGJ%uK@e8=nZsPrw27=5U_$ENFDjMFlBzX}L!H|8ZY<0`nR5#iS+x47%plI$ +zPiVo>_dQSH)@O4dC)S~)jN)+K;FEU^UEMgY7QWUdSlwL_&F4;cR>9~E+>;~b)blZ4 +z2?nMz`!ZS50*$G5X|-ku(brl`4bR==9F@7&z41e5q`W3o$L5n +z1>q0y+Yevc=z%FJmC(D(*J!Jttk4Gq&{u0vab0j>h%~{>>u@|yq$|3ZeUqOSAK0#4 +zS}#jUSa*eOcjvCm1!bT=T#b<5vGi?(lvU&@!Zv_tgMWTA2$u?sZiIhVuQn!ngbBDN +z>4!iIR`X3H6HbH>0U{Pqrw)6)1T@2)Rq={aqBXY|$f@P!El@YIwGusnW-rDPZ=M`% +zQ|8C4A0xW_zTf*1P%`$JwzIt|6!No1gmUy79z+hD4E(G?%hAa&k8J?(4Sn67fq|u{ +z1gMaQ)T~5J&M8>z9hleIk2XHlz;oqrqxJs-Fzy&6l1LSKp4D#8EiUK`8r;5N)<2x4=$i9 +zfd%_K!ZQk4wUAt^CdOFYK{dJnLkH{v#=Rb7G|0d5TOMSUC+k^aDQ)r1h_O9%eWb;x +zTSg?OpuwQh!hIj4zp@Bd*5OH0T{3p-vQJ+|IS%De-)RI5Hk{Coy +z>w3qk7o|ki_&UGmkOOki8w8@hI`Mf +zw{_h&;ur*KV +z+J$JvOAo{l4)(cW@;#`0iox-VdV;ntshv>*0Z~sBnrs#o6po0?BE|~faHrjBmZyh3 +z%e8$3q?XENaWP*&T@|Fm=pRrQEdU?Ibn^KlL~hTVE#xtE4nmjhTYNOXx!+w+r2|j; +z&1E1xwJ7vQIbC`|?%WCNH2sZhnjch=RMr1JZeLrx7(L-hgU6-`Mt86JU43>+sCLuaPE1TenF^-LFXAI|; +zZc-XNtn=~IB;ZFq9oC3ve)8g-AvVB)&s-jE*R|Sr&i5Sr*J+)Wb~y9(s>y`F226S07n8s^5>z4>K7R1XR8jE`iL5U`fwtI$7Lfk +zmlNa98jZDaTN2Ya7_U_Y2*S=`)8=cnSOe=Aii_!eGK~B>D +zJ-n1!UGeLl7vAPatRNp1+&a!{n|fO`|EGB;lT3T^;*7>N4|<+?;5;FsG#qgbRc#tN +ztq-;q*m)c=3V{Fs2lzpr9z_)_EB^okty${a5gR8PSOE#ok=+IV`*s3YJv#5MQ28jP +zdaTNPCWKcfp>R8c6|pqtvHfSslJ4NQ4{60i13Q{bx9=_y71+vL*t&rE>E5a8cfYvx +z7ixhW!N~uDU#CB!oG8%I)ZYEi%{}El9G_1V7Fo;&>CKzGk+7p$l=@F@@j{MC;X#( +z*!i)Z93V31lGg;zp}k=03{j}@zRq1AkV}htsCE}V4=#Zhc+;8_vcc29k~sSzoUZFW +zPS(Fw*WfrMvZITX(sUFyL`1pnE&0ryunmq9e^Q32kRNbN28q +z8of7)7pnR3cPfyZ>gWV*cb|$teOv6f1VD9JDiV3omA_4gnhRJB7-^^(8D{M<6( +zHNV8_mGgCLdk47L@#;6vHrTjY-9w%`eRYSvEFYeusA`Z0h08wu5X(tRkBCg{vhnv@ +zOAB?pD;AOoqUB95n<#gWGIE%SAOGmFX%G1Bhwla1js;qznPPKtl-a4Ur1Sqm?l{%S +zG_30NCyw5bB2qlcJcS${K6c!Y3F#XOuT)2RL?*&} +zs>&;TFElDu3UIDg)ZUdpcBsVV2*oJD1XB5^%p!G8zsuZJ)-f*2UU2dmljr{nShnfN +zp_g27bJTP*K(aNs5;98+=jWe7J0^m$iPRDOO+LG2#hlPExz&eu=%-jtBu37T8$SFEM`1m@ +zHW~#FdcHD0MALV)vj`(-I0=ZM2=cvP_e>_SyJ#a=eY{v0?_EIaVTB|kTZ +z8@n=}3|bJTFEud0AAGz)LUf9U78(@mJ(C@DhQg8f9=SvJ3v`I+A}TaBB*`N}0%fmm +z1vRfkeX*e8<`+x+P|+DqwJAj|l}dVhHo_VjI^vJ#5&#*Pdf~zD<0iGm)3FODAm2UU +z_X?*vlQRl3qbaTOokr?ks>^_dGqYjv5j4=u9FmMt6>h!5+ihuWixcS@O2c2~SDlN# +z^0w;Q8|GIU7nL->C<8qZk}ma~R>IiXBFrR=rQ8J$qU8jqw|^o*(}BS$lCNocg$UK~ +z9cNm|v$q+vq5=qGi<)n6&OPrmGHTJ*-5PEgI@hJFiy3W9oV0R^;W1BS#K6rr%W!@= +zCwI*bU%NG0fwEC?{p{&zp&NM-E8i~}(SAUxB}!X1Y!UK^@IH#vI97FKsfBas_B8dL +zcPW0!UUGnbiadGmMl2KcfVGE0F;V=;vUf5Gj@tLxC1S>o{T9QWm%^;?${-1JPC|WA +zXpE)ZmTWrL4%LIYu)-t8zHqsUK+5c-6k77~FjU +z-9OHh`@U?ZI$k!4S9(4q*;)hk17bh^Aqp{^L+GuC06>Yk^QFX+b_w21q8{)^tr)C6 +zd@S?Q@yz>tcg_#HS$t5b_m3eIFocK0#`jsKA+`hL5!?BdHY*neNOlg?j2WzeR<01d +z`(wTWf;qSV!`_9Cwr65P37FQfxMVg+ +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 +zFj~-E$F^a~0KLct>?{C=qVA5}k&8p0q* +z!_yR8wb~mz-cSp&>#u+ZxLM?UlTkJBCUy8!$wb?g?&th-C?Rg>R)+({aF~vuJeM(B +zpDrx)qpJ|WK^=C%W!9e&LmNQ6rzPcB`-|~gyfi$Wa@-aP`Ma)wj&enOK$^)00sTi) +zXTs&wZ}2kOH1loqQ-|4sctXa26M_7()D-6r^w6P3C=vna+jS +zVzFD#VzQ3&HMCmeCSTwm&jlX#Z`?@k1DwzQW$$Aq-Kg?W*Y$U{t +zxYj4ydSEMD&KaD2)fu|D)J(|{5-9;+^r*CE2YC`E6|j-6sQy!4aCjo3qJzh?cb&>P +zo+F*0jj#7x7J{XrOLy?nbZYK;r?ep@h4?Bz2otn?@d&|zn<3kBZoS95t|wpJe^)(Q +z)t1<C!CKa +zGkOL+%pch#d*5OBYe-dUYvYxxs#+G)l?c00Xx2Xu3rTknPBuk2DNR|Phb{1y!Zft!1`msK8%8K&2$kj{M{P0O0h2_jmF(}Q!U +z)z4ubjxJfU6`c*7hRZWU=T%v@{xKt?$~4UJ-*b8x#r|54^9#a_e8>rDf}p^11$7EJ +zIJ8-Q75U}lWS&}L(glHcc+-Rbpv7plmUDg4J^56}Ks-vl3S`66tt{pUse;`Fq56P_ +z=1Uh$krzYAK;?0aG5!bSVZlt2|Hp{O48+Is7wZZDy2AOflW+mo2kpT{<1rQUv2QeV +z{#<@CR5=>33`$hhtSFmLNoQlzl+L+7S}rO>Q#E1X()blp8Y@Ij(acVMZGIScQ>Z(L +z_2ezqP+G7!fCxHRI#Cl5+uTo0V6~Cwvb9(1SviX%?VBTKo3auAFpV?S`h>m@8;dZ{ +z!K~b~_4R8i#1&kVL~os4PiIFXKNEf8-6Xm*lmF8}GIXUs=sEt*(ksNpRu*@->j0I) +zM?GIR?u-98A~WO&4w +zEh1e%lX>fM-y0@n=|-$)Cfm_&dzh6UQ&w3<@khM+6k3_k(|Q8z)Y*T04pLn~1MlyW +z8A!j&QXtiVDK_JpBb|-jh!uwRggG1Y)~Qrh@c0O|S*sK2hh_T*{B`XJD#mfaKD%~! +zkoXt25MXel9#>c4vyE2I;V@D&G=VI@SGfF+joT`2*g+xvh>C6UJ%xLNCoR28EHvoF +zZ9N~|AbA>3nng9)CA3gGM0R^Z37M}8*G@XAgql+$*f6vZy<~4tS*)mR%xbm_KuF1U +zjm!gk$?ae-v=d`Sb)H4Db~Z$~IT&*3ECS@1!Hm$G%vEHBNAx-2)Cfwyze0F}jt`cI +z6`S58kYz}0+GqfE;VbG(&^=X?^;0 +zv>Cp2{~Jboah4v{yNY$6)_mjsSr4*gH&Ya@2w4+HRPBL2Ghl&^%$0Efg~dzob$!|)*?HDW9G4akDzhdo@uj&GYt!8AT*(9joy$P# +z3IH{o>WR$5OpmRBP6B-q??U`LT{rB^fg4(mrtVUSjEL74=33lEfbSPqz|E+Leh=7e +zkpEGZIBX*mPqAmIMBJ2i*9}FfQy->w>+-LdE-ScfNv{VAEA539E6L@~=zW{_fQW1k +z@a*3S3slyq06)cs#jm3P)Clt#Ou=5P`zVXTJjL&|(j#GU4tVrNJ_Bd);mFT9kA<6w +zoQxJPQB7`_QQB)C-I28uEl;txVy2`<9ld;A;JIK_$3E|GRBhUx(h6*H?#Ee2oC}@S +zdtZ3e)l^NGbeLJ3&(cNimh^ujtpWuh8)nNfZJxBnd%m@kBWZ+E#qQ5z%0KFa5OqCN +z<*82#ZwA!jL-IvBGxBUbV2W+1@CX}OAy*Ss=|iEf)q^^`RC$L82L${2W35H}fC868 +zo76Xk{q@ukti0rzs{5~AH3O0M;RA5n*h4H63B7q>$M8~kdQ@T-b9?&QpI>$F+8It? +zd*^IGTukB#@6_*LB`0%iK-gZehV+$1PW!fgJV$|RjtpD8R3$1AU;(0BI_ELJpA%2H +z)vu^ZqgzLG+nN)pI-EJBQFu38u>QQpp1Jp(z`lD0-B)?+yYD5dWy|YWny}(5a0Fl% +zqGoNhk#29q@GKBwO=N((0Cm!cd)+8s^w9(}(l)`4hax2u{Z8z8D4x>f#GUnJihch`y61%uwf8g +zO#bRp0lOD~E%&9NfBsLJX`1p+hub%>S+-UJ%N5{wa-zZqSxYvrgmh6vG+ITqNn7#u +zoTlqW8Rg8#LZhSOEgJfA+fu_R?q*^BV4BWhr5IF-=Q3Jz;$7R(Wta$`-lvNQ2k`6R*m6w +z8v`FVk@aINrFCWtTp?M~EvgIbNHsvl;qYjN%V+vPtzs33s&cHw=I`3QkbBkC_gK4X +zM0l%dY}C*~O5uSFa9ZgHy6Q(A_ZnwDPY}J+Q$r-&G9{3l4`=Y$&b{~^0T75;)k#=1 +z@AnV_C@bVoLi3ujju%YIOv6}Rk4~MMIjz2Gh0=~Vr4wry=Z^nfJ&vljF?4CaC=c=> +z(?4aaUce_MOgH51z4yfDsVv?zn-KwlNeB($%AtY6) +zR;L2=bh_YUqvr-b23tzgE$12uqCTCVaBY)Alh8PyG$xuwy_VCko}LQn>-3BiZY_t% +zyg+|}i!#@N%8CJuku)8^0>Kn(P4_w_g)oYy6g$j$hqBSuf}$>awYWFPu9^w}>T4ao +z1cepNyKM^IFq;|~agJF&Z+Dh>2uwksw}gjUa{YHH>ztE2@2yu=Xru^I>q@*{ITu_$ +z*vjIR{g|Lf<1O2RM_;|H^1&6I&|l*B1`l{}~ +z0}vn8+TvnpBb*Sq^>W|gN`s<38lG-GCncliv{oMad#$2&&`is5I4rfn;$dlE~v8?$m4?(?|0|V$jhfE +zKN2AqpvzT%Hw6n&EAkyq7$toV=VoxCY-T+JUTCoBscdN^Gk+r4J5!1IPc!S@CSNWK +zgEFF-R*hu2eRFiDIs@l(x?{<$=6$mTso(n>RlgwBZE|HsNxa2+!ux4c^TKpA3|Rx_ +zKy{kt=uRmh$Q)gy3% +zE=%bWG?a^#7_5`RDQj(+bqgTfOfw>U>&6w5#)LyX@$3ob`KS4O;gA9owE +zs{6VODA*P=rY^4{J +zkj=&7j(D44=x}U+Na^LE;KbW)m57ovPg5gZHb>*Iywc!d=pt9I<$7P`fqD}a^jh>8 +z@xtzZxjV*Sr=d=)wNRFJiK81Uwx&Z(Cu~Bs!==INQ-E%q9>~EH+QI||2S5Z! +zWX30nUn)w>`YhT}M+r`a2?L;Ud`2T|136nYG&Q +z>_v`NoG3C#&oTg%+jOWNVFp^w<5c`(<6VBb~do4l<5 +zK<$u$9`(94Y +zL|0$$h810y*+jI_*%Z*4_QPXrla__QqU{3B!#^f_CHjNtklJJl%W4*<4O6wxaMq`Y +z5(6xqtNo|vp&^H()sa3m7E3=6qD8*j{~j%#5PGO9aRQC?VaWWDBGXEbG5$LLRaAOX +zK>*)R_kzUZ)Iig9xv>lw2&TWdoh+@{F`4D=l%|&Ee@HwyA+!%3=nc> +z*Z1siiGF*~Sf*}A;Z7H8*QD4BYsRT^gtSBPzoIyF;@YYa +zb|ntMaYZRaQ%I=&Zyb-|iAAq;jxlPSH!mYJ_<^i9J8WCLv9et1v}vNSbN4lsz4^`P +zL!;>QYgUgv83U`F?o~kyxWFwl`*F0p|>W-+M~DN!c7dG!`;`)?+p72c;f +z)h~+KoLUvuea_Rulk)z@6e0=$##^x^&-6-gb84Ah+>|w>&-AzfH%GGvEXqI7afaJr +zGwVUH*8yKYjpk9-tB-rn*-Pkmw6m+dc+`wN1Ny1T;P +zK`$il29L{H(z)fxGI^m3(8S)taj2V}u!mPNE+UIN2j|>^mVa$29xi%E{)!?Ykx*{- +zSdb@zPH)NoYH+j>thY1w@2}oHb7P>|` +zJcOK_<*Se5<;f(dCpvir3hKm(9uwbbx`HQ+&%}=Lwcu~#<5gD0aF@eSTSpup$*WB) +ztuI7q%Pmyibo1PY@O?A;_(s`O1zITrGf5^19U`d}=o3pA0JE;}_}H~`4=s@^#sR4# +z_yw>=N9bMU)rMUbxkfDOBCRHrm%gfCrkgY9^I>)XAw6Kn?Se-zK2Kc1I#_^ocMHnmkt@ydnuJEm|HYmTB`==LOq-udAp}b^tAIc(GPC5Z6XepLaV^;ih6qdMG17b?j +znIURMgoM&k)utVHTl(8=&1AEQVmF+O-toV`5ZRN+s+rnFE><$|mpc*)uDb-B +zdOZ%vPXj({a`OsPXVX5%#cz)>fiuK9hkp*1v*+*Kp*RtnF>WXQq@BGw-ReEa%lhfh +zAU)B|vNeUqRD07U(-%N6{fA&ZWtNX^wF97d_o68!!*q;VwT$xu3rr$D=*4#o7w)Nw +zq0s(S-G^q;=eLyl*ASiE{@|sNMXPuGOc5V;RIAAa!s`Tqhv +zDKjv-E5vAKIX^w+z8Hcxva=jIQVf%p*-`S$lJD;~gjPml@Fb%Z+CKV +z(TBkSFk6kK-a*Pj=?&!CrPGL$sgb2F;3f3}ICX>kvswFxlq40VWL_dpPUTr_>KO?7 +zsHezJvYP|5AK%^tG*OAjt=1>0UM{qnENH+6^B26Tt%FtqTib|5ZzW6Wa~8hjF+r+K +zJuGj9oi});t^c;i>Sp-WQ+J?)0@?hMg8E-aIHH|6}Z7qXjLwL!8 +zLe@azH9}`GnQV$K>H>lXNCXd8gH9Ndt@hzUT13lX=@F4$Vf9LG7vs>^A2krZHdL+B +zv01ZXLTL*j561)Sw27SI;KEd(q|qk>7{n80S|ZW*&o%@vL5SJw(ew#3v@ogELgNBY& +zUN;6*8!u@SZB-jd%_=lK +ze;QQ>Ny^unljSuhw?66~KzObfraVABciQaIcMnfMnqho4-~3?Pq^|KjEH8{veiSzx +zzi=K#`4=~=p^l&GU@i8*Mh3Rp3}ELN5zD#&`{;wg{*W6Urtb{~zaSi%>ZB<4)LIo8b*RTM>Q|lpEA<18lv-MKjpJI)k3mh&LDRn1H(?$p#QU9>)lX +z@WG<8VXMU7FHH^)5J93Q^wQb`ksVeqS5Y!L3+GWLo`>T1XZpE(wZ^@*`^LDdilR!? +ztJXxC_$0VfS&Jkzw7w4f#})$bm~3Fv*GR#5KMgpsJ|soL^ew0x`7-n?p0r76TBLpY +z3l(oYTx&`9S&AyiZNODT3EJMPy_~2HKpi$F)UTP(5C*5Qu*QuCuWVNP&VhFO;z+U$ +zUZ-EiP$uaZAzA5)-wElDEGP4N6a`5NHtCH&!)0$QYXLD;i-EJHnVb68=&)aJ0M=3$ +z&AuNQbFOt|2hT!2>BD(h+g74p_`_StuX|TKd#Fq@X)Ba>!nlxzg9F@)V86@6zK@=> +z!Z~d5l?b8l3ov@|IUyAcu`)A81YtZh{(w2wP338fwxJGe^M_0Gb~!--T7 +zVi?`$)jwTtPGj#qi|HLy-xT?juXe6GTBq~TPw1E=#`O+vDwA;PijDcI$J0z8;|uN& +zy4tTU)?7b^!fDlLT&eI=Bt0Ma6>xd>;`>Ae)X0MrZ2^G}%f#d&W3a19k=b3*Rg13o +zRX`qj7;gY*`?m$?-IGDFI*gu!3bs?irQ?Ts~$ +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 +z#3LEreOY)9tEke4eEVvFoar3pPDx +zYNs9;H_>d|sXGo%!SDK#S1RvYnTOFz)dLIqv^v2PQsXSKaPssW=;2CZIzf;@gCsY;}Ylr2izXjvkpi5TU0q-rQR1*b|$hDpvbU +zIF{psK$+1!3AMI@f+QyP-utYF)C@mC%26!vcsT0hKi*PkTd@nvRfLGwQ`JdXQCe)I +z>M<-qNZ#>P-zfkcNh@Z3S2(QbHX7)02kxI!f-TVizPO6FJZ}(N$P(mQ>PkrB*TFh% +zTlR+vs*rC`kBn$BQye+$^NQs9jA7XlvQ(LulOGbj@sH?t4A}68@G_M@BSgGt!%?lni02dUL=xav+ +zh1}YCZQfikaf}^5*R`Cj!$^;*%;En9jX-k0Yagt`J)~fF;wd}>4iC4h6qD#WkG;|$ +z>ZP2%`60>IgT#vGtPFSH!+LSNIg97bRRkZb1s +zFH|R|)h=y1=8jl$HM#+QY^F^zWv5>YXNyK+VuopJD?d;*S@sy3*zG_z3Kq25lDrun +z7*?%l;@uB%SX)5LtM@$;5umPr4CBJKxxFa;{P08KrNvS&nQc(S3oT3B=ZQq) +z6(qqn48Pqf^3+A;#m;7tFzREdy0C{W920 +z1jemq=gX~1uCDzDj2>L`1a75GT38T+zux0jp9AV2R +z?PbfCos%mjVOvG%Me(RGdi5<7fHq%yi-MP#`XcOZJpbcOl^&&&;d0Unq6c*wzx`b+ +z7SW*~DSk?=vKyWx+=27?xLCEeR>;%eypbroc8HYTj(fs9WqVvWMqMX(mD;xqd2gzQ +z`QF4H5qDfAR6`M*ooPPuWm>d-j`}B+vSIhv(Ux)&)_LA__&A4s!GGgadF++ad|`B* +z3aa(o=tbE;Z0pcv_Yi@8O}nU@B8;wkO)1wmfsDUWAD$LGj`C|xkHx*V3W(J)8#5r?GXREBno}@=r!K?bfd{)c;#J%fQy)#uVq6XHH)1M09;)sb-Ub-4jcFSv(x~l)ZYF*N +zP?RHBUq_cBdR%?tZp|z*?DhoCOO?lQ?;jTd5S>w)I`2vtMu%3$`s9j>r>Z*Cgl4u6 +z4z77*x{Qw#8J+~%wq*N!oFRG0GSW>Cxvm1!!8R$k=QLj$dGenwor71 +z*u&r>B*McyO!J23P%@-o4X?J?vMCIC3aBaK#jlaWEY79A&332mzRX`22o7au&3@1h +zmXuE|Rzl&$RDwNr42i3Jt~)^Z&c$s+0NA+yJq6nUQXd!vX>219+coOF1@A0d@g{F? +z5P~h0Ec`E={dUzAYUb=SotX?al^IeTtGn@ev}I;9enh(%x%<~A6nG=BmsxiZvq)GTD_y53o7 +z!xN-U$$3jCzUpC&s<5sG!k}PbS}r=4KK+=DirUwo6GXu&)4e)T+z}7uJz$*+U?BV) +zKn8KP`>&C)k00)lM@?PiWw6x|wX8vS$?%lc|EUI0PRpgyO$HjWIOk=@-bjNtsr_!h +z6?Gffs6GWa)BEg>qMSbp!!cB9YDG>IZc=&wvpDVd*5C57w@=kuhH{nXoFlQe$rzen +zWyWV+JSY;^hKAM*Auo_TuxlGQ&UI}Epia`i8Kvq6ZlD^I>JnVuEjy<7M4o=0{eNNX +zk=PJ>+HKCdrF%k#>+QiQ)S!hmizoBW*|(VZFKr=4N;7x*n7)U1&+c$!{s?$7q*J_Z +zjyXqV3U2%l!jN0v1azzYaKj_Pm{l@vS&Z*2mv<&sgzGFUi@jma|~dE^;Sfiv2gqv&l#*Z}&113>*BF +zFr%q;|4=S-8|Zx6g*+OXH%vq%1>NT!2FffdFsU?i<5E%^S^z=AK1J~U+{>NaRk)R6 +z6m#mlM%(&jjPg{LRef!?p+{B6s$_lR5*(h8hLR4i-4Z9Y78aFa*#Chnp +zZ61mozB-+HlmB7 +zyEDKLy&@iVNkdCmkh>3k__NE^jJRBE<}z(XZFgMk`MVoMX3|@ft?7&qfskJ?)9IK# +zG9qC6@rlo0QqE^-cWFNljs$-%GuN3zK7kFRRZ`Qt +z#~H5%pPP>~HP=Dgo7JUDSB1vK03t@ErJHSgcYB!~nUBR20r06>$^G~bcqc(7s&m=< +z$HrYvcay2c;o2FOcFB*D4_uG(fkQ +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 +z{Z&USV!VF~9E-u+#P!T$&~J$U1}0 +zOu1i4suggXXeUfu!jRih(D@rH^wP;m>u-i{melvd7tIfAcq=MMow<%O+OV@0 +zS|~%iy>=q0gj~h)RdkbkLiGNqoDvcWv#mwGd36b7M&V6EW2wzGl220^lrLlGFX> +zdz5o_+%SP0J~fXn@c4%Ex%FGBBba&&VR1xQ`*DU@1JaxuRJicITT%Q; +zcSx!cAII>RcF+aUU_Q0PtmCVH6Q5m57aF3TV5?H=?@IPs+(0g_`;uPeKEqkoIID3Y +z7#1AvNizpD&L>m2EB`Hqwb`~Naibc_;}rM3kjUvx2?u_o-4RBfzanMf&~qKazHwG5 +zq_OAcVn-TfgHX3ikO=Cu!lm>Xj~sLljnGfdUN1T8AisGngRXi7Wwra!Y)NDcyK6;L +z_js21q=zaXqlx%r(IX(UOvuZf~|=(j^^|aqkBr +zer=W$>CI-78cc+7vqgi@m?SRBbyF&Uk4}9YW_hhI6y&giBK`}dM7WY^7>tpw)?Pi& +z+!^a&av5P-q9+ps|K6`^TwKaK69h_l5!!bX0ks4I&#GWnKmB^r=cT`g_D*{&kT+^ +z#5^8H;U?DAAU4isevL|DOv$*TF8!eas7XCsas*sbLctc5;S~gDoIBIJobX?;Sz+Ne +z0~eg-3T|%lJP$lss^2lkhLU{x_{8$G9NVtO%iOlW#t)W8%1D`= +z=daU)+0+1F<`R5k3qZJi{&2x4({I6rkN~ij65YBuJe%L!WH*tUpFx}sx@ciX3up82 +z2<$(HzMdLg4zJK-#O?*|I`K27@+UvoDd+-$Xxr?9KUb>)ac{NupDCpL;SK@CD*9aQ +zKP-AF-zaslhttRMNAHDreyI_D3Y!p(clvdKaz4vBdcZ7^$lU~JCS`BQK? +zw~$;_?th_SK1KOPY=f3hSG|salT&(B?#u22!5Orj9KCL#zs(##0OW*rGibJcBaU*I +z&aE1jaLoV=N^oBHUDmY4-Y}Q{cj{(~nckdGaW}yoV_dCI6>&hYht^T?;Vg(cJWl*u +zFxBBJe%Ro_ven`x1uqRVM}{{Jf89qmU1+$t^5jRG4)B=9sZ>Gs*J_I!?qsf&^0<l=q)W +zu%W(@kS5%zZ~Nx%QJz1c%_as!UZ&&~2_)Qi6-)a6W)rbS8H}PisDJnUq?$+iUa#@& +zhKPRd!~P!~Ks!o&jy-~XTW6ggY8y?TF)G`xQ9)^&ryc@xt+z!yZtxh0>rl!&w0@h_ +zz9iSAMq~h|8@LY?Ys31Lc&Z~-0yh2=lIIQf8Yc_<#0%q44=JPPTp4+Q5Mxh +zAf@B7eaHEHROO$Eip2zfRa-pckqrx9Z8i%Cgrdn21ez;2|2(l@xB{{3HiKQNsNHpO +z-NM7F@0g)i0RU8#7kIcYg*6WjxS4A)9+)2VO3Mee)&yRILt>^|hBhevvRCVjik!(* +zH?kIECNoh|zbJRJF^yi3Dbi9U*Y`*tj$3tak_K+l@muXK+eqZP95SC8<046Evo$aE +z{QNxiyEYgv*lupyq0KGj8~1@94`p<6#jf}+{7`IMhX6b{jz^Q-oLptKAQ%knGQlZ$ +z6L}A)^x#6vKlG5Kgt7-=#&-8S*Z)aKXVJqhP@}!N(9?XJga=!drokR-nw{b-^2`^AAU6 +zbRD?D{Q68MkP32K +z+GB&3+oBa@Dt*~7o?c<$*tTHw;ch1j;`#T~=M+J`0TEV;zUghZl$E`ETiaSiV~wJ% +z?D@s=#A(z8Su`o%sAHaK^=!=?xkYu|H~W~_?E8g0OV;rQz}^Ud&RA8 +z7b9A8SWGvV7|dn4P$;0%$kN5%!jTTs8^I0WkqiP0hm%II>{p*W`u81Y1R~@x3b{9M +z&Ce@ms1cXmd3R=DlihR55PbP^*1Lpq4!OSvE^REY831-Tri!q0V?eeWEHI>9qMR0X +zeeJOO2R1?5vI$Ga%aAwIO}xK2$arI(Y>M#e5B*cFQ1tt(ZgFu1)2TInwJ;)k(awku +zCB1|6r${NfAXbfHOIE%|%an=$Vu7@SHs%o`C@L1G;Lv(B3AcE4|&epV!Jm>r$@@|qYc`BX=?WvvU1cOeeE@=L`B&pY?Ay_YUe*K<4 +zZlc&9QaSjTAl>PHedt&4?!cJaYyi>3Q!#kKUuTIaEc2|*>L{sBk(<#+c +zR0&lyj`Fq^sDVSnU6p{)sOP=-Z-?kU(%5tTZemjhIu8)x2_Xn)CK}u1*dP&S +zl1-{dnB8}c6nglzt;qBh;=r?t9;vRsh>V%jrUCd6{dzjOCHG;4zRVz44M^Qr^2>5GGC!$21H9Iz`j>#3Ve@Kr^Q>c){$$YC>52I~uW7|@5$k^dfRPMJ +zzcT*II(b$loLPuxo?w|t;)16S);!ZVo{ +zeL#FxWZ#%=+7H>-26yaq=zv5bXlbwZhp6`?HL-y;yh|GDeG@4UgI3|HQ7k^f^1s)o +zlK4rJ?U4+JwNFcMGUgjb7!3i6T~nX^xbgMIdN9g9ys*3CVk_^+)|I>?|t2B6xh)X0;MbW2~<>^a2mz +zT_AEYP=^llR=rEDyg}*JqF%DP26gT?q`C48gJPX(31YWTmdaJJrG!1U3q`vqsOU(N +z4oRK_^3IRswk%`i=WPnyA*UGSlv&G`W>=rg6!qSUoYu(KuScB8fvR_Vd&G&LqPl2k +zhYIpW79#a+#}$rjKds>rXd}F!7h0XLNyxh;IBF-1;&bhtbiDdS1LNTpS;96m6oHi3 +z{)VsFZcuk4OT@a{6>>lV2SDp=vdWnPUB~%q~mP&&6A+tr2pPh198!~+_B0E +zj&S&vv`6Ht1`kAYN@q+t(1j#0?|w9 +zScIt*C3sR|W^Z2;0a-p8JI89-?XU=)mSLkNj3+w!A(hyN&C{T_VCn|?xmv^G#zxR5 +zu4nv#air&L1$O-0VR00ZsuhT4F>ELn+)mbd!I$B<1qLw-b7DsOE9)_@2YN+!Q$Sh( +zDl3hV7*X?90_l=oS9$8!>_q2NVH5j(U(@a+BgFujbj%CR!z2v%)u&9z_TQRkts0Ml +zaNPve5=xBNi^)hh*3B=gDAo&>JTk2mXlV}98|((LGPZk+qk~t86jp1$Hs?@_LrvSE +z5SO48Ap6yN%oZwni7H(mDPiDt#1AD_>8@%5`p0Y5;g==Rw%ky9Je253r +z;+hN!R|j3UE^Yxl)4_LnBF4K_bx(W8v!=C4&VM6pkXCWiHTot2^eN}S6eUI6yF0d- +z^iwCP%Z?h6ze%cU>~n4aD`QX#yC`;bT8}Eiq&5|6>Yn)zeiF8eQTH+XQjqBH(0T^H +z4#;5|o8Eu4YPi>?>aDu*R>y971-lwjW`YV_fua~H;yt4>7q*5*JXP(o!A&bKOhO1> +zY_8f{;D;+h>VUO_+#IXu8Y7bIyY$}(;0)g^a;{u>hB6;o7E4m#Qbhg!U?r)~=xZ1r +z)ysB9I`-8g@luO2yv^VB)k5aK9LoaFUFlEY0Yw@fsQ0CrCdeeG`D4XrRqj1HoR8!x +z;cgeWm@$ozxuI;_!C%|-%L5j#=59e3-(LMtErypXTa9u(!NdaR_j~WtJPb$-P|63z +ztY1iWsi9q(;ldlmMTrti%WU=KY(2g+md*r*kY|UV<#pDb +zj7t0FO*FVHzIp^2-EP46UKXyf@mo+>QbeMO41ptESRICtiHKYOAs{z3O4|&XQ{p-& +zBH;0ZmbD50w8i&|`W1k;2t??xUMcxu0y9Y$E6rB?M}Mm8g!%9B#khDMrs!(kHOj^c +z0K%11Kn+Nw#?q^v1c-SItzXU3Fkj!SDBE1+Eq*pnV0>4}xlG4#h}2xfHJ~xg{a9U! +z17XuG2Mnjc4laWfFMHptr%sAoVcYw)ia~-&b;KlvRS_Qm00)5qpDlDke*gr^3~Wlt +z`g6{h03q@DP2kw@0DHOmK=+ItI3cWok-PTQN(-Q~=f|7IjE`N@wI1is(h}=|ZmX@8 +zwcY6T20F>-15jj>1~($++gK9Thc#u*Hu}GV|Nd#_nuiBtm253wzJT!prPKw(u5i!c +z{~&Q4&g;w8glHfzC1teS(>0E=ieMZx!=cr&ypFw_tmFgAyPOxvC7%1mq)QV=3h?X( +zH>kg=uNg_(V5Y&&iYy@ZI0}(x +zsb5mL)h0W(rpaFAq<$}w20MHRsBdd!VYtmZSskPk5i=}|Zp&Im&8k1q!PLJz4v+4! +zQK49~zl%?%ldQ$(>R=}^{@}Rb!p^Hpv4`eR&O@#{5o9Q!q?>H2cQ|zH5I_3G9JaF& +z(XunVk^qNE#Djp>uqAT#i{N7VEP8jbeB>hA$BliJK4-R`l|vi*J+e+ZlWVH9h@l5; +z#|G*dB5<6GUbr9w1M=z!cUkWBChE#{k;_U}G2QIq@Jp;PON?YIw|~Mm-;gZOSw46M +zmV$u9nJMLg^9qWWkTAPelT$o#`Xb=o2^ro-oP*(y%Y$~uO*?f*_pqfcLnVbV4 +z;8ixU#2S{hCi<}4W}(sq(O^XBNCY`v*rJwSf}3OeK2(Lb0!b@DEz{VkAWP +zlz5yJhDW@Y{PxYqNUT(I8Z{Ji;|evoy@a(Kv@^WRDs;_o0CI6MC{1!HDX~7EE2FUm +zZJeBsD?MrlOO}G3trbt+G$R#JU+TKNX5ayz16PBeaXdux8T;V_y9M0OT1^$`zipY9 +z#S*z6bV<+M>V^76+XOU>l&}N8XAR3?ZwHX<$*7nGZf%rzGg;NYXaonyw6YQRJ*1KL^MTK5~!@Oj3f(0}%>W7QN6^|A-a8Ri^gX>-SK<-&;x +z1wc|0r*}_Anj`5#=exFs$+zAphznEOJ#H==1H+Nl+!r-KLQE{h{ihj_LCbG)I|xhH +zJv<;uM&Au`qBNuASSDs`TJy6qcC_EZv|#IAg8^c}QnA4RCtvr~VywI7SzFR0$)E`w +z5J~L*wk(TGzVOmnTPy#D`MQgNK96;)hH&mE2js@pY0{k>p}LrN4|mFGeE8tCIl&74 +zd*1w^{6IcdyK%6&?+-U}Je{pJUvNS*rd!7=Gt2%#O;~XVACM*)NJBWD%$DX!>#KnZ +zDeTtc?ARW_UxQ%>mV{@2AvX&8*W-Rd5PGE +zyZcy}=XI}DG3%np>_ocB0wt1SV@1@h;Kd;ZA9Cj^sBroqfHva0Qjs7|%iyv}NSv6l_XYZ2}l-yrQWW~|K4kg9HW}P78k3L;f$b?8 +z-Cfj@pW40Z9146&MljXx--NEY+mdc%O`!>yn{lmifS?%Y04n@1`NbOA?qj^;wQXy6AOFm!~bqU>VLFRRu4X#dSn10d@@h&I~SiOAPCfCzs*-r`_hlF&FrQIaDe{3|A&YJYD5psQ&1NNLf4~as&gMSZtK7e5}aLmV~uLN#A%r&wP-jlv|@Z>RU)_V5IHK`l7Y>-Cj6a90?i!AR1I7wmpQAErS3AFMUQ#54i6A?3KILmTMX3nxmHTJ2d6)QGqgvnLBsMf%1}Ywg +zbM3#11LVYkw8GHmC=swOLx5^((d}ZWiPibC1D*Ppyz*&+SbH5u4aq3d3;)PjDpp7P +z8K!V?Y|HARzDF!oXv~L{v020$D8AT(JTb1|kSxFr7Q~-Y3pLNjBO36n2O<~4%GNZ= +zLQI&XEg4e^QgsB$)e!F7WfB0A0cwZzLnsgDn}0OGud@(%(((M1OZFViL$O}OF9QJL +zgWbA3qq=U@NiaFqFE-h+t?R` +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 +z#({L)W*go +zTy(+6q6c9S=t7g|hb`~PGCjRMY$#qAv$_Xu1y{J*lZ_ +zpDySz$Mio?Csz5sYYhrb`Mq|(nFu6E;I;#kJtL2{2pQhM}|pW18gw9sQO +zk!;4JK}wn!8g@2G+oAUxkdU|3jKleDl7)ao6hh6s=VC4Nt&>a~_5gFHKy)R#tBhl+ +zZs|mkqACiTr!%5=#afO+wo>av6B#Lhp8Qy6Y?w@Si64TMwF+qa`T(BT%p4(8QfOT7 +zfBSOg0Z+G9d{bhEKs%;(E!iQDeNtp6L&q%Qc#R?;THI^>s)gEA6`NRvh-tL0Xx$f4 +zYuu#V+yOrBb(lF57>$erfsyslCgR@WT5;6rqKBer(Z>3~42yliCbMyxE!G_+seC?9 +z=dX@0>$%U>y_)`FU>cbtyo6vNrv78$i-5zZ+;U#rU +z2U*n!vo?S7x*1xO;puVryIY7EdY?qt&N1Ocb8H*TLSIiJKEvBoRD@WV4$5MGn>TMg +ztW>aX9K@7Hp=HDhP_nfhHe%WMmT3Wn*z{LQ5)XwlBgf-eMQTuR$Y0l+q|((@Y=yeZ +zUa7#1kX+AMbTnYif(ZehsjwjyEh +z!mBSNcI^%-iZB$?k&tU)vznv#rUi49H^67>GQF&JnOHwByp?CxN_84dTRwM;8w;+hfI6 +z2}Sl>_@<{L-bT`8Os43NnVXXH@qKu8GvI=3jK`X?}b0zwQ +zk^+73z>y=J?8lh +zOGc2F?){gcswd{#kRwVRfWh-V>Fee`FIK2@Khaos--mC=>l|&{BVW7@NJF8j!9gQbZc+imN7 +zy{jt=v)DZbLcE)#cuf5J7MIUDUTQke^uf;axQG*AS!R_H@^?nzba1g%*8`3gjb}Nm +zyuAt;#@DRsnE6sw*Rv2#AJinrT;2-83P|B1y#$?7Jr6rqS`|-MQp~2BG}S(X6AQetKT?CE=M=tx>4LxcxP8wDRG`SPWbj*b7RAz841;NWjh^15 +zUDRtM#Q|f|OKI5Y-z_zReeL0Y_SY8>gLK3JU2h*;2x&k;G)>obO~;MwOF|7Dgj$i$ +zMsNWgR2TN(ZQ+_YTkj{&(4e_0{I8y#xmOje+iG@Fo@<-&=?5oo*1xw{#QbCSWvqv} +zI;&FDtr|(lhHUuA%_8ogRRTR^?Wg4cf4PHi@MVz6<0gBS-Qj-n|srur+ +zIk-Bw`W48j-rl4Y5i)w)565HKPKO#O$vJYR$4%pYQeIW8Y72PUV +zU^huzrqx1O~~n<>Jd?jl>JCtZ+Tx +z=*d)*tXLlAGg`w&<)zVuA_?C?!qZKA$V1!p6Wy8!^FSOq=fm2^5)2(PWKm1<0lOSe +zvq)>eYM|V=-t0)#9KMxE5#;c0xJ*t_r|y&Vnc-j3hL^4BXC881A^h^|RmP+iW)RfN +z!Z#0atPck})6M{OonghK{;r-vxC;ji0CkwiKjn;QeY@SU7TV5r=biqb^5;A&b!9jy +zk~FUyAve;xR+ACy4j1*sP-NAUBY8SN=;XQ;=6%&qijqa^6$Sg8a7- +zI2B#%Jlr)?qm|O#qW0s<-_qtAytMZKJmrya4kyRsY3J{=d+P!A?sAa@9$uCPI_!K4*aC%heW8(+*N*BUyJtvxWI98RjR^BtLeBXSbA&HKo +z%(Bx^U*x+B%sc0w^zR%MLnyR9W@x?l-6gUcJy +z-@4LIkixr!ARm#qN^q|t$dbk)_g%s->#;)5!alde`%DE9@c6&2xUyy^I{SM@$BOX&PJrCeN+55nu2q<_dv^%nQS1s`XDNaNcUyA1a4?Tt|JUIp}_=_$^05P5_9YKN!vP&9XQu4pez6k=pGEm14C}x*Gd2opfjH{Au +zzaD?pGt#~F2LA!kvmAt-=MJI%`cJ`4r^xx7-^a-Qiw~!#AR}L^-rawVpm3S^3W+tg +z?-1kLPul*EQ~~)kZt2%XW4nz8+aC7`%eU(@7Y-WGlST}^t4#g)3sU_@AvB-EOOk_? +zl8I#5&mODN@@xo5RZVWDToNdjjp5Ck=&5gQXZ-<(@W~B=(Iox!$M+eRY2cn_iAepi +zB1)E$RP*}KuYtMp_j14RZudU&YuSDU9~&%U4bzYGBVd@#i`95?i=u!CSS%vZuHHWe +zCM+@uhq2G*H?6BZF3qrWCNm3Uza-xQt|cEq&m|qbu43Q9wxY0JE~);-W{)I_5p5zr +z?#5EPxF|lH_F6q%t*N8w*Bf~ypg#OlgO2P4dbze(1%@sx#@rW&fbLh9obZ{xUk_%L +zhZV`ai-WNdIuw3%wc3Zq{u+=P*>7^`#{6-~i)$H*FUt&me;X&WwjiP6;|i^=U4Cn01!zp4%d=KQ^G1(0Q~cRCRy}IHiQ6k-nZ6DC6{hs@z6F;uLG6?TI877D~TE(F~?A{vT0tS +z2IED~^+0-%TXM_U)hgYA000Mj0iSVnLVo}R$_)Fs$GkymAOatDAVI6Ee!jg7h>a8V +zq53~&V@iT2sX7_0W6SoC9a4%YVt +z4us>Orv2x#=7Q)^ef)0@ZmYkFe=^m}Uc5eJ$?K}$D^XmHJ(+Mn+CCVV9rZoGE&|1q +z{IP&wV2uK`iFILILQ~J?-9~E!T9_-~b_G3m%$xZjVbNc4*<31wv@=E!wix=VAncRYS8(li{|ns`r`!k8TB(t*6trlYY>1J4z-!cPw3aI6 +z)t)8vKxE*9`G_44%mSW7r)!2&q(L_(I6iiJ?RXvmRPkTjx^Am^x61$M +zV0&JzubfK;@O$@eam2fv+Mnhu$IL6vbD35hNq4<8R{Pk`tK+U8oYV`*BEUx;M@0T% +zbw6Z!jz`2K)Xs0GR61XiWc<0|=o0Z{ab5|ZD0<^-y=Xg4zP4e#(tI$vI&_2VoMIxO +zynF;?v-wSo3z1F8v&W8TuN|wb#-JSr*ULONu+Crz>Vfuj#EGW$>9QL!9u9diG$CUP +zssC8wC_yWNi0*kUi&UpUBFQW4n@q?(aNroCdKf|^4&xqTJj}UPTY=CQ0KYTIuf0jC +zUEp55vNN|k4(-9%jB#}^LUrvp#o`m+#r1W{=YW>si`E-ZCJSP9+jQ*XvkvDsQvP6&5)8=)#6vsz +zc}V(5Nd=|4v(ZOU-ZgLot>Kj!pO*_AcBE|0YTx=75|DXg=f2HO^yo+i +z4pih9CQdGjqw%~+UI?cfNX#u8>#2R>*fFcA^BYVt=YK)n5b|4e-M3Xoq7L`~7pqE+ +zN^y{;Xl1WrO=lzlXTwKnAx +zxaYyH0|{#Mc;v;%lA9MEqBPFDT)R?o>CpM_r9?O?9p|Os>-*}#H9Ja+QF-0{@^BvW +zyU8mk4o2dbnZ$Qbr0%!eY;)Y`au<%`o8pjWVvs15-Goj`-{}y|NaBklUW^CKRL(Z+ +z9c8ZPj6UN89gDBrw@q@)cQKNoaYq0;z*mmjqcjv| +zjUu0MWVaUNGGt7$bIx_+0lf(7khPZJV9?Z4DFgY?@pDrxTdKz@w78Kcco9(*pI@as +zD&OStbGyTP4z1eE0^g~b5@HB6g0aOt1EfloA8ODyY}WOPC`lQLorHCoVP$+9tmVIC +zH#EeYH61z!yhA`z-q^((6#B4UBCmF4pNv}6dZuJd8SQ{w`uK4UP +zTZ}&sTk`qYUbpJTeJX91oTZrwnJjU#Bqq6o)E6{U;^ZB5DqNzvmvCK&0||ws@+)p#tyd1He@jsR4okMqnzj2ovHzD|+?4!b}wH;Eep +zxRUcPD`kwOY-DUr=5% +zQN*g6&|V)&`vgLJm~QMJ-~p_)ZnR*-%f-JBSnzf{){S^YyDpN*??)4&If9r~{lSh# +z@7+{y0ooF0t`f2E%>|rg3`e^7e8O?iw+$WcKazCf6lCi4S_6}R3rUbLR^_uQ2*QLM +zJ^914f=;uX`SATVR1l{;%AShh0c(EeWrkW@3mC8HGu!JE^?z1MN(33agAP3d{j%f{ +z=srt}5ZUuPgEArcgKZW-Kc$Vw3>1#Ww?sMadDBp9C;PdLSdAh40oTk-xBhrn!=CDJ +z9x@HsYupdHm0AHPPsS5{auD9-Lw95sbud-G-9f@Fh>(8IHvkW6Kk~!;3n!t(LA_PKSAf +zDI&c6a6y0|>gG3PIB8A#IBb*#H#qlmJ8rv5@>y{5A28z`>zlss1)MYxrf6o3sXWmyov9G?7_ +z4vVUb0FR~SP6;{&>qXdfITRW)<-?rr=Kt;+VG`2q!O?VZ{$ceewOttvD|)8A9MO70 +zlVw}-8%Ypr$ZIOiHbEK~?Lz;SA6ct4WN3^S7GIxrPbdxheCWJwP8gtzY3`z*=giSNIc}Z$ZJN*pAI4%8+eFu^e0!?DhCax?_JCq1tgnKj= +zb9F1>Uy(#wfU`!iy0QUPfR;Y-aO%HDnNxa;>XKJ*rFR>6438@5Dt19qqiY3f?bVPq +zaZWwv*|lgAsW(OFEH1Bco<-tbbc&7*H96@l54*pFInhl7WL(h}u0kZHO14A1V`urh +z+Z9Bv72jw_{hW_^$sOUE9Z(Ydz#yhC0H==H?yrB&*mFVU&S1YJ*q$C4blYouDm0vN +zm75EtGhWVG*rYdi9}Fx>HLuRDDdDQqT(8s#;8oa2rW>-~mP|@d2{t~-dFr^ce0Jb< +zu_^y?2*{DgtHy85zlF!GEFS9f{1*-0C6o +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 +z%)Gk5wS~ +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 +zOhW2SP&ePSmy9Z +zRm*s%*lkNk6M4mUPFbSO)M-?CmqP7-@sl-HM%GmBv3HA)I0$Gy$8%F +z-L5GH^TU(;!0N#06tGGFh~Y2V%SoJ|`5aLGdTUm0UsEeB=Wc(^DlY^K7>F(*d=G8} +z&O_st_<2i4%?FA{jxz-_nAD;EBuD0X9S8x)JHo-6u;IC1_w3I(ijI7{(CT`XWfp2O +z`&J3pBGLw{~~4fBXN#39HYCkRepN!Ge$wFL@0?>J0){LF;WrbC#V +z%#oLHGXSkt3Z#N;2d3*ng|kF|!2kdUj{%>zYC?Yi1j-CDa5N5o&aeU#C`{R1`~%+h7T0Y-Tqwxc*M`kn0H`K^TzP%=avk5*#i*a(ZJ1 +zXq6V}c++L99L^l@>-?h8;#ZrT-w$4dm0v +zd(1lc?ot6S0drixfSg^#Rm+ge?977Ufi)^{xTsq8U1dEXuU0*RT(!?%a-1H$GwS+5 +zb;0hKH2L6eEx?z>lpG;h7MEM&QX@F++H8CIwRt7#fKK&$S4kKbJWvVZazvMbF~C9` +zTATz8io9I&Imj|Ej}q!zij-0mwc#V_%qgbIl0QvA1)#7va|^GTptN~C(l|;m+Lj>9 +zEe*y!%(WLYwteYUkx7UiN2iwHVg&W +zJx=4g>@#Q=<;#T3i@9PjaZqGEYGf`SXt0qRuRhuO +z6b#`o`jk2CU%Dq$P`)T?bTlE?+ITmmTnv&l&=SrCLVO{f;Wu>6F4w_zl3Umsr)FqX +z6xevl%sOqk899>8VZ(^cY_lws_TfaW%<)+MYUF^Ef{{IyX?yuS{JCbe22a)DrmPQF +zCB538Q@BVHFJ_Hq|Kq(mcU!i>ZPQ(etZuu&;EKd~BddzufQJJG@B~(YYIk$R1xq#% +z!jjCVl*|!|PiFM%qDPu43Gkh_s(uv;P9SNK?#$PX6%yQ$7H?&m*>ZRde_ngbq%tgY_Xt|psXXrhr>ZFA{fR{$Ti +z9%;x=6$wNc<&EcGRedG9d>htQ3bcw7zJ&w0aoOw?D;8VYO=!+#wjrT2wC{gVuI~FS +zw#w8+*|3%1J;(*`rX~X3{Qx!s6NcrHohDt7@d0}HQQ6Bm@>HNf{AkOdWiLPlZ~){e?WfX{5dnl`Aq3l+HA)UHK_wK20yt%+NrcmE0f%vb&aG3Jk4*3b +zPTsq9;XlE@B6O>s_Fn8ZbXL=M}YMBN_4^e}4osfgE{4*2?7i*cSDr5ztVDUZd-Lw8C0w>st!?R6AH9%XlU5fI29~EuBu+`n0>@aaJ%#1BK?k +zA&)hbL<|gF($y@CH^j6zTU_LF4@0-OfMrcJf)AH+(q)ppvT(VRjZm%(0_Wgwwp=7? +zr%UIY;^`Qva=Zy-69cQHvUx$(IS2i@z*d$_C~63{;FCmrf=hdZDKhuMcgE6-tH8OI +zk+3mNiK+r6(UI~k$3$$Z>)5p8F~JT0jSqk~QIXCaK-w4i|N042#5-(;lcKiM-Udt2 +z2m6)l80Ul1$!RSwWsF;wLmI7;#V3fxOne#UN7j^T)XW|nK|i;!p0R|tr95NBn3mWp +zCoYt%?y~jE`kyZRI^zW59_Vkx!%9N$ov9TbaevDQW{wl$Z{=SKU~6$Nu~&ZubKY`v +zFJ~>5Eqo_O3u+jBi$52|3z&%?*2571nUh4O_eBuJm(po;}$DAz$%vm-n5t- +zN@SPh6!1arbfYq3-n=l2dy<_LqnFDfHp&3(1m{rlz9d?cR!|@mMmy#KI{lXVPR%-_ +zplX-<^*+(RHb +z4T9wNTAS`EUk7`KuqX3zB3;Ko*8r*Yb~a5acI*_ug=_XAa%VD<f&6BHZ!>LP@;|{@ahe^o&)GYXz9V`v2Yae{e8`;v!SzEL)FW@vuAZXGR498R000M*L7Tfts6lL*ObAc^ +z{qX<*t!?Ik<`JLaZ2%iVA^{~mB2@!z9*B(N#xoa{zG+$wizbWv7Qp3U-f3L#G+P%>_G3(drIL +zkm*~l`-N!TTH0{Uz%$jwr8mrV&il``;g4k_ +zPcn*mBt5be1T_v!y?UEo1uYJuhNs|Clpx1rPi{~1oFtn_&NwpKf +zMYsSx6S7#UUZ$`>p6^e0@l&41njY~2b5Oy4VW(QcR7|Ew4bPEh@?SDdO%lCbesOMj +z<&HR6F#_BZ`Tt9#EY)*08vF4z+~W1DlB-+Jd@jKe(&e0d%En1Lb^u^o-zy>6w~g6m +z#?Z~`Z@AoB&uZYMyRqabHWhy5i4D0R#>Wd~;=${!o{Nwvw +z%d2xuK#NQ%48PNvsgE{zAY~cc8B=r}>#1p5>zl +z=xM$Ws-frL9w=sE1W&E;AIWyILv8$^g*g%fMh;*+i~(<6+SIN3Cd|2fSy|k4`4*yI +zxD`2GO?7aNU^!=DLgE)W{;beAb8J-v0$X>)#uo_@$MepCnj6B&kQn*MAQ%a3rZXIq +z`<81UV5b5ic>2e)Agw`TVL9!XtBqRpHS{01n*AOgw1s^wb5@?v6Y~M +zZ$8)sMJ$F`*JDK!_cAhCcj*+K+^Kz@?&r!P>a=M8N;shIDqYY$NQ9OA1|k4l=SlmY0B9XzzdT_Za{#v<+Y{)fWv{feYXssY)tHYE7j +zl`Ga!sF{OeEE_nfCT5zxIe%}Q*~>@<2;I+e!Z-owTTRDSc(gF$?QJMyMCpCj9{8*i9pt= +zAD+h-V(&v-C~lbHFP`!3(JvqXUlsk5PI+{-A-foYA{aFLrBPk(5qfPxi(>%$JT!J% +zJwhUo$|Sbad8#BW8LI-ypkU#`#`J`z<|d{N9C!BVH#)F8@O+zXk;=;ZMIFflE}a!4Uidn9ed +zzWWbVy&CVS8i^z{3eD;rBLG~cGQOQhw#!YQ2Um+=m%wgm6BX)g1Axm9X$x|QKfn4k +zUtXZm+o-S(Uc}r|Ud1)L?xEufRer1biXPIZP(M^?TuMF9zSz!w%WQB4sOryj+MKcX +zO_Sm&@Wuo?N@L;EgBE<=pW6(qt6ak$B!O@4zo~V{Opy3tleg2FE#`}9FSfEuM&gxl +z1twuO_l-Oy(I*I;@_tq)^+pV~u915Wr+R(J$5gQRwQC}sZ86g60^qi^5->zuiFWN>^;=Zkw;vEB +zM-h;al#rAb1`$D8LIIJK9=e9^W@rRKN~BXdq@_DVN?-`-?ryke(D%OYeed@VxIf(W +z%;&7V_KLmFUeB!aJagupEv_(Gf(`9&;=My?1{M)4B@mx``y~{WI>oQnOiV2E@G)weUs;`$EH3u +z&^xVsFvcU;o3UvZjRIy2%YBf;PoLniAVvS+xO;^x6pGl(*_*3O3JG(GG+4rjx_p0h +zC9kB*QSSBGn@Hz0QPsHIOkSb>DKFgc*awGE&Mmzcy@a}QRWrW=QFVF@2k91>P0G(C +zkT^NmOrW;*=@A;Q9-AlN3=OiZ$Hl1ptnc`w!{sRRv)=2dTv?p#n8lk?Yo9x*w1Uem +zx}AMzo5p6J4SF5D(+Pw%Y;HfZe +z&!R%p?~gNPg9t<9C5F3XlLk`aI1u-5zK58N;t>kUXM +z+2xKcA!}u@_V&x9ogK+D#nD+DC!S+Xq~oW)iii#A3rx~*bWXUATboE0+h~NwZ@!U$ +z?7H7o@SZ*I>ff*(!g}06QM^c$OyTVcoXfW|q~Vn(V*<>YpB*03v0>t0~{cpej^32`S}fmx^>dgAt;k}$Jq_m_lY +zd{$x3RW*_E(DBo-@IgF3pxx-yh{zdQIDL`pV2FRl?(k{i2yUF%DoAr+;?GG3;nvRz +zD4=QMQ2Hi3pKp)Osh>rFZTzITSU8uCh@Rs-{tC|~beRHpV@Z4SYXWl=dHn!Tuz&%HaytQ45KU_!T~zR0*8iZrVd89Ht=P`>;&)r9EvryfI*ZTOKY +zK{n%6Z0DCyQe{qXq?P5@i}4zGeupDsLO(Js<`FXm@TSl{Gmq4`?;<<}&S+^t$?Dvy +z_yfaGNfTS!E3b1m#TbP6;c%h +zHqP^RB24#18yP^g7rl_Bj6Z*UtfKn#Vb^)fn7f$xE}gpTp-viY!zstE4k4x?8?3c& +z>&)IF1r?s!E16{F7M6Dy*$<-~6h%y`Ich68B))rpRd;Ro(o83^cAW$ +z)8v7i`8&Hx@cg9p*2IfQ;!x5%1Ed)x6NT@kRL4-M6Dwl|xA!0rTHxlZ#9R?2<01yt +zdtx4EWf|4^VpXjle|#&lTYDn=&QSd$EPNZiuT__^v%CnVH8s5(u2!;*H5f>6V)9eG +zM359>|6*LmqK+}CXBKlHv_Wl6!Eiu5THQv*?BQ1(l}A)P2bhUcStBpw(CNh#1(O?D +z%|1>$PoU8hsmA1eXx$xfdENT)Wd{Rss7cq+^$&Ee&aIhs{FJzpXcqx0Uf7|k3rzDR +zQPTSt>3taD?wC(XeOWBrs$Fh7rFHKiiCctI +zbAtPznw%W>26#x3X(jY%3%o$hAT?|sEEcjbKP2HQIIe0c +zFc(?P_4)M`&p^nu92og5O8pGFtk)#U4qzo#xxSuc{mc*KK26=;Ys9HpQac&|?j9<} +zU4p)gzG18}xWD?1Yvaj9c@^7bl$7uVrE-sbK+d6amtw=IVp9{suO}6L_%+?8j9R0- +z@MC*0Wi!E1o2OZF8bVEHXYfj9h;CMpwJe4br*ijtTb!%eAe(nm7)6Gh!nv;iZCyOX +z0=+kU$v_7;SZJSOe6f}AZ56@oeJ_*{j?iFP)=s&?5A)zUH3_5l>)1{dU9@mnZ_m!_ +zTApl{?K#4o*ReCT60h}xi@3)LgicHYrZFVqR>YOen}QF!v~Sn1rAemMKS=UvUdW3~r%$_Yx*VpVA_v|>keQZ4*EoE%ez_vBMj_(O$z%*2-_oa1y +zqVQZOL=NNehL&BTln#tc23gO=WXccE4CNL^SqSEAGI~?>@{pMkvWnJwa#P9e6|_p9 +zBo)*sfV4eeMO@0D63-ZwCBr&;&|OF;W||(YSVk3_#9(eD_TW$w*V<_R@QxfQG{voSeKZOswSOaGa=2zvIvx;o$CIQ +z(QrYES4JB+ri+Cye;^X22Oqui1*mxUe1$+NR7UWA5}1@=w1;uIedKeuJm%JhL+MLg +z-dsIc?*l2J&-o(JL3}Ayr*A)fseIj +zHZP$>r4K17Z76@jY^y@>IQZ*>G2){H8Olc=_zHHNZDzuY%VPEgB)axAt>RhI+5`K~ +zZ%aNpFFKE3RZiJaVaCm-P^d~?u1^fA)^(jF;EP2&XFXnuQ_8xk$!@h_$g)d>^uv4M +z{1l?P@{1EhZ^1MbcScdxg2o^ +z68Mzbu-~~TGjc?vXyw=zciIX%e-J0p(LL1R#HNmBV{m0nVObC!!a7nD!?pL? +z@$Zdn8QFIwG4mLH3FoEcYBBr>GP*=)F*dCU9;!Ao(Yz^+{y~9nzN%WAcpVp#n$ka- +ze-Ug;EYJ9@ywe^vHuftzE<-}cmse~-O*>!o3x`yvsjB>7Zli4iKIaRTYxV(qtR56> +z>I?Ml4A|`&j6&|MN?V!q%-(U?3*$!$Q!ZwBswo-Cdr4olH#O<*+2$VYUmm0VG86Ja +zjfimhB{e{^KG!^5v`D_YoM$IE@d{%r*zCY@X2%pP8qv#2fzZHsJn21lx<6WPx8JC3 +zv^dFGuNZPrB++xdS^IQ~$G)aTZ7=N8+h(opQ42S1E)Oo_%3^YdcFMX>#>>>C+p^XZ +zJS2f7xuTPiy|D<6bgdc^y!>0*-}2WF$%w#%oMf-u?`DuZ1^#apY(B3E|B%Fdx$T#; +z7?L*%S!Jck`$>piBFJat4?Q+@-3B(zqu1MCcXS!i9NJl~qDlca6{5am>3&cx;l?A8 +z#du=4*K5Q@6k6f)Y~+Onu@{TMwhkUb0X$C}20Vs+A}i(Kf|ge|nqr$ZhN0 +zDrarWxX9*H$`NF4XD)jkDB~TMF +zHlFaFjdw30&*Y;&J#PkfFRQj3TGn7_dD7LliR^%GH0}n#_x$fz&-31_>36((y7hnWf*g3}vK*D*=ldYf&_$F+;7mo8jt??8eEV+6ZsQ=U;? +z!t5V93If=KLt8bJJ8jE@ecOn8p9ZUPCWVv3w(=9H% +zS99+tv690FO^rtr`5H-eAr!5dXLHUiv%U8q1Kd1!oezIWEjP772KJV(=Fh&++oySA42%g&xF9sedXMCahL{q)WQ +z0?|ekDpUJdG%(tBh^eml4k36V`GfQrV$9mKBW=-=?aewvBCFGy>jIW5wNU*Bd>z+4 +zOCw@C-x0zu)d!T)tNOvDU^*`l2z}kc%E|!*0-0Ml7()U654yDiT$=kqC?MqLZ~7ks +z(ETr2_;1Vq)ItTuyl-ctYX&Ia*_qvpdFvmBf1&~7{+s?a&VL#gMHq0}xpAa3fZEvt +zEph{MTf3W{o0%fxqWzgOT9^gYL>JIeTR{JP?$3a3C(zs08_&naP;;97c)Lw$YL;~;vUY-a9!Z-&I +z2*4ANNdfK+AmBI01d0a61%MC$NWW^ph63Oj004W8WB_{r!T0c1LWBgeJ` +zfQ)qlARIsx0Hh62ATV5k(+0j9`c{9|0J%OK0QBskcDevpw=lTjNcF>i79OBj+33Px +p$lCDV^w{Kgb))}cXN3$%0oA>6Mg|4R>N*%cfv|D$vvG28{1-l>vtIxJ + +diff --git a/dlls/mfreadwrite/tests/mfplat.c b/dlls/mfreadwrite/tests/mfplat.c +index 5e289d8d5bc..8ed94289703 100644 +--- a/dlls/mfreadwrite/tests/mfplat.c ++++ b/dlls/mfreadwrite/tests/mfplat.c +@@ -622,15 +622,10 @@ static void test_source_reader(void) + return; + } + +- stream = get_resource_stream("test.mp4"); +- +- hr = IMFByteStream_QueryInterface(stream, &IID_IMFAttributes, (void **)&attributes); +- ok(hr == S_OK, "got 0x%08x\n", hr); +- hr = IMFAttributes_SetString(attributes, &MF_BYTESTREAM_CONTENT_TYPE, L"video/mp4"); +- ok(hr == S_OK, "Failed to set string value, hr %#x.\n", hr); +- IMFAttributes_Release(attributes); ++ stream = get_resource_stream("test.wav"); + + hr = MFCreateSourceReaderFromByteStream(stream, NULL, &reader); ++todo_wine + ok(hr == S_OK, "Failed to create source reader, hr %#x.\n", hr); + + if (FAILED(hr)) +@@ -646,14 +641,14 @@ static void test_source_reader(void) + IMFMediaSource_Release(source); + + /* Stream selection. */ +- hr = IMFSourceReader_GetStreamSelection(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM, &selected); ++ hr = IMFSourceReader_GetStreamSelection(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, &selected); + ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr); + + hr = IMFSourceReader_GetStreamSelection(reader, 100, &selected); + ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr); + + selected = FALSE; +- hr = IMFSourceReader_GetStreamSelection(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, &selected); ++ hr = IMFSourceReader_GetStreamSelection(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM, &selected); + ok(hr == S_OK, "Failed to get stream selection, hr %#x.\n", hr); + ok(selected, "Unexpected selection.\n"); + +@@ -662,17 +657,17 @@ static void test_source_reader(void) + ok(hr == S_OK, "Failed to get stream selection, hr %#x.\n", hr); + ok(selected, "Unexpected selection.\n"); + +- hr = IMFSourceReader_SetStreamSelection(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM, TRUE); ++ hr = IMFSourceReader_SetStreamSelection(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, TRUE); + ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr); + + hr = IMFSourceReader_SetStreamSelection(reader, 100, TRUE); + ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr); + +- hr = IMFSourceReader_SetStreamSelection(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, FALSE); ++ hr = IMFSourceReader_SetStreamSelection(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM, FALSE); + ok(hr == S_OK, "Failed to deselect a stream, hr %#x.\n", hr); + + selected = TRUE; +- hr = IMFSourceReader_GetStreamSelection(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, &selected); ++ hr = IMFSourceReader_GetStreamSelection(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM, &selected); + ok(hr == S_OK, "Failed to get stream selection, hr %#x.\n", hr); + ok(!selected, "Unexpected selection.\n"); + +@@ -680,43 +675,43 @@ static void test_source_reader(void) + ok(hr == S_OK, "Failed to deselect a stream, hr %#x.\n", hr); + + selected = FALSE; +- hr = IMFSourceReader_GetStreamSelection(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, &selected); ++ hr = IMFSourceReader_GetStreamSelection(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM, &selected); + ok(hr == S_OK, "Failed to get stream selection, hr %#x.\n", hr); + ok(selected, "Unexpected selection.\n"); + + /* Native media type. */ +- hr = IMFSourceReader_GetNativeMediaType(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM, 0, &mediatype); ++ hr = IMFSourceReader_GetNativeMediaType(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, 0, &mediatype); + ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr); + + hr = IMFSourceReader_GetNativeMediaType(reader, 100, 0, &mediatype); + ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr); + +- hr = IMFSourceReader_GetNativeMediaType(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, 0, &mediatype); ++ hr = IMFSourceReader_GetNativeMediaType(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM, 0, &mediatype); + ok(hr == S_OK, "Failed to get native mediatype, hr %#x.\n", hr); +- hr = IMFSourceReader_GetNativeMediaType(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, 0, &mediatype2); ++ hr = IMFSourceReader_GetNativeMediaType(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM, 0, &mediatype2); + ok(hr == S_OK, "Failed to get native mediatype, hr %#x.\n", hr); + ok(mediatype != mediatype2, "Unexpected media type instance.\n"); + IMFMediaType_Release(mediatype2); + IMFMediaType_Release(mediatype); + + /* MF_SOURCE_READER_CURRENT_TYPE_INDEX is Win8+ */ +- hr = IMFSourceReader_GetNativeMediaType(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, ++ hr = IMFSourceReader_GetNativeMediaType(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM, + MF_SOURCE_READER_CURRENT_TYPE_INDEX, &mediatype); + ok(hr == S_OK || broken(hr == MF_E_NO_MORE_TYPES), "Failed to get native mediatype, hr %#x.\n", hr); + if (SUCCEEDED(hr)) + IMFMediaType_Release(mediatype); + +- hr = IMFSourceReader_GetNativeMediaType(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, 1, &mediatype); ++ hr = IMFSourceReader_GetNativeMediaType(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM, 1, &mediatype); + ok(hr == MF_E_NO_MORE_TYPES, "Unexpected hr %#x.\n", hr); + + /* Current media type. */ +- hr = IMFSourceReader_GetCurrentMediaType(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM, &mediatype); ++ hr = IMFSourceReader_GetCurrentMediaType(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, &mediatype); + ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr); + + hr = IMFSourceReader_GetCurrentMediaType(reader, 100, &mediatype); + ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr); + +- hr = IMFSourceReader_GetCurrentMediaType(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, &mediatype); ++ hr = IMFSourceReader_GetCurrentMediaType(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM, &mediatype); + ok(hr == S_OK, "Failed to get current media type, hr %#x.\n", hr); + IMFMediaType_Release(mediatype); + +@@ -724,70 +719,56 @@ static void test_source_reader(void) + ok(hr == S_OK, "Failed to get current media type, hr %#x.\n", hr); + IMFMediaType_Release(mediatype); + +- hr = MFCreateMediaType(&mediatype); +- ok (hr == S_OK, "Unexpected hr %#x.\n"); +- hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Video); +- ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr); +- hr = IMFMediaType_SetGUID(mediatype, &MF_MT_SUBTYPE, &MFVideoFormat_NV12); +- ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr); +- +- hr = IMFSourceReader_SetCurrentMediaType(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, NULL, mediatype); +- +- IMFMediaType_Release(mediatype); +- +- for (unsigned int i = 0; i < 60; i++) +- { +- hr = IMFSourceReader_ReadSample(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, 0, &actual_index, &stream_flags, +- ×tamp, &sample); +- ok(hr == S_OK, "Failed to get a sample, hr %#x.\n", hr); +- ok(actual_index == 0, "Unexpected stream index %u\n", actual_index); +- ok(!stream_flags, "Unexpected stream flags %#x.\n", stream_flags); +- IMFSample_Release(sample); +- } +- +- /* There is no audio stream. */ + hr = IMFSourceReader_ReadSample(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM, 0, &actual_index, &stream_flags, + ×tamp, &sample); ++ ok(hr == S_OK, "Failed to get a sample, hr %#x.\n", hr); ++ ok(actual_index == 0, "Unexpected stream index %u\n", actual_index); ++ ok(!stream_flags, "Unexpected stream flags %#x.\n", stream_flags); ++ IMFSample_Release(sample); ++ ++ /* There is no video stream. */ ++ hr = IMFSourceReader_ReadSample(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, 0, &actual_index, &stream_flags, ++ ×tamp, &sample); + ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr); +- ok(actual_index == MF_SOURCE_READER_FIRST_AUDIO_STREAM, "Unexpected stream index %u\n", actual_index); ++ ok(actual_index == MF_SOURCE_READER_FIRST_VIDEO_STREAM, "Unexpected stream index %u\n", actual_index); + ok(stream_flags == MF_SOURCE_READERF_ERROR, "Unexpected stream flags %#x.\n", stream_flags); + +- hr = IMFSourceReader_ReadSample(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM, 0, NULL, &stream_flags, ×tamp, ++ hr = IMFSourceReader_ReadSample(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, 0, NULL, &stream_flags, ×tamp, + &sample); + ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr); + +- hr = IMFSourceReader_ReadSample(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM, 0, NULL, NULL, ×tamp, &sample); ++ hr = IMFSourceReader_ReadSample(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, 0, NULL, NULL, ×tamp, &sample); + ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr); + +- hr = IMFSourceReader_ReadSample(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, 0, &actual_index, &stream_flags, ++ hr = IMFSourceReader_ReadSample(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM, 0, &actual_index, &stream_flags, + ×tamp, &sample); + ok(hr == S_OK, "Failed to get a sample, hr %#x.\n", hr); + ok(actual_index == 0, "Unexpected stream index %u\n", actual_index); + ok(stream_flags == MF_SOURCE_READERF_ENDOFSTREAM, "Unexpected stream flags %#x.\n", stream_flags); + ok(!sample, "Unexpected sample object.\n"); + +- hr = IMFSourceReader_ReadSample(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, MF_SOURCE_READER_CONTROLF_DRAIN, ++ hr = IMFSourceReader_ReadSample(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM, MF_SOURCE_READER_CONTROLF_DRAIN, + &actual_index, &stream_flags, ×tamp, &sample); + ok(hr == S_OK, "Failed to get a sample, hr %#x.\n", hr); + ok(actual_index == 0, "Unexpected stream index %u\n", actual_index); + ok(stream_flags == MF_SOURCE_READERF_ENDOFSTREAM, "Unexpected stream flags %#x.\n", stream_flags); + ok(!sample, "Unexpected sample object.\n"); + +- hr = IMFSourceReader_ReadSample(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, MF_SOURCE_READER_CONTROLF_DRAIN, ++ hr = IMFSourceReader_ReadSample(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM, MF_SOURCE_READER_CONTROLF_DRAIN, + &actual_index, &stream_flags, ×tamp, NULL); + ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr); + +- hr = IMFSourceReader_ReadSample(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, MF_SOURCE_READER_CONTROLF_DRAIN, ++ hr = IMFSourceReader_ReadSample(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM, MF_SOURCE_READER_CONTROLF_DRAIN, + &actual_index, NULL, ×tamp, &sample); + ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr); + +- hr = IMFSourceReader_ReadSample(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, MF_SOURCE_READER_CONTROLF_DRAIN, ++ hr = IMFSourceReader_ReadSample(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM, MF_SOURCE_READER_CONTROLF_DRAIN, + NULL, &stream_flags, ×tamp, &sample); + ok(hr == S_OK, "Failed to get a sample, hr %#x.\n", hr); + ok(stream_flags == MF_SOURCE_READERF_ENDOFSTREAM, "Unexpected stream flags %#x.\n", stream_flags); + ok(!sample, "Unexpected sample object.\n"); + +- hr = IMFSourceReader_ReadSample(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, MF_SOURCE_READER_CONTROLF_DRAIN, ++ hr = IMFSourceReader_ReadSample(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM, MF_SOURCE_READER_CONTROLF_DRAIN, + &actual_index, &stream_flags, NULL, &sample); + ok(hr == S_OK, "Failed to get a sample, hr %#x.\n", hr); + ok(actual_index == 0, "Unexpected stream index %u\n", actual_index); +@@ -796,31 +777,26 @@ static void test_source_reader(void) + + hr = IMFSourceReader_ReadSample(reader, MF_SOURCE_READER_ANY_STREAM, MF_SOURCE_READER_CONTROLF_DRAIN, + &actual_index, &stream_flags, NULL, &sample); +- todo_wine ok(hr == S_OK, "Failed to get a sample, hr %#x.\n", hr); +- if (hr == S_OK) +- { +- ok(actual_index == 0, "Unexpected stream index %u\n", actual_index); +- ok(stream_flags == MF_SOURCE_READERF_ENDOFSTREAM, "Unexpected stream flags %#x.\n", stream_flags); +- ok(!sample, "Unexpected sample object.\n"); +- } ++ ok(hr == S_OK, "Failed to get a sample, hr %#x.\n", hr); ++ ok(actual_index == 0, "Unexpected stream index %u\n", actual_index); ++ ok(stream_flags == MF_SOURCE_READERF_ENDOFSTREAM, "Unexpected stream flags %#x.\n", stream_flags); ++ ok(!sample, "Unexpected sample object.\n"); + + /* Flush. */ + hr = IMFSourceReader_Flush(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM); +- todo_wine ok(hr == S_OK, "Failed to flush stream, hr %#x.\n", hr); +- if (hr == S_OK) +- { +- hr = IMFSourceReader_Flush(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM); +- ok(hr == S_OK, "Failed to flush stream, hr %#x.\n", hr); ++ ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr); + +- hr = IMFSourceReader_Flush(reader, MF_SOURCE_READER_ALL_STREAMS); +- ok(hr == S_OK, "Failed to flush all streams, hr %#x.\n", hr); ++ hr = IMFSourceReader_Flush(reader, 100); ++ ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr); + +- hr = IMFSourceReader_Flush(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM); +- ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr); ++ hr = IMFSourceReader_Flush(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM); ++ ok(hr == S_OK, "Failed to flush stream, hr %#x.\n", hr); + +- hr = IMFSourceReader_Flush(reader, 100); +- ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr); +- } ++ hr = IMFSourceReader_Flush(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM); ++ ok(hr == S_OK, "Failed to flush stream, hr %#x.\n", hr); ++ ++ hr = IMFSourceReader_Flush(reader, MF_SOURCE_READER_ALL_STREAMS); ++ ok(hr == S_OK, "Failed to flush all streams, hr %#x.\n", hr); + + IMFSourceReader_Release(reader); + +diff --git a/dlls/mfreadwrite/tests/resource.rc b/dlls/mfreadwrite/tests/resource.rc +index 5edf5254906..f54212a8c8f 100644 +--- a/dlls/mfreadwrite/tests/resource.rc ++++ b/dlls/mfreadwrite/tests/resource.rc +@@ -18,5 +18,5 @@ + + #include "windef.h" + +-/* @makedep: test.mp4 */ +-test.mp4 RCDATA test.mp4 ++/* @makedep: test.wav */ ++test.wav RCDATA test.wav +diff --git a/dlls/mfreadwrite/tests/test.mp4 b/dlls/mfreadwrite/tests/test.mp4 +deleted file mode 100644 +index 72bcc0d8f3eafac344bb2152438afb0c4c691338..0000000000000000000000000000000000000000 +GIT binary patch +literal 0 +HcmV?d00001 + +literal 121550 +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 +z{%-Bh +zsx@awKRo<19F!2d&k$?u;k)fK!*$nr^b}uvxRH21e$%M*F_6Qi=W5-NIFDMd_ER(a +zqZ9LY=!^NF<`*h%jC+*aG@gYU@AN&Gf|VUCT+JP66aq^U37eKB=R@CQ?$IC)GAQTx +z4)y+V=vR~$sj8zO`Wp;jBw93aZwG03c36Lz()+NdQJ6dk^@e0XcZeBwAo3!fmv5^? +z5JK|Ph}nay5xYZ%kiYp96dwM2q8dc2H>+T@6k{{M8|k?$E1v3&oW+~_^jNzPG3dgR +zG_0(14AUpmP8%1jM5~){izbrd3vtd>?2H2DZC^s3;>I(O^%H}~A&KCd@LZAww#s3=0zDL|t_2?Q;<{R^GrOi>wTsx%4A=xvLL**+&V +z&fg&W%}^n))zEKkmZPmzI?((TlwU!EJ9jyAT*SLY%ru~McXq1!Y~1#=KS8eCCu*Yq +znX*jH1@;=7c&i=)7efc>n3fyg1j17?8BzPi*yv)Sf_r*!o`c3a`WlbvN#j5&{qWC$ +z@7l=4I@5M1ltOfDA5o2;U7qSV`HQed3C_ilOWJ;7Y`#k+m_V8~8a9U*SX1{ae*_}? +z2G_HVz>R;`RJpSIA&LpzNK3q5KV@8IoO*{U@5Lcp3sH6q{B544%0RE$=ym__8qc1{ +zSZ#acDq~E!YhY%rja?=ZCRxY$bpC_qFftb3TViS3wRCF| +z9Q>kEwdOdxF9oMC6j>7;xXmRhop4ViLHJwDFhNCZ3XfOqnml73rss<`o2bh>{$R$u +zuEpfo@Lrwm9?tS#!EqeO3O-IHxDA(5E(pJP>C30GK92jg+&m#33Z*<7;%cnh*ht@z +zF-J1np}O+yhc`QxI`dg2eO)AJP$laU-LGPaw}vSr(Q4^=sS}S;J;Ci#h@+v?(LW{O +zDoRqXoE%f>+iWPdiF~^W({qy4P#Mme^2s4l=dBwp-&L`y3(f+!>j@4jl^g^v}{6s*Hzb!0)N60tujwLVDLXhgA +zm>Y%03V6=*qK3IEuJHF`LI?BgtEFB*Sfk%&vCA(CSkXpI2bG6mmC@m}3eo0FxeCIs$2ehUM|FpvBfuhL+=u=xnSVL$bfmAoQgz@lZBGXkUGXvE +z&$QGRUN~t-%PN$VuA_8ZtI865WTPk_{#vp~;6Vgo_?o%I_fh6z4eQe>AeUB(9Ab_w +zJJdnE*e9~WAojbJtLfuf3_119EvB!i*tHRE@&f0>F1a&_d2o+`OHx#DPb9N5iPb1N +z82w~wcyNVu;IE_MtFh7)Pk!+>r+DuQUaY5CK2o{Dxxt`ury)^S+M)i2qg4T +z!5_{LDD@U)p_iNccS+v0k4pazw*a(1pjk^cj|;N9M>G;@_;Q1Z+(2oQEn-NMzEqD(92Mr +zmZ~dlimZ$&#E<_=&H5DrCq +zC@ioO9@L&zt?3HC)EG6g63swR*(^4(IVqD*i>%Z;ZOV{4ee6&sBkf +zb9i{wc!8pZy|H}1=giJ*7{%Em66{AHfyN~5BQM9V9 +zArQ0VfkpacERo0tP0`IgXFRA_J)UFiMa}cq2Xke)(IEN}`7YdK5lGw1fo+PsO*&3> +zgx|SkpE=_?tvm~Q_Q;nO-~CA9(6akES`(%Pq@b}fBKW{0JU#E;$YKvQS1ip)XwYi7 +z#JO%2Pey2K~ED-x8Q +zx@jFh$pQ}r>yu^$CHQ(SBMK(GJF0w;m$BK2IXU%(l=2hauNXXD=(EQx*(w^HL?!A( +z8u%l|f5dH+Gh!4$Kr9mBUU$4gBmmlWnMeKUBgs~%affbmKZJPMxJH}i<@Ww4J?ojJ +z|8Z|XgYOxO$}N@ZS#mGD6ua7tUrNOH$`V)DzqwqnB8&myKAx61YP0NrBr(JRX^8DZ +zuh59tB}&O3>_J}z5=1d1SN-mb>S|Lpy;6AhJ-%W6)Ol3pxbCI6JH2Xe!`I+mwqm`B^_ksJ=A8i& +z(f`=qNyjw3aBRz9`;xcze2vdCl4Hd);(v>}re+*C2Z6Lqq=0_d7eFYkKb1WqyDTi9 +zr2I&)8^QDdy;aQFtU)%CA|&E9z(ps5i89pCZ)nG^d +zf|ClZW?Ph!xS@Op6QkuYK*~z$)&b|?4BL6g*6KJmhU7`m$Vv%9EMIE&)|)IcrMZj? +zmQ^;Rf*ji#x?N;RTy!bN2dM4d7W*Th_%oZ4OpbS8U}IgZ#E65to8m#kF}h8V5RMILv~r +za*cC7F6q;ksS_ic_m^1>2Sjvy!EBR5(@o7KgzIQJoX{c8RGzxHSsYV|M6R&jPG}$P +zQ;0=TQZ~@}H!n^=a*4xbo??*E1*8g1oq-~AeI0=*78Foo5%{*Q%PgQ|bOb=QlLox& +z4xv0Q3a}-_6^U}d0kxYr)MRq-ZDq#4eVRsJ?x}Y>`i2UIdsVfJnTW`CP`Q=N^SNzW +z8r3}!yDCxjZR(FiP&0%m^u)ITe)-L|+s7Qz1cCILMZ-Div2vpOvtIE6_lwI*B>R0mh3zkyMji)zrihiOcz_o>xCIty;Ne>iWt|u()^7+ +zTQfw#H=>;4bmOB}v14YL{5q>n5WK^l<2NhRW=)>&itS3bu~fJpWZ*yudmx>YU(U_k +zYwP;ROT(J?#zN@G5{QZFenr`7e$ljo=OD?qQP4qv9BiME`4$|4?!VM)>135y09vB} +z%k2W$EW`#R +zn#r3LxX{q85WtO0b=SH)Qu}W(Thnh~=)PK9Ah)^8_qQfcA!}6;uqbz)P6FP&ZfH!% +z0yiGlW?sP}C!I~F+m-QOy**z;dy=M>YvWCj+i#g)a~)h--cWFXxaW=^jJ^jRc^x+P +z9+^0+XhV>UmPic6D_?itDeL_(wPvk>o$9#7^m*J +zR^COI-R4(W8rRz0*#OaHoOd^oj+e7Q%G2HmT5#EEC18Dy(Ja}l0)JeS% +zfw985&4akrc%GtU<0FpQI{udh-hHOn9&NYjk~g_o3-zW#)2e4jE|rt6${>57I)->3 +z@vwmbH_v#*4=U^;fns+H5n5z +z@QFFnBH_9;JWysB681$^5(q%zD4E7h00p@w=D9Bl8#}jI|WsEvl +zsS?VmS%s$EAp6J~Z#H!ve~O|fpG%e|xTtn1u!n)NJ@ +ztH(Nc{h7kCz_|v_f_{A01e+W5XNuIMW2g2Ys5y*m=W$_UN#tDxcP|%j%_vm+FPoa5NmHVQMJ*#nFp;F797w3-D9cQh<># +zQi5j@4_Fe~vrcQZnWXDD+WA0)P)_g14_eC!}w8I%B$z +zd#BHTk?B?5rMx^4ITjz!u5nk9fdr56_N5>M> +zh%An>{hFFG8g%>cHr~drhHj@tv&Sl0Zbszx9$pPL$`ce$~HJGC(YI>J4f01gD!kJ=f +z!0#e0j5FDHxRW^T#1xTnO`TeRWszJ);3Bj3I<=GjeF;KgK+rKx!YtW*SsqB0_dsZo +zMekvimJ=u1AP48~!c!++$XZ-NE=ZUoA=T?MfD8p+_vm%)074YO11orPVJ@Fx2pvzU +z1-5dnX>oN!_DP8#l8gq<^m)cMseplPmVApji5W1Q{RP7n$leS(|JhN)ob*IN_3Z1< +z4E|NCzh`G*Nn0F5L3ont_1=;K +zdW4(Kuo#^-{)jl?x#+JNa3|#{%i+(5oa0J&=y^>*8lC)+^o}}2$&J|nL^Dv>nk7Xi +z_q-91&ZAbp7Xe7cQ<$stqHx|{urrl8oY5EGswoRnxz5pRqhvzbfts!$qZ&Syu9~6F +znEE9KCxUkbjz<-Df*l9zs*rh< +zU)b2)P8bG?KKy*VR9}8tB=W)3337;8dseNm7SdNI@%Z`;6G%+wJ!pSQ5t*#`>d2Z^ +zjzpSM|CR)-e&;Ahq4wK-$e`AhH^GDlN{E(_Eu&1o*4Nq@2Qk-%GFdH)?Zv66uuk>% +z`a}u1z||HFB3*DynMpNW&SiysKEVHZj?Rg}>wM2B%`vwp+s;{i6sx4!_@204WIc#T +zt6bJtSra+K)hd^4i&2O6E#pl;lo)nnckl0;AXQ+*MQ&YT(b{0DT9IV1>y{yh=W5bz +zf8uPH{U(-^lKNY^S|zX;pIj3)(U~E?@8u^n>Qo=;_H}64aIzEte{=p+B*%NX~ +z#5v1iD6R7h#l%_pCGpC?E$JZPf4q5rf{{UK1D+PN?t@(Ze0obCORD0D+$;iGwxt#$ +zzv!<<3&j2+t-1<6VJfWACt4gYaPTx@II-Z9rYKe_SdytV##xaeXa`F7*+i@jfOFWo +ze%gc#qyq+3VI-sv6knC=&!MgIzzQX3yf_cnO*+caPY4GoWnOCv<41R#X+hl-!16cn +z=7Uz`q-ezER|3EUL`ruWH;)ig753mX3_F4KT^@0dtR;y0yt8I$*7e_>b}@F^$X4X- +z+=RTC1<=2e6*yABI;?mj42oNxbM0;p@B4&(^g4u5sU5WwCQ+jjAIz5FDU_-A_V(C3 +zGY!&l?VD~UCo#CX^(FI*1qWC536qED*08WIBoPS3M#uFhp+`br*r?7-485f75ggS8 +z_96UY44h_lZ@Ddka@O>+P+WHb_qV`)ZDzCr|%<57DXSjG4Zrvi@@ABFhk1xia`f>JQL +z94038Ysp2td`Gj7+p!f6T0|v!t1>S(^kOs}-Zm!_v_~q00Cuq7G6+EXU8GImn!9b7 +z5coyF@-46yzFCbt$1}vv)Y@?PGm*W4bB!zo{eZxR38VAe-9JoKguOxlV8s3?pvH0z +zSzh%}V^fdJ{fpls10u}_sYZ$EZS=>fTe^^4aBP{9m#KdXeB-dlF%{IiNxFjvS93|* +z`k6=i(4vUkTyP*5j0;kbXudhKq{HyQIYJ*9BYbv@eZUK+p0hJ)$=(X%1l3LIU+(PJ +z^(_NU_EA0}DvwebQ(dNuGg=E741O9u3pmG$*)#4bgtStz-OX1nF@eN8pNFuKOUJgR7wBafjE9Y{hR10)@p +zl_yu^=)K9_d&s??EOtBhUk;kw1O*GJc9F~>X0Xnq4jhaP!`XPeP<9rn*A{iJz?6v* +z(Kzn#eNpig?nEBfGr{={)z5;ej&3M0OMK3sHIUmt1nGhp*x~sgAA1y7PnwlR+IRoe +zQ?n#Q48@L3PMcsG3;81OiAz%RCvlE0%0Cmn*@f+>>*^6;7O*YEN|y)E0dg4pTIxXM +zHXu`K2_d0Q&1kV<)7a5xEsD(3(=gD<{VQHYH6@yu48dL_HuaL>k|seZv8)!62fn^Z +zkI5Btoj@2A>i~kWiLK+LxsB>;PkK(~UAoRC3&T=Is^M(gclw7aF-EuFTHV +zyp)#f`D}|`dQkfPsnB#8IUcWz+G_h{h$}J+K8}^$4~?wY@Gr4mPrcr1p0ruR`}=@X +zREqP6vo8sx%UK4iy_;`A);%sLt2-1u*Ci^hr{-UtgTXKVU9Eo?&(D#+g1*Rg7+&bK +z`SZBQ!AnxS!MGA@ZJSVi^<&>5zue-nu%C-qD&T%a!!UbvM8YWAiYLOKlN!ah@JKlq +ziu*ld083RRSi-DAmVW;uV&iAwUeT%C{JfAj*ReQ&FB+CMVaitFAPEMvPy7-72E@yC +z4duq7w7%7$q!c^32F>U*Kq-!y$bo(; +ziQMj|9Q1oOn?tUvar4Se8X-v+DPp;8- +zdY5&Vq$x+1aR(&Lw#L9UyVa{n_#OQqepkF6T&~o#ZrjTse18<@!>f*KI7L2*0XIxK +z#?J?#>+NpZ>91kHl%=nMKSvj0mq!w(49fV2y?2aLagWyw*DdxbKZ;bP@U(ddD9BUk +z3~gC`?J5hz*?)Xdi$>h*(**gN=g#tm4rqLb$F&h&CD*Y3;&H2`d1q>k^gg<_BEx1x +zL#JY>oDOkT4}VxhY!Z3&_aB4aqLtcis(xEat^J7(xRX_xvNy~Dptk7Oy3|VRdon!^ +z1W~|IGTJJq)<(n$qdWVO)hxmpDlZ_lzEk}!AcJ#aR@VMb_I54X2-2J +z$txf1IHqRAX^v$bCiYG@<`&PP!7Aw}zLJViP^^S3V@bfT_NyaaEypnNXrw_}{01n= +z8?8)4G}oG4cw-+F^9tX3-O-9EB2V2zzSj9{y?l`<|3<++)fDHV3Gsd1TaJD3u@_-k +z2clFAe5NViF6VWTJtWxXn7T@yzP6i5| +zoa=!^zkOAsj&#&Ox~@T-AbV0!_$*VjBKP+1sE;En|0NVTXSzfary4cIzpj3wKuF7n +z=y<=P07bTAE@Lr&ZJ@;)V5rbZ05xk+V+^2-q&AX?* +zvyA~USu?9c<=ipyrNhQcCBe23`p3=Hj~WbT7UzPAFh1#%>RDAD7 +z +zmltv{x$?(z^km5n77 +zz7KMh5cHmYGX>SNqA1rSHp1_@;fZ}BufNR-EHx4X=gqPvUiWN&K7)yK}ZsvML +zB#h4T-Ng~W>4;FsIhyxGn1lf6!2PDgm7%K(sf2jUL@yK3C{>0 +zi_%iZ2JYg$qoOzi+h`gNs}=Xvl;JGqCmt3f#~kS#SQl~X=+KpNgE1Ewm~#5Ce|d`U +zV|&c5P=NHtZ}oN$xO-oaSI>KJ6v!L2-CVV%ta&>z9<3_SolB5ib)5FyiDyL?Qmrg% +zbUZNSpdh6W)4z#tBWHG%@69jgEVa?X_||8KTu4S(F{N0TF*1C#bu-98>lQz-DPC)1 +zvz?5~=R$iU(Ohca;5e@1>=sL5;#d$+ghyufm#8>&dRqD^7+yE~RX_+m!PXk +z<@2p~DXvdD6xz6RR;amNpADE<%OVyuqZk?Co=rON(yu_F4hlx=-U@kjp`KA6>ugza +zXDsCd{rzISO1KZw>|#ycWShfowrxhJJ<)p7uI$}`o!Bzpb&L;M#ldWi0aYah6B6W= +z+jQ@L1*lvGj-CjXc{Af)WF$)=jT|0>^?G3 +zb=RyUy0z|B{pR=wZ&$qGH#;uUsL2429~fo)eRif!6k`;-S~+e~aE%Y@;Cr1mp*Qji +zdg0)!#5y4}Fd>b^SRF!6J(AM%T*21wlPe=l6+|Zhh(|g4`BN7N@)?Q@Zo?dEi<;vy +zgisJ&a9bJ$o|W$GJ>*(2;IJ^8F4YyR1^iN|}7iBEzM>I*7pKAeS4)9 +zS7#d!y?iT-khN+ZmWiy +zee>1#z@AV6ltL1mqJcKKSBmpN6b=Y+75x!h5CDwMa0!xB2>w|!pim6N=ez0u#8R8up!c;#$VoioUGm0w?Bis`7i8M5WqlFl1S{Xg8F(Szg`Mr?H8hw# +z)c-BvpN0dUV_*h`qsVyPw$S+0LQtiQJ3~H^*@b4^*(Vp^WpS@WV>6{WdyD6M!Jddo +z8jJM7u-1VF-MrDTt-ox$rFwJUHWkU3glHCFJjZGcb*D0g?z(@RDk*!fYDAUIec2F; +zPSkmg=VQCOg%@n3n?a=5?liwwy^n`j~j87ck+2M;g39+mX7GXvg@ +z`IWCkEpoB9zAK +zupBAla=UiQ>EvyNepn8y5S7$Pbr~Zfyq9`18G5sHhLpE@ +zq#eZcO0IM(r54fPrHAG$e#1+ES{4$$(B^)QFR~V%K}EJv_BJ~HropQSi`QjxPy(-e +zQKA8VU)xrcD%{Y6g0tgUrehDknBx9q(>zV{(+TAngKd+3XfD}aXiO6m--sPT(}E7a +zsG2(FyuH&=6PaBrP~*Bc{T&eqjGG#k!qtFIWH)s(X;UI_f85T6cy~3&7Hkfg%tN_^ +z$oh?;a=zW!JtKsBo%&qMb89*x*S^8qO^YaGqERY*2f=o;E +z4Fp=3^5hJ!nGZrpvp;yUs9F%b?KaHJUg>#?f9M^27&2b#S+KH2S}Zwq+jMB$0PRv6POT4$!lhvt{jQa~MSi0MUjD-g>gtd7 +zOfSbRtXD4T?d#$0AV3*W{WE0?2IAO>WWvfqa$7h&ZJG?Z+V>8R#LO=4238vT4+QHpjXy4 +zBVKrV8AnLu3nlV=)P+Z9DalH~7NhkVXh@%<7ao$F;%t`}97kmxN`(oeneG*Px$T7Q +z29=isfZ6ImkqCSCIx*S36sc+&mjqNgmQB<)woa+@?cs2P)DBF_FuI-`IQyb&z^>PUfM|F0eam;5Y}?Ym(l1c=U`wy} +z)(ECLT|Q+}?fGoz*i6c1%`^w!yjFTd$Q$DWNgN_2$7VL<3AfJ +zfCY+drQgs!07n^XKG8#9q$ww0ba)#jIV{$AE?h@OQzdN$RNN~*+ZC~Vwknu*Qy@|0 +z`)!*XABKu5cV!wU`CT50+f5XN@)#ws2~5MD9zEt#DwGkz(=Qi!2 +zY5l)1rC9kr4jhR+2P*>>?z_QeIuK|wvUyE*O~660AbHuYm@#}Xi+k!ZLUWBjqBKhH +zf|VHl`Y`B}x~o-S8#_>UwfdLkEJ_p***d3(h;fk)%rZgKLHvVwot|i`ep_hLTQoW_ +z(EDDVp_|!yjRwLtb%1}Lu_7Z92Rr|&fHi_Z}2pMNVTnKMYnB6P3zJDe+_mmK9%`k#Pik&bAXf%6~8Q%~kJ&a?=Nuln#MY +zwM2LbYsrCd3^xEM$4Yz!-%AtGlQ!FMz7IY>w6KwHXKMeRh=myr;3Y9t0B# +zX86)KUK?iGvLEXxw%Fa8zR;!dOy&JrS@%Q!fMQ461*#v{;2~2Vtxl)~c6}7fE3G|- +zCrNa-Sz7bt91{E*%J8r)qKe@i0tjkEM=Q&Xkbpbw-Q-^4UU+pFVLX+hWF|I7veR&0bvD6{7yvf)zZ!IMW_Gd-YH_bLQekS6zZ43;#0+qZpIg} +zQX&Jj1k2b%^qa*Vj@L +zyq2O_;{tX01S+rR+E*uI_cY|c*zT4Dl3woUV?i0tG1R!!jtR5E!oonA1wJ)5e+>8i +z3*IYt6e1?N7eZ{)RVcogl()VpkoV?1wMM$kF&j^^K18=#Yp$Ewc70vU5_b--L1uo~8Ooj-GL9H1^B@@7yV?ONN +zCyX7hUA@|V4>`~L+I%-!aP3jvE~ZKw#Fjjxnb+*bFl$Lq|GRM{EgUZ0ep)LX2kdiA +z^_*Vt21;n9w_+;$bm|?VENH0%YZ7NyJW7+LlmAH4#NH?tDg6EnzkrKu9QW2=`n$0# +zDhMN~qC$U{vhHiPtR#8i9z}Auqf3Y_cuOLzRZ3+ko?=^%qh2)qx-0jJd1r&cLawLI +zhBhRE`sVnbb@8xqC)6`0Y1^W1ak`^>D~C;*Ky=3l#EN;DvprfyM@2NpCh@Bv)3jTs +zqX>5!BXFE|psy1T55tzCvG-fjNm7#ZUoA08T&E8Yqti3J-Bx74GUx*Y+?3@w$I1~A +z(eksd7tPP;4+hRH{`nma1U4AZt42~Ylz*M4RZ`;*YDRk$ui=KSF2`E_d87b5Fw6f_ +zGh(&x%E+QD_x|o3HYe4UdY{J*S1ZmG&C=sx7eNYGaMSj4P-8Oj*F(wXv#7-!rHKkm +zC6e}INh=KR4Lo-YJ2TeQ{n;VA%M-4~v`9|T7N7O*MBlhW<-kAk}tk$j9Okb70mS1LNSzFP`K>obO?q`duRQYM_wK&Bp +z5**}B)oA@Xt-*l>2)@xV5$rqNC> +zc1Jh|PM0%PMjz+$KSq2!f0{`?eKbRChsljMMssd88-JT-Fql)%V@eoTa~bje0)F?~ +zZO4HP|Md8f+8N)kzSQL^=SOl&1=n9A9ERg;jH +zCy)5roRoZyC#Hy!480^D0DuU~KEpqp- +z1^H;jG5Tu1KKqIchacFZ3L5Tc?!a=U;<1FeoCxzo79#Fh$DM2~Td*{(Q^bunoDMYN +zR7q?A$gzk6P4VtnWcGOCEw}H@q0>2-yew*+4ss5R5pJ}~7c4Jdo_(41!-QYOT!i!A +zD2X4+1ZD4^U$O@k+U6@%`^QnwF(P5PKQmaT;-nZN+1OG^qu9F7aQrf?oJx(8i*WcM +zX-5W&6fFiUg^544(5)z*vz?YLVe?Iac)mhXq3vV75K@`2Z8iAZ?TA(RCQUU4>27ZW +z$5c*4xUsREI0^=iN4^L|i%0e}<2tPpR|aro9qeK{YP?^hZr&FQBUVn-Ii#;7o|U4l +z<18*N&TU&|E;n!Eqctt|I{&$-xoN8i)Ps7lCXVAJH^H(#RNFh2FNEcPdo~Yx_&`#c +z;xd-`fu}VfECsEkq|y5<_`lkaUANTn$)3sg4}Q@O +zh@Vl1X!u!nh>MYS<7dx?;*DY)@h1uzIMP^f{o-xvN+>t02RGvDMFEF2*Ezw6-k}v8 +zhXzITQ8T4ZItw#Yh7NlsyamZ}ot40z_g_f}kfyf0s+MzW<>E0kz6)2a);Lqh*{D%#af0KupO@Y+2P# +zxXU<{I2oXE>;C|AK#ad=S>H2|y;x%mwfgOsff+MGNwUB?tO=$8pgzNw4rPSJF0+ho +zs*{Wg8Q18MNapr(yhB(jA%Faa8l~dts#`stdsr3YU(90E+^Uc*`oRStt9nQ-%Yt-d +zRsW47BLsNIX#(zjDQson*iZO=E^GDVV|3mGr;+$>vWf;k1xCSJ({Igc9s}wV_lqF! +zzd(V|p3rwhNIHHBO1J4W&uf=H#>XmA3W7ETO#r6KJjBzE`alhjfX`w)2dZRW_4+2K +zXh{rGDz5pf1g)21G{7q0m>JT}^i}Y({>@qh`-4o&cyM!M8a!jJ!Ni#IWdzop;nv?L +zA|3E>3!cY4uJLmE1fA{*1;1$0`Zd7_6O>4{DA%wd;IjihgQ!fo +zHQ4`aW@v!=Q2?#E8vPJY0}O}b?{tG`S+jC9qu`M^f;tzXeqH_BKGY`AT2!No#2#=*_-iE3i;RB578Ha;ZGA2i%6naul%G63%BqRsmPWrkY1F+ +z+=Z}D*Fyxz0UzugHG^c=K3%S`A8E{LR5W{$c3Es&H~TXzkHS`1WdbwZqpl_^V8iye(Nn3>c2iIJcY>G!^{h+t|9e4iiAl~0tCC1mxRR<+Ea4QG<}h{LsguM +z<81hUUXVO(oA-m;dya&R*2(}RlP5ffn63r%GG7Gv3xT_R#^OVZ;L~}Ns0opdqXkAk +zCNkT?xaU%rGB@tLa$KG)rp-gki=<4(JDT( +z?mhn=I97ZgZ_#%`!ybOGPN!&ih)`Zhn?9Qg7`Mv@Wow$V;^!3Jl{`WgBD}USa4RPY +zBp4krR-foqv5EOXb&ja_3q!L+Ga%%WO42K`{_P)Kk0fR=Jlm4|HlAdcYTd8eiu&(O +zV6-{Ofxe)jd-J+K{3vJ1000Mj0iLI7LVo}R%3Q-L{Nba32z@}%sg8v6QgvHtQE#O4 +zQt@X@k3lwduL=?CK$;S+`|7Hc)MNxa$W$bg7A4#0lujq +z5_`h3aoatNXk$!TB{FZ@CJ~h65@fA)a7!;Sc7`@pZUx{zEl29d{dG6hii*9p4xNZTuS5 +z-xCX}y6E0zE&(%perM_3XaUsP`0g^ockOc3H&Dj%NPOW>O2C)kMVTt)nC7=wOBG&~ +z9W5xI&t@w*VgaT^$uE0i?>%G?9*4Q?BskvnhB_H +zcZ}n1aS*@`c+6lCUaojb^zW(`+E>TZgHoNr2ltS;P$d;ixpd9AIkIX!$cw&#-$t+x +zUKZ0o$W7o&H|xqhGjEw|bjn58u$Xc($<$#9XrE2;DFq)4Ce;s?ds^NQTSFjVJcn^5fDBPr`$ +zlO;q{{=#?brl59|n(XnC)k<{ci#g-A0!o4bMF`N63oq6^s1bgT1A0hB-%B|1)cQ=& +z5E$-JCHqgRHU~gW6!DP&%aJB!W4fo5a_qTB)<*&*F_b!N6khzp!y(4c!pR$q +z_e0G?nb$&LyK6ps`Lc*S>V>ObP?q`NGco#Z4i2!`bVMYyzdKbp(D1vQ>M%x5RbF)6^>ENx!0r?Qp7ghILM3C(j +z+;q`q2Mze?n)Gr9HSMc*krQ#e4IO?y4ucp8Wsa|rlziItM^y6S0kadx@XKQ8a$?I_6%4mGKJ-xH6d!i=SmpS+7<3=V!$5j$kSGw`j;P94GJi7Cu74n<-t5W3g&1^7u6Kq|z@%ZVp +zCCu5Q91B^aiog_ftJ&LQr2N=6@e<^@u4dp9y`1K9KjU6l=|u34No)YnguV8wKoljT +z7%(oLu85$v0GIx)X?Hix(W)vJ?cjudUU*PX(^``ud{jR4erdCE6U$dA^>nW?vbVh} +zUuTz9f5x(Ia{lf +zPwBb`O@ZknrpE*B%l_f+D-Wpegd?FdH7*?4FUYv~xV2_%lNUG{piKmQ$$2{Zs$(Nj +z@$BX%e2Lek4svCDD)G>+22Ba= +z-csA~UqIi;uhai5kgKC(s*?t) +zxHLgT;%*GD;7WB;OA_2asC~FkahP5xZ$tN|=6z5oQMV_e6{<0Wfu@OI*Opf>Vx_>W +zw?u_ARC-InL!5vBH_qt@j{`-)g$KC5RBXW0*-gFmLP>VhD0a{^6~?iDO}+~Mz6WIn +z&U$*G7ih@Q?jPzmxVw(*VbLlTSbr$tP|}to!78b-ZN}o|iQ5xGLZMCOaI{mqy4ol5 +zX;fLx)~AEpTRM`9gkOMP_FFq`5Qnr`qVX2fK+Qk`4U(108WgTzSO|^VmDs4;U$T)$ +zsQPHW9LqnVP0TxDfqs8CY9OR +zm7(~01!KHa$BL-Ow@sUtKKG_ecwHyKF3>k=Dh*uXl*?>OS^R%)_`&Sk0?QkV`e?PS +z_;Ps4tyRx4cXg-eMu)-ogwR&@)_r=zn_Y;9i1`w`u0HVlpG_7g_nHFn*>#~6369Cau#Az +zmOxd@2qLt3W+MfU$B;dMa`Kr)TCs1q&mFgKNE~42pAf+8V3`c5AdjS@#nHJy{gfjo +z9>a0>5Zn}`U5v^vI{gMR;n!%n)Z@SF<)y&wh|bgtr`(qA)#75HW&nJ7lH#~rRw+E5 +z%!wSNsJ@1SO$%e22_}{!O~`tI{6`eZ{F0@1mmh_O +z@ibs-NykBF*)JfA#=JIWt3TQ&SBqO$Kp28ed6$OK8gZwxD2%=F|i-}QoN_XQreov +z5h3ieUcV-q%T?Kv!>Zx}S%VC9?fCL-%}(bQ@?9gD(=b{{;gI4k$y;Nz<2#KpLgsd4YEVZRRs;oCZ%<*tv`HB<6~PfMkbw?3SCgjSetP45($!p`@t?L}u>c +zk;RO`riOl*d+l5teWyx-WFM|-k6v3XYkz@lxFcWcDAVtcbPNp%Smr7uKLr8y9fQrP +zjSr5FTmW}$&@fz9TUC|)LpisT9AJ2b;k(tNj +zDKz%sLd4DeQ$IxT@JislyF)*Y-&|F1CkRe(8Z>mrE*W*~Kd%ifX@$i59;ef6K(C88 +z77~;sef}*G+Hb=lwIIs>G7TsJVvwp)T`i`bu!v^RJ;?-uT1s$WkrlDqx&>Puxz3t@ +z3ByaDdoY08w@1TQ+LUsO>f}_O627h$H +zxG7I?F3(ET*5FP1H6n_zYQv${O`QhWBr<@=$fo%8mg3}Nl9N2*smy{A$E|P8A=6Vz +zqG7tRHnuAif@~&xjbsh%cGOpjIW=Wk1y~+6tGchRD$y#;dixNmVDg|G7Dm`}nwG^5 +z@!@XZYNTx8kiUd3uZIwL!DOo&H}zIq~$lN<}ca{13Gj%MXE +z99xNzdR=?tz!K?hfhO(P*~e}5I#j8ZasOq?GhAQXl|NU8QY76AU(38TB~zQ@XxNm{ +zy(VlMOzO1?dWprybD4|4NG9;!Y%Y_1P8#r^FvB-#hUH5Flw~(f=#--u1X*sG(2$6} +zDN-*K@$|wXfZk5}H+}&n0Uh^`n2cwL$Z!&9Ongith%^^6{f~pngyw7kmG+)e8j?A2 +z-~-@|k{iuxU_I<=F=2p#R!~um-jeqHzg@wI=iXk!CPj*sJRs6=QJJF81tUvfefwYw +zHVMZ6>9escSBGvZv$s6L^HFX1E-%}RiTTb8a1=TgimAG-ZbxE&g0?q~|B43AI7C}z +zE9T=L$tOqRxC?bW88lvg7wbX@9v}v!S7@!$eC3$J$koqyQQGKgiVzo{L)UyFv=zVW|<%pq~e9xc@kA%(-(8AhqmVGrN@6Gy6F7SV*~wP&QX7=RUUlMD?=-CGt+sTUx{P!_8=;lNpEKgB0tO2k +zCGn2QDB4K_L;xqWst9%OgD9AzPuz142!1)#ySdHH1(+A$B^gIv5gmw +zPF`OuvC#rj`-nYQ<5AKbu88k*Kxk$AKMtu@KoDYRXvlvHcH%%Mcv(TNf_=vThKC(5 +z5t3D3Yygh#I)$zFDe +zyC$IE(zeRhwn>aM6%8cSAaAH?#UhmI*%x-c4?i+OPcxE6^G)Ew(P`&v$32C;|F~`9 +zGSDw11-CsxsV+Z}jo!V|J4IorkX)pl2drsvYVLfgv2M8;%?Y4@tycQ@Fwhn^9EcJT +z;!2o1LalEv`06991ziiRhlTXrchG!Skv%?eq7ZQ!Kw7qlR>WWCRn#4}d&&E-(K@vR +zjJcSTb`B@P#JA`PBuPL0CEv?0AfR9*2YGcbN;P8{_yKuQK&1`VW8BUa6hO34@jB1I +zfBL(VaxOg*?0O66n*Te|+N0{pZna=P)kLfXXjo0XD>dyzSE-!BNhTunhk|vC*YrjA +zsw|HrCRHGugI!F4yYqDy9KQc{hufA^J|350Yz!_}1Rdl`1t%mp@`$Wd@&i- +zPZhc%r~pf*Di<+}RHlhxqRefRaI%h~p0}s3Jr(zQUc6!Y*(h)$Q-to9<>O7Pt+XZ% +z+EG|b@ZH$KzeCoVi%)$e3S}Cw)5ejx>$EW5LeeK->wVbUb4@zOcZcCL$g6I;X}F$3 +z8Ja_m2G~i&wh>ODXlo%eu0CH{vDEy#XemSQ)6ZWlaz45mio~8|5n)4z6(m*H!9qMp +zCH0@Fr8UOBLc5KrOI120E4mZK8rF97lIBAX7Hs376V#&}4=ay8+5eieL+wp|WzxqU +ze3g|n<$9OBlcF()@L8)eHIYmZ&&g`mPnF>Vv$>1QnX3x+U4PdVlp`w=yZbyz+ +zgF|OH_rgLCzXM1X5Kl!CKTOFk?g +zRAI;CxDf_T)-44h3YL;z4TjVw!kn=m-NCQr{L} +z1Vc{Bv{9|-{dILYr(UDwjMwxpxTrIyWUqwZgjE|l;Lnr^(vGL^LYE13CSxmNF1VI} +zB8Yhmby%apPFt+7(a}e~;UnmwoDq7oUYO?~>0>hxfI8&XD*D_F>B>vq$FHCH?MIx} +zYRmlg2J1xNRrpzZ=swL;TD_LyNe`1Tzni6G8+~9dEzbs_{?5!Aix>U4Vpd`%@~(q@)K1RbY)?2@*9avdqj +zS3TR!EK`v`1++e>O&_3;Hsu+IoC0$Qh!_=6Wt%kDE`=`~I@W&YUq6Vg@tv*}KWccA +zO-?C0Cm@^)mRoU?wzb(ZsF(Pow2fX@zRa?PQ%tHG{dcLhvEwS6Ezl4K{ZTpXZ-Dl{ +zSSliH)$|vFI&|uKZL3N3VI0sn4_wlM%TY#apYXD!i={DGwb~vHV7A0nbREogF~J={ +zyd3 +z$+E`@XVlY#h4M)WWjhrQmwr}T$AH-ko3kMyTp~(ouhNvpg@xd!eTOB?5xpFJa{n^Q +z4SdA81kYn|5qWO2*<)~Hf(Vp1^lksC5QSEYxTDGEY|tE36H;&1a`YJ +zVH6SCQ&Iqin4YKUCT-kZ@@T?>hJ<+~J%DZc@wqT43p)FLSd$JKw9SEF4SM4 +zG_e*=f(>)Cy~{$42Ym{%Exy{^d=k_(-pV8*$h1~WqOEDmVKg1E&Ndv0TBl4z!fOn~ +zV<@}YM6icHwdqL_H7awqG!qj-@v}Azk8uxFxmhYvEcLvC2mDk35(mWQ!}6#{4%x$+ +zyMKJ1++pcXUtPh6#A7N#kUM0+VC=_-vwHI?0%BtQ+!+;JTTfvTTB%PKAE$36;{atZwLo-IzVK=MTo40~d%%>w^=?S6kL6e;0r +z*swKV$*QUg{MALbA&8?G*qUD0i?fIN*-6pI9`4({@(E5e4P+;Th594(sD@FHzO882 +z-J-2SZ>h1ywP*n5?t9kB)^Q5z()NI{BV%>+0hhF4rGrtB!)2>L#!BXR+eE9S7QL3G +zf06$B_Xu;cL-K=rVk-MK?cnw4b4w9a^e1=cgXeT2pB_#W3B3&Tg^CgL1QTRW`(GbP +zcF%k`1`PNnQL5~TNT>NZlN1wLsf<;_X*rb>L6PNZ=hZ5vZ#HUgQHdtDx0+e615z$| +z+a_WuzkxE09}of*fATipk&TD6!S}D@!z{D?0!)h2vbXCcA!hG$ts$=;US?<>y2$>| +zu)Rf?mc;8CkTK{&k& +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 +z;oSg1k*vum2Bp4q{RL7BXg|46T&{~~d(a;p +zM+18ys$wKBLh+WZvDK_{wgA-$<5hCBq~VUP;;vK}92;)?03_t<;f4Gf-d0Y%Zc@vZ +zN$@csVZLk${Kx6ea(2=cT;u%zXvhAkk9@l`;>2zVou;QFoL5H|6~DwOUAE2jmtcgK +z4gdfL|3RAYNvJ_=nM??8|Nf_h00f(j!MN$nVIIE#4$S{{=U9ubV97#}rx*~4PW5HS +zb%q0a{EqpRjxhlleR<3a-6vp1hZS5IgsTkyheS4utMs}4ck|M|NDJt1{@nKHss6HW +z?c>&Av7;ua8U7tw=Wi@$AGV` +zuc^cdM5`Y9XIS|zkEQ`zkN8)$Jw{0zCZ^td>Gb{IVnn-jV1`_1-OFR +zhSV&AK@pUW#+7Eny>@LaftsMp2<{0hNV +z?B!8bMt%l4T;VVWD-UBDG_S9SmA7z2S{P{6>ra)OjewXEQ)>=$=<%s79&#Fj#5}EJ +zywU*M+1@`|aG95#&Bt+Im!{FxrGvQk=K;@4VQo~u&e9!)5wGFBPW^Pu70zl~_T~FJ +zC-rUyJ;*-*=Oe0}|NH`4i5JRawI4p27bzifmjYnl=bYyxX4GWpsSaJBzV2CR!1)~6 +zH_bMPB!Tv&Ir_&N95T>Ce5}EyB#rDG7aLD&$l(7Zcopxz68xpy+t?d-A<6+h%@Gp(IkA8-c=R)d(^9(Z8eK}z4 +z4)(r~LEybCGwKk|?u3R{^Rn~nUC_&x%c7@E_nS}?H?2`(Hz*#C2}A)?(_1yCwo2*z +z=h_3BY5ru?_}`c~e96;7E2%^(8!!yr#W8Y8Fd;yyPlcXXYf{M9lF&H#T!vTj;JI9? +z8(7WaK2N&<5+pWn;;XcdXlgBZ-Lyp%UF2HRUY{=ad2o^hxlR}fL?d0Jw<~oM!h&3f +zhS%T2rtj0cW@rgI!M>;~Qi34EP9vdrLY&}iKfYP=;egI={l^vdb|Lb|VMF6964bX_ +zn#IUQV&zX&e`hZjQ%)G4H&C`N<4#KvX2Y(ewY*UwrA(*SA)!XGSyKm=k=iyl8zblI +z?z!MOYU$}vw8tV6FK+x2>s@|E{IwEVnc+t*nfGh~A20lNdlNST^!g?!qS?hH*LtuT +zHXhRgc;#SPP}?3Ks3ZlZX&&ojaGn0kKnsY%PlYwO_qQJ*S%s82hJ!=P +zkuuB3n_KWq1&zer?Kb +z?TLb7D(E&Jp`N#HZBv2~o{F2TmqH#*xw}kSb>)*E?mR_9JZL`+rJg}tj#SC&!NcgJ +zfeOK>TwN)H{T~M1&201gteu$SUZE}4iP=zg#%uo_fuNfpFx0lUBuHL>708CZ`Xh-a +zsIXyG*}zGb2SiE+648d#KCyq8kE1#4#6JGv{b%r8%PpOkV|6t8wa+TnxvQHbnvBhF +z%*PAp+RMPH1~+=d{7HGHVL4$lLEwzbugDs-bh)w&kE$Q{bDmb39yk^1&EX6brSRBw +z5ufYCFx&rnL!TUg><^OfYc(+GmjfmyZeYlq-~+Yxs8(pODrYb7?-*Wqjy(^nk6;o>RoP0YR-dF0Mt%|`qa?m#ar(*wIk16Wv +zfk|CYYg3;mQ|$x=gKS1bt5W!WJOJtmS1;a!ULE>j=vS=aJp*oRngtGT7%qe9q4EMi=04qRuTvKukLc>c>6OYqJdfoZb +za!8Vo9xxX^JT>A10ln_f3P=_$SZXh{XsIn9+PJ54zMFk}ifWajJu7wbuL>piaoj-4 +z7x7$${0+|QgINTVd+pvB=8{UdVE8E7q6D7WjR=YWYTf)L%R%)K1!~GjSmgR +z7dEs>i2I|55^P1UgzaOjRB%Vt^+?QpdDEYpfBAWnW^RDkWD7uD0eH!?ZdRC(Q$go+ +zt$S-TA`z$46v`vZAIl`_>cK}oPGMbn1LA$|E`>JS4a_C5NC4g`8gP|PDf-mET^P;d +zK~tdM8yExJI#emyeNgKT>iFIlh8*9e1u`f;#bLgtG6*V`rc+WRkF0>=K36D*$Y-TA+jGAP=3it$t2 +z(c{+KIoIO+n7`%}qin}AFB&9fkHF<)vrmSD2HLk6RXZ~j4NPWPJLd9doHtV`<) +z!JtU^d{lf@2i9%HtCW>WRTfU?%9t_m^wha1yUC_&(d3enA;ZTY!6Ovp3-^P!|F#h3 +zlv)}>&kVW7vQW2}dkyc)i$i5qBkGE%3tuu!3|6(s-l8#iNXr5Zp@HdDIy4 +zM>5}HUCEcUTP6Wk-q%6IdmBw=N%Q)d+-yK4ens2t?@_D)b2+~e_Jn5et+a>28|sh +z9-7cILwpiQ1Xn-q`1WYb2a@HE44c^Xz>z*jbIIaH|Dkn23V`gV&uOdTh1*OSWqEwEzh(KO&})6-`kS +zF>sjjFwvTgyG;Zv$yqYL_~rvA+Tb0AJJH%T({;}|s;}PD1cPZxWO}|%cDn*bhx14u +z49qxyM(7-T|Dz0Fd5ioWR74qqkDVl|?x`48t;ZN0WRN1al%YTrA&?y+!T{8HY5nlj +z?I>&Y<%gHbGuE@Ju4WBF^n>1jDq4W&P +z4zMHIiI5=~h?~eae)rug`I88@A@0rO>xSN^l&9iG=-VYGkqI(nV1JA{{BqK(IH1H&@0Pt!^_8wvt;t;fhD@81F-Q}(gH +zi?qfdv6m)!z{9Ki=I4mR7n8zLaTJxPO5J+?KHFESiyn*;MvLA)y~|jwFC+pOX~+HB +z&~_TgZl0NRqoyINasPzLxTFw~5{CHb95yB8BN-fb=CJ*79cE&Jy!T&VZ4t~ZjYvaM +zg48a~NpWkx#+=y{-*ll$#8|Yu#HW7fE7#c^ChW@ef~97})v%r>w!8n_eA3t00dbNp +z@N>6O5ehHkYsi_P$y&z1BuQo!!+xi7PC`X8D{sv0xWokFZzUTuiyEyzK8f>9h~}-{ +zR-kGMwk{L+UcXu_26s#kbdcS9fmdQz}80MV%>;z^wC-2qZ#%>7%g)pwu= +zoxNkbqQH*8iI1ftAJnSvQGVaZ!n`enz%`W^_Rcqe6-Uo6%z(UB+=O%FGw%iN?}Asd +zf!=b2zKY~dniN|(^l<-8gOiB1T-Oc&pmRi +zid)R9t>%^Cmjfx&` +zqaLu1si{S`ZVEayo(f(%aZRRF6h0s!39GM<1bIf~+m)Sx@jIHmXvVNrk@3(#M +z>@Nk&i@zanZ$W@Jzbo@j^J%Jeflj+n{qTsabg?CmdE(nz@tqX8000Mv0iP{&LVo}R +z$_y~Qz(=qK00@3`@GOsV51;%%Ml60Yo7i=Hq?JB*2YhwH9+8ky%LPC&PCl61b6VmY +zVf$VuNeZ04nQ +zs!z0u9C1_`Ty;T@bckOmM+%$(e1H8G;h^wIU&upHUK8FpZx``Z3*W~uDq^k*E7tOm5QM%gdLWild`9OhHd4U>h^lmJv~)NGD^dTZc=@ehx{8?o{Ax9=@m9^mVQvoo;m9&-AVFi76GbcgEx&#Qja +zQh9)0Y~;=Mt~Po^@X``WW@R7-u`s2EFmV5<8eri{s}p5lz6AiYVEIJ^y#KZvi?8$Y +z#*-x}nGj3h!~%ZiEc4ivDbVTh!)~BP_JAiU@q<5JWm;Gs1!mfzL9u@}-K0mTs}n-H +zqZLR#bTPECkP5`#zunAG=N`<4Pz2OiQZQ?jUe>{x@1x!^B-^mMNq5s&HMr5hZRJ(Z`Y52;K@U?&;q(AX$X4elZ3V?)>oh7iS#B{vr +zffZfDQPTI}eePINRSoRvi{+B(FiA)T+`ntltXRE)QHkjThGu;AYAHQ#$5lid_X{C< +z4>pg|L*^y<>-*9aIO(&6d7zt`j4Bzy(t{d5x5_EZ)&To^ff +z|H0ERe(CX7fPXnFS?#K_=DU33$U{1oSs$I$ZjutBpQdEmJ@fW?Z3%Zy$$gUS;5{Or +zO8Q6$BZq%hojUL;PEl5!`ICC&wYv;#_aCYWQ&?Mb+CMO&vWp{pPbB=snhO`!E}o^p +zo;IMM?_yeIfF(4CaY`MbX#qJUzXf{;?!*-$9jrOwuSB(Nyff#bPP-r0zDjcEUi9P( +zWD(SNl|v@>uP$cNmfMVL>u2m{2CNhXAb%Yo`gok%I@Sz5sV)Ca*Lp7-1PN81KQbNO +zcp!~A{aPd)pZ?9BeUP=klQ%;f6PE#gQ6A8pgv(aTc@-~E%|$yUZ6Y*RBR@7=Sk!F> +zNN{xL(zAN3x8Uc%Nkj6En7MJ>zL(3Y +ztY-#~#w=v1r1YS{T-~foE$<>k+vTYKvgm7)RlAUNPH9aZcHo`2WR28q1)Et?pH +z@-Nbf+wHI~ZbDk=fLa*~6J;H)f#QWPkX1;dUe0(lt6Ke1lOf|Jk4i|WH(wOD#ky9^ +zyYAf$A~Y4Xn?CwTR~Gc@Vby%>Wi77KzxOc)@p&1~Fi|!JmPT)#Xz@|#As&y9Y+tX% +zuuqkVBSY^P#~TopHeP0))xe#w6LZ_|V12vCT?dU&&FIh$OWTWQ{EM4MCH%;9VR2$s +zg3W`rDJU;qRgaIOmPK7v&pZuJeukCiVN}2)bbK3|uNgd+Mgmn>tQEB|u=*Lt8(d+s +z20RM93`_uA)jaMTqo-9AupX@c_`$@U_f|Kk6<9*c(6&kA7?$#}bf{z;QGz(m8kiBZ45{e#bNFeYF6ZG& +z*}+#_>2o5VI(l^HoB^n1ajf^H~}SsvYtWWca`6L`^jQM?(P +z4OuKHQFnipDyxTga2)fvVm|zP2?chO*^>X;h@_g`z0<`U5f*<5DtH)Ea1oSV5cuiI +zNO3l^B6rFGm?+kYr4N0}H#)BU(BYQR+33JEyvq*KZNJ482Bhq5(&PC}Bmow^vy({? +zGT!y+{>^b6c_8k_FYb{`B{@oM@ZHh*BHv+@w7p!NW0N3Idql^!ZQHgzJGO1xwr$%x +zwr$(Ct!z?n@*#iXcHKJX=|+!CI9GD>ylOEW6$H2|n%Or@R86+GW4J&1(}{gv9j7@n +zv6hh~Q0QQS>b_Y~x+bSMi+jcSbzliA%dMDZ^Jg`#1i0>B6bAz4(f{XE`0;>Z6 +zHt%4eKdXRO01msq~(dX_;KN$XVK2FII48j2X|d6I)io80&1pFZAB{iK@*NXoC0t^A)m +zw7Y~mLiiY+K9Akc-R~|-ypC&a!f(KKrT|QPPvU2;m_|Fzdf4)5&`wphW+%C69wxD6 +z5iZ0TPq$vogX@WTB&+}o6G$~` +z7Mw?|ZDc`t;YWT4LN?!$hLN#84OO{_^|n}xCLgOy_5MFy91mlmKtzGIUL9<{+p6i;+5 +ziMGW;^gE$e`QzhDHF7@rMa-8DW0q{(gS`DEA!DEflA{Qa#h<;;35MbT`L2_luO|~# +z-{=jBnjpu-n+y^3oyPAeOg=oI<#EkkCDPc4Z6>fOU3tX5P0`M1$tfJfw1{3`I8jH9 +z%dYQA8ox~#?!pVhckL;?)cs%c9vq$wENbm`er|gBDy``fxfcA~5-IUI(_Y2&l7K3! +zMJbnBiODWq9^rhH25$fm#i@xed4>1reXLnDAS +zs+g|)DmSb{^|80m_IlJUjX&pv{COVhMfn>Oz-krP>>pDhqH>Wh5B%Ct?N#*zQUQ#Z +zE>Dj5CJe>YwO#3PhGGmh=Bi5AvhMFuTbTd*SDA|nW`WG0F}(nmSPa|^PXEcHgDluH +z8Hdcx@DpciRo^1oqwG$4p)x1alUCV*7y%MnN|8?VO+vK5X$5@L4rLxk{Ky>^$H>l3 +zsb3VQ4pFg9wS^zn5((Vf!xq~IZrdmxRXh8+Q|qbh{95V_+eUaX(%=8I|G@mxF!=y+ +z8WY=|+c#kS(dm!9qz!rHwqV9O7~A`)W?qR#L8Q2$!O9{+iRPn_h{zIPPqc_*rY@Y% +z*3vEWVat>%c6~6gs21Jk+<2$sOJygZPeagIXw#V;UCrv#u3-LhxLJB5-kUSH=RqJr +z)^yqk;a<3HUmnF!cjS$!bK$u((1J>~Fi +z`{~LWn-%}5h*69;J?ifSiA4uAQP-&Xa>U&G;#!hzHP&U@AB;8)O{7~?uXeC}TjOR5iyvkFHhgKk_-E%Xe>yAr+*IF< +zT(?E*`AisYS91C29xO;L;KpHB+KvXT;;SFKs14u!tb+)j^Z;-n8k1{x4<N3<#rzMP}&+%g`Sv9iLohu6yNrw0o0DQ-1 +zc-_WA0c7%Obtxg@Vp}PMMUA|)&{8L+YOou;EwJ(JoreIq1?00;i7zQ9rkzBJ8#Q}M +zml+*S>bp4CwW|e1M}9Ie1^NJ+(q0#R@DXwyimqr9!g<!lj~Cq$0+1s3*1INt+ZO+pvW=h8H*`Z}ewm(2lMs_u>S7zBECr3Ze<`K? +zdNji^nhGeFmHOpEAp%iboX7a*C8bL{qNfrX8|E~G)9(CB;by@smjB1YV}W2#{<=)+ +z1JhR2x(>VEmG@$zF`2FydZ%P*bTHw_hB;Z0vRG9du4JbBfSLPB0 +z&kT>E0hdBvWR&-~=dXrT{uU>5%65Q!w7gL9%qQWC*rt(`vk*_bOTK3r?&l{VSyQFV +z%y)(g2m9`%b=2z8UjB5w>+d4NerM^Wg$5nEUgp{MnF|A&cf_u3tUBH)Y54m*2PD35 +zyIg?k$g(vs++B|0N(;W2z+`Q+Zx*jj#3RD%|E&b9oVaCoj%+#=-&{a41{2wb|KKT7 +zqnX(-R-|bP{`KSsO0VE72hi5DD+Nh1srlp;T{W>rO(qGl0rK@1D@T}WOuH_00OIhr +zk|p$J=|ODLp0*@s# +zgQ)h0=}9vkqD}B>WqKrMp+#*Rg?+2Oir(ReQ0jDFmeLe!)WVN2@ +zTF%3HwisVo=2-fl2P+r#-2$!*uyBm6@%2}@kDNjJF~OZLt+7;v8$_+nt+dQxDi7jT +z?(#0&UzruEk5CB0YuXkwHqe&}2iI{_HX&^8<4bLmG0Ew`*8A=C*wgB$8pygeHio$P +zY!#Z$SbG01IY(#k$o%t7gNpl2k8K^D7#fX-^jA7#`zSV?Sj;p`V(3S$i +zYF$tFc~G~9Wtm8mgZo6zt;Ujyg|}xjGH?<*3vM4JqTkp2wy`iuFFptANZVqvMsIq^ +zL)?MyWZbhX7hoy+io~7dBJ8T2H88P5`%kAP3s(35NXv(mbp^QUr`hpwl#cGnJfU=0 +z6&H?yj%0IfIuA711jXmfUhq7_#2%K#ToW_Pi* +znu+S!Wc9h$mtRcY@zX3k)#>tiUobBGNx_$vxDw{aTwIdCuLN*6to$$4ubL&)&-?B{t!-LIr=(DJ2N@0;LlV< +zoI%Szzu8PFRu#X;@jaS<#q$l+kj?JkyN31gw;&kUK;`8Jq*BMczyQKFi*GHn>fEA& +zenUgRFnjFXEH*9t;UQcvIt +zFi1)xigTTo!KX^p9WeaZ0@W-xjjvV=|4QyI66W?N8%Ia*9TiEWlKyE4yibYlY;;}* +z)(yg7!~Rfr6@cUn3g;h%;T_Rg=AC?HdnSyfU_IgMu(2YFbou7T+!?3bkn(Kv;A)vf%FQG^v4569FKH{++mo +z30iKxiF`Qp^H{FbH76eW>>qN*_aR`S0~a010#^X;ew!%a{gh1H2ahz$xy~o`@xfHo +zB@B{(*!13`HV&ZD>~7Fm)MDSRh`A4N^w7q9NU;Tp?EC71*>whGe03_t2$tblzyRH1 +z4w)0f3dFa?27R4X4Qz1VbH~hydeIO5jeSJ`qorr3p!Dbv*3=M0m+lP&B3Y$pU?G3A +zk#U0X+)}=1HyQ8bsLxMvk&i8|Ncca;2O~gt)?>h5jRn+z&)Hnhosn>YBPseXyUlTZ +zea@B6eOq~F+}n~ZEXJkav`9U82lP|{{;X>80yce{XJ^4rFR~+XkDgv;6!`pwA<(GaNHlMQ)Y?HS~w8W8@iMFwsCg +z*aBiJcv?C^Sz)cTx`eg@=TJWLmtvx6av7F(?6tMRjbbED=*G-sod{#lE8(}VeSaz6 +zi!V7?;CVNr?gdg}hnvxc8)j<;W%~D`{Ht2Q6wFinUy7~%f)PLo=-UUvr!ju@4c+WE +z^!`-K5QC-NTKOiC;FbJx?7CXSjsqg4`O!1eMHGYYBwTDpq1 +zYEy5uH8Rr|M@v@pjmd2f!C%6ITxSsRcUW1Hj@p@=OZSHwNRo!wR9F@6@8AvjEX_rNyPG!%j57baB +zNo{}ArmWh%3}#|WTdVy@bESIwL9|g261L3Dl!DqZTUNlT1CMD0jx6qy!L4~u9@wYu +zGsKRHmt9t)?Ut(rC*N0nJF|qh$ps?;PXCd1_6DI5QMdFyKEP|Ax@d9n=@cTrOkH>z +z-K_`PA{giE!&P}}@JkV(p$GMGFhZdf9%+i7XpAAJd7)U)%AmB!>=k|`L$ZTIu%tjH +zH4z+smcR~2#|%C#HsN=>G`z+<3XLZqnozG25#IuzeH8Z6Yec7Rg+$I_j_RJ|J(8bn +z=CFJv8FQSd0=QCCD@zjvS%@43rkrPIS-Gx_A>9gy<|D52?`w6?CIr=CtV>BYRd~2S&7uwobF=sY)$* +z%wYU`p}15{C^|&3_f}5-!OB96JPszJCp0PiXK6N=bEDlMS*#jO^G2&^8dCUK)g2Uj +z!xumERlqE@L0rOy3bVZ8tZindMSi#U+~F*SOcTg)D0D!wrIY|>LA1yrH5X-{debC^ +zA^XM6{vIQvgZkZXx0-FGk7fy85CL#OTY}8X?iBKn2AI(HTpmq>LyfmfyRQqKh|zLb +z9T4O1+kJ@_2F=7*IbhM=l6glR{;IY^gKb$^ZTa+k3-tE*+q+=~Uo^Zspau3)94))Z +z<;a46M3Al5NAD8j(OR$0XdQL?7bJ=H9up=4$1}1>IohIBhZ43ilu&#YVuwN98N_LV +z+6s`bQ(P;jPsohqs~p2|gJp!>0U_N;MDQG@0Pl<)@=-rUWV6|V_89lpqqj7DE9EUy +z04&C4ia4JuM-BzBC0+p9)VKLn#3VayR#Nzb#8p28ZV5r29MWiem(hjVgsuL-I%g1# +zGmkK4shS{v)wm^WgxO#*WaTuy#oj3rJpVZ=AFcf{L^HLvjH@6uW5J{LOixbLV7;AYaGSdhOh%g;E +zQ_8=h{KmaXWBcp}ntQGf`)=|=4S@QKH2f1HbpQ)aop?Cr3t$2GM`}+tO|ODy@|H*; +z?P{L`P>Ex*s@VLHN;R$<_ho=n*Vg-<&c6F9%uC0qBQm!8ZmL6ygkB{{pjGGPBz2); +z3Fc?zqsv5-6%eZckO+Qn+@#uR +z6zbl+8Y7Vb+};o}_0BTPL1)?cQ|an3GgPAWJt3QbV3tGG#IVCPM<=Ig@4f(5biE)y +zD|(1m;BxWQ6#9`r_%8vc&(8r8SJQU>J#*0NxEa`2@d$V6&;*YMzB{xos&2o!9-rv} +zulTxm^RlisTW5|~yRiNs^jub%C4C{l7-I!`ZVhR@B^mo-d}bklp+Z{fS=?arZ8*b6sxonQ^2ppRjvbNpB$#&Trrz%cKWAq+~3(<_;ixi93trBiVu|sWh +zdY)v~A4)E@iowjmaU^E*nS$2apvgow41j%U{P@ +z1S34OHanig_zg46ib1MrcVxd%C!DB;Bpy!%F#Q?>wmZ?4vT|*)0CSvtvK}bIm~%j2 +zjxfd+Ml?Qz#C12t_)<`(VVDb}HinoZXq~qj&~m{WV!o_9&hx!h +z*0@~7*%KrWPCGODex_OEEqq<4oVpf1ywIgLg0E^m5T1|Lfk6ET;o$NLaJd{c8H?N6 +zwM%y+uk^bcTQfX>WZi`;yOEH4E)(>f*yEXas8fa(ak;t-m_}V0r`P+{E&jq}o70p_ +zI3PD@t7CTS3XBa1o`rUV`~QCR`G9#2|H0hW?p8#}=KlXM_k{|nT~r>Mym(-WT@%$K +zA>O$5+@pIog2*-drDzc+*qMx)%I}6IYzUJ0?A9E0lQHQdG~({{7HnSTnUM8+JVSco +zb2c?#NB21t+4hXC;kv3@Elo{JJBL!}4lW6;|3BO^$O7K@%&mpTw;cccQPo%+!Q1{V +z$A3~9fVI+!;id=CeL~s^Yglhd3?t|@EGO_#h($tUVALWu@s1OS+2UWdxl+C19xq9Y +z77hB;2JCKKQ%)~F+m=BMAhV0ffu22sGQHFz;NfYv>Ds=MCozv^0(z!j|4+gEPIWY% +z1c%)Qg<{$xgWR*P*`W{oF@ynjfkv+Hdu?9?U{2s-x(^JyOK0VjfCi=m{N|8Bux&GC +z)fkFc5qi!w@Nods8Eh4B@vgw7K@`=&PUe%cMp`g55~jX`F|Arfv-J@qoECqJHo +z9(q_YK}g|kyJy!36k1O_Ay=+M1hzvAd=+++sX;)nI0~}Upl`Xi?LfI+a}4i2Cb)nE +z!(QfhFuKRXT~~WJq<=gW>3jjY6yk5>2$Us2qi#S_f2p(IPg6CL|1@-93zZ; +zz{+Tlcs>-!=;M}nwR8epwG{_31^oaMtKk$14ir}LE%ic>OplO6~UTjh{cQz5Xp@>;u`E4J<}+2iekrA0iYawM2kWwEI?fu +zaw?g%Rs|9FhM(pfCe#lxqx^NM+1ED#q$;Hn%Dq>nX-75FhC_w>M%|bk=U0RGB{s59 +z9LcE^d0i6oJx$qLy0C!LET5HaoB(OGbubohkO_V=U?3i?A+CRcu!}p=ldp$81IA`1f2jTk +z_Nd4TPzw-%tSvcb>T%>3wax(C9z5Lyk|ri3JM)VO8=SpX^h +zcD!VYF^_7#EY$@;&fink4}-V!&#BZL)k4PKI3za3e$+E*soB#H9Es^|=8c%IDqv}> +zN-hlg(ZP#XRJ2Y!HQMDR2MD|jDL7LZx@8IpOAHoYN-DCK_+!d+gSl;8hL;JDd_tfU +zvcAMtWE#}wtyOsno^X@dl>I0>rLYG3Q0~J{aX^YBc^o;P=3nTYs~iI +z1=q}a7gm)OV;BbMasRo^)lM_Hu()Hbhl%FsdzTbE#!Osb~Blzx2orXjdJ?oYNeP#fA+dcL>D%XQP-hKX(GS1-!*y +zU$q(ZRVm;vL0_#xrFV^DT=OvlpXnei3M9{jQGY2mlKYU?yp?{~&{qjzk9G$!eMP8+ +z*X#21_{Mj)d;McvP;pw-tp7rSBZqp!Dpt- +z#(01;`A@A6X$G>^YlX;>pJ=hI$&tR5{MCZsqF7tD$83)10I8!L3eI$I+x)#|viWVt +zpfi1(o0PCu)tgr02TA`ml!d^PG1k&5BFDjIBwLqp3f1#K$Zx*FT8gg~lf5PaWr6Og +zr_MJ>^JiRW+XNAtN=H#0eLqE}r)zt?+Zs&`RiucRa5TLO1m_9&T0{_n-U2lB53Z#8 +zc6tChbeBbF5R&sT)^iFDk^3ZMTkty?BY46Kf#z?7V338aTmAdy2h&BoNmlTRqS{9H +z4SN$t*ucv3kb123BD4&JRJ2|&>&u*3ijF7O?E4YdR!8qglPgyJ!gW4TB_Y-X+l(iP +zpNcm7H<4f?8n#Ddy*-N)_T7MPko9UUhar0iOr-%C#Q!Oxk1B>vCIXwgBvmh{&(dEC +zBo1pY+=Y>_5Ge)JhXxRQ&WBz!tuAG>F&^#bVr(i%8$d4su1!M<9=cvj`?Ngi#b2W& +zL&k}-HbIt-Hd)K%4bH4oF({`Owj7vq;~UAYJYY?{hfzUTcNL<(IEEQD@4qk6ya4l@ +z{)c~$NM*ljzn5=hQ}%)Iy74ZwyZ~WKz%`a@q5YUi&wMP7EcgJk=pf!#4q4U1lHSdS +zGXgR}Y(3&D#|`<^`$@TK6&gE9_2H%0K22V2SUkq}1EHlU$Y%!A$hnPC2A9dJDfA3f +z_dioWx5TTP +zj_;rql%n7iqgj1x)$JW+<#D;5h*SbTykXeM +zCB}O#`Qs>Zstx`Or8(i;X6ue%w2g!8Y67)?AA~GLjOJ|w5qdqC;o;(`MU+dfH`KO_ +z>3H}grqD%-jZV6JbYPDxpW;=7-^ei!#|4j;UJhYXKk4a&O1Eq$K+*CkKaUz~^)WvX +z(JZ9g0kT0ry^76CB8<(^$27lNF$~Nh#X|U-PnU}*$r>^A0xX9CCu}9V!(PRs0zVYo +zsP~+rm-l`2jqS==(B?OakHKHtI!59_7C>x88dk}`q;Hz|0hR2u0W-D+1@u$D!HM4S +zft(5{K!b!qfUs!vD)nH0D2{!f#X}28I9nTi2?V==2Wc_}VtU^ge#-z9V3nK}(Tk5> +zrHFngNYh6Ofz<(ZW`m_vPr&TtpdUbh83VHoEWpq^2c|vnv4ZD;ys?Cna>X(K +zGx(-&$qE|H2zdt;K79mEi`d8)+T9loJ(fdL_zp$qecPf%NLlxLVci-lkUG-{$jH!G~)x00JHJ_x=H11Dt9=0)&NXzd;haQVMs!=v2B~`@(N+t +zR5x~tPzOIFsL4_&+A2hG>F-w3F9C$uNC3NqnVG;R1(qJfgnBuqav3 +zh`6STbD1dJhu*KISoJa%#*cfHaUyHsVPL+P@nG>@;wVO24KGm*s6UdS{weC?^rO|I&oZ!8U~%9B(lwwR%_ZD^cS+<2%w>Fw{>O)@T97r +zE#f2g=dGuJel3kd)>1mHiW9>PwL8AJ;29EsF6LkuGcc~KZxHt1a@YkU@!C{+ +z41gBCa^coNN0y0Fr6g-`3+356%p}3+@|1pn$W0zK6hYbJ=CS*CR6=#NH6U>~n{AB{ +z9oAi#l_!MZI?!VYwRITs|;s!ZCw{_n1Jm9T~5q?NY9Dr(fD +zs{pK3Fq4DLQl+`LiQ0D#{>UWDMTL`}Wk?2Myx*am#A_U%8_#oL@-T?CdMlw!J#4rj +zD}YaMGm&Z5)PHz1fW!hhayrV6w8-# +zpL_z`5zK$vdna#Ee)s&vWpp3*$4<6#h)qL=j5a~72t~9ogXZ#-_5F^}u-_4)2uro( +zUVcgRL#O$zlD1xwJ@rXEgPC#MPYAFPhJC^4{L=H+aU!tf`om{A7*gX;0%(LEV<=TRcz#tB+IX~0w$lrU6Z*k{}%Trbv +zc0iq~%B;HR-DN2{vUJ|MhTm{k(Q6xQEni3 +z_SU!I0=Iq?L(i2j!-Nr{u6`YoVjgSP2yUFuB~=ng(aJ&p!O21}6QOw=Cq2y9wuXf- +z2Rmxx^^8M%V%I`FRCZIRo9P>_b{#{3k!k~gSCQ2e8<#2 +z_6m9;JpjO>gFc^EE=J9R$>(gr5U>$d50n3n!ZuJ5(aCb0%* +z#-aClYUSK?*vrdb;m96&|I>Pvk%wMz0~LYUIBOS7oZ~hc0NwSv%q!jyAOvWFU|PmW +z6KdjA9P;=H!*voc=P#LLtL>bn=AqrRQ@G=n5;D>Q`t>C^-M$ofv>vwhRw1Ku7uw@} +z^yI6N9?$KEU!?Gb2Fou>{-#y-LTX6vu_ir2;R94m*Ph;*BGdYZC`NTaY4HPs-oyp8 +z1{UB8bMsfzl#>R~!=zxNT}2764#O^XirqKoFm)W}YLlN?-w)Qbi?>a*N!P4f;_G%H +z3kz&d&cz4|w0DAZYO`Ktpn*0PclBqwHA +z$R89sk<&ygSyu@6N5n6*&}nAa?I_?Fr%uyb8K!?VY*=@=kn4HT0996nLt!amwMqXJ +zR^jj3B<(=MWx18CI!gfchc}q8#d?{nVWk|dXKnRD)vt76Mv*7DGI-1)w9!>#4?5t-8RVmyQWE;k9OFM!b5~%fnTYdm)S^5xOhXdk@do$6j_q>Gu%n&1_ +zvS^^Lxx`%{pnDS-ySL1l+u}jUwX$Zny)Do7QrZIN!N8YnRWat|NALUl64IX2MRNLz +zS}0X}nBE3KW=LaSS^${q1J03iN#swgqFt)&*<*QdgPG}nD%1C+lP&#QkhdngavLbM +zuAARR!C)Wzy#|rMbustoLfNzy`5-0P=qKtZ-nSgxqAz0~G=q|@SZNk-z= +zn&U#cN!{*&h8Kyp&i!3nh*f!s^GJd)h+w7=Cz>d`7dNwN&cP#{$kp-CGQFbfbNEnZ +z821wv5@h*IvL9#rjwy(hx052XJUn|;jS`h{%hXJ=#O$gr;AXkVu=#O?%7!mHuwJzw +zNE?2U9b=e`2s%MrS^KaRGWwii}Oy +zr-@S$v|Ba*$}Gwbs^O+^TMZURQ04Wkl8M&`9$#f#xP*3IvmkibeL~G61ZswF%u=U=q7-SYdA3IIw+@7 +z61?Krz@STHoL7O89@PD*Av|8_uM91tK0NV-^mw>;J%A_jUB5a&MX){A++ftdDfq_r +z&~u7w9KY&3o0ka|^%|JuL#9S+LVz~PFD7;zXfu;qBb*p$zsy;z8D5OIODaUWrtie! +zS>UUWmy?6+CIH2$);-uARnBL{q1{JwLg!|7x* +ztiAdo^NmRaM}z?QFf1hH&E|r+?H!5FYNY0#isc;IFg9&?cwO+xAPp}@xI?A7No!|v +z5vZYzR`I3LSm9tRNqHNZQN+=T>twmaFIjb_1Jc#12ye`gdaC*BXV9_a^iMb6Grhl4 +z+n*IBacu0Z3=zFt{7n!LNHE;j4g}IihOrGGfu~{aWh<#KrxCx-HkURwy8o^>XygAx +zHK1kCZ6)1xuf{OD->_~cU{|lwVdt1R+wQEp7BnQrYu0w>l=>Vr7d +zBp);{TQz5;U*o)^4in@q+MU~GvSd88%zb1y5>SFXma?ZeAVYnfdBQmIu&sMic-v<6 +zY0!J2%G99-p5_R%XoPuk4TPw(4Faf}c-IY-ZJCzR)uRmLH;Ea&kH{Eg^&z1>^D=Kg +z$y;E^!V7F|CJ5WIs?&PT74jCQM!u2pi}6(epVGVosv@2O%wqT7oXd@OP~&1`0mya+ +z_yI&VTUbjp7gHC|vZgjIetzsaQGk#XY`Q8jNp$YVbqr_c2dXq5S=YWJKTu{@_)AWlN?-YZ^@^LoQlCcfMz>rW5Qu?E=a546a9a$q*qqq(Sa4;zaE% +z5Wu+x6v?j3J}E_f9E;&kmU7*4+7s`lxwfb=aIz$>PFwa?bj0^3eYWOmohqMrPfa?L +zH4fG@;Sa(h7Fi$-?ZlKTYtsuEg;Jl}Odi58g-Jo4mHJC8E>xUD25Gtc_{lTjiiF#bY`~xcO*5ywx +z%HWOj1f$AS(|&GF5CIk+G{T7}#PW9pSDLbqqWSqjA0zkf!a#^FoaJ3Uaxqu(mxIWw +ztf*RH2X|e22Z>v+K+%s<7s6mc5^3cp*o89*2uS1D&!*U7>(=UJxc<(ma7JE+N&ihI +zV@u`@x9~0QR~VF>Ir=I$pX#4G4D-v_4y?D1-aYR-P31%%f}|=sBoSNZQ)hk!=aYWTKMBh_~m2 +z+g@Nu-2_0{a$vFnuJ&x6Nruksc~K?kmf_KMn8kAMABcp7bNIwfCXQ;bU60?IHayzh +z0!R1Uw1ez1sT06XUnu~_+U~;e-U2)vVD}GQHk(rT{u~(Xng&l*zB$2-8L<_j9)NPD26fV25v;ocKxtn+<4tmf)%8_ +zHxOfonKIdeKH4a{G-%B_x6Y*NR47J9*@*9Z#W2XDCvr3bdA=Zvi*)&~dB7wKluhP6 +z<5G>E;BoTmq=)3d`80?$>*U3TMHO9S#_-XoC@!MR8CnL4sJLqw9Q+l2^EQ^j|8B0C +zqACVQ(`KPG2WtV;;Im?1(SQM~H6ZOtgaQ4^QYpxW@--Ok4$M1gXAM3ZEic^H%5fNS24C<0?$Z~h>( +zHw6wbe{ouSuE+bbNXo$0fetGlKlLL>rmgXKZ4PnIk?j@Jzx35KVQICeY`I$ak039DbWeu0Gh6z)=g_}hyD?ZOiSfJj +z*7Li<{?kBks{o#_h!kM`h}hp)X#lZ1GRL5LPQ*fZ0DRd$XA}&M`wylZz1ta@`A920 +zJsIFv@OjXjTJN8L9n|4G)ca`kQB5?Wu6EmTWlC3kKKBlOpScq)9oy11=AkC8gx(}e?p8u9ke@{Z~|#-V}-P^!j3_G;eg@7 +z-!72x;l +zMOANe!yrAoaGZeo^g@3(eT&v7zw@ILg8$QQ%WCN>+%tj~;EeZ_Eo|fMA^BB4K7@Fu +zWsT$sRT7N_Pud+j`dXHMF39tZ{9wXzEIbo6#b`BPH+VgTe2{*7>OMyt1~!G~GCy2B +zWRSA$_jqp7!$8!7?F6J>8m_z|Mldji3c{o=AXp +zqW6%#RrmlF=na>k%xB_=P__-f{Ix4nmJ?E8*R#M%h8IrCS +zRinpm!Qu@zsAWSRoC9TnsvY2dB3F8X5AQ8Tl^9qtk-8GLhtFscjVCaTc+Z5deRAsR +zPy_}r&Zh#J)9)!L4o3M;ey)5>){R4n*uf7hiUrj=weKqEs#0bV7y+D%w~~QM1X0O)5EAL@MwUh7N>yUhmrk{3+`)uY@Z2Um)(%bzaY`xu +zBZC^e7JK}h+PSj=Z_BI6gy|vupRj}52U6zo-F_4mND#HBp~1N`N9Q&~s{fPkR)D(6 +z*HKIrRo&UJ?l7sJ7$7$0PJUp{Ec +zrK+t8Ywlm-M*!wE|A$#WHNI(URRaW%y9jxof0tLQN7Deqm@F4UdH`#xae^%7Xei9c +zO9tMzI%aKYPwn57DhBkQtV+>~|D>a*5{)d!@7LmgrA>U{=`ll@sAm82#tZ5vE)Vm~ +zlS7cLqn@l^`EO&_8xT>G*KcNZ<@u;Ym54rHK9iiwO;~^yGww&rMF~Qb|(IVB9F%~(32|BwOpf?jnnNTVq32TuzK +z(oxo3%a;2reEqQei;~oF2$#|Z4TNwH0>6ld +z(NYyhkbN82Gm4b}6^s>Ol2iN(2uagNQ5|)t4{Wm|QBHw76&XtaKy4E=TL?Q!i=FJ1 +zku`+=t?kJOFOI!~M0|hEcmOUXX5J_@S2QnqCm1~eugRNLPoW6NntbX_l4UF21k?`7 +zUhDJm)BF<%t8%MWF0wtjc-|@(n@l70dzUb{o_qnu4M8tJlC)g6xRVev`Zp5>_i<9} +zD*JbB$;cTl%po_7SNz$>I>?&5^J8`Z^uyYgT(L!71C4^I9}VjTSKpbDY3&+d1M^75 +zByWRpxbd#kY1F{V`3Pkh{Z;?395#3h0>;>pUHa85a_;>TwYhsY(hD{zU3t+8kC3vB +zN*iCXX71lZx@}MI^i3@0guj +z`^4_JV-@s^#7}7Wgq-J|fZUJA;5Bp1K%{Tj?uLypRwL!>^dc`W@j0j^Tx)>~#XK^H +z2svcr^y!^P-wCBTK-M$u){O}nO}!q(Mf(LSpZNjmsgiEQ2cxz)=n(Q#Y@iVt20hYk +z6T(Miw;Ir9#XwO=ieZ}&OoecPhO&j{QH0AFTQpwIn{!5BEX>x{}z&lKceOhIs1 +zecEEcN`VX)5Z7R$$vNo>V$)0Nt#T7wFs82K;KMsMLCkxHZBpM4lEFOhVfY?-%n)0} +zYM4(*Ip6fDcQM^1%Kl6}?jwf2=Rf7EqNephl@9c@I)w+va9S7VM#Tk{GXJ*FRDMVr +z@Ngql&~xtHrhHJx0YX3|&S=FBpMMuE48?!D_og{%fBtybG= +zy1B% +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 +z97}r67cz!Z)hS#_`Hc|KMPK6_?(| +zMf#E3G#SSbo?>kXoU3jL21Rhw2zvB?nTbO)${U?gtW&q&G;FT9K@(vb?06kag_&=l +z;yk!h4*&HW{Dj>pG7T}(+>5q!K~bHvL*NcH^F1zTVi8;Q8S4ua?ZsxpOD5?Waa1$w +z%;1DGj9R$?-=Mb;z7BEYNco#J5J{u1uP9w@#}si~Jraro%*tSiN^5eb8{$ZxOR?Bm;9Y +zC?*14+8+D`SrgXE4S*D(OC2WbgnyZ~Ir2~$$f^>#@Ol>AS#(z8umAuD`9YuBMHMV7 +z{{RE6Szqv=$7D#>077##{k|-@cC70bFKkNU&}ZQhf`qJI&KKST7t0THgh=&Rn|{ +zeptAR{6A+kx}H8=@~SXRpff8wbsE#`F&sGp0?^En`;*feL#|v(zhAdR={J+tRSoac +zYGPh>;c%=W*52ZbH`XGBGxR|Q=TH;lBE(;RD>{ZNjV#0!XQvg9``K3fI(`Oqk{IHo +z-lMO=zzwWp`ptXPF&eN#~})fqrm&<3g*Y@n&b +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 +zKt7!>lZ=2wx?P}J+LParE2_vu +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 +zs^*!SfgxNh8PD8Es+4~i!@MR +zeTo328jvWfUN@1N3R`c4I=iy59^f>QvM5l&!zKxrx=uXHj_#~I#t<~Eww!62aL6C0 +z(huAsRSDs&hsavwAw^m_d-qN>!Jh17R2n>>db6K0;EI`0+8YKYeM=y~=xfqZOT=Suxe(l_GXZrRH8UG#8T;I2tm_x!dO`n`6%|4Qqb452%P})^F>bm(0GZncR +zZnon!f-&wy?4IZ$^g_WdW{omz$Kv?!&?$rkM6hV=segz(eZ@#a4?D>S&Rwc!?aU`i +zEHtYn#xiZpCbt>~qMmfRmbKBVwjO}BkZA}37)WN_@&tjlW_;FZmrudH|U5`EfdG_RxSRs1^sMKH2 +zV>!R`B?-(8M*MQ@wF(6%$*$#9z}V*)@S29n7p(y&0eTMfHE&=bOE3tmHS~_}Z}0sz +zeD$S^VGJ%uK@e8=nZsPrw27=5U_$ENFDjMFlBzX}L!H|8ZY<0`nR5#iS+x47%plI$ +zPiVo>_dQSH)@O4dC)S~)jN)+K;FEU^UEMgY7QWUdSlwL_&F4;cR>9~E+>;~b)blZ4 +z2?nMz`!ZS50*$G5X|-ku(brl`4bR==9F@7&z41e5q`W3o$L5n +z1>q0y+Yevc=z%FJmC(D(*J!Jttk4Gq&{u0vab0j>h%~{>>u@|yq$|3ZeUqOSAK0#4 +zS}#jUSa*eOcjvCm1!bT=T#b<5vGi?(lvU&@!Zv_tgMWTA2$u?sZiIhVuQn!ngbBDN +z>4!iIR`X3H6HbH>0U{Pqrw)6)1T@2)Rq={aqBXY|$f@P!El@YIwGusnW-rDPZ=M`% +zQ|8C4A0xW_zTf*1P%`$JwzIt|6!No1gmUy79z+hD4E(G?%hAa&k8J?(4Sn67fq|u{ +z1gMaQ)T~5J&M8>z9hleIk2XHlz;oqrqxJs-Fzy&6l1LSKp4D#8EiUK`8r;5N)<2x4=$i9 +zfd%_K!ZQk4wUAt^CdOFYK{dJnLkH{v#=Rb7G|0d5TOMSUC+k^aDQ)r1h_O9%eWb;x +zTSg?OpuwQh!hIj4zp@Bd*5OH0T{3p-vQJ+|IS%De-)RI5Hk{Coy +z>w3qk7o|ki_&UGmkOOki8w8@hI`Mf +zw{_h&;ur*KV +z+J$JvOAo{l4)(cW@;#`0iox-VdV;ntshv>*0Z~sBnrs#o6po0?BE|~faHrjBmZyh3 +z%e8$3q?XENaWP*&T@|Fm=pRrQEdU?Ibn^KlL~hTVE#xtE4nmjhTYNOXx!+w+r2|j; +z&1E1xwJ7vQIbC`|?%WCNH2sZhnjch=RMr1JZeLrx7(L-hgU6-`Mt86JU43>+sCLuaPE1TenF^-LFXAI|; +zZc-XNtn=~IB;ZFq9oC3ve)8g-AvVB)&s-jE*R|Sr&i5Sr*J+)Wb~y9(s>y`F226S07n8s^5>z4>K7R1XR8jE`iL5U`fwtI$7Lfk +zmlNa98jZDaTN2Ya7_U_Y2*S=`)8=cnSOe=Aii_!eGK~B>D +zJ-n1!UGeLl7vAPatRNp1+&a!{n|fO`|EGB;lT3T^;*7>N4|<+?;5;FsG#qgbRc#tN +ztq-;q*m)c=3V{Fs2lzpr9z_)_EB^okty${a5gR8PSOE#ok=+IV`*s3YJv#5MQ28jP +zdaTNPCWKcfp>R8c6|pqtvHfSslJ4NQ4{60i13Q{bx9=_y71+vL*t&rE>E5a8cfYvx +z7ixhW!N~uDU#CB!oG8%I)ZYEi%{}El9G_1V7Fo;&>CKzGk+7p$l=@F@@j{MC;X#( +z*!i)Z93V31lGg;zp}k=03{j}@zRq1AkV}htsCE}V4=#Zhc+;8_vcc29k~sSzoUZFW +zPS(Fw*WfrMvZITX(sUFyL`1pnE&0ryunmq9e^Q32kRNbN28q +z8of7)7pnR3cPfyZ>gWV*cb|$teOv6f1VD9JDiV3omA_4gnhRJB7-^^(8D{M<6( +zHNV8_mGgCLdk47L@#;6vHrTjY-9w%`eRYSvEFYeusA`Z0h08wu5X(tRkBCg{vhnv@ +zOAB?pD;AOoqUB95n<#gWGIE%SAOGmFX%G1Bhwla1js;qznPPKtl-a4Ur1Sqm?l{%S +zG_30NCyw5bB2qlcJcS${K6c!Y3F#XOuT)2RL?*&} +zs>&;TFElDu3UIDg)ZUdpcBsVV2*oJD1XB5^%p!G8zsuZJ)-f*2UU2dmljr{nShnfN +zp_g27bJTP*K(aNs5;98+=jWe7J0^m$iPRDOO+LG2#hlPExz&eu=%-jtBu37T8$SFEM`1m@ +zHW~#FdcHD0MALV)vj`(-I0=ZM2=cvP_e>_SyJ#a=eY{v0?_EIaVTB|kTZ +z8@n=}3|bJTFEud0AAGz)LUf9U78(@mJ(C@DhQg8f9=SvJ3v`I+A}TaBB*`N}0%fmm +z1vRfkeX*e8<`+x+P|+DqwJAj|l}dVhHo_VjI^vJ#5&#*Pdf~zD<0iGm)3FODAm2UU +z_X?*vlQRl3qbaTOokr?ks>^_dGqYjv5j4=u9FmMt6>h!5+ihuWixcS@O2c2~SDlN# +z^0w;Q8|GIU7nL->C<8qZk}ma~R>IiXBFrR=rQ8J$qU8jqw|^o*(}BS$lCNocg$UK~ +z9cNm|v$q+vq5=qGi<)n6&OPrmGHTJ*-5PEgI@hJFiy3W9oV0R^;W1BS#K6rr%W!@= +zCwI*bU%NG0fwEC?{p{&zp&NM-E8i~}(SAUxB}!X1Y!UK^@IH#vI97FKsfBas_B8dL +zcPW0!UUGnbiadGmMl2KcfVGE0F;V=;vUf5Gj@tLxC1S>o{T9QWm%^;?${-1JPC|WA +zXpE)ZmTWrL4%LIYu)-t8zHqsUK+5c-6k77~FjU +z-9OHh`@U?ZI$k!4S9(4q*;)hk17bh^Aqp{^L+GuC06>Yk^QFX+b_w21q8{)^tr)C6 +zd@S?Q@yz>tcg_#HS$t5b_m3eIFocK0#`jsKA+`hL5!?BdHY*neNOlg?j2WzeR<01d +z`(wTWf;qSV!`_9Cwr65P37FQfxMVg+ +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 +zFj~-E$F^a~0KLct>?{C=qVA5}k&8p0q* +z!_yR8wb~mz-cSp&>#u+ZxLM?UlTkJBCUy8!$wb?g?&th-C?Rg>R)+({aF~vuJeM(B +zpDrx)qpJ|WK^=C%W!9e&LmNQ6rzPcB`-|~gyfi$Wa@-aP`Ma)wj&enOK$^)00sTi) +zXTs&wZ}2kOH1loqQ-|4sctXa26M_7()D-6r^w6P3C=vna+jS +zVzFD#VzQ3&HMCmeCSTwm&jlX#Z`?@k1DwzQW$$Aq-Kg?W*Y$U{t +zxYj4ydSEMD&KaD2)fu|D)J(|{5-9;+^r*CE2YC`E6|j-6sQy!4aCjo3qJzh?cb&>P +zo+F*0jj#7x7J{XrOLy?nbZYK;r?ep@h4?Bz2otn?@d&|zn<3kBZoS95t|wpJe^)(Q +z)t1<C!CKa +zGkOL+%pch#d*5OBYe-dUYvYxxs#+G)l?c00Xx2Xu3rTknPBuk2DNR|Phb{1y!Zft!1`msK8%8K&2$kj{M{P0O0h2_jmF(}Q!U +z)z4ubjxJfU6`c*7hRZWU=T%v@{xKt?$~4UJ-*b8x#r|54^9#a_e8>rDf}p^11$7EJ +zIJ8-Q75U}lWS&}L(glHcc+-Rbpv7plmUDg4J^56}Ks-vl3S`66tt{pUse;`Fq56P_ +z=1Uh$krzYAK;?0aG5!bSVZlt2|Hp{O48+Is7wZZDy2AOflW+mo2kpT{<1rQUv2QeV +z{#<@CR5=>33`$hhtSFmLNoQlzl+L+7S}rO>Q#E1X()blp8Y@Ij(acVMZGIScQ>Z(L +z_2ezqP+G7!fCxHRI#Cl5+uTo0V6~Cwvb9(1SviX%?VBTKo3auAFpV?S`h>m@8;dZ{ +z!K~b~_4R8i#1&kVL~os4PiIFXKNEf8-6Xm*lmF8}GIXUs=sEt*(ksNpRu*@->j0I) +zM?GIR?u-98A~WO&4w +zEh1e%lX>fM-y0@n=|-$)Cfm_&dzh6UQ&w3<@khM+6k3_k(|Q8z)Y*T04pLn~1MlyW +z8A!j&QXtiVDK_JpBb|-jh!uwRggG1Y)~Qrh@c0O|S*sK2hh_T*{B`XJD#mfaKD%~! +zkoXt25MXel9#>c4vyE2I;V@D&G=VI@SGfF+joT`2*g+xvh>C6UJ%xLNCoR28EHvoF +zZ9N~|AbA>3nng9)CA3gGM0R^Z37M}8*G@XAgql+$*f6vZy<~4tS*)mR%xbm_KuF1U +zjm!gk$?ae-v=d`Sb)H4Db~Z$~IT&*3ECS@1!Hm$G%vEHBNAx-2)Cfwyze0F}jt`cI +z6`S58kYz}0+GqfE;VbG(&^=X?^;0 +zv>Cp2{~Jboah4v{yNY$6)_mjsSr4*gH&Ya@2w4+HRPBL2Ghl&^%$0Efg~dzob$!|)*?HDW9G4akDzhdo@uj&GYt!8AT*(9joy$P# +z3IH{o>WR$5OpmRBP6B-q??U`LT{rB^fg4(mrtVUSjEL74=33lEfbSPqz|E+Leh=7e +zkpEGZIBX*mPqAmIMBJ2i*9}FfQy->w>+-LdE-ScfNv{VAEA539E6L@~=zW{_fQW1k +z@a*3S3slyq06)cs#jm3P)Clt#Ou=5P`zVXTJjL&|(j#GU4tVrNJ_Bd);mFT9kA<6w +zoQxJPQB7`_QQB)C-I28uEl;txVy2`<9ld;A;JIK_$3E|GRBhUx(h6*H?#Ee2oC}@S +zdtZ3e)l^NGbeLJ3&(cNimh^ujtpWuh8)nNfZJxBnd%m@kBWZ+E#qQ5z%0KFa5OqCN +z<*82#ZwA!jL-IvBGxBUbV2W+1@CX}OAy*Ss=|iEf)q^^`RC$L82L${2W35H}fC868 +zo76Xk{q@ukti0rzs{5~AH3O0M;RA5n*h4H63B7q>$M8~kdQ@T-b9?&QpI>$F+8It? +zd*^IGTukB#@6_*LB`0%iK-gZehV+$1PW!fgJV$|RjtpD8R3$1AU;(0BI_ELJpA%2H +z)vu^ZqgzLG+nN)pI-EJBQFu38u>QQpp1Jp(z`lD0-B)?+yYD5dWy|YWny}(5a0Fl% +zqGoNhk#29q@GKBwO=N((0Cm!cd)+8s^w9(}(l)`4hax2u{Z8z8D4x>f#GUnJihch`y61%uwf8g +zO#bRp0lOD~E%&9NfBsLJX`1p+hub%>S+-UJ%N5{wa-zZqSxYvrgmh6vG+ITqNn7#u +zoTlqW8Rg8#LZhSOEgJfA+fu_R?q*^BV4BWhr5IF-=Q3Jz;$7R(Wta$`-lvNQ2k`6R*m6w +z8v`FVk@aINrFCWtTp?M~EvgIbNHsvl;qYjN%V+vPtzs33s&cHw=I`3QkbBkC_gK4X +zM0l%dY}C*~O5uSFa9ZgHy6Q(A_ZnwDPY}J+Q$r-&G9{3l4`=Y$&b{~^0T75;)k#=1 +z@AnV_C@bVoLi3ujju%YIOv6}Rk4~MMIjz2Gh0=~Vr4wry=Z^nfJ&vljF?4CaC=c=> +z(?4aaUce_MOgH51z4yfDsVv?zn-KwlNeB($%AtY6) +zR;L2=bh_YUqvr-b23tzgE$12uqCTCVaBY)Alh8PyG$xuwy_VCko}LQn>-3BiZY_t% +zyg+|}i!#@N%8CJuku)8^0>Kn(P4_w_g)oYy6g$j$hqBSuf}$>awYWFPu9^w}>T4ao +z1cepNyKM^IFq;|~agJF&Z+Dh>2uwksw}gjUa{YHH>ztE2@2yu=Xru^I>q@*{ITu_$ +z*vjIR{g|Lf<1O2RM_;|H^1&6I&|l*B1`l{}~ +z0}vn8+TvnpBb*Sq^>W|gN`s<38lG-GCncliv{oMad#$2&&`is5I4rfn;$dlE~v8?$m4?(?|0|V$jhfE +zKN2AqpvzT%Hw6n&EAkyq7$toV=VoxCY-T+JUTCoBscdN^Gk+r4J5!1IPc!S@CSNWK +zgEFF-R*hu2eRFiDIs@l(x?{<$=6$mTso(n>RlgwBZE|HsNxa2+!ux4c^TKpA3|Rx_ +zKy{kt=uRmh$Q)gy3% +zE=%bWG?a^#7_5`RDQj(+bqgTfOfw>U>&6w5#)LyX@$3ob`KS4O;gA9owE +zs{6VODA*P=rY^4{J +zkj=&7j(D44=x}U+Na^LE;KbW)m57ovPg5gZHb>*Iywc!d=pt9I<$7P`fqD}a^jh>8 +z@xtzZxjV*Sr=d=)wNRFJiK81Uwx&Z(Cu~Bs!==INQ-E%q9>~EH+QI||2S5Z! +zWX30nUn)w>`YhT}M+r`a2?L;Ud`2T|136nYG&Q +z>_v`NoG3C#&oTg%+jOWNVFp^w<5c`(<6VBb~do4l<5 +zK<$u$9`(94Y +zL|0$$h810y*+jI_*%Z*4_QPXrla__QqU{3B!#^f_CHjNtklJJl%W4*<4O6wxaMq`Y +z5(6xqtNo|vp&^H()sa3m7E3=6qD8*j{~j%#5PGO9aRQC?VaWWDBGXEbG5$LLRaAOX +zK>*)R_kzUZ)Iig9xv>lw2&TWdoh+@{F`4D=l%|&Ee@HwyA+!%3=nc> +z*Z1siiGF*~Sf*}A;Z7H8*QD4BYsRT^gtSBPzoIyF;@YYa +zb|ntMaYZRaQ%I=&Zyb-|iAAq;jxlPSH!mYJ_<^i9J8WCLv9et1v}vNSbN4lsz4^`P +zL!;>QYgUgv83U`F?o~kyxWFwl`*F0p|>W-+M~DN!c7dG!`;`)?+p72c;f +z)h~+KoLUvuea_Rulk)z@6e0=$##^x^&-6-gb84Ah+>|w>&-AzfH%GGvEXqI7afaJr +zGwVUH*8yKYjpk9-tB-rn*-Pkmw6m+dc+`wN1Ny1T;P +zK`$il29L{H(z)fxGI^m3(8S)taj2V}u!mPNE+UIN2j|>^mVa$29xi%E{)!?Ykx*{- +zSdb@zPH)NoYH+j>thY1w@2}oHb7P>|` +zJcOK_<*Se5<;f(dCpvir3hKm(9uwbbx`HQ+&%}=Lwcu~#<5gD0aF@eSTSpup$*WB) +ztuI7q%Pmyibo1PY@O?A;_(s`O1zITrGf5^19U`d}=o3pA0JE;}_}H~`4=s@^#sR4# +z_yw>=N9bMU)rMUbxkfDOBCRHrm%gfCrkgY9^I>)XAw6Kn?Se-zK2Kc1I#_^ocMHnmkt@ydnuJEm|HYmTB`==LOq-udAp}b^tAIc(GPC5Z6XepLaV^;ih6qdMG17b?j +znIURMgoM&k)utVHTl(8=&1AEQVmF+O-toV`5ZRN+s+rnFE><$|mpc*)uDb-B +zdOZ%vPXj({a`OsPXVX5%#cz)>fiuK9hkp*1v*+*Kp*RtnF>WXQq@BGw-ReEa%lhfh +zAU)B|vNeUqRD07U(-%N6{fA&ZWtNX^wF97d_o68!!*q;VwT$xu3rr$D=*4#o7w)Nw +zq0s(S-G^q;=eLyl*ASiE{@|sNMXPuGOc5V;RIAAa!s`Tqhv +zDKjv-E5vAKIX^w+z8Hcxva=jIQVf%p*-`S$lJD;~gjPml@Fb%Z+CKV +z(TBkSFk6kK-a*Pj=?&!CrPGL$sgb2F;3f3}ICX>kvswFxlq40VWL_dpPUTr_>KO?7 +zsHezJvYP|5AK%^tG*OAjt=1>0UM{qnENH+6^B26Tt%FtqTib|5ZzW6Wa~8hjF+r+K +zJuGj9oi});t^c;i>Sp-WQ+J?)0@?hMg8E-aIHH|6}Z7qXjLwL!8 +zLe@azH9}`GnQV$K>H>lXNCXd8gH9Ndt@hzUT13lX=@F4$Vf9LG7vs>^A2krZHdL+B +zv01ZXLTL*j561)Sw27SI;KEd(q|qk>7{n80S|ZW*&o%@vL5SJw(ew#3v@ogELgNBY& +zUN;6*8!u@SZB-jd%_=lK +ze;QQ>Ny^unljSuhw?66~KzObfraVABciQaIcMnfMnqho4-~3?Pq^|KjEH8{veiSzx +zzi=K#`4=~=p^l&GU@i8*Mh3Rp3}ELN5zD#&`{;wg{*W6Urtb{~zaSi%>ZB<4)LIo8b*RTM>Q|lpEA<18lv-MKjpJI)k3mh&LDRn1H(?$p#QU9>)lX +z@WG<8VXMU7FHH^)5J93Q^wQb`ksVeqS5Y!L3+GWLo`>T1XZpE(wZ^@*`^LDdilR!? +ztJXxC_$0VfS&Jkzw7w4f#})$bm~3Fv*GR#5KMgpsJ|soL^ew0x`7-n?p0r76TBLpY +z3l(oYTx&`9S&AyiZNODT3EJMPy_~2HKpi$F)UTP(5C*5Qu*QuCuWVNP&VhFO;z+U$ +zUZ-EiP$uaZAzA5)-wElDEGP4N6a`5NHtCH&!)0$QYXLD;i-EJHnVb68=&)aJ0M=3$ +z&AuNQbFOt|2hT!2>BD(h+g74p_`_StuX|TKd#Fq@X)Ba>!nlxzg9F@)V86@6zK@=> +z!Z~d5l?b8l3ov@|IUyAcu`)A81YtZh{(w2wP338fwxJGe^M_0Gb~!--T7 +zVi?`$)jwTtPGj#qi|HLy-xT?juXe6GTBq~TPw1E=#`O+vDwA;PijDcI$J0z8;|uN& +zy4tTU)?7b^!fDlLT&eI=Bt0Ma6>xd>;`>Ae)X0MrZ2^G}%f#d&W3a19k=b3*Rg13o +zRX`qj7;gY*`?m$?-IGDFI*gu!3bs?irQ?Ts~$ +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 +z#3LEreOY)9tEke4eEVvFoar3pPDx +zYNs9;H_>d|sXGo%!SDK#S1RvYnTOFz)dLIqv^v2PQsXSKaPssW=;2CZIzf;@gCsY;}Ylr2izXjvkpi5TU0q-rQR1*b|$hDpvbU +zIF{psK$+1!3AMI@f+QyP-utYF)C@mC%26!vcsT0hKi*PkTd@nvRfLGwQ`JdXQCe)I +z>M<-qNZ#>P-zfkcNh@Z3S2(QbHX7)02kxI!f-TVizPO6FJZ}(N$P(mQ>PkrB*TFh% +zTlR+vs*rC`kBn$BQye+$^NQs9jA7XlvQ(LulOGbj@sH?t4A}68@G_M@BSgGt!%?lni02dUL=xav+ +zh1}YCZQfikaf}^5*R`Cj!$^;*%;En9jX-k0Yagt`J)~fF;wd}>4iC4h6qD#WkG;|$ +z>ZP2%`60>IgT#vGtPFSH!+LSNIg97bRRkZb1s +zFH|R|)h=y1=8jl$HM#+QY^F^zWv5>YXNyK+VuopJD?d;*S@sy3*zG_z3Kq25lDrun +z7*?%l;@uB%SX)5LtM@$;5umPr4CBJKxxFa;{P08KrNvS&nQc(S3oT3B=ZQq) +z6(qqn48Pqf^3+A;#m;7tFzREdy0C{W920 +z1jemq=gX~1uCDzDj2>L`1a75GT38T+zux0jp9AV2R +z?PbfCos%mjVOvG%Me(RGdi5<7fHq%yi-MP#`XcOZJpbcOl^&&&;d0Unq6c*wzx`b+ +z7SW*~DSk?=vKyWx+=27?xLCEeR>;%eypbroc8HYTj(fs9WqVvWMqMX(mD;xqd2gzQ +z`QF4H5qDfAR6`M*ooPPuWm>d-j`}B+vSIhv(Ux)&)_LA__&A4s!GGgadF++ad|`B* +z3aa(o=tbE;Z0pcv_Yi@8O}nU@B8;wkO)1wmfsDUWAD$LGj`C|xkHx*V3W(J)8#5r?GXREBno}@=r!K?bfd{)c;#J%fQy)#uVq6XHH)1M09;)sb-Ub-4jcFSv(x~l)ZYF*N +zP?RHBUq_cBdR%?tZp|z*?DhoCOO?lQ?;jTd5S>w)I`2vtMu%3$`s9j>r>Z*Cgl4u6 +z4z77*x{Qw#8J+~%wq*N!oFRG0GSW>Cxvm1!!8R$k=QLj$dGenwor71 +z*u&r>B*McyO!J23P%@-o4X?J?vMCIC3aBaK#jlaWEY79A&332mzRX`22o7au&3@1h +zmXuE|Rzl&$RDwNr42i3Jt~)^Z&c$s+0NA+yJq6nUQXd!vX>219+coOF1@A0d@g{F? +z5P~h0Ec`E={dUzAYUb=SotX?al^IeTtGn@ev}I;9enh(%x%<~A6nG=BmsxiZvq)GTD_y53o7 +z!xN-U$$3jCzUpC&s<5sG!k}PbS}r=4KK+=DirUwo6GXu&)4e)T+z}7uJz$*+U?BV) +zKn8KP`>&C)k00)lM@?PiWw6x|wX8vS$?%lc|EUI0PRpgyO$HjWIOk=@-bjNtsr_!h +z6?Gffs6GWa)BEg>qMSbp!!cB9YDG>IZc=&wvpDVd*5C57w@=kuhH{nXoFlQe$rzen +zWyWV+JSY;^hKAM*Auo_TuxlGQ&UI}Epia`i8Kvq6ZlD^I>JnVuEjy<7M4o=0{eNNX +zk=PJ>+HKCdrF%k#>+QiQ)S!hmizoBW*|(VZFKr=4N;7x*n7)U1&+c$!{s?$7q*J_Z +zjyXqV3U2%l!jN0v1azzYaKj_Pm{l@vS&Z*2mv<&sgzGFUi@jma|~dE^;Sfiv2gqv&l#*Z}&113>*BF +zFr%q;|4=S-8|Zx6g*+OXH%vq%1>NT!2FffdFsU?i<5E%^S^z=AK1J~U+{>NaRk)R6 +z6m#mlM%(&jjPg{LRef!?p+{B6s$_lR5*(h8hLR4i-4Z9Y78aFa*#Chnp +zZ61mozB-+HlmB7 +zyEDKLy&@iVNkdCmkh>3k__NE^jJRBE<}z(XZFgMk`MVoMX3|@ft?7&qfskJ?)9IK# +zG9qC6@rlo0QqE^-cWFNljs$-%GuN3zK7kFRRZ`Qt +z#~H5%pPP>~HP=Dgo7JUDSB1vK03t@ErJHSgcYB!~nUBR20r06>$^G~bcqc(7s&m=< +z$HrYvcay2c;o2FOcFB*D4_uG(fkQ +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 +z{Z&USV!VF~9E-u+#P!T$&~J$U1}0 +zOu1i4suggXXeUfu!jRih(D@rH^wP;m>u-i{melvd7tIfAcq=MMow<%O+OV@0 +zS|~%iy>=q0gj~h)RdkbkLiGNqoDvcWv#mwGd36b7M&V6EW2wzGl220^lrLlGFX> +zdz5o_+%SP0J~fXn@c4%Ex%FGBBba&&VR1xQ`*DU@1JaxuRJicITT%Q; +zcSx!cAII>RcF+aUU_Q0PtmCVH6Q5m57aF3TV5?H=?@IPs+(0g_`;uPeKEqkoIID3Y +z7#1AvNizpD&L>m2EB`Hqwb`~Naibc_;}rM3kjUvx2?u_o-4RBfzanMf&~qKazHwG5 +zq_OAcVn-TfgHX3ikO=Cu!lm>Xj~sLljnGfdUN1T8AisGngRXi7Wwra!Y)NDcyK6;L +z_js21q=zaXqlx%r(IX(UOvuZf~|=(j^^|aqkBr +zer=W$>CI-78cc+7vqgi@m?SRBbyF&Uk4}9YW_hhI6y&giBK`}dM7WY^7>tpw)?Pi& +z+!^a&av5P-q9+ps|K6`^TwKaK69h_l5!!bX0ks4I&#GWnKmB^r=cT`g_D*{&kT+^ +z#5^8H;U?DAAU4isevL|DOv$*TF8!eas7XCsas*sbLctc5;S~gDoIBIJobX?;Sz+Ne +z0~eg-3T|%lJP$lss^2lkhLU{x_{8$G9NVtO%iOlW#t)W8%1D`= +z=daU)+0+1F<`R5k3qZJi{&2x4({I6rkN~ij65YBuJe%L!WH*tUpFx}sx@ciX3up82 +z2<$(HzMdLg4zJK-#O?*|I`K27@+UvoDd+-$Xxr?9KUb>)ac{NupDCpL;SK@CD*9aQ +zKP-AF-zaslhttRMNAHDreyI_D3Y!p(clvdKaz4vBdcZ7^$lU~JCS`BQK? +zw~$;_?th_SK1KOPY=f3hSG|salT&(B?#u22!5Orj9KCL#zs(##0OW*rGibJcBaU*I +z&aE1jaLoV=N^oBHUDmY4-Y}Q{cj{(~nckdGaW}yoV_dCI6>&hYht^T?;Vg(cJWl*u +zFxBBJe%Ro_ven`x1uqRVM}{{Jf89qmU1+$t^5jRG4)B=9sZ>Gs*J_I!?qsf&^0<l=q)W +zu%W(@kS5%zZ~Nx%QJz1c%_as!UZ&&~2_)Qi6-)a6W)rbS8H}PisDJnUq?$+iUa#@& +zhKPRd!~P!~Ks!o&jy-~XTW6ggY8y?TF)G`xQ9)^&ryc@xt+z!yZtxh0>rl!&w0@h_ +zz9iSAMq~h|8@LY?Ys31Lc&Z~-0yh2=lIIQf8Yc_<#0%q44=JPPTp4+Q5Mxh +zAf@B7eaHEHROO$Eip2zfRa-pckqrx9Z8i%Cgrdn21ez;2|2(l@xB{{3HiKQNsNHpO +z-NM7F@0g)i0RU8#7kIcYg*6WjxS4A)9+)2VO3Mee)&yRILt>^|hBhevvRCVjik!(* +zH?kIECNoh|zbJRJF^yi3Dbi9U*Y`*tj$3tak_K+l@muXK+eqZP95SC8<046Evo$aE +z{QNxiyEYgv*lupyq0KGj8~1@94`p<6#jf}+{7`IMhX6b{jz^Q-oLptKAQ%knGQlZ$ +z6L}A)^x#6vKlG5Kgt7-=#&-8S*Z)aKXVJqhP@}!N(9?XJga=!drokR-nw{b-^2`^AAU6 +zbRD?D{Q68MkP32K +z+GB&3+oBa@Dt*~7o?c<$*tTHw;ch1j;`#T~=M+J`0TEV;zUghZl$E`ETiaSiV~wJ% +z?D@s=#A(z8Su`o%sAHaK^=!=?xkYu|H~W~_?E8g0OV;rQz}^Ud&RA8 +z7b9A8SWGvV7|dn4P$;0%$kN5%!jTTs8^I0WkqiP0hm%II>{p*W`u81Y1R~@x3b{9M +z&Ce@ms1cXmd3R=DlihR55PbP^*1Lpq4!OSvE^REY831-Tri!q0V?eeWEHI>9qMR0X +zeeJOO2R1?5vI$Ga%aAwIO}xK2$arI(Y>M#e5B*cFQ1tt(ZgFu1)2TInwJ;)k(awku +zCB1|6r${NfAXbfHOIE%|%an=$Vu7@SHs%o`C@L1G;Lv(B3AcE4|&epV!Jm>r$@@|qYc`BX=?WvvU1cOeeE@=L`B&pY?Ay_YUe*K<4 +zZlc&9QaSjTAl>PHedt&4?!cJaYyi>3Q!#kKUuTIaEc2|*>L{sBk(<#+c +zR0&lyj`Fq^sDVSnU6p{)sOP=-Z-?kU(%5tTZemjhIu8)x2_Xn)CK}u1*dP&S +zl1-{dnB8}c6nglzt;qBh;=r?t9;vRsh>V%jrUCd6{dzjOCHG;4zRVz44M^Qr^2>5GGC!$21H9Iz`j>#3Ve@Kr^Q>c){$$YC>52I~uW7|@5$k^dfRPMJ +zzcT*II(b$loLPuxo?w|t;)16S);!ZVo{ +zeL#FxWZ#%=+7H>-26yaq=zv5bXlbwZhp6`?HL-y;yh|GDeG@4UgI3|HQ7k^f^1s)o +zlK4rJ?U4+JwNFcMGUgjb7!3i6T~nX^xbgMIdN9g9ys*3CVk_^+)|I>?|t2B6xh)X0;MbW2~<>^a2mz +zT_AEYP=^llR=rEDyg}*JqF%DP26gT?q`C48gJPX(31YWTmdaJJrG!1U3q`vqsOU(N +z4oRK_^3IRswk%`i=WPnyA*UGSlv&G`W>=rg6!qSUoYu(KuScB8fvR_Vd&G&LqPl2k +zhYIpW79#a+#}$rjKds>rXd}F!7h0XLNyxh;IBF-1;&bhtbiDdS1LNTpS;96m6oHi3 +z{)VsFZcuk4OT@a{6>>lV2SDp=vdWnPUB~%q~mP&&6A+tr2pPh198!~+_B0E +zj&S&vv`6Ht1`kAYN@q+t(1j#0?|w9 +zScIt*C3sR|W^Z2;0a-p8JI89-?XU=)mSLkNj3+w!A(hyN&C{T_VCn|?xmv^G#zxR5 +zu4nv#air&L1$O-0VR00ZsuhT4F>ELn+)mbd!I$B<1qLw-b7DsOE9)_@2YN+!Q$Sh( +zDl3hV7*X?90_l=oS9$8!>_q2NVH5j(U(@a+BgFujbj%CR!z2v%)u&9z_TQRkts0Ml +zaNPve5=xBNi^)hh*3B=gDAo&>JTk2mXlV}98|((LGPZk+qk~t86jp1$Hs?@_LrvSE +z5SO48Ap6yN%oZwni7H(mDPiDt#1AD_>8@%5`p0Y5;g==Rw%ky9Je253r +z;+hN!R|j3UE^Yxl)4_LnBF4K_bx(W8v!=C4&VM6pkXCWiHTot2^eN}S6eUI6yF0d- +z^iwCP%Z?h6ze%cU>~n4aD`QX#yC`;bT8}Eiq&5|6>Yn)zeiF8eQTH+XQjqBH(0T^H +z4#;5|o8Eu4YPi>?>aDu*R>y971-lwjW`YV_fua~H;yt4>7q*5*JXP(o!A&bKOhO1> +zY_8f{;D;+h>VUO_+#IXu8Y7bIyY$}(;0)g^a;{u>hB6;o7E4m#Qbhg!U?r)~=xZ1r +z)ysB9I`-8g@luO2yv^VB)k5aK9LoaFUFlEY0Yw@fsQ0CrCdeeG`D4XrRqj1HoR8!x +z;cgeWm@$ozxuI;_!C%|-%L5j#=59e3-(LMtErypXTa9u(!NdaR_j~WtJPb$-P|63z +ztY1iWsi9q(;ldlmMTrti%WU=KY(2g+md*r*kY|UV<#pDb +zj7t0FO*FVHzIp^2-EP46UKXyf@mo+>QbeMO41ptESRICtiHKYOAs{z3O4|&XQ{p-& +zBH;0ZmbD50w8i&|`W1k;2t??xUMcxu0y9Y$E6rB?M}Mm8g!%9B#khDMrs!(kHOj^c +z0K%11Kn+Nw#?q^v1c-SItzXU3Fkj!SDBE1+Eq*pnV0>4}xlG4#h}2xfHJ~xg{a9U! +z17XuG2Mnjc4laWfFMHptr%sAoVcYw)ia~-&b;KlvRS_Qm00)5qpDlDke*gr^3~Wlt +z`g6{h03q@DP2kw@0DHOmK=+ItI3cWok-PTQN(-Q~=f|7IjE`N@wI1is(h}=|ZmX@8 +zwcY6T20F>-15jj>1~($++gK9Thc#u*Hu}GV|Nd#_nuiBtm253wzJT!prPKw(u5i!c +z{~&Q4&g;w8glHfzC1teS(>0E=ieMZx!=cr&ypFw_tmFgAyPOxvC7%1mq)QV=3h?X( +zH>kg=uNg_(V5Y&&iYy@ZI0}(x +zsb5mL)h0W(rpaFAq<$}w20MHRsBdd!VYtmZSskPk5i=}|Zp&Im&8k1q!PLJz4v+4! +zQK49~zl%?%ldQ$(>R=}^{@}Rb!p^Hpv4`eR&O@#{5o9Q!q?>H2cQ|zH5I_3G9JaF& +z(XunVk^qNE#Djp>uqAT#i{N7VEP8jbeB>hA$BliJK4-R`l|vi*J+e+ZlWVH9h@l5; +z#|G*dB5<6GUbr9w1M=z!cUkWBChE#{k;_U}G2QIq@Jp;PON?YIw|~Mm-;gZOSw46M +zmV$u9nJMLg^9qWWkTAPelT$o#`Xb=o2^ro-oP*(y%Y$~uO*?f*_pqfcLnVbV4 +z;8ixU#2S{hCi<}4W}(sq(O^XBNCY`v*rJwSf}3OeK2(Lb0!b@DEz{VkAWP +zlz5yJhDW@Y{PxYqNUT(I8Z{Ji;|evoy@a(Kv@^WRDs;_o0CI6MC{1!HDX~7EE2FUm +zZJeBsD?MrlOO}G3trbt+G$R#JU+TKNX5ayz16PBeaXdux8T;V_y9M0OT1^$`zipY9 +z#S*z6bV<+M>V^76+XOU>l&}N8XAR3?ZwHX<$*7nGZf%rzGg;NYXaonyw6YQRJ*1KL^MTK5~!@Oj3f(0}%>W7QN6^|A-a8Ri^gX>-SK<-&;x +z1wc|0r*}_Anj`5#=exFs$+zAphznEOJ#H==1H+Nl+!r-KLQE{h{ihj_LCbG)I|xhH +zJv<;uM&Au`qBNuASSDs`TJy6qcC_EZv|#IAg8^c}QnA4RCtvr~VywI7SzFR0$)E`w +z5J~L*wk(TGzVOmnTPy#D`MQgNK96;)hH&mE2js@pY0{k>p}LrN4|mFGeE8tCIl&74 +zd*1w^{6IcdyK%6&?+-U}Je{pJUvNS*rd!7=Gt2%#O;~XVACM*)NJBWD%$DX!>#KnZ +zDeTtc?ARW_UxQ%>mV{@2AvX&8*W-Rd5PGE +zyZcy}=XI}DG3%np>_ocB0wt1SV@1@h;Kd;ZA9Cj^sBroqfHva0Qjs7|%iyv}NSv6l_XYZ2}l-yrQWW~|K4kg9HW}P78k3L;f$b?8 +z-Cfj@pW40Z9146&MljXx--NEY+mdc%O`!>yn{lmifS?%Y04n@1`NbOA?qj^;wQXy6AOFm!~bqU>VLFRRu4X#dSn10d@@h&I~SiOAPCfCzs*-r`_hlF&FrQIaDe{3|A&YJYD5psQ&1NNLf4~as&gMSZtK7e5}aLmV~uLN#A%r&wP-jlv|@Z>RU)_V5IHK`l7Y>-Cj6a90?i!AR1I7wmpQAErS3AFMUQ#54i6A?3KILmTMX3nxmHTJ2d6)QGqgvnLBsMf%1}Ywg +zbM3#11LVYkw8GHmC=swOLx5^((d}ZWiPibC1D*Ppyz*&+SbH5u4aq3d3;)PjDpp7P +z8K!V?Y|HARzDF!oXv~L{v020$D8AT(JTb1|kSxFr7Q~-Y3pLNjBO36n2O<~4%GNZ= +zLQI&XEg4e^QgsB$)e!F7WfB0A0cwZzLnsgDn}0OGud@(%(((M1OZFViL$O}OF9QJL +zgWbA3qq=U@NiaFqFE-h+t?R` +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 +z#({L)W*go +zTy(+6q6c9S=t7g|hb`~PGCjRMY$#qAv$_Xu1y{J*lZ_ +zpDySz$Mio?Csz5sYYhrb`Mq|(nFu6E;I;#kJtL2{2pQhM}|pW18gw9sQO +zk!;4JK}wn!8g@2G+oAUxkdU|3jKleDl7)ao6hh6s=VC4Nt&>a~_5gFHKy)R#tBhl+ +zZs|mkqACiTr!%5=#afO+wo>av6B#Lhp8Qy6Y?w@Si64TMwF+qa`T(BT%p4(8QfOT7 +zfBSOg0Z+G9d{bhEKs%;(E!iQDeNtp6L&q%Qc#R?;THI^>s)gEA6`NRvh-tL0Xx$f4 +zYuu#V+yOrBb(lF57>$erfsyslCgR@WT5;6rqKBer(Z>3~42yliCbMyxE!G_+seC?9 +z=dX@0>$%U>y_)`FU>cbtyo6vNrv78$i-5zZ+;U#rU +z2U*n!vo?S7x*1xO;puVryIY7EdY?qt&N1Ocb8H*TLSIiJKEvBoRD@WV4$5MGn>TMg +ztW>aX9K@7Hp=HDhP_nfhHe%WMmT3Wn*z{LQ5)XwlBgf-eMQTuR$Y0l+q|((@Y=yeZ +zUa7#1kX+AMbTnYif(ZehsjwjyEh +z!mBSNcI^%-iZB$?k&tU)vznv#rUi49H^67>GQF&JnOHwByp?CxN_84dTRwM;8w;+hfI6 +z2}Sl>_@<{L-bT`8Os43NnVXXH@qKu8GvI=3jK`X?}b0zwQ +zk^+73z>y=J?8lh +zOGc2F?){gcswd{#kRwVRfWh-V>Fee`FIK2@Khaos--mC=>l|&{BVW7@NJF8j!9gQbZc+imN7 +zy{jt=v)DZbLcE)#cuf5J7MIUDUTQke^uf;axQG*AS!R_H@^?nzba1g%*8`3gjb}Nm +zyuAt;#@DRsnE6sw*Rv2#AJinrT;2-83P|B1y#$?7Jr6rqS`|-MQp~2BG}S(X6AQetKT?CE=M=tx>4LxcxP8wDRG`SPWbj*b7RAz841;NWjh^15 +zUDRtM#Q|f|OKI5Y-z_zReeL0Y_SY8>gLK3JU2h*;2x&k;G)>obO~;MwOF|7Dgj$i$ +zMsNWgR2TN(ZQ+_YTkj{&(4e_0{I8y#xmOje+iG@Fo@<-&=?5oo*1xw{#QbCSWvqv} +zI;&FDtr|(lhHUuA%_8ogRRTR^?Wg4cf4PHi@MVz6<0gBS-Qj-n|srur+ +zIk-Bw`W48j-rl4Y5i)w)565HKPKO#O$vJYR$4%pYQeIW8Y72PUV +zU^huzrqx1O~~n<>Jd?jl>JCtZ+Tx +z=*d)*tXLlAGg`w&<)zVuA_?C?!qZKA$V1!p6Wy8!^FSOq=fm2^5)2(PWKm1<0lOSe +zvq)>eYM|V=-t0)#9KMxE5#;c0xJ*t_r|y&Vnc-j3hL^4BXC881A^h^|RmP+iW)RfN +z!Z#0atPck})6M{OonghK{;r-vxC;ji0CkwiKjn;QeY@SU7TV5r=biqb^5;A&b!9jy +zk~FUyAve;xR+ACy4j1*sP-NAUBY8SN=;XQ;=6%&qijqa^6$Sg8a7- +zI2B#%Jlr)?qm|O#qW0s<-_qtAytMZKJmrya4kyRsY3J{=d+P!A?sAa@9$uCPI_!K4*aC%heW8(+*N*BUyJtvxWI98RjR^BtLeBXSbA&HKo +z%(Bx^U*x+B%sc0w^zR%MLnyR9W@x?l-6gUcJy +z-@4LIkixr!ARm#qN^q|t$dbk)_g%s->#;)5!alde`%DE9@c6&2xUyy^I{SM@$BOX&PJrCeN+55nu2q<_dv^%nQS1s`XDNaNcUyA1a4?Tt|JUIp}_=_$^05P5_9YKN!vP&9XQu4pez6k=pGEm14C}x*Gd2opfjH{Au +zzaD?pGt#~F2LA!kvmAt-=MJI%`cJ`4r^xx7-^a-Qiw~!#AR}L^-rawVpm3S^3W+tg +z?-1kLPul*EQ~~)kZt2%XW4nz8+aC7`%eU(@7Y-WGlST}^t4#g)3sU_@AvB-EOOk_? +zl8I#5&mODN@@xo5RZVWDToNdjjp5Ck=&5gQXZ-<(@W~B=(Iox!$M+eRY2cn_iAepi +zB1)E$RP*}KuYtMp_j14RZudU&YuSDU9~&%U4bzYGBVd@#i`95?i=u!CSS%vZuHHWe +zCM+@uhq2G*H?6BZF3qrWCNm3Uza-xQt|cEq&m|qbu43Q9wxY0JE~);-W{)I_5p5zr +z?#5EPxF|lH_F6q%t*N8w*Bf~ypg#OlgO2P4dbze(1%@sx#@rW&fbLh9obZ{xUk_%L +zhZV`ai-WNdIuw3%wc3Zq{u+=P*>7^`#{6-~i)$H*FUt&me;X&WwjiP6;|i^=U4Cn01!zp4%d=KQ^G1(0Q~cRCRy}IHiQ6k-nZ6DC6{hs@z6F;uLG6?TI877D~TE(F~?A{vT0tS +z2IED~^+0-%TXM_U)hgYA000Mj0iSVnLVo}R$_)Fs$GkymAOatDAVI6Ee!jg7h>a8V +zq53~&V@iT2sX7_0W6SoC9a4%YVt +z4us>Orv2x#=7Q)^ef)0@ZmYkFe=^m}Uc5eJ$?K}$D^XmHJ(+Mn+CCVV9rZoGE&|1q +z{IP&wV2uK`iFILILQ~J?-9~E!T9_-~b_G3m%$xZjVbNc4*<31wv@=E!wix=VAncRYS8(li{|ns`r`!k8TB(t*6trlYY>1J4z-!cPw3aI6 +z)t)8vKxE*9`G_44%mSW7r)!2&q(L_(I6iiJ?RXvmRPkTjx^Am^x61$M +zV0&JzubfK;@O$@eam2fv+Mnhu$IL6vbD35hNq4<8R{Pk`tK+U8oYV`*BEUx;M@0T% +zbw6Z!jz`2K)Xs0GR61XiWc<0|=o0Z{ab5|ZD0<^-y=Xg4zP4e#(tI$vI&_2VoMIxO +zynF;?v-wSo3z1F8v&W8TuN|wb#-JSr*ULONu+Crz>Vfuj#EGW$>9QL!9u9diG$CUP +zssC8wC_yWNi0*kUi&UpUBFQW4n@q?(aNroCdKf|^4&xqTJj}UPTY=CQ0KYTIuf0jC +zUEp55vNN|k4(-9%jB#}^LUrvp#o`m+#r1W{=YW>si`E-ZCJSP9+jQ*XvkvDsQvP6&5)8=)#6vsz +zc}V(5Nd=|4v(ZOU-ZgLot>Kj!pO*_AcBE|0YTx=75|DXg=f2HO^yo+i +z4pih9CQdGjqw%~+UI?cfNX#u8>#2R>*fFcA^BYVt=YK)n5b|4e-M3Xoq7L`~7pqE+ +zN^y{;Xl1WrO=lzlXTwKnAx +zxaYyH0|{#Mc;v;%lA9MEqBPFDT)R?o>CpM_r9?O?9p|Os>-*}#H9Ja+QF-0{@^BvW +zyU8mk4o2dbnZ$Qbr0%!eY;)Y`au<%`o8pjWVvs15-Goj`-{}y|NaBklUW^CKRL(Z+ +z9c8ZPj6UN89gDBrw@q@)cQKNoaYq0;z*mmjqcjv| +zjUu0MWVaUNGGt7$bIx_+0lf(7khPZJV9?Z4DFgY?@pDrxTdKz@w78Kcco9(*pI@as +zD&OStbGyTP4z1eE0^g~b5@HB6g0aOt1EfloA8ODyY}WOPC`lQLorHCoVP$+9tmVIC +zH#EeYH61z!yhA`z-q^((6#B4UBCmF4pNv}6dZuJd8SQ{w`uK4UP +zTZ}&sTk`qYUbpJTeJX91oTZrwnJjU#Bqq6o)E6{U;^ZB5DqNzvmvCK&0||ws@+)p#tyd1He@jsR4okMqnzj2ovHzD|+?4!b}wH;Eep +zxRUcPD`kwOY-DUr=5% +zQN*g6&|V)&`vgLJm~QMJ-~p_)ZnR*-%f-JBSnzf{){S^YyDpN*??)4&If9r~{lSh# +z@7+{y0ooF0t`f2E%>|rg3`e^7e8O?iw+$WcKazCf6lCi4S_6}R3rUbLR^_uQ2*QLM +zJ^914f=;uX`SATVR1l{;%AShh0c(EeWrkW@3mC8HGu!JE^?z1MN(33agAP3d{j%f{ +z=srt}5ZUuPgEArcgKZW-Kc$Vw3>1#Ww?sMadDBp9C;PdLSdAh40oTk-xBhrn!=CDJ +z9x@HsYupdHm0AHPPsS5{auD9-Lw95sbud-G-9f@Fh>(8IHvkW6Kk~!;3n!t(LA_PKSAf +zDI&c6a6y0|>gG3PIB8A#IBb*#H#qlmJ8rv5@>y{5A28z`>zlss1)MYxrf6o3sXWmyov9G?7_ +z4vVUb0FR~SP6;{&>qXdfITRW)<-?rr=Kt;+VG`2q!O?VZ{$ceewOttvD|)8A9MO70 +zlVw}-8%Ypr$ZIOiHbEK~?Lz;SA6ct4WN3^S7GIxrPbdxheCWJwP8gtzY3`z*=giSNIc}Z$ZJN*pAI4%8+eFu^e0!?DhCax?_JCq1tgnKj= +zb9F1>Uy(#wfU`!iy0QUPfR;Y-aO%HDnNxa;>XKJ*rFR>6438@5Dt19qqiY3f?bVPq +zaZWwv*|lgAsW(OFEH1Bco<-tbbc&7*H96@l54*pFInhl7WL(h}u0kZHO14A1V`urh +z+Z9Bv72jw_{hW_^$sOUE9Z(Ydz#yhC0H==H?yrB&*mFVU&S1YJ*q$C4blYouDm0vN +zm75EtGhWVG*rYdi9}Fx>HLuRDDdDQqT(8s#;8oa2rW>-~mP|@d2{t~-dFr^ce0Jb< +zu_^y?2*{DgtHy85zlF!GEFS9f{1*-0C6o +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 +z%)Gk5wS~ +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 +zOhW2SP&ePSmy9Z +zRm*s%*lkNk6M4mUPFbSO)M-?CmqP7-@sl-HM%GmBv3HA)I0$Gy$8%F +z-L5GH^TU(;!0N#06tGGFh~Y2V%SoJ|`5aLGdTUm0UsEeB=Wc(^DlY^K7>F(*d=G8} +z&O_st_<2i4%?FA{jxz-_nAD;EBuD0X9S8x)JHo-6u;IC1_w3I(ijI7{(CT`XWfp2O +z`&J3pBGLw{~~4fBXN#39HYCkRepN!Ge$wFL@0?>J0){LF;WrbC#V +z%#oLHGXSkt3Z#N;2d3*ng|kF|!2kdUj{%>zYC?Yi1j-CDa5N5o&aeU#C`{R1`~%+h7T0Y-Tqwxc*M`kn0H`K^TzP%=avk5*#i*a(ZJ1 +zXq6V}c++L99L^l@>-?h8;#ZrT-w$4dm0v +zd(1lc?ot6S0drixfSg^#Rm+ge?977Ufi)^{xTsq8U1dEXuU0*RT(!?%a-1H$GwS+5 +zb;0hKH2L6eEx?z>lpG;h7MEM&QX@F++H8CIwRt7#fKK&$S4kKbJWvVZazvMbF~C9` +zTATz8io9I&Imj|Ej}q!zij-0mwc#V_%qgbIl0QvA1)#7va|^GTptN~C(l|;m+Lj>9 +zEe*y!%(WLYwteYUkx7UiN2iwHVg&W +zJx=4g>@#Q=<;#T3i@9PjaZqGEYGf`SXt0qRuRhuO +z6b#`o`jk2CU%Dq$P`)T?bTlE?+ITmmTnv&l&=SrCLVO{f;Wu>6F4w_zl3Umsr)FqX +z6xevl%sOqk899>8VZ(^cY_lws_TfaW%<)+MYUF^Ef{{IyX?yuS{JCbe22a)DrmPQF +zCB538Q@BVHFJ_Hq|Kq(mcU!i>ZPQ(etZuu&;EKd~BddzufQJJG@B~(YYIk$R1xq#% +z!jjCVl*|!|PiFM%qDPu43Gkh_s(uv;P9SNK?#$PX6%yQ$7H?&m*>ZRde_ngbq%tgY_Xt|psXXrhr>ZFA{fR{$Ti +z9%;x=6$wNc<&EcGRedG9d>htQ3bcw7zJ&w0aoOw?D;8VYO=!+#wjrT2wC{gVuI~FS +zw#w8+*|3%1J;(*`rX~X3{Qx!s6NcrHohDt7@d0}HQQ6Bm@>HNf{AkOdWiLPlZ~){e?WfX{5dnl`Aq3l+HA)UHK_wK20yt%+NrcmE0f%vb&aG3Jk4*3b +zPTsq9;XlE@B6O>s_Fn8ZbXL=M}YMBN_4^e}4osfgE{4*2?7i*cSDr5ztVDUZd-Lw8C0w>st!?R6AH9%XlU5fI29~EuBu+`n0>@aaJ%#1BK?k +zA&)hbL<|gF($y@CH^j6zTU_LF4@0-OfMrcJf)AH+(q)ppvT(VRjZm%(0_Wgwwp=7? +zr%UIY;^`Qva=Zy-69cQHvUx$(IS2i@z*d$_C~63{;FCmrf=hdZDKhuMcgE6-tH8OI +zk+3mNiK+r6(UI~k$3$$Z>)5p8F~JT0jSqk~QIXCaK-w4i|N042#5-(;lcKiM-Udt2 +z2m6)l80Ul1$!RSwWsF;wLmI7;#V3fxOne#UN7j^T)XW|nK|i;!p0R|tr95NBn3mWp +zCoYt%?y~jE`kyZRI^zW59_Vkx!%9N$ov9TbaevDQW{wl$Z{=SKU~6$Nu~&ZubKY`v +zFJ~>5Eqo_O3u+jBi$52|3z&%?*2571nUh4O_eBuJm(po;}$DAz$%vm-n5t- +zN@SPh6!1arbfYq3-n=l2dy<_LqnFDfHp&3(1m{rlz9d?cR!|@mMmy#KI{lXVPR%-_ +zplX-<^*+(RHb +z4T9wNTAS`EUk7`KuqX3zB3;Ko*8r*Yb~a5acI*_ug=_XAa%VD<f&6BHZ!>LP@;|{@ahe^o&)GYXz9V`v2Yae{e8`;v!SzEL)FW@vuAZXGR498R000M*L7Tfts6lL*ObAc^ +z{qX<*t!?Ik<`JLaZ2%iVA^{~mB2@!z9*B(N#xoa{zG+$wizbWv7Qp3U-f3L#G+P%>_G3(drIL +zkm*~l`-N!TTH0{Uz%$jwr8mrV&il``;g4k_ +zPcn*mBt5be1T_v!y?UEo1uYJuhNs|Clpx1rPi{~1oFtn_&NwpKf +zMYsSx6S7#UUZ$`>p6^e0@l&41njY~2b5Oy4VW(QcR7|Ew4bPEh@?SDdO%lCbesOMj +z<&HR6F#_BZ`Tt9#EY)*08vF4z+~W1DlB-+Jd@jKe(&e0d%En1Lb^u^o-zy>6w~g6m +z#?Z~`Z@AoB&uZYMyRqabHWhy5i4D0R#>Wd~;=${!o{Nwvw +z%d2xuK#NQ%48PNvsgE{zAY~cc8B=r}>#1p5>zl +z=xM$Ws-frL9w=sE1W&E;AIWyILv8$^g*g%fMh;*+i~(<6+SIN3Cd|2fSy|k4`4*yI +zxD`2GO?7aNU^!=DLgE)W{;beAb8J-v0$X>)#uo_@$MepCnj6B&kQn*MAQ%a3rZXIq +z`<81UV5b5ic>2e)Agw`TVL9!XtBqRpHS{01n*AOgw1s^wb5@?v6Y~M +zZ$8)sMJ$F`*JDK!_cAhCcj*+K+^Kz@?&r!P>a=M8N;shIDqYY$NQ9OA1|k4l=SlmY0B9XzzdT_Za{#v<+Y{)fWv{feYXssY)tHYE7j +zl`Ga!sF{OeEE_nfCT5zxIe%}Q*~>@<2;I+e!Z-owTTRDSc(gF$?QJMyMCpCj9{8*i9pt= +zAD+h-V(&v-C~lbHFP`!3(JvqXUlsk5PI+{-A-foYA{aFLrBPk(5qfPxi(>%$JT!J% +zJwhUo$|Sbad8#BW8LI-ypkU#`#`J`z<|d{N9C!BVH#)F8@O+zXk;=;ZMIFflE}a!4Uidn9ed +zzWWbVy&CVS8i^z{3eD;rBLG~cGQOQhw#!YQ2Um+=m%wgm6BX)g1Axm9X$x|QKfn4k +zUtXZm+o-S(Uc}r|Ud1)L?xEufRer1biXPIZP(M^?TuMF9zSz!w%WQB4sOryj+MKcX +zO_Sm&@Wuo?N@L;EgBE<=pW6(qt6ak$B!O@4zo~V{Opy3tleg2FE#`}9FSfEuM&gxl +z1twuO_l-Oy(I*I;@_tq)^+pV~u915Wr+R(J$5gQRwQC}sZ86g60^qi^5->zuiFWN>^;=Zkw;vEB +zM-h;al#rAb1`$D8LIIJK9=e9^W@rRKN~BXdq@_DVN?-`-?ryke(D%OYeed@VxIf(W +z%;&7V_KLmFUeB!aJagupEv_(Gf(`9&;=My?1{M)4B@mx``y~{WI>oQnOiV2E@G)weUs;`$EH3u +z&^xVsFvcU;o3UvZjRIy2%YBf;PoLniAVvS+xO;^x6pGl(*_*3O3JG(GG+4rjx_p0h +zC9kB*QSSBGn@Hz0QPsHIOkSb>DKFgc*awGE&Mmzcy@a}QRWrW=QFVF@2k91>P0G(C +zkT^NmOrW;*=@A;Q9-AlN3=OiZ$Hl1ptnc`w!{sRRv)=2dTv?p#n8lk?Yo9x*w1Uem +zx}AMzo5p6J4SF5D(+Pw%Y;HfZe +z&!R%p?~gNPg9t<9C5F3XlLk`aI1u-5zK58N;t>kUXM +z+2xKcA!}u@_V&x9ogK+D#nD+DC!S+Xq~oW)iii#A3rx~*bWXUATboE0+h~NwZ@!U$ +z?7H7o@SZ*I>ff*(!g}06QM^c$OyTVcoXfW|q~Vn(V*<>YpB*03v0>t0~{cpej^32`S}fmx^>dgAt;k}$Jq_m_lY +zd{$x3RW*_E(DBo-@IgF3pxx-yh{zdQIDL`pV2FRl?(k{i2yUF%DoAr+;?GG3;nvRz +zD4=QMQ2Hi3pKp)Osh>rFZTzITSU8uCh@Rs-{tC|~beRHpV@Z4SYXWl=dHn!Tuz&%HaytQ45KU_!T~zR0*8iZrVd89Ht=P`>;&)r9EvryfI*ZTOKY +zK{n%6Z0DCyQe{qXq?P5@i}4zGeupDsLO(Js<`FXm@TSl{Gmq4`?;<<}&S+^t$?Dvy +z_yfaGNfTS!E3b1m#TbP6;c%h +zHqP^RB24#18yP^g7rl_Bj6Z*UtfKn#Vb^)fn7f$xE}gpTp-viY!zstE4k4x?8?3c& +z>&)IF1r?s!E16{F7M6Dy*$<-~6h%y`Ich68B))rpRd;Ro(o83^cAW$ +z)8v7i`8&Hx@cg9p*2IfQ;!x5%1Ed)x6NT@kRL4-M6Dwl|xA!0rTHxlZ#9R?2<01yt +zdtx4EWf|4^VpXjle|#&lTYDn=&QSd$EPNZiuT__^v%CnVH8s5(u2!;*H5f>6V)9eG +zM359>|6*LmqK+}CXBKlHv_Wl6!Eiu5THQv*?BQ1(l}A)P2bhUcStBpw(CNh#1(O?D +z%|1>$PoU8hsmA1eXx$xfdENT)Wd{Rss7cq+^$&Ee&aIhs{FJzpXcqx0Uf7|k3rzDR +zQPTSt>3taD?wC(XeOWBrs$Fh7rFHKiiCctI +zbAtPznw%W>26#x3X(jY%3%o$hAT?|sEEcjbKP2HQIIe0c +zFc(?P_4)M`&p^nu92og5O8pGFtk)#U4qzo#xxSuc{mc*KK26=;Ys9HpQac&|?j9<} +zU4p)gzG18}xWD?1Yvaj9c@^7bl$7uVrE-sbK+d6amtw=IVp9{suO}6L_%+?8j9R0- +z@MC*0Wi!E1o2OZF8bVEHXYfj9h;CMpwJe4br*ijtTb!%eAe(nm7)6Gh!nv;iZCyOX +z0=+kU$v_7;SZJSOe6f}AZ56@oeJ_*{j?iFP)=s&?5A)zUH3_5l>)1{dU9@mnZ_m!_ +zTApl{?K#4o*ReCT60h}xi@3)LgicHYrZFVqR>YOen}QF!v~Sn1rAemMKS=UvUdW3~r%$_Yx*VpVA_v|>keQZ4*EoE%ez_vBMj_(O$z%*2-_oa1y +zqVQZOL=NNehL&BTln#tc23gO=WXccE4CNL^SqSEAGI~?>@{pMkvWnJwa#P9e6|_p9 +zBo)*sfV4eeMO@0D63-ZwCBr&;&|OF;W||(YSVk3_#9(eD_TW$w*V<_R@QxfQG{voSeKZOswSOaGa=2zvIvx;o$CIQ +z(QrYES4JB+ri+Cye;^X22Oqui1*mxUe1$+NR7UWA5}1@=w1;uIedKeuJm%JhL+MLg +z-dsIc?*l2J&-o(JL3}Ayr*A)fseIj +zHZP$>r4K17Z76@jY^y@>IQZ*>G2){H8Olc=_zHHNZDzuY%VPEgB)axAt>RhI+5`K~ +zZ%aNpFFKE3RZiJaVaCm-P^d~?u1^fA)^(jF;EP2&XFXnuQ_8xk$!@h_$g)d>^uv4M +z{1l?P@{1EhZ^1MbcScdxg2o^ +z68Mzbu-~~TGjc?vXyw=zciIX%e-J0p(LL1R#HNmBV{m0nVObC!!a7nD!?pL? +z@$Zdn8QFIwG4mLH3FoEcYBBr>GP*=)F*dCU9;!Ao(Yz^+{y~9nzN%WAcpVp#n$ka- +ze-Ug;EYJ9@ywe^vHuftzE<-}cmse~-O*>!o3x`yvsjB>7Zli4iKIaRTYxV(qtR56> +z>I?Ml4A|`&j6&|MN?V!q%-(U?3*$!$Q!ZwBswo-Cdr4olH#O<*+2$VYUmm0VG86Ja +zjfimhB{e{^KG!^5v`D_YoM$IE@d{%r*zCY@X2%pP8qv#2fzZHsJn21lx<6WPx8JC3 +zv^dFGuNZPrB++xdS^IQ~$G)aTZ7=N8+h(opQ42S1E)Oo_%3^YdcFMX>#>>>C+p^XZ +zJS2f7xuTPiy|D<6bgdc^y!>0*-}2WF$%w#%oMf-u?`DuZ1^#apY(B3E|B%Fdx$T#; +z7?L*%S!Jck`$>piBFJat4?Q+@-3B(zqu1MCcXS!i9NJl~qDlca6{5am>3&cx;l?A8 +z#du=4*K5Q@6k6f)Y~+Onu@{TMwhkUb0X$C}20Vs+A}i(Kf|ge|nqr$ZhN0 +zDrarWxX9*H$`NF4XD)jkDB~TMF +zHlFaFjdw30&*Y;&J#PkfFRQj3TGn7_dD7LliR^%GH0}n#_x$fz&-31_>36((y7hnWf*g3}vK*D*=ldYf&_$F+;7mo8jt??8eEV+6ZsQ=U;? +z!t5V93If=KLt8bJJ8jE@ecOn8p9ZUPCWVv3w(=9H% +zS99+tv690FO^rtr`5H-eAr!5dXLHUiv%U8q1Kd1!oezIWEjP772KJV(=Fh&++oySA42%g&xF9sedXMCahL{q)WQ +z0?|ekDpUJdG%(tBh^eml4k36V`GfQrV$9mKBW=-=?aewvBCFGy>jIW5wNU*Bd>z+4 +zOCw@C-x0zu)d!T)tNOvDU^*`l2z}kc%E|!*0-0Ml7()U654yDiT$=kqC?MqLZ~7ks +z(ETr2_;1Vq)ItTuyl-ctYX&Ia*_qvpdFvmBf1&~7{+s?a&VL#gMHq0}xpAa3fZEvt +zEph{MTf3W{o0%fxqWzgOT9^gYL>JIeTR{JP?$3a3C(zs08_&naP;;97c)Lw$YL;~;vUY-a9!Z-&I +z2*4ANNdfK+AmBI01d0a61%MC$NWW^ph63Oj004W8WB_{r!T0c1LWBgeJ` +zfQ)qlARIsx0Hh62ATV5k(+0j9`c{9|0J%OK0QBskcDevpw=lTjNcF>i79OBj+33Px +p$lCDV^w{Kgb))}cXN3$%0oA>6Mg|4R>N*%cfv|D$vvG28{1-l>vtIxJ + +-- +2.28.0 + diff --git a/patches/mfplat-streaming-support/0047-Report-streams-backwards-and-only-select-one-of-each.patch b/patches/mfplat-streaming-support/0038-Report-streams-backwards-and-only-select-one-of-each.patch similarity index 75% rename from patches/mfplat-streaming-support/0047-Report-streams-backwards-and-only-select-one-of-each.patch rename to patches/mfplat-streaming-support/0038-Report-streams-backwards-and-only-select-one-of-each.patch index 38633bbd..7c2d216c 100644 --- a/patches/mfplat-streaming-support/0047-Report-streams-backwards-and-only-select-one-of-each.patch +++ b/patches/mfplat-streaming-support/0038-Report-streams-backwards-and-only-select-one-of-each.patch @@ -1,28 +1,28 @@ -From cffa1c6ab7784bc9a7d7c411e204d2abb7bbb501 Mon Sep 17 00:00:00 2001 +From 7d34ffde0e719704327c261443d0e8dbead7d79f Mon Sep 17 00:00:00 2001 From: Derek Lesho Date: Tue, 5 May 2020 15:35:16 -0500 -Subject: [PATCH] Report streams backwards and only select one of each stream - type. +Subject: [PATCH 38/52] Report streams backwards and only select one of each + stream type. --- dlls/winegstreamer/media_source.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c -index 0165ea1570..3807a37555 100644 +index f0a654d1fa4..14b7571b80a 100644 --- a/dlls/winegstreamer/media_source.c +++ b/dlls/winegstreamer/media_source.c -@@ -1438,6 +1438,7 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, enum source_t - source_descs[type].bytestream_caps); +@@ -1630,6 +1630,7 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_ + GST_STATIC_CAPS_ANY); struct media_source *object = heap_alloc_zero(sizeof(*object)); + BOOL video_selected = FALSE, audio_selected = FALSE; - GList *demuxer_list_one, *demuxer_list_two; - GstElementFactory *demuxer_factory = NULL; IMFStreamDescriptor **descriptors = NULL; -@@ -1535,15 +1536,34 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, enum source_t + HRESULT hr; + int ret; +@@ -1717,15 +1718,34 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_ descriptors = heap_alloc(object->stream_count * sizeof(IMFStreamDescriptor*)); - for (i = 0; i < object->stream_count; i++) + for (unsigned int i = 0; i < object->stream_count; i++) { - IMFMediaStream_GetStreamDescriptor(&object->streams[i]->IMFMediaStream_iface, &descriptors[i]); + IMFMediaStream_GetStreamDescriptor(&object->streams[i]->IMFMediaStream_iface, &descriptors[object->stream_count - 1 - i]); @@ -32,7 +32,7 @@ index 0165ea1570..3807a37555 100644 goto fail; + /* Select one of each major type. */ - for (i = 0; i < object->stream_count; i++) + for (unsigned int i = 0; i < object->stream_count; i++) { - IMFPresentationDescriptor_SelectStream(object->pres_desc, i); + IMFMediaTypeHandler *handler; diff --git a/patches/mfplat-streaming-support/0048-winegstreamer-Implement-IMFMediaSource-Stop.patch b/patches/mfplat-streaming-support/0039-winegstreamer-Implement-IMFMediaSource-Stop.patch similarity index 74% rename from patches/mfplat-streaming-support/0048-winegstreamer-Implement-IMFMediaSource-Stop.patch rename to patches/mfplat-streaming-support/0039-winegstreamer-Implement-IMFMediaSource-Stop.patch index 0b976f15..eecdee86 100644 --- a/patches/mfplat-streaming-support/0048-winegstreamer-Implement-IMFMediaSource-Stop.patch +++ b/patches/mfplat-streaming-support/0039-winegstreamer-Implement-IMFMediaSource-Stop.patch @@ -1,18 +1,18 @@ -From fac27f9bb91686dddfc85d367514b21db135b6a8 Mon Sep 17 00:00:00 2001 +From 0ccd1eb9ac722329ed137b49a260a0458ca86a0c Mon Sep 17 00:00:00 2001 From: Derek Lesho Date: Thu, 7 May 2020 13:09:47 -0500 -Subject: [PATCH] winegstreamer: Implement IMFMediaSource::Stop. +Subject: [PATCH 39/52] winegstreamer: Implement IMFMediaSource::Stop. Signed-off-by: Derek Lesho --- - dlls/winegstreamer/media_source.c | 32 +++++++++++++++++++++++++++++-- - 1 file changed, 30 insertions(+), 2 deletions(-) + dlls/winegstreamer/media_source.c | 30 ++++++++++++++++++++++++++++-- + 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c -index 3807a37555..517e5ee677 100644 +index 14b7571b80a..a162bad99d8 100644 --- a/dlls/winegstreamer/media_source.c +++ b/dlls/winegstreamer/media_source.c -@@ -60,6 +60,7 @@ struct media_stream +@@ -68,6 +68,7 @@ struct media_stream enum source_async_op { SOURCE_ASYNC_START, @@ -20,15 +20,16 @@ index 3807a37555..517e5ee677 100644 SOURCE_ASYNC_REQUEST_SAMPLE, }; -@@ -328,6 +329,25 @@ static HRESULT start_pipeline(struct media_source *source, struct source_async_c +@@ -360,6 +361,23 @@ static HRESULT start_pipeline(struct media_source *source, struct source_async_c return S_OK; } +static void stop_pipeline(struct media_source *source) +{ -+ unsigned int i; ++ /* TODO: seek to beginning */ ++ gst_element_set_state(source->container, GST_STATE_PAUSED); + -+ for (i = 0; i < source->stream_count; i++) ++ for (unsigned int i = 0; i < source->stream_count; i++) + { + struct media_stream *stream = source->streams[i]; + if (stream->state != STREAM_INACTIVE) @@ -38,15 +39,12 @@ index 3807a37555..517e5ee677 100644 + IMFMediaEventQueue_QueueEventParamVar(source->event_queue, MESourceStopped, &GUID_NULL, S_OK, NULL); + + source->state = SOURCE_STOPPED; -+ -+ gst_element_set_state(source->container, GST_STATE_READY); -+ gst_element_get_state(source->container, NULL, NULL, -1); +} + static void dispatch_end_of_presentation(struct media_source *source) { PROPVARIANT empty = {.vt = VT_EMPTY}; -@@ -419,6 +439,9 @@ static HRESULT WINAPI source_async_commands_Invoke(IMFAsyncCallback *iface, IMFA +@@ -451,6 +469,9 @@ static HRESULT WINAPI source_async_commands_Invoke(IMFAsyncCallback *iface, IMFA case SOURCE_ASYNC_START: start_pipeline(source, command); break; @@ -56,7 +54,7 @@ index 3807a37555..517e5ee677 100644 case SOURCE_ASYNC_REQUEST_SAMPLE: wait_on_sample(command->u.request_sample.stream, command->u.request_sample.token); break; -@@ -1249,13 +1272,18 @@ static HRESULT WINAPI media_source_Start(IMFMediaSource *iface, IMFPresentationD +@@ -1319,13 +1340,18 @@ static HRESULT WINAPI media_source_Start(IMFMediaSource *iface, IMFPresentationD static HRESULT WINAPI media_source_Stop(IMFMediaSource *iface) { struct media_source *source = impl_from_IMFMediaSource(iface); diff --git a/patches/mfplat-streaming-support/0049-winegstreamer-Introduce-MPEG-4-Section-2-video-decod.patch b/patches/mfplat-streaming-support/0040-winegstreamer-Introduce-MPEG-4-Section-2-video-decod.patch similarity index 78% rename from patches/mfplat-streaming-support/0049-winegstreamer-Introduce-MPEG-4-Section-2-video-decod.patch rename to patches/mfplat-streaming-support/0040-winegstreamer-Introduce-MPEG-4-Section-2-video-decod.patch index 2d4dce7c..624d26a3 100644 --- a/patches/mfplat-streaming-support/0049-winegstreamer-Introduce-MPEG-4-Section-2-video-decod.patch +++ b/patches/mfplat-streaming-support/0040-winegstreamer-Introduce-MPEG-4-Section-2-video-decod.patch @@ -1,7 +1,7 @@ -From 6f5d0e6c4694d6dab828318998ed6f5c1c33b27a Mon Sep 17 00:00:00 2001 +From aa97104ccc89cd65593354eb51c480454f17e2dd Mon Sep 17 00:00:00 2001 From: Derek Lesho Date: Mon, 11 May 2020 16:05:50 -0500 -Subject: [PATCH 49/54] winegstreamer: Introduce MPEG-4 Section-2 video +Subject: [PATCH 40/52] winegstreamer: Introduce MPEG-4 Section-2 video decoder. Signed-off-by: Derek Lesho @@ -14,22 +14,22 @@ Signed-off-by: Derek Lesho 5 files changed, 52 insertions(+) diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h -index b855d650dc..6dc90e2881 100644 +index c41f231f35f..b609afa555d 100644 --- a/dlls/winegstreamer/gst_private.h +++ b/dlls/winegstreamer/gst_private.h -@@ -67,6 +67,7 @@ enum decoder_type +@@ -68,6 +68,7 @@ enum decoder_type DECODER_TYPE_H264, DECODER_TYPE_AAC, DECODER_TYPE_WMV, + DECODER_TYPE_M4S2, }; - HRESULT generic_decoder_construct(REFIID riid, void **obj, enum decoder_type); - enum source_type + HRESULT generic_decoder_construct(REFIID riid, void **obj, enum decoder_type) DECLSPEC_HIDDEN; + HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj) DECLSPEC_HIDDEN; diff --git a/dlls/winegstreamer/mf_decode.c b/dlls/winegstreamer/mf_decode.c -index c7e1bfb1a9..633a468ed3 100644 +index a86e9db410e..c5d9cbad392 100644 --- a/dlls/winegstreamer/mf_decode.c +++ b/dlls/winegstreamer/mf_decode.c -@@ -31,6 +31,9 @@ const GUID *aac_output_types[] = {&MFAudioFormat_Float, &MFAudioFormat_PCM}; +@@ -32,6 +32,9 @@ const GUID *aac_output_types[] = {&MFAudioFormat_Float, &MFAudioFormat_PCM}; const GUID *wmv_input_types[] = {&MFVideoFormat_WMV3, &MFVideoFormat_WVC1}; const GUID *wmv_output_types[] = {&MFVideoFormat_NV12, &MFVideoFormat_YV12, &MFVideoFormat_YUY2, &MFVideoFormat_UYVY, &MFVideoFormat_YVYU, &MFVideoFormat_NV11, &MFVideoFormat_RGB32, &MFVideoFormat_RGB24, &MFVideoFormat_RGB555, &MFVideoFormat_RGB8}; @@ -39,7 +39,7 @@ index c7e1bfb1a9..633a468ed3 100644 static struct decoder_desc { const GUID *major_type; -@@ -60,6 +63,13 @@ static struct decoder_desc +@@ -61,6 +64,13 @@ static struct decoder_desc ARRAY_SIZE(wmv_input_types), wmv_output_types, ARRAY_SIZE(wmv_output_types), @@ -54,10 +54,10 @@ index c7e1bfb1a9..633a468ed3 100644 }; diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c -index 161c8032a7..e0da02074e 100644 +index 429a2cfda1c..5fe7ac4d354 100644 --- a/dlls/winegstreamer/mfplat.c +++ b/dlls/winegstreamer/mfplat.c -@@ -419,6 +419,11 @@ static HRESULT wmv_decoder_create(REFIID riid, void **ret) +@@ -421,6 +421,11 @@ static HRESULT wmv_decoder_create(REFIID riid, void **ret) return generic_decoder_construct(riid, ret, DECODER_TYPE_WMV); } @@ -66,18 +66,18 @@ index 161c8032a7..e0da02074e 100644 + return generic_decoder_construct(riid, ret, DECODER_TYPE_M4S2); +} + - static HRESULT mp4_stream_handler_create(REFIID riid, void **ret) - { - return container_stream_handler_construct(riid, ret, SOURCE_TYPE_MPEG_4); -@@ -442,6 +447,7 @@ class_objects[] = + static GUID CLSID_CColorConvertDMO = {0x98230571,0x0087,0x4204,{0xb0,0x20,0x32,0x82,0x53,0x8e,0x57,0xd3}}; + + static const struct class_object +@@ -435,6 +440,7 @@ class_objects[] = { &CLSID_CMSH264DecoderMFT, &h264_decoder_create }, { &CLSID_CMSAACDecMFT, &aac_decoder_create }, { &CLSID_CWMVDecMediaObject, &wmv_decoder_create }, + { &CLSID_CMpeg4sDecMFT, m4s2_decoder_create }, - { &CLSID_MPEG4ByteStreamHandler, &mp4_stream_handler_create }, - { &CLSID_ASFByteStreamHandler, &asf_stream_handler_create }, { &CLSID_CColorConvertDMO, &color_converter_create }, -@@ -546,6 +552,22 @@ const GUID *wmv_decoder_output_types[] = + }; + +@@ -534,6 +540,22 @@ const GUID *wmv_decoder_output_types[] = &MFVideoFormat_RGB8, }; @@ -100,7 +100,7 @@ index 161c8032a7..e0da02074e 100644 static const struct mft { const GUID *clsid; -@@ -608,6 +630,18 @@ mfts[] = +@@ -596,6 +618,18 @@ mfts[] = ARRAY_SIZE(wmv_decoder_output_types), wmv_decoder_output_types, NULL @@ -120,7 +120,7 @@ index 161c8032a7..e0da02074e 100644 }; diff --git a/dlls/winegstreamer/winegstreamer_classes.idl b/dlls/winegstreamer/winegstreamer_classes.idl -index d933d40cfd..3a3daad3ab 100644 +index 1556b6cff9f..5969eaa591a 100644 --- a/dlls/winegstreamer/winegstreamer_classes.idl +++ b/dlls/winegstreamer/winegstreamer_classes.idl @@ -74,6 +74,12 @@ coclass CMSH264DecoderMFT { } @@ -135,13 +135,13 @@ index d933d40cfd..3a3daad3ab 100644 + [ threading(both), - uuid(41457294-644c-4298-a28a-BD69F2C0CF3B) + uuid(82d353df-90bd-4382-8bc2-3f6192b76e34) diff --git a/include/mfidl.idl b/include/mfidl.idl -index ce3707ba50..35dd4c2f96 100644 +index 0885e4e3007..a344986a7aa 100644 --- a/include/mfidl.idl +++ b/include/mfidl.idl -@@ -1244,5 +1244,6 @@ cpp_quote("EXTERN_GUID(CLSID_VideoProcessorMFT, 0x88753b26, 0x5b24, 0x49bd, 0xb2 - cpp_quote("EXTERN_GUID(CLSID_MPEG4ByteStreamHandler, 0x271c3902, 0x6095, 0x4c45, 0xa2, 0x2f, 0x20, 0x09, 0x18, 0x16, 0xee, 0x9e);") +@@ -1243,5 +1243,6 @@ cpp_quote("EXTERN_GUID(MF_ACTIVATE_CUSTOM_VIDEO_PRESENTER_FLAGS, 0xba491366, 0xb + cpp_quote("EXTERN_GUID(CLSID_VideoProcessorMFT, 0x88753b26, 0x5b24, 0x49bd, 0xb2, 0xe7, 0xc, 0x44, 0x5c, 0x78, 0xc9, 0x82);") cpp_quote("EXTERN_GUID(CLSID_CMSH264DecoderMFT, 0x62ce7e72, 0x4c71, 0x4d20, 0xb1, 0x5d, 0x45, 0x28, 0x31, 0xa8, 0x7d, 0x9d);") cpp_quote("EXTERN_GUID(CLSID_CMSAACDecMFT, 0x32d186a7, 0x218f, 0x4c75, 0x88, 0x76, 0xdd, 0x77, 0x27, 0x3a, 0x89, 0x99);") +cpp_quote("EXTERN_GUID(CLSID_CMpeg4sDecMFT, 0x5686a0d9, 0xfe39, 0x409f, 0x9d, 0xff, 0x3f, 0xdb, 0xc8, 0x49, 0xf9, 0xf5);") diff --git a/patches/mfplat-streaming-support/0050-HACK-Switch-between-all-selection-streams-on-MF_SOUR.patch b/patches/mfplat-streaming-support/0041-HACK-Switch-between-all-selection-streams-on-MF_SOUR.patch similarity index 91% rename from patches/mfplat-streaming-support/0050-HACK-Switch-between-all-selection-streams-on-MF_SOUR.patch rename to patches/mfplat-streaming-support/0041-HACK-Switch-between-all-selection-streams-on-MF_SOUR.patch index d17ead53..50bdd6e1 100644 --- a/patches/mfplat-streaming-support/0050-HACK-Switch-between-all-selection-streams-on-MF_SOUR.patch +++ b/patches/mfplat-streaming-support/0041-HACK-Switch-between-all-selection-streams-on-MF_SOUR.patch @@ -1,7 +1,7 @@ -From 3450bedc5c9b3e80be234b30191e3e604d24495d Mon Sep 17 00:00:00 2001 +From 3babfd1eb77488359a9882eee9619689198c84de Mon Sep 17 00:00:00 2001 From: Derek Lesho Date: Tue, 12 May 2020 16:48:52 -0500 -Subject: [PATCH 50/54] HACK: Switch between all selection streams on +Subject: [PATCH 41/52] HACK: Switch between all selection streams on MF_SOURCE_READER_ANY_STREAM. --- @@ -9,7 +9,7 @@ Subject: [PATCH 50/54] HACK: Switch between all selection streams on 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/dlls/mfreadwrite/reader.c b/dlls/mfreadwrite/reader.c -index f8c03e62d3..423250e3cb 100644 +index f8c03e62d35..423250e3cb7 100644 --- a/dlls/mfreadwrite/reader.c +++ b/dlls/mfreadwrite/reader.c @@ -1045,7 +1045,29 @@ static HRESULT source_reader_get_stream_read_index(struct source_reader *reader, diff --git a/patches/mfplat-streaming-support/0042-Set-BPS-on-AAC.patch b/patches/mfplat-streaming-support/0042-Set-BPS-on-AAC.patch deleted file mode 100644 index 50c999ae..00000000 --- a/patches/mfplat-streaming-support/0042-Set-BPS-on-AAC.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 6e87e29160026d27f950fce99f3a5a044add84af Mon Sep 17 00:00:00 2001 -From: Derek Lesho -Date: Fri, 3 Apr 2020 13:09:30 -0500 -Subject: [PATCH 42/54] Set BPS on AAC. - ---- - dlls/winegstreamer/mfplat.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c -index e1735a5f82..780008face 100644 ---- a/dlls/winegstreamer/mfplat.c -+++ b/dlls/winegstreamer/mfplat.c -@@ -916,6 +916,7 @@ static IMFMediaType* transform_to_media_type(GstCaps *caps) - struct aac_user_data *user_data = NULL; - - IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFAudioFormat_AAC); -+ IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_BITS_PER_SAMPLE, 16); - - codec_data = gst_structure_get_value(info, "codec_data"); - if (codec_data) --- -2.28.0 - diff --git a/patches/mfplat-streaming-support/0051-winegstreamer-Introduce-WMA-audio-decoder.patch b/patches/mfplat-streaming-support/0042-winegstreamer-Introduce-WMA-audio-decoder.patch similarity index 85% rename from patches/mfplat-streaming-support/0051-winegstreamer-Introduce-WMA-audio-decoder.patch rename to patches/mfplat-streaming-support/0042-winegstreamer-Introduce-WMA-audio-decoder.patch index 3ef5c619..cf89350a 100644 --- a/patches/mfplat-streaming-support/0051-winegstreamer-Introduce-WMA-audio-decoder.patch +++ b/patches/mfplat-streaming-support/0042-winegstreamer-Introduce-WMA-audio-decoder.patch @@ -1,7 +1,7 @@ -From 39e3081768b545c0c4f3f16f4b7d3219d0b249b1 Mon Sep 17 00:00:00 2001 +From 311f686ac23db13323f18fa18b8e8c2b9b9143cd Mon Sep 17 00:00:00 2001 From: Derek Lesho Date: Tue, 12 May 2020 16:50:41 -0500 -Subject: [PATCH 51/54] winegstreamer: Introduce WMA audio decoder. +Subject: [PATCH 42/52] winegstreamer: Introduce WMA audio decoder. Signed-off-by: Derek Lesho --- @@ -13,22 +13,22 @@ Signed-off-by: Derek Lesho 5 files changed, 51 insertions(+), 1 deletion(-) diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h -index 6dc90e2881..af2134078a 100644 +index b609afa555d..8e75beb82dd 100644 --- a/dlls/winegstreamer/gst_private.h +++ b/dlls/winegstreamer/gst_private.h -@@ -67,6 +67,7 @@ enum decoder_type +@@ -68,6 +68,7 @@ enum decoder_type DECODER_TYPE_H264, DECODER_TYPE_AAC, DECODER_TYPE_WMV, + DECODER_TYPE_WMA, DECODER_TYPE_M4S2, }; - HRESULT generic_decoder_construct(REFIID riid, void **obj, enum decoder_type); + HRESULT generic_decoder_construct(REFIID riid, void **obj, enum decoder_type) DECLSPEC_HIDDEN; diff --git a/dlls/winegstreamer/mf_decode.c b/dlls/winegstreamer/mf_decode.c -index 633a468ed3..3d314eaab4 100644 +index c5d9cbad392..7ce72a9a6a3 100644 --- a/dlls/winegstreamer/mf_decode.c +++ b/dlls/winegstreamer/mf_decode.c -@@ -31,6 +31,9 @@ const GUID *aac_output_types[] = {&MFAudioFormat_Float, &MFAudioFormat_PCM}; +@@ -32,6 +32,9 @@ const GUID *aac_output_types[] = {&MFAudioFormat_Float, &MFAudioFormat_PCM}; const GUID *wmv_input_types[] = {&MFVideoFormat_WMV3, &MFVideoFormat_WVC1}; const GUID *wmv_output_types[] = {&MFVideoFormat_NV12, &MFVideoFormat_YV12, &MFVideoFormat_YUY2, &MFVideoFormat_UYVY, &MFVideoFormat_YVYU, &MFVideoFormat_NV11, &MFVideoFormat_RGB32, &MFVideoFormat_RGB24, &MFVideoFormat_RGB555, &MFVideoFormat_RGB8}; @@ -38,7 +38,7 @@ index 633a468ed3..3d314eaab4 100644 const GUID *m4s2_input_types[] = {&MFVideoFormat_MPEG2}; const GUID *m4s2_output_types[] = {&MFVideoFormat_I420, &MFVideoFormat_IYUV, &MFVideoFormat_NV12, &MFVideoFormat_YUY2, &MFVideoFormat_YV12}; -@@ -64,6 +67,13 @@ static struct decoder_desc +@@ -65,6 +68,13 @@ static struct decoder_desc wmv_output_types, ARRAY_SIZE(wmv_output_types), }, @@ -53,10 +53,10 @@ index 633a468ed3..3d314eaab4 100644 &MFMediaType_Video, m4s2_input_types, diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c -index e0da02074e..bcfcd398ec 100644 +index 5fe7ac4d354..28c9beb4649 100644 --- a/dlls/winegstreamer/mfplat.c +++ b/dlls/winegstreamer/mfplat.c -@@ -419,6 +419,11 @@ static HRESULT wmv_decoder_create(REFIID riid, void **ret) +@@ -421,6 +421,11 @@ static HRESULT wmv_decoder_create(REFIID riid, void **ret) return generic_decoder_construct(riid, ret, DECODER_TYPE_WMV); } @@ -68,15 +68,15 @@ index e0da02074e..bcfcd398ec 100644 static HRESULT m4s2_decoder_create(REFIID riid, void **ret) { return generic_decoder_construct(riid, ret, DECODER_TYPE_M4S2); -@@ -447,6 +452,7 @@ class_objects[] = +@@ -440,6 +445,7 @@ class_objects[] = { &CLSID_CMSH264DecoderMFT, &h264_decoder_create }, { &CLSID_CMSAACDecMFT, &aac_decoder_create }, { &CLSID_CWMVDecMediaObject, &wmv_decoder_create }, + { &CLSID_CWMADecMediaObject, &wma_decoder_create }, { &CLSID_CMpeg4sDecMFT, m4s2_decoder_create }, - { &CLSID_MPEG4ByteStreamHandler, &mp4_stream_handler_create }, - { &CLSID_ASFByteStreamHandler, &asf_stream_handler_create }, -@@ -552,6 +558,20 @@ const GUID *wmv_decoder_output_types[] = + { &CLSID_CColorConvertDMO, &color_converter_create }, + }; +@@ -540,6 +546,20 @@ const GUID *wmv_decoder_output_types[] = &MFVideoFormat_RGB8, }; @@ -97,7 +97,7 @@ index e0da02074e..bcfcd398ec 100644 static WCHAR m4s2decoderW[] = {'M','p','e','g','4','s',' ','D','e','c','o','d','e','r',' ','M','F','T',0}; const GUID *m4s2_decoder_input_types[] = -@@ -631,6 +651,18 @@ mfts[] = +@@ -619,6 +639,18 @@ mfts[] = wmv_decoder_output_types, NULL }, @@ -117,10 +117,10 @@ index e0da02074e..bcfcd398ec 100644 &CLSID_CMpeg4sDecMFT, &MFT_CATEGORY_VIDEO_DECODER, diff --git a/dlls/winegstreamer/winegstreamer_classes.idl b/dlls/winegstreamer/winegstreamer_classes.idl -index 3a3daad3ab..9f210fbbf7 100644 +index 5969eaa591a..c014d359a39 100644 --- a/dlls/winegstreamer/winegstreamer_classes.idl +++ b/dlls/winegstreamer/winegstreamer_classes.idl -@@ -92,6 +92,12 @@ coclass ASFByteStreamHandler {} +@@ -86,6 +86,12 @@ coclass CMpeg4sDecMFT { } ] coclass CLSID_CWMVDecMediaObject {} @@ -134,10 +134,10 @@ index 3a3daad3ab..9f210fbbf7 100644 threading(both), uuid(98230571-0087-4204-b020-3282538e57d3) diff --git a/include/mfidl.idl b/include/mfidl.idl -index 35dd4c2f96..3c11402931 100644 +index a344986a7aa..5154b798dfb 100644 --- a/include/mfidl.idl +++ b/include/mfidl.idl -@@ -1246,4 +1246,5 @@ cpp_quote("EXTERN_GUID(CLSID_CMSH264DecoderMFT, 0x62ce7e72, 0x4c71, 0x4d20, 0xb1 +@@ -1245,4 +1245,5 @@ cpp_quote("EXTERN_GUID(CLSID_CMSH264DecoderMFT, 0x62ce7e72, 0x4c71, 0x4d20, 0xb1 cpp_quote("EXTERN_GUID(CLSID_CMSAACDecMFT, 0x32d186a7, 0x218f, 0x4c75, 0x88, 0x76, 0xdd, 0x77, 0x27, 0x3a, 0x89, 0x99);") cpp_quote("EXTERN_GUID(CLSID_CMpeg4sDecMFT, 0x5686a0d9, 0xfe39, 0x409f, 0x9d, 0xff, 0x3f, 0xdb, 0xc8, 0x49, 0xf9, 0xf5);") cpp_quote("EXTERN_GUID(CLSID_ASFByteStreamHandler, 0x41457294, 0x644c, 0x4298, 0xa2, 0x8a, 0xbd, 0x69, 0xf2, 0xc0, 0xcf, 0x3b);") diff --git a/patches/mfplat-streaming-support/0043-Support-stereo-down-folding.patch b/patches/mfplat-streaming-support/0043-Support-stereo-down-folding.patch new file mode 100644 index 00000000..4b48b2c8 --- /dev/null +++ b/patches/mfplat-streaming-support/0043-Support-stereo-down-folding.patch @@ -0,0 +1,29 @@ +From f72479c9e576a766f38bcd9c8c377ee53adbdfe2 Mon Sep 17 00:00:00 2001 +From: Derek Lesho +Date: Wed, 13 May 2020 12:32:42 -0500 +Subject: [PATCH 43/52] Support stereo down folding. + +--- + dlls/winegstreamer/mf_decode.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/dlls/winegstreamer/mf_decode.c b/dlls/winegstreamer/mf_decode.c +index 7ce72a9a6a3..00f69aa76cc 100644 +--- a/dlls/winegstreamer/mf_decode.c ++++ b/dlls/winegstreamer/mf_decode.c +@@ -327,9 +327,11 @@ static HRESULT WINAPI mf_decoder_GetOutputAvailableType(IMFTransform *iface, DWO + + copy_attr(output_type, decoder->input_type, &MF_MT_FRAME_SIZE); + copy_attr(output_type, decoder->input_type, &MF_MT_FRAME_RATE); +- copy_attr(output_type, decoder->input_type, &MF_MT_AUDIO_NUM_CHANNELS); + copy_attr(output_type, decoder->input_type, &MF_MT_AUDIO_SAMPLES_PER_SECOND); + ++ /* TODO: support both stereo folding and matching channels */ ++ IMFMediaType_SetUINT32(output_type, &MF_MT_AUDIO_NUM_CHANNELS, 2); ++ + if (FAILED(hr = IMFMediaType_SetGUID(output_type, &MF_MT_MAJOR_TYPE, decoder_descs[decoder->type].major_type))) + { + IMFMediaType_Release(output_type); +-- +2.28.0 + diff --git a/patches/mfplat-streaming-support/0044-winegstreamer-Implement-MF_SD_LANGUAGE.patch b/patches/mfplat-streaming-support/0044-winegstreamer-Implement-MF_SD_LANGUAGE.patch new file mode 100644 index 00000000..3df79fdc --- /dev/null +++ b/patches/mfplat-streaming-support/0044-winegstreamer-Implement-MF_SD_LANGUAGE.patch @@ -0,0 +1,64 @@ +From ada0cb5f81f858b27b3c52f6c10097a7444b8793 Mon Sep 17 00:00:00 2001 +From: Derek Lesho +Date: Tue, 11 Aug 2020 13:41:15 -0500 +Subject: [PATCH 44/52] winegstreamer: Implement MF_SD_LANGUAGE. + +Signed-off-by: Derek Lesho +--- + dlls/winegstreamer/media_source.c | 33 +++++++++++++++++++++++++++++-- + 1 file changed, 31 insertions(+), 2 deletions(-) + +diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c +index a162bad99d8..07c16ac8a07 100644 +--- a/dlls/winegstreamer/media_source.c ++++ b/dlls/winegstreamer/media_source.c +@@ -1796,8 +1796,12 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_ + /* TODO: consider streams which don't start at T=0 */ + for (unsigned int i = 0; i < object->stream_count; i++) + { +- GstQuery *query = gst_query_new_duration(GST_FORMAT_TIME); +- if (gst_pad_query(object->streams[i]->their_src, query)) ++ struct media_stream *stream = object->streams[i]; ++ GstEvent *tag_event; ++ GstQuery *query; ++ ++ query = gst_query_new_duration(GST_FORMAT_TIME); ++ if (gst_pad_query(stream->their_src, query)) + { + gint64 stream_pres_time; + gst_query_parse_duration(query, NULL, &stream_pres_time); +@@ -1811,6 +1815,31 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_ + { + WARN("Unable to get presentation time of stream %u\n", i); + } ++ ++ tag_event = gst_pad_get_sticky_event(stream->their_src, GST_EVENT_TAG, 0); ++ if (tag_event) ++ { ++ GstTagList *tag_list; ++ gchar *language_code = NULL; ++ ++ gst_event_parse_tag(tag_event, &tag_list); ++ ++ gst_tag_list_get_string(tag_list, "language-code", &language_code); ++ if (language_code) ++ { ++ DWORD char_count = MultiByteToWideChar(CP_UTF8, 0, language_code, -1, NULL, 0); ++ if (char_count) ++ { ++ WCHAR *language_codeW = heap_alloc(char_count * sizeof(WCHAR)); ++ MultiByteToWideChar(CP_UTF8, 0, language_code, -1, language_codeW, char_count); ++ IMFStreamDescriptor_SetString(stream->descriptor, &MF_SD_LANGUAGE, language_codeW); ++ heap_free(language_codeW); ++ } ++ g_free(language_code); ++ } ++ ++ gst_event_unref(tag_event); ++ } + } + + if (object->stream_count) +-- +2.28.0 + diff --git a/patches/mfplat-streaming-support/0001-Revert-mf-topoloader-Add-a-structure-for-iterative-b.patch b/patches/mfplat-streaming-support/0045-Revert-mf-topoloader-Add-a-structure-for-iterative-b.patch similarity index 96% rename from patches/mfplat-streaming-support/0001-Revert-mf-topoloader-Add-a-structure-for-iterative-b.patch rename to patches/mfplat-streaming-support/0045-Revert-mf-topoloader-Add-a-structure-for-iterative-b.patch index 945020f3..ca35ea59 100644 --- a/patches/mfplat-streaming-support/0001-Revert-mf-topoloader-Add-a-structure-for-iterative-b.patch +++ b/patches/mfplat-streaming-support/0045-Revert-mf-topoloader-Add-a-structure-for-iterative-b.patch @@ -1,7 +1,7 @@ -From ac9dd9bf46de1056dd26a3230bfd885d2962c8aa Mon Sep 17 00:00:00 2001 -From: Alistair Leslie-Hughes -Date: Tue, 11 Aug 2020 09:26:57 +1000 -Subject: [PATCH 01/54] Revert "mf/topoloader: Add a structure for iterative +From dfa7779e8abad5caf9beeac2c459e074bc05dbe2 Mon Sep 17 00:00:00 2001 +From: Derek Lesho +Date: Tue, 11 Aug 2020 15:58:42 -0500 +Subject: [PATCH 45/52] Revert "mf/topoloader: Add a structure for iterative branch resolution." This reverts commit e308d81a617632fe0fedd243952f79e8d9ec05b4. @@ -11,7 +11,7 @@ This reverts commit e308d81a617632fe0fedd243952f79e8d9ec05b4. 2 files changed, 4 insertions(+), 143 deletions(-) diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c -index f01385cc46..aa2c5199b9 100644 +index f01385cc46c..aa2c5199b95 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -1400,7 +1400,6 @@ static void test_topology_loader(void) @@ -45,7 +45,7 @@ index f01385cc46..aa2c5199b9 100644 ok(full_topology != topology, "Unexpected instance.\n"); diff --git a/dlls/mf/topology.c b/dlls/mf/topology.c -index 8032e438b7..840f1bd25f 100644 +index 8032e438b73..840f1bd25f4 100644 --- a/dlls/mf/topology.c +++ b/dlls/mf/topology.c @@ -1935,41 +1935,17 @@ static ULONG WINAPI topology_loader_Release(IMFTopoLoader *iface) diff --git a/patches/mfplat-streaming-support/0002-Revert-mf-topoloader-Clone-source-nodes-as-a-first-l.patch b/patches/mfplat-streaming-support/0046-Revert-mf-topoloader-Clone-source-nodes-as-a-first-l.patch similarity index 92% rename from patches/mfplat-streaming-support/0002-Revert-mf-topoloader-Clone-source-nodes-as-a-first-l.patch rename to patches/mfplat-streaming-support/0046-Revert-mf-topoloader-Clone-source-nodes-as-a-first-l.patch index fb456658..f3cef22e 100644 --- a/patches/mfplat-streaming-support/0002-Revert-mf-topoloader-Clone-source-nodes-as-a-first-l.patch +++ b/patches/mfplat-streaming-support/0046-Revert-mf-topoloader-Clone-source-nodes-as-a-first-l.patch @@ -1,7 +1,7 @@ -From f02867e2a1129f7aef4488db827fc52a6131b3d4 Mon Sep 17 00:00:00 2001 -From: Alistair Leslie-Hughes -Date: Tue, 11 Aug 2020 09:26:59 +1000 -Subject: [PATCH 02/54] Revert "mf/topoloader: Clone source nodes as a first +From 536cc47d3eaa127969d6a3137e28c7a388e54a58 Mon Sep 17 00:00:00 2001 +From: Derek Lesho +Date: Tue, 11 Aug 2020 15:59:04 -0500 +Subject: [PATCH 46/52] Revert "mf/topoloader: Clone source nodes as a first layer of resulting topology." This reverts commit 16d44b61d15193905ef40661bc1547cb45e7b019. @@ -10,7 +10,7 @@ This reverts commit 16d44b61d15193905ef40661bc1547cb45e7b019. 1 file changed, 4 insertions(+), 57 deletions(-) diff --git a/dlls/mf/topology.c b/dlls/mf/topology.c -index 840f1bd25f..8522f56969 100644 +index 840f1bd25f4..8522f569691 100644 --- a/dlls/mf/topology.c +++ b/dlls/mf/topology.c @@ -1933,40 +1933,9 @@ static ULONG WINAPI topology_loader_Release(IMFTopoLoader *iface) diff --git a/patches/mfplat-streaming-support/0046-Set-wait-on-eos-to-allow-other-streams-to-continue-w.patch b/patches/mfplat-streaming-support/0046-Set-wait-on-eos-to-allow-other-streams-to-continue-w.patch deleted file mode 100644 index 8bbb6929..00000000 --- a/patches/mfplat-streaming-support/0046-Set-wait-on-eos-to-allow-other-streams-to-continue-w.patch +++ /dev/null @@ -1,25 +0,0 @@ -From c68cf22e60e000f279ab7f2cc8c707447d9795f3 Mon Sep 17 00:00:00 2001 -From: Derek Lesho -Date: Mon, 4 May 2020 12:40:56 -0500 -Subject: [PATCH] Set "wait-on-eos" to allow other streams to continue while - appsink buffers. - ---- - dlls/winegstreamer/media_source.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c -index a3f76518eb..0165ea1570 100644 ---- a/dlls/winegstreamer/media_source.c -+++ b/dlls/winegstreamer/media_source.c -@@ -1042,6 +1042,7 @@ static HRESULT media_stream_constructor(struct media_source *source, GstPad *pad - g_object_set(object->appsink, "emit-signals", TRUE, NULL); - g_object_set(object->appsink, "sync", FALSE, NULL); - g_object_set(object->appsink, "async", FALSE, NULL); /* <- This allows us interact with the bin w/o prerolling */ -+ g_object_set(object->appsink, "wait-on-eos", FALSE, NULL); - g_signal_connect(object->appsink, "new-sample", G_CALLBACK(stream_new_sample_wrapper), object); - - if (FAILED(hr = media_stream_align_with_mf(object, &stream_type))) --- -2.28.0 - diff --git a/patches/mfplat-streaming-support/0003-Revert-mf-topoloader-Switch-to-public-interface-for-.patch b/patches/mfplat-streaming-support/0047-Revert-mf-topoloader-Switch-to-public-interface-for-.patch similarity index 91% rename from patches/mfplat-streaming-support/0003-Revert-mf-topoloader-Switch-to-public-interface-for-.patch rename to patches/mfplat-streaming-support/0047-Revert-mf-topoloader-Switch-to-public-interface-for-.patch index 99a5ad51..87f0951b 100644 --- a/patches/mfplat-streaming-support/0003-Revert-mf-topoloader-Switch-to-public-interface-for-.patch +++ b/patches/mfplat-streaming-support/0047-Revert-mf-topoloader-Switch-to-public-interface-for-.patch @@ -1,7 +1,7 @@ -From e42f00a2fd98ea18f76b2f8c874d86b27723c57d Mon Sep 17 00:00:00 2001 -From: Alistair Leslie-Hughes -Date: Tue, 11 Aug 2020 09:27:00 +1000 -Subject: [PATCH 03/54] Revert "mf/topoloader: Switch to public interface for +From 7a0d07917acb65ae5dd623231e5756b2371d1484 Mon Sep 17 00:00:00 2001 +From: Derek Lesho +Date: Tue, 11 Aug 2020 15:59:13 -0500 +Subject: [PATCH 47/52] Revert "mf/topoloader: Switch to public interface for initial topology validation." This reverts commit 8e343024b577892bd4908304ded34b758579698d. @@ -10,7 +10,7 @@ This reverts commit 8e343024b577892bd4908304ded34b758579698d. 1 file changed, 12 insertions(+), 24 deletions(-) diff --git a/dlls/mf/topology.c b/dlls/mf/topology.c -index 8522f56969..abe66c45fd 100644 +index 8522f569691..abe66c45fd4 100644 --- a/dlls/mf/topology.c +++ b/dlls/mf/topology.c @@ -1936,50 +1936,38 @@ static ULONG WINAPI topology_loader_Release(IMFTopoLoader *iface) diff --git a/patches/mfplat-streaming-support/0006-mf-Partially-implement-the-topology-loader.patch b/patches/mfplat-streaming-support/0048-mf-Partially-implement-the-topology-loader.patch similarity index 98% rename from patches/mfplat-streaming-support/0006-mf-Partially-implement-the-topology-loader.patch rename to patches/mfplat-streaming-support/0048-mf-Partially-implement-the-topology-loader.patch index 606c67b6..ca855348 100644 --- a/patches/mfplat-streaming-support/0006-mf-Partially-implement-the-topology-loader.patch +++ b/patches/mfplat-streaming-support/0048-mf-Partially-implement-the-topology-loader.patch @@ -1,8 +1,8 @@ -From 01329fe9741031c7ae7cbe74f7b79d5a92f5e52c Mon Sep 17 00:00:00 2001 +From 5c73b5ab912098d1399781cef97956c188bdc187 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20G=C3=B3mez=20Del=20Real?= Date: Wed, 1 Apr 2020 16:11:07 -0500 -Subject: [PATCH 06/54] mf: Partially implement the topology loader. +Subject: [PATCH 48/52] mf: Partially implement the topology loader. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -14,10 +14,10 @@ Signed-off-by: Sergio Gómez Del Real 2 files changed, 321 insertions(+), 19 deletions(-) diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c -index 8691ef55c9..f4f72dda5e 100644 +index aa2c5199b95..1a08604fb39 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c -@@ -1572,7 +1572,6 @@ static void test_topology_loader(void) +@@ -1428,7 +1428,6 @@ static void test_topology_loader(void) /* Empty topology */ hr = IMFTopoLoader_Load(loader, topology, &full_topology, NULL); @@ -25,7 +25,7 @@ index 8691ef55c9..f4f72dda5e 100644 ok(hr == MF_E_TOPO_UNSUPPORTED, "Unexpected hr %#x.\n", hr); hr = MFCreateSourceResolver(&resolver); -@@ -1617,7 +1616,6 @@ todo_wine +@@ -1473,7 +1472,6 @@ todo_wine /* Source node only. */ hr = IMFTopoLoader_Load(loader, topology, &full_topology, NULL); @@ -33,7 +33,7 @@ index 8691ef55c9..f4f72dda5e 100644 ok(hr == MF_E_TOPO_UNSUPPORTED, "Unexpected hr %#x.\n", hr); /* Add grabber sink. */ -@@ -1643,7 +1641,6 @@ todo_wine +@@ -1499,7 +1497,6 @@ todo_wine ok(hr == S_OK, "Failed to add sink node, hr %#x.\n", hr); hr = IMFTopoLoader_Load(loader, topology, &full_topology, NULL); @@ -42,7 +42,7 @@ index 8691ef55c9..f4f72dda5e 100644 hr = IMFTopologyNode_ConnectOutput(src_node, 0, sink_node, 0); diff --git a/dlls/mf/topology.c b/dlls/mf/topology.c -index abe66c45fd..d4a59f7136 100644 +index abe66c45fd4..d4a59f7136e 100644 --- a/dlls/mf/topology.c +++ b/dlls/mf/topology.c @@ -1933,47 +1933,352 @@ static ULONG WINAPI topology_loader_Release(IMFTopoLoader *iface) diff --git a/patches/mfplat-streaming-support/0038-mf-Miscelaneous-fixes-to-topology-resolution.patch b/patches/mfplat-streaming-support/0049-mf-Miscelaneous-fixes-to-topology-resolution.patch similarity index 91% rename from patches/mfplat-streaming-support/0038-mf-Miscelaneous-fixes-to-topology-resolution.patch rename to patches/mfplat-streaming-support/0049-mf-Miscelaneous-fixes-to-topology-resolution.patch index 28ecb28f..e8507cb0 100644 --- a/patches/mfplat-streaming-support/0038-mf-Miscelaneous-fixes-to-topology-resolution.patch +++ b/patches/mfplat-streaming-support/0049-mf-Miscelaneous-fixes-to-topology-resolution.patch @@ -1,14 +1,14 @@ -From 3162911a265859e6767fb3c61229ca512dc06bc1 Mon Sep 17 00:00:00 2001 +From b66660df34eeb885c28a9381461255712a7b3bd1 Mon Sep 17 00:00:00 2001 From: Derek Lesho Date: Thu, 2 Apr 2020 15:43:52 -0500 -Subject: [PATCH 38/54] mf: Miscelaneous fixes to topology resolution. +Subject: [PATCH 49/52] mf: Miscelaneous fixes to topology resolution. --- dlls/mf/topology.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/dlls/mf/topology.c b/dlls/mf/topology.c -index d4a59f7136..2e84920434 100644 +index d4a59f7136e..2e849204343 100644 --- a/dlls/mf/topology.c +++ b/dlls/mf/topology.c @@ -2026,7 +2026,7 @@ static HRESULT topology_loader_resolve_branch(IMFTopologyNode *src, IMFMediaType diff --git a/patches/mfplat-streaming-support/0039-Rewrite-branch-resolver.patch b/patches/mfplat-streaming-support/0050-Rewrite-branch-resolver.patch similarity index 91% rename from patches/mfplat-streaming-support/0039-Rewrite-branch-resolver.patch rename to patches/mfplat-streaming-support/0050-Rewrite-branch-resolver.patch index 1a92fcda..d8dc39b3 100644 --- a/patches/mfplat-streaming-support/0039-Rewrite-branch-resolver.patch +++ b/patches/mfplat-streaming-support/0050-Rewrite-branch-resolver.patch @@ -1,18 +1,18 @@ -From f60e21e99a3cddea383792307c4b8c8278e887b8 Mon Sep 17 00:00:00 2001 +From ebfd4c055be8d68a34b4bfd6a80e449afce5d9c8 Mon Sep 17 00:00:00 2001 From: Derek Lesho Date: Thu, 2 Apr 2020 15:45:52 -0500 -Subject: [PATCH] Rewrite branch resolver. +Subject: [PATCH 50/52] Rewrite branch resolver. and a HACK: Set output type of found decoder, this should probably happen somewhere else. --- dlls/mf/topology.c | 280 ++++++++++++++++++++++++++++----------------- - 1 file changed, 172 insertions(+), 108 deletions(-) + 1 file changed, 173 insertions(+), 107 deletions(-) diff --git a/dlls/mf/topology.c b/dlls/mf/topology.c -index 2e84920434..5a00fe7ea3 100644 +index 2e849204343..91d29782582 100644 --- a/dlls/mf/topology.c +++ b/dlls/mf/topology.c -@@ -1948,135 +1948,195 @@ static void topology_loader_add_branch(struct topology *topology, IMFTopologyNod +@@ -1948,135 +1948,196 @@ static void topology_loader_add_branch(struct topology *topology, IMFTopologyNod } } @@ -29,7 +29,6 @@ index 2e84920434..5a00fe7ea3 100644 + IMFActivate **activates; + UINT32 num_activates; + HRESULT hr; -+ unsigned int i; + + if (FAILED(hr = IMFMediaType_GetMajorType(input_type, &major_type))) + return hr; @@ -45,7 +44,7 @@ index 2e84920434..5a00fe7ea3 100644 + + hr = E_FAIL; + -+ for (i = 0; i < num_activates; i++) ++ for (unsigned int i = 0; i < num_activates; i++) + { + IMFTransform *mft; + @@ -83,13 +82,14 @@ index 2e84920434..5a00fe7ea3 100644 + IMFTopologyNode *node; + struct connect_to_sink_context *ctx = context; + -+ if (SUCCEEDED(IMFMediaTypeHandler_SetCurrentMediaType(ctx->sink_mth, type->type))) ++ if (SUCCEEDED(IMFMediaTypeHandler_IsMediaTypeSupported(ctx->sink_mth, type->type, NULL))) + { + MFCreateTopologyNode(MF_TOPOLOGY_TRANSFORM_NODE, &node); + IMFTopologyNode_SetObject(node, (IUnknown *) type->transform); + IMFTopologyNode_ConnectOutput(ctx->src, 0, node, 0); + IMFTopologyNode_ConnectOutput(node, 0, ctx->sink, 0); + ++ IMFMediaTypeHandler_SetCurrentMediaType(ctx->sink_mth, type->type); + IMFTransform_SetOutputType(type->transform, 0, type->type, 0); + + return S_OK; @@ -141,11 +141,12 @@ index 2e84920434..5a00fe7ea3 100644 IMFStreamSink_GetMediaTypeHandler(streamsink, &mth); - if (method == MF_CONNECT_DIRECT) + -+ if (SUCCEEDED(hr = IMFMediaTypeHandler_SetCurrentMediaType(mth, mediatype))) ++ if (SUCCEEDED(hr = IMFMediaTypeHandler_IsMediaTypeSupported(mth, mediatype, NULL))) { - if (FAILED(hr = IMFMediaTypeHandler_SetCurrentMediaType(mth, mediatype))) - return hr; - hr = IMFTopologyNode_ConnectOutput(src, 0, sink, 0); ++ IMFMediaTypeHandler_SetCurrentMediaType(mth, mediatype); + return IMFTopologyNode_ConnectOutput(src, 0, sink, 0); + } + @@ -310,7 +311,7 @@ index 2e84920434..5a00fe7ea3 100644 IMFAttributes *attrs_src; IMFStreamSink *strm_sink; IMFMediaType *mtype_src; -@@ -2084,6 +2144,7 @@ static HRESULT topology_loader_resolve_partial_topology(struct topology_node *sr +@@ -2084,6 +2145,7 @@ static HRESULT topology_loader_resolve_partial_topology(struct topology_node *sr HRESULT hr; int i; @@ -318,7 +319,7 @@ index 2e84920434..5a00fe7ea3 100644 attrs_src = src->attributes; if (FAILED(hr = IMFAttributes_GetUnknown(attrs_src, &MF_TOPONODE_STREAM_DESCRIPTOR, &IID_IMFStreamDescriptor, (void **)&desc))) return hr; -@@ -2137,12 +2198,15 @@ static HRESULT topology_loader_resolve_partial_topology(struct topology_node *sr +@@ -2137,12 +2199,15 @@ static HRESULT topology_loader_resolve_partial_topology(struct topology_node *sr if (FAILED(IMFTopologyNode_GetUINT32(clone_sink, &MF_TOPONODE_STREAMID, &streamid))) IMFTopologyNode_SetUINT32(clone_sink, &MF_TOPONODE_STREAMID, 0); @@ -337,7 +338,7 @@ index 2e84920434..5a00fe7ea3 100644 for (i = 0; i < num_media_types; i++) if (SUCCEEDED(topology_loader_resolve_branch(clone_src, src_mediatypes[i], clone_sink, method))) { -@@ -2154,7 +2218,7 @@ static HRESULT topology_loader_resolve_partial_topology(struct topology_node *sr +@@ -2154,7 +2219,7 @@ static HRESULT topology_loader_resolve_partial_topology(struct topology_node *sr else { for (i = 0; i < num_media_types; i++) @@ -346,7 +347,7 @@ index 2e84920434..5a00fe7ea3 100644 if (SUCCEEDED(topology_loader_resolve_branch(clone_src, src_mediatypes[i], clone_sink, method))) { topology_loader_add_branch(*full_topology, clone_src, clone_sink); -@@ -2165,10 +2229,10 @@ static HRESULT topology_loader_resolve_partial_topology(struct topology_node *sr +@@ -2165,7 +2230,7 @@ static HRESULT topology_loader_resolve_partial_topology(struct topology_node *sr } else { @@ -354,11 +355,15 @@ index 2e84920434..5a00fe7ea3 100644 + for (method = MF_CONNECT_DIRECT; method <= sink_method; method++) if (SUCCEEDED(topology_loader_resolve_branch(clone_src, src_mediatypes[0], clone_sink, method))) { -- TRACE("Successfully connected nodes with method %u\n", method); -+ TRACE("Successfully connected nodes with method %u\n", src_method); - topology_loader_add_branch(*full_topology, clone_src, clone_sink); - heap_free(src_mediatypes); - return S_OK; + TRACE("Successfully connected nodes with method %u\n", method); +@@ -2274,6 +2339,7 @@ static HRESULT WINAPI topology_loader_Load(IMFTopoLoader *iface, IMFTopology *in + + if (FAILED(hr = topology_loader_resolve_partial_topology(src, sink, topology, &full_topology))) + { ++ ERR("Failed to resolve connection between %p and %p. %x\n", src, sink, hr); + heap_free(node_pairs); + return hr; + } -- 2.28.0 diff --git a/patches/mfplat-streaming-support/0051-mf-sar-Compare-against-native-media-type-in-IsMediaT.patch b/patches/mfplat-streaming-support/0051-mf-sar-Compare-against-native-media-type-in-IsMediaT.patch new file mode 100644 index 00000000..998a143a --- /dev/null +++ b/patches/mfplat-streaming-support/0051-mf-sar-Compare-against-native-media-type-in-IsMediaT.patch @@ -0,0 +1,30 @@ +From 7884831a19a53abf4b33b7c6cabf5a52247c2b32 Mon Sep 17 00:00:00 2001 +From: Derek Lesho +Date: Wed, 26 Aug 2020 10:23:58 -0500 +Subject: [PATCH 51/52] mf/sar: Compare against native media type in + IsMediaTypeSupported. + +TODO: add tests. +--- + dlls/mf/sar.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/dlls/mf/sar.c b/dlls/mf/sar.c +index 6f1f1bd834e..547f8eb391c 100644 +--- a/dlls/mf/sar.c ++++ b/dlls/mf/sar.c +@@ -1479,8 +1479,9 @@ static HRESULT WINAPI audio_renderer_stream_type_handler_IsMediaTypeSupported(IM + TRACE("%p, %p, %p.\n", iface, in_type, out_type); + + EnterCriticalSection(&renderer->cs); +- hr = renderer->current_media_type && IMFMediaType_IsEqual(renderer->current_media_type, in_type, &flags) == S_OK ? +- S_OK : MF_E_INVALIDMEDIATYPE; ++ hr = IMFMediaType_IsEqual(renderer->current_media_type ? renderer->current_media_type : renderer->media_type, in_type, &flags) == S_OK ? ++ S_OK : MF_E_INVALIDMEDIATYPE; ++ + LeaveCriticalSection(&renderer->cs); + + return hr; +-- +2.28.0 + diff --git a/patches/mfplat-streaming-support/0052-winegstreamer-Fix-unrecognized-format-errors-when-tr.patch b/patches/mfplat-streaming-support/0052-winegstreamer-Fix-unrecognized-format-errors-when-tr.patch deleted file mode 100644 index bdcd9c9d..00000000 --- a/patches/mfplat-streaming-support/0052-winegstreamer-Fix-unrecognized-format-errors-when-tr.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 12817ac3db28b1945a664ea3411186e1e64f6ed4 Mon Sep 17 00:00:00 2001 -From: Victor Hermann Chiletto -Date: Tue, 9 Jun 2020 01:35:53 -0300 -Subject: [PATCH 52/54] winegstreamer: Fix unrecognized format errors when - transforming caps to media type - -Probably not needed, but it's nice to get this out of the way ---- - dlls/winegstreamer/mfplat.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c -index bcfcd398ec..39b98f3eba 100644 ---- a/dlls/winegstreamer/mfplat.c -+++ b/dlls/winegstreamer/mfplat.c -@@ -910,6 +910,8 @@ static IMFMediaType* transform_to_media_type(GstCaps *caps) - { - if (!(strcmp(format, "WVC1"))) - IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFVideoFormat_WVC1); -+ else if (!(strcmp(format, "WMV3"))) -+ IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFVideoFormat_WMV3); - else - FIXME("Unrecognized format %s\n", format); - } --- -2.28.0 - diff --git a/patches/mfplat-streaming-support/0052-winegstreamer-Implement-audio-conversion-MFT.patch b/patches/mfplat-streaming-support/0052-winegstreamer-Implement-audio-conversion-MFT.patch new file mode 100644 index 00000000..592924a8 --- /dev/null +++ b/patches/mfplat-streaming-support/0052-winegstreamer-Implement-audio-conversion-MFT.patch @@ -0,0 +1,879 @@ +From 779877a3e829ba787f289ea13047562652e79ad9 Mon Sep 17 00:00:00 2001 +From: Derek Lesho +Date: Wed, 26 Aug 2020 10:28:37 -0500 +Subject: [PATCH 52/52] winegstreamer: Implement audio conversion MFT. + +Signed-off-by: Derek Lesho +--- + dlls/winegstreamer/Makefile.in | 1 + + dlls/winegstreamer/audioconvert.c | 762 +++++++++++++++++++ + dlls/winegstreamer/gst_private.h | 1 + + dlls/winegstreamer/mfplat.c | 23 + + dlls/winegstreamer/winegstreamer_classes.idl | 6 + + 5 files changed, 793 insertions(+) + create mode 100644 dlls/winegstreamer/audioconvert.c + +diff --git a/dlls/winegstreamer/Makefile.in b/dlls/winegstreamer/Makefile.in +index a266b0a95e4..81c670c17e4 100644 +--- a/dlls/winegstreamer/Makefile.in ++++ b/dlls/winegstreamer/Makefile.in +@@ -6,6 +6,7 @@ EXTRALIBS = $(GSTREAMER_LIBS) $(PTHREAD_LIBS) + PARENTSRC = ../strmbase ../mf + + C_SRCS = \ ++ audioconvert.c \ + colorconvert.c \ + filter.c \ + gst_cbs.c \ +diff --git a/dlls/winegstreamer/audioconvert.c b/dlls/winegstreamer/audioconvert.c +new file mode 100644 +index 00000000000..acb842242f1 +--- /dev/null ++++ b/dlls/winegstreamer/audioconvert.c +@@ -0,0 +1,762 @@ ++#include "config.h" ++#include ++ ++#include "gst_private.h" ++#include "gst_cbs.h" ++ ++#include "mfapi.h" ++#include "mferror.h" ++#include "mfidl.h" ++ ++#include "wine/debug.h" ++#include "wine/heap.h" ++ ++WINE_DEFAULT_DEBUG_CHANNEL(mfplat); ++ ++static const GUID *raw_types[] = { ++ &MFAudioFormat_PCM, ++ &MFAudioFormat_Float, ++}; ++ ++struct audio_converter ++{ ++ IMFTransform IMFTransform_iface; ++ LONG refcount; ++ IMFAttributes *attributes; ++ IMFAttributes *output_attributes; ++ IMFMediaType *input_type; ++ IMFMediaType *output_type; ++ BOOL valid_state, inflight; ++ GstElement *container, *appsrc, *audioconvert, *resampler, *appsink; ++ GstBus *bus; ++ CRITICAL_SECTION cs; ++}; ++ ++static struct audio_converter *impl_audio_converter_from_IMFTransform(IMFTransform *iface) ++{ ++ return CONTAINING_RECORD(iface, struct audio_converter, IMFTransform_iface); ++} ++ ++static HRESULT WINAPI audio_converter_QueryInterface(IMFTransform *iface, REFIID riid, void **obj) ++{ ++ TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj); ++ ++ if (IsEqualIID(riid, &IID_IMFTransform) || ++ IsEqualIID(riid, &IID_IUnknown)) ++ { ++ *obj = iface; ++ IMFTransform_AddRef(iface); ++ return S_OK; ++ } ++ ++ WARN("Unsupported %s.\n", debugstr_guid(riid)); ++ *obj = NULL; ++ return E_NOINTERFACE; ++} ++ ++static ULONG WINAPI audio_converter_AddRef(IMFTransform *iface) ++{ ++ struct audio_converter *transform = impl_audio_converter_from_IMFTransform(iface); ++ ULONG refcount = InterlockedIncrement(&transform->refcount); ++ ++ TRACE("%p, refcount %u.\n", iface, refcount); ++ ++ return refcount; ++} ++ ++static ULONG WINAPI audio_converter_Release(IMFTransform *iface) ++{ ++ struct audio_converter *transform = impl_audio_converter_from_IMFTransform(iface); ++ ULONG refcount = InterlockedDecrement(&transform->refcount); ++ ++ TRACE("%p, refcount %u.\n", iface, refcount); ++ ++ if (!refcount) ++ { ++ if (transform->attributes) ++ IMFAttributes_Release(transform->attributes); ++ if (transform->output_attributes) ++ IMFAttributes_Release(transform->output_attributes); ++ heap_free(transform); ++ } ++ ++ return refcount; ++} ++ ++static HRESULT WINAPI audio_converter_GetStreamLimits(IMFTransform *iface, DWORD *input_minimum, DWORD *input_maximum, ++ DWORD *output_minimum, DWORD *output_maximum) ++{ ++ TRACE("%p, %p, %p, %p, %p.\n", iface, input_minimum, input_maximum, output_minimum, output_maximum); ++ ++ *input_minimum = *input_maximum = *output_minimum = *output_maximum = 1; ++ ++ return S_OK; ++} ++ ++static HRESULT WINAPI audio_converter_GetStreamCount(IMFTransform *iface, DWORD *inputs, DWORD *outputs) ++{ ++ TRACE("%p, %p, %p.\n", iface, inputs, outputs); ++ ++ *inputs = *outputs = 1; ++ ++ return S_OK; ++} ++ ++static HRESULT WINAPI audio_converter_GetStreamIDs(IMFTransform *iface, DWORD input_size, DWORD *inputs, ++ DWORD output_size, DWORD *outputs) ++{ ++ return E_NOTIMPL; ++} ++ ++static HRESULT WINAPI audio_converter_GetInputStreamInfo(IMFTransform *iface, DWORD id, MFT_INPUT_STREAM_INFO *info) ++{ ++ struct audio_converter *converter = impl_audio_converter_from_IMFTransform(iface); ++ ++ TRACE("%p %u %p\n", converter, id, info); ++ ++ if (id != 0) ++ return MF_E_INVALIDSTREAMNUMBER; ++ ++ /* If we create a wrapped GstBuffer, remove MFT_INPUT_STREAM_DOES_NOT_ADDREF */ ++ info->dwFlags = MFT_INPUT_STREAM_WHOLE_SAMPLES | MFT_INPUT_STREAM_DOES_NOT_ADDREF; ++ info->cbMaxLookahead = 0; ++ info->cbAlignment = 0; ++ /* this is incorrect */ ++ info->hnsMaxLatency = 0; ++ return S_OK; ++} ++ ++static HRESULT WINAPI audio_converter_GetOutputStreamInfo(IMFTransform *iface, DWORD id, MFT_OUTPUT_STREAM_INFO *info) ++{ ++ struct audio_converter *converter = impl_audio_converter_from_IMFTransform(iface); ++ ++ MFT_OUTPUT_STREAM_INFO stream_info = {}; ++ ++ TRACE("%p %u %p\n", converter, id, info); ++ ++ if (id != 0) ++ return MF_E_INVALIDSTREAMNUMBER; ++ ++ stream_info.dwFlags = MFT_OUTPUT_STREAM_PROVIDES_SAMPLES; ++ stream_info.cbSize = 0; ++ stream_info.cbAlignment = 0; ++ ++ *info = stream_info; ++ ++ return S_OK; ++} ++ ++static HRESULT WINAPI audio_converter_GetAttributes(IMFTransform *iface, IMFAttributes **attributes) ++{ ++ struct audio_converter *transform = impl_audio_converter_from_IMFTransform(iface); ++ ++ TRACE("%p, %p.\n", iface, attributes); ++ ++ *attributes = transform->attributes; ++ IMFAttributes_AddRef(*attributes); ++ ++ return S_OK; ++} ++ ++static HRESULT WINAPI audio_converter_GetInputStreamAttributes(IMFTransform *iface, DWORD id, ++ IMFAttributes **attributes) ++{ ++ return E_NOTIMPL; ++} ++ ++static HRESULT WINAPI audio_converter_GetOutputStreamAttributes(IMFTransform *iface, DWORD id, ++ IMFAttributes **attributes) ++{ ++ struct audio_converter *transform = impl_audio_converter_from_IMFTransform(iface); ++ ++ TRACE("%p, %u, %p.\n", iface, id, attributes); ++ ++ *attributes = transform->output_attributes; ++ IMFAttributes_AddRef(*attributes); ++ ++ return S_OK; ++} ++ ++static HRESULT WINAPI audio_converter_DeleteInputStream(IMFTransform *iface, DWORD id) ++{ ++ TRACE("%p, %u.\n", iface, id); ++ ++ return E_NOTIMPL; ++} ++ ++static HRESULT WINAPI audio_converter_AddInputStreams(IMFTransform *iface, DWORD streams, DWORD *ids) ++{ ++ TRACE("%p, %u, %p.\n", iface, streams, ids); ++ ++ return E_NOTIMPL; ++} ++ ++static HRESULT WINAPI audio_converter_GetInputAvailableType(IMFTransform *iface, DWORD id, DWORD index, ++ IMFMediaType **type) ++{ ++ IMFMediaType *ret; ++ HRESULT hr; ++ ++ TRACE("%p, %u, %u, %p.\n", iface, id, index, type); ++ ++ if (id != 0) ++ return MF_E_INVALIDSTREAMNUMBER; ++ ++ if (index >= ARRAY_SIZE(raw_types)) ++ return MF_E_NO_MORE_TYPES; ++ ++ if (FAILED(hr = MFCreateMediaType(&ret))) ++ return hr; ++ ++ if (FAILED(hr = IMFMediaType_SetGUID(ret, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio))) ++ { ++ IMFMediaType_Release(ret); ++ return hr; ++ } ++ ++ if (FAILED(hr = IMFMediaType_SetGUID(ret, &MF_MT_SUBTYPE, raw_types[index]))) ++ { ++ IMFMediaType_Release(ret); ++ return hr; ++ } ++ ++ *type = ret; ++ ++ return S_OK; ++} ++ ++static void copy_attr(IMFMediaType *target, IMFMediaType *source, const GUID *key) ++{ ++ PROPVARIANT val; ++ ++ if (SUCCEEDED(IMFAttributes_GetItem((IMFAttributes *)source, key, &val))) ++ { ++ IMFAttributes_SetItem((IMFAttributes* )target, key, &val); ++ } ++} ++ ++static HRESULT WINAPI audio_converter_GetOutputAvailableType(IMFTransform *iface, DWORD id, DWORD index, ++ IMFMediaType **type) ++{ ++ struct audio_converter *converter = impl_audio_converter_from_IMFTransform(iface); ++ IMFMediaType *output_type; ++ HRESULT hr; ++ ++ static const DWORD rates[] = {44100, 48000}; ++ static const DWORD channel_cnts[] = {1, 2, 6}; ++ static const DWORD sizes[] = {16, 24, 32}; ++ const GUID *subtype; ++ DWORD rate, channels, bps; ++ ++ TRACE("%p, %u, %u, %p.\n", iface, id, index, type); ++ ++ if (id != 0) ++ return MF_E_INVALIDSTREAMNUMBER; ++ ++ if (!(converter->input_type)) ++ return MF_E_TRANSFORM_TYPE_NOT_SET; ++ ++ if (index >= (2/*rates*/ * 3/*layouts*/ * 3/*bps PCM*/) + (2 * 3)) ++ return MF_E_NO_MORE_TYPES; ++ ++ if (FAILED(hr = MFCreateMediaType(&output_type))) ++ return hr; ++ ++ copy_attr(output_type, converter->input_type, &MF_MT_MAJOR_TYPE); ++ ++ if (index < 2 * 3 * 3) ++ { ++ subtype = &MFAudioFormat_PCM; ++ rate = rates[index % 2]; ++ channels = channel_cnts[(index / 2) % 3]; ++ bps = sizes[(index / (2*3)) % 3]; ++ } ++ else ++ { ++ index -= (2 * 3 * 3); ++ subtype = &MFAudioFormat_Float; ++ bps = 32; ++ rate = rates[index % 2]; ++ channels = channel_cnts[(index / 2) % 3]; ++ } ++ ++ if (FAILED(hr = IMFMediaType_SetGUID(output_type, &MF_MT_SUBTYPE, subtype))) ++ goto fail; ++ if (FAILED(hr = IMFMediaType_SetUINT32(output_type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, rate))) ++ goto fail; ++ if (FAILED(hr = IMFMediaType_SetUINT32(output_type, &MF_MT_AUDIO_NUM_CHANNELS, channels))) ++ goto fail; ++ if (FAILED(hr = IMFMediaType_SetUINT32(output_type, &MF_MT_AUDIO_BITS_PER_SAMPLE, bps))) ++ goto fail; ++ ++ if (FAILED(hr = IMFMediaType_SetUINT32(output_type, &MF_MT_AUDIO_BLOCK_ALIGNMENT, channels * bps / 8))) ++ goto fail; ++ if (FAILED(hr = IMFMediaType_SetUINT32(output_type, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, rate * channels * bps / 8))) ++ goto fail; ++ if (FAILED(hr = IMFMediaType_SetUINT32(output_type, &MF_MT_AUDIO_CHANNEL_MASK, ++ channels == 1 ? SPEAKER_FRONT_CENTER : ++ channels == 2 ? SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT : ++ /*channels == 6*/ 0x3F))) ++ goto fail; ++ if (FAILED(hr = IMFMediaType_SetUINT32(output_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE))) ++ goto fail; ++ ++ *type = output_type; ++ ++ return S_OK; ++ fail: ++ IMFMediaType_Release(output_type); ++ return hr; ++} ++ ++static void audio_converter_update_pipeline_state(struct audio_converter *converter) ++{ ++ GstCaps *input_caps, *output_caps; ++ gchar *input_caps_str, *output_caps_str; ++ ++ converter->valid_state = converter->input_type && converter->output_type; ++ ++ if (!converter->valid_state) ++ { ++ gst_element_set_state(converter->container, GST_STATE_READY); ++ return; ++ } ++ ++ g_object_set(converter->appsrc, "caps", (input_caps = caps_from_mf_media_type(converter->input_type)), NULL); ++ g_object_set(converter->appsink, "caps", (output_caps = caps_from_mf_media_type(converter->output_type)), NULL); ++ ++ input_caps_str = gst_caps_to_string(input_caps); ++ output_caps_str = gst_caps_to_string(output_caps); ++ TRACE("AUDIO CONVERTER IN =\n%s\nAUDIO CONVERTER OUT = \n%s\n", debugstr_a(input_caps_str), debugstr_a(output_caps_str)); ++ g_free(input_caps_str); ++ g_free(output_caps_str); ++ ++ gst_element_set_state(converter->container, GST_STATE_PLAYING); ++ return; ++} ++ ++static HRESULT WINAPI audio_converter_SetInputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags) ++{ ++ HRESULT hr; ++ ++ struct audio_converter *converter = impl_audio_converter_from_IMFTransform(iface); ++ ++ TRACE("%p, %u, %p, %#x.\n", iface, id, type, flags); ++ ++ if (id != 0) ++ return MF_E_INVALIDSTREAMNUMBER; ++ ++ if (type) ++ { ++ GUID major_type, subtype; ++ DWORD unused; ++ BOOL found = FALSE; ++ ++ if (FAILED(IMFMediaType_GetGUID(type, &MF_MT_MAJOR_TYPE, &major_type))) ++ return MF_E_INVALIDTYPE; ++ if (FAILED(IMFMediaType_GetGUID(type, &MF_MT_SUBTYPE, &subtype))) ++ return MF_E_INVALIDTYPE; ++ if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, &unused))) ++ return MF_E_INVALIDTYPE; ++ if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_NUM_CHANNELS, &unused))) ++ return MF_E_INVALIDTYPE; ++ if (IsEqualGUID(&subtype, &MFAudioFormat_PCM) && FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_BITS_PER_SAMPLE, &unused))) ++ return MF_E_INVALIDTYPE; ++ ++ if (!(IsEqualGUID(&major_type, &MFMediaType_Audio))) ++ return MF_E_INVALIDTYPE; ++ ++ for (unsigned int i = 0; i < ARRAY_SIZE(raw_types); i++) ++ { ++ if (IsEqualGUID(&subtype, raw_types[i])) ++ { ++ found = TRUE; ++ break; ++ } ++ } ++ ++ if (!found) ++ return MF_E_INVALIDTYPE; ++ } ++ ++ if (flags & MFT_SET_TYPE_TEST_ONLY) ++ return S_OK; ++ ++ hr = S_OK; ++ ++ EnterCriticalSection(&converter->cs); ++ ++ if (type) ++ { ++ if (!converter->input_type) ++ if (FAILED(hr = MFCreateMediaType(&converter->input_type))) ++ goto done; ++ ++ if (FAILED(hr = IMFMediaType_CopyAllItems(type, (IMFAttributes *) converter->input_type))) ++ goto done; ++ } ++ else if (converter->input_type) ++ { ++ IMFMediaType_Release(converter->input_type); ++ converter->input_type = NULL; ++ } ++ ++ done: ++ if (hr == S_OK) ++ audio_converter_update_pipeline_state(converter); ++ LeaveCriticalSection(&converter->cs); ++ ++ return S_OK; ++} ++ ++static HRESULT WINAPI audio_converter_SetOutputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags) ++{ ++ struct audio_converter *converter = impl_audio_converter_from_IMFTransform(iface); ++ HRESULT hr; ++ GUID major_type, subtype; ++ DWORD output_sample_rate; ++ DWORD unused; ++ ++ TRACE("%p, %u, %p, %#x.\n", iface, id, type, flags); ++ ++ if (id != 0) ++ return MF_E_INVALIDSTREAMNUMBER; ++ ++ if (!converter->input_type) ++ return MF_E_TRANSFORM_TYPE_NOT_SET; ++ ++ if (type) ++ { ++ /* validate the type */ ++ ++ if (FAILED(IMFMediaType_GetGUID(type, &MF_MT_MAJOR_TYPE, &major_type))) ++ return MF_E_INVALIDTYPE; ++ if (FAILED(IMFMediaType_GetGUID(type, &MF_MT_SUBTYPE, &subtype))) ++ return MF_E_INVALIDTYPE; ++ if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_NUM_CHANNELS, &unused))) ++ return MF_E_INVALIDTYPE; ++ if (IsEqualGUID(&subtype, &MFAudioFormat_PCM) && FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_BITS_PER_SAMPLE, &unused))) ++ return MF_E_INVALIDTYPE; ++ ++ ++ if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, &output_sample_rate))) ++ return MF_E_INVALIDTYPE; ++ ++ if (!(IsEqualGUID(&major_type, &MFMediaType_Audio))) ++ return MF_E_INVALIDTYPE; ++ ++ for (unsigned int i = 0; i < ARRAY_SIZE(raw_types); i++) ++ { ++ if (IsEqualGUID(&subtype, raw_types[i])) ++ break; ++ if (i == ARRAY_SIZE(raw_types)) ++ return MF_E_INVALIDTYPE; ++ } ++ } ++ ++ if (flags & MFT_SET_TYPE_TEST_ONLY) ++ return S_OK; ++ ++ EnterCriticalSection(&converter->cs); ++ ++ hr = S_OK; ++ ++ if (type) ++ { ++ if (!converter->output_type) ++ if (FAILED(hr = MFCreateMediaType(&converter->output_type))) ++ goto done; ++ ++ if (FAILED(hr = IMFMediaType_CopyAllItems(type, (IMFAttributes *) converter->output_type))) ++ goto done; ++ } ++ else if (converter->output_type) ++ { ++ IMFMediaType_Release(converter->output_type); ++ converter->output_type = NULL; ++ } ++ ++ done: ++ if (hr == S_OK) ++ audio_converter_update_pipeline_state(converter); ++ LeaveCriticalSection(&converter->cs); ++ ++ return hr; ++} ++ ++static HRESULT WINAPI audio_converter_GetInputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type) ++{ ++ FIXME("%p, %u, %p.\n", iface, id, type); ++ ++ return E_NOTIMPL; ++} ++ ++static HRESULT WINAPI audio_converter_GetOutputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type) ++{ ++ FIXME("%p, %u, %p.\n", iface, id, type); ++ ++ return E_NOTIMPL; ++} ++ ++static HRESULT WINAPI audio_converter_GetInputStatus(IMFTransform *iface, DWORD id, DWORD *flags) ++{ ++ FIXME("%p, %u, %p.\n", iface, id, flags); ++ ++ return E_NOTIMPL; ++} ++ ++static HRESULT WINAPI audio_converter_GetOutputStatus(IMFTransform *iface, DWORD *flags) ++{ ++ FIXME("%p, %p.\n", iface, flags); ++ ++ return E_NOTIMPL; ++} ++ ++static HRESULT WINAPI audio_converter_SetOutputBounds(IMFTransform *iface, LONGLONG lower, LONGLONG upper) ++{ ++ FIXME("%p, %s, %s.\n", iface, wine_dbgstr_longlong(lower), wine_dbgstr_longlong(upper)); ++ ++ return E_NOTIMPL; ++} ++ ++static HRESULT WINAPI audio_converter_ProcessEvent(IMFTransform *iface, DWORD id, IMFMediaEvent *event) ++{ ++ TRACE("%p, %u, %p.\n", iface, id, event); ++ ++ return E_NOTIMPL; ++} ++ ++static HRESULT WINAPI audio_converter_ProcessMessage(IMFTransform *iface, MFT_MESSAGE_TYPE message, ULONG_PTR param) ++{ ++ FIXME("%p, %u.\n", iface, message); ++ ++ return S_OK; ++} ++ ++static HRESULT WINAPI audio_converter_ProcessInput(IMFTransform *iface, DWORD id, IMFSample *sample, DWORD flags) ++{ ++ struct audio_converter *converter = impl_audio_converter_from_IMFTransform(iface); ++ GstBuffer *gst_buffer; ++ HRESULT hr = S_OK; ++ int ret; ++ ++ TRACE("%p, %u, %p, %#x.\n", iface, id, sample, flags); ++ ++ if (flags) ++ WARN("Unsupported flags %#x\n", flags); ++ ++ if (id != 0) ++ return MF_E_INVALIDSTREAMNUMBER; ++ ++ EnterCriticalSection(&converter->cs); ++ ++ if (!converter->valid_state) ++ { ++ hr = MF_E_TRANSFORM_TYPE_NOT_SET; ++ goto done; ++ } ++ ++ if (converter->inflight) ++ { ++ hr = MF_E_NOTACCEPTING; ++ goto done; ++ } ++ ++ if (!(gst_buffer = gst_buffer_from_mf_sample(sample))) ++ { ++ hr = E_FAIL; ++ goto done; ++ } ++ ++ g_signal_emit_by_name(converter->appsrc, "push-buffer", gst_buffer, &ret); ++ gst_buffer_unref(gst_buffer); ++ if (ret != GST_FLOW_OK) ++ { ++ ERR("Couldn't push buffer ret = %d\n", ret); ++ hr = E_FAIL; ++ goto done; ++ } ++ ++ converter->inflight = TRUE; ++ ++ done: ++ LeaveCriticalSection(&converter->cs); ++ ++ return hr; ++} ++ ++static HRESULT WINAPI audio_converter_ProcessOutput(IMFTransform *iface, DWORD flags, DWORD count, ++ MFT_OUTPUT_DATA_BUFFER *samples, DWORD *status) ++{ ++ struct audio_converter *converter = impl_audio_converter_from_IMFTransform(iface); ++ MFT_OUTPUT_DATA_BUFFER *relevant_buffer = NULL; ++ GstSample *sample; ++ HRESULT hr = S_OK; ++ ++ TRACE("%p, %#x, %u, %p, %p.\n", iface, flags, count, samples, status); ++ ++ if (flags) ++ WARN("Unsupported flags %#x\n", flags); ++ ++ for (unsigned int i = 0; i < count; i++) ++ { ++ MFT_OUTPUT_DATA_BUFFER *out_buffer = &samples[i]; ++ ++ if (out_buffer->dwStreamID != 0) ++ return MF_E_INVALIDSTREAMNUMBER; ++ ++ if (relevant_buffer) ++ return MF_E_INVALIDSTREAMNUMBER; ++ ++ relevant_buffer = out_buffer; ++ } ++ ++ if (!relevant_buffer) ++ return S_OK; ++ ++ EnterCriticalSection(&converter->cs); ++ ++ if (!converter->valid_state) ++ { ++ hr = MF_E_TRANSFORM_TYPE_NOT_SET; ++ goto done; ++ } ++ ++ if (!converter->inflight) ++ { ++ hr = MF_E_TRANSFORM_NEED_MORE_INPUT; ++ goto done; ++ } ++ ++ g_signal_emit_by_name(converter->appsink, "pull-sample", &sample); ++ ++ converter->inflight = FALSE; ++ ++ relevant_buffer->pSample = mf_sample_from_gst_buffer(gst_sample_get_buffer(sample)); ++ gst_sample_unref(sample); ++ relevant_buffer->dwStatus = S_OK; ++ relevant_buffer->pEvents = NULL; ++ *status = 0; ++ ++ done: ++ LeaveCriticalSection(&converter->cs); ++ ++ return hr; ++} ++ ++static const IMFTransformVtbl audio_converter_vtbl = ++{ ++ audio_converter_QueryInterface, ++ audio_converter_AddRef, ++ audio_converter_Release, ++ audio_converter_GetStreamLimits, ++ audio_converter_GetStreamCount, ++ audio_converter_GetStreamIDs, ++ audio_converter_GetInputStreamInfo, ++ audio_converter_GetOutputStreamInfo, ++ audio_converter_GetAttributes, ++ audio_converter_GetInputStreamAttributes, ++ audio_converter_GetOutputStreamAttributes, ++ audio_converter_DeleteInputStream, ++ audio_converter_AddInputStreams, ++ audio_converter_GetInputAvailableType, ++ audio_converter_GetOutputAvailableType, ++ audio_converter_SetInputType, ++ audio_converter_SetOutputType, ++ audio_converter_GetInputCurrentType, ++ audio_converter_GetOutputCurrentType, ++ audio_converter_GetInputStatus, ++ audio_converter_GetOutputStatus, ++ audio_converter_SetOutputBounds, ++ audio_converter_ProcessEvent, ++ audio_converter_ProcessMessage, ++ audio_converter_ProcessInput, ++ audio_converter_ProcessOutput, ++}; ++ ++HRESULT audio_converter_create(REFIID riid, void **ret) ++{ ++ struct audio_converter *object; ++ HRESULT hr; ++ ++ TRACE("%s %p\n", debugstr_guid(riid), ret); ++ ++ if (!(object = heap_alloc_zero(sizeof(*object)))) ++ return E_OUTOFMEMORY; ++ ++ object->IMFTransform_iface.lpVtbl = &audio_converter_vtbl; ++ object->refcount = 1; ++ ++ InitializeCriticalSection(&object->cs); ++ ++ if (FAILED(hr = MFCreateAttributes(&object->attributes, 0))) ++ goto failed; ++ ++ if (FAILED(hr = MFCreateAttributes(&object->output_attributes, 0))) ++ goto failed; ++ ++ object->container = gst_bin_new(NULL); ++ object->bus = gst_bus_new(); ++ gst_element_set_bus(object->container, object->bus); ++ ++ if (!(object->appsrc = gst_element_factory_make("appsrc", NULL))) ++ { ++ ERR("Failed to create appsrc"); ++ hr = E_FAIL; ++ goto failed; ++ } ++ gst_bin_add(GST_BIN(object->container), object->appsrc); ++ ++ if (!(object->audioconvert = gst_element_factory_make("audioconvert", NULL))) ++ { ++ ERR("Failed to create converter\n"); ++ hr = E_FAIL; ++ goto failed; ++ } ++ gst_bin_add(GST_BIN(object->container), object->audioconvert); ++ ++ if (!(object->resampler = gst_element_factory_make("audioresample", NULL))) ++ { ++ ERR("Failed to create resampler\n"); ++ hr = E_FAIL; ++ goto failed; ++ } ++ gst_bin_add(GST_BIN(object->container), object->resampler); ++ ++ if (!(object->appsink = gst_element_factory_make("appsink", NULL))) ++ { ++ ERR("Failed to create appsink\n"); ++ hr = E_FAIL; ++ goto failed; ++ } ++ gst_bin_add(GST_BIN(object->container), object->appsink); ++ ++ if (!(gst_element_link(object->appsrc, object->audioconvert))) ++ { ++ ERR("Failed to link appsrc to audioconvert\n"); ++ hr = E_FAIL; ++ goto failed; ++ } ++ ++ if (!(gst_element_link(object->audioconvert, object->resampler))) ++ { ++ ERR("Failed to link audioconvert to resampler\n"); ++ hr = E_FAIL; ++ goto failed; ++ } ++ ++ if (!(gst_element_link(object->resampler, object->appsink))) ++ { ++ ERR("Failed to link resampler to appsink\n"); ++ hr = E_FAIL; ++ goto failed; ++ } ++ ++ *ret = &object->IMFTransform_iface; ++ return S_OK; ++ ++failed: ++ ++ IMFTransform_Release(&object->IMFTransform_iface); ++ return hr; ++} +\ No newline at end of file +diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h +index 8e75beb82dd..b505387637b 100644 +--- a/dlls/winegstreamer/gst_private.h ++++ b/dlls/winegstreamer/gst_private.h +@@ -75,5 +75,6 @@ HRESULT generic_decoder_construct(REFIID riid, void **obj, enum decoder_type) DE + HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj) DECLSPEC_HIDDEN; + + HRESULT color_converter_create(REFIID riid, void **ret); ++HRESULT audio_converter_create(REFIID riid, void **ret); + + #endif /* __GST_PRIVATE_INCLUDED__ */ +diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c +index 28c9beb4649..3b50264d0f8 100644 +--- a/dlls/winegstreamer/mfplat.c ++++ b/dlls/winegstreamer/mfplat.c +@@ -433,6 +433,8 @@ static HRESULT m4s2_decoder_create(REFIID riid, void **ret) + + static GUID CLSID_CColorConvertDMO = {0x98230571,0x0087,0x4204,{0xb0,0x20,0x32,0x82,0x53,0x8e,0x57,0xd3}}; + ++static GUID CLSID_WINEAudioConverter = {0x6a170414,0xaad9,0x4693,{0xb8,0x06,0x3a,0x0c,0x47,0xc5,0x70,0xd6}}; ++ + static const struct class_object + { + const GUID *clsid; +@@ -448,6 +450,7 @@ class_objects[] = + { &CLSID_CWMADecMediaObject, &wma_decoder_create }, + { &CLSID_CMpeg4sDecMFT, m4s2_decoder_create }, + { &CLSID_CColorConvertDMO, &color_converter_create }, ++ { &CLSID_WINEAudioConverter, &audio_converter_create }, + }; + + HRESULT mfplat_get_class_object(REFCLSID rclsid, REFIID riid, void **obj) +@@ -497,6 +500,14 @@ const GUID *color_converter_supported_types[] = + &MFVideoFormat_YVYU, + }; + ++static WCHAR audio_converterW[] = {'A','u','d','i','o',' ','C','o','n','v','e','r','t','e','r',0}; ++ ++const GUID *audio_converter_supported_types[] = ++{ ++ &MFAudioFormat_PCM, ++ &MFAudioFormat_Float, ++}; ++ + static WCHAR h264decoderW[] = {'H','.','2','6','4',' ','D','e','c','o','d','e','r',0}; + const GUID *h264_decoder_input_types[] = + { +@@ -603,6 +614,18 @@ mfts[] = + color_converter_supported_types, + NULL + }, ++ { ++ &CLSID_WINEAudioConverter, ++ &MFT_CATEGORY_AUDIO_EFFECT, ++ audio_converterW, ++ MFT_ENUM_FLAG_SYNCMFT, ++ &MFMediaType_Audio, ++ ARRAY_SIZE(audio_converter_supported_types), ++ audio_converter_supported_types, ++ ARRAY_SIZE(audio_converter_supported_types), ++ audio_converter_supported_types, ++ NULL ++ }, + { + &CLSID_CMSH264DecoderMFT, + &MFT_CATEGORY_VIDEO_DECODER, +diff --git a/dlls/winegstreamer/winegstreamer_classes.idl b/dlls/winegstreamer/winegstreamer_classes.idl +index c014d359a39..c58fa417bbe 100644 +--- a/dlls/winegstreamer/winegstreamer_classes.idl ++++ b/dlls/winegstreamer/winegstreamer_classes.idl +@@ -97,3 +97,9 @@ coclass CLSID_CWMADecMediaObject {} + uuid(98230571-0087-4204-b020-3282538e57d3) + ] + coclass CColorConvertDMO { } ++ ++[ ++ threading(both), ++ uuid(6a170414-aad9-4693-b806-3a0c47c570d6) ++] ++coclass WINEAudioConverter { } +-- +2.28.0 + diff --git a/patches/mfplat-streaming-support/0055-winegstreamer-Support-eAVEncH264VProfile_Constrained.patch b/patches/mfplat-streaming-support/0053-winegstreamer-Support-eAVEncH264VProfile_Constrained.patch similarity index 100% rename from patches/mfplat-streaming-support/0055-winegstreamer-Support-eAVEncH264VProfile_Constrained.patch rename to patches/mfplat-streaming-support/0053-winegstreamer-Support-eAVEncH264VProfile_Constrained.patch diff --git a/patches/mfplat-streaming-support/0053-winegstreamer-Translate-WMV3-attributes-to-caps.patch b/patches/mfplat-streaming-support/0053-winegstreamer-Translate-WMV3-attributes-to-caps.patch deleted file mode 100644 index 16a236fc..00000000 --- a/patches/mfplat-streaming-support/0053-winegstreamer-Translate-WMV3-attributes-to-caps.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 69fd2aa695178b36154ded6a13b74a5ec4b98304 Mon Sep 17 00:00:00 2001 -From: Victor Hermann Chiletto -Date: Tue, 9 Jun 2020 01:36:53 -0300 -Subject: [PATCH 53/54] winegstreamer: Translate WMV3 attributes to caps - ---- - dlls/winegstreamer/mfplat.c | 9 +++++++++ - 1 file changed, 9 insertions(+) - -diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c -index 39b98f3eba..042c02c486 100644 ---- a/dlls/winegstreamer/mfplat.c -+++ b/dlls/winegstreamer/mfplat.c -@@ -1319,6 +1319,15 @@ GstCaps *caps_from_mf_media_type(IMFMediaType *type) - - user_data_to_codec_data(type, output); - } -+ else if (IsEqualGUID(&subtype, &MFVideoFormat_WMV3)) -+ { -+ output = gst_caps_new_empty_simple("video/x-wmv"); -+ gst_caps_set_simple(output, "format", G_TYPE_STRING, "WMV3", NULL); -+ -+ gst_caps_set_simple(output, "wmvversion", G_TYPE_INT, 3, NULL); -+ -+ user_data_to_codec_data(type, output); -+ } - else { - FIXME("Unrecognized subtype %s\n", debugstr_guid(&subtype)); - return NULL; --- -2.28.0 - diff --git a/patches/mfplat-streaming-support/0054-winegstreamer-expose-NV12-as-the-first-color-space-i.patch b/patches/mfplat-streaming-support/0054-winegstreamer-expose-NV12-as-the-first-color-space-i.patch deleted file mode 100644 index 4675dc08..00000000 --- a/patches/mfplat-streaming-support/0054-winegstreamer-expose-NV12-as-the-first-color-space-i.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 8aabbee010a69fde257706cf3d178864feb1858c Mon Sep 17 00:00:00 2001 -From: Victor Hermann Chiletto -Date: Wed, 10 Jun 2020 01:10:57 -0300 -Subject: [PATCH 54/54] winegstreamer: expose NV12 as the first color space in - IMFTransform::GetOutputAvailableType - ---- - dlls/winegstreamer/mf_decode.c | 2 +- - dlls/winegstreamer/mfplat.c | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/dlls/winegstreamer/mf_decode.c b/dlls/winegstreamer/mf_decode.c -index 3d314eaab4..6e41838fdc 100644 ---- a/dlls/winegstreamer/mf_decode.c -+++ b/dlls/winegstreamer/mf_decode.c -@@ -23,7 +23,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(mfplat); - /* keep in sync with mfplat.c's mft registrations */ - - const GUID *h264_input_types[] = {&MFVideoFormat_H264}; --const GUID *h264_output_types[] = {&MFVideoFormat_I420, &MFVideoFormat_IYUV, &MFVideoFormat_NV12, &MFVideoFormat_YUY2, &MFVideoFormat_YV12}; -+const GUID *h264_output_types[] = {&MFVideoFormat_NV12, &MFVideoFormat_I420, &MFVideoFormat_IYUV, &MFVideoFormat_YUY2, &MFVideoFormat_YV12}; - - const GUID *aac_input_types[] = {&MFAudioFormat_AAC}; - const GUID *aac_output_types[] = {&MFAudioFormat_Float, &MFAudioFormat_PCM}; -diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c -index 042c02c486..94e6ca534f 100644 ---- a/dlls/winegstreamer/mfplat.c -+++ b/dlls/winegstreamer/mfplat.c -@@ -516,9 +516,9 @@ const GUID *h264_decoder_input_types[] = - }; - const GUID *h264_decoder_output_types[] = - { -+ &MFVideoFormat_NV12, - &MFVideoFormat_I420, - &MFVideoFormat_IYUV, -- &MFVideoFormat_NV12, - &MFVideoFormat_YUY2, - &MFVideoFormat_YV12, - }; --- -2.28.0 - diff --git a/patches/mfplat-streaming-support/definition b/patches/mfplat-streaming-support/definition index 4922e06b..46a40d0b 100644 --- a/patches/mfplat-streaming-support/definition +++ b/patches/mfplat-streaming-support/definition @@ -1,2 +1 @@ Fixes: [49692] mfplat: Improved support for multiple video formats. -Disabled: True diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index d66bd38c..c1c54482 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -149,6 +149,7 @@ patch_enable_all () enable_krnl386_exe16_GDT_LDT_Emulation="$1" enable_krnl386_exe16_Invalid_Console_Handles="$1" enable_loader_KeyboardLayouts="$1" + enable_mfplat_streaming_support="$1" enable_mmsystem_dll16_MIDIHDR_Refcount="$1" enable_mountmgr_DosDevices="$1" enable_mscoree_CorValidateImage="$1" @@ -544,6 +545,9 @@ patch_enable () loader-KeyboardLayouts) enable_loader_KeyboardLayouts="$2" ;; + mfplat-streaming-support) + enable_mfplat_streaming_support="$2" + ;; mmsystem.dll16-MIDIHDR_Refcount) enable_mmsystem_dll16_MIDIHDR_Refcount="$2" ;; @@ -2768,6 +2772,77 @@ if test "$enable_loader_KeyboardLayouts" -eq 1; then patch_apply loader-KeyboardLayouts/0002-user32-Improve-GetKeyboardLayoutList.patch fi +# Patchset mfplat-streaming-support +# | +# | This patchset fixes the following Wine bugs: +# | * [#49692] mfplat: Improved support for multiple video formats. +# | +# | Modified files: +# | * dlls/mf/Makefile.in, dlls/mf/handler.c, dlls/mf/handler.h, dlls/mf/main.c, dlls/mf/sar.c, dlls/mf/session.c, +# | dlls/mf/tests/mf.c, dlls/mf/topology.c, dlls/mfplat/mediatype.c, dlls/mfplat/tests/mfplat.c, dlls/mfplat/tests/test.mp4, +# | dlls/mfreadwrite/reader.c, dlls/mfreadwrite/tests/mfplat.c, dlls/mfreadwrite/tests/resource.rc, +# | dlls/mfreadwrite/tests/test.mp4, dlls/winegstreamer/Makefile.in, dlls/winegstreamer/audioconvert.c, +# | dlls/winegstreamer/colorconvert.c, dlls/winegstreamer/gst_cbs.c, dlls/winegstreamer/gst_cbs.h, +# | dlls/winegstreamer/gst_private.h, dlls/winegstreamer/main.c, dlls/winegstreamer/media_source.c, +# | dlls/winegstreamer/mf_decode.c, dlls/winegstreamer/mfplat.c, dlls/winegstreamer/winegstreamer_classes.idl, +# | include/mfidl.idl, tools/make_makefiles, tools/makedep.c +# | +if test "$enable_mfplat_streaming_support" -eq 1; then + patch_apply mfplat-streaming-support/0001-winegstreamer-Add-a-GstPad-wrapping-the-media-source.patch + patch_apply mfplat-streaming-support/0002-winegstreamer-Use-decodebin-to-initialize-media-stre.patch + patch_apply mfplat-streaming-support/0003-winegstreamer-Implement-IMFMediaStream-GetStreamDesc.patch + patch_apply mfplat-streaming-support/0004-winegstreamer-Insert-parser-into-pipeline-to-rectify.patch + patch_apply mfplat-streaming-support/0005-winegstreamer-Insert-videoconvert-into-decoded-video.patch + patch_apply mfplat-streaming-support/0006-winegstreamer-Insert-audioconvert-into-decoded-audio.patch + patch_apply mfplat-streaming-support/0007-winegstreamer-Translate-H.264-caps-to-attributes.patch + patch_apply mfplat-streaming-support/0008-winegstreamer-Translate-WMV-caps-to-attributes.patch + patch_apply mfplat-streaming-support/0009-winegstreamer-Translate-AAC-caps-to-attributes.patch + patch_apply mfplat-streaming-support/0010-winegstreamer-Translate-MPEG-4-Section-2-caps-to-att.patch + patch_apply mfplat-streaming-support/0011-winegstreamer-Translate-WMA-caps-to-attributes.patch + patch_apply mfplat-streaming-support/0012-winegstreamer-Implement-IMFMediaSource-CreatePresent.patch + patch_apply mfplat-streaming-support/0013-winegstreamer-Introduce-IMFMediaType-GstCaps-convert.patch + patch_apply mfplat-streaming-support/0014-winegstreamer-Translate-H.264-attributes-to-caps.patch + patch_apply mfplat-streaming-support/0015-winegstreamer-Translate-WMV-attributes-to-caps.patch + patch_apply mfplat-streaming-support/0016-winegstreamer-Translate-AAC-attributes-to-caps.patch + patch_apply mfplat-streaming-support/0017-winegstreamer-Translate-MPEG-4-Section-2-attributes-.patch + patch_apply mfplat-streaming-support/0018-winegstreamer-Translate-WMA-attributes-to-caps.patch + patch_apply mfplat-streaming-support/0019-winegstreamer-Implement-IMFMediaSource-Start.patch + patch_apply mfplat-streaming-support/0020-winegstreamer-Implement-IMFMediaStream-RequestSample.patch + patch_apply mfplat-streaming-support/0021-winegstreamer-Implement-IMFMediaSource-GetCharacteri.patch + patch_apply mfplat-streaming-support/0022-winegstreamer-Calculate-the-MF_PD_DURATION-of-the-me.patch + patch_apply mfplat-streaming-support/0023-tools-Add-support-for-multiple-parent-directories.patch + patch_apply mfplat-streaming-support/0024-mf-Introduce-handler-helper.patch + patch_apply mfplat-streaming-support/0025-Introduce-IMFSample-GstBuffer-converter.patch + patch_apply mfplat-streaming-support/0026-winegstreamer-Implement-decoder-MFT-on-gstreamer.patch + patch_apply mfplat-streaming-support/0027-mfreadwrite-Select-all-streams-when-creating-a-sourc.patch + patch_apply mfplat-streaming-support/0028-Miscellaneous.patch + patch_apply mfplat-streaming-support/0029-WMV.patch + patch_apply mfplat-streaming-support/0030-mf-Ask-for-more-samples-from-upstream-node-when-upon.patch + patch_apply mfplat-streaming-support/0031-winegstreamer-Implement-IMFMedisStream-GetMediaSourc.patch + patch_apply mfplat-streaming-support/0032-Expose-PCM-output-type-on-AAC-decoder.patch + patch_apply mfplat-streaming-support/0033-mfplat-Add-I420-format-information.patch + patch_apply mfplat-streaming-support/0034-winegstreamer-Implement-Color-Converter-MFT.patch + patch_apply mfplat-streaming-support/0035-HACK-Set-BPS-to-16-for-output-template.patch + patch_apply mfplat-streaming-support/0036-Improve-tests.patch + patch_apply mfplat-streaming-support/0037-Revert-Improve-tests.patch + patch_apply mfplat-streaming-support/0038-Report-streams-backwards-and-only-select-one-of-each.patch + patch_apply mfplat-streaming-support/0039-winegstreamer-Implement-IMFMediaSource-Stop.patch + patch_apply mfplat-streaming-support/0040-winegstreamer-Introduce-MPEG-4-Section-2-video-decod.patch + patch_apply mfplat-streaming-support/0041-HACK-Switch-between-all-selection-streams-on-MF_SOUR.patch + patch_apply mfplat-streaming-support/0042-winegstreamer-Introduce-WMA-audio-decoder.patch + patch_apply mfplat-streaming-support/0043-Support-stereo-down-folding.patch + patch_apply mfplat-streaming-support/0044-winegstreamer-Implement-MF_SD_LANGUAGE.patch + patch_apply mfplat-streaming-support/0045-Revert-mf-topoloader-Add-a-structure-for-iterative-b.patch + patch_apply mfplat-streaming-support/0046-Revert-mf-topoloader-Clone-source-nodes-as-a-first-l.patch + patch_apply mfplat-streaming-support/0047-Revert-mf-topoloader-Switch-to-public-interface-for-.patch + patch_apply mfplat-streaming-support/0048-mf-Partially-implement-the-topology-loader.patch + patch_apply mfplat-streaming-support/0049-mf-Miscelaneous-fixes-to-topology-resolution.patch + patch_apply mfplat-streaming-support/0050-Rewrite-branch-resolver.patch + patch_apply mfplat-streaming-support/0051-mf-sar-Compare-against-native-media-type-in-IsMediaT.patch + patch_apply mfplat-streaming-support/0052-winegstreamer-Implement-audio-conversion-MFT.patch + patch_apply mfplat-streaming-support/0053-winegstreamer-Support-eAVEncH264VProfile_Constrained.patch +fi + # Patchset mmsystem.dll16-MIDIHDR_Refcount # | # | This patchset fixes the following Wine bugs: