diff options
163 files changed, 10488 insertions, 876 deletions
diff --git a/camera/CameraMetadata.cpp b/camera/CameraMetadata.cpp index f447c5b..7765914 100644 --- a/camera/CameraMetadata.cpp +++ b/camera/CameraMetadata.cpp @@ -133,11 +133,19 @@ void CameraMetadata::acquire(CameraMetadata &other) { } status_t CameraMetadata::append(const CameraMetadata &other) { + return append(other.mBuffer); +} + +status_t CameraMetadata::append(const camera_metadata_t* other) { if (mLocked) { ALOGE("%s: CameraMetadata is locked", __FUNCTION__); return INVALID_OPERATION; } - return append_camera_metadata(mBuffer, other.mBuffer); + size_t extraEntries = get_camera_metadata_entry_count(other); + size_t extraData = get_camera_metadata_data_count(other); + resizeIfNeeded(extraEntries, extraData); + + return append_camera_metadata(mBuffer, other); } size_t CameraMetadata::entryCount() const { diff --git a/camera/CameraParameters.cpp b/camera/CameraParameters.cpp index c51f265..af091f4 100644 --- a/camera/CameraParameters.cpp +++ b/camera/CameraParameters.cpp @@ -470,7 +470,7 @@ status_t CameraParameters::dump(int fd, const Vector<String16>& args) const const size_t SIZE = 256; char buffer[SIZE]; String8 result; - snprintf(buffer, 255, "CameraParameters::dump: mMap.size = %d\n", mMap.size()); + snprintf(buffer, 255, "CameraParameters::dump: mMap.size = %zu\n", mMap.size()); result.append(buffer); for (size_t i = 0; i < mMap.size(); i++) { String8 k, v; diff --git a/cmds/screenrecord/Android.mk b/cmds/screenrecord/Android.mk index b4a5947..d77fdb6 100644 --- a/cmds/screenrecord/Android.mk +++ b/cmds/screenrecord/Android.mk @@ -18,10 +18,14 @@ include $(CLEAR_VARS) LOCAL_SRC_FILES := \ screenrecord.cpp \ + EglWindow.cpp \ + TextRenderer.cpp \ + Overlay.cpp \ + Program.cpp LOCAL_SHARED_LIBRARIES := \ libstagefright libmedia libutils libbinder libstagefright_foundation \ - libjpeg libgui libcutils liblog + libjpeg libgui libcutils liblog libEGL libGLESv2 LOCAL_C_INCLUDES := \ frameworks/av/media/libstagefright \ @@ -30,6 +34,7 @@ LOCAL_C_INCLUDES := \ external/jpeg LOCAL_CFLAGS += -Wno-multichar +#LOCAL_CFLAGS += -UNDEBUG LOCAL_MODULE_TAGS := optional diff --git a/cmds/screenrecord/EglWindow.cpp b/cmds/screenrecord/EglWindow.cpp new file mode 100644 index 0000000..aa0517f --- /dev/null +++ b/cmds/screenrecord/EglWindow.cpp @@ -0,0 +1,146 @@ +/* + * Copyright 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "ScreenRecord" +//#define LOG_NDEBUG 0 +#include <utils/Log.h> + +#define EGL_EGLEXT_PROTOTYPES + +#include <gui/BufferQueue.h> +#include <gui/GraphicBufferAlloc.h> +#include <gui/Surface.h> + +#include "EglWindow.h" + +#include <EGL/egl.h> +#include <EGL/eglext.h> + +#include <assert.h> + +using namespace android; + + +status_t EglWindow::createWindow(const sp<IGraphicBufferProducer>& surface) { + status_t err = eglSetupContext(); + if (err != NO_ERROR) { + return err; + } + + surface->query(NATIVE_WINDOW_WIDTH, &mWidth); + surface->query(NATIVE_WINDOW_HEIGHT, &mHeight); + + // Output side (EGL surface to draw on). + sp<ANativeWindow> anw = new Surface(surface); + mEglSurface = eglCreateWindowSurface(mEglDisplay, mEglConfig, anw.get(), + NULL); + if (mEglSurface == EGL_NO_SURFACE) { + ALOGE("eglCreateWindowSurface error: %#x", eglGetError()); + eglRelease(); + return UNKNOWN_ERROR; + } + + return NO_ERROR; +} + +status_t EglWindow::makeCurrent() const { + if (!eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) { + ALOGE("eglMakeCurrent failed: %#x", eglGetError()); + return UNKNOWN_ERROR; + } + return NO_ERROR; +} + +status_t EglWindow::eglSetupContext() { + EGLBoolean result; + + mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); + if (mEglDisplay == EGL_NO_DISPLAY) { + ALOGE("eglGetDisplay failed: %#x", eglGetError()); + return UNKNOWN_ERROR; + } + + EGLint majorVersion, minorVersion; + result = eglInitialize(mEglDisplay, &majorVersion, &minorVersion); + if (result != EGL_TRUE) { + ALOGE("eglInitialize failed: %#x", eglGetError()); + return UNKNOWN_ERROR; + } + ALOGV("Initialized EGL v%d.%d", majorVersion, minorVersion); + + EGLint numConfigs = 0; + EGLint configAttribs[] = { + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, + EGL_RECORDABLE_ANDROID, 1, + EGL_RED_SIZE, 8, + EGL_GREEN_SIZE, 8, + EGL_BLUE_SIZE, 8, + EGL_NONE + }; + result = eglChooseConfig(mEglDisplay, configAttribs, &mEglConfig, 1, + &numConfigs); + if (result != EGL_TRUE) { + ALOGE("eglChooseConfig error: %#x", eglGetError()); + return UNKNOWN_ERROR; + } + + EGLint contextAttribs[] = { + EGL_CONTEXT_CLIENT_VERSION, 2, + EGL_NONE + }; + mEglContext = eglCreateContext(mEglDisplay, mEglConfig, EGL_NO_CONTEXT, + contextAttribs); + if (mEglContext == EGL_NO_CONTEXT) { + ALOGE("eglCreateContext error: %#x", eglGetError()); + return UNKNOWN_ERROR; + } + + return NO_ERROR; +} + +void EglWindow::eglRelease() { + ALOGV("EglWindow::eglRelease"); + if (mEglDisplay != EGL_NO_DISPLAY) { + eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, + EGL_NO_CONTEXT); + + if (mEglContext != EGL_NO_CONTEXT) { + eglDestroyContext(mEglDisplay, mEglContext); + } + + if (mEglSurface != EGL_NO_SURFACE) { + eglDestroySurface(mEglDisplay, mEglSurface); + } + } + + mEglDisplay = EGL_NO_DISPLAY; + mEglContext = EGL_NO_CONTEXT; + mEglSurface = EGL_NO_SURFACE; + mEglConfig = NULL; + + eglReleaseThread(); +} + +// Sets the presentation time on the current EGL buffer. +void EglWindow::presentationTime(nsecs_t whenNsec) const { + eglPresentationTimeANDROID(mEglDisplay, mEglSurface, whenNsec); +} + +// Swaps the EGL buffer. +void EglWindow::swapBuffers() const { + eglSwapBuffers(mEglDisplay, mEglSurface); +} diff --git a/cmds/screenrecord/EglWindow.h b/cmds/screenrecord/EglWindow.h new file mode 100644 index 0000000..02a2efc --- /dev/null +++ b/cmds/screenrecord/EglWindow.h @@ -0,0 +1,84 @@ +/* + * Copyright 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SCREENRECORD_EGL_WINDOW_H +#define SCREENRECORD_EGL_WINDOW_H + +#include <gui/BufferQueue.h> +#include <utils/Errors.h> + +#include <EGL/egl.h> + +namespace android { + +/* + * Wraps EGL display, context, surface, config for a window surface. + * + * Not thread safe. + */ +class EglWindow { +public: + EglWindow() : + mEglDisplay(EGL_NO_DISPLAY), + mEglContext(EGL_NO_CONTEXT), + mEglSurface(EGL_NO_SURFACE), + mEglConfig(NULL), + mWidth(0), + mHeight(0) + {} + ~EglWindow() { eglRelease(); } + + // Creates an EGL window for the supplied surface. + status_t createWindow(const sp<IGraphicBufferProducer>& surface); + + // Return width and height values (obtained from IGBP). + int getWidth() const { return mWidth; } + int getHeight() const { return mHeight; } + + // Release anything we created. + void release() { eglRelease(); } + + // Make this context current. + status_t makeCurrent() const; + + // Sets the presentation time on the current EGL buffer. + void presentationTime(nsecs_t whenNsec) const; + + // Swaps the EGL buffer. + void swapBuffers() const; + +private: + EglWindow(const EglWindow&); + EglWindow& operator=(const EglWindow&); + + // Init display, create config and context. + status_t eglSetupContext(); + void eglRelease(); + + // Basic EGL goodies. + EGLDisplay mEglDisplay; + EGLContext mEglContext; + EGLSurface mEglSurface; + EGLConfig mEglConfig; + + // Surface dimensions. + int mWidth; + int mHeight; +}; + +}; // namespace android + +#endif /*SCREENRECORD_EGL_WINDOW_H*/ diff --git a/cmds/screenrecord/FontBitmap.h b/cmds/screenrecord/FontBitmap.h new file mode 100644 index 0000000..2b94f35 --- /dev/null +++ b/cmds/screenrecord/FontBitmap.h @@ -0,0 +1,6571 @@ +// auto-generated from Android default system font at 24pts +class FontBitmap { +public: + static const uint32_t width = 256; + static const uint32_t height = 204; + static const uint32_t numGlyphs = 95; + static const uint32_t firstGlyphChar = 32; + static const uint32_t maxGlyphHeight = 34; + static const uint32_t outlineWidth = 1; + static const uint8_t pixels[]; + static const uint16_t yoffset[]; + static const uint16_t glyphWidth[]; +}; +const uint8_t FontBitmap::pixels[] = { + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x64, 0xca, 0xd2, + 0xb4, 0x22, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xe, 0x40, 0x68, 0x62, 0x4a, + 0x4a, 0x6a, 0x5c, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xb4, 0x9b, 0xd7, + 0x4b, 0x48, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xe, 0x40, 0x68, 0x66, 0x3e, 0xa, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x2, 0x66, 0x9a, 0x98, + 0x56, 0x0, 0x1c, 0xa0, 0xa8, 0x9c, 0x16, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x4, 0xe, 0x1a, 0x20, 0x16, 0xc, + 0x0, 0x0, 0x0, 0x3e, 0x27, 0x67, 0x67, 0x13, + 0x39, 0x67, 0x61, 0xde, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x6, 0x12, 0x16, 0x10, 0x6, + 0xc, 0x16, 0x14, 0xa, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x14, 0xe4, 0xbb, 0xff, + 0x5b, 0x78, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x10, 0x3e, 0x5a, 0x54, 0x2c, + 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x1a, 0x4a, 0x6c, 0x62, 0x38, 0xa, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3e, 0x27, 0x67, 0x67, 0x21, 0x32, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x6, 0x9c, 0xd, 0x9d, 0x8d, + 0xcc, 0x0, 0x74, 0x43, 0xc7, 0x39, 0xdc, 0x24, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x8, 0x14, 0x18, 0x10, 0x4, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa, 0x14, 0x1a, 0x12, 0x6, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1c, 0x4a, 0x6c, 0x68, 0x40, + 0x14, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x4, 0x2a, 0x58, 0x76, + 0x68, 0x3e, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x54, 0x11, 0x23, 0x23, 0x23, 0xfe, + 0x0, 0x0, 0x0, 0x64, 0x63, 0xff, 0xff, 0x35, + 0x8d, 0xff, 0xf1, 0xf8, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9c, 0x19, 0x23, 0x15, 0x7e, + 0xb, 0x23, 0x21, 0xb8, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x2e, 0xba, 0xfe, 0x35, 0xcb, 0xff, + 0x77, 0x5, 0xd8, 0x4a, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2, 0x78, 0xfc, 0x2f, 0x5f, 0x51, 0x19, + 0xe0, 0x3c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x20, 0xba, 0xfe, 0x41, 0x67, 0x5f, 0x21, 0xf2, + 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x64, 0x63, 0xff, 0xff, 0x57, 0x4e, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x88, 0x15, 0xcb, 0xff, 0xdb, + 0xd4, 0x0, 0x7a, 0x9b, 0xff, 0xef, 0x4f, 0xd8, + 0x14, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x9c, 0x1d, 0x23, 0x13, 0x56, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x12, + 0xfa, 0x21, 0x23, 0x17, 0x5a, 0x0, 0x0, 0x0, + 0x0, 0x3e, 0xd0, 0xfe, 0x43, 0x67, 0x61, 0x33, + 0xfe, 0xae, 0x22, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x16, 0x4e, 0x98, 0xd4, 0xf8, + 0x5, 0xde, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x6, 0x70, 0xf0, 0x11, 0x53, 0x69, + 0x5f, 0x2f, 0xfe, 0xb2, 0x26, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x8c, 0x89, 0xff, 0xff, 0xff, 0xfe, + 0x0, 0x0, 0x0, 0x7a, 0x63, 0xff, 0xff, 0x27, + 0x8d, 0xff, 0xeb, 0xfc, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xec, 0xcb, 0xff, 0x89, 0xbe, + 0x71, 0xff, 0xdf, 0xdc, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x38, 0xf6, 0x5d, 0xd9, 0xff, 0xff, 0xff, + 0xff, 0xe9, 0x7f, 0xfe, 0x5e, 0x0, 0x0, 0x0, + 0x0, 0x58, 0xb, 0xaf, 0xff, 0xff, 0xff, 0xf1, + 0x71, 0xec, 0x16, 0x4, 0x38, 0x38, 0x36, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x12, + 0xde, 0x49, 0xdb, 0xff, 0xff, 0xff, 0xf9, 0x97, + 0xfe, 0x52, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x7a, 0x63, 0xff, 0xff, 0x4d, 0x4c, 0x0, 0x0, + 0x0, 0x0, 0x42, 0xfe, 0xbb, 0xff, 0xfb, 0x5f, + 0xc0, 0x0, 0x6a, 0x25, 0xdf, 0xff, 0xed, 0x33, + 0x9e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xd2, 0xcb, 0xff, 0x89, 0x84, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x62, + 0x31, 0xff, 0xff, 0x8d, 0x66, 0x0, 0x0, 0x0, + 0x4e, 0xfe, 0x71, 0xe5, 0xff, 0xff, 0xff, 0xff, + 0xd1, 0x4b, 0xe8, 0x24, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x78, 0xe8, 0xfe, 0x37, 0x73, 0xa3, 0xcf, + 0xf5, 0x15, 0xa, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4, 0xa6, 0x15, 0xa5, 0xf7, 0xff, 0xff, + 0xff, 0xff, 0xd3, 0x53, 0xf2, 0x2e, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xb0, 0x89, 0xff, 0xff, 0xff, 0xfe, + 0x0, 0x0, 0x0, 0x7a, 0x63, 0xff, 0xf5, 0xfe, + 0x8d, 0xff, 0xd1, 0xf6, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xe, 0xfe, 0xef, 0xff, 0x5b, 0xe2, + 0x9b, 0xff, 0xbb, 0xe8, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xd4, 0x6b, 0xfd, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x95, 0xf6, 0x16, 0x0, 0x0, + 0x0, 0xc4, 0x8f, 0xff, 0xff, 0xbf, 0xdb, 0xff, + 0xf9, 0x39, 0x5e, 0x68, 0x13, 0x67, 0xfe, 0x6c, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x72, + 0x31, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x89, 0xda, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x7a, 0x63, 0xff, 0xff, 0x19, 0x2a, 0x0, 0x0, + 0x0, 0x4, 0xda, 0x77, 0xff, 0xff, 0x89, 0xf4, + 0x30, 0x0, 0xc, 0xc0, 0x41, 0xf9, 0xff, 0xc9, + 0xfe, 0x3c, 0x0, 0x0, 0x0, 0x6, 0x2e, 0x2e, + 0x2a, 0xe8, 0xbf, 0xff, 0x7b, 0x9e, 0x1a, 0x1a, + 0x1a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, + 0x1a, 0x32, 0x46, 0x34, 0x1c, 0x4, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc8, + 0x8d, 0xff, 0xff, 0x31, 0x62, 0x0, 0x0, 0x12, + 0xf0, 0x83, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xf7, 0x4f, 0xbc, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xd6, 0xaf, 0xef, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x15, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x64, 0x11, 0xd1, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xfb, 0x5d, 0xc8, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xb0, 0x89, 0xff, 0xff, 0xff, 0xfe, + 0x0, 0x0, 0x0, 0x7a, 0x63, 0xff, 0xdb, 0xfe, + 0x8d, 0xff, 0xb5, 0xe2, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x3c, 0x29, 0xff, 0xff, 0x23, 0xf2, + 0xc3, 0xff, 0x93, 0xc2, 0x0, 0x0, 0x0, 0x0, + 0x22, 0x9, 0xe9, 0xff, 0xff, 0xef, 0x93, 0x89, + 0xe5, 0xff, 0xff, 0xfd, 0x39, 0x68, 0x0, 0x0, + 0x0, 0xf2, 0xd5, 0xff, 0xa7, 0xfe, 0xf, 0xeb, + 0xff, 0x87, 0xac, 0xf4, 0x9b, 0xff, 0xa3, 0x7a, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc8, + 0x9f, 0xff, 0xff, 0xed, 0x85, 0x9d, 0xfd, 0xff, + 0xeb, 0xfe, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x7a, 0x63, 0xff, 0xe7, 0xfe, 0x6, 0x0, 0x0, + 0x0, 0x4c, 0x11, 0xed, 0xff, 0xdf, 0x9, 0x52, + 0x0, 0x0, 0x0, 0x1a, 0xf4, 0xa3, 0xff, 0xff, + 0x6f, 0xc0, 0x0, 0x0, 0x0, 0x42, 0x17, 0x57, + 0xfe, 0xf8, 0xb5, 0xff, 0x6d, 0xec, 0x5, 0x41, + 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x12, + 0xb, 0x3f, 0x3f, 0x3f, 0xf, 0x1c, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x16, 0xfe, + 0xd5, 0xff, 0xd1, 0xfc, 0x12, 0x0, 0x0, 0x68, + 0x31, 0xf9, 0xff, 0xff, 0xdf, 0x89, 0x95, 0xf3, + 0xff, 0xff, 0xdd, 0xfe, 0x2a, 0x0, 0x0, 0x0, + 0x0, 0xe4, 0xdd, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x15, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xe0, 0x9b, 0xff, 0xff, 0xff, 0xbd, 0x7f, + 0x9f, 0xf9, 0xff, 0xff, 0xe3, 0xfe, 0x20, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xb0, 0x89, 0xff, 0xff, 0xff, 0xfe, + 0x0, 0x0, 0x0, 0x7a, 0x63, 0xff, 0xbf, 0xf8, + 0x8d, 0xff, 0x95, 0xc2, 0x0, 0x0, 0x0, 0x14, + 0x34, 0x50, 0xaa, 0x5f, 0xff, 0xeb, 0xfe, 0xfe, + 0xe5, 0xff, 0x69, 0xb0, 0x36, 0x16, 0x0, 0x0, + 0x4e, 0x4d, 0xff, 0xff, 0xff, 0x73, 0xf2, 0xe6, + 0x3b, 0xfd, 0xff, 0xff, 0x93, 0xb4, 0x0, 0x0, + 0x0, 0xfa, 0xeb, 0xff, 0x83, 0xbe, 0xf8, 0xcd, + 0xff, 0xa1, 0xea, 0x43, 0xfb, 0xf9, 0x3d, 0x7a, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe8, + 0xcd, 0xff, 0xff, 0x83, 0xf4, 0xfe, 0xc1, 0xff, + 0xff, 0x15, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x7a, 0x63, 0xff, 0xc7, 0xf0, 0x0, 0x0, 0x0, + 0x0, 0xbc, 0x7f, 0xff, 0xff, 0x7f, 0xcc, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x74, 0x2d, 0xfd, 0xff, + 0xd9, 0xfe, 0x22, 0x0, 0x0, 0x82, 0x71, 0xff, + 0xdb, 0x85, 0xb1, 0xff, 0x71, 0x8f, 0xe5, 0xeb, + 0x5, 0x1c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, + 0x2f, 0xff, 0xff, 0xff, 0x3f, 0x34, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x66, 0x37, + 0xff, 0xff, 0x89, 0xc4, 0x0, 0x0, 0x0, 0xbe, + 0x93, 0xff, 0xff, 0xf5, 0x27, 0xe0, 0xf2, 0x61, + 0xff, 0xff, 0xff, 0x57, 0x76, 0x0, 0x0, 0x0, + 0x0, 0xcc, 0x8f, 0xa7, 0xa7, 0xc9, 0xff, 0xff, + 0xff, 0x15, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x14, 0xfe, 0xed, 0xff, 0xff, 0xbf, 0xfe, 0xcc, + 0xfa, 0x89, 0xff, 0xff, 0xff, 0x47, 0x4e, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xb0, 0x89, 0xff, 0xff, 0xff, 0xfe, + 0x0, 0x0, 0x0, 0x60, 0x63, 0xff, 0xa1, 0xe4, + 0x8d, 0xff, 0x75, 0x8a, 0x0, 0x0, 0x0, 0x7e, + 0x33, 0x4d, 0x4d, 0xa1, 0xff, 0xd5, 0x4d, 0x55, + 0xff, 0xff, 0x6b, 0x4d, 0x37, 0x8e, 0x0, 0x0, + 0x64, 0x63, 0xff, 0xff, 0xff, 0x49, 0x8a, 0x18, + 0xfc, 0xe1, 0xff, 0xff, 0xb7, 0xb6, 0x0, 0x0, + 0x0, 0xf8, 0xdf, 0xff, 0x91, 0xf4, 0xfe, 0xdb, + 0xff, 0x93, 0xfe, 0xcf, 0xff, 0x97, 0xf2, 0x1a, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xea, + 0xcf, 0xff, 0xff, 0x7d, 0xe0, 0xfe, 0xd3, 0xff, + 0xf5, 0xfe, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x60, 0x63, 0xff, 0xa3, 0xc4, 0x0, 0x0, 0x0, + 0x8, 0xfa, 0xcf, 0xff, 0xfb, 0x21, 0x50, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x10, 0xfc, 0xcb, 0xff, + 0xff, 0x4d, 0x78, 0x0, 0x0, 0x80, 0x8f, 0xf9, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, + 0x43, 0x1c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2e, + 0x2f, 0xff, 0xff, 0xff, 0x3f, 0x46, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xcc, 0x91, + 0xff, 0xff, 0x2f, 0x5e, 0x0, 0x0, 0x0, 0xec, + 0xc7, 0xff, 0xff, 0xc3, 0xf8, 0xc, 0x30, 0xfe, + 0xef, 0xff, 0xff, 0x93, 0xb6, 0x0, 0x0, 0x0, + 0x0, 0x58, 0xa0, 0xc8, 0xee, 0x7f, 0xff, 0xff, + 0xff, 0x15, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1a, 0x33, 0xff, 0xff, 0xff, 0x77, 0xac, 0x0, + 0x80, 0x43, 0xff, 0xff, 0xff, 0x67, 0x68, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xb0, 0x89, 0xff, 0xff, 0xff, 0xfe, + 0x0, 0x0, 0x0, 0x3a, 0x1f, 0x51, 0x2d, 0xa8, + 0x2d, 0x51, 0x1d, 0x46, 0x0, 0x0, 0x0, 0xac, + 0xa9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xbb, 0xbc, 0x0, 0x0, + 0x4c, 0x49, 0xff, 0xff, 0xff, 0x85, 0xf6, 0x60, + 0xc2, 0x47, 0x57, 0x57, 0x41, 0x8e, 0x0, 0x0, + 0x0, 0xdc, 0xb1, 0xff, 0xeb, 0x7b, 0x99, 0xff, + 0xff, 0x5d, 0x7d, 0xff, 0xdf, 0xf, 0x60, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xce, + 0xa7, 0xff, 0xff, 0xcb, 0xb, 0x9b, 0xff, 0xff, + 0xaf, 0xee, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3a, 0x1d, 0x4d, 0x29, 0x74, 0x0, 0x0, 0x0, + 0x32, 0x1f, 0xfb, 0xff, 0xd5, 0xfc, 0xa, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xcc, 0x95, 0xff, + 0xff, 0x9b, 0xc6, 0x0, 0x0, 0x58, 0xee, 0x13, + 0x67, 0xbd, 0xff, 0xff, 0xf7, 0xaf, 0x6b, 0x19, + 0xee, 0x1c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2e, + 0x2f, 0xff, 0xff, 0xff, 0x3f, 0x46, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0xfe, 0xd9, + 0xff, 0xcf, 0xfc, 0x10, 0x0, 0x0, 0x0, 0xf8, + 0xdf, 0xff, 0xff, 0xa9, 0xda, 0x0, 0x0, 0xfa, + 0xd7, 0xff, 0xff, 0xaf, 0xd6, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xa2, 0x7f, 0xff, 0xff, + 0xff, 0x15, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1a, 0x1b, 0x63, 0x63, 0x63, 0x27, 0x4a, 0x0, + 0xa2, 0x5b, 0xff, 0xff, 0xff, 0x51, 0x58, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xb0, 0x89, 0xff, 0xff, 0xff, 0xfe, + 0x0, 0x0, 0x0, 0x8, 0x2e, 0x3a, 0x34, 0x1e, + 0x34, 0x3a, 0x2e, 0x8, 0x0, 0x0, 0x0, 0xa4, + 0x93, 0xdd, 0xdd, 0xfb, 0xff, 0xe7, 0xdd, 0xed, + 0xff, 0xf5, 0xdd, 0xdd, 0xa1, 0xb6, 0x0, 0x0, + 0x20, 0x9, 0xe9, 0xff, 0xff, 0xf9, 0x93, 0x1b, + 0xee, 0x9a, 0x6c, 0x5e, 0x40, 0x1a, 0x0, 0x0, + 0x0, 0x82, 0x2d, 0xe7, 0xff, 0xff, 0xff, 0xff, + 0xb5, 0x27, 0xf1, 0xff, 0x59, 0xc4, 0x4, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7c, + 0x3d, 0xfb, 0xff, 0xff, 0xe9, 0xff, 0xff, 0xdf, + 0x21, 0x7c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x8, 0x2a, 0x36, 0x30, 0xe, 0x0, 0x0, 0x0, + 0x6e, 0x59, 0xff, 0xff, 0xaf, 0xe2, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x8c, 0x65, 0xff, + 0xff, 0xc9, 0xf0, 0x0, 0x0, 0x0, 0x4, 0x8e, + 0xd, 0xd1, 0xff, 0xfb, 0xfd, 0x5b, 0xee, 0x48, + 0x6, 0x0, 0x0, 0x20, 0x7a, 0xb0, 0xc8, 0xd4, + 0x2f, 0xff, 0xff, 0xff, 0x3f, 0xd8, 0xc8, 0xb0, + 0x7c, 0x22, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x6c, 0x3b, 0xff, + 0xff, 0x87, 0xc2, 0x0, 0x0, 0x0, 0x0, 0xfc, + 0xe9, 0xff, 0xff, 0xa3, 0xd0, 0x0, 0x0, 0xf4, + 0xd1, 0xff, 0xff, 0xbb, 0xe0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xa2, 0x7f, 0xff, 0xff, + 0xff, 0x15, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x8, 0x38, 0x60, 0x7a, 0x62, 0x3c, 0xc, 0x30, + 0xfc, 0xb7, 0xff, 0xff, 0xf3, 0x17, 0x2c, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xb0, 0x89, 0xff, 0xff, 0xff, 0xfe, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5a, + 0xce, 0xf0, 0x5, 0xf9, 0xff, 0x4f, 0xfe, 0xa9, + 0xff, 0xb1, 0xfe, 0xf2, 0xd2, 0x68, 0x0, 0x0, + 0x0, 0xd2, 0x67, 0xfb, 0xff, 0xff, 0xff, 0xf3, + 0xa5, 0x2f, 0xf0, 0x5a, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x10, 0xc8, 0x19, 0x85, 0xab, 0xa1, 0x69, + 0xfe, 0xb7, 0xff, 0xb1, 0xfc, 0x2c, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2e, + 0xfc, 0x9b, 0xff, 0xff, 0xff, 0xff, 0xc5, 0x23, + 0xbc, 0x46, 0x6a, 0x7a, 0x52, 0x1c, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa0, 0x81, 0xff, 0xff, 0x95, 0xc2, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x54, 0x43, 0xff, + 0xff, 0xe9, 0xfe, 0x0, 0x0, 0x0, 0x38, 0xfe, + 0xa7, 0xff, 0xd9, 0x7d, 0xff, 0xeb, 0x29, 0x9e, + 0x0, 0x0, 0x0, 0x5a, 0x49, 0x9f, 0x9f, 0x9f, + 0xa9, 0xff, 0xff, 0xff, 0xad, 0x9f, 0x9f, 0x9f, + 0x4d, 0x5e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x50, 0xa6, 0xd0, + 0xdc, 0xdc, 0xdc, 0xda, 0xb8, 0x74, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xd0, 0x93, 0xff, + 0xfd, 0x2d, 0x5a, 0x0, 0x0, 0x0, 0x0, 0xfc, + 0xeb, 0xff, 0xff, 0xa3, 0xce, 0x0, 0x0, 0xf2, + 0xd1, 0xff, 0xff, 0xbd, 0xe4, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xa2, 0x7f, 0xff, 0xff, + 0xff, 0x15, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x16, 0xe0, + 0x5f, 0xff, 0xff, 0xff, 0x99, 0xe8, 0x6, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xb0, 0x89, 0xff, 0xff, 0xff, 0xfe, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4e, 0x3d, 0xff, 0xfd, 0x15, 0xf8, 0xcf, + 0xff, 0x89, 0xb4, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x36, 0xf2, 0x53, 0xdb, 0xff, 0xff, 0xff, + 0xff, 0xf9, 0x93, 0x5, 0x84, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x6, 0x52, 0xa0, 0xc6, 0xc0, 0xe6, + 0x5d, 0xff, 0xef, 0x25, 0xd6, 0xd4, 0xd4, 0xaa, + 0x54, 0x4, 0x0, 0x0, 0x0, 0x0, 0x1c, 0xda, + 0x3b, 0xdb, 0xff, 0xff, 0xff, 0xfb, 0x47, 0xec, + 0x36, 0xf, 0x6f, 0x6f, 0x43, 0x6e, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xbc, 0x95, 0xff, 0xff, 0x83, 0xac, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x2c, 0x27, 0xff, + 0xff, 0xfb, 0xfe, 0x6, 0x0, 0x0, 0x40, 0x6b, + 0xff, 0xff, 0x51, 0xfe, 0xd1, 0xff, 0xcb, 0xb4, + 0x0, 0x0, 0x0, 0x86, 0x77, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x7b, 0x8a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xb0, 0x87, 0xb3, + 0xb3, 0xb3, 0xb3, 0xb3, 0xab, 0xec, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x1a, 0xfe, 0xdb, 0xff, + 0xcd, 0xfc, 0x10, 0x0, 0x0, 0x0, 0x0, 0xfc, + 0xeb, 0xff, 0xff, 0xa3, 0xce, 0x0, 0x0, 0xf2, + 0xd1, 0xff, 0xff, 0xbd, 0xe4, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xa2, 0x7f, 0xff, 0xff, + 0xff, 0x15, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, 0xc6, 0x37, + 0xf1, 0xff, 0xff, 0xd5, 0xf, 0x64, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xb0, 0x89, 0xff, 0xff, 0xff, 0xfe, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x42, 0xc0, + 0xea, 0xfa, 0x6f, 0xff, 0xe3, 0xfe, 0xfe, 0xf1, + 0xff, 0x5b, 0xf6, 0xd2, 0x78, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x26, 0xbc, 0x5, 0x6d, 0xc9, 0xff, + 0xff, 0xff, 0xff, 0xb9, 0xfe, 0x34, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x64, 0x11, + 0xe3, 0xff, 0x79, 0x13, 0x8b, 0xb7, 0xb7, 0x89, + 0x11, 0xb0, 0x4, 0x0, 0x0, 0x0, 0xb6, 0x41, + 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe9, 0x2d, + 0xca, 0x43, 0xff, 0xff, 0x93, 0x96, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc8, 0xa1, 0xff, 0xff, 0x7b, 0xa0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x16, 0x17, 0xff, + 0xff, 0xff, 0x15, 0xe, 0x0, 0x0, 0x40, 0x21, + 0xb7, 0xad, 0xfa, 0xbc, 0x4b, 0xf1, 0x71, 0xb0, + 0x0, 0x0, 0x0, 0x82, 0x77, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x7b, 0x88, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xdc, 0xc1, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xf5, 0xfc, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x6e, 0x3f, 0xff, 0xff, + 0x85, 0xbe, 0x0, 0x0, 0x0, 0x0, 0x0, 0xfc, + 0xeb, 0xff, 0xff, 0xa3, 0xce, 0x0, 0x0, 0xf2, + 0xd1, 0xff, 0xff, 0xbd, 0xe4, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xa2, 0x7f, 0xff, 0xff, + 0xff, 0x15, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xa, 0xb6, 0x2b, 0xe3, + 0xff, 0xff, 0xeb, 0x31, 0xb0, 0x4, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x8e, 0x89, 0xff, 0xff, 0xff, 0xfe, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x82, 0x77, + 0xd7, 0xd7, 0xe9, 0xff, 0xf5, 0xd7, 0xd7, 0xff, + 0xff, 0xdb, 0xd7, 0xaf, 0xce, 0x0, 0x0, 0x0, + 0x3a, 0x6a, 0x90, 0x80, 0x7c, 0xb8, 0xfc, 0x47, + 0xd3, 0xff, 0xff, 0xff, 0x65, 0x8e, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1a, 0xf4, 0x9b, + 0xff, 0xcb, 0x17, 0xdd, 0xff, 0xff, 0xff, 0xff, + 0xd9, 0x11, 0x56, 0x0, 0x0, 0x1c, 0xfe, 0xd9, + 0xff, 0xff, 0xd3, 0x4f, 0xf3, 0xff, 0xff, 0xd7, + 0x15, 0x77, 0xff, 0xff, 0x7b, 0x96, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xca, 0xa3, 0xff, 0xff, 0x79, 0x9e, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x12, 0xf, 0xff, + 0xff, 0xff, 0x1d, 0xe, 0x0, 0x0, 0xa, 0x86, + 0xbe, 0xd, 0x76, 0x22, 0xda, 0x1f, 0xe0, 0x3e, + 0x0, 0x0, 0x0, 0x56, 0x41, 0x8d, 0x8d, 0x8d, + 0x99, 0xff, 0xff, 0xff, 0x9f, 0x8d, 0x8d, 0x8d, + 0x43, 0x5a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xcc, 0xc1, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xf5, 0xfa, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xd4, 0x97, 0xff, 0xfd, + 0x29, 0x58, 0x0, 0x0, 0x0, 0x0, 0x0, 0xfc, + 0xe9, 0xff, 0xff, 0xa3, 0xd0, 0x0, 0x0, 0xf4, + 0xd1, 0xff, 0xff, 0xbb, 0xe0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xa2, 0x7f, 0xff, 0xff, + 0xff, 0x15, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x6, 0xa8, 0x21, 0xdb, 0xff, + 0xff, 0xf3, 0x49, 0xd4, 0x12, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x58, 0x1b, 0x35, 0x35, 0x35, 0xfe, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x88, 0x8d, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xd1, 0xd2, 0x0, 0x0, 0x0, + 0xd4, 0x6d, 0x73, 0x73, 0x47, 0x88, 0x1e, 0xb2, + 0x21, 0xf3, 0xff, 0xff, 0xa7, 0xc8, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xa8, 0x41, 0xfb, + 0xf9, 0x3d, 0x93, 0xff, 0xf3, 0x73, 0x79, 0xf7, + 0xff, 0x8b, 0xae, 0x0, 0x0, 0x48, 0x43, 0xff, + 0xff, 0xff, 0x67, 0xf8, 0x61, 0xfb, 0xff, 0xff, + 0xbf, 0xcf, 0xff, 0xff, 0x41, 0x5a, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc2, 0x9b, 0xff, 0xff, 0x7f, 0xa6, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x21, 0xff, + 0xff, 0xff, 0x5, 0x8, 0x0, 0x0, 0x0, 0x0, + 0x2, 0x2, 0x2, 0x0, 0x8, 0x8, 0x8, 0x0, + 0x0, 0x0, 0x0, 0x1c, 0x68, 0x9c, 0xb6, 0xc2, + 0x2f, 0xff, 0xff, 0xff, 0x3f, 0xc8, 0xb6, 0x9c, + 0x6a, 0x1c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x8c, 0x9, 0xd, + 0xd, 0xd, 0xd, 0xd, 0xb, 0xde, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1c, 0xfe, 0xdd, 0xff, 0xcb, + 0xfc, 0xe, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf8, + 0xdf, 0xff, 0xff, 0xa9, 0xdc, 0x0, 0x0, 0xfa, + 0xd7, 0xff, 0xff, 0xaf, 0xd4, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xa2, 0x7f, 0xff, 0xff, + 0xff, 0x15, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x4, 0x9a, 0x17, 0xd1, 0xff, 0xff, + 0xf9, 0x5b, 0xe4, 0x20, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x8, 0x1a, 0x2c, 0x36, 0x26, 0x14, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x60, 0x2b, + 0x4d, 0x4d, 0xe9, 0xff, 0x8b, 0x4d, 0xa7, 0xff, + 0xd3, 0x4d, 0x4d, 0x3f, 0xaa, 0x0, 0x0, 0x0, + 0xee, 0xe9, 0xff, 0xff, 0xaf, 0xe6, 0x6, 0x14, + 0xfe, 0xd9, 0xff, 0xff, 0xb9, 0xd8, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x48, 0xfe, 0xcf, 0xff, + 0x97, 0xfe, 0xc1, 0xff, 0xb1, 0xfa, 0xfa, 0xb9, + 0xff, 0xbb, 0xdc, 0x0, 0x0, 0x5c, 0x5f, 0xff, + 0xff, 0xff, 0x4f, 0xa8, 0xf6, 0x7f, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xd9, 0xfe, 0x1c, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xac, 0x8b, 0xff, 0xff, 0x8b, 0xb8, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, 0x35, 0xff, + 0xff, 0xf3, 0xfe, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2e, + 0x2f, 0xff, 0xff, 0xff, 0x3f, 0x46, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x4, + 0x6, 0x6, 0x6, 0x6, 0x4, 0x2, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x74, 0x43, 0xff, 0xff, 0x81, + 0xba, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xea, + 0xc5, 0xff, 0xff, 0xc5, 0xf8, 0x10, 0x32, 0xfe, + 0xf1, 0xff, 0xff, 0x91, 0xb4, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xa2, 0x7f, 0xff, 0xff, + 0xff, 0x15, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x88, 0xf, 0xc7, 0xff, 0xff, 0xfd, + 0x6b, 0xf0, 0x2c, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x52, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, 0x30, + 0x68, 0x13, 0xfd, 0xff, 0x3f, 0xf2, 0xb3, 0xff, + 0xa7, 0xe4, 0x54, 0x3a, 0x1a, 0x0, 0x0, 0x0, + 0xee, 0xc9, 0xff, 0xff, 0xeb, 0x19, 0xe2, 0xe0, + 0x21, 0xf3, 0xff, 0xff, 0xa7, 0xc6, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x8, 0xe0, 0x7d, 0xff, 0xdf, + 0xf, 0xf0, 0xcb, 0xff, 0xa7, 0xe4, 0xe6, 0xad, + 0xff, 0xc5, 0xe2, 0x0, 0x0, 0x48, 0x43, 0xff, + 0xff, 0xff, 0x99, 0xfc, 0xd8, 0xfe, 0x9f, 0xff, + 0xff, 0xff, 0xff, 0x63, 0xca, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x84, 0x69, 0xff, 0xff, 0xa5, 0xd4, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x72, 0x57, 0xff, + 0xff, 0xd5, 0xf8, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2e, + 0x2f, 0xff, 0xff, 0xff, 0x3f, 0x46, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x3c, 0xcc, 0xf2, 0xf6, + 0xdc, 0x78, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x3c, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0x14, + 0x0, 0x0, 0x0, 0xd8, 0x9b, 0xff, 0xfb, 0x27, + 0x54, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xba, + 0x8f, 0xff, 0xff, 0xf7, 0x2d, 0xe8, 0xf4, 0x63, + 0xff, 0xff, 0xff, 0x53, 0x72, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xa2, 0x7f, 0xff, 0xff, + 0xff, 0x15, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x74, 0x9, 0xbd, 0xff, 0xff, 0xff, 0x7d, + 0xfe, 0xe6, 0xe0, 0xe0, 0xda, 0xb4, 0x66, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x8a, 0x89, 0xff, 0xff, 0xff, 0xfe, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x64, 0x4d, 0xff, 0xf9, 0x9, 0xfa, 0xd7, 0xff, + 0x7d, 0xa6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb2, 0x77, 0xff, 0xff, 0xff, 0xe1, 0x95, 0x91, + 0xdd, 0xff, 0xff, 0xff, 0x5f, 0x8a, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x8, 0x1f, 0xf1, 0xff, 0x59, + 0xc4, 0xd4, 0xb1, 0xff, 0xd1, 0x5, 0xfe, 0xcd, + 0xff, 0xab, 0xce, 0x0, 0x0, 0x1c, 0xfe, 0xdf, + 0xff, 0xff, 0xff, 0xb1, 0x87, 0x9f, 0xe3, 0xff, + 0xff, 0xff, 0xfd, 0x63, 0xea, 0x1e, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x48, 0x39, 0xff, 0xff, 0xc5, 0xf4, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xb0, 0x7f, 0xff, + 0xff, 0xb1, 0xdc, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x22, + 0x2f, 0xff, 0xff, 0xff, 0x3f, 0x36, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x74, 0x71, 0xe3, 0xe3, + 0xaf, 0xc4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x68, 0x6f, 0xff, 0xff, 0xff, 0x35, 0x26, + 0x0, 0x0, 0x20, 0xfe, 0xe1, 0xff, 0xc9, 0xfa, + 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x60, + 0x2b, 0xf7, 0xff, 0xff, 0xe5, 0x93, 0x9d, 0xf5, + 0xff, 0xff, 0xd9, 0xfe, 0x26, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xa2, 0x7f, 0xff, 0xff, + 0xff, 0x15, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xda, 0xab, 0xff, 0xff, 0xff, 0xed, 0xb7, + 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0x9d, 0xd0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xb0, 0x89, 0xff, 0xff, 0xff, 0xfe, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa4, 0x7b, 0xff, 0xd9, 0xfc, 0x5, 0xf7, 0xff, + 0x4f, 0x66, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x42, 0x5, 0xb9, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xb5, 0xfe, 0x30, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x8, 0xdc, 0x55, 0x8d, 0xfc, + 0x2c, 0x94, 0x5f, 0xff, 0xff, 0xdb, 0xd5, 0xff, + 0xff, 0x59, 0x8a, 0x0, 0x0, 0x0, 0xc2, 0x55, + 0xf9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xf5, 0x45, 0xce, 0x10, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x16, 0xfe, 0xe5, 0xff, 0xef, 0x5, 0x2a, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x2, 0xee, 0xb3, 0xff, + 0xff, 0x6d, 0x9a, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x14, + 0x11, 0x67, 0x67, 0x67, 0x19, 0x20, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x9c, 0x7f, 0xff, 0xff, + 0xc5, 0xe4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x8c, 0x6f, 0xff, 0xff, 0xff, 0x35, 0x36, + 0x0, 0x0, 0x78, 0x47, 0xff, 0xff, 0x7f, 0xb8, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, + 0xea, 0x79, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xf3, 0x47, 0xb6, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xa2, 0x7f, 0xff, 0xff, + 0xff, 0x15, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xf6, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xdd, 0xf0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x8a, 0x89, 0xff, 0xff, 0xff, 0xfe, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x94, 0xa5, 0xff, 0xb5, 0xda, 0x3d, 0xff, 0xff, + 0x15, 0x2a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x84, 0xfe, 0x7f, 0xe1, 0xff, 0xff, 0xff, + 0xff, 0xdf, 0x7b, 0xfe, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x28, 0x72, 0x72, 0x56, + 0x0, 0x30, 0xfe, 0x83, 0xf5, 0xff, 0xff, 0xf5, + 0x81, 0xfc, 0x2a, 0x0, 0x0, 0x0, 0x28, 0xec, + 0x47, 0xc9, 0xfd, 0xff, 0xff, 0xff, 0xf3, 0xa7, + 0x41, 0xe3, 0xff, 0xff, 0xe9, 0x35, 0x10, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xde, 0xa5, 0xff, 0xff, 0x59, 0x98, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x44, 0xb, 0xef, 0xff, + 0xf3, 0x17, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, + 0x38, 0x62, 0x80, 0x64, 0x3a, 0x6, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xa6, 0x7f, 0xff, 0xff, + 0xc1, 0xe4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x68, 0x6f, 0xff, 0xff, 0xff, 0x35, 0x26, + 0x0, 0x0, 0xdc, 0x9d, 0xff, 0xfb, 0x23, 0x50, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x44, 0xf8, 0x63, 0xd9, 0xff, 0xff, 0xff, 0xfd, + 0xc7, 0x41, 0xe2, 0x20, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x7c, 0x7f, 0xff, 0xff, + 0xff, 0x15, 0xa, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xee, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xdd, 0xe8, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x52, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x6c, 0xfe, 0xfe, 0xfe, 0x8c, 0xfe, 0xfe, 0xfe, + 0xf6, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x4a, 0xcc, 0xfe, 0x2f, 0xed, 0xff, + 0x27, 0xfe, 0xca, 0x46, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x4c, 0xe8, 0xf, 0x43, 0x43, 0xf, + 0xe8, 0x4c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, + 0xa4, 0xfa, 0x1f, 0x4f, 0x59, 0x41, 0x9, 0xec, + 0xde, 0xfe, 0xfe, 0xfe, 0xfe, 0xc8, 0x10, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x7a, 0x39, 0xfd, 0xff, 0xbb, 0xfa, 0x24, + 0x0, 0x0, 0x0, 0x4, 0xce, 0x77, 0xff, 0xff, + 0x9f, 0xea, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xbe, 0x89, 0xff, 0xff, + 0xa7, 0xca, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x3c, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0x14, + 0x0, 0x8, 0xe6, 0xe3, 0xff, 0xc7, 0xf8, 0xc, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x32, 0xbe, 0xfe, 0x31, 0x55, 0x51, 0x23, + 0xfc, 0xa0, 0x1c, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x48, 0xfe, 0xfe, 0xfe, + 0xfe, 0xfe, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xbc, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, + 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xb2, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x10, 0xf8, 0xe9, 0xff, + 0xfe, 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x4, 0x20, 0x38, 0x38, 0x20, + 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x8, 0x2c, 0x50, 0x5e, 0x42, 0x1c, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x16, 0xf8, 0xad, 0xff, 0xfd, 0x4d, 0xc2, + 0x8, 0x0, 0x0, 0x74, 0x11, 0xe3, 0xff, 0xef, + 0x25, 0x6e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x6, 0xf0, 0xaf, 0xff, 0xff, + 0x5d, 0x88, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x8, 0x21, 0x95, 0x95, 0x55, 0xa4, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x12, 0x38, 0x54, 0x52, 0x30, + 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xda, 0x91, 0x9f, + 0xfe, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x7c, 0x21, 0xe9, 0xff, 0xdf, 0x1d, + 0x9e, 0x0, 0x52, 0xfe, 0xa9, 0xff, 0xff, 0x71, + 0xde, 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x18, 0x17, 0xf1, 0xff, 0xd1, + 0xfe, 0x2e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x8, 0x62, 0x9c, 0xa8, 0x76, 0x28, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x58, 0x9c, 0x9c, + 0x68, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xa, 0xd0, 0x4b, 0xf5, 0xff, 0xcb, + 0xce, 0x0, 0x78, 0x89, 0xff, 0xff, 0x9b, 0xfe, + 0x3c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x18, 0x37, 0xd9, 0xf1, 0x41, + 0xae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x22, 0xe6, 0x4b, 0xe7, 0xb5, + 0xd0, 0x0, 0x78, 0x6b, 0xfb, 0x8d, 0xfe, 0x64, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x14, 0xb4, 0x5, 0x31, 0xde, + 0x1c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x22, 0xcc, 0x17, 0x39, + 0x88, 0x0, 0x3a, 0xb, 0x3b, 0xf2, 0x56, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x10, 0x10, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0x18, 0x18, + 0x14, 0x0, 0x2, 0x18, 0x18, 0x16, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x8, 0x30, 0x5c, 0x76, + 0x66, 0x3c, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2, 0xe, 0x18, 0x20, 0x18, 0xc, 0x2, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x4, 0xe, 0x1a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x16, 0xc, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1c, 0x48, 0x6c, 0x6a, 0x46, 0x1c, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x2, 0xe, 0x18, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x1e, 0x14, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2, 0x22, 0x52, 0x74, 0x6e, 0x46, 0x18, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x22, 0x50, 0x70, 0x60, 0x36, + 0xa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x28, 0x56, + 0x76, 0x6e, 0x46, 0x18, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, + 0x16, 0x20, 0x1c, 0x10, 0x6, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xe, 0x86, 0xf6, 0x1b, 0x57, 0x6b, + 0x5f, 0x2f, 0xfe, 0xba, 0x30, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x7e, 0xd, 0x23, 0x23, 0x23, 0xb, 0x24, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x62, 0x11, 0x23, 0x23, + 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x5, + 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x52, + 0xda, 0xfe, 0x41, 0x63, 0x61, 0x41, 0x5, 0xd4, + 0x2c, 0x0, 0x0, 0x0, 0x3a, 0xd, 0x23, 0x23, + 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, + 0x23, 0x1d, 0xa8, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5a, 0xe4, 0xb, 0x4b, 0x69, 0x63, 0x3d, 0xfe, + 0xc8, 0x38, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x44, 0xd8, 0x5, 0x4b, 0x69, 0x5b, 0x21, + 0xf8, 0x8c, 0xe, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x6, 0x70, 0xec, 0x11, 0x51, + 0x69, 0x63, 0x3d, 0xfe, 0xcc, 0x3e, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa, 0x46, 0x8c, 0xbe, 0xd2, 0xd2, 0xc4, 0x9a, + 0x56, 0x14, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x24, 0xfe, + 0x23, 0x23, 0x23, 0x15, 0x94, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x12, 0xca, 0x29, 0xb5, 0xfb, 0xff, 0xff, + 0xff, 0xff, 0xd7, 0x5f, 0xfa, 0x40, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2c, + 0xfc, 0xb3, 0xff, 0xff, 0xff, 0x4d, 0x42, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xac, 0x97, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x2f, + 0x20, 0x0, 0x0, 0x0, 0x0, 0x4, 0x98, 0x9, + 0x89, 0xe9, 0xff, 0xff, 0xff, 0xff, 0xeb, 0x5b, + 0x44, 0x0, 0x0, 0x0, 0x66, 0x6b, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xd3, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x78, + 0x9, 0x93, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xe1, + 0x6b, 0xfc, 0x44, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5c, 0xfe, 0x79, 0xeb, 0xff, 0xff, 0xff, 0xfd, + 0xbb, 0x2b, 0xc8, 0xe, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xa4, 0x19, 0xa5, 0xf5, 0xff, + 0xff, 0xff, 0xff, 0xe3, 0x71, 0xfe, 0x4c, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x92, + 0xf8, 0x21, 0x73, 0x99, 0xab, 0xaf, 0x9d, 0x7f, + 0x35, 0xfe, 0xac, 0x26, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x82, 0x4f, + 0xff, 0xff, 0xff, 0xc5, 0xf8, 0xa, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x8a, 0x31, 0xe7, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x75, 0xe0, 0x4, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0xc6, + 0x5b, 0xff, 0xff, 0xff, 0xff, 0x4d, 0x5c, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xda, 0xaf, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x2f, + 0x2a, 0x0, 0x0, 0x0, 0x0, 0x7c, 0x13, 0xc7, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x43, + 0x44, 0x0, 0x0, 0x0, 0x76, 0x6b, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xd3, 0xf2, 0x0, 0x0, 0x0, 0x20, 0xfe, + 0xaf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x79, 0xe0, 0x4, 0x0, 0x0, 0x0, 0x26, + 0xfa, 0x93, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xe5, 0x2b, 0x8e, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x42, 0x9, 0xd1, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x81, 0xe8, 0x8, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x42, 0xf2, 0x3d, + 0xbb, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xcf, 0x51, 0xf8, 0x48, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe2, 0xa5, + 0xff, 0xff, 0xff, 0xfb, 0x21, 0x50, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xf0, 0xb7, 0xff, 0xff, 0xff, 0xb7, 0x7d, + 0x99, 0xf3, 0xff, 0xff, 0xf1, 0x13, 0x32, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x62, 0xf, + 0xe1, 0xff, 0xff, 0xff, 0xff, 0x4d, 0x5c, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xec, 0xc3, 0xff, 0xff, + 0xd7, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0x23, + 0x1c, 0x0, 0x0, 0x0, 0x1e, 0xfc, 0xb1, 0xff, + 0xff, 0xff, 0xd1, 0x8d, 0x89, 0xa7, 0xcf, 0xfe, + 0x1c, 0x0, 0x0, 0x0, 0x50, 0x47, 0xad, 0xad, + 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xe9, 0xff, + 0xff, 0xc5, 0xdc, 0x0, 0x0, 0x0, 0x6c, 0x49, + 0xff, 0xff, 0xff, 0xe1, 0x85, 0x93, 0xf3, 0xff, + 0xff, 0xf1, 0xf, 0x2a, 0x0, 0x0, 0x0, 0x9a, + 0x53, 0xff, 0xff, 0xff, 0xdb, 0x85, 0xa5, 0xfd, + 0xff, 0xff, 0xbd, 0xfa, 0x14, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xa0, 0x77, 0xff, 0xff, 0xff, 0xd7, + 0x8b, 0x9b, 0xf3, 0xff, 0xff, 0xf5, 0x1f, 0x3e, + 0x0, 0x0, 0x0, 0x0, 0x4a, 0xfc, 0x77, 0xfb, + 0xff, 0xf3, 0xb5, 0x7b, 0x5f, 0x5b, 0x73, 0xa3, + 0xe5, 0xff, 0xfd, 0x7f, 0xfc, 0x3c, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x2a, 0x5, 0xe9, + 0xff, 0xff, 0xff, 0xff, 0x7f, 0xba, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xf4, 0xf7, 0xff, 0xff, 0xb5, 0xfe, 0xc8, + 0xf4, 0x73, 0xff, 0xff, 0xff, 0x5d, 0x64, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1a, 0xf2, 0x97, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x4d, 0x5c, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xf8, 0xd9, 0xff, 0xff, + 0x65, 0xf2, 0xe8, 0xe8, 0xe8, 0xe8, 0xce, 0x92, + 0xc, 0x0, 0x0, 0x0, 0x78, 0x45, 0xff, 0xff, + 0xff, 0xaf, 0xfe, 0xd6, 0xbe, 0xda, 0xc8, 0x9e, + 0x0, 0x0, 0x0, 0x0, 0x20, 0x86, 0xbe, 0xd6, + 0xd6, 0xd6, 0xd6, 0xda, 0xfa, 0x67, 0xff, 0xff, + 0xef, 0x35, 0x9a, 0x0, 0x0, 0x0, 0xa4, 0x8d, + 0xff, 0xff, 0xff, 0x39, 0xe2, 0xf4, 0x7b, 0xff, + 0xff, 0xff, 0x55, 0x56, 0x0, 0x0, 0x0, 0xec, + 0xbd, 0xff, 0xff, 0xef, 0x21, 0xe0, 0xfa, 0x8d, + 0xff, 0xff, 0xfd, 0x33, 0x52, 0x0, 0x0, 0x0, + 0x3c, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0x14, 0x0, + 0x0, 0x0, 0x3c, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, + 0x14, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x6, 0x52, 0x9e, 0x9c, 0x72, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x60, 0x98, 0x9c, 0x62, + 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xb2, 0xb3, 0xff, 0xff, 0xef, 0x19, + 0xdc, 0xf2, 0x67, 0xff, 0xff, 0xff, 0x6b, 0x78, + 0x0, 0x0, 0x0, 0x20, 0xf2, 0x7f, 0xff, 0xff, + 0xb7, 0x27, 0xf2, 0xb2, 0x82, 0x7e, 0xa4, 0xe4, + 0xd, 0x91, 0xff, 0xff, 0x6f, 0xdc, 0xa, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x8c, 0x59, 0xff, + 0xff, 0xf9, 0xff, 0xff, 0xcb, 0xfa, 0xe, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x9, 0x7b, 0x7b, 0x7b, 0x41, 0x8c, 0x0, + 0x6a, 0x31, 0xff, 0xff, 0xff, 0x73, 0x78, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xa6, 0x3d, 0xf9, + 0xff, 0xeb, 0xff, 0xff, 0xff, 0x4d, 0x5c, 0x0, + 0x0, 0x0, 0x0, 0x2, 0xfe, 0xed, 0xff, 0xff, + 0x43, 0x6a, 0x3a, 0x34, 0x16, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xc8, 0x9d, 0xff, 0xff, + 0xf5, 0x19, 0xb0, 0x98, 0x9c, 0x74, 0x34, 0x2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x92, 0x2d, 0xf1, 0xff, 0xff, + 0x63, 0xde, 0x14, 0x0, 0x0, 0x0, 0xb6, 0x9d, + 0xff, 0xff, 0xf1, 0xfe, 0x1e, 0x78, 0x41, 0xff, + 0xff, 0xff, 0x67, 0x68, 0x0, 0x0, 0x2, 0xfe, + 0xef, 0xff, 0xff, 0xa7, 0xee, 0xa, 0x5c, 0x21, + 0xff, 0xff, 0xff, 0x79, 0x94, 0x0, 0x0, 0x0, + 0x68, 0x6f, 0xff, 0xff, 0xff, 0x35, 0x26, 0x0, + 0x0, 0x0, 0x68, 0x6f, 0xff, 0xff, 0xff, 0x35, + 0x26, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x18, 0x7a, 0xec, 0x19, 0x83, 0xa9, 0xc8, + 0x0, 0x0, 0x0, 0x26, 0x7e, 0xb2, 0xc8, 0xc8, + 0xc8, 0xc8, 0xc8, 0xc8, 0xc8, 0xc8, 0xa8, 0x6c, + 0x8, 0x0, 0x0, 0x0, 0xae, 0x97, 0x91, 0x27, + 0xf6, 0x90, 0x24, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x98, 0x67, 0x87, 0x87, 0x6f, 0xde, + 0x6, 0x4e, 0x19, 0xff, 0xff, 0xff, 0x83, 0x92, + 0x0, 0x0, 0x0, 0xac, 0x49, 0xf9, 0xff, 0xa5, + 0xfe, 0x88, 0x2c, 0x64, 0x92, 0x9c, 0x74, 0x38, + 0x5e, 0xfc, 0x89, 0xff, 0xef, 0x21, 0x5a, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xea, 0xad, 0xff, + 0xff, 0x9d, 0xf9, 0xff, 0xfd, 0x2b, 0x5a, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x46, 0x78, 0x9c, 0x86, 0x58, 0x1a, 0x1c, + 0xc2, 0x57, 0xff, 0xff, 0xff, 0x4d, 0x5a, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x46, 0xfe, 0xcd, 0xff, + 0xf9, 0x79, 0xff, 0xff, 0xff, 0x4d, 0x5c, 0x0, + 0x0, 0x0, 0x0, 0x14, 0xb, 0xfd, 0xff, 0xff, + 0x19, 0x1b, 0x49, 0x39, 0xfe, 0xde, 0x52, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xec, 0xcb, 0xff, 0xff, + 0xc7, 0xfe, 0x53, 0x85, 0x89, 0x63, 0xd, 0xc4, + 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x2e, 0xfe, 0xbf, 0xff, 0xff, 0xab, + 0xfc, 0x32, 0x0, 0x0, 0x0, 0x0, 0x94, 0x7f, + 0xff, 0xff, 0xfd, 0x1f, 0xa4, 0xd0, 0x63, 0xff, + 0xff, 0xff, 0x41, 0x4c, 0x0, 0x0, 0x2, 0xb, + 0xff, 0xff, 0xff, 0x87, 0xbe, 0x0, 0xa, 0xfe, + 0xf1, 0xff, 0xff, 0x9b, 0xbe, 0x0, 0x0, 0x0, + 0x8c, 0x6f, 0xff, 0xff, 0xff, 0x35, 0x36, 0x0, + 0x0, 0x0, 0x8c, 0x6f, 0xff, 0xff, 0xff, 0x35, + 0x36, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x32, + 0xa6, 0xfc, 0x3b, 0xa5, 0xf3, 0xff, 0xcd, 0xea, + 0x0, 0x0, 0x0, 0x6a, 0x53, 0x9f, 0x9f, 0x9f, + 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x1d, + 0x18, 0x0, 0x0, 0x0, 0xd6, 0xb3, 0xff, 0xf9, + 0xb5, 0x4f, 0xfe, 0xbe, 0x46, 0x4, 0x0, 0x0, + 0x0, 0x0, 0x34, 0x74, 0xa0, 0xa2, 0x78, 0x3c, + 0x0, 0x88, 0x3d, 0xff, 0xff, 0xff, 0x69, 0x7a, + 0x0, 0x0, 0x28, 0xfe, 0xcf, 0xff, 0xd3, 0x9, + 0x70, 0x86, 0xfe, 0x49, 0x83, 0x83, 0x63, 0x13, + 0xe0, 0x84, 0x5, 0xd5, 0xff, 0x8b, 0xca, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x32, 0x9, 0xef, 0xff, + 0xff, 0x45, 0xc3, 0xff, 0xff, 0x87, 0xc2, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x48, 0xf8, 0xfe, 0x9, + 0x43, 0xd5, 0xff, 0xff, 0xcd, 0xfe, 0x24, 0x0, + 0x0, 0x0, 0x0, 0xc, 0xe0, 0x7b, 0xff, 0xff, + 0x95, 0x57, 0xff, 0xff, 0xff, 0x4d, 0x5c, 0x0, + 0x0, 0x0, 0x0, 0x38, 0x31, 0xff, 0xff, 0xf9, + 0xc3, 0xff, 0xff, 0xff, 0xed, 0x89, 0xfe, 0x64, + 0x0, 0x0, 0x0, 0x0, 0xf6, 0xdb, 0xff, 0xff, + 0xcb, 0xd5, 0xff, 0xff, 0xff, 0xff, 0xe3, 0x47, + 0xd4, 0xa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xb2, 0x5d, 0xff, 0xff, 0xef, 0x21, + 0x78, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4e, 0x1f, + 0xf1, 0xff, 0xff, 0xbb, 0x3d, 0x4d, 0xd9, 0xff, + 0xff, 0xcd, 0xfe, 0x1c, 0x0, 0x0, 0x2, 0xfe, + 0xfd, 0xff, 0xff, 0x8f, 0xc8, 0x0, 0x0, 0xfc, + 0xe5, 0xff, 0xff, 0xa7, 0xce, 0x0, 0x0, 0x0, + 0x68, 0x6f, 0xff, 0xff, 0xff, 0x35, 0x26, 0x0, + 0x0, 0x0, 0x68, 0x6f, 0xff, 0xff, 0xff, 0x35, + 0x26, 0x0, 0x0, 0x0, 0x8, 0x58, 0xd0, 0xfe, + 0x63, 0xc5, 0xff, 0xff, 0xff, 0xff, 0xcd, 0xe0, + 0x0, 0x0, 0x0, 0x98, 0x87, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x2f, + 0x26, 0x0, 0x0, 0x0, 0xc6, 0xb3, 0xff, 0xff, + 0xff, 0xff, 0xd5, 0x79, 0x11, 0xe6, 0x72, 0x14, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x52, 0xfe, 0xaf, 0xff, 0xff, 0xf5, 0x21, 0x40, + 0x0, 0x0, 0x86, 0x55, 0xff, 0xff, 0x53, 0xb2, + 0x82, 0x11, 0xbb, 0xff, 0xff, 0xff, 0xff, 0xef, + 0x81, 0xc8, 0xc4, 0x7d, 0xff, 0xd9, 0xfa, 0x4, + 0x0, 0x0, 0x0, 0x0, 0x96, 0x63, 0xff, 0xff, + 0xe5, 0xfe, 0x7d, 0xff, 0xff, 0xd1, 0xfc, 0x12, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x7c, 0x7d, 0xfd, 0xff, + 0xff, 0xff, 0xff, 0xd1, 0x25, 0xa0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x84, 0x25, 0xef, 0xff, 0xdf, + 0xd, 0x57, 0xff, 0xff, 0xff, 0x4d, 0x5c, 0x0, + 0x0, 0x0, 0x0, 0x64, 0x53, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9d, 0xf8, + 0x16, 0x0, 0x0, 0x0, 0xfa, 0xe3, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xeb, + 0x21, 0x68, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x22, 0xfe, 0xd1, 0xff, 0xff, 0x8f, 0xe4, + 0xa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0xdc, + 0x53, 0xeb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xd7, 0x2b, 0xa2, 0x0, 0x0, 0x0, 0x0, 0xfe, + 0xe7, 0xff, 0xff, 0xbb, 0xfa, 0x32, 0x5e, 0xfe, + 0xe5, 0xff, 0xff, 0xa9, 0xd4, 0x0, 0x0, 0x0, + 0x3c, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0x14, 0x0, + 0x0, 0x0, 0x3c, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, + 0x14, 0x0, 0x0, 0x30, 0xe6, 0x1d, 0x89, 0xe1, + 0xff, 0xff, 0xff, 0xff, 0xfd, 0xc7, 0x69, 0xb2, + 0x0, 0x0, 0x0, 0x8c, 0x87, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x2f, + 0x22, 0x0, 0x0, 0x0, 0x90, 0x53, 0xb7, 0xf5, + 0xff, 0xff, 0xff, 0xff, 0xef, 0x9d, 0x33, 0xf6, + 0x5a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6c, + 0xfe, 0x89, 0xff, 0xff, 0xff, 0x8f, 0xea, 0xa, + 0x0, 0x0, 0xdc, 0xa7, 0xff, 0xd7, 0xfe, 0x4c, + 0xfe, 0xb7, 0xff, 0xff, 0xcd, 0xb1, 0xe9, 0xff, + 0xdd, 0xea, 0x52, 0x29, 0xff, 0xfb, 0x11, 0x24, + 0x0, 0x0, 0x0, 0x4, 0xee, 0xb3, 0xff, 0xff, + 0xa5, 0xea, 0x27, 0xfd, 0xff, 0xff, 0x31, 0x62, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x90, 0x7f, 0xff, 0xff, + 0xff, 0xff, 0xf7, 0x79, 0xfe, 0x7c, 0x0, 0x0, + 0x0, 0x0, 0x2e, 0xfc, 0xb3, 0xff, 0xff, 0x55, + 0xda, 0x57, 0xff, 0xff, 0xff, 0x4d, 0x5c, 0x0, + 0x0, 0x0, 0x0, 0x6e, 0x6f, 0xff, 0xff, 0xff, + 0xb5, 0x75, 0x8b, 0xed, 0xff, 0xff, 0xfd, 0x39, + 0x66, 0x0, 0x0, 0x0, 0xfa, 0xe3, 0xff, 0xff, + 0xfd, 0xa1, 0x55, 0x53, 0xb5, 0xff, 0xff, 0xff, + 0x9b, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x7c, 0x4d, 0xff, 0xff, 0xf9, 0x21, 0x5e, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0xb0, + 0x11, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, + 0x77, 0xfe, 0x74, 0x0, 0x0, 0x0, 0x0, 0xe2, + 0xb1, 0xff, 0xff, 0xf9, 0x5f, 0xfe, 0xd, 0x95, + 0xff, 0xff, 0xff, 0xa9, 0xd4, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x68, 0x5f, 0xf5, 0xff, 0xff, + 0xff, 0xff, 0xd7, 0x8b, 0x2b, 0xfa, 0xac, 0x38, + 0x0, 0x0, 0x0, 0x58, 0x25, 0x49, 0x49, 0x49, + 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0xd, + 0x12, 0x0, 0x0, 0x0, 0x26, 0x94, 0xf2, 0x15, + 0x75, 0xc3, 0xfb, 0xff, 0xff, 0xff, 0xfd, 0x93, + 0xac, 0x0, 0x0, 0x0, 0x0, 0x0, 0x68, 0x5, + 0xa5, 0xff, 0xff, 0xff, 0xad, 0xfe, 0x58, 0x0, + 0x0, 0x4, 0xfe, 0xdf, 0xff, 0x9d, 0xd6, 0x9c, + 0x5b, 0xff, 0xff, 0x97, 0xfe, 0xfc, 0xbf, 0xff, + 0xcb, 0xf0, 0xe, 0xfe, 0xf1, 0xff, 0x4b, 0x4a, + 0x0, 0x0, 0x0, 0x3a, 0xf, 0xf3, 0xff, 0xff, + 0x59, 0x8a, 0xfc, 0xcf, 0xff, 0xff, 0x8d, 0xca, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x66, 0x55, 0xad, 0xaf, + 0xcb, 0xff, 0xff, 0xff, 0xad, 0xfe, 0x2c, 0x0, + 0x0, 0x4, 0xc6, 0x5b, 0xff, 0xff, 0xad, 0xfe, + 0xce, 0x57, 0xff, 0xff, 0xff, 0x4d, 0xaa, 0x4a, + 0x8, 0x0, 0x0, 0x54, 0x49, 0x9b, 0xab, 0x99, + 0xfe, 0xbe, 0xea, 0x4f, 0xff, 0xff, 0xff, 0x8f, + 0xb2, 0x0, 0x0, 0x0, 0xfa, 0xe3, 0xff, 0xff, + 0xb5, 0xfe, 0x94, 0xa4, 0xfe, 0xdb, 0xff, 0xff, + 0xdb, 0xfa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xdc, 0xa1, 0xff, 0xff, 0xc3, 0xf8, 0xa, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x64, 0x17, + 0xcf, 0xff, 0xff, 0xf1, 0xb7, 0xc1, 0xfb, 0xff, + 0xff, 0xa3, 0xfe, 0x2c, 0x0, 0x0, 0x0, 0x8a, + 0x43, 0xfb, 0xff, 0xff, 0xff, 0xeb, 0xf7, 0xff, + 0xff, 0xff, 0xff, 0xa9, 0xd4, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x90, 0x7b, 0xff, 0xff, 0xff, + 0xaf, 0x41, 0xfe, 0xd8, 0x62, 0xe, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x2c, 0x88, 0xba, 0xce, 0xce, + 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xae, 0x72, + 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0x46, + 0xbe, 0xfc, 0x23, 0x8d, 0xf7, 0xff, 0xff, 0xb3, + 0xd4, 0x0, 0x0, 0x0, 0x0, 0x6, 0xf0, 0x9f, + 0xff, 0xff, 0xfd, 0x89, 0xfe, 0x76, 0x0, 0x0, + 0x0, 0x1a, 0xf, 0xff, 0xff, 0x67, 0x94, 0xf0, + 0xbb, 0xff, 0xf3, 0x13, 0x62, 0xf4, 0xd1, 0xff, + 0xb9, 0xe2, 0x0, 0xfc, 0xe3, 0xff, 0x5b, 0x6c, + 0x0, 0x0, 0x0, 0xa0, 0x6b, 0xff, 0xff, 0xef, + 0x9, 0xac, 0xea, 0x8d, 0xff, 0xff, 0xd7, 0xfe, + 0x16, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x28, 0x8c, 0xc2, 0xe2, + 0xfe, 0x6d, 0xff, 0xff, 0xff, 0x5b, 0x84, 0x0, + 0x0, 0x3a, 0x11, 0xe1, 0xff, 0xfd, 0x89, 0x7b, + 0x7b, 0x9b, 0xff, 0xff, 0xff, 0x97, 0x7b, 0x1b, + 0x1e, 0x0, 0x0, 0x20, 0x78, 0xb4, 0xca, 0xa8, + 0x60, 0x0, 0x24, 0xfe, 0xe5, 0xff, 0xff, 0xb5, + 0xd8, 0x0, 0x0, 0x0, 0xf8, 0xdf, 0xff, 0xff, + 0xb1, 0xe2, 0x0, 0x0, 0xe0, 0x9d, 0xff, 0xff, + 0xf9, 0xfe, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1c, 0xfe, 0xe3, 0xff, 0xff, 0x85, 0xba, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd2, 0x99, + 0xff, 0xff, 0xf1, 0x2f, 0xf6, 0xfc, 0x5f, 0xff, + 0xff, 0xff, 0x5b, 0x8e, 0x0, 0x0, 0x0, 0x1c, + 0xf2, 0x73, 0xf9, 0xff, 0xff, 0xff, 0xff, 0xd5, + 0xed, 0xff, 0xff, 0xa7, 0xce, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x7c, 0x7b, 0xff, 0xff, 0xff, + 0xfd, 0xc9, 0x7b, 0x1b, 0xf6, 0xa2, 0x3a, 0x4, + 0x0, 0x0, 0x0, 0x68, 0x4d, 0x91, 0x91, 0x91, + 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x19, + 0x16, 0x0, 0x0, 0x0, 0x0, 0x2a, 0x8c, 0xec, + 0xd, 0x6b, 0xbb, 0xf9, 0xff, 0xff, 0xff, 0xb3, + 0xc2, 0x0, 0x0, 0x0, 0x0, 0x22, 0x17, 0xf9, + 0xff, 0xff, 0x9f, 0xfc, 0x52, 0x0, 0x0, 0x0, + 0x0, 0x3c, 0x39, 0xff, 0xff, 0x47, 0x66, 0x5, + 0xf3, 0xff, 0xc3, 0xf6, 0x4, 0xfa, 0xe3, 0xff, + 0xa7, 0xd2, 0x0, 0xfc, 0xe1, 0xff, 0x63, 0x72, + 0x0, 0x0, 0x6, 0xf4, 0xb9, 0xff, 0xff, 0xd7, + 0x7b, 0x7b, 0x7b, 0x95, 0xff, 0xff, 0xff, 0x39, + 0x6c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1c, 0x92, 0xca, 0xe2, 0xca, 0x90, 0x1a, 0x0, + 0x3a, 0xfe, 0xed, 0xff, 0xff, 0xa1, 0xbe, 0x0, + 0x0, 0x5c, 0x69, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x39, + 0x30, 0x0, 0x0, 0x60, 0xba, 0xe4, 0xe6, 0xc6, + 0x6a, 0x0, 0x0, 0xfa, 0xd3, 0xff, 0xff, 0xbf, + 0xe0, 0x0, 0x0, 0x0, 0xf2, 0xd3, 0xff, 0xff, + 0xc3, 0xf0, 0x0, 0x0, 0xc8, 0x8f, 0xff, 0xff, + 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5a, 0x43, 0xff, 0xff, 0xff, 0x47, 0x64, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf6, 0xdd, + 0xff, 0xff, 0xaf, 0xf4, 0x10, 0x30, 0xfe, 0xdd, + 0xff, 0xff, 0xad, 0xcc, 0x0, 0x0, 0x0, 0x0, + 0x40, 0xec, 0x31, 0x93, 0xb7, 0xb7, 0x83, 0xf, + 0xf7, 0xff, 0xff, 0x99, 0xbe, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x4a, 0x19, 0x85, 0xdf, 0xff, + 0xff, 0xff, 0xff, 0xf9, 0xbb, 0x6b, 0xf, 0x96, + 0x0, 0x0, 0x0, 0x96, 0x87, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x2f, + 0x26, 0x0, 0x0, 0x0, 0x74, 0xfe, 0x57, 0xad, + 0xf1, 0xff, 0xff, 0xff, 0xff, 0xed, 0x9b, 0x2f, + 0x86, 0x0, 0x0, 0x0, 0x0, 0x26, 0x41, 0xff, + 0xff, 0xff, 0x5d, 0x84, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x54, 0x51, 0xff, 0xff, 0x2d, 0x66, 0x35, + 0xff, 0xff, 0x9f, 0xd2, 0x4, 0xfe, 0xf3, 0xff, + 0x93, 0xbc, 0xa, 0xfe, 0xef, 0xff, 0x57, 0x5e, + 0x0, 0x0, 0x44, 0x17, 0xf7, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x95, + 0xd2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x30, 0x41, 0xbb, 0xbb, 0xbb, 0x3d, 0x74, 0x0, + 0x20, 0xfe, 0xe5, 0xff, 0xff, 0xaf, 0xcc, 0x0, + 0x0, 0x5e, 0x5b, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x39, + 0x30, 0x0, 0x0, 0xb4, 0x99, 0xc3, 0xcf, 0xa1, + 0xe2, 0x8, 0x24, 0xfe, 0xe3, 0xff, 0xff, 0xb1, + 0xd6, 0x0, 0x0, 0x0, 0xdc, 0xb1, 0xff, 0xff, + 0xe7, 0x5, 0x3c, 0xc, 0xf0, 0xad, 0xff, 0xff, + 0xed, 0xfe, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa0, 0x7b, 0xff, 0xff, 0xf9, 0xb, 0x20, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xfa, 0xef, + 0xff, 0xff, 0xa9, 0xec, 0x4, 0x16, 0xfc, 0xd7, + 0xff, 0xff, 0xc1, 0xde, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x12, 0x66, 0xb4, 0xd6, 0xd4, 0xdc, 0x41, + 0xff, 0xff, 0xff, 0x75, 0x90, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x6, 0x52, 0xcc, 0xfe, 0x5f, + 0xc1, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xc7, 0xd6, + 0x0, 0x0, 0x0, 0x8e, 0x87, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x2f, + 0x22, 0x0, 0x0, 0x0, 0xb8, 0xab, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xd3, 0x77, 0xf, 0xe4, 0x6e, + 0x10, 0x0, 0x0, 0x0, 0x0, 0x20, 0x13, 0x3f, + 0x3f, 0x3f, 0x13, 0x32, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x5a, 0x4f, 0xff, 0xff, 0x2f, 0x7c, 0x57, + 0xff, 0xff, 0x8d, 0xc0, 0x1a, 0xf, 0xff, 0xff, + 0x7d, 0xa4, 0x54, 0x21, 0xff, 0xff, 0x29, 0x36, + 0x0, 0x0, 0xaa, 0x73, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdd, + 0xfe, 0x1c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x30, 0x3b, 0xff, 0xff, 0xff, 0x9d, 0xfe, 0xce, + 0xf0, 0x49, 0xff, 0xff, 0xff, 0x91, 0xae, 0x0, + 0x0, 0x34, 0x1f, 0x6b, 0x6b, 0x6b, 0x6b, 0x6b, + 0x6b, 0x91, 0xff, 0xff, 0xff, 0x8b, 0x6b, 0x17, + 0x1c, 0x0, 0x0, 0xc4, 0xbb, 0xff, 0xff, 0xed, + 0x1b, 0xe0, 0xee, 0x4f, 0xff, 0xff, 0xff, 0x83, + 0xa6, 0x0, 0x0, 0x0, 0x9a, 0x71, 0xff, 0xff, + 0xff, 0x6f, 0xf8, 0xe4, 0x25, 0xf1, 0xff, 0xff, + 0xbf, 0xec, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xd2, 0xa3, 0xff, 0xff, 0xdb, 0xfc, 0x2, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf6, 0xdb, + 0xff, 0xff, 0xe3, 0xf, 0xdc, 0xec, 0x39, 0xf9, + 0xff, 0xff, 0xab, 0xcc, 0x0, 0x0, 0x0, 0x0, + 0x1c, 0xb0, 0xd0, 0xdc, 0xbc, 0xd8, 0x9, 0xbf, + 0xff, 0xff, 0xf9, 0x27, 0x4a, 0x0, 0x0, 0x0, + 0x3c, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0x14, 0x0, + 0x0, 0x0, 0x3c, 0xcc, 0xf2, 0xf6, 0xdc, 0x78, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x30, 0xa2, + 0xfa, 0x35, 0xa1, 0xf1, 0xff, 0xff, 0xcd, 0xee, + 0x0, 0x0, 0x0, 0x5a, 0x2d, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0xf, + 0x14, 0x0, 0x0, 0x0, 0xda, 0xb3, 0xff, 0xff, + 0xf9, 0xb1, 0x4b, 0xfe, 0xbc, 0x44, 0x4, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x2a, 0xe4, 0xfa, + 0xfe, 0xfc, 0xe6, 0x2e, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x42, 0x45, 0xff, 0xff, 0x3f, 0x90, 0x59, + 0xff, 0xff, 0x95, 0xda, 0x9e, 0x39, 0xff, 0xff, + 0x6b, 0x96, 0xd8, 0x85, 0xff, 0xd9, 0xfe, 0xe, + 0x0, 0x8, 0xf6, 0xc1, 0xff, 0xff, 0xcd, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x7f, 0xff, 0xff, 0xff, + 0x43, 0x76, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x18, 0xfe, 0xd9, 0xff, 0xff, 0xff, 0xbb, 0x89, + 0x9f, 0xf1, 0xff, 0xff, 0xf9, 0x39, 0x68, 0x0, + 0x0, 0x8, 0x3e, 0x6a, 0x86, 0x86, 0x86, 0x86, + 0xb8, 0x57, 0xff, 0xff, 0xff, 0x4d, 0x9e, 0x3e, + 0x6, 0x0, 0x0, 0xa0, 0x6d, 0xff, 0xff, 0xff, + 0xdd, 0x8f, 0x99, 0xef, 0xff, 0xff, 0xf3, 0x21, + 0x54, 0x0, 0x0, 0x0, 0x3e, 0xb, 0xdf, 0xff, + 0xff, 0xf9, 0xa1, 0x8f, 0xdf, 0xff, 0xff, 0xff, + 0x57, 0x9c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xf0, 0xc9, 0xff, 0xff, 0xc1, 0xec, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd0, 0x99, + 0xff, 0xff, 0xff, 0xd9, 0x8f, 0x97, 0xeb, 0xff, + 0xff, 0xff, 0x5f, 0x8e, 0x0, 0x0, 0x0, 0x0, + 0x52, 0x43, 0xd5, 0xa1, 0x89, 0x91, 0xd5, 0xff, + 0xff, 0xff, 0xa1, 0xf2, 0xe, 0x0, 0x0, 0x0, + 0x68, 0x6f, 0xff, 0xff, 0xff, 0x35, 0x26, 0x0, + 0x0, 0x0, 0x74, 0x71, 0xe3, 0xe3, 0xaf, 0xc4, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x14, 0x76, 0xe8, 0x15, 0x7f, 0xdb, 0xcd, 0xdc, + 0x0, 0x0, 0x0, 0x10, 0x36, 0x58, 0x6a, 0x6a, + 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x4e, 0x2c, + 0x4, 0x0, 0x0, 0x0, 0xc2, 0xb3, 0xe5, 0x8f, + 0x23, 0xf4, 0x8c, 0x22, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x4a, 0x51, 0xf5, + 0xf5, 0xf5, 0x57, 0x4e, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x24, 0x1b, 0xff, 0xff, 0x6b, 0xac, 0x2d, + 0xff, 0xff, 0xd5, 0xb, 0x1b, 0xc3, 0xff, 0xff, + 0x6d, 0xfa, 0x27, 0xe7, 0xff, 0x7b, 0xc4, 0x0, + 0x0, 0x4c, 0x1f, 0xf9, 0xff, 0xff, 0x7b, 0xd2, + 0x7a, 0x7a, 0x7a, 0x8a, 0xfe, 0xe9, 0xff, 0xff, + 0x9b, 0xda, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb6, 0x49, 0xf1, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x7f, 0xf0, 0x16, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x6a, 0x57, 0xff, 0xff, 0xff, 0x4d, 0x5c, 0x0, + 0x0, 0x0, 0x0, 0x3a, 0xfe, 0xb3, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0x71, 0xe4, + 0xa, 0x0, 0x0, 0x0, 0x2, 0xc0, 0x47, 0xef, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x97, + 0xfc, 0x2a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xfc, 0xe5, 0xff, 0xff, 0xa7, 0xd6, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x64, 0x19, + 0xd7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xb1, 0xfe, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x76, 0x71, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xc5, 0xd, 0x6c, 0x0, 0x0, 0x0, 0x0, + 0x8c, 0x6f, 0xff, 0xff, 0xff, 0x35, 0x36, 0x0, + 0x0, 0x0, 0x9c, 0x7f, 0xff, 0xff, 0xc5, 0xe4, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x6, 0x4e, 0xc8, 0xec, 0x3f, 0xa4, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x88, 0x3f, 0x5, 0xd6, + 0x5e, 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x68, 0x57, 0xff, + 0xff, 0xff, 0x5b, 0x6e, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x8, 0xfe, 0xe3, 0xff, 0xa1, 0xe6, 0xfe, + 0xcf, 0xff, 0xff, 0xf3, 0xf9, 0xe9, 0xe1, 0xff, + 0xdb, 0xa7, 0xeb, 0xff, 0xc3, 0xfe, 0x44, 0x0, + 0x0, 0xb4, 0x7b, 0xff, 0xff, 0xfd, 0x27, 0x50, + 0x0, 0x0, 0x0, 0x0, 0xe6, 0xad, 0xff, 0xff, + 0xe3, 0xfe, 0x24, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x20, 0xdc, 0x31, 0xb3, 0xf7, 0xff, 0xff, + 0xff, 0xfd, 0xcb, 0x57, 0xfa, 0x4a, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x4c, 0x57, 0xff, 0xff, 0xff, 0x4d, 0x42, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x7c, 0xfe, 0x7f, 0xe1, + 0xff, 0xff, 0xff, 0xff, 0xd9, 0x61, 0xf8, 0x3e, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1e, 0xda, 0x37, + 0xbb, 0xfb, 0xff, 0xff, 0xff, 0xe3, 0x75, 0xfe, + 0x5e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xf8, 0xf7, 0xff, 0xff, 0x93, 0xa4, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0xae, + 0x17, 0x9d, 0xef, 0xff, 0xff, 0xff, 0xff, 0xe3, + 0x83, 0x5, 0x7a, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x64, 0x65, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xe5, + 0x87, 0x5, 0x92, 0x2, 0x0, 0x0, 0x0, 0x0, + 0x68, 0x6f, 0xff, 0xff, 0xff, 0x35, 0x26, 0x0, + 0x0, 0x0, 0xa6, 0x7f, 0xff, 0xff, 0xc1, 0xe4, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x16, 0x16, 0x16, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x16, 0x16, 0x16, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x4c, 0x57, 0xff, + 0xff, 0xff, 0x5b, 0x52, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xde, 0xa7, 0xff, 0xe9, 0xd, 0xc6, + 0x39, 0xdf, 0xff, 0xff, 0xe5, 0x4b, 0x5b, 0xf3, + 0xff, 0xff, 0xf5, 0xa3, 0x13, 0x92, 0x0, 0x0, + 0x0, 0xb2, 0xc7, 0xff, 0xff, 0xcf, 0xfc, 0xc, + 0x0, 0x0, 0x0, 0x0, 0x90, 0x63, 0xff, 0xff, + 0xff, 0x4d, 0x24, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x12, 0x86, 0xf2, 0xd, 0x47, 0x59, + 0x4d, 0x1b, 0xfc, 0xaa, 0x2a, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2a, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0x24, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x48, 0xcc, 0xfe, + 0x31, 0x57, 0x55, 0x2d, 0xfe, 0xbc, 0x30, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x16, 0x90, + 0xf6, 0x19, 0x4d, 0x57, 0x39, 0xfe, 0xce, 0x40, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xe4, 0xfe, 0xfe, 0xfe, 0xfe, 0x5c, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, + 0x68, 0xe4, 0xfe, 0x3d, 0x57, 0x55, 0x31, 0xfe, + 0xd0, 0x4c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x34, 0xca, 0xfe, 0x2f, 0x4f, 0x55, 0x35, 0xfe, + 0xd4, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3c, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0x14, 0x0, + 0x0, 0x0, 0xbe, 0x89, 0xff, 0xff, 0xa7, 0xca, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x2a, 0xfe, 0xfe, + 0xfe, 0xfe, 0xfe, 0x2c, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x82, 0x47, 0xff, 0xff, 0x91, 0xf4, + 0xca, 0x5, 0x45, 0x43, 0x9, 0xd2, 0xe6, 0x1f, + 0x55, 0x49, 0xf, 0xec, 0x6e, 0x4, 0x0, 0x0, + 0x0, 0x94, 0xfe, 0xfe, 0xfe, 0xfe, 0xa0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x32, 0xfe, 0xfe, 0xfe, + 0xfe, 0xfe, 0x24, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x2, 0x22, 0x48, 0x5e, + 0x4e, 0x2a, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x12, + 0x38, 0x58, 0x56, 0x34, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x6, 0x2a, 0x4c, 0x58, 0x3c, 0x16, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x18, 0x3e, 0x5c, 0x58, 0x38, 0x12, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x10, 0x32, 0x54, 0x54, 0x38, 0x14, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x6, 0xf0, 0xaf, 0xff, 0xff, 0x5d, 0x88, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x1e, 0xfe, 0xaf, 0xff, 0xfb, 0x6b, + 0xfa, 0x8c, 0x46, 0x36, 0x1c, 0x0, 0x2c, 0x58, + 0x6e, 0x52, 0x22, 0x4, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x18, 0x17, 0xf1, 0xff, 0xd1, 0xfe, 0x2e, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x7c, 0x1b, 0xd9, 0xff, 0xfd, + 0xab, 0x35, 0xfe, 0xf2, 0xee, 0xf8, 0xfe, 0x4f, + 0x2f, 0x5c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x18, 0x37, 0xd9, 0xf1, 0x41, 0xae, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x8, 0xb4, 0x1f, 0xc7, 0xff, + 0xff, 0xff, 0xdf, 0xc7, 0xbf, 0xd3, 0xef, 0xff, + 0x87, 0x78, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x14, 0xb4, 0x5, 0x31, 0xde, 0x1c, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x8, 0x98, 0xfe, 0x67, + 0xc7, 0xf9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xd3, + 0x5d, 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x10, 0x10, 0x10, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x36, 0xac, + 0xf6, 0x13, 0x49, 0x5f, 0x6b, 0x57, 0x23, 0xfc, + 0xb6, 0x2e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x4, 0x24, 0x4c, 0x72, 0x78, 0x60, 0x34, 0xc, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4, 0xe, 0x1a, 0x20, 0x20, 0x20, 0x1e, + 0x14, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x20, 0x4e, 0x72, 0x72, 0x4e, 0x20, 0x2, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0xe, 0x1a, + 0x20, 0x20, 0x20, 0x1c, 0x10, 0x6, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x4, 0xe, 0x1a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x18, 0xe, 0x2, 0x0, + 0x0, 0x4, 0xe, 0x1a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x18, 0xe, 0x2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1e, + 0x4a, 0x70, 0x74, 0x54, 0x28, 0x4, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0xe, 0x1a, + 0x20, 0x16, 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc, 0x16, 0x20, 0x1a, 0xe, 0x4, 0x0, 0x0, + 0x0, 0x2, 0xc, 0x18, 0x20, 0x18, 0xc, 0x2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x2, 0xe, 0x18, 0x20, 0x16, 0xc, + 0x0, 0x0, 0x0, 0x0, 0x4, 0xe, 0x1a, 0x20, + 0x16, 0xc, 0x0, 0x0, 0x0, 0x0, 0xa, 0x16, + 0x20, 0x20, 0x18, 0xc, 0x2, 0x0, 0x0, 0x4, + 0xe, 0x1a, 0x20, 0x16, 0xc, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, + 0xe, 0x1a, 0x20, 0x20, 0x16, 0xc, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x16, 0x20, + 0x20, 0x1a, 0xe, 0x4, 0x0, 0x0, 0x0, 0x4, + 0xe, 0x1a, 0x20, 0x16, 0xc, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xc, 0x16, 0x20, 0x1a, 0xe, 0x4, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x14, 0x3e, 0x66, 0x72, 0x56, 0x28, 0x4, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x52, 0x11, 0x23, 0x23, 0x23, 0x23, 0x23, + 0x1f, 0x9, 0xfe, 0xea, 0x9e, 0x30, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x60, 0xe2, + 0x5, 0x49, 0x65, 0x65, 0x49, 0xb, 0xec, 0x76, + 0x8, 0x0, 0x0, 0x0, 0x0, 0x52, 0x11, 0x23, + 0x23, 0x23, 0x23, 0x23, 0x15, 0xfe, 0xf8, 0xc2, + 0x5c, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x52, 0x11, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, + 0x23, 0x23, 0x23, 0x23, 0x23, 0xd, 0x32, 0x0, + 0x0, 0x52, 0x11, 0x23, 0x23, 0x23, 0x23, 0x23, + 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0xd, 0x34, + 0x0, 0x0, 0x0, 0x0, 0x4, 0x5c, 0xe0, 0x5, + 0x45, 0x65, 0x67, 0x4f, 0x13, 0xf6, 0x8e, 0x14, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x52, 0x11, 0x23, + 0x23, 0x23, 0xfe, 0x2, 0x0, 0x0, 0x0, 0x2, + 0xfe, 0x23, 0x23, 0x23, 0x11, 0x4e, 0x0, 0x0, + 0x0, 0x24, 0xb, 0x23, 0x23, 0x23, 0xb, 0x2e, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x32, 0xd, 0x23, 0x23, 0x23, 0x9, + 0x1c, 0x0, 0x0, 0x0, 0x52, 0x11, 0x23, 0x23, + 0x23, 0xfe, 0x2, 0x0, 0x0, 0x40, 0xfe, 0x21, + 0x23, 0x23, 0x23, 0xf, 0x4, 0x0, 0x0, 0x52, + 0x11, 0x23, 0x23, 0x23, 0xfe, 0x2, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x52, + 0x11, 0x23, 0x23, 0x23, 0x23, 0x5, 0x30, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x40, 0x9, 0x23, 0x23, + 0x23, 0x23, 0xf, 0x44, 0x0, 0x0, 0x0, 0x52, + 0x11, 0x23, 0x23, 0x23, 0xfe, 0x42, 0x0, 0x0, + 0x0, 0x2, 0xfe, 0x23, 0x23, 0x23, 0x11, 0x4e, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, 0xc8, + 0xfe, 0x35, 0x5d, 0x67, 0x51, 0x11, 0xf2, 0x8a, + 0x14, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x88, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xeb, 0xbd, 0x5f, 0xfe, 0x70, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x8, 0xa6, 0x11, 0x97, + 0xef, 0xff, 0xff, 0xff, 0xff, 0xf5, 0xa7, 0x1f, + 0xc2, 0xe, 0x0, 0x0, 0x0, 0x88, 0x87, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xd1, 0x8d, + 0x1b, 0xd6, 0x2c, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x5f, 0x58, 0x0, + 0x0, 0x88, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x63, 0x5c, + 0x0, 0x0, 0x0, 0x6, 0xa4, 0xf, 0x91, 0xed, + 0xff, 0xff, 0xff, 0xff, 0xfb, 0xbb, 0x35, 0xdc, + 0x1c, 0x0, 0x0, 0x0, 0x0, 0x88, 0x87, 0xff, + 0xff, 0xff, 0xd, 0x4, 0x0, 0x0, 0x0, 0x4, + 0xd, 0xff, 0xff, 0xff, 0x83, 0x82, 0x0, 0x0, + 0x0, 0x42, 0x4d, 0xff, 0xff, 0xff, 0x5b, 0x52, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x58, 0x5f, 0xff, 0xff, 0xff, 0x43, + 0x36, 0x0, 0x0, 0x0, 0x88, 0x87, 0xff, 0xff, + 0xff, 0xd, 0x4, 0x0, 0xe, 0xe0, 0x75, 0xff, + 0xff, 0xff, 0xd9, 0x15, 0x4, 0x0, 0x0, 0x88, + 0x87, 0xff, 0xff, 0xff, 0xd, 0x4, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x88, + 0x87, 0xff, 0xff, 0xff, 0xff, 0x5f, 0x94, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xac, 0x75, 0xff, 0xff, + 0xff, 0xff, 0x77, 0x76, 0x0, 0x0, 0x0, 0x88, + 0x87, 0xff, 0xff, 0xff, 0x77, 0xda, 0x8, 0x0, + 0x0, 0x4, 0xd, 0xff, 0xff, 0xff, 0x83, 0x82, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x7a, 0xfe, 0x75, + 0xdf, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xb5, 0x35, + 0xde, 0x2a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xac, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xa7, 0xfe, 0x36, + 0x0, 0x0, 0x0, 0x0, 0x86, 0x1b, 0xd1, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, + 0x29, 0x94, 0x0, 0x0, 0x0, 0xac, 0x87, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xed, 0x59, 0xee, 0x26, 0x0, 0x0, 0x0, 0x0, + 0xac, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x5f, 0x68, 0x0, + 0x0, 0xac, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x63, 0x6e, + 0x0, 0x0, 0x0, 0x86, 0x19, 0xcf, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0x43, + 0xb8, 0x0, 0x0, 0x0, 0x0, 0xac, 0x87, 0xff, + 0xff, 0xff, 0xd, 0x6, 0x0, 0x0, 0x0, 0x6, + 0xd, 0xff, 0xff, 0xff, 0x83, 0xa6, 0x0, 0x0, + 0x0, 0x5c, 0x4d, 0xff, 0xff, 0xff, 0x5b, 0x70, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x76, 0x5f, 0xff, 0xff, 0xff, 0x43, + 0x4c, 0x0, 0x0, 0x0, 0xac, 0x87, 0xff, 0xff, + 0xff, 0xd, 0x6, 0x0, 0x8a, 0x27, 0xef, 0xff, + 0xff, 0xf9, 0x43, 0xb8, 0x4, 0x0, 0x0, 0xac, + 0x87, 0xff, 0xff, 0xff, 0xd, 0x6, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xac, + 0x87, 0xff, 0xff, 0xff, 0xff, 0xb1, 0xee, 0x4, + 0x0, 0x0, 0x0, 0xa, 0xf8, 0xc3, 0xff, 0xff, + 0xff, 0xff, 0x77, 0x98, 0x0, 0x0, 0x0, 0xac, + 0x87, 0xff, 0xff, 0xff, 0xeb, 0x1b, 0x6e, 0x0, + 0x0, 0x6, 0xd, 0xff, 0xff, 0xff, 0x83, 0xa6, + 0x0, 0x0, 0x0, 0x0, 0x60, 0x5, 0xb1, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, + 0x57, 0xde, 0x14, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xac, 0x87, 0xff, 0xff, 0xff, 0xad, 0xad, + 0xb1, 0xc7, 0xfb, 0xff, 0xff, 0xff, 0x67, 0x9a, + 0x0, 0x0, 0x0, 0x20, 0xfe, 0xb7, 0xff, 0xff, + 0xff, 0xbf, 0x7d, 0x89, 0xbd, 0xff, 0xff, 0xff, + 0xc3, 0xfe, 0x1c, 0x0, 0x0, 0xac, 0x87, 0xff, + 0xff, 0xff, 0xad, 0xad, 0xb7, 0xd7, 0xff, 0xff, + 0xff, 0xf9, 0x51, 0xc6, 0x2, 0x0, 0x0, 0x0, + 0xac, 0x87, 0xff, 0xff, 0xff, 0xad, 0xad, 0xad, + 0xad, 0xad, 0xad, 0xad, 0xad, 0x41, 0x44, 0x0, + 0x0, 0xac, 0x87, 0xff, 0xff, 0xff, 0xad, 0xad, + 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0x43, 0x4a, + 0x0, 0x0, 0x24, 0xfe, 0xb9, 0xff, 0xff, 0xff, + 0xcd, 0x85, 0x81, 0xb1, 0xfd, 0xff, 0xff, 0xdb, + 0x9, 0x32, 0x0, 0x0, 0x0, 0xac, 0x87, 0xff, + 0xff, 0xff, 0xd, 0x6, 0x0, 0x0, 0x0, 0x6, + 0xd, 0xff, 0xff, 0xff, 0x83, 0xa6, 0x0, 0x0, + 0x0, 0x5c, 0x4d, 0xff, 0xff, 0xff, 0x5b, 0x70, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x76, 0x5f, 0xff, 0xff, 0xff, 0x43, + 0x4c, 0x0, 0x0, 0x0, 0xac, 0x87, 0xff, 0xff, + 0xff, 0xd, 0x6, 0x36, 0xfe, 0xb9, 0xff, 0xff, + 0xff, 0x87, 0xf0, 0x1c, 0x0, 0x0, 0x0, 0xac, + 0x87, 0xff, 0xff, 0xff, 0xd, 0x6, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xac, + 0x87, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xf, 0x3a, + 0x0, 0x0, 0x0, 0x50, 0x21, 0xfb, 0xff, 0xff, + 0xff, 0xff, 0x77, 0x98, 0x0, 0x0, 0x0, 0xac, + 0x87, 0xff, 0xff, 0xff, 0xff, 0xa1, 0xf6, 0x1a, + 0x0, 0x6, 0xd, 0xff, 0xff, 0xff, 0x83, 0xa6, + 0x0, 0x0, 0x0, 0x12, 0xf4, 0x97, 0xff, 0xff, + 0xff, 0xd9, 0x91, 0x83, 0xad, 0xf9, 0xff, 0xff, + 0xf1, 0x35, 0x8e, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xac, 0x87, 0xff, 0xff, 0xff, 0xd, 0xd8, + 0xe0, 0xfa, 0x43, 0xf7, 0xff, 0xff, 0xb5, 0xd6, + 0x0, 0x0, 0x0, 0x7c, 0x49, 0xff, 0xff, 0xff, + 0xa3, 0xfe, 0xc6, 0xc6, 0xfe, 0x95, 0xff, 0xff, + 0xff, 0x43, 0x6a, 0x0, 0x0, 0xac, 0x87, 0xff, + 0xff, 0xff, 0xd, 0xda, 0xe8, 0xfe, 0x53, 0xed, + 0xff, 0xff, 0xe3, 0xb, 0x40, 0x0, 0x0, 0x0, + 0xac, 0x87, 0xff, 0xff, 0xff, 0xd, 0xd8, 0xd6, + 0xd6, 0xd6, 0xd6, 0xd6, 0xbc, 0x84, 0x1a, 0x0, + 0x0, 0xac, 0x87, 0xff, 0xff, 0xff, 0xd, 0xd8, + 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xbc, 0x84, 0x1c, + 0x0, 0x0, 0x80, 0x4f, 0xff, 0xff, 0xff, 0xb1, + 0xfe, 0xce, 0xbe, 0xfa, 0x77, 0xff, 0xff, 0xff, + 0x63, 0x8c, 0x0, 0x0, 0x0, 0xac, 0x87, 0xff, + 0xff, 0xff, 0xd, 0x6, 0x0, 0x0, 0x0, 0x6, + 0xd, 0xff, 0xff, 0xff, 0x83, 0xa6, 0x0, 0x0, + 0x0, 0x5c, 0x4d, 0xff, 0xff, 0xff, 0x5b, 0x70, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x76, 0x5f, 0xff, 0xff, 0xff, 0x43, + 0x4c, 0x0, 0x0, 0x0, 0xac, 0x87, 0xff, 0xff, + 0xff, 0xd, 0xe, 0xd6, 0x69, 0xff, 0xff, 0xff, + 0xc7, 0xfe, 0x50, 0x0, 0x0, 0x0, 0x0, 0xac, + 0x87, 0xff, 0xff, 0xff, 0xd, 0x6, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xac, + 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0x6b, 0xa0, + 0x0, 0x0, 0x0, 0xba, 0x7f, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x77, 0x98, 0x0, 0x0, 0x0, 0xac, + 0x87, 0xff, 0xff, 0xff, 0xff, 0xfb, 0x41, 0xa2, + 0x0, 0x6, 0xd, 0xff, 0xff, 0xff, 0x83, 0xa6, + 0x0, 0x0, 0x0, 0x68, 0x31, 0xfb, 0xff, 0xff, + 0xc1, 0x9, 0xda, 0xc0, 0xf8, 0x51, 0xf9, 0xff, + 0xff, 0xb9, 0xf8, 0x8, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xac, 0x87, 0xff, 0xff, 0xff, 0xd, 0x6, + 0x0, 0x1c, 0xfc, 0xcf, 0xff, 0xff, 0xcb, 0xe6, + 0x0, 0x0, 0x0, 0xca, 0xa1, 0xff, 0xff, 0xf7, + 0x21, 0x72, 0x0, 0x0, 0x60, 0x13, 0xfb, 0xff, + 0xff, 0x91, 0x98, 0x0, 0x0, 0xac, 0x87, 0xff, + 0xff, 0xff, 0xd, 0x6, 0x0, 0x26, 0xde, 0x67, + 0xff, 0xff, 0xff, 0x73, 0x9c, 0x0, 0x0, 0x0, + 0xac, 0x87, 0xff, 0xff, 0xff, 0xd, 0x6, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xac, 0x87, 0xff, 0xff, 0xff, 0xd, 0x6, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xce, 0xa3, 0xff, 0xff, 0xf7, 0x27, + 0x80, 0x0, 0x0, 0x42, 0xfe, 0xe3, 0xff, 0xff, + 0xa7, 0x9a, 0x0, 0x0, 0x0, 0xac, 0x87, 0xff, + 0xff, 0xff, 0xd, 0x6, 0x0, 0x0, 0x0, 0x6, + 0xd, 0xff, 0xff, 0xff, 0x83, 0xa6, 0x0, 0x0, + 0x0, 0x5c, 0x4d, 0xff, 0xff, 0xff, 0x5b, 0x70, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x76, 0x5f, 0xff, 0xff, 0xff, 0x43, + 0x4c, 0x0, 0x0, 0x0, 0xac, 0x87, 0xff, 0xff, + 0xff, 0xd, 0x7e, 0x1f, 0xeb, 0xff, 0xff, 0xef, + 0x2d, 0x9a, 0x0, 0x0, 0x0, 0x0, 0x0, 0xac, + 0x87, 0xff, 0xff, 0xff, 0xd, 0x6, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xac, + 0x87, 0xff, 0xff, 0xeb, 0xff, 0xff, 0xbb, 0xf4, + 0x6, 0x0, 0x10, 0xfc, 0xcb, 0xff, 0xff, 0xeb, + 0xff, 0xff, 0x77, 0x98, 0x0, 0x0, 0x0, 0xac, + 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc9, 0xfe, + 0x3a, 0x6, 0xd, 0xff, 0xff, 0xff, 0x83, 0xa6, + 0x0, 0x0, 0x0, 0xbe, 0x93, 0xff, 0xff, 0xfb, + 0x37, 0x96, 0x0, 0x0, 0x26, 0xf6, 0xa9, 0xff, + 0xff, 0xfd, 0x1f, 0x3a, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xac, 0x87, 0xff, 0xff, 0xff, 0xd, 0x6, + 0x6, 0x5e, 0xfe, 0xd9, 0xff, 0xff, 0xb5, 0xd4, + 0x0, 0x0, 0x0, 0xec, 0xcb, 0xff, 0xff, 0xcb, + 0xf8, 0xa, 0x0, 0x0, 0x4, 0xf4, 0xa3, 0xbd, + 0xbd, 0x83, 0x8a, 0x0, 0x0, 0xac, 0x87, 0xff, + 0xff, 0xff, 0xd, 0x6, 0x0, 0x0, 0x34, 0xfe, + 0xe7, 0xff, 0xff, 0xb1, 0xd8, 0x0, 0x0, 0x0, + 0xac, 0x87, 0xff, 0xff, 0xff, 0xd, 0x4c, 0x46, + 0x46, 0x46, 0x46, 0x30, 0x1a, 0x0, 0x0, 0x0, + 0x0, 0xac, 0x87, 0xff, 0xff, 0xff, 0xd, 0x6, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xee, 0xcd, 0xff, 0xff, 0xcd, 0xfa, + 0xc, 0x0, 0x0, 0x0, 0xc4, 0x49, 0x63, 0x63, + 0x49, 0x82, 0x0, 0x0, 0x0, 0xac, 0x87, 0xff, + 0xff, 0xff, 0xd, 0x6, 0x0, 0x0, 0x0, 0x6, + 0xd, 0xff, 0xff, 0xff, 0x83, 0xa6, 0x0, 0x0, + 0x0, 0x5c, 0x4d, 0xff, 0xff, 0xff, 0x5b, 0x70, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x76, 0x5f, 0xff, 0xff, 0xff, 0x43, + 0x4c, 0x0, 0x0, 0x0, 0xac, 0x87, 0xff, 0xff, + 0xff, 0xd, 0xfc, 0xaf, 0xff, 0xff, 0xff, 0x6b, + 0xde, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0xac, + 0x87, 0xff, 0xff, 0xff, 0xd, 0x6, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xac, + 0x87, 0xff, 0xff, 0xcb, 0xe3, 0xff, 0xf7, 0x17, + 0x44, 0x0, 0x5e, 0x2d, 0xfd, 0xff, 0xd3, 0xdb, + 0xff, 0xff, 0x77, 0x98, 0x0, 0x0, 0x0, 0xac, + 0x87, 0xff, 0xff, 0xff, 0xdf, 0xff, 0xff, 0x6d, + 0xd0, 0xa, 0xd, 0xff, 0xff, 0xff, 0x83, 0xa6, + 0x0, 0x0, 0x0, 0xe8, 0xc5, 0xff, 0xff, 0xd3, + 0xfc, 0x16, 0x0, 0x0, 0x0, 0x8e, 0x53, 0xff, + 0xff, 0xff, 0x65, 0x72, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xac, 0x87, 0xff, 0xff, 0xff, 0xd, 0xfe, + 0xfe, 0x17, 0x91, 0xff, 0xff, 0xff, 0x5b, 0x96, + 0x0, 0x0, 0x0, 0xf6, 0xdb, 0xff, 0xff, 0xb3, + 0xe2, 0x0, 0x0, 0x0, 0x0, 0x6c, 0xba, 0xde, + 0xd8, 0xac, 0x4c, 0x0, 0x0, 0xac, 0x87, 0xff, + 0xff, 0xff, 0xd, 0x6, 0x0, 0x0, 0x0, 0xf2, + 0xc3, 0xff, 0xff, 0xcf, 0xf0, 0x0, 0x0, 0x0, + 0xac, 0x87, 0xff, 0xff, 0xff, 0x43, 0x3f, 0x3f, + 0x3f, 0x3f, 0x3f, 0x3f, 0x9, 0xe, 0x0, 0x0, + 0x0, 0xac, 0x87, 0xff, 0xff, 0xff, 0xd, 0xf0, + 0xf0, 0xf0, 0xf0, 0xf0, 0xda, 0xa0, 0xa, 0x0, + 0x0, 0x0, 0xf6, 0xdb, 0xff, 0xff, 0xb3, 0xe4, + 0x0, 0x0, 0x0, 0x0, 0x20, 0x4c, 0x70, 0x70, + 0x4c, 0x20, 0x0, 0x0, 0x0, 0xac, 0x87, 0xff, + 0xff, 0xff, 0xd, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, + 0xd, 0xff, 0xff, 0xff, 0x83, 0xa6, 0x0, 0x0, + 0x0, 0x5c, 0x4d, 0xff, 0xff, 0xff, 0x5b, 0x70, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x76, 0x5f, 0xff, 0xff, 0xff, 0x43, + 0x4c, 0x0, 0x0, 0x0, 0xac, 0x87, 0xff, 0xff, + 0xff, 0x33, 0x69, 0xff, 0xff, 0xff, 0xb1, 0xfe, + 0x38, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xac, + 0x87, 0xff, 0xff, 0xff, 0xd, 0x6, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xac, + 0x87, 0xff, 0xff, 0xd5, 0x99, 0xff, 0xff, 0x75, + 0xac, 0x0, 0xc6, 0x89, 0xff, 0xff, 0x85, 0xe3, + 0xff, 0xff, 0x77, 0x98, 0x0, 0x0, 0x0, 0xac, + 0x87, 0xff, 0xff, 0xff, 0x5f, 0xff, 0xff, 0xe5, + 0x13, 0x66, 0xd, 0xff, 0xff, 0xff, 0x83, 0xa6, + 0x0, 0x0, 0x0, 0xf4, 0xd9, 0xff, 0xff, 0xb7, + 0xe6, 0x0, 0x0, 0x0, 0x0, 0x32, 0x27, 0xff, + 0xff, 0xff, 0x7d, 0x9a, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xac, 0x87, 0xff, 0xff, 0xff, 0xf1, 0xf1, + 0xf3, 0xff, 0xff, 0xff, 0xf5, 0x81, 0xfc, 0x2c, + 0x0, 0x0, 0x0, 0xf8, 0xdf, 0xff, 0xff, 0xad, + 0xd8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xac, 0x87, 0xff, + 0xff, 0xff, 0xd, 0x6, 0x0, 0x0, 0x0, 0xe4, + 0xb7, 0xff, 0xff, 0xdb, 0xf6, 0x0, 0x0, 0x0, + 0xac, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x29, 0x1c, 0x0, 0x0, + 0x0, 0xac, 0x87, 0xff, 0xff, 0xff, 0xcf, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0x21, 0x18, 0x0, + 0x0, 0x0, 0xf8, 0xdf, 0xff, 0xff, 0xad, 0xd8, + 0x0, 0x68, 0xc0, 0xe4, 0xec, 0xec, 0xec, 0xe4, + 0xbe, 0x62, 0x0, 0x0, 0x0, 0xac, 0x87, 0xff, + 0xff, 0xff, 0xcf, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcf, 0xff, 0xff, 0xff, 0x83, 0xa6, 0x0, 0x0, + 0x0, 0x5c, 0x4d, 0xff, 0xff, 0xff, 0x5b, 0x70, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x76, 0x5f, 0xff, 0xff, 0xff, 0x43, + 0x4c, 0x0, 0x0, 0x0, 0xac, 0x87, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xe5, 0x19, 0x82, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xac, + 0x87, 0xff, 0xff, 0xff, 0xd, 0x6, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xac, + 0x87, 0xff, 0xff, 0xdd, 0x3b, 0xff, 0xff, 0xc3, + 0xf8, 0x20, 0xfe, 0xd5, 0xff, 0xfb, 0x25, 0xeb, + 0xff, 0xff, 0x77, 0x98, 0x0, 0x0, 0x0, 0xac, + 0x87, 0xff, 0xff, 0xff, 0xd, 0xbb, 0xff, 0xff, + 0x99, 0xf0, 0xd, 0xff, 0xff, 0xff, 0x83, 0xa6, + 0x0, 0x0, 0x0, 0xf8, 0xdf, 0xff, 0xff, 0xad, + 0xda, 0x0, 0x0, 0x0, 0x0, 0x10, 0xd, 0xff, + 0xff, 0xff, 0x87, 0xa8, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xac, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xe3, 0x81, 0xfe, 0x6a, + 0x0, 0x0, 0x0, 0xfa, 0xdf, 0xff, 0xff, 0xad, + 0xd6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xac, 0x87, 0xff, + 0xff, 0xff, 0xd, 0x6, 0x0, 0x0, 0x0, 0xe0, + 0xb7, 0xff, 0xff, 0xdd, 0xf8, 0x0, 0x0, 0x0, + 0xac, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x29, 0x22, 0x0, 0x0, + 0x0, 0xac, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x29, 0x22, 0x0, + 0x0, 0x0, 0xfa, 0xdf, 0xff, 0xff, 0xad, 0xd6, + 0x0, 0xc4, 0x9f, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, + 0x9b, 0xbe, 0x0, 0x0, 0x0, 0xac, 0x87, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x83, 0xa6, 0x0, 0x0, + 0x0, 0x5c, 0x4d, 0xff, 0xff, 0xff, 0x5b, 0x70, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x76, 0x5f, 0xff, 0xff, 0xff, 0x43, + 0x4c, 0x0, 0x0, 0x0, 0xac, 0x87, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0x27, 0x90, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xac, + 0x87, 0xff, 0xff, 0xff, 0xd, 0x6, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xac, + 0x87, 0xff, 0xff, 0xe5, 0xfe, 0xd3, 0xff, 0xfb, + 0x21, 0x98, 0x39, 0xff, 0xff, 0xc3, 0xfe, 0xf3, + 0xff, 0xff, 0x77, 0x98, 0x0, 0x0, 0x0, 0xac, + 0x87, 0xff, 0xff, 0xff, 0xd, 0x31, 0xf7, 0xff, + 0xf9, 0x37, 0xd, 0xff, 0xff, 0xff, 0x83, 0xa6, + 0x0, 0x0, 0x0, 0xfa, 0xdf, 0xff, 0xff, 0xad, + 0xd6, 0x0, 0x0, 0x0, 0x0, 0x6, 0xd, 0xff, + 0xff, 0xff, 0x87, 0xac, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xac, 0x87, 0xff, 0xff, 0xff, 0x93, 0x91, + 0x91, 0x95, 0xbb, 0xff, 0xff, 0xff, 0xa1, 0xf6, + 0x12, 0x0, 0x0, 0xf8, 0xdf, 0xff, 0xff, 0xad, + 0xda, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xac, 0x87, 0xff, + 0xff, 0xff, 0xd, 0x6, 0x0, 0x0, 0x0, 0xe4, + 0xb7, 0xff, 0xff, 0xdb, 0xf6, 0x0, 0x0, 0x0, + 0xac, 0x87, 0xff, 0xff, 0xff, 0x9d, 0x9b, 0x9b, + 0x9b, 0x9b, 0x9b, 0x9b, 0x19, 0x14, 0x0, 0x0, + 0x0, 0xac, 0x87, 0xff, 0xff, 0xff, 0xef, 0xef, + 0xef, 0xef, 0xef, 0xef, 0xef, 0x27, 0x1a, 0x0, + 0x0, 0x0, 0xf8, 0xdf, 0xff, 0xff, 0xad, 0xda, + 0x0, 0xda, 0xcd, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xc7, 0xe4, 0x0, 0x0, 0x0, 0xac, 0x87, 0xff, + 0xff, 0xff, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, + 0xef, 0xff, 0xff, 0xff, 0x83, 0xa6, 0x0, 0x0, + 0x0, 0x5c, 0x4d, 0xff, 0xff, 0xff, 0x5b, 0x70, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x76, 0x5f, 0xff, 0xff, 0xff, 0x43, + 0x4c, 0x0, 0x0, 0x0, 0xac, 0x87, 0xff, 0xff, + 0xff, 0xe9, 0xe9, 0xff, 0xff, 0xff, 0xbb, 0xfe, + 0x3c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xac, + 0x87, 0xff, 0xff, 0xff, 0xd, 0x6, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xac, + 0x87, 0xff, 0xff, 0xef, 0xfe, 0x85, 0xff, 0xff, + 0x7d, 0xf2, 0x93, 0xff, 0xff, 0x71, 0xfe, 0xfb, + 0xff, 0xff, 0x77, 0x98, 0x0, 0x0, 0x0, 0xac, + 0x87, 0xff, 0xff, 0xff, 0xd, 0xec, 0x93, 0xff, + 0xff, 0xbf, 0xd, 0xff, 0xff, 0xff, 0x83, 0xa6, + 0x0, 0x0, 0x0, 0xf8, 0xdf, 0xff, 0xff, 0xad, + 0xda, 0x0, 0x0, 0x0, 0x0, 0x12, 0xd, 0xff, + 0xff, 0xff, 0x87, 0xa8, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xac, 0x87, 0xff, 0xff, 0xff, 0xd, 0xba, + 0xba, 0xcc, 0xfe, 0x8b, 0xff, 0xff, 0xfb, 0x31, + 0x46, 0x0, 0x0, 0xf6, 0xdb, 0xff, 0xff, 0xb5, + 0xe4, 0x0, 0x0, 0x0, 0x0, 0x6c, 0xb8, 0xdc, + 0xd6, 0xa8, 0x4c, 0x0, 0x0, 0xac, 0x87, 0xff, + 0xff, 0xff, 0xd, 0x6, 0x0, 0x0, 0x0, 0xf4, + 0xc5, 0xff, 0xff, 0xcd, 0xee, 0x0, 0x0, 0x0, + 0xac, 0x87, 0xff, 0xff, 0xff, 0xd, 0xc8, 0xc6, + 0xc6, 0xc6, 0xc6, 0xa4, 0x68, 0x6, 0x0, 0x0, + 0x0, 0xac, 0x87, 0xff, 0xff, 0xff, 0xd, 0xfe, + 0xfe, 0xfe, 0xfe, 0xfe, 0xf8, 0xd4, 0xc, 0x0, + 0x0, 0x0, 0xf6, 0xdb, 0xff, 0xff, 0xb5, 0xe6, + 0x0, 0xc2, 0x9b, 0xc1, 0xc1, 0xef, 0xff, 0xff, + 0xc7, 0xec, 0x0, 0x0, 0x0, 0xac, 0x87, 0xff, + 0xff, 0xff, 0xd, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, + 0xd, 0xff, 0xff, 0xff, 0x83, 0xa6, 0x0, 0x0, + 0x0, 0x5c, 0x4d, 0xff, 0xff, 0xff, 0x5b, 0x70, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x76, 0x5f, 0xff, 0xff, 0xff, 0x43, + 0x4c, 0x0, 0x0, 0x0, 0xac, 0x87, 0xff, 0xff, + 0xff, 0xd, 0xfe, 0xc1, 0xff, 0xff, 0xff, 0x71, + 0xde, 0xe, 0x0, 0x0, 0x0, 0x0, 0x0, 0xac, + 0x87, 0xff, 0xff, 0xff, 0xd, 0x6, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xac, + 0x87, 0xff, 0xff, 0xf7, 0xfe, 0x25, 0xfb, 0xff, + 0xcb, 0xfe, 0xdd, 0xff, 0xf3, 0x11, 0xf, 0xff, + 0xff, 0xff, 0x77, 0x98, 0x0, 0x0, 0x0, 0xac, + 0x87, 0xff, 0xff, 0xff, 0xd, 0x60, 0xf, 0xe3, + 0xff, 0xff, 0x67, 0xff, 0xff, 0xff, 0x83, 0xa6, + 0x0, 0x0, 0x0, 0xf4, 0xd9, 0xff, 0xff, 0xbb, + 0xe8, 0x0, 0x0, 0x0, 0x0, 0x36, 0x2b, 0xff, + 0xff, 0xff, 0x7b, 0x98, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xac, 0x87, 0xff, 0xff, 0xff, 0xd, 0x6, + 0x0, 0x0, 0x70, 0x35, 0xff, 0xff, 0xff, 0x6b, + 0x74, 0x0, 0x0, 0xec, 0xcb, 0xff, 0xff, 0xcd, + 0xfa, 0xc, 0x0, 0x0, 0x6, 0xf6, 0xa3, 0xbb, + 0xbb, 0x81, 0x8e, 0x0, 0x0, 0xac, 0x87, 0xff, + 0xff, 0xff, 0xd, 0x6, 0x0, 0x0, 0x3c, 0x5, + 0xeb, 0xff, 0xff, 0xaf, 0xd6, 0x0, 0x0, 0x0, + 0xac, 0x87, 0xff, 0xff, 0xff, 0xd, 0x6, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xac, 0x87, 0xff, 0xff, 0xff, 0xd, 0x6, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xec, 0xcb, 0xff, 0xff, 0xcf, 0xfa, + 0x12, 0x62, 0xb8, 0xe0, 0xfe, 0xcb, 0xff, 0xff, + 0xc7, 0xec, 0x0, 0x0, 0x0, 0xac, 0x87, 0xff, + 0xff, 0xff, 0xd, 0x6, 0x0, 0x0, 0x0, 0x6, + 0xd, 0xff, 0xff, 0xff, 0x83, 0xa6, 0x0, 0x0, + 0x0, 0x5c, 0x4d, 0xff, 0xff, 0xff, 0x5b, 0x70, + 0x0, 0x0, 0x34, 0xe8, 0xfc, 0xfe, 0xfc, 0xe6, + 0x1a, 0x0, 0x80, 0x5f, 0xff, 0xff, 0xff, 0x43, + 0x44, 0x0, 0x0, 0x0, 0xac, 0x87, 0xff, 0xff, + 0xff, 0xd, 0x98, 0x31, 0xf3, 0xff, 0xff, 0xef, + 0x27, 0x8e, 0x0, 0x0, 0x0, 0x0, 0x0, 0xac, + 0x87, 0xff, 0xff, 0xff, 0xd, 0x6, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xac, + 0x87, 0xff, 0xff, 0xff, 0x5, 0xfa, 0xc1, 0xff, + 0xfd, 0x5d, 0xff, 0xff, 0xb1, 0xf0, 0x21, 0xff, + 0xff, 0xff, 0x77, 0x98, 0x0, 0x0, 0x0, 0xac, + 0x87, 0xff, 0xff, 0xff, 0xd, 0xa, 0xca, 0x65, + 0xff, 0xff, 0xe3, 0xff, 0xff, 0xff, 0x83, 0xa6, + 0x0, 0x0, 0x0, 0xe8, 0xc3, 0xff, 0xff, 0xd5, + 0xfe, 0x1a, 0x0, 0x0, 0x0, 0x92, 0x55, 0xff, + 0xff, 0xff, 0x61, 0x6e, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xac, 0x87, 0xff, 0xff, 0xff, 0xd, 0x6, + 0x0, 0x0, 0x8c, 0x3b, 0xff, 0xff, 0xff, 0x75, + 0x7e, 0x0, 0x0, 0xca, 0xa1, 0xff, 0xff, 0xf7, + 0x23, 0x72, 0x0, 0x0, 0x6a, 0x17, 0xfb, 0xff, + 0xff, 0x95, 0x9c, 0x0, 0x0, 0xac, 0x87, 0xff, + 0xff, 0xff, 0xd, 0x6, 0x0, 0x32, 0xe6, 0x71, + 0xff, 0xff, 0xff, 0x6d, 0x98, 0x0, 0x0, 0x0, + 0xac, 0x87, 0xff, 0xff, 0xff, 0xd, 0x6, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xac, 0x87, 0xff, 0xff, 0xff, 0xd, 0x6, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xc8, 0x9d, 0xff, 0xff, 0xf9, 0x31, + 0x92, 0x0, 0x0, 0x0, 0xf0, 0xcb, 0xff, 0xff, + 0xc7, 0xec, 0x0, 0x0, 0x0, 0xac, 0x87, 0xff, + 0xff, 0xff, 0xd, 0x6, 0x0, 0x0, 0x0, 0x6, + 0xd, 0xff, 0xff, 0xff, 0x83, 0xa6, 0x0, 0x0, + 0x0, 0x5c, 0x4d, 0xff, 0xff, 0xff, 0x5b, 0x70, + 0x0, 0x0, 0x4c, 0x67, 0xf7, 0xf7, 0xf7, 0x3f, + 0x5e, 0x0, 0xb2, 0x75, 0xff, 0xff, 0xff, 0x31, + 0x2c, 0x0, 0x0, 0x0, 0xac, 0x87, 0xff, 0xff, + 0xff, 0xd, 0x18, 0xe8, 0x83, 0xff, 0xff, 0xff, + 0xbd, 0xfe, 0x3e, 0x0, 0x0, 0x0, 0x0, 0xac, + 0x87, 0xff, 0xff, 0xff, 0xd, 0x6, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xac, + 0x87, 0xff, 0xff, 0xff, 0xd, 0xac, 0x71, 0xff, + 0xff, 0xe9, 0xff, 0xff, 0x5b, 0xa0, 0x29, 0xff, + 0xff, 0xff, 0x77, 0x98, 0x0, 0x0, 0x0, 0xac, + 0x87, 0xff, 0xff, 0xff, 0xd, 0x6, 0x34, 0xfe, + 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x83, 0xa6, + 0x0, 0x0, 0x0, 0xba, 0x8f, 0xff, 0xff, 0xfd, + 0x3f, 0xa2, 0x4, 0x0, 0x2a, 0xf8, 0xad, 0xff, + 0xff, 0xfb, 0x1b, 0x36, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xac, 0x87, 0xff, 0xff, 0xff, 0xd, 0xe0, + 0xe2, 0xf0, 0x9, 0xad, 0xff, 0xff, 0xff, 0x4d, + 0x5a, 0x0, 0x0, 0x7c, 0x49, 0xff, 0xff, 0xff, + 0xa5, 0xfe, 0xd0, 0xd0, 0xfe, 0x9f, 0xff, 0xff, + 0xff, 0x4b, 0x72, 0x0, 0x0, 0xac, 0x87, 0xff, + 0xff, 0xff, 0xd, 0xe4, 0xf0, 0xfe, 0x63, 0xf1, + 0xff, 0xff, 0xdf, 0x9, 0x3a, 0x0, 0x0, 0x0, + 0xac, 0x87, 0xff, 0xff, 0xff, 0xd, 0xe0, 0xe0, + 0xe0, 0xe0, 0xe0, 0xe0, 0xc8, 0x92, 0x20, 0x0, + 0x0, 0xac, 0x87, 0xff, 0xff, 0xff, 0xd, 0x6, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x74, 0x41, 0xfd, 0xff, 0xff, 0xbf, + 0x9, 0xdc, 0xb6, 0xd6, 0xfe, 0xd1, 0xff, 0xff, + 0xc7, 0xec, 0x0, 0x0, 0x0, 0xac, 0x87, 0xff, + 0xff, 0xff, 0xd, 0x6, 0x0, 0x0, 0x0, 0x6, + 0xd, 0xff, 0xff, 0xff, 0x83, 0xa6, 0x0, 0x0, + 0x0, 0x5c, 0x4d, 0xff, 0xff, 0xff, 0x5b, 0x70, + 0x0, 0x0, 0x4c, 0x47, 0xff, 0xff, 0xff, 0x81, + 0xf6, 0xd0, 0xfe, 0xb7, 0xff, 0xff, 0xf1, 0x9, + 0x12, 0x0, 0x0, 0x0, 0xac, 0x87, 0xff, 0xff, + 0xff, 0xd, 0x6, 0x4c, 0x5, 0xcf, 0xff, 0xff, + 0xff, 0x73, 0xe0, 0xe, 0x0, 0x0, 0x0, 0xac, + 0x87, 0xff, 0xff, 0xff, 0xd, 0xe0, 0xe0, 0xe0, + 0xe0, 0xe0, 0xd2, 0xa6, 0x4a, 0x0, 0x0, 0xac, + 0x87, 0xff, 0xff, 0xff, 0xd, 0x44, 0x11, 0xf3, + 0xff, 0xff, 0xff, 0xe7, 0x5, 0x4e, 0x29, 0xff, + 0xff, 0xff, 0x77, 0x98, 0x0, 0x0, 0x0, 0xac, + 0x87, 0xff, 0xff, 0xff, 0xd, 0x6, 0x0, 0x98, + 0x39, 0xf9, 0xff, 0xff, 0xff, 0xff, 0x83, 0xa6, + 0x0, 0x0, 0x0, 0x62, 0x2d, 0xf9, 0xff, 0xff, + 0xc9, 0x11, 0xe6, 0xce, 0xfa, 0x57, 0xfb, 0xff, + 0xff, 0xb5, 0xf6, 0x8, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xac, 0x87, 0xff, 0xff, 0xff, 0xb7, 0xb7, + 0xb7, 0xbf, 0xe3, 0xff, 0xff, 0xff, 0xdb, 0xfe, + 0x22, 0x0, 0x0, 0x20, 0xfe, 0xb9, 0xff, 0xff, + 0xff, 0xc7, 0x89, 0x93, 0xc9, 0xff, 0xff, 0xff, + 0xc5, 0xfe, 0x22, 0x0, 0x0, 0xac, 0x87, 0xff, + 0xff, 0xff, 0xb7, 0xb7, 0xbf, 0xe1, 0xff, 0xff, + 0xff, 0xf7, 0x49, 0xc0, 0x0, 0x0, 0x0, 0x0, + 0xac, 0x87, 0xff, 0xff, 0xff, 0xb7, 0xb7, 0xb7, + 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0x49, 0x50, 0x0, + 0x0, 0xac, 0x87, 0xff, 0xff, 0xff, 0xd, 0x6, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x1c, 0xfa, 0xa7, 0xff, 0xff, 0xff, + 0xdb, 0x93, 0x83, 0x95, 0xd1, 0xff, 0xff, 0xff, + 0xc3, 0xd4, 0x0, 0x0, 0x0, 0xac, 0x87, 0xff, + 0xff, 0xff, 0xd, 0x6, 0x0, 0x0, 0x0, 0x6, + 0xd, 0xff, 0xff, 0xff, 0x83, 0xa6, 0x0, 0x0, + 0x0, 0x5c, 0x4d, 0xff, 0xff, 0xff, 0x5b, 0x70, + 0x0, 0x0, 0x1e, 0xfe, 0xe3, 0xff, 0xff, 0xf7, + 0xa5, 0x89, 0xbb, 0xff, 0xff, 0xff, 0xa7, 0xea, + 0x0, 0x0, 0x0, 0x0, 0xac, 0x87, 0xff, 0xff, + 0xff, 0xd, 0x6, 0x0, 0xaa, 0x3f, 0xf9, 0xff, + 0xff, 0xef, 0x29, 0x90, 0x0, 0x0, 0x0, 0xac, + 0x87, 0xff, 0xff, 0xff, 0xb7, 0xb7, 0xb7, 0xb7, + 0xb7, 0xb7, 0xb7, 0x7f, 0xa2, 0x0, 0x0, 0xac, + 0x87, 0xff, 0xff, 0xff, 0xd, 0xa, 0xee, 0xb1, + 0xff, 0xff, 0xff, 0x9f, 0xde, 0x2a, 0x29, 0xff, + 0xff, 0xff, 0x77, 0x98, 0x0, 0x0, 0x0, 0xac, + 0x87, 0xff, 0xff, 0xff, 0xd, 0x6, 0x0, 0x16, + 0xf2, 0x9b, 0xff, 0xff, 0xff, 0xff, 0x83, 0xa6, + 0x0, 0x0, 0x0, 0x10, 0xee, 0x8f, 0xff, 0xff, + 0xff, 0xe3, 0x9f, 0x91, 0xb7, 0xfb, 0xff, 0xff, + 0xef, 0x31, 0x88, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xac, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xed, 0x45, 0xba, + 0x0, 0x0, 0x0, 0x0, 0x88, 0x1d, 0xcf, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, + 0x27, 0x98, 0x0, 0x0, 0x0, 0xac, 0x87, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xe5, 0x4d, 0xe8, 0x20, 0x0, 0x0, 0x0, 0x0, + 0xac, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x67, 0x74, 0x0, + 0x0, 0xac, 0x87, 0xff, 0xff, 0xff, 0xd, 0x6, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x70, 0xb, 0xb7, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, + 0x37, 0x98, 0x0, 0x0, 0x0, 0xac, 0x87, 0xff, + 0xff, 0xff, 0xd, 0x6, 0x0, 0x0, 0x0, 0x6, + 0xd, 0xff, 0xff, 0xff, 0x83, 0xa6, 0x0, 0x0, + 0x0, 0x5c, 0x4d, 0xff, 0xff, 0xff, 0x5b, 0x70, + 0x0, 0x0, 0x0, 0xc8, 0x5d, 0xfb, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xd9, 0x1d, 0x74, + 0x0, 0x0, 0x0, 0x0, 0xac, 0x87, 0xff, 0xff, + 0xff, 0xd, 0x6, 0x0, 0x1a, 0xf2, 0x93, 0xff, + 0xff, 0xff, 0xbf, 0xfe, 0x40, 0x0, 0x0, 0xac, + 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xb3, 0xd0, 0x0, 0x0, 0xac, + 0x87, 0xff, 0xff, 0xff, 0xd, 0x6, 0x90, 0x59, + 0xff, 0xff, 0xff, 0x41, 0x76, 0x2a, 0x29, 0xff, + 0xff, 0xff, 0x77, 0x98, 0x0, 0x0, 0x0, 0xac, + 0x87, 0xff, 0xff, 0xff, 0xd, 0x6, 0x0, 0x0, + 0x66, 0x15, 0xe9, 0xff, 0xff, 0xff, 0x83, 0xa6, + 0x0, 0x0, 0x0, 0x0, 0x58, 0xfe, 0xa7, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, + 0x51, 0xda, 0x12, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x86, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xfd, 0xf3, 0xd3, 0x95, 0x21, 0xd4, 0x1e, + 0x0, 0x0, 0x0, 0x0, 0x8, 0xa4, 0x11, 0x91, + 0xe9, 0xff, 0xff, 0xff, 0xff, 0xeb, 0x9b, 0x17, + 0xba, 0xe, 0x0, 0x0, 0x0, 0x86, 0x87, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xf9, 0xeb, 0xc3, 0x7f, + 0xf, 0xca, 0x24, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x86, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x67, 0x60, 0x0, + 0x0, 0x86, 0x87, 0xff, 0xff, 0xff, 0xd, 0x4, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x2, 0x82, 0xfe, 0x73, 0xd7, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xd5, 0x89, 0xd, + 0xbc, 0x16, 0x0, 0x0, 0x0, 0x86, 0x87, 0xff, + 0xff, 0xff, 0xd, 0x4, 0x0, 0x0, 0x0, 0x4, + 0xd, 0xff, 0xff, 0xff, 0x83, 0x82, 0x0, 0x0, + 0x0, 0x42, 0x4d, 0xff, 0xff, 0xff, 0x5b, 0x52, + 0x0, 0x0, 0x0, 0x2e, 0xf0, 0x4d, 0xc9, 0xfd, + 0xff, 0xff, 0xff, 0xf3, 0xa5, 0x19, 0xb2, 0x8, + 0x0, 0x0, 0x0, 0x0, 0x86, 0x87, 0xff, 0xff, + 0xff, 0xd, 0x4, 0x0, 0x0, 0x5e, 0xd, 0xdb, + 0xff, 0xff, 0xff, 0x75, 0x40, 0x0, 0x0, 0x86, + 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xb3, 0xbc, 0x0, 0x0, 0x86, + 0x87, 0xff, 0xff, 0xff, 0xd, 0x4, 0x2c, 0xfe, + 0xe7, 0xff, 0xd9, 0xfe, 0x1c, 0x1c, 0x29, 0xff, + 0xff, 0xff, 0x77, 0x74, 0x0, 0x0, 0x0, 0x86, + 0x87, 0xff, 0xff, 0xff, 0xd, 0x4, 0x0, 0x0, + 0x6, 0xd4, 0x6f, 0xff, 0xff, 0xff, 0x83, 0x82, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x6e, 0xfe, 0x69, + 0xd3, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xab, 0x2d, + 0xd8, 0x26, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x50, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, + 0xfe, 0xfe, 0xfe, 0xf6, 0xc8, 0x64, 0xa, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x5a, 0xda, + 0xfe, 0x39, 0x55, 0x55, 0x35, 0xfe, 0xe0, 0x68, + 0x6, 0x0, 0x0, 0x0, 0x0, 0x50, 0xfe, 0xfe, + 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xee, 0xb0, + 0x4a, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x50, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, + 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0x36, 0x0, + 0x0, 0x50, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0x2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, 0xbe, 0xfe, + 0x25, 0x4f, 0x57, 0x43, 0x21, 0xfc, 0xc4, 0x54, + 0x2, 0x0, 0x0, 0x0, 0x0, 0x50, 0xfe, 0xfe, + 0xfe, 0xfe, 0xfe, 0x2, 0x0, 0x0, 0x0, 0x2, + 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0x4c, 0x0, 0x0, + 0x0, 0x24, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0x2c, + 0x0, 0x0, 0x0, 0x0, 0x24, 0xa6, 0xfa, 0x1b, + 0x4d, 0x59, 0x47, 0xb, 0xea, 0x70, 0x6, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x50, 0xfe, 0xfe, 0xfe, + 0xfe, 0xfe, 0x2, 0x0, 0x0, 0x2, 0xb0, 0xfe, + 0xfe, 0xfe, 0xfe, 0xfe, 0x40, 0x0, 0x0, 0x50, + 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, + 0xfe, 0xfe, 0xfe, 0xfe, 0x7e, 0x0, 0x0, 0x50, + 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0x2, 0x0, 0xc2, + 0xfe, 0xfe, 0xfe, 0xac, 0x0, 0xe, 0xfe, 0xfe, + 0xfe, 0xfe, 0xfe, 0x42, 0x0, 0x0, 0x0, 0x50, + 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0x2, 0x0, 0x0, + 0x0, 0x3c, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0x4c, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x36, 0xb8, + 0xfc, 0x23, 0x4d, 0x57, 0x41, 0x9, 0xea, 0x7e, + 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x16, 0x3c, 0x5a, 0x58, 0x38, 0x14, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, + 0x2e, 0x50, 0x5c, 0x48, 0x24, 0xa, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x2a, + 0x4e, 0x5e, 0x46, 0x20, 0x2, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc, 0x2e, 0x50, 0x5a, 0x40, 0x1a, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x62, 0xd0, 0xf0, 0xf8, 0xf8, 0xee, 0xca, + 0x4c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x90, + 0xde, 0xf4, 0xf8, 0xf8, 0xea, 0xbc, 0x24, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb0, 0x9b, 0xdd, 0xdd, 0xdd, 0xdd, 0x83, + 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe2, + 0xc3, 0xdd, 0xdd, 0xdd, 0xdd, 0x4d, 0x4a, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4, 0xe, 0x1a, 0x20, 0x20, 0x20, 0x20, + 0x1e, 0x14, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x14, 0x3e, 0x66, 0x72, 0x56, 0x28, 0x4, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x4, 0xe, 0x1a, 0x20, 0x20, 0x20, 0x20, 0x1e, + 0x14, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, + 0x32, 0x5e, 0x78, 0x6c, 0x44, 0x18, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x4, 0x10, 0x1a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x1e, 0x12, 0x8, 0x0, 0x0, 0x6, + 0x12, 0x1c, 0x1e, 0x14, 0x8, 0x0, 0x0, 0x0, + 0x0, 0x4, 0xe, 0x1a, 0x20, 0x16, 0xc, 0x0, + 0x0, 0x8, 0x14, 0x1e, 0x1e, 0x14, 0x8, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x4, 0xe, 0x1a, 0x20, + 0x18, 0xc, 0x2, 0x2, 0xe, 0x18, 0x20, 0x16, + 0xc, 0x0, 0x0, 0x0, 0x8, 0x14, 0x1a, 0x12, + 0x8, 0x0, 0x0, 0x0, 0xc, 0x16, 0x20, 0x18, + 0xc, 0x2, 0x0, 0x6, 0x12, 0x1c, 0x20, 0x1a, + 0xe, 0x4, 0x0, 0x0, 0x0, 0x2, 0xe, 0x18, + 0x20, 0x1c, 0x12, 0x6, 0x0, 0xa, 0x14, 0x20, + 0x1e, 0x14, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x6, 0x12, 0x1c, 0x20, 0x16, 0xc, 0x0, 0x0, + 0xc, 0x16, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x18, 0xc, 0x2, 0x0, + 0x0, 0xd6, 0xb3, 0xff, 0xff, 0xff, 0xff, 0x99, + 0xae, 0x0, 0xa, 0x16, 0x20, 0x1a, 0xe, 0x4, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf0, + 0xe3, 0xff, 0xff, 0xff, 0xff, 0x5b, 0x6a, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0x16, 0x1a, + 0x10, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x52, 0x11, 0x23, 0x23, 0x23, 0x23, 0x23, + 0x23, 0x1d, 0xfe, 0xfc, 0xd2, 0x6a, 0xc, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, + 0xc8, 0xfe, 0x35, 0x5d, 0x67, 0x51, 0x11, 0xf2, + 0x8a, 0x14, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x52, 0x11, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, + 0x1d, 0xfe, 0xfc, 0xd4, 0x6a, 0xa, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x28, 0xa8, 0xfc, + 0x21, 0x57, 0x69, 0x61, 0x3b, 0xfe, 0xd4, 0x4e, + 0x0, 0x0, 0x0, 0x0, 0x60, 0x13, 0x23, 0x23, + 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, + 0x23, 0x23, 0x23, 0x1b, 0x98, 0x0, 0x0, 0x7c, + 0x17, 0x23, 0x23, 0x1f, 0xbe, 0x0, 0x0, 0x0, + 0x0, 0x44, 0xf, 0x23, 0x23, 0x23, 0x5, 0x10, + 0x0, 0x92, 0x1f, 0x23, 0x23, 0x1d, 0xd2, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x6c, 0xf, 0x23, 0x23, + 0x23, 0xb, 0xe, 0x1c, 0xd, 0x23, 0x23, 0x23, + 0xfe, 0x1c, 0x0, 0x0, 0xd6, 0x1d, 0x23, 0x1b, + 0xbe, 0x0, 0x0, 0x26, 0x5, 0x23, 0x23, 0x23, + 0xb, 0x10, 0x0, 0x36, 0x17, 0x23, 0x23, 0x23, + 0x11, 0x8c, 0x0, 0x0, 0x0, 0x76, 0xd, 0x23, + 0x23, 0x23, 0x19, 0x4c, 0x0, 0x86, 0x21, 0x23, + 0x23, 0x1f, 0xf0, 0x14, 0x0, 0x0, 0x0, 0x4, + 0xcc, 0x19, 0x23, 0x23, 0x23, 0x7, 0x0, 0xe, + 0x5, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, + 0x23, 0x23, 0x23, 0x23, 0x23, 0xb, 0x24, 0x0, + 0x0, 0xdc, 0xb3, 0xff, 0xff, 0xf7, 0xcb, 0x79, + 0x8a, 0x0, 0xa6, 0x21, 0x23, 0x23, 0x11, 0x82, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xdc, + 0xb3, 0xd5, 0xff, 0xff, 0xff, 0x5b, 0x70, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x28, 0xfe, 0x21, 0x23, + 0x15, 0x9e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x88, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xfd, 0xdd, 0x9b, 0x25, 0xd4, 0x20, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7a, 0xfe, + 0x75, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xb5, + 0x35, 0xde, 0x2a, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x88, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xfd, 0xdd, 0x9b, 0x21, 0xce, 0x16, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x4a, 0xfa, 0x55, 0xcb, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xe5, 0x85, 0x5, + 0x8c, 0x2, 0x0, 0x0, 0x9a, 0x95, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xc7, 0xd4, 0x0, 0x0, 0xba, + 0xb1, 0xff, 0xff, 0xe3, 0xee, 0x0, 0x0, 0x0, + 0x0, 0x76, 0x77, 0xff, 0xff, 0xff, 0x2f, 0x20, + 0x0, 0xae, 0xc3, 0xff, 0xff, 0xef, 0x5, 0x26, + 0x0, 0x0, 0x0, 0x0, 0xd4, 0xa1, 0xff, 0xff, + 0xfd, 0x29, 0xe, 0x1c, 0x41, 0xff, 0xff, 0xff, + 0x41, 0x54, 0x0, 0x20, 0x5, 0xf1, 0xff, 0xe3, + 0xfe, 0x12, 0x0, 0x66, 0x51, 0xff, 0xff, 0xff, + 0x2b, 0x10, 0x0, 0x36, 0x63, 0xff, 0xff, 0xff, + 0xbf, 0xfc, 0x24, 0x0, 0x18, 0xf8, 0xad, 0xff, + 0xff, 0xff, 0x7b, 0x4c, 0x0, 0x90, 0xb7, 0xff, + 0xff, 0xfb, 0x35, 0x7e, 0x0, 0x0, 0x0, 0x4c, + 0xf, 0xeb, 0xff, 0xff, 0xdb, 0x7, 0x0, 0x1c, + 0x29, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x4d, 0x3c, 0x0, + 0x0, 0xdc, 0xb3, 0xff, 0xff, 0xdf, 0xfe, 0xb4, + 0x44, 0x0, 0xbe, 0xd1, 0xff, 0xff, 0xb7, 0xf2, + 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7c, + 0xdc, 0x4d, 0xff, 0xff, 0xff, 0x5b, 0x70, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x96, 0x55, 0xff, 0xff, + 0xcd, 0xfc, 0x1a, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xac, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xeb, 0x49, 0xce, + 0x6, 0x0, 0x0, 0x0, 0x0, 0x60, 0x5, 0xb1, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xf1, 0x57, 0xde, 0x14, 0x0, 0x0, 0x0, 0x0, + 0xac, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xe9, 0x37, 0x9e, 0x0, + 0x0, 0x0, 0x0, 0x1a, 0xf4, 0x7f, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, + 0xd, 0x5e, 0x0, 0x0, 0xac, 0x95, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xc7, 0xe0, 0x0, 0x0, 0xda, + 0xb1, 0xff, 0xff, 0xe3, 0xfa, 0x0, 0x0, 0x0, + 0x0, 0x98, 0x77, 0xff, 0xff, 0xff, 0x2f, 0x2e, + 0x0, 0xae, 0x77, 0xff, 0xff, 0xff, 0x53, 0x7c, + 0x0, 0x0, 0x0, 0x16, 0xfe, 0xdf, 0xff, 0xff, + 0xc9, 0xfc, 0xe, 0x1a, 0xfe, 0xf3, 0xff, 0xff, + 0x75, 0x9a, 0x0, 0x6a, 0x49, 0xff, 0xff, 0xff, + 0x31, 0x52, 0x0, 0xac, 0x81, 0xff, 0xff, 0xe7, + 0xfe, 0xe, 0x0, 0x32, 0xfe, 0xbf, 0xff, 0xff, + 0xff, 0x4f, 0xa4, 0x0, 0x8e, 0x3b, 0xfb, 0xff, + 0xff, 0xd3, 0xfe, 0x46, 0x0, 0x8c, 0x39, 0xfb, + 0xff, 0xff, 0xab, 0xf2, 0xe, 0x0, 0x0, 0xd0, + 0x81, 0xff, 0xff, 0xff, 0x67, 0xc0, 0x0, 0x22, + 0x29, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x41, 0x3a, 0x0, + 0x0, 0xdc, 0xb3, 0xff, 0xff, 0xdf, 0xfa, 0x0, + 0x0, 0x0, 0xbe, 0x7d, 0xff, 0xff, 0xf7, 0x1f, + 0x52, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5c, 0x4d, 0xff, 0xff, 0xff, 0x5b, 0x70, 0x0, + 0x0, 0x0, 0x0, 0xc, 0xf6, 0xb7, 0xff, 0xff, + 0xff, 0x41, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xac, 0x87, 0xff, 0xff, 0xff, 0xad, 0xad, + 0xad, 0xb3, 0xd5, 0xff, 0xff, 0xff, 0xe9, 0x17, + 0x50, 0x0, 0x0, 0x0, 0x12, 0xf4, 0x97, 0xff, + 0xff, 0xff, 0xd9, 0x91, 0x83, 0xad, 0xf9, 0xff, + 0xff, 0xf1, 0x35, 0x8e, 0x0, 0x0, 0x0, 0x0, + 0xac, 0x87, 0xff, 0xff, 0xff, 0xad, 0xad, 0xad, + 0xb9, 0xe5, 0xff, 0xff, 0xff, 0xc7, 0xfc, 0xc, + 0x0, 0x0, 0x0, 0x70, 0x3f, 0xfb, 0xff, 0xff, + 0xef, 0x99, 0x75, 0x87, 0xd5, 0xff, 0xff, 0xff, + 0x95, 0xde, 0x0, 0x0, 0x7e, 0x65, 0xad, 0xad, + 0xad, 0xad, 0xb7, 0xff, 0xff, 0xff, 0xc7, 0xad, + 0xad, 0xad, 0xad, 0x87, 0xb6, 0x0, 0x0, 0xda, + 0xb1, 0xff, 0xff, 0xe3, 0xfa, 0x0, 0x0, 0x0, + 0x0, 0x98, 0x77, 0xff, 0xff, 0xff, 0x2f, 0x2e, + 0x0, 0x48, 0x1b, 0xf9, 0xff, 0xff, 0x9b, 0xd4, + 0x0, 0x0, 0x0, 0x62, 0x39, 0xff, 0xff, 0xff, + 0x7f, 0xb8, 0x0, 0x0, 0xf6, 0xc9, 0xff, 0xff, + 0xa1, 0xd0, 0x0, 0xbe, 0x8b, 0xff, 0xff, 0xff, + 0x79, 0xa6, 0x0, 0xdc, 0xad, 0xff, 0xff, 0xbd, + 0xec, 0x0, 0x0, 0x0, 0x92, 0x33, 0xf7, 0xff, + 0xff, 0xc9, 0xfe, 0x46, 0xfc, 0xb9, 0xff, 0xff, + 0xfd, 0x4b, 0xb0, 0x0, 0x0, 0x16, 0xf6, 0xab, + 0xff, 0xff, 0xf9, 0x29, 0x70, 0x0, 0x40, 0x9, + 0xe3, 0xff, 0xff, 0xd1, 0xfe, 0x36, 0x0, 0x16, + 0x1b, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, + 0xb7, 0xff, 0xff, 0xff, 0xb9, 0xfe, 0x1a, 0x0, + 0x0, 0xdc, 0xb3, 0xff, 0xff, 0xdf, 0xfa, 0x0, + 0x0, 0x0, 0x4c, 0x19, 0xf5, 0xff, 0xff, 0x83, + 0xc4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5c, 0x4d, 0xff, 0xff, 0xff, 0x5b, 0x70, 0x0, + 0x0, 0x0, 0x0, 0x60, 0x27, 0xf9, 0xff, 0xff, + 0xff, 0xa7, 0xec, 0x6, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xac, 0x87, 0xff, 0xff, 0xff, 0xd, 0xd8, + 0xd8, 0xe6, 0xfe, 0x87, 0xff, 0xff, 0xff, 0x81, + 0xa8, 0x0, 0x0, 0x0, 0x68, 0x31, 0xfb, 0xff, + 0xff, 0xc1, 0x9, 0xda, 0xc0, 0xf8, 0x51, 0xf9, + 0xff, 0xff, 0xb9, 0xf8, 0x8, 0x0, 0x0, 0x0, + 0xac, 0x87, 0xff, 0xff, 0xff, 0xd, 0xd8, 0xda, + 0xee, 0xd, 0xc3, 0xff, 0xff, 0xff, 0x25, 0x2e, + 0x0, 0x0, 0x0, 0xb2, 0x97, 0xff, 0xff, 0xfb, + 0x3d, 0xea, 0xae, 0xd0, 0x5, 0xcf, 0xff, 0xff, + 0xeb, 0x5, 0xc, 0x0, 0x34, 0x92, 0xc4, 0xd6, + 0xd6, 0xe0, 0x35, 0xff, 0xff, 0xff, 0x6f, 0xec, + 0xd6, 0xd6, 0xcc, 0xa0, 0x50, 0x0, 0x0, 0xda, + 0xb1, 0xff, 0xff, 0xe3, 0xfa, 0x0, 0x0, 0x0, + 0x0, 0x98, 0x77, 0xff, 0xff, 0xff, 0x2f, 0x2e, + 0x0, 0x8, 0xf6, 0xbf, 0xff, 0xff, 0xd9, 0xfe, + 0x10, 0x0, 0x0, 0xbe, 0x89, 0xff, 0xff, 0xfb, + 0x23, 0x50, 0x0, 0x0, 0xce, 0x9d, 0xff, 0xff, + 0xc7, 0xf2, 0x0, 0xf2, 0xc3, 0xff, 0xff, 0xff, + 0xb3, 0xe8, 0x0, 0xf8, 0xd3, 0xff, 0xff, 0x8d, + 0xbc, 0x0, 0x0, 0x0, 0x14, 0xee, 0x93, 0xff, + 0xff, 0xff, 0x59, 0xe2, 0x47, 0xff, 0xff, 0xff, + 0xab, 0xfa, 0x22, 0x0, 0x0, 0x0, 0x7c, 0x2d, + 0xf7, 0xff, 0xff, 0x9f, 0xec, 0x8, 0xc4, 0x75, + 0xff, 0xff, 0xff, 0x59, 0xb2, 0x0, 0x0, 0x8, + 0x7a, 0xb6, 0xd6, 0xd6, 0xd6, 0xd6, 0xde, 0xfe, + 0xad, 0xff, 0xff, 0xf1, 0x29, 0x8a, 0x0, 0x0, + 0x0, 0xdc, 0xb3, 0xff, 0xff, 0xdf, 0xfa, 0x0, + 0x0, 0x0, 0x6, 0xf0, 0xb1, 0xff, 0xff, 0xd5, + 0xfe, 0x1c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5c, 0x4d, 0xff, 0xff, 0xff, 0x5b, 0x70, 0x0, + 0x0, 0x0, 0x0, 0xd8, 0x91, 0xff, 0xff, 0xd5, + 0xff, 0xf3, 0x17, 0x4e, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xac, 0x87, 0xff, 0xff, 0xff, 0xd, 0x6, + 0x0, 0x0, 0x50, 0xfe, 0xe5, 0xff, 0xff, 0xb5, + 0xd6, 0x0, 0x0, 0x0, 0xbe, 0x93, 0xff, 0xff, + 0xfb, 0x37, 0x96, 0x0, 0x0, 0x26, 0xf6, 0xa9, + 0xff, 0xff, 0xfd, 0x1f, 0x3a, 0x0, 0x0, 0x0, + 0xac, 0x87, 0xff, 0xff, 0xff, 0xd, 0x6, 0x0, + 0x2, 0xb6, 0x63, 0xff, 0xff, 0xff, 0x4f, 0x44, + 0x0, 0x0, 0x0, 0xc8, 0xad, 0xff, 0xff, 0xe7, + 0xfe, 0x46, 0x0, 0x0, 0xb8, 0x7b, 0xf5, 0xf5, + 0xf5, 0x27, 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x36, 0x35, 0xff, 0xff, 0xff, 0x6f, 0x8c, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xda, + 0xb1, 0xff, 0xff, 0xe3, 0xfa, 0x0, 0x0, 0x0, + 0x0, 0x98, 0x77, 0xff, 0xff, 0xff, 0x2f, 0x2e, + 0x0, 0x0, 0xa8, 0x71, 0xff, 0xff, 0xff, 0x2f, + 0x56, 0x0, 0x6, 0xf8, 0xc9, 0xff, 0xff, 0xc5, + 0xfa, 0xc, 0x0, 0x0, 0x8c, 0x69, 0xff, 0xff, + 0xeb, 0xfe, 0x30, 0x5, 0xf3, 0xff, 0xff, 0xff, + 0xe7, 0xfe, 0x2c, 0x5, 0xf5, 0xff, 0xff, 0x57, + 0x76, 0x0, 0x0, 0x0, 0x0, 0x5e, 0xf, 0xe3, + 0xff, 0xff, 0xd1, 0xfe, 0xc3, 0xff, 0xff, 0xef, + 0x21, 0x7a, 0x0, 0x0, 0x0, 0x0, 0x10, 0xf0, + 0x9d, 0xff, 0xff, 0xf3, 0x1f, 0x82, 0xfe, 0xdb, + 0xff, 0xff, 0xc5, 0xfe, 0x2a, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0xc4, 0x57, + 0xff, 0xff, 0xff, 0x7b, 0xe2, 0xe, 0x0, 0x0, + 0x0, 0xdc, 0xb3, 0xff, 0xff, 0xdf, 0xfa, 0x0, + 0x0, 0x0, 0x0, 0x90, 0x55, 0xff, 0xff, 0xff, + 0x43, 0x7e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5c, 0x4d, 0xff, 0xff, 0xff, 0x5b, 0x70, 0x0, + 0x0, 0x0, 0x34, 0x5, 0xe5, 0xff, 0xd5, 0x65, + 0xff, 0xff, 0x81, 0xc6, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xac, 0x87, 0xff, 0xff, 0xff, 0xd, 0x6, + 0x0, 0x0, 0x4, 0xfa, 0xcf, 0xff, 0xff, 0xc1, + 0xe0, 0x0, 0x0, 0x0, 0xe8, 0xc5, 0xff, 0xff, + 0xd3, 0xfc, 0x16, 0x0, 0x0, 0x0, 0x8e, 0x53, + 0xff, 0xff, 0xff, 0x65, 0x72, 0x0, 0x0, 0x0, + 0xac, 0x87, 0xff, 0xff, 0xff, 0xd, 0x6, 0x0, + 0x0, 0xa2, 0x5b, 0xff, 0xff, 0xff, 0x41, 0x3e, + 0x0, 0x0, 0x0, 0xb2, 0x97, 0xff, 0xff, 0xff, + 0x63, 0xfc, 0x9a, 0x2e, 0x44, 0xe6, 0xfc, 0xfe, + 0xfa, 0xde, 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x36, 0x35, 0xff, 0xff, 0xff, 0x6f, 0x8c, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xda, + 0xb1, 0xff, 0xff, 0xe3, 0xfa, 0x0, 0x0, 0x0, + 0x0, 0x98, 0x77, 0xff, 0xff, 0xff, 0x2f, 0x2e, + 0x0, 0x0, 0x42, 0x15, 0xf7, 0xff, 0xff, 0x81, + 0xb4, 0x0, 0x40, 0x19, 0xf9, 0xff, 0xff, 0x7b, + 0xb2, 0x0, 0x0, 0x0, 0x42, 0x29, 0xff, 0xff, + 0xff, 0x29, 0x90, 0x4d, 0xff, 0xff, 0xfb, 0xff, + 0xff, 0x37, 0x8c, 0x3d, 0xff, 0xff, 0xfb, 0x15, + 0x2e, 0x0, 0x0, 0x0, 0x0, 0x4, 0xca, 0x63, + 0xff, 0xff, 0xff, 0x9b, 0xff, 0xff, 0xff, 0x7d, + 0xe0, 0xa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6c, + 0x21, 0xf1, 0xff, 0xff, 0x93, 0xf6, 0x67, 0xff, + 0xff, 0xff, 0x49, 0xa0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x66, 0x11, 0xe1, + 0xff, 0xff, 0xc9, 0xfe, 0x44, 0x0, 0x0, 0x0, + 0x0, 0xdc, 0xb3, 0xff, 0xff, 0xdf, 0xfa, 0x0, + 0x0, 0x0, 0x0, 0x28, 0xfe, 0xdf, 0xff, 0xff, + 0xa5, 0xe8, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5c, 0x4d, 0xff, 0xff, 0xff, 0x5b, 0x70, 0x0, + 0x0, 0x0, 0xa6, 0x65, 0xff, 0xff, 0x7f, 0x5, + 0xe7, 0xff, 0xd9, 0xfe, 0x26, 0x0, 0x0, 0x0, + 0x0, 0xac, 0x87, 0xff, 0xff, 0xff, 0xd, 0x6, + 0x0, 0x6, 0x82, 0x11, 0xef, 0xff, 0xff, 0xad, + 0xd0, 0x0, 0x0, 0x0, 0xf4, 0xd9, 0xff, 0xff, + 0xb7, 0xe6, 0x0, 0x0, 0x0, 0x0, 0x32, 0x27, + 0xff, 0xff, 0xff, 0x7d, 0x9a, 0x0, 0x0, 0x0, + 0xac, 0x87, 0xff, 0xff, 0xff, 0xd, 0xba, 0xbe, + 0xda, 0xfe, 0xab, 0xff, 0xff, 0xe7, 0xd, 0x1e, + 0x0, 0x0, 0x0, 0x6e, 0x3d, 0xfb, 0xff, 0xff, + 0xfd, 0xbb, 0x5d, 0x5, 0xe8, 0x88, 0x22, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x36, 0x35, 0xff, 0xff, 0xff, 0x6f, 0x8c, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xda, + 0xb1, 0xff, 0xff, 0xe3, 0xfa, 0x0, 0x0, 0x0, + 0x0, 0x98, 0x77, 0xff, 0xff, 0xff, 0x2f, 0x2e, + 0x0, 0x0, 0x6, 0xf4, 0xbb, 0xff, 0xff, 0xc3, + 0xf6, 0x4, 0x9c, 0x6d, 0xff, 0xff, 0xf9, 0x1f, + 0x4a, 0x0, 0x0, 0x0, 0xe, 0xfe, 0xe5, 0xff, + 0xff, 0x63, 0xde, 0x8f, 0xff, 0xff, 0xad, 0xff, + 0xff, 0x7f, 0xdc, 0x71, 0xff, 0xff, 0xd9, 0xfc, + 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x32, 0xfe, + 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xd3, 0x5, + 0x48, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, + 0xe6, 0x91, 0xff, 0xff, 0xef, 0x15, 0xd1, 0xff, + 0xff, 0xbb, 0xfc, 0x20, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x1e, 0xf6, 0x9b, 0xff, + 0xff, 0xf7, 0x39, 0xa0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xdc, 0xb3, 0xff, 0xff, 0xdf, 0xfa, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xd2, 0x8f, 0xff, 0xff, + 0xef, 0xd, 0x3e, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5c, 0x4d, 0xff, 0xff, 0xff, 0x5b, 0x70, 0x0, + 0x0, 0x14, 0xfc, 0xc3, 0xff, 0xf5, 0x1b, 0xe6, + 0x97, 0xff, 0xff, 0x53, 0x94, 0x0, 0x0, 0x0, + 0x0, 0xac, 0x87, 0xff, 0xff, 0xff, 0xd, 0xfa, + 0xfa, 0xfe, 0x19, 0xb3, 0xff, 0xff, 0xff, 0x6d, + 0x96, 0x0, 0x0, 0x0, 0xf8, 0xdf, 0xff, 0xff, + 0xad, 0xda, 0x0, 0x0, 0x0, 0x0, 0x10, 0xd, + 0xff, 0xff, 0xff, 0x87, 0xa8, 0x0, 0x0, 0x0, + 0xac, 0x87, 0xff, 0xff, 0xff, 0x93, 0x91, 0x91, + 0x9f, 0xcf, 0xff, 0xff, 0xf7, 0x5f, 0xce, 0x2, + 0x0, 0x0, 0x0, 0x1a, 0xf4, 0x7b, 0xfb, 0xff, + 0xff, 0xff, 0xff, 0xed, 0xad, 0x4b, 0xfe, 0x96, + 0x12, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x36, 0x35, 0xff, 0xff, 0xff, 0x6f, 0x8c, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xda, + 0xb1, 0xff, 0xff, 0xe3, 0xfa, 0x0, 0x0, 0x0, + 0x0, 0x98, 0x77, 0xff, 0xff, 0xff, 0x2f, 0x2e, + 0x0, 0x0, 0x0, 0xa2, 0x6d, 0xff, 0xff, 0xf7, + 0x11, 0x36, 0xea, 0xb1, 0xff, 0xff, 0xc1, 0xf8, + 0x8, 0x0, 0x0, 0x0, 0x0, 0xec, 0xbb, 0xff, + 0xff, 0x91, 0xfc, 0xc5, 0xff, 0xf9, 0x31, 0xff, + 0xff, 0xb7, 0xfa, 0x9d, 0xff, 0xff, 0xad, 0xde, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x94, + 0x35, 0xf7, 0xff, 0xff, 0xff, 0xfd, 0x4d, 0xb2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5c, 0x15, 0xeb, 0xff, 0xff, 0xb9, 0xff, 0xff, + 0xfb, 0x3d, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xb2, 0x47, 0xfb, 0xff, + 0xff, 0x8d, 0xee, 0x16, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xdc, 0xb3, 0xff, 0xff, 0xdf, 0xfa, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x60, 0x2b, 0xfb, 0xff, + 0xff, 0x6f, 0xac, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5c, 0x4d, 0xff, 0xff, 0xff, 0x5b, 0x70, 0x0, + 0x0, 0x32, 0x35, 0xfd, 0xff, 0xaf, 0xf0, 0x6e, + 0x31, 0xfd, 0xff, 0xb7, 0xb6, 0x0, 0x0, 0x0, + 0x0, 0xac, 0x87, 0xff, 0xff, 0xff, 0xdf, 0xdf, + 0xdf, 0xe5, 0xfb, 0xff, 0xff, 0xff, 0xd1, 0x5, + 0x3a, 0x0, 0x0, 0x0, 0xfa, 0xdf, 0xff, 0xff, + 0xad, 0xd6, 0x0, 0x0, 0x0, 0x0, 0x6, 0xd, + 0xff, 0xff, 0xff, 0x87, 0xac, 0x0, 0x0, 0x0, + 0xac, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xd1, 0x3d, 0xf4, 0x32, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x46, 0xf4, 0x49, 0xc7, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x31, + 0xd4, 0x16, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x36, 0x35, 0xff, 0xff, 0xff, 0x6f, 0x8c, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xda, + 0xb1, 0xff, 0xff, 0xe3, 0xfa, 0x0, 0x0, 0x0, + 0x0, 0x98, 0x77, 0xff, 0xff, 0xff, 0x2f, 0x2e, + 0x0, 0x0, 0x0, 0x3c, 0x11, 0xf3, 0xff, 0xff, + 0x63, 0xa0, 0xfe, 0xed, 0xff, 0xff, 0x75, 0xac, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xba, 0x8b, 0xff, + 0xff, 0xb9, 0x9, 0xf3, 0xff, 0xcb, 0xfe, 0xdb, + 0xff, 0xeb, 0xfe, 0xc5, 0xff, 0xff, 0x7b, 0xa6, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x36, + 0xfe, 0xc3, 0xff, 0xff, 0xff, 0xd9, 0xfe, 0x58, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x6, 0xda, 0x83, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xad, 0xf8, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x54, 0x9, 0xd5, 0xff, 0xff, + 0xd9, 0x9, 0x56, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xdc, 0xb3, 0xff, 0xff, 0xdf, 0xfa, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xe, 0xfa, 0xc1, 0xff, + 0xff, 0xc5, 0xfa, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x5c, 0x4d, 0xff, 0xff, 0xff, 0x5b, 0x70, 0x0, + 0x0, 0x32, 0x4b, 0x91, 0x91, 0x3d, 0x86, 0x12, + 0xf6, 0x7b, 0x91, 0x89, 0xa8, 0x0, 0x0, 0x0, + 0x0, 0xac, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xcb, 0x25, 0xa6, + 0x0, 0x0, 0x0, 0x0, 0xf8, 0xdf, 0xff, 0xff, + 0xad, 0xda, 0x0, 0x0, 0x0, 0x0, 0x12, 0xd, + 0xff, 0xff, 0xff, 0x87, 0xa6, 0x0, 0x0, 0x0, + 0xac, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xb9, 0xf, 0x6e, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0xa2, 0xfc, + 0x41, 0x9d, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xed, + 0x39, 0x9a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x36, 0x35, 0xff, 0xff, 0xff, 0x6f, 0x8c, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xda, + 0xb1, 0xff, 0xff, 0xe3, 0xfa, 0x0, 0x0, 0x0, + 0x0, 0x98, 0x77, 0xff, 0xff, 0xff, 0x2f, 0x2e, + 0x0, 0x0, 0x0, 0x4, 0xf0, 0xb5, 0xff, 0xff, + 0xa9, 0xf0, 0x4f, 0xff, 0xff, 0xf7, 0x19, 0x46, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x72, 0x55, 0xff, + 0xff, 0xdf, 0x51, 0xff, 0xff, 0x95, 0xf8, 0xa7, + 0xff, 0xff, 0x3d, 0xeb, 0xff, 0xff, 0x43, 0x5a, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xba, + 0x53, 0xff, 0xff, 0xff, 0xff, 0xff, 0x73, 0xda, + 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4e, 0xb, 0xe3, 0xff, 0xff, 0xff, 0xf9, + 0x2f, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x16, 0xee, 0x8b, 0xff, 0xff, 0xfb, + 0x4b, 0xb8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xdc, 0xb3, 0xff, 0xff, 0xdf, 0xfa, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xa6, 0x6b, 0xff, + 0xff, 0xfd, 0x2f, 0x66, 0x0, 0x0, 0x0, 0x0, + 0x5c, 0x4d, 0xff, 0xff, 0xff, 0x5b, 0x70, 0x0, + 0x0, 0x20, 0x6e, 0xa0, 0x9e, 0x6a, 0x1a, 0x0, + 0x46, 0x86, 0xac, 0x8e, 0x52, 0x0, 0x0, 0x0, + 0x0, 0xac, 0x87, 0xff, 0xff, 0xff, 0xdd, 0xdd, + 0xdd, 0xdb, 0xcf, 0xab, 0x5f, 0xfe, 0x9e, 0xc, + 0x0, 0x0, 0x0, 0x0, 0xf4, 0xd9, 0xff, 0xff, + 0xbb, 0xe8, 0x0, 0x0, 0x0, 0x0, 0x36, 0x2b, + 0xff, 0xff, 0xff, 0x7b, 0x96, 0x0, 0x0, 0x0, + 0xac, 0x87, 0xff, 0xff, 0xff, 0x4d, 0x49, 0x49, + 0x5b, 0xa5, 0xff, 0xff, 0xff, 0xa3, 0xe4, 0x0, + 0x0, 0x0, 0x6, 0x3a, 0x62, 0x80, 0x6a, 0x56, + 0x7e, 0xd8, 0xfe, 0x47, 0xb7, 0xff, 0xff, 0xff, + 0xc3, 0xf8, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x36, 0x35, 0xff, 0xff, 0xff, 0x6f, 0x8c, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd8, + 0xb1, 0xff, 0xff, 0xe3, 0xfc, 0x0, 0x0, 0x0, + 0x0, 0x9c, 0x77, 0xff, 0xff, 0xff, 0x2f, 0x2a, + 0x0, 0x0, 0x0, 0x0, 0x9a, 0x67, 0xff, 0xff, + 0xe5, 0xfe, 0x9b, 0xff, 0xff, 0xbd, 0xf6, 0x6, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x2c, 0x13, 0xfb, + 0xff, 0xfb, 0x97, 0xff, 0xff, 0x55, 0xc4, 0x6b, + 0xff, 0xff, 0x93, 0xff, 0xff, 0xf3, 0x5, 0x1c, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x50, 0x9, + 0xd9, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xeb, 0x1f, + 0x78, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2, 0xd2, 0x75, 0xff, 0xff, 0xff, 0xa1, + 0xf4, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x9e, 0x37, 0xf7, 0xff, 0xff, 0xa1, + 0xf8, 0x22, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xdc, 0xb3, 0xff, 0xff, 0xdf, 0xfa, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x38, 0xb, 0xed, + 0xff, 0xff, 0x93, 0xd6, 0x0, 0x0, 0x0, 0x0, + 0x5c, 0x4d, 0xff, 0xff, 0xff, 0x5b, 0x70, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xac, 0x87, 0xff, 0xff, 0xff, 0xd, 0xf8, + 0xf8, 0xf6, 0xee, 0xd4, 0x8e, 0x30, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xe8, 0xc3, 0xff, 0xff, + 0xd5, 0xfe, 0x1a, 0x0, 0x0, 0x0, 0x92, 0x55, + 0xff, 0xff, 0xff, 0x5f, 0x6a, 0x0, 0x0, 0x0, + 0xac, 0x87, 0xff, 0xff, 0xff, 0xd, 0x58, 0x5e, + 0x94, 0xfe, 0xb7, 0xff, 0xff, 0xef, 0xfe, 0x6, + 0x0, 0x0, 0xe, 0x15, 0x67, 0x67, 0x67, 0x2d, + 0x5e, 0x0, 0x1e, 0x90, 0xfe, 0xb3, 0xff, 0xff, + 0xfb, 0x13, 0x16, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x36, 0x35, 0xff, 0xff, 0xff, 0x6f, 0x8c, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd0, + 0xab, 0xff, 0xff, 0xeb, 0xfe, 0x8, 0x0, 0x0, + 0x0, 0xb2, 0x81, 0xff, 0xff, 0xff, 0x25, 0x1c, + 0x0, 0x0, 0x0, 0x0, 0x36, 0xd, 0xf1, 0xff, + 0xff, 0x41, 0xd9, 0xff, 0xff, 0x71, 0xa6, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0xfc, 0xd9, + 0xff, 0xff, 0xeb, 0xff, 0xf5, 0xb, 0x5c, 0x1f, + 0xfd, 0xff, 0xeb, 0xff, 0xff, 0xcb, 0xf6, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, 0xe6, 0x87, + 0xff, 0xff, 0xff, 0x75, 0xf9, 0xff, 0xff, 0xab, + 0xfa, 0x26, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x68, 0x43, 0xff, 0xff, 0xff, 0x63, + 0x9e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x44, 0xfe, 0xc7, 0xff, 0xff, 0xe3, 0x15, + 0x6c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xdc, 0xb3, 0xff, 0xff, 0xdf, 0xfa, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0xe4, 0xa1, + 0xff, 0xff, 0xe3, 0xfe, 0x2c, 0x0, 0x0, 0x0, + 0x5c, 0x4d, 0xff, 0xff, 0xff, 0x5b, 0x70, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xac, 0x87, 0xff, 0xff, 0xff, 0xd, 0x6, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xba, 0x8f, 0xff, 0xff, + 0xfd, 0x3f, 0xa2, 0x4, 0x0, 0x2a, 0xf8, 0xad, + 0xff, 0xff, 0xf7, 0x15, 0x34, 0x0, 0x0, 0x0, + 0xac, 0x87, 0xff, 0xff, 0xff, 0xd, 0x6, 0x0, + 0x0, 0xbc, 0x81, 0xff, 0xff, 0xff, 0x19, 0x14, + 0x0, 0x0, 0xe, 0x1d, 0xff, 0xff, 0xff, 0x8b, + 0xd0, 0x6, 0x0, 0x0, 0xcc, 0x77, 0xff, 0xff, + 0xff, 0x31, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x36, 0x35, 0xff, 0xff, 0xff, 0x6f, 0x8c, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb6, + 0x97, 0xff, 0xff, 0xff, 0x1d, 0x74, 0x0, 0x0, + 0x16, 0xf2, 0xa5, 0xff, 0xff, 0xf9, 0x5, 0xc, + 0x0, 0x0, 0x0, 0x0, 0x2, 0xee, 0xb1, 0xff, + 0xff, 0x9f, 0xff, 0xff, 0xf7, 0x15, 0x40, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xde, 0xad, + 0xff, 0xff, 0xff, 0xff, 0xc5, 0xf6, 0xa, 0xfc, + 0xd5, 0xff, 0xff, 0xff, 0xff, 0x9d, 0xce, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x84, 0x29, 0xf3, + 0xff, 0xff, 0xc3, 0xfe, 0xa5, 0xff, 0xff, 0xfd, + 0x51, 0xba, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x4c, 0x43, 0xff, 0xff, 0xff, 0x63, + 0x7a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xe, 0xe2, 0x79, 0xff, 0xff, 0xff, 0x5d, 0xca, + 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xdc, 0xb3, 0xff, 0xff, 0xdf, 0xfa, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x78, 0x41, + 0xff, 0xff, 0xff, 0x5b, 0x96, 0x0, 0x0, 0x0, + 0x5c, 0x4d, 0xff, 0xff, 0xff, 0x5b, 0x70, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xac, 0x87, 0xff, 0xff, 0xff, 0xd, 0x6, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x62, 0x2d, 0xf9, 0xff, + 0xff, 0xc9, 0x11, 0xe6, 0xce, 0xfa, 0x57, 0xfb, + 0xff, 0xff, 0xad, 0xf2, 0x6, 0x0, 0x0, 0x0, + 0xac, 0x87, 0xff, 0xff, 0xff, 0xd, 0x6, 0x0, + 0x0, 0x94, 0x73, 0xff, 0xff, 0xff, 0x29, 0x2a, + 0x0, 0x0, 0x8, 0xfe, 0xdf, 0xff, 0xff, 0xdd, + 0x15, 0xe8, 0xb4, 0xc8, 0xfe, 0xb1, 0xff, 0xff, + 0xfb, 0x11, 0x14, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x36, 0x35, 0xff, 0xff, 0xff, 0x6f, 0x8c, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7a, + 0x59, 0xff, 0xff, 0xff, 0xa7, 0xfe, 0xd8, 0xc4, + 0xf4, 0x37, 0xf5, 0xff, 0xff, 0xcb, 0xf8, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x94, 0x5f, 0xff, + 0xff, 0xf3, 0xff, 0xff, 0xb9, 0xf4, 0x6, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa4, 0x7b, + 0xff, 0xff, 0xff, 0xff, 0x8d, 0xbe, 0x0, 0xd4, + 0x9f, 0xff, 0xff, 0xff, 0xff, 0x6b, 0x8e, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x2a, 0xfc, 0xb3, 0xff, + 0xff, 0xfd, 0x47, 0xca, 0x27, 0xf5, 0xff, 0xff, + 0xd9, 0x9, 0x54, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x4c, 0x43, 0xff, 0xff, 0xff, 0x63, + 0x7a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x8a, 0x27, 0xf1, 0xff, 0xff, 0xb3, 0xfe, 0xe4, + 0xe0, 0xe0, 0xe0, 0xe0, 0xcc, 0x98, 0x2e, 0x0, + 0x0, 0xdc, 0xb3, 0xff, 0xff, 0xdf, 0xfa, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1a, 0xfe, + 0xd1, 0xff, 0xff, 0xb5, 0xf4, 0x8, 0x0, 0x0, + 0x5c, 0x4d, 0xff, 0xff, 0xff, 0x5b, 0x70, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xac, 0x87, 0xff, 0xff, 0xff, 0xd, 0x6, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x10, 0xee, 0x8f, 0xff, + 0xff, 0xff, 0xe3, 0x9f, 0x91, 0xb7, 0xfb, 0xff, + 0xff, 0xeb, 0x27, 0x7e, 0x0, 0x0, 0x0, 0x0, + 0xac, 0x87, 0xff, 0xff, 0xff, 0xd, 0x6, 0x0, + 0x0, 0x7e, 0x69, 0xff, 0xff, 0xff, 0x39, 0x52, + 0x0, 0x0, 0x0, 0xc8, 0x75, 0xff, 0xff, 0xff, + 0xe9, 0x9f, 0x81, 0x89, 0xc3, 0xff, 0xff, 0xff, + 0xbf, 0xf8, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x36, 0x35, 0xff, 0xff, 0xff, 0x6f, 0x8c, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2a, + 0xfe, 0xd1, 0xff, 0xff, 0xff, 0xd1, 0x97, 0x89, + 0xab, 0xf7, 0xff, 0xff, 0xff, 0x5f, 0xac, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x30, 0x9, 0xef, + 0xff, 0xff, 0xff, 0xff, 0x6b, 0xa0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x58, 0x41, + 0xff, 0xff, 0xff, 0xff, 0x49, 0x6a, 0x0, 0x86, + 0x61, 0xff, 0xff, 0xff, 0xff, 0x2b, 0x42, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xbc, 0x57, 0xff, 0xff, + 0xff, 0xb5, 0xfa, 0x2a, 0xec, 0x95, 0xff, 0xff, + 0xff, 0x8b, 0xec, 0x14, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x4c, 0x43, 0xff, 0xff, 0xff, 0x63, + 0x7a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, + 0xfe, 0xb9, 0xff, 0xff, 0xff, 0xc3, 0xb7, 0xb7, + 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0x5d, 0x6c, 0x0, + 0x0, 0xdc, 0xb3, 0xff, 0xff, 0xdf, 0xfa, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xbe, + 0x7d, 0xff, 0xff, 0xf7, 0x1d, 0x52, 0x0, 0x0, + 0x5c, 0x4d, 0xff, 0xff, 0xff, 0x5b, 0x70, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xac, 0x87, 0xff, 0xff, 0xff, 0xd, 0x6, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x58, 0xfe, 0xa7, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x4f, 0xf2, 0x20, 0x0, 0x0, 0x0, 0x0, + 0xac, 0x87, 0xff, 0xff, 0xff, 0xd, 0x6, 0x0, + 0x0, 0x58, 0x51, 0xff, 0xff, 0xff, 0x67, 0xba, + 0x0, 0x0, 0x0, 0x40, 0xfe, 0x91, 0xfd, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe5, + 0x31, 0x92, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x36, 0x35, 0xff, 0xff, 0xff, 0x6f, 0x8c, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xaa, 0x31, 0xe1, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xfd, 0x8b, 0xfe, 0x30, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xea, 0xad, + 0xff, 0xff, 0xff, 0xf3, 0x11, 0x3c, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1a, 0xfe, + 0xf3, 0xff, 0xff, 0xef, 0x5, 0x20, 0x0, 0x34, + 0x15, 0xf9, 0xff, 0xff, 0xe7, 0xfe, 0xe, 0x0, + 0x0, 0x0, 0x0, 0x52, 0x9, 0xdb, 0xff, 0xff, + 0xfb, 0x35, 0x8a, 0x0, 0x62, 0x19, 0xed, 0xff, + 0xff, 0xf7, 0x33, 0x94, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x4c, 0x43, 0xff, 0xff, 0xff, 0x63, + 0x7a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1e, + 0x29, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x83, 0x98, 0x0, + 0x0, 0xdc, 0xb3, 0xff, 0xff, 0xdf, 0xfa, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4e, + 0x19, 0xf5, 0xff, 0xff, 0x81, 0xc4, 0x0, 0x0, + 0x5c, 0x4d, 0xff, 0xff, 0xff, 0x5b, 0x70, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x86, 0x87, 0xff, 0xff, 0xff, 0xd, 0x4, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6e, 0xfe, + 0x69, 0xd3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xdb, 0x33, 0xd6, 0x22, 0x0, 0x0, 0x0, + 0x86, 0x87, 0xff, 0xff, 0xff, 0xd, 0x4, 0x0, + 0x0, 0x28, 0xf, 0xe9, 0xff, 0xff, 0xcf, 0xb4, + 0x0, 0x0, 0x0, 0x0, 0x5a, 0xf8, 0x49, 0xbb, + 0xf7, 0xff, 0xff, 0xff, 0xff, 0xed, 0xa1, 0x21, + 0xc6, 0x12, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x26, 0x35, 0xff, 0xff, 0xff, 0x6f, 0x68, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x12, 0xc0, 0x17, 0x97, 0xe7, 0xff, 0xff, 0xff, + 0xff, 0xf9, 0xc3, 0x55, 0xf8, 0x54, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8e, 0x5b, + 0xff, 0xff, 0xff, 0xb7, 0xee, 0x4, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf0, + 0xc9, 0xff, 0xff, 0xbf, 0xea, 0x0, 0x0, 0x6, + 0xf6, 0xcf, 0xff, 0xff, 0xbd, 0xe2, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x52, 0x89, 0xff, 0xff, 0xff, + 0xa7, 0xf4, 0x14, 0x0, 0x6, 0xde, 0x87, 0xff, + 0xff, 0xff, 0xc1, 0x94, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x36, 0x43, 0xff, 0xff, 0xff, 0x63, + 0x5a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1e, + 0x2f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x83, 0x82, 0x0, + 0x0, 0xdc, 0xb3, 0xff, 0xff, 0xdf, 0xfa, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, + 0xf2, 0xb1, 0xff, 0xff, 0xd5, 0xfe, 0x1c, 0x0, + 0x5c, 0x4d, 0xff, 0xff, 0xff, 0x5b, 0x70, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x50, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0x2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x36, + 0xb8, 0xfc, 0x23, 0x4d, 0x59, 0x3d, 0x63, 0xf5, + 0xff, 0xff, 0xeb, 0x4d, 0x50, 0x0, 0x0, 0x0, + 0x50, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0x2, 0x0, + 0x0, 0x4, 0xc8, 0xfe, 0xfe, 0xfe, 0xfe, 0xa0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x94, 0xf2, + 0x9, 0x43, 0x59, 0x55, 0x35, 0xfe, 0xe4, 0x70, + 0xa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x14, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0x3c, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x6, 0x64, 0xda, 0xfe, 0x31, 0x53, 0x59, + 0x47, 0xf, 0xf6, 0xa0, 0x28, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2c, 0xfe, + 0xfe, 0xfe, 0xfe, 0xfe, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x98, + 0xfe, 0xfe, 0xfe, 0xfe, 0x8a, 0x0, 0x0, 0x0, + 0x9e, 0xfe, 0xfe, 0xfe, 0xfe, 0x88, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x52, 0xfe, 0xfe, 0xfe, 0xfe, + 0xfe, 0x6e, 0x0, 0x0, 0x0, 0x50, 0xfe, 0xfe, + 0xfe, 0xfe, 0xfe, 0x8c, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x1c, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, + 0x32, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, + 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, + 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0x4c, 0x0, + 0x0, 0xdc, 0xb3, 0xff, 0xff, 0xdf, 0xfe, 0x96, + 0x36, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x90, 0x57, 0xff, 0xff, 0xff, 0x43, 0x3e, 0x64, + 0xca, 0x4d, 0xff, 0xff, 0xff, 0x5b, 0x70, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc, 0x2e, 0x50, 0x5a, 0x66, 0xea, 0x4b, + 0xed, 0xff, 0xf5, 0x67, 0x50, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1c, 0x42, 0x60, 0x5a, 0x3a, 0x14, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x12, 0x36, 0x58, 0x60, + 0x48, 0x22, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xdc, 0xb3, 0xff, 0xff, 0xf3, 0xb1, 0x69, + 0x82, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2a, 0xfe, 0x8d, 0x95, 0x95, 0x51, 0x3e, 0xd6, + 0x9b, 0xbf, 0xff, 0xff, 0xff, 0x5b, 0x70, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x22, 0xd8, + 0x35, 0xc9, 0x49, 0xe8, 0x34, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xda, 0xb3, 0xff, 0xff, 0xff, 0xff, 0x99, + 0xae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x56, 0x94, 0xbc, 0xa8, 0x76, 0x26, 0xf2, + 0xe3, 0xff, 0xff, 0xff, 0xff, 0x5b, 0x6e, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x14, + 0xa0, 0xac, 0xa4, 0x20, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb8, 0xab, 0xf5, 0xf5, 0xf5, 0xf5, 0x91, + 0x98, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xea, + 0xd9, 0xf5, 0xf5, 0xf5, 0xf5, 0x57, 0x4e, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x74, 0xec, 0xfc, 0xfe, 0xfe, 0xfc, 0xe8, + 0x5a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xac, + 0xf4, 0xfe, 0xfe, 0xfe, 0xfc, 0xe2, 0x2a, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x24, 0x52, 0x76, 0x76, 0x52, 0x26, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa, 0x3e, 0x66, 0x80, 0x66, 0x3e, 0xa, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x54, + 0x98, 0xba, 0xb2, 0x80, 0x34, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x28, 0x56, 0x78, 0x74, 0x50, 0x22, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1a, 0x4a, 0x70, 0x7e, 0x5c, 0x30, 0x0, + 0x0, 0x0, 0x1a, 0x4a, 0x70, 0x7e, 0x5c, 0x32, + 0x0, 0x0, 0x0, 0x24, 0x52, 0x76, 0x78, 0x54, + 0x26, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1a, 0x4a, 0x70, 0x7e, 0x5c, + 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x3c, + 0x6e, 0x90, 0x86, 0x5e, 0x2a, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xa0, 0x4f, 0x67, 0x67, 0x51, 0xa8, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x32, 0x21, 0x67, 0x67, 0x67, 0x21, 0x32, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x4e, 0xf2, 0x2d, + 0x7f, 0x9b, 0x99, 0x67, 0xaa, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb4, 0x55, 0x67, 0x67, 0x4d, 0x98, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x78, 0x41, 0x67, 0x67, 0x5f, 0xda, 0x0, + 0x0, 0x0, 0x74, 0x3f, 0x67, 0x67, 0x63, 0xe4, + 0x0, 0x0, 0x0, 0xa0, 0x4f, 0x67, 0x67, 0x51, + 0xac, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x78, 0x41, 0x67, 0x67, 0x5f, + 0xda, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x17, + 0x71, 0x73, 0x73, 0x57, 0xf0, 0x22, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xd4, 0xc3, 0xff, 0xff, 0xcb, 0xdc, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x54, 0x57, 0xff, 0xff, 0xff, 0x57, 0x54, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x28, 0xfc, 0x85, 0xfb, + 0xff, 0xff, 0xff, 0xc7, 0xd2, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xe4, 0xd3, 0xff, 0xff, 0xbd, 0xce, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xae, 0x9f, 0xff, 0xff, 0xef, 0xf8, 0x0, + 0x0, 0x0, 0xaa, 0x9b, 0xff, 0xff, 0xf5, 0xfa, + 0x0, 0x0, 0x0, 0xd4, 0xc3, 0xff, 0xff, 0xcd, + 0xde, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xae, 0x9f, 0xff, 0xff, 0xef, + 0xf8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x6c, + 0x77, 0xfb, 0xff, 0xfb, 0x4d, 0xc8, 0x8, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xea, 0xc3, 0xff, 0xff, 0xcb, 0xee, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x6a, 0x57, 0xff, 0xff, 0xff, 0x57, 0x6a, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x8e, 0x55, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xb1, 0xcc, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xf4, 0xd3, 0xff, 0xff, 0xbd, 0xe4, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xae, 0x9f, 0xff, 0xff, 0xef, 0xf8, 0x0, + 0x0, 0x0, 0xaa, 0x9b, 0xff, 0xff, 0xf5, 0xfc, + 0x0, 0x0, 0x0, 0xea, 0xc3, 0xff, 0xff, 0xcd, + 0xf0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xc8, 0x9f, 0xff, 0xff, 0xef, + 0xfe, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, + 0xf6, 0x6d, 0xfb, 0xff, 0xe3, 0x1d, 0x5e, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xea, 0xc3, 0xff, 0xff, 0xcb, 0xee, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x6a, 0x57, 0xff, 0xff, 0xff, 0x57, 0x6a, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xd2, 0xaf, 0xff, 0xff, + 0xfb, 0x7b, 0x45, 0x37, 0x86, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xf4, 0xd3, 0xff, 0xff, 0xbd, 0xe4, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x78, 0x41, 0x67, 0x67, 0x5f, 0xda, 0x0, + 0x0, 0x0, 0x74, 0x3d, 0x63, 0x63, 0x5d, 0xe4, + 0x0, 0x0, 0x0, 0xea, 0xc3, 0xff, 0xff, 0xcd, + 0xf0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xc8, 0x9f, 0xff, 0xff, 0xef, + 0xfe, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3a, 0xf2, 0x65, 0xd9, 0xd9, 0x95, 0x5e, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xea, 0xc3, 0xff, 0xff, 0xcb, 0xee, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x6a, 0x57, 0xff, 0xff, 0xff, 0x57, 0x6a, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xec, 0xcd, 0xff, 0xff, + 0xc9, 0xfe, 0x6a, 0x30, 0x16, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xf4, 0xd3, 0xff, 0xff, 0xbd, 0xe4, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1a, 0x4a, 0x70, 0x7e, 0x5c, 0x30, 0x0, + 0x0, 0x0, 0x18, 0x46, 0x6a, 0x78, 0x58, 0x2e, + 0x0, 0x0, 0x0, 0xea, 0xc3, 0xff, 0xff, 0xcd, + 0xf0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xc8, 0x9f, 0xff, 0xff, 0xef, + 0xfe, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x34, 0xbe, 0xea, 0xee, 0xca, 0x58, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x3c, 0xa6, 0xe8, 0xfa, + 0xfc, 0xf8, 0xe4, 0x98, 0x2a, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xea, 0xc3, 0xff, 0xff, 0xcb, 0xf8, + 0xea, 0xf8, 0xf8, 0xe2, 0x8e, 0x1c, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x22, 0x8e, 0xde, + 0xf8, 0xfc, 0xf8, 0xe4, 0x98, 0x2a, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x48, 0xbc, 0xf0, 0xfa, + 0xf4, 0xe2, 0x57, 0xff, 0xff, 0xff, 0x57, 0x6a, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x74, 0xd4, + 0xf6, 0xfa, 0xf8, 0xe6, 0x9e, 0x2e, 0x0, 0x0, + 0x0, 0x0, 0x56, 0xb6, 0xfe, 0xd3, 0xff, 0xff, + 0xbd, 0xfc, 0xd4, 0x9a, 0x18, 0x0, 0x0, 0x0, + 0x0, 0x46, 0xba, 0xf0, 0xfa, 0xf6, 0xd2, 0xa4, + 0xc0, 0xe2, 0xd4, 0x9e, 0x1e, 0x0, 0x0, 0x0, + 0xf4, 0xd3, 0xff, 0xff, 0xbd, 0xf2, 0xe0, 0xf8, + 0xf8, 0xea, 0xa2, 0x28, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x44, 0xae, 0xdc, 0xe6, 0xc8, 0x80, 0x0, + 0x0, 0x0, 0x38, 0xa8, 0xd8, 0xea, 0xce, 0x90, + 0x0, 0x0, 0x0, 0xea, 0xc3, 0xff, 0xff, 0xcd, + 0xf0, 0x0, 0x5c, 0xb8, 0xe0, 0xea, 0xd4, 0x9e, + 0x20, 0x0, 0x0, 0xc8, 0x9f, 0xff, 0xff, 0xef, + 0xfe, 0x0, 0x0, 0x0, 0x5e, 0xb8, 0xe0, 0xdc, + 0xb2, 0x9c, 0xda, 0xf6, 0xf8, 0xee, 0xae, 0x34, + 0x60, 0xce, 0xf4, 0xfa, 0xf2, 0xc0, 0x48, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x68, 0xbe, 0xe2, 0xda, + 0xae, 0x92, 0xd6, 0xf6, 0xfa, 0xf0, 0xb6, 0x3c, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x14, + 0x78, 0xd4, 0xf6, 0xfa, 0xfa, 0xec, 0xb0, 0x44, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x4, 0x8e, 0xfe, 0x6f, 0xbf, 0xe3, + 0xef, 0xe3, 0xb9, 0x57, 0xfc, 0x5c, 0x0, 0x0, + 0x0, 0x0, 0xea, 0xc3, 0xff, 0xff, 0xcb, 0x49, + 0xc3, 0xeb, 0xe5, 0xb7, 0x41, 0xea, 0x26, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x52, 0xfa, 0x4d, 0xb3, + 0xdf, 0xed, 0xe3, 0xb9, 0x57, 0xfc, 0x5c, 0x0, + 0x0, 0x0, 0x0, 0x7a, 0xfe, 0x7d, 0xd1, 0xeb, + 0xdd, 0x8f, 0x59, 0xff, 0xff, 0xff, 0x57, 0x6a, + 0x0, 0x0, 0x0, 0x0, 0x2a, 0xe2, 0x2f, 0xa3, + 0xdb, 0xed, 0xe3, 0xbd, 0x5d, 0xfe, 0x60, 0x0, + 0x0, 0x0, 0xae, 0x8d, 0xc3, 0xf3, 0xff, 0xff, + 0xeb, 0xc3, 0xc3, 0x3b, 0x38, 0x0, 0x0, 0x0, + 0x76, 0xfe, 0x7b, 0xcf, 0xeb, 0xdf, 0x97, 0xd, + 0xa5, 0xc3, 0xc3, 0x45, 0x44, 0x0, 0x0, 0x0, + 0xf4, 0xd3, 0xff, 0xff, 0xbd, 0x2d, 0xb1, 0xe5, + 0xe9, 0xc3, 0x55, 0xf2, 0x2e, 0x0, 0x0, 0x0, + 0x0, 0x90, 0x79, 0xc3, 0xc3, 0xb7, 0xe8, 0x0, + 0x0, 0x0, 0x78, 0x69, 0xc3, 0xc3, 0xc3, 0xfe, + 0x0, 0x0, 0x0, 0xea, 0xc3, 0xff, 0xff, 0xcd, + 0xf0, 0x24, 0xfa, 0x93, 0xc3, 0xc3, 0xc3, 0x53, + 0x20, 0x0, 0x0, 0xc8, 0x9f, 0xff, 0xff, 0xef, + 0xfe, 0x0, 0x0, 0x0, 0xb8, 0x95, 0xc3, 0xc3, + 0x79, 0x27, 0xa9, 0xe1, 0xeb, 0xcb, 0x61, 0xfc, + 0x11, 0x95, 0xdb, 0xed, 0xd5, 0x7d, 0xfe, 0x5c, + 0x0, 0x0, 0x0, 0x0, 0xc8, 0x9f, 0xc3, 0xc3, + 0x71, 0x1d, 0xa1, 0xdf, 0xeb, 0xcf, 0x71, 0xfe, + 0x4c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x38, 0xec, + 0x35, 0xa5, 0xd9, 0xeb, 0xe5, 0xc5, 0x79, 0x5, + 0x9e, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x62, 0x11, 0xc1, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x93, 0xfa, 0x22, 0x0, + 0x0, 0x0, 0xea, 0xc3, 0xff, 0xff, 0xe5, 0xf5, + 0xff, 0xff, 0xff, 0xff, 0xf7, 0x53, 0xc4, 0x2, + 0x0, 0x0, 0x0, 0x2c, 0xfa, 0x89, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x93, 0xfe, 0x2e, + 0x0, 0x0, 0x38, 0xfe, 0xb1, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xd9, 0xff, 0xff, 0xff, 0x57, 0x6a, + 0x0, 0x0, 0x0, 0xe, 0xdc, 0x57, 0xf3, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x97, 0xfc, 0x2e, + 0x0, 0x0, 0xca, 0xbb, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x4d, 0x4a, 0x0, 0x0, 0x36, + 0xfe, 0xad, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc1, + 0xf1, 0xff, 0xff, 0x5b, 0x66, 0x0, 0x0, 0x0, + 0xf4, 0xd3, 0xff, 0xff, 0xd1, 0xeb, 0xff, 0xff, + 0xff, 0xff, 0xfb, 0x5d, 0xbc, 0x0, 0x0, 0x0, + 0x0, 0xbc, 0x9f, 0xff, 0xff, 0xef, 0xfa, 0x0, + 0x0, 0x0, 0xa4, 0x89, 0xff, 0xff, 0xff, 0xfe, + 0x0, 0x0, 0x0, 0xea, 0xc3, 0xff, 0xff, 0xcd, + 0xf0, 0xb4, 0x4f, 0xff, 0xff, 0xff, 0xbf, 0xd4, + 0x20, 0x0, 0x0, 0xc8, 0x9f, 0xff, 0xff, 0xef, + 0xfe, 0x0, 0x0, 0x0, 0xe0, 0xc3, 0xff, 0xff, + 0xbf, 0xe5, 0xff, 0xff, 0xff, 0xff, 0xfd, 0x61, + 0xcb, 0xff, 0xff, 0xff, 0xff, 0xff, 0x93, 0xee, + 0x8, 0x0, 0x0, 0x0, 0xea, 0xd1, 0xff, 0xff, + 0xb1, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0x83, + 0xe0, 0x2, 0x0, 0x0, 0x0, 0x1c, 0xec, 0x6b, + 0xf9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcd, + 0x1d, 0x88, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xd2, 0x99, 0xff, 0xff, 0xff, 0xcb, + 0xb7, 0xed, 0xff, 0xff, 0xff, 0x4b, 0x76, 0x0, + 0x0, 0x0, 0xea, 0xc3, 0xff, 0xff, 0xff, 0xff, + 0xdb, 0xe1, 0xff, 0xff, 0xff, 0xe1, 0xb, 0x34, + 0x0, 0x0, 0x0, 0xac, 0x59, 0xff, 0xff, 0xff, + 0xef, 0xd1, 0xf3, 0xff, 0xff, 0xff, 0x5d, 0x9c, + 0x0, 0x0, 0xb0, 0x6b, 0xff, 0xff, 0xff, 0xf9, + 0xd5, 0xef, 0xff, 0xff, 0xff, 0xff, 0x57, 0x6a, + 0x0, 0x0, 0x0, 0x70, 0x29, 0xef, 0xff, 0xff, + 0xf9, 0xd5, 0xed, 0xff, 0xff, 0xff, 0x5d, 0xa2, + 0x0, 0x0, 0xb0, 0x93, 0xcb, 0xf3, 0xff, 0xff, + 0xef, 0xcb, 0xcb, 0x3d, 0x38, 0x0, 0x0, 0xae, + 0x67, 0xff, 0xff, 0xff, 0xf9, 0xd5, 0xed, 0xff, + 0xff, 0xff, 0xff, 0x5b, 0x70, 0x0, 0x0, 0x0, + 0xf4, 0xd3, 0xff, 0xff, 0xff, 0xf9, 0xd7, 0xeb, + 0xff, 0xff, 0xff, 0xd9, 0xfe, 0x10, 0x0, 0x0, + 0x0, 0xc8, 0x9f, 0xff, 0xff, 0xef, 0xfe, 0x0, + 0x0, 0x0, 0xb0, 0x89, 0xff, 0xff, 0xff, 0xfe, + 0x0, 0x0, 0x0, 0xea, 0xc3, 0xff, 0xff, 0xcd, + 0xf4, 0x5, 0xd5, 0xff, 0xff, 0xed, 0x27, 0x8e, + 0x0, 0x0, 0x0, 0xc8, 0x9f, 0xff, 0xff, 0xef, + 0xfe, 0x0, 0x0, 0x0, 0xea, 0xc3, 0xff, 0xff, + 0xff, 0xfb, 0xd7, 0xeb, 0xff, 0xff, 0xff, 0xf9, + 0xff, 0xe5, 0xdb, 0xff, 0xff, 0xff, 0xf9, 0x1f, + 0x3c, 0x0, 0x0, 0x0, 0xf2, 0xd1, 0xff, 0xff, + 0xff, 0xfb, 0xd9, 0xe7, 0xff, 0xff, 0xff, 0xef, + 0xb, 0x22, 0x0, 0x0, 0x0, 0x92, 0x41, 0xf9, + 0xff, 0xff, 0xf9, 0xd1, 0xe3, 0xff, 0xff, 0xff, + 0xb9, 0xfe, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xd4, 0xdf, 0xff, 0xff, 0xbd, 0xfe, + 0xf6, 0x31, 0xf9, 0xff, 0xff, 0x9b, 0xb8, 0x0, + 0x0, 0x0, 0xea, 0xc3, 0xff, 0xff, 0xf7, 0x4f, + 0xfe, 0xfe, 0x8f, 0xff, 0xff, 0xff, 0x63, 0x88, + 0x0, 0x0, 0x8, 0xfa, 0xcb, 0xff, 0xff, 0xdb, + 0x19, 0xfc, 0x23, 0xdf, 0xff, 0xff, 0xbb, 0xe2, + 0x0, 0x4, 0xf8, 0xcb, 0xff, 0xff, 0xf1, 0x39, + 0xfe, 0x11, 0xbb, 0xff, 0xff, 0xff, 0x57, 0x6a, + 0x0, 0x0, 0x0, 0xda, 0xa1, 0xff, 0xff, 0xf9, + 0x49, 0xfe, 0x15, 0xd5, 0xff, 0xff, 0xc3, 0xf0, + 0x0, 0x0, 0x5a, 0xbc, 0xfe, 0xd3, 0xff, 0xff, + 0xbd, 0xfe, 0xda, 0xa2, 0x18, 0x0, 0x2, 0xf8, + 0xcb, 0xff, 0xff, 0xf1, 0x39, 0xfe, 0xb, 0xad, + 0xff, 0xff, 0xff, 0x5b, 0x70, 0x0, 0x0, 0x0, + 0xf4, 0xd3, 0xff, 0xff, 0xe3, 0x35, 0xfe, 0x9, + 0xbb, 0xff, 0xff, 0xff, 0x2d, 0x36, 0x0, 0x0, + 0x0, 0xc8, 0x9f, 0xff, 0xff, 0xef, 0xfe, 0x0, + 0x0, 0x0, 0xb0, 0x89, 0xff, 0xff, 0xff, 0xfe, + 0x0, 0x0, 0x0, 0xea, 0xc3, 0xff, 0xff, 0xcd, + 0xfe, 0x81, 0xff, 0xff, 0xff, 0x67, 0xda, 0xc, + 0x0, 0x0, 0x0, 0xc8, 0x9f, 0xff, 0xff, 0xef, + 0xfe, 0x0, 0x0, 0x0, 0xea, 0xc3, 0xff, 0xff, + 0xed, 0x43, 0xfe, 0xd, 0xcf, 0xff, 0xff, 0xff, + 0x8f, 0xfe, 0xfe, 0x7f, 0xff, 0xff, 0xff, 0x67, + 0x78, 0x0, 0x0, 0x0, 0xf2, 0xd1, 0xff, 0xff, + 0xeb, 0x43, 0xfe, 0xfe, 0xa7, 0xff, 0xff, 0xff, + 0x49, 0x50, 0x0, 0x0, 0x2, 0xf2, 0xbb, 0xff, + 0xff, 0xf1, 0x39, 0xfc, 0xfe, 0xa1, 0xff, 0xff, + 0xff, 0x49, 0x76, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xbc, 0x2b, 0x2f, 0x2f, 0x1d, 0xda, + 0xc0, 0xfe, 0xdf, 0xff, 0xff, 0xb1, 0xd4, 0x0, + 0x0, 0x0, 0xea, 0xc3, 0xff, 0xff, 0xcb, 0xfa, + 0x24, 0x5a, 0x11, 0xf7, 0xff, 0xff, 0xa1, 0xca, + 0x0, 0x0, 0x2a, 0x1b, 0xfd, 0xff, 0xff, 0x87, + 0xd4, 0x12, 0xd0, 0x89, 0xff, 0xff, 0xdd, 0xdc, + 0x0, 0x1e, 0xf, 0xfb, 0xff, 0xff, 0xa7, 0xee, + 0x1a, 0xaa, 0x57, 0xff, 0xff, 0xff, 0x57, 0x6a, + 0x0, 0x0, 0x4, 0xfe, 0xe3, 0xff, 0xff, 0xb5, + 0xfe, 0xdc, 0xf8, 0x87, 0xff, 0xff, 0xf1, 0xfe, + 0x2, 0x0, 0x0, 0x0, 0xf4, 0xd3, 0xff, 0xff, + 0xbd, 0xe4, 0x0, 0x0, 0x0, 0x0, 0x1c, 0xd, + 0xfb, 0xff, 0xff, 0xa7, 0xee, 0x18, 0x9c, 0x51, + 0xff, 0xff, 0xff, 0x5b, 0x70, 0x0, 0x0, 0x0, + 0xf4, 0xd3, 0xff, 0xff, 0xbd, 0xf2, 0x14, 0xa4, + 0x5d, 0xff, 0xff, 0xff, 0x57, 0x60, 0x0, 0x0, + 0x0, 0xc8, 0x9f, 0xff, 0xff, 0xef, 0xfe, 0x0, + 0x0, 0x0, 0xb0, 0x89, 0xff, 0xff, 0xff, 0xfe, + 0x0, 0x0, 0x0, 0xea, 0xc3, 0xff, 0xff, 0xcd, + 0x25, 0xf1, 0xff, 0xff, 0xaf, 0xfe, 0x36, 0x0, + 0x0, 0x0, 0x0, 0xc8, 0x9f, 0xff, 0xff, 0xef, + 0xfe, 0x0, 0x0, 0x0, 0xea, 0xc3, 0xff, 0xff, + 0xcb, 0xf8, 0x1e, 0xce, 0x87, 0xff, 0xff, 0xff, + 0x25, 0x68, 0x4e, 0x1b, 0xff, 0xff, 0xff, 0x87, + 0xa4, 0x0, 0x0, 0x0, 0xf2, 0xd1, 0xff, 0xff, + 0xc1, 0xf6, 0x1c, 0x8e, 0x4f, 0xff, 0xff, 0xff, + 0x67, 0x78, 0x0, 0x0, 0x1a, 0xb, 0xf7, 0xff, + 0xff, 0xa3, 0xee, 0x16, 0x6e, 0x1d, 0xf7, 0xff, + 0xff, 0x9b, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x14, 0x90, 0xfa, 0x2d, 0x6f, 0x8d, + 0x97, 0x99, 0xef, 0xff, 0xff, 0xb3, 0xdc, 0x0, + 0x0, 0x0, 0xea, 0xc3, 0xff, 0xff, 0xcb, 0xee, + 0x0, 0x4, 0xfa, 0xd1, 0xff, 0xff, 0xc1, 0xe4, + 0x0, 0x0, 0x52, 0x4f, 0xff, 0xff, 0xff, 0x59, + 0x80, 0x0, 0x52, 0xfe, 0xfe, 0xfe, 0xfe, 0xb4, + 0x0, 0x40, 0x41, 0xff, 0xff, 0xff, 0x6f, 0xa2, + 0x0, 0x6a, 0x57, 0xff, 0xff, 0xff, 0x57, 0x6a, + 0x0, 0x0, 0x12, 0x11, 0xff, 0xff, 0xff, 0xd3, + 0xad, 0xad, 0xad, 0xc9, 0xff, 0xff, 0xff, 0xb, + 0x6, 0x0, 0x0, 0x0, 0xf4, 0xd3, 0xff, 0xff, + 0xbd, 0xe4, 0x0, 0x0, 0x0, 0x0, 0x3e, 0x41, + 0xff, 0xff, 0xff, 0x6f, 0xa2, 0x0, 0x64, 0x51, + 0xff, 0xff, 0xff, 0x5b, 0x70, 0x0, 0x0, 0x0, + 0xf4, 0xd3, 0xff, 0xff, 0xbd, 0xe4, 0x0, 0x56, + 0x41, 0xff, 0xff, 0xff, 0x65, 0x78, 0x0, 0x0, + 0x0, 0xc8, 0x9f, 0xff, 0xff, 0xef, 0xfe, 0x0, + 0x0, 0x0, 0xb0, 0x89, 0xff, 0xff, 0xff, 0xfe, + 0x0, 0x0, 0x0, 0xea, 0xc3, 0xff, 0xff, 0xfb, + 0xf3, 0xff, 0xff, 0xe5, 0x19, 0x7a, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xc8, 0x9f, 0xff, 0xff, 0xef, + 0xfe, 0x0, 0x0, 0x0, 0xea, 0xc3, 0xff, 0xff, + 0xcb, 0xee, 0x0, 0x9c, 0x75, 0xff, 0xff, 0xff, + 0x29, 0x26, 0x8, 0xfe, 0xfb, 0xff, 0xff, 0x91, + 0xb4, 0x0, 0x0, 0x0, 0xf2, 0xd1, 0xff, 0xff, + 0xc1, 0xe8, 0x0, 0x48, 0x39, 0xff, 0xff, 0xff, + 0x6f, 0x88, 0x0, 0x0, 0x3e, 0x3f, 0xff, 0xff, + 0xff, 0x6d, 0xa0, 0x0, 0x8, 0xfa, 0xd5, 0xff, + 0xff, 0xc1, 0xe4, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x8c, 0x19, 0xb5, 0xfd, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xb3, 0xdc, 0x0, + 0x0, 0x0, 0xea, 0xc3, 0xff, 0xff, 0xcb, 0xee, + 0x0, 0x0, 0xee, 0xc3, 0xff, 0xff, 0xcd, 0xec, + 0x0, 0x0, 0x6a, 0x5f, 0xff, 0xff, 0xff, 0x47, + 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x58, 0x51, 0xff, 0xff, 0xff, 0x59, 0x7a, + 0x0, 0x6a, 0x57, 0xff, 0xff, 0xff, 0x57, 0x6a, + 0x0, 0x0, 0x1c, 0x2b, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x15, + 0xa, 0x0, 0x0, 0x0, 0xf4, 0xd3, 0xff, 0xff, + 0xbd, 0xe4, 0x0, 0x0, 0x0, 0x0, 0x58, 0x51, + 0xff, 0xff, 0xff, 0x59, 0x7a, 0x0, 0x64, 0x51, + 0xff, 0xff, 0xff, 0x5b, 0x70, 0x0, 0x0, 0x0, + 0xf4, 0xd3, 0xff, 0xff, 0xbd, 0xe4, 0x0, 0x46, + 0x3f, 0xff, 0xff, 0xff, 0x67, 0x80, 0x0, 0x0, + 0x0, 0xc8, 0x9f, 0xff, 0xff, 0xef, 0xfe, 0x0, + 0x0, 0x0, 0xb0, 0x89, 0xff, 0xff, 0xff, 0xfe, + 0x0, 0x0, 0x0, 0xea, 0xc3, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xd3, 0x5, 0x54, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xc8, 0x9f, 0xff, 0xff, 0xef, + 0xfe, 0x0, 0x0, 0x0, 0xea, 0xc3, 0xff, 0xff, + 0xcb, 0xee, 0x0, 0x94, 0x73, 0xff, 0xff, 0xff, + 0x29, 0x2a, 0x0, 0xfe, 0xfb, 0xff, 0xff, 0x91, + 0xb8, 0x0, 0x0, 0x0, 0xf2, 0xd1, 0xff, 0xff, + 0xc1, 0xe8, 0x0, 0x3e, 0x39, 0xff, 0xff, 0xff, + 0x6f, 0x8c, 0x0, 0x0, 0x54, 0x53, 0xff, 0xff, + 0xff, 0x57, 0x7a, 0x0, 0x0, 0xf0, 0xc3, 0xff, + 0xff, 0xcd, 0xec, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc, 0xfc, 0xbd, 0xff, 0xff, 0xfb, 0xb5, + 0x91, 0x8d, 0xed, 0xff, 0xff, 0xb3, 0xdc, 0x0, + 0x0, 0x0, 0xea, 0xc3, 0xff, 0xff, 0xcb, 0xee, + 0x0, 0x0, 0xf0, 0xc5, 0xff, 0xff, 0xcb, 0xec, + 0x0, 0x0, 0x5e, 0x57, 0xff, 0xff, 0xff, 0x51, + 0x6e, 0x0, 0x18, 0x54, 0x80, 0x92, 0x6c, 0x38, + 0x0, 0x52, 0x4f, 0xff, 0xff, 0xff, 0x5d, 0x82, + 0x0, 0x6a, 0x57, 0xff, 0xff, 0xff, 0x57, 0x6a, + 0x0, 0x0, 0x18, 0x21, 0xff, 0xff, 0xff, 0xdb, + 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xf, + 0x8, 0x0, 0x0, 0x0, 0xf4, 0xd3, 0xff, 0xff, + 0xbd, 0xe4, 0x0, 0x0, 0x0, 0x0, 0x52, 0x4f, + 0xff, 0xff, 0xff, 0x5d, 0x82, 0x0, 0x64, 0x51, + 0xff, 0xff, 0xff, 0x5b, 0x70, 0x0, 0x0, 0x0, + 0xf4, 0xd3, 0xff, 0xff, 0xbd, 0xe4, 0x0, 0x46, + 0x3f, 0xff, 0xff, 0xff, 0x67, 0x80, 0x0, 0x0, + 0x0, 0xc8, 0x9f, 0xff, 0xff, 0xef, 0xfe, 0x0, + 0x0, 0x0, 0xb0, 0x89, 0xff, 0xff, 0xff, 0xfe, + 0x0, 0x0, 0x0, 0xea, 0xc3, 0xff, 0xff, 0xf1, + 0xcd, 0xff, 0xff, 0xff, 0x87, 0xea, 0x12, 0x0, + 0x0, 0x0, 0x0, 0xc8, 0x9f, 0xff, 0xff, 0xef, + 0xfe, 0x0, 0x0, 0x0, 0xea, 0xc3, 0xff, 0xff, + 0xcb, 0xee, 0x0, 0x94, 0x73, 0xff, 0xff, 0xff, + 0x29, 0x2a, 0x0, 0xfe, 0xfb, 0xff, 0xff, 0x91, + 0xb8, 0x0, 0x0, 0x0, 0xf2, 0xd1, 0xff, 0xff, + 0xc1, 0xe8, 0x0, 0x3e, 0x39, 0xff, 0xff, 0xff, + 0x6f, 0x8c, 0x0, 0x0, 0x48, 0x49, 0xff, 0xff, + 0xff, 0x65, 0x8a, 0x0, 0x0, 0xf6, 0xcf, 0xff, + 0xff, 0xc7, 0xe8, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2a, 0x27, 0xff, 0xff, 0xff, 0x91, 0xfc, + 0xc8, 0xfe, 0xdd, 0xff, 0xff, 0xb3, 0xdc, 0x0, + 0x0, 0x0, 0xea, 0xc3, 0xff, 0xff, 0xcb, 0xf4, + 0x4, 0x1c, 0xfe, 0xdb, 0xff, 0xff, 0xb9, 0xde, + 0x0, 0x0, 0x3a, 0x33, 0xff, 0xff, 0xff, 0x71, + 0xb2, 0x0, 0x82, 0x3b, 0x77, 0x77, 0x69, 0xb6, + 0x0, 0x34, 0x33, 0xff, 0xff, 0xff, 0x7d, 0xc4, + 0x0, 0x7c, 0x57, 0xff, 0xff, 0xff, 0x57, 0x6a, + 0x0, 0x0, 0xa, 0xfe, 0xf5, 0xff, 0xff, 0xab, + 0xfe, 0xea, 0xe8, 0xe8, 0xea, 0xea, 0xd0, 0x8e, + 0x4, 0x0, 0x0, 0x0, 0xf4, 0xd3, 0xff, 0xff, + 0xbd, 0xe4, 0x0, 0x0, 0x0, 0x0, 0x34, 0x33, + 0xff, 0xff, 0xff, 0x7d, 0xc4, 0x0, 0x74, 0x51, + 0xff, 0xff, 0xff, 0x5b, 0x70, 0x0, 0x0, 0x0, + 0xf4, 0xd3, 0xff, 0xff, 0xbd, 0xe4, 0x0, 0x46, + 0x3f, 0xff, 0xff, 0xff, 0x67, 0x80, 0x0, 0x0, + 0x0, 0xc8, 0x9f, 0xff, 0xff, 0xef, 0xfe, 0x0, + 0x0, 0x0, 0xb0, 0x89, 0xff, 0xff, 0xff, 0xfe, + 0x0, 0x0, 0x0, 0xea, 0xc3, 0xff, 0xff, 0xcd, + 0xfe, 0xd1, 0xff, 0xff, 0xf5, 0x31, 0x96, 0x0, + 0x0, 0x0, 0x0, 0xc8, 0x9f, 0xff, 0xff, 0xef, + 0xfe, 0x0, 0x0, 0x0, 0xea, 0xc3, 0xff, 0xff, + 0xcb, 0xee, 0x0, 0x94, 0x73, 0xff, 0xff, 0xff, + 0x29, 0x2a, 0x0, 0xfe, 0xfb, 0xff, 0xff, 0x91, + 0xb8, 0x0, 0x0, 0x0, 0xf2, 0xd1, 0xff, 0xff, + 0xc1, 0xe8, 0x0, 0x3e, 0x39, 0xff, 0xff, 0xff, + 0x6f, 0x8c, 0x0, 0x0, 0x26, 0x1f, 0xff, 0xff, + 0xff, 0x89, 0xd0, 0x0, 0x36, 0x5, 0xeb, 0xff, + 0xff, 0xab, 0xd2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x32, 0x47, 0xff, 0xff, 0xff, 0x65, 0xe8, + 0xd4, 0x13, 0xe9, 0xff, 0xff, 0xb3, 0xe2, 0x0, + 0x0, 0x0, 0xea, 0xc3, 0xff, 0xff, 0xe1, 0xf, + 0xe2, 0xee, 0x43, 0xff, 0xff, 0xff, 0x8f, 0xb4, + 0x0, 0x0, 0x14, 0xfe, 0xe5, 0xff, 0xff, 0xbd, + 0xfe, 0xd8, 0xfe, 0xad, 0xff, 0xff, 0xd1, 0xce, + 0x0, 0x14, 0xfe, 0xef, 0xff, 0xff, 0xcd, 0x5, + 0xde, 0xfa, 0x7b, 0xff, 0xff, 0xff, 0x57, 0x6a, + 0x0, 0x0, 0x0, 0xf2, 0xc1, 0xff, 0xff, 0xf5, + 0x39, 0xf0, 0xbe, 0xd4, 0xfc, 0x3b, 0xf4, 0x10, + 0x0, 0x0, 0x0, 0x0, 0xf4, 0xd3, 0xff, 0xff, + 0xbd, 0xe4, 0x0, 0x0, 0x0, 0x0, 0x14, 0xfe, + 0xed, 0xff, 0xff, 0xcd, 0x5, 0xdc, 0xf8, 0x71, + 0xff, 0xff, 0xff, 0x5b, 0x70, 0x0, 0x0, 0x0, + 0xf4, 0xd3, 0xff, 0xff, 0xbd, 0xe4, 0x0, 0x46, + 0x3f, 0xff, 0xff, 0xff, 0x67, 0x80, 0x0, 0x0, + 0x0, 0xc8, 0x9f, 0xff, 0xff, 0xef, 0xfe, 0x0, + 0x0, 0x0, 0xb0, 0x89, 0xff, 0xff, 0xff, 0xfe, + 0x0, 0x0, 0x0, 0xea, 0xc3, 0xff, 0xff, 0xcd, + 0xfa, 0x47, 0xfb, 0xff, 0xff, 0xc3, 0xfe, 0x3e, + 0x0, 0x0, 0x0, 0xc8, 0x9f, 0xff, 0xff, 0xef, + 0xfe, 0x0, 0x0, 0x0, 0xea, 0xc3, 0xff, 0xff, + 0xcb, 0xee, 0x0, 0x94, 0x73, 0xff, 0xff, 0xff, + 0x29, 0x2a, 0x0, 0xfe, 0xfb, 0xff, 0xff, 0x91, + 0xb8, 0x0, 0x0, 0x0, 0xf2, 0xd1, 0xff, 0xff, + 0xc1, 0xe8, 0x0, 0x3e, 0x39, 0xff, 0xff, 0xff, + 0x6f, 0x8c, 0x0, 0x0, 0x8, 0xfc, 0xd5, 0xff, + 0xff, 0xd7, 0x5, 0xd6, 0xf2, 0x69, 0xff, 0xff, + 0xff, 0x6d, 0x94, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x28, 0x21, 0xff, 0xff, 0xff, 0xd9, 0x73, + 0x81, 0xd9, 0xff, 0xff, 0xff, 0xbf, 0xec, 0x0, + 0x0, 0x0, 0xea, 0xc3, 0xff, 0xff, 0xff, 0xd9, + 0x95, 0xa1, 0xed, 0xff, 0xff, 0xfb, 0x35, 0x64, + 0x0, 0x0, 0x0, 0xd4, 0x8b, 0xff, 0xff, 0xff, + 0xbf, 0x8d, 0xb5, 0xff, 0xff, 0xff, 0x8d, 0xc2, + 0x0, 0x0, 0xe6, 0xa7, 0xff, 0xff, 0xff, 0xcd, + 0x93, 0xaf, 0xfb, 0xff, 0xff, 0xff, 0x57, 0x6a, + 0x0, 0x0, 0x0, 0x9e, 0x55, 0xff, 0xff, 0xff, + 0xf1, 0xa1, 0x87, 0x97, 0xcd, 0xfd, 0x2f, 0x5c, + 0x0, 0x0, 0x0, 0x0, 0xf4, 0xd3, 0xff, 0xff, + 0xbd, 0xe4, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe4, + 0xa5, 0xff, 0xff, 0xff, 0xcd, 0x93, 0xab, 0xf9, + 0xff, 0xff, 0xff, 0x5b, 0x70, 0x0, 0x0, 0x0, + 0xf4, 0xd3, 0xff, 0xff, 0xbd, 0xe4, 0x0, 0x46, + 0x3f, 0xff, 0xff, 0xff, 0x67, 0x80, 0x0, 0x0, + 0x0, 0xc8, 0x9f, 0xff, 0xff, 0xef, 0xfe, 0x0, + 0x0, 0x0, 0xb0, 0x89, 0xff, 0xff, 0xff, 0xfe, + 0x0, 0x0, 0x0, 0xea, 0xc3, 0xff, 0xff, 0xcd, + 0xf2, 0xf8, 0xa3, 0xff, 0xff, 0xff, 0x71, 0xdc, + 0xa, 0x0, 0x0, 0xc8, 0x9f, 0xff, 0xff, 0xef, + 0xfe, 0x0, 0x0, 0x0, 0xea, 0xc3, 0xff, 0xff, + 0xcb, 0xee, 0x0, 0x94, 0x73, 0xff, 0xff, 0xff, + 0x29, 0x2a, 0x0, 0xfe, 0xfb, 0xff, 0xff, 0x91, + 0xb8, 0x0, 0x0, 0x0, 0xf2, 0xd1, 0xff, 0xff, + 0xc1, 0xe8, 0x0, 0x3e, 0x39, 0xff, 0xff, 0xff, + 0x6f, 0x8c, 0x0, 0x0, 0x0, 0xba, 0x6f, 0xff, + 0xff, 0xff, 0xcd, 0x89, 0x9d, 0xf3, 0xff, 0xff, + 0xe1, 0x9, 0x3a, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa, 0xfc, 0xbb, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xfb, 0xe5, 0xff, 0xff, 0xd7, 0xfc, 0x8, + 0x0, 0x0, 0xea, 0xc3, 0xff, 0xff, 0xe3, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x9f, 0xf6, 0x14, + 0x0, 0x0, 0x0, 0x54, 0xb, 0xcb, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0xf, 0x58, + 0x0, 0x0, 0x76, 0x27, 0xeb, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xe9, 0xfd, 0xff, 0xff, 0x57, 0x6a, + 0x0, 0x0, 0x0, 0x28, 0xfa, 0x91, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0x64, + 0x0, 0x0, 0x0, 0x0, 0xf4, 0xd3, 0xff, 0xff, + 0xbd, 0xe4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x72, + 0x23, 0xe9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, + 0xff, 0xff, 0xff, 0x5b, 0x6e, 0x0, 0x0, 0x0, + 0xf4, 0xd3, 0xff, 0xff, 0xbd, 0xe4, 0x0, 0x46, + 0x3f, 0xff, 0xff, 0xff, 0x67, 0x80, 0x0, 0x0, + 0x0, 0xc8, 0x9f, 0xff, 0xff, 0xef, 0xfe, 0x0, + 0x0, 0x0, 0xb0, 0x89, 0xff, 0xff, 0xff, 0xfe, + 0x0, 0x0, 0x0, 0xea, 0xc3, 0xff, 0xff, 0xcd, + 0xf0, 0x70, 0x19, 0xe9, 0xff, 0xff, 0xed, 0x21, + 0x80, 0x0, 0x0, 0xc8, 0x9f, 0xff, 0xff, 0xef, + 0xfe, 0x0, 0x0, 0x0, 0xea, 0xc3, 0xff, 0xff, + 0xcb, 0xee, 0x0, 0x94, 0x73, 0xff, 0xff, 0xff, + 0x29, 0x2a, 0x0, 0xfe, 0xfb, 0xff, 0xff, 0x91, + 0xb8, 0x0, 0x0, 0x0, 0xf2, 0xd1, 0xff, 0xff, + 0xc1, 0xe8, 0x0, 0x3e, 0x39, 0xff, 0xff, 0xff, + 0x6f, 0x8c, 0x0, 0x0, 0x0, 0x3c, 0xfe, 0xad, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, + 0x4b, 0xc2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xf4, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, + 0xfe, 0xfe, 0xfe, 0xfe, 0x8c, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x8a, 0x1d, 0xb9, 0xff, 0xff, 0xff, + 0xe9, 0x67, 0x8b, 0xff, 0xff, 0xfd, 0x1f, 0x8, + 0x0, 0x0, 0xce, 0xc3, 0xff, 0xff, 0x77, 0x97, + 0xf9, 0xff, 0xff, 0xf5, 0x99, 0x5, 0x66, 0x0, + 0x0, 0x0, 0x0, 0x2, 0x9a, 0x11, 0x9d, 0xf1, + 0xff, 0xff, 0xff, 0xf3, 0x9d, 0x13, 0xa2, 0x4, + 0x0, 0x0, 0xc, 0xd0, 0x3d, 0xcd, 0xff, 0xff, + 0xff, 0xd9, 0x3f, 0xe3, 0xff, 0xff, 0x57, 0x4c, + 0x0, 0x0, 0x0, 0x0, 0x58, 0xfe, 0x6d, 0xdb, + 0xff, 0xff, 0xff, 0xff, 0xeb, 0xa1, 0x23, 0x58, + 0x0, 0x0, 0x0, 0x0, 0xe0, 0xd3, 0xff, 0xff, + 0xbd, 0xc8, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, + 0xce, 0x39, 0xcb, 0xff, 0xff, 0xff, 0xdf, 0x81, + 0xff, 0xff, 0xff, 0x59, 0x64, 0x0, 0x0, 0x0, + 0xe0, 0xd3, 0xff, 0xff, 0xbd, 0xc8, 0x0, 0x30, + 0x3f, 0xff, 0xff, 0xff, 0x67, 0x60, 0x0, 0x0, + 0x0, 0xa4, 0x9f, 0xff, 0xff, 0xef, 0xf6, 0x0, + 0x0, 0x0, 0xb2, 0x89, 0xff, 0xff, 0xff, 0xfe, + 0x0, 0x0, 0x0, 0xce, 0xc3, 0xff, 0xff, 0xcd, + 0xd8, 0x6, 0xd4, 0x6d, 0xff, 0xff, 0xff, 0xb1, + 0x80, 0x0, 0x0, 0xa4, 0x9f, 0xff, 0xff, 0xef, + 0xf6, 0x0, 0x0, 0x0, 0xce, 0xc3, 0xff, 0xff, + 0xcb, 0xd6, 0x0, 0x70, 0x73, 0xff, 0xff, 0xff, + 0x29, 0x1c, 0x0, 0xfe, 0xfb, 0xff, 0xff, 0x91, + 0x94, 0x0, 0x0, 0x0, 0xdc, 0xd1, 0xff, 0xff, + 0xc1, 0xcc, 0x0, 0x2a, 0x39, 0xff, 0xff, 0xff, + 0x6f, 0x68, 0x0, 0x0, 0x0, 0x0, 0x76, 0xfe, + 0x83, 0xe5, 0xff, 0xff, 0xff, 0xfb, 0xc1, 0x3f, + 0xe0, 0x22, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xfe, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xc1, 0xcc, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x8, 0x88, 0xfa, 0x25, 0x53, 0x45, + 0x9, 0xe0, 0xfe, 0xfe, 0xfe, 0xfe, 0xf2, 0x8, + 0x0, 0x0, 0x90, 0xfe, 0xfe, 0xfe, 0xfe, 0xf4, + 0x1d, 0x4f, 0x49, 0x11, 0xea, 0x60, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x4, 0x66, 0xe4, 0x5, + 0x3f, 0x55, 0x45, 0xb, 0xe8, 0x68, 0x4, 0x0, + 0x0, 0x0, 0x0, 0x18, 0xa4, 0xfc, 0x2d, 0x53, + 0x3d, 0xfe, 0xec, 0xfe, 0xfe, 0xfe, 0xfe, 0x2a, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x3a, 0xc2, 0xfe, + 0x2d, 0x51, 0x51, 0x31, 0xfe, 0xe2, 0x70, 0xc, + 0x0, 0x0, 0x0, 0x0, 0xa6, 0xfe, 0xfe, 0xfe, + 0xfe, 0x88, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1e, 0xa6, 0xfc, 0x2d, 0x53, 0x41, 0xfe, 0x73, + 0xff, 0xff, 0xff, 0x43, 0x42, 0x0, 0x0, 0x0, + 0xa6, 0xfe, 0xfe, 0xfe, 0xfe, 0x88, 0x0, 0x1a, + 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0x36, 0x0, 0x0, + 0x0, 0x68, 0xfe, 0xfe, 0xfe, 0xfe, 0xd2, 0x0, + 0x0, 0x0, 0xc2, 0x8d, 0xff, 0xff, 0xff, 0xfe, + 0x0, 0x0, 0x0, 0x90, 0xfe, 0xfe, 0xfe, 0xfe, + 0x9c, 0x0, 0x3a, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, + 0x7c, 0x0, 0x0, 0x68, 0xfe, 0xfe, 0xfe, 0xfe, + 0xd2, 0x0, 0x0, 0x0, 0x90, 0xfe, 0xfe, 0xfe, + 0xfe, 0x98, 0x0, 0x40, 0xfe, 0xfe, 0xfe, 0xfe, + 0xfe, 0xe, 0x0, 0xec, 0xfe, 0xfe, 0xfe, 0xfe, + 0x5a, 0x0, 0x0, 0x0, 0xa2, 0xfe, 0xfe, 0xfe, + 0xfe, 0x8c, 0x0, 0x16, 0xfe, 0xfe, 0xfe, 0xfe, + 0xfe, 0x3c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4c, + 0xd4, 0xfe, 0x35, 0x53, 0x49, 0x1b, 0xf8, 0x98, + 0x1a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xfe, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xc1, 0xda, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xc, 0x30, 0x48, 0x40, + 0x1e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, + 0x2c, 0x46, 0x42, 0x24, 0x4, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1a, + 0x3e, 0x54, 0x42, 0x1e, 0x2, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x34, 0x48, + 0x3c, 0x1a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, + 0x32, 0x50, 0x52, 0x36, 0x12, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5a, 0x21, 0x15, 0xf6, 0xde, 0xe8, 0xb, 0xcf, + 0xff, 0xff, 0xf3, 0xb, 0x1e, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x7a, 0xbe, 0xfe, 0xb1, 0xff, 0xff, 0xef, 0xfe, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x14, 0x38, 0x50, 0x48, 0x26, 0x8, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xf8, 0xa7, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, + 0xa9, 0xa9, 0xa9, 0x7f, 0xac, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xba, 0x8d, 0xf3, 0xb9, 0x9b, 0x9d, 0xdb, 0xff, + 0xff, 0xff, 0xa1, 0xea, 0x2, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, + 0x5, 0xb1, 0xb9, 0xfd, 0xff, 0xff, 0xbf, 0xee, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x70, 0xb0, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, + 0xd4, 0xd4, 0xc8, 0x9a, 0x48, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc2, 0xc7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xcd, 0x13, 0x6c, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, + 0x23, 0xff, 0xff, 0xff, 0xff, 0xf9, 0x4d, 0x9a, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa4, 0x55, 0xb1, 0xef, 0xff, 0xff, 0xfd, 0xdb, + 0x89, 0xb, 0x9e, 0x4, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, + 0x37, 0xff, 0xff, 0xff, 0xd5, 0x57, 0xf0, 0x22, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x28, 0x90, 0xea, 0xfe, 0x21, 0x2d, 0x11, 0xfc, + 0xc8, 0x52, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x16, + 0xfa, 0x1b, 0x35, 0x1b, 0xfc, 0xb4, 0x2a, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xa, 0x1a, 0x1c, 0x14, 0x4, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x8, 0x1a, 0x22, 0x1a, 0x8, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x26, + 0x86, 0x86, 0x72, 0x2, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x76, + 0x84, 0x80, 0x1e, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x7a, 0xfe, + 0x51, 0xa9, 0xd, 0x3a, 0x0, 0x0, 0x0, 0xa, + 0x16, 0x16, 0xc, 0x0, 0x0, 0x0, 0x4e, 0x1f, + 0xa7, 0x45, 0xfa, 0x68, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x62, 0xb, 0xb1, + 0xff, 0xff, 0x69, 0x4e, 0x0, 0x0, 0x0, 0xec, + 0x21, 0x23, 0x5, 0x10, 0x0, 0x0, 0x64, 0x7d, + 0xff, 0xff, 0x9f, 0xfe, 0x4c, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0xaa, + 0xe2, 0xf6, 0xe8, 0xbc, 0x3a, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x6, 0xe6, 0x99, 0xff, + 0xff, 0xd9, 0x3f, 0x4c, 0x0, 0x0, 0x0, 0xfe, + 0xfb, 0xff, 0x2f, 0x20, 0x0, 0x0, 0x60, 0x49, + 0xe1, 0xff, 0xff, 0x83, 0xd4, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0xb, + 0xd7, 0xd7, 0xd7, 0x6d, 0x76, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x2c, 0x17, 0xf1, 0xff, + 0xff, 0x37, 0xba, 0x1a, 0x0, 0x0, 0x0, 0xfe, + 0xfb, 0xff, 0x2f, 0x2e, 0x0, 0x0, 0x20, 0xca, + 0x4f, 0xff, 0xff, 0xe7, 0x9, 0x16, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0xd, + 0xff, 0xff, 0xff, 0x83, 0x9e, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x60, 0x53, 0xff, 0xff, + 0xdd, 0xfe, 0x16, 0x0, 0x0, 0x0, 0x0, 0xfe, + 0xfb, 0xff, 0x2f, 0x2e, 0x0, 0x0, 0x0, 0x24, + 0xfe, 0xed, 0xff, 0xff, 0x39, 0x40, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x5e, 0xb8, 0xe0, 0xdc, 0xb6, 0xb6, 0xea, + 0xf8, 0xf8, 0xe0, 0x88, 0x16, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x48, 0xbc, 0xf0, 0xfa, + 0xf6, 0xd0, 0xa6, 0xc4, 0xe4, 0xd2, 0x9a, 0x16, + 0x0, 0x0, 0x0, 0x5e, 0xb8, 0xe0, 0xdc, 0xb8, + 0xbc, 0xec, 0xf0, 0xda, 0x46, 0x0, 0x0, 0x0, + 0x4, 0x54, 0xbe, 0xf0, 0xfa, 0xfc, 0xf6, 0xd6, + 0x80, 0x1a, 0x0, 0x0, 0x0, 0x64, 0xbc, 0xd, + 0xff, 0xff, 0xff, 0x83, 0xf4, 0xb2, 0x4e, 0x0, + 0x0, 0x6a, 0xbe, 0xe2, 0xde, 0xb6, 0x56, 0x0, + 0x10, 0x98, 0xd2, 0xea, 0xd6, 0xa0, 0x24, 0x0, + 0x0, 0x5e, 0xba, 0xe0, 0xe6, 0xc4, 0x78, 0x0, + 0x0, 0x4e, 0xb2, 0xdc, 0xe8, 0xca, 0x86, 0x0, + 0x4c, 0xb2, 0xdc, 0xde, 0xb4, 0x52, 0x0, 0x38, + 0xa8, 0xd8, 0xd0, 0x92, 0x6, 0x2, 0x8e, 0xce, + 0xea, 0xd4, 0x9a, 0x18, 0x0, 0x3a, 0xaa, 0xda, + 0xea, 0xd8, 0xa4, 0x2e, 0xa, 0x92, 0xd0, 0xea, + 0xe2, 0xbe, 0x68, 0x0, 0x72, 0xc2, 0xe4, 0xe4, + 0xc2, 0x74, 0x0, 0x0, 0x4e, 0xb2, 0xde, 0xea, + 0xd0, 0x94, 0xa, 0x0, 0x86, 0xca, 0xe8, 0xea, + 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xd4, 0x9c, + 0x1c, 0x0, 0x0, 0x0, 0x88, 0x73, 0xff, 0xff, + 0xcb, 0xf2, 0x0, 0x0, 0x0, 0x0, 0x0, 0xfe, + 0xfb, 0xff, 0x2f, 0x2e, 0x0, 0x0, 0x0, 0x0, + 0xfa, 0xdb, 0xff, 0xff, 0x5d, 0x68, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb8, 0x95, 0xc3, 0xc3, 0x75, 0x49, 0xc3, + 0xeb, 0xe3, 0xb3, 0x39, 0xe2, 0x20, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x7a, 0xfe, 0x7d, 0xd1, 0xeb, + 0xdf, 0x93, 0xb, 0xad, 0xc3, 0xc3, 0x37, 0x32, + 0x0, 0x0, 0x0, 0xb8, 0x95, 0xc3, 0xc3, 0x79, + 0x43, 0xc9, 0xeb, 0x7b, 0x74, 0x0, 0x0, 0xc, + 0xb2, 0x11, 0x89, 0xcf, 0xe9, 0xed, 0xd9, 0xa9, + 0x3f, 0xf2, 0x40, 0x0, 0x0, 0xc4, 0x9d, 0xc5, + 0xff, 0xff, 0xff, 0xdb, 0xc3, 0x83, 0xa0, 0x0, + 0x0, 0xca, 0xa1, 0xc3, 0xc3, 0x8d, 0xae, 0x0, + 0x28, 0x2f, 0xc3, 0xc3, 0xc3, 0x4f, 0x52, 0x0, + 0x0, 0x90, 0x97, 0xc3, 0xc3, 0xaf, 0xfc, 0xe, + 0x0, 0xc6, 0x83, 0xc3, 0xc3, 0xbb, 0xb, 0x0, + 0x7c, 0x83, 0xc3, 0xc3, 0x89, 0xc6, 0x0, 0xa6, + 0x6b, 0xc3, 0xc3, 0x17, 0x3c, 0x22, 0xb, 0xc1, + 0xc3, 0xc3, 0x3f, 0x1c, 0x0, 0x40, 0x73, 0xc3, + 0xc3, 0xc3, 0x5b, 0xb0, 0x64, 0x21, 0xc1, 0xc3, + 0xc3, 0xa1, 0x84, 0x0, 0xaa, 0xa9, 0xc3, 0xc3, + 0xab, 0xfc, 0x10, 0x0, 0xd0, 0x85, 0xc3, 0xc3, + 0xc3, 0x27, 0xa, 0x0, 0xee, 0xbb, 0xc3, 0xc3, + 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x41, + 0x40, 0x0, 0x0, 0x0, 0x98, 0x7b, 0xff, 0xff, + 0xc7, 0xee, 0x0, 0x0, 0x0, 0x0, 0x0, 0xfe, + 0xfb, 0xff, 0x2f, 0x2e, 0x0, 0x0, 0x0, 0x0, + 0xf6, 0xd7, 0xff, 0xff, 0x67, 0x7c, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xe0, 0xc3, 0xff, 0xff, 0xcf, 0xf7, 0xff, + 0xff, 0xff, 0xff, 0xf3, 0x49, 0xba, 0x0, 0x0, + 0x0, 0x0, 0x38, 0xfe, 0xb1, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xbb, 0xfb, 0xff, 0xff, 0x49, 0x4c, + 0x0, 0x0, 0x0, 0xe0, 0xc3, 0xff, 0xff, 0xb9, + 0xeb, 0xff, 0xff, 0x75, 0x8c, 0x0, 0x0, 0x7c, + 0x23, 0xd9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xfb, 0x73, 0xec, 0x10, 0x0, 0xdc, 0xcd, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xad, 0xbe, 0x0, + 0x0, 0xec, 0xd3, 0xff, 0xff, 0xbb, 0xd8, 0x0, + 0x3e, 0x3f, 0xff, 0xff, 0xff, 0x67, 0x76, 0x0, + 0x0, 0x98, 0x87, 0xff, 0xff, 0xff, 0x2b, 0x4e, + 0xc, 0xfc, 0xd9, 0xff, 0xff, 0xc1, 0xd6, 0x0, + 0x86, 0x7b, 0xff, 0xff, 0xd7, 0xfa, 0x6, 0xf4, + 0xc1, 0xff, 0xff, 0x69, 0x96, 0x64, 0x4b, 0xff, + 0xff, 0xf7, 0xf, 0x1c, 0x0, 0x40, 0x1d, 0xeb, + 0xff, 0xff, 0xcf, 0xfe, 0xe8, 0x97, 0xff, 0xff, + 0xff, 0x5d, 0x84, 0x0, 0xb4, 0x9f, 0xff, 0xff, + 0xff, 0x2d, 0x54, 0x1a, 0xfe, 0xe3, 0xff, 0xff, + 0xd7, 0xe6, 0xa, 0x0, 0xfc, 0xf5, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x57, + 0x4c, 0x0, 0x0, 0x0, 0xa2, 0x7b, 0xff, 0xff, + 0xc7, 0xea, 0x0, 0x0, 0x0, 0x0, 0x0, 0xfe, + 0xfb, 0xff, 0x2f, 0x2e, 0x0, 0x0, 0x0, 0x0, + 0xf4, 0xd7, 0xff, 0xff, 0x67, 0x86, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xea, 0xc3, 0xff, 0xff, 0xff, 0xfd, 0xd9, + 0xe5, 0xff, 0xff, 0xff, 0xdb, 0x5, 0x2e, 0x0, + 0x0, 0x0, 0xb0, 0x6b, 0xff, 0xff, 0xff, 0xf7, + 0xcf, 0xe9, 0xff, 0xff, 0xff, 0xff, 0x49, 0x54, + 0x0, 0x0, 0x0, 0xea, 0xc3, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x57, 0x64, 0x0, 0x0, 0xe2, + 0xad, 0xff, 0xff, 0xf7, 0xa7, 0x9b, 0xe5, 0xff, + 0xff, 0xf7, 0x2f, 0x54, 0x0, 0xc6, 0xa1, 0xcb, + 0xff, 0xff, 0xff, 0xdf, 0xcb, 0x89, 0xa2, 0x0, + 0x0, 0xf4, 0xd3, 0xff, 0xff, 0xbb, 0xe2, 0x0, + 0x46, 0x3f, 0xff, 0xff, 0xff, 0x67, 0x80, 0x0, + 0x0, 0x5a, 0x2d, 0xfd, 0xff, 0xff, 0x79, 0xa6, + 0x48, 0x25, 0xff, 0xff, 0xff, 0x75, 0xaa, 0x0, + 0x52, 0x31, 0xff, 0xff, 0xf9, 0xf, 0x50, 0xd, + 0xf5, 0xff, 0xff, 0xad, 0xe6, 0xaa, 0x81, 0xff, + 0xff, 0xcb, 0xf8, 0x4, 0x0, 0x8, 0xd8, 0x73, + 0xff, 0xff, 0xff, 0x55, 0x19, 0xf1, 0xff, 0xff, + 0xb9, 0xfe, 0x2e, 0x0, 0x78, 0x45, 0xff, 0xff, + 0xff, 0x7d, 0xb0, 0x68, 0x3f, 0xff, 0xff, 0xff, + 0x8b, 0xca, 0x0, 0x0, 0xf8, 0xef, 0xfb, 0xfb, + 0xfb, 0xfb, 0xfb, 0xff, 0xff, 0xff, 0xf3, 0x2d, + 0x38, 0x0, 0x0, 0x0, 0xc2, 0x87, 0xff, 0xff, + 0xbd, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xfe, + 0xfb, 0xff, 0x2f, 0x2e, 0x0, 0x0, 0x0, 0x0, + 0xec, 0xcd, 0xff, 0xff, 0x73, 0xaa, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x48, 0xa6, 0xd0, 0xd0, + 0x9e, 0x42, 0x2, 0x0, 0x2, 0x18, 0x1a, 0x18, + 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xea, 0xc3, 0xff, 0xff, 0xf3, 0x49, 0xfe, + 0xfe, 0xa5, 0xff, 0xff, 0xff, 0x5d, 0x82, 0x0, + 0x0, 0x4, 0xf8, 0xcb, 0xff, 0xff, 0xef, 0x33, + 0xfc, 0x9, 0xaf, 0xff, 0xff, 0xff, 0x49, 0x54, + 0x0, 0x0, 0x0, 0xea, 0xc3, 0xff, 0xff, 0xff, + 0xbb, 0x77, 0x75, 0x1d, 0x30, 0x0, 0x0, 0xf8, + 0xe9, 0xff, 0xff, 0x8f, 0xfc, 0xea, 0x39, 0xff, + 0xff, 0xff, 0x7d, 0x5c, 0x0, 0x6a, 0xc4, 0xd, + 0xff, 0xff, 0xff, 0x83, 0xf4, 0xb8, 0x52, 0x0, + 0x0, 0xf4, 0xd3, 0xff, 0xff, 0xbb, 0xe2, 0x0, + 0x46, 0x3f, 0xff, 0xff, 0xff, 0x67, 0x80, 0x0, + 0x0, 0x10, 0xfc, 0xcd, 0xff, 0xff, 0xb5, 0xea, + 0x9c, 0x73, 0xff, 0xff, 0xf7, 0x19, 0x44, 0x0, + 0x12, 0xfe, 0xe3, 0xff, 0xff, 0x4d, 0xb8, 0x5f, + 0xff, 0xff, 0xff, 0xe7, 0xfe, 0xe2, 0xad, 0xff, + 0xff, 0x93, 0xc8, 0x0, 0x0, 0x0, 0x3e, 0xfe, + 0xc9, 0xff, 0xff, 0xc3, 0x8d, 0xff, 0xff, 0xf3, + 0x2d, 0x8a, 0x0, 0x0, 0x1e, 0xfe, 0xdb, 0xff, + 0xff, 0xbf, 0xf4, 0xc6, 0x8f, 0xff, 0xff, 0xfd, + 0x2d, 0x60, 0x0, 0x0, 0xd2, 0xfc, 0xfe, 0xfe, + 0xfe, 0xfe, 0x97, 0xff, 0xff, 0xff, 0x6d, 0xe4, + 0x10, 0x0, 0x26, 0x98, 0xfe, 0xbb, 0xff, 0xff, + 0x95, 0xb8, 0x0, 0x0, 0x0, 0x0, 0x0, 0xfe, + 0xfb, 0xff, 0x2f, 0x2e, 0x0, 0x0, 0x0, 0x0, + 0xce, 0xa7, 0xff, 0xff, 0xa9, 0xfc, 0x8c, 0x1e, + 0x0, 0x0, 0x0, 0x86, 0x9, 0x7d, 0xb7, 0xb1, + 0x77, 0xb, 0xbc, 0x1c, 0x26, 0xd, 0x39, 0xb, + 0xf2, 0x2e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xea, 0xc3, 0xff, 0xff, 0xcb, 0xfa, 0x20, + 0x74, 0x23, 0xfb, 0xff, 0xff, 0x9f, 0xc6, 0x0, + 0x0, 0x1e, 0xf, 0xfb, 0xff, 0xff, 0xa5, 0xec, + 0x14, 0xa6, 0x5f, 0xff, 0xff, 0xff, 0x49, 0x54, + 0x0, 0x0, 0x0, 0xea, 0xc3, 0xff, 0xff, 0xd9, + 0xfe, 0xba, 0x74, 0x46, 0x8, 0x0, 0x0, 0xf8, + 0xeb, 0xff, 0xff, 0xb3, 0x5, 0xea, 0xfe, 0x41, + 0x43, 0x43, 0x25, 0x50, 0x0, 0x0, 0x6, 0xd, + 0xff, 0xff, 0xff, 0x83, 0xa6, 0x0, 0x0, 0x0, + 0x0, 0xf4, 0xd3, 0xff, 0xff, 0xbb, 0xe2, 0x0, + 0x46, 0x3f, 0xff, 0xff, 0xff, 0x67, 0x80, 0x0, + 0x0, 0x0, 0xbc, 0x83, 0xff, 0xff, 0xe9, 0xfe, + 0xe6, 0xaf, 0xff, 0xff, 0xbd, 0xf6, 0x6, 0x0, + 0x0, 0xe6, 0xb1, 0xff, 0xff, 0x83, 0xf4, 0xa5, + 0xff, 0xff, 0xff, 0xff, 0x41, 0xfc, 0xd7, 0xff, + 0xff, 0x55, 0x76, 0x0, 0x0, 0x0, 0x0, 0xa2, + 0x3d, 0xf9, 0xff, 0xff, 0xf1, 0xff, 0xff, 0x89, + 0xe8, 0x10, 0x0, 0x0, 0x0, 0xd0, 0x91, 0xff, + 0xff, 0xf5, 0xd, 0xfc, 0xcf, 0xff, 0xff, 0xcb, + 0xfc, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, + 0xda, 0x5d, 0xfd, 0xff, 0xff, 0xa7, 0xfe, 0x3a, + 0x0, 0x0, 0x70, 0x51, 0xbb, 0xff, 0xff, 0xef, + 0x2d, 0x68, 0x0, 0x0, 0x0, 0x0, 0x0, 0xfe, + 0xfb, 0xff, 0x2f, 0x2e, 0x0, 0x0, 0x0, 0x0, + 0x7e, 0x3d, 0xf5, 0xff, 0xff, 0xb3, 0x45, 0x5a, + 0x0, 0x0, 0x30, 0xfe, 0xbb, 0xff, 0xff, 0xff, + 0xff, 0xdd, 0x43, 0xee, 0xca, 0x4f, 0xff, 0xfb, + 0x5b, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xea, 0xc3, 0xff, 0xff, 0xcb, 0xee, 0x0, + 0xc, 0xfc, 0xd7, 0xff, 0xff, 0xbf, 0xe4, 0x0, + 0x0, 0x40, 0x41, 0xff, 0xff, 0xff, 0x6f, 0xa2, + 0x0, 0x76, 0x5f, 0xff, 0xff, 0xff, 0x49, 0x54, + 0x0, 0x0, 0x0, 0xea, 0xc3, 0xff, 0xff, 0xcb, + 0xf2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe2, + 0xad, 0xff, 0xff, 0xff, 0xe7, 0xb1, 0x7b, 0x2d, + 0xfc, 0xac, 0x38, 0xc, 0x0, 0x0, 0x6, 0xd, + 0xff, 0xff, 0xff, 0x83, 0xa6, 0x0, 0x0, 0x0, + 0x0, 0xf4, 0xd3, 0xff, 0xff, 0xbb, 0xe2, 0x0, + 0x46, 0x3f, 0xff, 0xff, 0xff, 0x67, 0x80, 0x0, + 0x0, 0x0, 0x56, 0x27, 0xfb, 0xff, 0xff, 0x41, + 0xfe, 0xe3, 0xff, 0xff, 0x6f, 0xa4, 0x0, 0x0, + 0x0, 0xa2, 0x77, 0xff, 0xff, 0xb1, 0xfe, 0xdf, + 0xff, 0xd1, 0xff, 0xff, 0x8d, 0xf, 0xf9, 0xff, + 0xf5, 0xb, 0x28, 0x0, 0x0, 0x0, 0x0, 0x1a, + 0xf4, 0x9b, 0xff, 0xff, 0xff, 0xff, 0xd9, 0x9, + 0x52, 0x0, 0x0, 0x0, 0x0, 0x64, 0x31, 0xff, + 0xff, 0xff, 0x5f, 0x21, 0xfb, 0xff, 0xff, 0x7f, + 0xba, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa2, + 0x2d, 0xed, 0xff, 0xff, 0xd5, 0xf, 0x72, 0x0, + 0x0, 0x0, 0x9e, 0x8d, 0xff, 0xff, 0xeb, 0x43, + 0xea, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0xfe, + 0xfb, 0xff, 0x2f, 0x2e, 0x0, 0x0, 0x0, 0x0, + 0x1a, 0xf2, 0x4d, 0xed, 0xff, 0xff, 0x7b, 0x84, + 0x0, 0x0, 0x92, 0x5f, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xf5, 0x85, 0x4d, 0xcb, 0xff, 0xff, + 0x39, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xea, 0xc3, 0xff, 0xff, 0xcb, 0xee, 0x0, + 0x0, 0xf0, 0xc5, 0xff, 0xff, 0xcd, 0xec, 0x0, + 0x0, 0x58, 0x51, 0xff, 0xff, 0xff, 0x59, 0x7a, + 0x0, 0x76, 0x5f, 0xff, 0xff, 0xff, 0x49, 0x54, + 0x0, 0x0, 0x0, 0xea, 0xc3, 0xff, 0xff, 0xcb, + 0xee, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x78, + 0x19, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, + 0xbf, 0x33, 0xcc, 0x8, 0x0, 0x0, 0x6, 0xd, + 0xff, 0xff, 0xff, 0x83, 0xa6, 0x0, 0x0, 0x0, + 0x0, 0xf4, 0xd3, 0xff, 0xff, 0xbb, 0xe2, 0x0, + 0x46, 0x3f, 0xff, 0xff, 0xff, 0x67, 0x80, 0x0, + 0x0, 0x0, 0xc, 0xfa, 0xc9, 0xff, 0xff, 0x89, + 0x35, 0xff, 0xff, 0xf5, 0x13, 0x3e, 0x0, 0x0, + 0x0, 0x4e, 0x2d, 0xff, 0xff, 0xd9, 0x35, 0xff, + 0xff, 0x7d, 0xd5, 0xff, 0xcb, 0x4f, 0xff, 0xff, + 0xc7, 0xf6, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x94, 0x17, 0xf7, 0xff, 0xff, 0xff, 0x6b, 0xe4, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x12, 0xfc, 0xcf, + 0xff, 0xff, 0xa5, 0x75, 0xff, 0xff, 0xf9, 0x21, + 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, 0x64, 0x9, + 0xcd, 0xff, 0xff, 0xf3, 0x37, 0xb0, 0x4, 0x0, + 0x0, 0x0, 0x8c, 0x89, 0xff, 0xff, 0xff, 0xa7, + 0xfe, 0x34, 0x0, 0x0, 0x0, 0x0, 0x0, 0xfe, + 0xfb, 0xff, 0x2f, 0x2e, 0x0, 0x0, 0x0, 0x0, + 0x46, 0x5, 0xb5, 0xff, 0xff, 0xff, 0x77, 0x74, + 0x0, 0x0, 0xc4, 0xaf, 0xff, 0xf9, 0x5d, 0x41, + 0xb3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xd3, + 0xfe, 0x16, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xea, 0xc3, 0xff, 0xff, 0xcb, 0xee, 0x0, + 0x0, 0xf4, 0xcb, 0xff, 0xff, 0xcb, 0xec, 0x0, + 0x0, 0x52, 0x4f, 0xff, 0xff, 0xff, 0x5d, 0x82, + 0x0, 0x76, 0x5f, 0xff, 0xff, 0xff, 0x49, 0x54, + 0x0, 0x0, 0x0, 0xea, 0xc3, 0xff, 0xff, 0xcb, + 0xee, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, + 0x92, 0xfe, 0x4d, 0xa3, 0xd9, 0xff, 0xff, 0xff, + 0xff, 0xe9, 0x1f, 0x4c, 0x0, 0x0, 0x6, 0xd, + 0xff, 0xff, 0xff, 0x83, 0xa6, 0x0, 0x0, 0x0, + 0x0, 0xf2, 0xd3, 0xff, 0xff, 0xbb, 0xe6, 0x0, + 0x46, 0x3f, 0xff, 0xff, 0xff, 0x67, 0x80, 0x0, + 0x0, 0x0, 0x0, 0xb6, 0x7d, 0xff, 0xff, 0xc3, + 0x7f, 0xff, 0xff, 0xb9, 0xf2, 0x4, 0x0, 0x0, + 0x0, 0x10, 0xfe, 0xe1, 0xff, 0xfb, 0x8b, 0xff, + 0xff, 0x29, 0x95, 0xff, 0xfb, 0x8d, 0xff, 0xff, + 0x8f, 0xc2, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, + 0xe6, 0x83, 0xff, 0xff, 0xff, 0xff, 0xc5, 0xfe, + 0x3c, 0x0, 0x0, 0x0, 0x0, 0x0, 0xbe, 0x81, + 0xff, 0xff, 0xe1, 0xb9, 0xff, 0xff, 0xbf, 0xf8, + 0xa, 0x0, 0x0, 0x0, 0x0, 0x30, 0xfa, 0x9b, + 0xff, 0xff, 0xff, 0x6d, 0xe4, 0x16, 0x0, 0x0, + 0x0, 0x0, 0x52, 0xfe, 0x43, 0xeb, 0xff, 0xff, + 0x67, 0x94, 0x0, 0x0, 0x0, 0x0, 0x0, 0xfe, + 0xfb, 0xff, 0x2f, 0x2e, 0x0, 0x0, 0x0, 0x0, + 0xac, 0x7b, 0xff, 0xff, 0xdf, 0x37, 0xfe, 0x42, + 0x0, 0x0, 0xb6, 0xab, 0xef, 0xc1, 0xf8, 0x9e, + 0xfe, 0x7d, 0xf7, 0xff, 0xff, 0xff, 0xef, 0x43, + 0xae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xea, 0xc3, 0xff, 0xff, 0xcb, 0xf2, 0x0, + 0x2a, 0xfe, 0xe3, 0xff, 0xff, 0xb7, 0xde, 0x0, + 0x0, 0x34, 0x33, 0xff, 0xff, 0xff, 0x7d, 0xc4, + 0x0, 0x82, 0x5f, 0xff, 0xff, 0xff, 0x49, 0x54, + 0x0, 0x0, 0x0, 0xea, 0xc3, 0xff, 0xff, 0xcb, + 0xee, 0x0, 0x0, 0x0, 0x0, 0x0, 0x32, 0x9, + 0x15, 0x15, 0x13, 0xfc, 0xfe, 0x27, 0x9f, 0xff, + 0xff, 0xff, 0x7b, 0x8c, 0x0, 0x0, 0x4, 0xd, + 0xff, 0xff, 0xff, 0x83, 0xac, 0x0, 0x0, 0x0, + 0x0, 0xee, 0xcf, 0xff, 0xff, 0xc3, 0xf2, 0x0, + 0x56, 0x3f, 0xff, 0xff, 0xff, 0x67, 0x80, 0x0, + 0x0, 0x0, 0x0, 0x50, 0x21, 0xfb, 0xff, 0xf3, + 0xb7, 0xff, 0xff, 0x6b, 0xa0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xe2, 0xad, 0xff, 0xff, 0xe9, 0xff, + 0xd3, 0xfe, 0x47, 0xff, 0xff, 0xe9, 0xff, 0xff, + 0x4f, 0x6e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x88, + 0x29, 0xf3, 0xff, 0xff, 0xfb, 0xff, 0xff, 0x71, + 0xd8, 0x8, 0x0, 0x0, 0x0, 0x0, 0x54, 0x23, + 0xfb, 0xff, 0xff, 0xf3, 0xff, 0xff, 0x71, 0xa8, + 0x0, 0x0, 0x0, 0x0, 0x10, 0xdc, 0x61, 0xff, + 0xff, 0xff, 0xa7, 0xfc, 0x3a, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1c, 0xea, 0x99, 0xff, 0xff, + 0xb1, 0xd2, 0x0, 0x0, 0x0, 0x0, 0x0, 0xfe, + 0xfb, 0xff, 0x2f, 0x2e, 0x0, 0x0, 0x0, 0x0, + 0xe2, 0xc1, 0xff, 0xff, 0x85, 0xdc, 0x16, 0x0, + 0x0, 0x0, 0x74, 0xe6, 0xf4, 0x9, 0x8c, 0x0, + 0x48, 0xea, 0x2b, 0x87, 0xa3, 0x8d, 0x29, 0xda, + 0x1c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xea, 0xc3, 0xff, 0xff, 0xdb, 0x5, 0xd8, + 0xf2, 0x59, 0xff, 0xff, 0xff, 0x8b, 0xb0, 0x0, + 0x0, 0x14, 0xfe, 0xef, 0xff, 0xff, 0xcb, 0x5, + 0xd6, 0xf8, 0x77, 0xff, 0xff, 0xff, 0x49, 0x54, + 0x0, 0x0, 0x0, 0xea, 0xc3, 0xff, 0xff, 0xcb, + 0xee, 0x0, 0x0, 0x0, 0x0, 0x0, 0x38, 0x63, + 0xff, 0xff, 0xfb, 0x17, 0xae, 0xb4, 0xfe, 0xeb, + 0xff, 0xff, 0x91, 0xa0, 0x0, 0x0, 0x2, 0x5, + 0xff, 0xff, 0xff, 0x8d, 0xf2, 0x80, 0x30, 0x0, + 0x0, 0xe0, 0xbb, 0xff, 0xff, 0xe9, 0x9, 0xda, + 0xf6, 0x5b, 0xff, 0xff, 0xff, 0x67, 0x80, 0x0, + 0x0, 0x0, 0x0, 0xa, 0xfa, 0xc5, 0xff, 0xff, + 0xf3, 0xff, 0xf3, 0xf, 0x3a, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x9c, 0x73, 0xff, 0xff, 0xff, 0xff, + 0x93, 0xd2, 0xfe, 0xe7, 0xff, 0xff, 0xff, 0xf3, + 0x9, 0x24, 0x0, 0x0, 0x0, 0x0, 0x2e, 0xfe, + 0xb7, 0xff, 0xff, 0xdd, 0x99, 0xff, 0xff, 0xeb, + 0x1d, 0x74, 0x0, 0x0, 0x0, 0x0, 0xc, 0xf8, + 0xc1, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x13, 0x40, + 0x0, 0x0, 0x0, 0x2, 0xa6, 0x2f, 0xef, 0xff, + 0xff, 0xd5, 0xf, 0xee, 0xe0, 0xe0, 0xcc, 0x9a, + 0x32, 0x0, 0x0, 0x0, 0xac, 0x7d, 0xff, 0xff, + 0xc5, 0xe6, 0x0, 0x0, 0x0, 0x0, 0x0, 0xfe, + 0xfb, 0xff, 0x2f, 0x2e, 0x0, 0x0, 0x0, 0x0, + 0xf2, 0xd5, 0xff, 0xff, 0x69, 0x92, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xe, 0x5a, 0x9e, 0xba, 0xa2, 0x5e, 0xe, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xea, 0xc3, 0xff, 0xff, 0xff, 0xcf, 0x8b, + 0x9f, 0xf1, 0xff, 0xff, 0xfb, 0x2f, 0x5e, 0x0, + 0x0, 0x0, 0xe6, 0xa7, 0xff, 0xff, 0xff, 0xc7, + 0x8d, 0xa5, 0xf7, 0xff, 0xff, 0xff, 0x49, 0x54, + 0x0, 0x0, 0x0, 0xea, 0xc3, 0xff, 0xff, 0xcb, + 0xee, 0x0, 0x0, 0x0, 0x0, 0x0, 0x38, 0x19, + 0xf3, 0xff, 0xff, 0xc1, 0x51, 0x3f, 0x8b, 0xff, + 0xff, 0xff, 0x67, 0x7c, 0x0, 0x0, 0x0, 0xfe, + 0xeb, 0xff, 0xff, 0xe9, 0x99, 0x5f, 0x8c, 0x0, + 0x0, 0xb2, 0x89, 0xff, 0xff, 0xff, 0xcb, 0x91, + 0xa9, 0xf5, 0xff, 0xff, 0xff, 0x67, 0x80, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xb2, 0x79, 0xff, 0xff, + 0xff, 0xff, 0xb5, 0xf0, 0x4, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x4a, 0x29, 0xff, 0xff, 0xff, 0xff, + 0x45, 0x70, 0xe4, 0xab, 0xff, 0xff, 0xff, 0xc3, + 0xf4, 0x0, 0x0, 0x0, 0x0, 0x4, 0xc6, 0x5d, + 0xff, 0xff, 0xff, 0x73, 0x21, 0xf3, 0xff, 0xff, + 0xa7, 0xf8, 0x22, 0x0, 0x0, 0x0, 0x0, 0xaa, + 0x71, 0xff, 0xff, 0xff, 0xff, 0xb5, 0xf0, 0x4, + 0x0, 0x0, 0x0, 0x18, 0xb, 0xcf, 0xff, 0xff, + 0xff, 0xcd, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0x63, + 0x74, 0x0, 0x0, 0x0, 0x9e, 0x7b, 0xff, 0xff, + 0xc7, 0xec, 0x0, 0x0, 0x0, 0x0, 0x0, 0xfe, + 0xfb, 0xff, 0x2f, 0x2e, 0x0, 0x0, 0x0, 0x0, + 0xf6, 0xd7, 0xff, 0xff, 0x67, 0x82, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xea, 0xc3, 0xff, 0xff, 0xfb, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x95, 0xf4, 0x10, 0x0, + 0x0, 0x0, 0x76, 0x27, 0xeb, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0x49, 0x54, + 0x0, 0x0, 0x0, 0xea, 0xc3, 0xff, 0xff, 0xcb, + 0xee, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0xe4, + 0x73, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xc7, 0x5, 0x34, 0x0, 0x0, 0x0, 0xe4, + 0xad, 0xff, 0xff, 0xff, 0xff, 0xa9, 0xc8, 0x0, + 0x0, 0x5a, 0x25, 0xef, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xe7, 0xf7, 0xff, 0xff, 0x67, 0x80, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x4a, 0x1d, 0xf9, 0xff, + 0xff, 0xff, 0x65, 0x9a, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xe, 0xfe, 0xdd, 0xff, 0xff, 0xe5, + 0xfe, 0x1e, 0x90, 0x63, 0xff, 0xff, 0xff, 0x8b, + 0xbc, 0x0, 0x0, 0x0, 0x0, 0x60, 0xf, 0xe1, + 0xff, 0xff, 0xdf, 0x5, 0xf0, 0x9d, 0xff, 0xff, + 0xfd, 0x4b, 0xb2, 0x0, 0x0, 0x0, 0x0, 0x40, + 0x13, 0xf5, 0xff, 0xff, 0xff, 0x63, 0x98, 0x0, + 0x0, 0x0, 0x0, 0x2c, 0x39, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x89, + 0xa0, 0x0, 0x0, 0x0, 0x92, 0x7b, 0xff, 0xff, + 0xc7, 0xee, 0x0, 0x0, 0x0, 0x0, 0x0, 0xfe, + 0xfb, 0xff, 0x2f, 0x2e, 0x0, 0x0, 0x0, 0x0, + 0xf8, 0xd7, 0xff, 0xff, 0x65, 0x74, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xea, 0xc3, 0xff, 0xff, 0xcb, 0x9f, 0xfb, + 0xff, 0xff, 0xf3, 0x8f, 0xfe, 0x5e, 0x0, 0x0, + 0x0, 0x0, 0xc, 0xd0, 0x3d, 0xcd, 0xff, 0xff, + 0xff, 0xdd, 0x87, 0xff, 0xff, 0xff, 0x49, 0x54, + 0x0, 0x0, 0x0, 0xce, 0xc3, 0xff, 0xff, 0xcb, + 0xd6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, + 0xfa, 0x5d, 0xd5, 0xff, 0xff, 0xff, 0xff, 0xed, + 0x99, 0x11, 0x96, 0x0, 0x0, 0x0, 0x0, 0x7a, + 0x21, 0xbd, 0xff, 0xff, 0xff, 0xb9, 0xba, 0x0, + 0x0, 0xc, 0xd8, 0x4b, 0xdb, 0xff, 0xff, 0xff, + 0xcf, 0x39, 0xdb, 0xff, 0xff, 0x67, 0x60, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x8, 0xf4, 0xc1, 0xff, + 0xff, 0xf1, 0xd, 0x36, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xd6, 0xa9, 0xff, 0xff, 0xa7, + 0xdc, 0x0, 0x36, 0xf, 0xf5, 0xff, 0xff, 0x49, + 0x68, 0x0, 0x0, 0x0, 0x0, 0x60, 0x95, 0xff, + 0xff, 0xff, 0x77, 0xc8, 0x6c, 0x25, 0xf5, 0xff, + 0xff, 0xd5, 0x7, 0x0, 0x0, 0x0, 0x0, 0x4, + 0xf6, 0xb3, 0xff, 0xff, 0xed, 0x9, 0x32, 0x0, + 0x0, 0x0, 0x0, 0x2a, 0x39, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x89, + 0x8a, 0x0, 0x0, 0x0, 0x78, 0x65, 0xff, 0xff, + 0xd1, 0xf8, 0x0, 0x0, 0x0, 0x0, 0x0, 0xfe, + 0xfb, 0xff, 0x2f, 0x2e, 0x0, 0x0, 0x0, 0x8, + 0xfc, 0xe3, 0xff, 0xff, 0x4d, 0x56, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xea, 0xc3, 0xff, 0xff, 0xcb, 0xfe, 0x21, + 0x51, 0x49, 0xf, 0xe8, 0x58, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x18, 0xa4, 0xfc, 0x2d, 0x53, + 0x3f, 0xfe, 0x5f, 0xff, 0xff, 0xff, 0x49, 0x54, + 0x0, 0x0, 0x0, 0x90, 0xfe, 0xfe, 0xfe, 0xfe, + 0x98, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2e, 0xb6, 0xfe, 0x25, 0x4f, 0x55, 0x39, 0xfe, + 0xe2, 0x64, 0x4, 0x0, 0x0, 0x0, 0x0, 0xa, + 0x8e, 0xfe, 0x25, 0x51, 0x43, 0x5, 0x84, 0x0, + 0x0, 0x0, 0x22, 0xbc, 0xfe, 0x39, 0x55, 0x33, + 0xfe, 0xe4, 0xfe, 0xfe, 0xfe, 0xfe, 0x36, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x8c, 0xfe, 0xfe, + 0xfe, 0xfe, 0xd6, 0x2, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x72, 0xfe, 0xfe, 0xfe, 0xfe, + 0x70, 0x0, 0x4, 0xde, 0xfe, 0xfe, 0xfe, 0xfe, + 0x20, 0x0, 0x0, 0x0, 0x0, 0x5e, 0xfe, 0xfe, + 0xfe, 0xfe, 0xfe, 0x42, 0xc, 0xe0, 0xfe, 0xfe, + 0xfe, 0xfe, 0xa8, 0x0, 0x0, 0x0, 0x0, 0x1a, + 0xfc, 0xbb, 0xff, 0xff, 0xa7, 0xe8, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x16, 0xfe, 0xfe, 0xfe, 0xfe, + 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, + 0x52, 0x0, 0x0, 0x0, 0x46, 0x39, 0xff, 0xff, + 0xf1, 0x9, 0x4e, 0x0, 0x0, 0x0, 0x0, 0xfe, + 0xfb, 0xff, 0x2f, 0x2e, 0x0, 0x0, 0x0, 0x66, + 0x1b, 0xfb, 0xff, 0xfd, 0x1f, 0x2a, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xea, 0xc3, 0xff, 0xff, 0xcb, 0xee, 0x2e, + 0x48, 0x44, 0x22, 0x4, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x34, 0x48, + 0x3c, 0x84, 0x5f, 0xff, 0xff, 0xff, 0x49, 0x54, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xc, 0x2e, 0x4e, 0x56, 0x3a, 0x16, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc, 0x30, 0x46, 0x3e, 0x1c, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x16, 0x3a, 0x48, 0x38, + 0x14, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, 0xa0, 0xee, + 0x3d, 0xfb, 0xff, 0xff, 0x51, 0x86, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x16, 0xfe, 0xcd, 0xff, + 0xff, 0x83, 0xfc, 0x40, 0x0, 0x0, 0x0, 0xfe, + 0xfb, 0xff, 0x2f, 0x2e, 0x0, 0x0, 0x50, 0xfe, + 0x99, 0xff, 0xff, 0xbb, 0xfa, 0x8, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xea, 0xc3, 0xff, 0xff, 0xcb, 0xee, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x76, 0x5f, 0xff, 0xff, 0xff, 0x49, 0x54, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xa8, 0x73, 0xb5, + 0xef, 0xff, 0xff, 0xd5, 0xfe, 0x26, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xaa, 0x4d, 0xf7, + 0xff, 0xff, 0x73, 0x50, 0x0, 0x0, 0x0, 0xfe, + 0xfb, 0xff, 0x2f, 0x22, 0x0, 0x0, 0x68, 0x87, + 0xff, 0xff, 0xef, 0x3b, 0x90, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xe6, 0xc3, 0xff, 0xff, 0xcb, 0xea, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x72, 0x5f, 0xff, 0xff, 0xff, 0x49, 0x50, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xe2, 0xc1, 0xff, + 0xff, 0xff, 0xfb, 0x55, 0xb6, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x24, 0xe8, 0x41, + 0xc7, 0xfd, 0x37, 0x50, 0x0, 0x0, 0x0, 0xee, + 0x47, 0x49, 0xd, 0x12, 0x0, 0x0, 0x68, 0x4f, + 0xfd, 0xbd, 0x35, 0xda, 0x18, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc6, 0xb1, 0xe9, 0xe9, 0xb7, 0xcc, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x52, 0x57, 0xe9, 0xe9, 0xe9, 0x41, 0x38, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xd8, 0xd7, 0xff, + 0xff, 0xdf, 0x63, 0xf2, 0x28, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1c, 0x9e, + 0xfa, 0x29, 0xf6, 0x16, 0x0, 0x0, 0x0, 0x1e, + 0x3a, 0x3c, 0x22, 0x2, 0x0, 0x0, 0x24, 0xf4, + 0x29, 0xfa, 0x92, 0x14, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x7c, 0xe2, 0xf8, 0xf8, 0xe4, 0x82, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2a, 0xd0, 0xf4, 0xfc, 0xf4, 0xcc, 0x1c, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xaa, 0x9, 0x2f, + 0x17, 0xfe, 0xc6, 0x32, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xe, 0xe, 0xe, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, + 0xe, 0xe, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x16, + 0x16, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +}; +const uint16_t FontBitmap::glyphWidth[] = { + 8, 9, 10, 16, 16, 20, 18, 6, + 10, 10, 13, 15, 8, 11, 9, 11, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 9, 9, 14, 16, 14, 14, + 23, 17, 17, 17, 18, 16, 16, 18, + 19, 9, 16, 18, 15, 23, 19, 19, + 18, 19, 18, 17, 17, 18, 17, 23, + 17, 17, 16, 9, 12, 9, 13, 13, + 10, 15, 16, 14, 16, 15, 11, 16, + 16, 8, 8, 15, 8, 23, 16, 16, + 16, 16, 11, 14, 10, 16, 14, 20, + 14, 14, 14, 10, 8, 10, 18, +}; +const uint16_t FontBitmap::yoffset[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, + 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 136, + 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, + 170, 170, 170, 170, 170, 170, 170, 170, + 170, 170, 170, 170, 170, 170, 170, +}; diff --git a/cmds/screenrecord/Overlay.cpp b/cmds/screenrecord/Overlay.cpp new file mode 100644 index 0000000..2e98874 --- /dev/null +++ b/cmds/screenrecord/Overlay.cpp @@ -0,0 +1,401 @@ +/* + * Copyright 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "ScreenRecord" +//#define LOG_NDEBUG 0 +#include <utils/Log.h> + +#include <gui/BufferQueue.h> +#include <gui/GraphicBufferAlloc.h> +#include <gui/Surface.h> +#include <cutils/properties.h> +#include <utils/misc.h> + +#include <GLES2/gl2.h> +#include <GLES2/gl2ext.h> + +#include <stdlib.h> +#include <assert.h> + +#include "screenrecord.h" +#include "Overlay.h" +#include "TextRenderer.h" + +using namespace android; + +// System properties to look up and display on the info screen. +const char* Overlay::kPropertyNames[] = { + "ro.build.description", + // includes ro.build.id, ro.build.product, ro.build.tags, ro.build.type, + // and ro.build.version.release + "ro.product.manufacturer", + "ro.product.model", + "ro.board.platform", + "ro.revision", + "dalvik.vm.heapgrowthlimit", + "dalvik.vm.heapsize", + "persist.sys.dalvik.vm.lib.1", + //"ro.product.cpu.abi", + //"ro.bootloader", + //"this-never-appears!", +}; + + +status_t Overlay::start(const sp<IGraphicBufferProducer>& outputSurface, + sp<IGraphicBufferProducer>* pBufferProducer) { + ALOGV("Overlay::start"); + mOutputSurface = outputSurface; + + // Grab the current monotonic time and the current wall-clock time so we + // can map one to the other. This allows the overlay counter to advance + // by the exact delay between frames, but if the wall clock gets adjusted + // we won't track it, which means we'll gradually go out of sync with the + // times in logcat. + mStartMonotonicNsecs = systemTime(CLOCK_MONOTONIC); + mStartRealtimeNsecs = systemTime(CLOCK_REALTIME); + + Mutex::Autolock _l(mMutex); + + // Start the thread. Traffic begins immediately. + run("overlay"); + + mState = INIT; + while (mState == INIT) { + mStartCond.wait(mMutex); + } + + if (mThreadResult != NO_ERROR) { + ALOGE("Failed to start overlay thread: err=%d", mThreadResult); + return mThreadResult; + } + assert(mState == RUNNING); + + ALOGV("Overlay::start successful"); + *pBufferProducer = mBufferQueue; + return NO_ERROR; +} + +status_t Overlay::stop() { + ALOGV("Overlay::stop"); + Mutex::Autolock _l(mMutex); + mState = STOPPING; + mEventCond.signal(); + return NO_ERROR; +} + +bool Overlay::threadLoop() { + Mutex::Autolock _l(mMutex); + + mThreadResult = setup_l(); + + if (mThreadResult != NO_ERROR) { + ALOGW("Aborting overlay thread"); + mState = STOPPED; + release_l(); + mStartCond.broadcast(); + return false; + } + + ALOGV("Overlay thread running"); + mState = RUNNING; + mStartCond.broadcast(); + + while (mState == RUNNING) { + mEventCond.wait(mMutex); + if (mFrameAvailable) { + ALOGV("Awake, frame available"); + processFrame_l(); + mFrameAvailable = false; + } else { + ALOGV("Awake, frame not available"); + } + } + + ALOGV("Overlay thread stopping"); + release_l(); + mState = STOPPED; + return false; // stop +} + +status_t Overlay::setup_l() { + status_t err; + + err = mEglWindow.createWindow(mOutputSurface); + if (err != NO_ERROR) { + return err; + } + mEglWindow.makeCurrent(); + + int width = mEglWindow.getWidth(); + int height = mEglWindow.getHeight(); + + glViewport(0, 0, width, height); + glDisable(GL_DEPTH_TEST); + glDisable(GL_CULL_FACE); + + // Shaders for rendering from different types of textures. + err = mTexProgram.setup(Program::PROGRAM_TEXTURE_2D); + if (err != NO_ERROR) { + return err; + } + err = mExtTexProgram.setup(Program::PROGRAM_EXTERNAL_TEXTURE); + if (err != NO_ERROR) { + return err; + } + + err = mTextRenderer.loadIntoTexture(); + if (err != NO_ERROR) { + return err; + } + mTextRenderer.setScreenSize(width, height); + + // Input side (buffers from virtual display). + glGenTextures(1, &mExtTextureName); + if (mExtTextureName == 0) { + ALOGE("glGenTextures failed: %#x", glGetError()); + return UNKNOWN_ERROR; + } + + mBufferQueue = new BufferQueue(/*new GraphicBufferAlloc()*/); + mGlConsumer = new GLConsumer(mBufferQueue, mExtTextureName, + GL_TEXTURE_EXTERNAL_OES); + mGlConsumer->setName(String8("virtual display")); + mGlConsumer->setDefaultBufferSize(width, height); + mGlConsumer->setDefaultMaxBufferCount(5); + mGlConsumer->setConsumerUsageBits(GRALLOC_USAGE_HW_TEXTURE); + + mGlConsumer->setFrameAvailableListener(this); + + return NO_ERROR; +} + + +void Overlay::release_l() { + ALOGV("Overlay::release_l"); + mOutputSurface.clear(); + mGlConsumer.clear(); + mBufferQueue.clear(); + + mTexProgram.release(); + mExtTexProgram.release(); + mEglWindow.release(); +} + +void Overlay::processFrame_l() { + float texMatrix[16]; + + mGlConsumer->updateTexImage(); + mGlConsumer->getTransformMatrix(texMatrix); + nsecs_t monotonicNsec = mGlConsumer->getTimestamp(); + nsecs_t frameNumber = mGlConsumer->getFrameNumber(); + int64_t droppedFrames = 0; + + if (mLastFrameNumber > 0) { + mTotalDroppedFrames += size_t(frameNumber - mLastFrameNumber) - 1; + } + mLastFrameNumber = frameNumber; + + mTextRenderer.setProportionalScale(35); + + if (false) { // DEBUG - full blue background + glClearColor(0.0f, 0.0f, 1.0f, 1.0f); + glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); + } + + int width = mEglWindow.getWidth(); + int height = mEglWindow.getHeight(); + if (false) { // DEBUG - draw inset + mExtTexProgram.blit(mExtTextureName, texMatrix, + 100, 100, width-200, height-200); + } else { + mExtTexProgram.blit(mExtTextureName, texMatrix, + 0, 0, width, height); + } + + glEnable(GL_BLEND); + glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + if (false) { // DEBUG - show entire font bitmap + mTexProgram.blit(mTextRenderer.getTextureName(), Program::kIdentity, + 100, 100, width-200, height-200); + } + + char textBuf[64]; + getTimeString_l(monotonicNsec, textBuf, sizeof(textBuf)); + String8 timeStr(String8::format("%s f=%lld (%zd)", + textBuf, frameNumber, mTotalDroppedFrames)); + mTextRenderer.drawString(mTexProgram, Program::kIdentity, 0, 0, timeStr); + + glDisable(GL_BLEND); + + if (false) { // DEBUG - add red rectangle in lower-left corner + glEnable(GL_SCISSOR_TEST); + glScissor(0, 0, 200, 200); + glClearColor(1.0f, 0.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + glDisable(GL_SCISSOR_TEST); + } + + mEglWindow.presentationTime(monotonicNsec); + mEglWindow.swapBuffers(); +} + +void Overlay::getTimeString_l(nsecs_t monotonicNsec, char* buf, size_t bufLen) { + //const char* format = "%m-%d %T"; // matches log output + const char* format = "%T"; + struct tm tm; + + // localtime/strftime is not the fastest way to do this, but a trivial + // benchmark suggests that the cost is negligible. + int64_t realTime = mStartRealtimeNsecs + + (monotonicNsec - mStartMonotonicNsecs); + time_t secs = (time_t) (realTime / 1000000000); + localtime_r(&secs, &tm); + strftime(buf, bufLen, format, &tm); + + int32_t msec = (int32_t) ((realTime % 1000000000) / 1000000); + char tmpBuf[5]; + snprintf(tmpBuf, sizeof(tmpBuf), ".%03d", msec); + strlcat(buf, tmpBuf, bufLen); +} + +// Callback; executes on arbitrary thread. +void Overlay::onFrameAvailable() { + ALOGV("Overlay::onFrameAvailable"); + Mutex::Autolock _l(mMutex); + mFrameAvailable = true; + mEventCond.signal(); +} + + +/*static*/ status_t Overlay::drawInfoPage( + const sp<IGraphicBufferProducer>& outputSurface) { + status_t err; + + EglWindow window; + err = window.createWindow(outputSurface); + if (err != NO_ERROR) { + return err; + } + window.makeCurrent(); + + int width = window.getWidth(); + int height = window.getHeight(); + glViewport(0, 0, width, height); + glDisable(GL_DEPTH_TEST); + glDisable(GL_CULL_FACE); + + // Shaders for rendering. + Program texProgram; + err = texProgram.setup(Program::PROGRAM_TEXTURE_2D); + if (err != NO_ERROR) { + return err; + } + TextRenderer textRenderer; + err = textRenderer.loadIntoTexture(); + if (err != NO_ERROR) { + return err; + } + textRenderer.setScreenSize(width, height); + + doDrawInfoPage(window, texProgram, textRenderer); + + // Destroy the surface. This causes a disconnect. + texProgram.release(); + window.release(); + + return NO_ERROR; +} + +/*static*/ void Overlay::doDrawInfoPage(const EglWindow& window, + const Program& texProgram, TextRenderer& textRenderer) { + const nsecs_t holdTime = 250000000LL; + + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + + int width = window.getWidth(); + int height = window.getHeight(); + + // Draw a thin border around the screen. Some players, e.g. browser + // plugins, make it hard to see where the edges are when the device + // is using a black background, so this gives the viewer a frame of + // reference. + // + // This is a clumsy way to do it, but we're only doing it for one frame, + // and it's easier than actually drawing lines. + const int lineWidth = 4; + glEnable(GL_SCISSOR_TEST); + glClearColor(0.5f, 0.5f, 0.5f, 1.0f); + glScissor(0, 0, width, lineWidth); + glClear(GL_COLOR_BUFFER_BIT); + glScissor(0, height - lineWidth, width, lineWidth); + glClear(GL_COLOR_BUFFER_BIT); + glScissor(0, 0, lineWidth, height); + glClear(GL_COLOR_BUFFER_BIT); + glScissor(width - lineWidth, 0, lineWidth, height); + glClear(GL_COLOR_BUFFER_BIT); + glDisable(GL_SCISSOR_TEST); + + //glEnable(GL_BLEND); + //glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + textRenderer.setProportionalScale(30); + + float xpos = 0; + float ypos = 0; + ypos = textRenderer.drawWrappedString(texProgram, xpos, ypos, + String8::format("Android screenrecord v%d.%d", + kVersionMajor, kVersionMinor)); + + // Show date/time + time_t now = time(0); + struct tm tm; + localtime_r(&now, &tm); + char timeBuf[64]; + strftime(timeBuf, sizeof(timeBuf), "%a, %d %b %Y %T %z", &tm); + String8 header("Started "); + header += timeBuf; + ypos = textRenderer.drawWrappedString(texProgram, xpos, ypos, header); + ypos += 8 * textRenderer.getScale(); // slight padding + + // Show selected system property values + for (int i = 0; i < NELEM(kPropertyNames); i++) { + char valueBuf[PROPERTY_VALUE_MAX]; + + property_get(kPropertyNames[i], valueBuf, ""); + if (valueBuf[0] == '\0') { + continue; + } + String8 str(String8::format("%s: [%s]", kPropertyNames[i], valueBuf)); + ypos = textRenderer.drawWrappedString(texProgram, xpos, ypos, str); + } + ypos += 8 * textRenderer.getScale(); // slight padding + + // Show GL info + String8 glStr("OpenGL: "); + glStr += (char*) glGetString(GL_VENDOR); + glStr += " / "; + glStr += (char*) glGetString(GL_RENDERER); + glStr += ", "; + glStr += (char*) glGetString(GL_VERSION); + ypos = textRenderer.drawWrappedString(texProgram, xpos, ypos, glStr); + + //glDisable(GL_BLEND); + + // Set a presentation time slightly in the past. This will cause the + // player to hold the frame on screen. + window.presentationTime(systemTime(CLOCK_MONOTONIC) - holdTime); + window.swapBuffers(); +} diff --git a/cmds/screenrecord/Overlay.h b/cmds/screenrecord/Overlay.h new file mode 100644 index 0000000..b8473b4 --- /dev/null +++ b/cmds/screenrecord/Overlay.h @@ -0,0 +1,157 @@ +/* + * Copyright 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SCREENRECORD_OVERLAY_H +#define SCREENRECORD_OVERLAY_H + +#include "Program.h" +#include "TextRenderer.h" +#include "EglWindow.h" + +#include <gui/BufferQueue.h> +#include <gui/GLConsumer.h> +#include <utils/Thread.h> + +#include <EGL/egl.h> + +namespace android { + +/* + * Overlay "filter". This sits between the virtual display and the video + * encoder. + * + * Most functions run on a thread created by start(). + */ +class Overlay : public GLConsumer::FrameAvailableListener, Thread { +public: + Overlay() : Thread(false), + mThreadResult(UNKNOWN_ERROR), + mState(UNINITIALIZED), + mFrameAvailable(false), + mExtTextureName(0), + mStartMonotonicNsecs(0), + mStartRealtimeNsecs(0), + mLastFrameNumber(-1), + mTotalDroppedFrames(0) + {} + virtual ~Overlay() { assert(mState == UNINITIALIZED || mState == STOPPED); } + + // Creates a thread that performs the overlay. Pass in the surface that + // output will be sent to. + // + // This creates a dedicated thread for processing frames. + // + // Returns a reference to the producer side of a new BufferQueue that will + // be used by the virtual display. + status_t start(const sp<IGraphicBufferProducer>& outputSurface, + sp<IGraphicBufferProducer>* pBufferProducer); + + // Stops the thread and releases resources. It's okay to call this even + // if start() was never called. + status_t stop(); + + // This creates an EGL context and window surface, draws some informative + // text on it, swaps the buffer, and then tears the whole thing down. + static status_t drawInfoPage(const sp<IGraphicBufferProducer>& outputSurface); + +private: + Overlay(const Overlay&); + Overlay& operator=(const Overlay&); + + // Draw the initial info screen. + static void doDrawInfoPage(const EglWindow& window, + const Program& texRender, TextRenderer& textRenderer); + + // (overrides GLConsumer::FrameAvailableListener method) + virtual void onFrameAvailable(); + + // (overrides Thread method) + virtual bool threadLoop(); + + // One-time setup (essentially object construction on the overlay thread). + status_t setup_l(); + + // Release all resources held. + void release_l(); + + // Release EGL display, context, surface. + void eglRelease_l(); + + // Process a frame received from the virtual display. + void processFrame_l(); + + // Convert a monotonic time stamp into a string with the current time. + void getTimeString_l(nsecs_t monotonicNsec, char* buf, size_t bufLen); + + // Guards all fields below. + Mutex mMutex; + + // Initialization gate. + Condition mStartCond; + + // Thread status, mostly useful during startup. + status_t mThreadResult; + + // Overlay thread state. States advance from left to right; object may + // not be restarted. + enum { UNINITIALIZED, INIT, RUNNING, STOPPING, STOPPED } mState; + + // Event notification. Overlay thread sleeps on this until a frame + // arrives or it's time to shut down. + Condition mEventCond; + + // Set by the FrameAvailableListener callback. + bool mFrameAvailable; + + // The surface we send our output to, i.e. the video encoder's input + // surface. + sp<IGraphicBufferProducer> mOutputSurface; + + // Our queue. The producer side is passed to the virtual display, the + // consumer side feeds into our GLConsumer. + sp<BufferQueue> mBufferQueue; + + // This receives frames from the virtual display and makes them available + // as an external texture. + sp<GLConsumer> mGlConsumer; + + // EGL display / context / surface. + EglWindow mEglWindow; + + // GL rendering support. + Program mExtTexProgram; + Program mTexProgram; + + // Text rendering. + TextRenderer mTextRenderer; + + // External texture, updated by GLConsumer. + GLuint mExtTextureName; + + // Start time, used to map monotonic to wall-clock time. + nsecs_t mStartMonotonicNsecs; + nsecs_t mStartRealtimeNsecs; + + // Used for tracking dropped frames. + nsecs_t mLastFrameNumber; + size_t mTotalDroppedFrames; + + static const char* kPropertyNames[]; +}; + +}; // namespace android + +#endif /*SCREENRECORD_OVERLAY_H*/ diff --git a/cmds/screenrecord/Program.cpp b/cmds/screenrecord/Program.cpp new file mode 100644 index 0000000..a198204 --- /dev/null +++ b/cmds/screenrecord/Program.cpp @@ -0,0 +1,303 @@ +/* + * Copyright 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "ScreenRecord" +//#define LOG_NDEBUG 0 +#include <utils/Log.h> + +#include "Program.h" + +#include <GLES2/gl2.h> +#include <GLES2/gl2ext.h> + +#include <assert.h> + +using namespace android; + +// 4x4 identity matrix +const float Program::kIdentity[] = { + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f +}; + +// Simple vertex shader. Texture coord calc includes matrix for GLConsumer +// transform. +static const char* kVertexShader = + "uniform mat4 uMVPMatrix;\n" + "uniform mat4 uGLCMatrix;\n" + "attribute vec4 aPosition;\n" + "attribute vec4 aTextureCoord;\n" + "varying vec2 vTextureCoord;\n" + "void main() {\n" + " gl_Position = uMVPMatrix * aPosition;\n" + " vTextureCoord = (uGLCMatrix * aTextureCoord).xy;\n" + "}\n"; + +// Trivial fragment shader for external texture. +static const char* kExtFragmentShader = + "#extension GL_OES_EGL_image_external : require\n" + "precision mediump float;\n" + "varying vec2 vTextureCoord;\n" + "uniform samplerExternalOES uTexture;\n" + "void main() {\n" + " gl_FragColor = texture2D(uTexture, vTextureCoord);\n" + "}\n"; + +// Trivial fragment shader for mundane texture. +static const char* kFragmentShader = + "precision mediump float;\n" + "varying vec2 vTextureCoord;\n" + "uniform sampler2D uTexture;\n" + "void main() {\n" + " gl_FragColor = texture2D(uTexture, vTextureCoord);\n" + //" gl_FragColor = vec4(0.2, 1.0, 0.2, 1.0);\n" + "}\n"; + +status_t Program::setup(ProgramType type) { + ALOGV("Program::setup type=%d", type); + status_t err; + + mProgramType = type; + + GLuint program; + if (type == PROGRAM_TEXTURE_2D) { + err = createProgram(&program, kVertexShader, kFragmentShader); + } else { + err = createProgram(&program, kVertexShader, kExtFragmentShader); + } + if (err != NO_ERROR) { + return err; + } + assert(program != 0); + + maPositionLoc = glGetAttribLocation(program, "aPosition"); + maTextureCoordLoc = glGetAttribLocation(program, "aTextureCoord"); + muMVPMatrixLoc = glGetUniformLocation(program, "uMVPMatrix"); + muGLCMatrixLoc = glGetUniformLocation(program, "uGLCMatrix"); + muTextureLoc = glGetUniformLocation(program, "uTexture"); + if ((maPositionLoc | maTextureCoordLoc | muMVPMatrixLoc | + muGLCMatrixLoc | muTextureLoc) == -1) { + ALOGE("Attrib/uniform lookup failed: %#x", glGetError()); + glDeleteProgram(program); + return UNKNOWN_ERROR; + } + + mProgram = program; + return NO_ERROR; +} + +void Program::release() { + ALOGV("Program::release"); + if (mProgram != 0) { + glDeleteProgram(mProgram); + mProgram = 0; + } +} + +status_t Program::createProgram(GLuint* outPgm, const char* vertexShader, + const char* fragmentShader) { + GLuint vs, fs; + status_t err; + + err = compileShader(GL_VERTEX_SHADER, vertexShader, &vs); + if (err != NO_ERROR) { + return err; + } + err = compileShader(GL_FRAGMENT_SHADER, fragmentShader, &fs); + if (err != NO_ERROR) { + glDeleteShader(vs); + return err; + } + + GLuint program; + err = linkShaderProgram(vs, fs, &program); + glDeleteShader(vs); + glDeleteShader(fs); + if (err == NO_ERROR) { + *outPgm = program; + } + return err; +} + +status_t Program::compileShader(GLenum shaderType, const char* src, + GLuint* outShader) { + GLuint shader = glCreateShader(shaderType); + if (shader == 0) { + ALOGE("glCreateShader error: %#x", glGetError()); + return UNKNOWN_ERROR; + } + + glShaderSource(shader, 1, &src, NULL); + glCompileShader(shader); + + GLint compiled = 0; + glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); + if (!compiled) { + ALOGE("Compile of shader type %d failed", shaderType); + GLint infoLen = 0; + glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen); + if (infoLen) { + char* buf = new char[infoLen]; + if (buf) { + glGetShaderInfoLog(shader, infoLen, NULL, buf); + ALOGE("Compile log: %s", buf); + delete[] buf; + } + } + glDeleteShader(shader); + return UNKNOWN_ERROR; + } + *outShader = shader; + return NO_ERROR; +} + +status_t Program::linkShaderProgram(GLuint vs, GLuint fs, GLuint* outPgm) { + GLuint program = glCreateProgram(); + if (program == 0) { + ALOGE("glCreateProgram error: %#x", glGetError()); + return UNKNOWN_ERROR; + } + + glAttachShader(program, vs); + glAttachShader(program, fs); + glLinkProgram(program); + GLint linkStatus = GL_FALSE; + glGetProgramiv(program, GL_LINK_STATUS, &linkStatus); + if (linkStatus != GL_TRUE) { + ALOGE("glLinkProgram failed"); + GLint bufLength = 0; + glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength); + if (bufLength) { + char* buf = new char[bufLength]; + if (buf) { + glGetProgramInfoLog(program, bufLength, NULL, buf); + ALOGE("Link log: %s", buf); + delete[] buf; + } + } + glDeleteProgram(program); + return UNKNOWN_ERROR; + } + + *outPgm = program; + return NO_ERROR; +} + + + +status_t Program::blit(GLuint texName, const float* texMatrix, + int32_t x, int32_t y, int32_t w, int32_t h) const { + ALOGV("Program::blit %d xy=%d,%d wh=%d,%d", texName, x, y, w, h); + + const float pos[] = { + float(x), float(y+h), + float(x+w), float(y+h), + float(x), float(y), + float(x+w), float(y), + }; + const float uv[] = { + 0.0f, 0.0f, + 1.0f, 0.0f, + 0.0f, 1.0f, + 1.0f, 1.0f, + }; + status_t err; + + err = beforeDraw(texName, texMatrix, pos, uv); + if (err == NO_ERROR) { + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + err = afterDraw(); + } + return err; +} + +status_t Program::drawTriangles(GLuint texName, const float* texMatrix, + const float* vertices, const float* texes, size_t count) const { + ALOGV("Program::drawTriangles texName=%d", texName); + + status_t err; + + err = beforeDraw(texName, texMatrix, vertices, texes); + if (err == NO_ERROR) { + glDrawArrays(GL_TRIANGLES, 0, count); + err = afterDraw(); + } + return err; +} + +status_t Program::beforeDraw(GLuint texName, const float* texMatrix, + const float* vertices, const float* texes) const { + // Create an orthographic projection matrix based on viewport size. + GLint vp[4]; + glGetIntegerv(GL_VIEWPORT, vp); + float screenToNdc[16] = { + 2.0f/float(vp[2]), 0.0f, 0.0f, 0.0f, + 0.0f, -2.0f/float(vp[3]), 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + -1.0f, 1.0f, 0.0f, 1.0f, + }; + + glUseProgram(mProgram); + + glVertexAttribPointer(maPositionLoc, 2, GL_FLOAT, GL_FALSE, 0, vertices); + glVertexAttribPointer(maTextureCoordLoc, 2, GL_FLOAT, GL_FALSE, 0, texes); + glEnableVertexAttribArray(maPositionLoc); + glEnableVertexAttribArray(maTextureCoordLoc); + + glUniformMatrix4fv(muMVPMatrixLoc, 1, GL_FALSE, screenToNdc); + glUniformMatrix4fv(muGLCMatrixLoc, 1, GL_FALSE, texMatrix); + + glActiveTexture(GL_TEXTURE0); + + switch (mProgramType) { + case PROGRAM_EXTERNAL_TEXTURE: + glBindTexture(GL_TEXTURE_EXTERNAL_OES, texName); + break; + case PROGRAM_TEXTURE_2D: + glBindTexture(GL_TEXTURE_2D, texName); + break; + default: + ALOGE("unexpected program type %d", mProgramType); + return UNKNOWN_ERROR; + } + + glUniform1i(muTextureLoc, 0); + + GLenum glErr; + if ((glErr = glGetError()) != GL_NO_ERROR) { + ALOGE("GL error before draw: %#x", glErr); + glDisableVertexAttribArray(maPositionLoc); + glDisableVertexAttribArray(maTextureCoordLoc); + return UNKNOWN_ERROR; + } + + return NO_ERROR; +} + +status_t Program::afterDraw() const { + glDisableVertexAttribArray(maPositionLoc); + glDisableVertexAttribArray(maTextureCoordLoc); + + GLenum glErr; + if ((glErr = glGetError()) != GL_NO_ERROR) { + ALOGE("GL error after draw: %#x", glErr); + return UNKNOWN_ERROR; + } + + return NO_ERROR; +} diff --git a/cmds/screenrecord/Program.h b/cmds/screenrecord/Program.h new file mode 100644 index 0000000..e47bc0d --- /dev/null +++ b/cmds/screenrecord/Program.h @@ -0,0 +1,92 @@ +/* + * Copyright 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SCREENRECORD_PROGRAM_H +#define SCREENRECORD_PROGRAM_H + +#include <utils/Errors.h> + +#include <EGL/egl.h> +#include <GLES2/gl2.h> + +namespace android { + +/* + * Utility class for GLES rendering. + * + * Not thread-safe. + */ +class Program { +public: + enum ProgramType { PROGRAM_UNKNOWN=0, PROGRAM_EXTERNAL_TEXTURE, + PROGRAM_TEXTURE_2D }; + + Program() : + mProgramType(PROGRAM_UNKNOWN), + mProgram(0), + maPositionLoc(0), + maTextureCoordLoc(0), + muMVPMatrixLoc(0), + muGLCMatrixLoc(0), + muTextureLoc(0) + {} + ~Program() { release(); } + + // Initialize the program for use with the specified texture type. + status_t setup(ProgramType type); + + // Release the program and associated resources. + void release(); + + // Blit the specified texture to { x, y, x+w, y+h }. + status_t blit(GLuint texName, const float* texMatrix, + int32_t x, int32_t y, int32_t w, int32_t h) const; + + // Draw a number of triangles. + status_t drawTriangles(GLuint texName, const float* texMatrix, + const float* vertices, const float* texes, size_t count) const; + + static const float kIdentity[]; + +private: + Program(const Program&); + Program& operator=(const Program&); + + // Common code for draw functions. + status_t beforeDraw(GLuint texName, const float* texMatrix, + const float* vertices, const float* texes) const; + status_t afterDraw() const; + + // GLES 2 shader utilities. + status_t createProgram(GLuint* outPgm, const char* vertexShader, + const char* fragmentShader); + static status_t compileShader(GLenum shaderType, const char* src, + GLuint* outShader); + static status_t linkShaderProgram(GLuint vs, GLuint fs, GLuint* outPgm); + + ProgramType mProgramType; + GLuint mProgram; + + GLint maPositionLoc; + GLint maTextureCoordLoc; + GLint muMVPMatrixLoc; + GLint muGLCMatrixLoc; + GLint muTextureLoc; +}; + +}; // namespace android + +#endif /*SCREENRECORD_PROGRAM_H*/ diff --git a/cmds/screenrecord/TextRenderer.cpp b/cmds/screenrecord/TextRenderer.cpp new file mode 100644 index 0000000..784055c --- /dev/null +++ b/cmds/screenrecord/TextRenderer.cpp @@ -0,0 +1,358 @@ +/* + * Copyright 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "ScreenRecord" +//#define LOG_NDEBUG 0 +#include <utils/Log.h> + +#include "TextRenderer.h" + +#include <assert.h> + +namespace android { +#include "FontBitmap.h" +}; + +using namespace android; + +const char TextRenderer::kWhitespace[] = " \t\n\r"; + +bool TextRenderer::mInitialized = false; +uint32_t TextRenderer::mXOffset[FontBitmap::numGlyphs]; + +void TextRenderer::initOnce() { + if (!mInitialized) { + initXOffset(); + mInitialized = true; + } +} + +void TextRenderer::initXOffset() { + // Generate a table of X offsets. They start at zero and reset whenever + // we move down a line (i.e. the Y offset changes). The offset increases + // by one pixel more than the width because the generator left a gap to + // avoid reading pixels from adjacent glyphs in the texture filter. + uint16_t offset = 0; + uint16_t prevYOffset = (int16_t) -1; + for (unsigned int i = 0; i < FontBitmap::numGlyphs; i++) { + if (prevYOffset != FontBitmap::yoffset[i]) { + prevYOffset = FontBitmap::yoffset[i]; + offset = 0; + } + mXOffset[i] = offset; + offset += FontBitmap::glyphWidth[i] + 1; + } +} + +static bool isPowerOfTwo(uint32_t val) { + // a/k/a "is exactly one bit set"; note returns true for 0 + return (val & (val -1)) == 0; +} + +static uint32_t powerOfTwoCeil(uint32_t val) { + // drop it, smear the bits across, pop it + val--; + val |= val >> 1; + val |= val >> 2; + val |= val >> 4; + val |= val >> 8; + val |= val >> 16; + val++; + + return val; +} + +float TextRenderer::getGlyphHeight() const { + return FontBitmap::maxGlyphHeight; +} + +status_t TextRenderer::loadIntoTexture() { + ALOGV("Font::loadIntoTexture"); + + glGenTextures(1, &mTextureName); + if (mTextureName == 0) { + ALOGE("glGenTextures failed: %#x", glGetError()); + return UNKNOWN_ERROR; + } + glBindTexture(GL_TEXTURE_2D, mTextureName); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + // The pixel data is stored as combined color+alpha, 8 bits per pixel. + // It's guaranteed to be a power-of-two wide, but we cut off the height + // where the data ends. We want to expand it to a power-of-two bitmap + // with ARGB data and hand that to glTexImage2D. + + if (!isPowerOfTwo(FontBitmap::width)) { + ALOGE("npot glyph bitmap width %u", FontBitmap::width); + return UNKNOWN_ERROR; + } + + uint32_t potHeight = powerOfTwoCeil(FontBitmap::height); + uint8_t* rgbaPixels = new uint8_t[FontBitmap::width * potHeight * 4]; + memset(rgbaPixels, 0, FontBitmap::width * potHeight * 4); + uint8_t* pix = rgbaPixels; + + for (unsigned int i = 0; i < FontBitmap::width * FontBitmap::height; i++) { + uint8_t alpha, color; + if ((FontBitmap::pixels[i] & 1) == 0) { + // black pixel with varying alpha + color = 0x00; + alpha = FontBitmap::pixels[i] & ~1; + } else { + // opaque grey pixel + color = FontBitmap::pixels[i] & ~1; + alpha = 0xff; + } + *pix++ = color; + *pix++ = color; + *pix++ = color; + *pix++ = alpha; + } + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, FontBitmap::width, potHeight, 0, + GL_RGBA, GL_UNSIGNED_BYTE, rgbaPixels); + delete[] rgbaPixels; + GLint glErr = glGetError(); + if (glErr != 0) { + ALOGE("glTexImage2D failed: %#x", glErr); + return UNKNOWN_ERROR; + } + return NO_ERROR; +} + +void TextRenderer::setProportionalScale(float linesPerScreen) { + if (mScreenWidth == 0 || mScreenHeight == 0) { + ALOGW("setFontScale: can't set scale for width=%d height=%d", + mScreenWidth, mScreenHeight); + return; + } + float tallest = mScreenWidth > mScreenHeight ? mScreenWidth : mScreenHeight; + setScale(tallest / (linesPerScreen * getGlyphHeight())); +} + +float TextRenderer::computeScaledStringWidth(const String8& str8) const { + // String8.length() isn't documented, but I'm assuming it will return + // the number of characters rather than the number of bytes. Since + // we can only display ASCII we want to ignore anything else, so we + // just convert to char* -- but String8 doesn't document what it does + // with values outside 0-255. So just convert to char* and use strlen() + // to see what we get. + const char* str = str8.string(); + return computeScaledStringWidth(str, strlen(str)); +} + +size_t TextRenderer::glyphIndex(char ch) const { + size_t chi = ch - FontBitmap::firstGlyphChar; + if (chi >= FontBitmap::numGlyphs) { + chi = '?' - FontBitmap::firstGlyphChar; + } + assert(chi < FontBitmap::numGlyphs); + return chi; +} + +float TextRenderer::computeScaledStringWidth(const char* str, + size_t len) const { + float width = 0.0f; + for (size_t i = 0; i < len; i++) { + size_t chi = glyphIndex(str[i]); + float glyphWidth = FontBitmap::glyphWidth[chi]; + width += (glyphWidth - 1 - FontBitmap::outlineWidth) * mScale; + } + + return width; +} + +void TextRenderer::drawString(const Program& program, const float* texMatrix, + float x, float y, const String8& str8) const { + ALOGV("drawString %.3f,%.3f '%s' (scale=%.3f)", x, y, str8.string(),mScale); + initOnce(); + + // We want to draw the entire string with a single GLES call. We + // generate two arrays, one with screen coordinates, one with texture + // coordinates. Need two triangles per character. + const char* str = str8.string(); + size_t len = strlen(str); // again, unsure about String8 handling + + const size_t quadCoords = + 2 /*triangles*/ * 3 /*vertex/tri*/ * 2 /*coord/vertex*/; + float vertices[len * quadCoords]; + float texes[len * quadCoords]; + + float fullTexWidth = FontBitmap::width; + float fullTexHeight = powerOfTwoCeil(FontBitmap::height); + for (size_t i = 0; i < len; i++) { + size_t chi = glyphIndex(str[i]); + float glyphWidth = FontBitmap::glyphWidth[chi]; + float glyphHeight = FontBitmap::maxGlyphHeight; + + float vertLeft = x; + float vertRight = x + glyphWidth * mScale; + float vertTop = y; + float vertBottom = y + glyphHeight * mScale; + + // Lowest-numbered glyph is in top-left of bitmap, which puts it at + // the bottom-left in texture coordinates. + float texLeft = mXOffset[chi] / fullTexWidth; + float texRight = (mXOffset[chi] + glyphWidth) / fullTexWidth; + float texTop = FontBitmap::yoffset[chi] / fullTexHeight; + float texBottom = (FontBitmap::yoffset[chi] + glyphHeight) / + fullTexHeight; + + size_t off = i * quadCoords; + vertices[off + 0] = vertLeft; + vertices[off + 1] = vertBottom; + vertices[off + 2] = vertRight; + vertices[off + 3] = vertBottom; + vertices[off + 4] = vertLeft; + vertices[off + 5] = vertTop; + vertices[off + 6] = vertLeft; + vertices[off + 7] = vertTop; + vertices[off + 8] = vertRight; + vertices[off + 9] = vertBottom; + vertices[off + 10] = vertRight; + vertices[off + 11] = vertTop; + texes[off + 0] = texLeft; + texes[off + 1] = texBottom; + texes[off + 2] = texRight; + texes[off + 3] = texBottom; + texes[off + 4] = texLeft; + texes[off + 5] = texTop; + texes[off + 6] = texLeft; + texes[off + 7] = texTop; + texes[off + 8] = texRight; + texes[off + 9] = texBottom; + texes[off + 10] = texRight; + texes[off + 11] = texTop; + + // We added 1-pixel padding in the texture, so we want to advance by + // one less. Also, each glyph is surrounded by a black outline, which + // we want to merge. + x += (glyphWidth - 1 - FontBitmap::outlineWidth) * mScale; + } + + program.drawTriangles(mTextureName, texMatrix, vertices, texes, + len * quadCoords / 2); +} + +float TextRenderer::drawWrappedString(const Program& texRender, + float xpos, float ypos, const String8& str) { + ALOGV("drawWrappedString %.3f,%.3f '%s'", xpos, ypos, str.string()); + initOnce(); + + if (mScreenWidth == 0 || mScreenHeight == 0) { + ALOGW("drawWrappedString: can't wrap with width=%d height=%d", + mScreenWidth, mScreenHeight); + return ypos; + } + + const float indentWidth = mIndentMult * getScale(); + if (xpos < mBorderWidth) { + xpos = mBorderWidth; + } + if (ypos < mBorderWidth) { + ypos = mBorderWidth; + } + + const size_t maxWidth = (mScreenWidth - mBorderWidth) - xpos; + if (maxWidth < 1) { + ALOGE("Unable to render text: xpos=%.3f border=%.3f width=%u", + xpos, mBorderWidth, mScreenWidth); + return ypos; + } + float stringWidth = computeScaledStringWidth(str); + if (stringWidth <= maxWidth) { + // Trivial case. + drawString(texRender, Program::kIdentity, xpos, ypos, str); + ypos += getScaledGlyphHeight(); + } else { + // We need to break the string into pieces, ideally at whitespace + // boundaries. + char* mangle = strdup(str.string()); + char* start = mangle; + while (start != NULL) { + float xposAdj = (start == mangle) ? xpos : xpos + indentWidth; + char* brk = breakString(start, + (float) (mScreenWidth - mBorderWidth - xposAdj)); + if (brk == NULL) { + // draw full string + drawString(texRender, Program::kIdentity, xposAdj, ypos, + String8(start)); + start = NULL; + } else { + // draw partial string + char ch = *brk; + *brk = '\0'; + drawString(texRender, Program::kIdentity, xposAdj, ypos, + String8(start)); + *brk = ch; + start = brk; + if (strchr(kWhitespace, ch) != NULL) { + // if we broke on whitespace, skip past it + start++; + } + } + ypos += getScaledGlyphHeight(); + } + free(mangle); + } + + return ypos; +} + +char* TextRenderer::breakString(const char* str, float maxWidth) const { + // Ideally we'd do clever things like binary search. Not bothering. + ALOGV("breakString '%s' %.3f", str, maxWidth); + + size_t len = strlen(str); + if (len == 0) { + // Caller should detect this and not advance ypos. + return NULL; + } + + float stringWidth = computeScaledStringWidth(str, len); + if (stringWidth <= maxWidth) { + return NULL; // trivial -- use full string + } + + // Find the longest string that will fit. + size_t goodPos = 0; + for (size_t i = 0; i < len; i++) { + stringWidth = computeScaledStringWidth(str, i); + if (stringWidth < maxWidth) { + goodPos = i; + } else { + break; // too big + } + } + if (goodPos == 0) { + // space is too small to hold any glyph; output a single char + ALOGW("Couldn't find a nonzero prefix that fit from '%s'", str); + goodPos = 1; + } + + // Scan back for whitespace. If we can't find any we'll just have + // an ugly mid-word break. + for (size_t i = goodPos; i > 0; i--) { + if (strchr(kWhitespace, str[i]) != NULL) { + goodPos = i; + break; + } + } + + ALOGV("goodPos=%d for str='%s'", goodPos, str); + return const_cast<char*>(str + goodPos); +} diff --git a/cmds/screenrecord/TextRenderer.h b/cmds/screenrecord/TextRenderer.h new file mode 100644 index 0000000..03dd2fb --- /dev/null +++ b/cmds/screenrecord/TextRenderer.h @@ -0,0 +1,140 @@ +/* + * Copyright 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SCREENRECORD_TEXT_RENDER_H +#define SCREENRECORD_TEXT_RENDER_H + +#include "Program.h" + +#include <utils/String8.h> +#include <utils/Errors.h> + +#include <GLES2/gl2.h> + + +namespace android { + +/* + * Simple font representation. + * + * Not thread-safe. + */ +class TextRenderer { +public: + TextRenderer() : + mTextureName(0), + mScale(1.0f), + mBorderWidth(10.0f), + mIndentMult(30.0f), + mScreenWidth(0), + mScreenHeight(0) + {} + ~TextRenderer() {} + + // Load the glyph bitmap into a 2D texture in the current context. + status_t loadIntoTexture(); + + // Set the screen dimensions, used for scaling and line wrap. + void setScreenSize(uint32_t width, uint32_t height) { + mScreenWidth = width; + mScreenHeight = height; + } + + // Get/set the font scaling. + float getScale() const { return mScale; } + void setScale(float scale) { mScale = scale; } + + // Set the font scaling based on the desired number of lines per screen. + // The display's tallest axis is used, so if the device is in landscape + // the screen will fit fewer lines. + void setProportionalScale(float linesPerScreen); + + // Render the text string at the specified coordinates. Pass in the + // upper-left corner in non-GL-flipped coordinates, i.e. to print text + // at the top left of the screen use (0,0). + // + // Set blend func (1, 1-srcAlpha) before calling if drawing onto + // something other than black. + void drawString(const Program& program, const float* texMatrix, + float x, float y, const String8& str) const; + + // Draw a string, possibly wrapping it at the screen boundary. Top-left + // is at (0,0). + // + // Returns the updated Y position. + float drawWrappedString(const Program& texRender, float xpos, float ypos, + const String8& str); + + // Returns the name of the texture the font was loaded into. + GLuint getTextureName() const { return mTextureName; } + +private: + TextRenderer(const TextRenderer&); + TextRenderer& operator=(const TextRenderer&); + + // Perform one-time initialization. + static void initOnce(); + + // Populate the mXOffset array. + static void initXOffset(); + + // Find a good place to break the string. Returns NULL if the entire + // string will fit. + char* breakString(const char* str, float maxWidth) const; + + // Computes the width of the string, in pixels. + float computeScaledStringWidth(const String8& str8) const; + + // Computes the width of first N characters in the string. + float computeScaledStringWidth(const char* str, size_t len) const; + + // Returns the font's glyph height. This is the full pixel height of the + // tallest glyph, both above and below the baseline, NOT adjusted by the + // current scale factor. + float getGlyphHeight() const; + + // Like getGlyphHeight(), but result is scaled. + float getScaledGlyphHeight() const { return getGlyphHeight() * mScale; } + + // Convert an ASCII character to a glyph index. Returns the glyph for + // '?' if we have no glyph for the specified character. + size_t glyphIndex(char ch) const; + + GLuint mTextureName; + float mScale; + + // Number of pixels preserved at the left/right edges of the screen by + // drawWrappedString(). Not scaled. + float mBorderWidth; + + // Distance to indent a broken line. Used by drawWrappedString(). + // Value will be adjusted by the current scale factor. + float mIndentMult; + + // Screen dimensions. + uint32_t mScreenWidth; + uint32_t mScreenHeight; + + // Static font info. + static bool mInitialized; + static uint32_t mXOffset[]; + + static const char kWhitespace[]; +}; + +}; // namespace android + +#endif /*SCREENRECORD_TEXT_RENDER_H*/ diff --git a/cmds/screenrecord/screenrecord.cpp b/cmds/screenrecord/screenrecord.cpp index 49999b5..61f83e3 100644 --- a/cmds/screenrecord/screenrecord.cpp +++ b/cmds/screenrecord/screenrecord.cpp @@ -15,13 +15,14 @@ */ #define LOG_TAG "ScreenRecord" +#define ATRACE_TAG ATRACE_TAG_GRAPHICS //#define LOG_NDEBUG 0 #include <utils/Log.h> #include <binder/IPCThreadState.h> #include <utils/Errors.h> -#include <utils/Thread.h> #include <utils/Timers.h> +#include <utils/Trace.h> #include <gui/Surface.h> #include <gui/SurfaceComposerClient.h> @@ -29,7 +30,6 @@ #include <ui/DisplayInfo.h> #include <media/openmax/OMX_IVCommon.h> #include <media/stagefright/foundation/ABuffer.h> -#include <media/stagefright/foundation/ADebug.h> #include <media/stagefright/foundation/AMessage.h> #include <media/stagefright/MediaCodec.h> #include <media/stagefright/MediaErrors.h> @@ -40,30 +40,37 @@ #include <unistd.h> #include <string.h> #include <stdio.h> +#include <ctype.h> #include <fcntl.h> #include <signal.h> #include <getopt.h> #include <sys/wait.h> +#include <assert.h> + +#include "screenrecord.h" +#include "Overlay.h" using namespace android; static const uint32_t kMinBitRate = 100000; // 0.1Mbps -static const uint32_t kMaxBitRate = 100 * 1000000; // 100Mbps +static const uint32_t kMaxBitRate = 200 * 1000000; // 200Mbps static const uint32_t kMaxTimeLimitSec = 180; // 3 minutes static const uint32_t kFallbackWidth = 1280; // 720p static const uint32_t kFallbackHeight = 720; // Command-line parameters. -static bool gVerbose = false; // chatty on stdout -static bool gRotate = false; // rotate 90 degrees -static bool gSizeSpecified = false; // was size explicitly requested? -static uint32_t gVideoWidth = 0; // default width+height +static bool gVerbose = false; // chatty on stdout +static bool gRotate = false; // rotate 90 degrees +static bool gSizeSpecified = false; // was size explicitly requested? +static bool gWantInfoScreen = false; // do we want initial info screen? +static bool gWantFrameTime = false; // do we want times on each frame? +static uint32_t gVideoWidth = 0; // default width+height static uint32_t gVideoHeight = 0; -static uint32_t gBitRate = 4000000; // 4Mbps +static uint32_t gBitRate = 4000000; // 4Mbps static uint32_t gTimeLimitSec = kMaxTimeLimitSec; // Set by signal handler to stop recording. -static bool gStopRequested; +static volatile bool gStopRequested; // Previous signal handler state, restored after first hit. static struct sigaction gOrigSigactionINT; @@ -97,8 +104,7 @@ static void signalCatcher(int signum) * when Ctrl-C is hit. If we're run from the host, the local adb process * gets the signal, and we get a SIGHUP when the terminal disconnects. */ -static status_t configureSignals() -{ +static status_t configureSignals() { struct sigaction act; memset(&act, 0, sizeof(act)); act.sa_handler = signalCatcher; @@ -156,35 +162,30 @@ static status_t prepareEncoder(float displayFps, sp<MediaCodec>* pCodec, fprintf(stderr, "ERROR: unable to create video/avc codec instance\n"); return UNKNOWN_ERROR; } + err = codec->configure(format, NULL, NULL, MediaCodec::CONFIGURE_FLAG_ENCODE); if (err != NO_ERROR) { - codec->release(); - codec.clear(); - fprintf(stderr, "ERROR: unable to configure codec (err=%d)\n", err); + codec->release(); return err; } - ALOGV("Creating buffer producer"); + ALOGV("Creating encoder input surface"); sp<IGraphicBufferProducer> bufferProducer; err = codec->createInputSurface(&bufferProducer); if (err != NO_ERROR) { - codec->release(); - codec.clear(); - fprintf(stderr, "ERROR: unable to create encoder input surface (err=%d)\n", err); + codec->release(); return err; } ALOGV("Starting codec"); err = codec->start(); if (err != NO_ERROR) { - codec->release(); - codec.clear(); - fprintf(stderr, "ERROR: unable to start codec (err=%d)\n", err); + codec->release(); return err; } @@ -195,12 +196,11 @@ static status_t prepareEncoder(float displayFps, sp<MediaCodec>* pCodec, } /* - * Configures the virtual display. When this completes, virtual display - * frames will start being sent to the encoder's surface. + * Sets the display projection, based on the display dimensions, video size, + * and device orientation. */ -static status_t prepareVirtualDisplay(const DisplayInfo& mainDpyInfo, - const sp<IGraphicBufferProducer>& bufferProducer, - sp<IBinder>* pDisplayHandle) { +static status_t setDisplayProjection(const sp<IBinder>& dpy, + const DisplayInfo& mainDpyInfo) { status_t err; // Set the region of the layer stack we're interested in, which in our @@ -266,15 +266,25 @@ static status_t prepareVirtualDisplay(const DisplayInfo& mainDpyInfo, } } + SurfaceComposerClient::setDisplayProjection(dpy, + gRotate ? DISPLAY_ORIENTATION_90 : DISPLAY_ORIENTATION_0, + layerStackRect, displayRect); + return NO_ERROR; +} +/* + * Configures the virtual display. When this completes, virtual display + * frames will start arriving from the buffer producer. + */ +static status_t prepareVirtualDisplay(const DisplayInfo& mainDpyInfo, + const sp<IGraphicBufferProducer>& bufferProducer, + sp<IBinder>* pDisplayHandle) { sp<IBinder> dpy = SurfaceComposerClient::createDisplay( - String8("ScreenRecorder"), false /* secure */); + String8("ScreenRecorder"), false /*secure*/); SurfaceComposerClient::openGlobalTransaction(); SurfaceComposerClient::setDisplaySurface(dpy, bufferProducer); - SurfaceComposerClient::setDisplayProjection(dpy, - gRotate ? DISPLAY_ORIENTATION_90 : DISPLAY_ORIENTATION_0, - layerStackRect, displayRect); + setDisplayProjection(dpy, mainDpyInfo); SurfaceComposerClient::setDisplayLayerStack(dpy, 0); // default stack SurfaceComposerClient::closeGlobalTransaction(); @@ -291,13 +301,15 @@ static status_t prepareVirtualDisplay(const DisplayInfo& mainDpyInfo, * The muxer must *not* have been started before calling. */ static status_t runEncoder(const sp<MediaCodec>& encoder, - const sp<MediaMuxer>& muxer) { + const sp<MediaMuxer>& muxer, const sp<IBinder>& mainDpy, + const sp<IBinder>& virtualDpy, uint8_t orientation) { static int kTimeout = 250000; // be responsive on signal status_t err; ssize_t trackIdx = -1; uint32_t debugNumFrames = 0; int64_t startWhenNsec = systemTime(CLOCK_MONOTONIC); int64_t endWhenNsec = startWhenNsec + seconds_to_nanoseconds(gTimeLimitSec); + DisplayInfo mainDpyInfo; Vector<sp<ABuffer> > buffers; err = encoder->getOutputBuffers(&buffers); @@ -338,10 +350,31 @@ static status_t runEncoder(const sp<MediaCodec>& encoder, if (size != 0) { ALOGV("Got data in buffer %d, size=%d, pts=%lld", bufIndex, size, ptsUsec); - CHECK(trackIdx != -1); + assert(trackIdx != -1); + + { // scope + ATRACE_NAME("orientation"); + // Check orientation, update if it has changed. + // + // Polling for changes is inefficient and wrong, but the + // useful stuff is hard to get at without a Dalvik VM. + err = SurfaceComposerClient::getDisplayInfo(mainDpy, + &mainDpyInfo); + if (err != NO_ERROR) { + ALOGW("getDisplayInfo(main) failed: %d", err); + } else if (orientation != mainDpyInfo.orientation) { + ALOGD("orientation changed, now %d", mainDpyInfo.orientation); + SurfaceComposerClient::openGlobalTransaction(); + setDisplayProjection(virtualDpy, mainDpyInfo); + SurfaceComposerClient::closeGlobalTransaction(); + orientation = mainDpyInfo.orientation; + } + } // If the virtual display isn't providing us with timestamps, - // use the current time. + // use the current time. This isn't great -- we could get + // decoded data in clusters -- but we're not expecting + // to hit this anyway. if (ptsUsec == 0) { ptsUsec = systemTime(SYSTEM_TIME_MONOTONIC) / 1000; } @@ -349,12 +382,18 @@ static status_t runEncoder(const sp<MediaCodec>& encoder, // The MediaMuxer docs are unclear, but it appears that we // need to pass either the full set of BufferInfo flags, or // (flags & BUFFER_FLAG_SYNCFRAME). - err = muxer->writeSampleData(buffers[bufIndex], trackIdx, - ptsUsec, flags); - if (err != NO_ERROR) { - fprintf(stderr, "Failed writing data to muxer (err=%d)\n", - err); - return err; + // + // If this blocks for too long we could drop frames. We may + // want to queue these up and do them on a different thread. + { // scope + ATRACE_NAME("write sample"); + err = muxer->writeSampleData(buffers[bufIndex], trackIdx, + ptsUsec, flags); + if (err != NO_ERROR) { + fprintf(stderr, + "Failed writing data to muxer (err=%d)\n", err); + return err; + } } debugNumFrames++; } @@ -366,8 +405,8 @@ static status_t runEncoder(const sp<MediaCodec>& encoder, } if ((flags & MediaCodec::BUFFER_FLAG_EOS) != 0) { // Not expecting EOS from SurfaceFlinger. Go with it. - ALOGD("Received end-of-stream"); - gStopRequested = false; + ALOGI("Received end-of-stream"); + gStopRequested = true; } break; case -EAGAIN: // INFO_TRY_AGAIN_LATER @@ -375,7 +414,7 @@ static status_t runEncoder(const sp<MediaCodec>& encoder, break; case INFO_FORMAT_CHANGED: // INFO_OUTPUT_FORMAT_CHANGED { - // format includes CSD, which we must provide to muxer + // Format includes CSD, which we must provide to muxer. ALOGV("Encoder format changed"); sp<AMessage> newFormat; encoder->getOutputFormat(&newFormat); @@ -389,7 +428,7 @@ static status_t runEncoder(const sp<MediaCodec>& encoder, } break; case INFO_OUTPUT_BUFFERS_CHANGED: // INFO_OUTPUT_BUFFERS_CHANGED - // not expected for an encoder; handle it anyway + // Not expected for an encoder; handle it anyway. ALOGV("Encoder buffers changed"); err = encoder->getOutputBuffers(&buffers); if (err != NO_ERROR) { @@ -399,7 +438,7 @@ static status_t runEncoder(const sp<MediaCodec>& encoder, } break; case INVALID_OPERATION: - fprintf(stderr, "Request for encoder buffer failed\n"); + ALOGW("dequeueOutputBuffer returned INVALID_OPERATION"); return err; default: fprintf(stderr, @@ -411,8 +450,8 @@ static status_t runEncoder(const sp<MediaCodec>& encoder, ALOGV("Encoder stopping (req=%d)", gStopRequested); if (gVerbose) { printf("Encoder stopping; recorded %u frames in %lld seconds\n", - debugNumFrames, - nanoseconds_to_seconds(systemTime(CLOCK_MONOTONIC) - startWhenNsec)); + debugNumFrames, nanoseconds_to_seconds( + systemTime(CLOCK_MONOTONIC) - startWhenNsec)); } return NO_ERROR; } @@ -460,8 +499,8 @@ static status_t recordScreen(const char* fileName) { // Configure and start the encoder. sp<MediaCodec> encoder; - sp<IGraphicBufferProducer> bufferProducer; - err = prepareEncoder(mainDpyInfo.fps, &encoder, &bufferProducer); + sp<IGraphicBufferProducer> encoderInputSurface; + err = prepareEncoder(mainDpyInfo.fps, &encoder, &encoderInputSurface); if (err != NO_ERROR && !gSizeSpecified) { // fallback is defined for landscape; swap if we're in portrait @@ -474,11 +513,41 @@ static status_t recordScreen(const char* fileName) { gVideoWidth, gVideoHeight, newWidth, newHeight); gVideoWidth = newWidth; gVideoHeight = newHeight; - err = prepareEncoder(mainDpyInfo.fps, &encoder, &bufferProducer); + err = prepareEncoder(mainDpyInfo.fps, &encoder, + &encoderInputSurface); } } - if (err != NO_ERROR) { - return err; + if (err != NO_ERROR) return err; + + // From here on, we must explicitly release() the encoder before it goes + // out of scope, or we will get an assertion failure from stagefright + // later on in a different thread. + + + // Draw the "info" page by rendering a frame with GLES and sending + // it directly to the encoder. + // TODO: consider displaying this as a regular layer to avoid b/11697754 + if (gWantInfoScreen) { + Overlay::drawInfoPage(encoderInputSurface); + } + + // Configure optional overlay. + sp<IGraphicBufferProducer> bufferProducer; + sp<Overlay> overlay; + if (gWantFrameTime) { + // Send virtual display frames to an external texture. + overlay = new Overlay(); + err = overlay->start(encoderInputSurface, &bufferProducer); + if (err != NO_ERROR) { + encoder->release(); + return err; + } + if (gVerbose) { + printf("Bugreport overlay created\n"); + } + } else { + // Use the encoder's input surface as the virtual display surface. + bufferProducer = encoderInputSurface; } // Configure virtual display. @@ -486,25 +555,22 @@ static status_t recordScreen(const char* fileName) { err = prepareVirtualDisplay(mainDpyInfo, bufferProducer, &dpy); if (err != NO_ERROR) { encoder->release(); - encoder.clear(); - return err; } - // Configure, but do not start, muxer. + // Configure muxer. We have to wait for the CSD blob from the encoder + // before we can start it. sp<MediaMuxer> muxer = new MediaMuxer(fileName, MediaMuxer::OUTPUT_FORMAT_MPEG_4); if (gRotate) { - muxer->setOrientationHint(90); + muxer->setOrientationHint(90); // TODO: does this do anything? } // Main encoder loop. - err = runEncoder(encoder, muxer); + err = runEncoder(encoder, muxer, mainDpy, dpy, mainDpyInfo.orientation); if (err != NO_ERROR) { - encoder->release(); - encoder.clear(); - - return err; + fprintf(stderr, "Encoder failed (err=%d)\n", err); + // fall through to cleanup } if (gVerbose) { @@ -512,14 +578,18 @@ static status_t recordScreen(const char* fileName) { } // Shut everything down, starting with the producer side. - bufferProducer = NULL; + encoderInputSurface = NULL; SurfaceComposerClient::destroyDisplay(dpy); - + if (overlay != NULL) { + overlay->stop(); + } encoder->stop(); + // If we don't stop muxer explicitly, i.e. let the destructor run, + // it may hang (b/11050628). muxer->stop(); encoder->release(); - return 0; + return err; } /* @@ -528,6 +598,28 @@ static status_t recordScreen(const char* fileName) { * This is optional, but nice to have. */ static status_t notifyMediaScanner(const char* fileName) { + // need to do allocations before the fork() + String8 fileUrl("file://"); + fileUrl.append(fileName); + + const char* kCommand = "/system/bin/am"; + const char* const argv[] = { + kCommand, + "broadcast", + "-a", + "android.intent.action.MEDIA_SCANNER_SCAN_FILE", + "-d", + fileUrl.string(), + NULL + }; + if (gVerbose) { + printf("Executing:"); + for (int i = 0; argv[i] != NULL; i++) { + printf(" %s", argv[i]); + } + putchar('\n'); + } + pid_t pid = fork(); if (pid < 0) { int err = errno; @@ -539,34 +631,14 @@ static status_t notifyMediaScanner(const char* fileName) { int status; pid_t actualPid = TEMP_FAILURE_RETRY(waitpid(pid, &status, 0)); if (actualPid != pid) { - ALOGW("waitpid() returned %d (errno=%d)", actualPid, errno); + ALOGW("waitpid(%d) returned %d (errno=%d)", pid, actualPid, errno); } else if (status != 0) { ALOGW("'am broadcast' exited with status=%d", status); } else { ALOGV("'am broadcast' exited successfully"); } } else { - const char* kCommand = "/system/bin/am"; - - // child; we're single-threaded, so okay to alloc - String8 fileUrl("file://"); - fileUrl.append(fileName); - const char* const argv[] = { - kCommand, - "broadcast", - "-a", - "android.intent.action.MEDIA_SCANNER_SCAN_FILE", - "-d", - fileUrl.string(), - NULL - }; - if (gVerbose) { - printf("Executing:"); - for (int i = 0; argv[i] != NULL; i++) { - printf(" %s", argv[i]); - } - putchar('\n'); - } else { + if (!gVerbose) { // non-verbose, suppress 'am' output ALOGV("closing stdout/stderr in child"); int fd = open("/dev/null", O_WRONLY); @@ -611,13 +683,37 @@ static bool parseWidthHeight(const char* widthHeight, uint32_t* pWidth, } /* + * Accepts a string with a bare number ("4000000") or with a single-character + * unit ("4m"). + * + * Returns an error if parsing fails. + */ +static status_t parseValueWithUnit(const char* str, uint32_t* pValue) { + long value; + char* endptr; + + value = strtol(str, &endptr, 10); + if (*endptr == '\0') { + // bare number + *pValue = value; + return NO_ERROR; + } else if (toupper(*endptr) == 'M' && *(endptr+1) == '\0') { + *pValue = value * 1000000; // check for overflow? + return NO_ERROR; + } else { + fprintf(stderr, "Unrecognized value: %s\n", str); + return UNKNOWN_ERROR; + } +} + +/* * Dumps usage on stderr. */ static void usage() { fprintf(stderr, "Usage: screenrecord [options] <filename>\n" "\n" - "Records the device's display to a .mp4 file.\n" + "Android screenrecord v%d.%d. Records the device's display to a .mp4 file.\n" "\n" "Options:\n" "--size WIDTHxHEIGHT\n" @@ -625,11 +721,13 @@ static void usage() { " display resolution (if supported), 1280x720 if not. For best results,\n" " use a size supported by the AVC encoder.\n" "--bit-rate RATE\n" - " Set the video bit rate, in megabits per second. Default %dMbps.\n" + " Set the video bit rate, in bits per second. Value may be specified as\n" + " bits or megabits, e.g. '4000000' is equivalent to '4M'. Default %dMbps.\n" + "--bugreport\n" + " Add additional information, such as a timestamp overlay, that is helpful\n" + " in videos captured to illustrate bugs.\n" "--time-limit TIME\n" " Set the maximum recording time, in seconds. Default / maximum is %d.\n" - "--rotate\n" - " Rotate the output 90 degrees.\n" "--verbose\n" " Display interesting information on stdout.\n" "--help\n" @@ -637,7 +735,7 @@ static void usage() { "\n" "Recording continues until Ctrl-C is hit or the time limit is reached.\n" "\n", - gBitRate / 1000000, gTimeLimitSec + kVersionMajor, kVersionMinor, gBitRate / 1000000, gTimeLimitSec ); } @@ -646,13 +744,16 @@ static void usage() { */ int main(int argc, char* const argv[]) { static const struct option longOptions[] = { - { "help", no_argument, NULL, 'h' }, - { "verbose", no_argument, NULL, 'v' }, - { "size", required_argument, NULL, 's' }, - { "bit-rate", required_argument, NULL, 'b' }, - { "time-limit", required_argument, NULL, 't' }, - { "rotate", no_argument, NULL, 'r' }, - { NULL, 0, NULL, 0 } + { "help", no_argument, NULL, 'h' }, + { "verbose", no_argument, NULL, 'v' }, + { "size", required_argument, NULL, 's' }, + { "bit-rate", required_argument, NULL, 'b' }, + { "time-limit", required_argument, NULL, 't' }, + { "show-device-info", no_argument, NULL, 'i' }, + { "show-frame-time", no_argument, NULL, 'f' }, + { "bugreport", no_argument, NULL, 'u' }, + { "rotate", no_argument, NULL, 'r' }, + { NULL, 0, NULL, 0 } }; while (true) { @@ -684,7 +785,9 @@ int main(int argc, char* const argv[]) { gSizeSpecified = true; break; case 'b': - gBitRate = atoi(optarg); + if (parseValueWithUnit(optarg, &gBitRate) != NO_ERROR) { + return 2; + } if (gBitRate < kMinBitRate || gBitRate > kMaxBitRate) { fprintf(stderr, "Bit rate %dbps outside acceptable range [%d,%d]\n", @@ -701,7 +804,18 @@ int main(int argc, char* const argv[]) { return 2; } break; + case 'i': + gWantInfoScreen = true; + break; + case 'f': + gWantFrameTime = true; + break; + case 'u': + gWantInfoScreen = true; + gWantFrameTime = true; + break; case 'r': + // experimental feature gRotate = true; break; default: diff --git a/cmds/screenrecord/screenrecord.h b/cmds/screenrecord/screenrecord.h new file mode 100644 index 0000000..95e8a68 --- /dev/null +++ b/cmds/screenrecord/screenrecord.h @@ -0,0 +1,23 @@ +/* + * Copyright 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SCREENRECORD_SCREENRECORD_H +#define SCREENRECORD_SCREENRECORD_H + +#define kVersionMajor 1 +#define kVersionMinor 1 + +#endif /*SCREENRECORD_SCREENRECORD_H*/ diff --git a/cmds/stagefright/codec.cpp b/cmds/stagefright/codec.cpp index fdfefdf..d125ad1 100644 --- a/cmds/stagefright/codec.cpp +++ b/cmds/stagefright/codec.cpp @@ -16,6 +16,7 @@ //#define LOG_NDEBUG 0 #define LOG_TAG "codec" +#include <inttypes.h> #include <utils/Log.h> #include "SimplePlayer.h" @@ -291,13 +292,13 @@ static int decode( CHECK_EQ((status_t)OK, state->mCodec->release()); if (state->mIsAudio) { - printf("track %d: %lld bytes received. %.2f KB/sec\n", + printf("track %zu: %" PRId64 " bytes received. %.2f KB/sec\n", i, state->mNumBytesDecoded, state->mNumBytesDecoded * 1E6 / 1024 / elapsedTimeUs); } else { - printf("track %d: %lld frames decoded, %.2f fps. %lld bytes " - "received. %.2f KB/sec\n", + printf("track %zu: %" PRId64 " frames decoded, %.2f fps. %" PRId64 + " bytes received. %.2f KB/sec\n", i, state->mNumBuffersDecoded, state->mNumBuffersDecoded * 1E6 / elapsedTimeUs, diff --git a/cmds/stagefright/muxer.cpp b/cmds/stagefright/muxer.cpp index cca33e0..90daea2 100644 --- a/cmds/stagefright/muxer.cpp +++ b/cmds/stagefright/muxer.cpp @@ -16,6 +16,7 @@ //#define LOG_NDEBUG 0 #define LOG_TAG "muxer" +#include <inttypes.h> #include <utils/Log.h> #include <binder/ProcessState.h> @@ -198,7 +199,7 @@ static int muxing( trackIndexMap.clear(); int64_t elapsedTimeUs = ALooper::GetNowUs() - muxerStartTimeUs; - fprintf(stderr, "SUCCESS: muxer generate the video in %lld ms\n", + fprintf(stderr, "SUCCESS: muxer generate the video in %" PRId64 " ms\n", elapsedTimeUs / 1000); return 0; diff --git a/cmds/stagefright/recordvideo.cpp b/cmds/stagefright/recordvideo.cpp index c30c122..1d267f9 100644 --- a/cmds/stagefright/recordvideo.cpp +++ b/cmds/stagefright/recordvideo.cpp @@ -16,6 +16,7 @@ #include "SineSource.h" +#include <inttypes.h> #include <binder/ProcessState.h> #include <media/stagefright/foundation/ADebug.h> #include <media/stagefright/AudioPlayer.h> @@ -312,7 +313,7 @@ int main(int argc, char **argv) { fprintf(stderr, "record failed: %d\n", err); return 1; } - fprintf(stderr, "encoding %d frames in %lld us\n", nFrames, (end-start)/1000); + fprintf(stderr, "encoding %d frames in %" PRId64 " us\n", nFrames, (end-start)/1000); fprintf(stderr, "encoding speed is: %.2f fps\n", (nFrames * 1E9) / (end-start)); return 0; } diff --git a/cmds/stagefright/sf2.cpp b/cmds/stagefright/sf2.cpp index c817443..b2b9ce5 100644 --- a/cmds/stagefright/sf2.cpp +++ b/cmds/stagefright/sf2.cpp @@ -16,6 +16,7 @@ //#define LOG_NDEBUG 0 #define LOG_TAG "sf2" +#include <inttypes.h> #include <utils/Log.h> #include <binder/ProcessState.h> @@ -183,11 +184,11 @@ protected: int64_t delayUs = ALooper::GetNowUs() - mStartTimeUs; if (mDecodeAudio) { - printf("%lld bytes received. %.2f KB/sec\n", + printf("%" PRId64 " bytes received. %.2f KB/sec\n", mTotalBytesReceived, mTotalBytesReceived * 1E6 / 1024 / delayUs); } else { - printf("%d frames decoded, %.2f fps. %lld bytes " + printf("%d frames decoded, %.2f fps. %" PRId64 " bytes " "received. %.2f KB/sec\n", mNumOutputBuffersReceived, mNumOutputBuffersReceived * 1E6 / delayUs, diff --git a/cmds/stagefright/stagefright.cpp b/cmds/stagefright/stagefright.cpp index 030bf1b..8efb39e 100644 --- a/cmds/stagefright/stagefright.cpp +++ b/cmds/stagefright/stagefright.cpp @@ -22,6 +22,7 @@ #include <stdlib.h> #include <string.h> +#include <inttypes.h> #include "jpeg.h" #include "SineSource.h" @@ -89,8 +90,8 @@ static void displayDecodeHistogram(Vector<int64_t> *decodeTimesUs) { int64_t minUs = decodeTimesUs->itemAt(0); int64_t maxUs = decodeTimesUs->itemAt(n - 1); - printf("min decode time %lld us (%.2f secs)\n", minUs, minUs / 1E6); - printf("max decode time %lld us (%.2f secs)\n", maxUs, maxUs / 1E6); + printf("min decode time %" PRId64 " us (%.2f secs)\n", minUs, minUs / 1E6); + printf("max decode time %" PRId64 " us (%.2f secs)\n", maxUs, maxUs / 1E6); size_t counts[100]; for (size_t i = 0; i < 100; ++i) { @@ -110,7 +111,7 @@ static void displayDecodeHistogram(Vector<int64_t> *decodeTimesUs) { int64_t slotUs = minUs + (i * (maxUs - minUs) / 100); double fps = 1E6 / slotUs; - printf("[%.2f fps]: %d\n", fps, counts[i]); + printf("[%.2f fps]: %zu\n", fps, counts[i]); } } @@ -262,7 +263,7 @@ static void playSource(OMXClient *client, sp<MediaSource> &source) { } } - printf("buffer has timestamp %lld us (%.2f secs)\n", + printf("buffer has timestamp %" PRId64 " us (%.2f secs)\n", timestampUs, timestampUs / 1E6); buffer->release(); @@ -285,7 +286,7 @@ static void playSource(OMXClient *client, sp<MediaSource> &source) { seekTimeUs = (rand() * (float)durationUs) / RAND_MAX; options.setSeekTo(seekTimeUs); - printf("seeking to %lld us (%.2f secs)\n", + printf("seeking to %" PRId64 " us (%.2f secs)\n", seekTimeUs, seekTimeUs / 1E6); } } @@ -388,7 +389,7 @@ static void playSource(OMXClient *client, sp<MediaSource> &source) { // sizes may be different across decoders. printf("avg. %.2f KB/sec\n", totalBytes / 1024 * 1E6 / delay); - printf("decoded a total of %lld bytes\n", totalBytes); + printf("decoded a total of %" PRId64 " bytes\n", totalBytes); } } @@ -574,7 +575,8 @@ static void performSeekTest(const sp<MediaSource> &source) { int64_t timeUs; CHECK(buffer->meta_data()->findInt64(kKeyTime, &timeUs)); - printf("%lld\t%lld\t%lld\n", seekTimeUs, timeUs, seekTimeUs - timeUs); + printf("%" PRId64 "\t%" PRId64 "\t%" PRId64 "\n", + seekTimeUs, timeUs, seekTimeUs - timeUs); buffer->release(); buffer = NULL; @@ -1071,7 +1073,7 @@ int main(int argc, char **argv) { int64_t thumbTimeUs; if (meta->findInt64(kKeyThumbnailTime, &thumbTimeUs)) { - printf("thumbnailTime: %lld us (%.2f secs)\n", + printf("thumbnailTime: %" PRId64 " us (%.2f secs)\n", thumbTimeUs, thumbTimeUs / 1E6); } diff --git a/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/Android.mk b/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/Android.mk index e251f82..48b0afe 100644 --- a/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/Android.mk +++ b/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/Android.mk @@ -61,7 +61,7 @@ LOCAL_C_INCLUDES += \ $(LOCAL_PATH)/include \ external/openssl/include -LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/drm +LOCAL_MODULE_RELATIVE_PATH := drm LOCAL_MODULE_TAGS := optional diff --git a/drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.cpp b/drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.cpp index f2cadf7..69fa7a0 100644 --- a/drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.cpp +++ b/drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.cpp @@ -695,7 +695,7 @@ namespace android { { String8 result; for (size_t i = 0; i < numSubSamples; i++) { - result.appendFormat("[%d] {clear:%d, encrypted:%d} ", i, + result.appendFormat("[%zu] {clear:%zu, encrypted:%zu} ", i, subSamples[i].mNumBytesOfClearData, subSamples[i].mNumBytesOfEncryptedData); } diff --git a/include/camera/CameraMetadata.h b/include/camera/CameraMetadata.h index fe2bd19..1254d3c 100644 --- a/include/camera/CameraMetadata.h +++ b/include/camera/CameraMetadata.h @@ -99,6 +99,11 @@ class CameraMetadata { status_t append(const CameraMetadata &other); /** + * Append metadata from a raw camera_metadata buffer + */ + status_t append(const camera_metadata* other); + + /** * Number of metadata entries. */ size_t entryCount() const; diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h index 225ef76..4c22412 100644 --- a/include/media/AudioSystem.h +++ b/include/media/AudioSystem.h @@ -127,8 +127,8 @@ public: // NOTE: this feature is not supported on all hardware platforms and it is // necessary to check returned status before using the returned values. static status_t getRenderPosition(audio_io_handle_t output, - size_t *halFrames, - size_t *dspFrames, + uint32_t *halFrames, + uint32_t *dspFrames, audio_stream_type_t stream = AUDIO_STREAM_DEFAULT); // return the number of input frames lost by HAL implementation, or 0 if the handle is invalid diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h index f2f9c22..f6646ab 100644 --- a/include/media/AudioTrack.h +++ b/include/media/AudioTrack.h @@ -187,7 +187,8 @@ public: int notificationFrames = 0, int sessionId = 0, transfer_type transferType = TRANSFER_DEFAULT, - const audio_offload_info_t *offloadInfo = NULL); + const audio_offload_info_t *offloadInfo = NULL, + int uid = -1); /* Creates an audio track and registers it with AudioFlinger. * With this constructor, the track is configured for static buffer mode. @@ -211,7 +212,8 @@ public: int notificationFrames = 0, int sessionId = 0, transfer_type transferType = TRANSFER_DEFAULT, - const audio_offload_info_t *offloadInfo = NULL); + const audio_offload_info_t *offloadInfo = NULL, + int uid = -1); /* Terminates the AudioTrack and unregisters it from AudioFlinger. * Also destroys all resources associated with the AudioTrack. @@ -248,7 +250,8 @@ public: bool threadCanCallJava = false, int sessionId = 0, transfer_type transferType = TRANSFER_DEFAULT, - const audio_offload_info_t *offloadInfo = NULL); + const audio_offload_info_t *offloadInfo = NULL, + int uid = -1); /* Result of constructing the AudioTrack. This must be checked for successful initialization * before using any AudioTrack API (except for set()), because using @@ -658,7 +661,7 @@ protected: sp<AudioTrackThread> mAudioTrackThread; float mVolume[2]; float mSendLevel; - uint32_t mSampleRate; + mutable uint32_t mSampleRate; // mutable because getSampleRate() can update it. size_t mFrameCount; // corresponds to current IAudioTrack size_t mReqFrameCount; // frame count to request the next time a new // IAudioTrack is needed @@ -751,6 +754,7 @@ private: sp<DeathNotifier> mDeathNotifier; uint32_t mSequence; // incremented for each new IAudioTrack attempt audio_io_handle_t mOutput; // cached output io handle + int mClientUid; }; class TimedAudioTrack : public AudioTrack diff --git a/include/media/EffectsFactoryApi.h b/include/media/EffectsFactoryApi.h index b1143b9..b1ed7b0 100644 --- a/include/media/EffectsFactoryApi.h +++ b/include/media/EffectsFactoryApi.h @@ -171,30 +171,6 @@ int EffectGetDescriptor(const effect_uuid_t *pEffectUuid, effect_descriptor_t *p //////////////////////////////////////////////////////////////////////////////// int EffectIsNullUuid(const effect_uuid_t *pEffectUuid); -//////////////////////////////////////////////////////////////////////////////// -// -// Function: EffectGetSubEffects -// -// Description: Returns the descriptors of the sub effects of the effect -// whose uuid is pointed to by first argument. -// -// Input: -// pEffectUuid: pointer to the effect uuid. -// size: size of the buffer pointed by pDescriptor. -// -// Input/Output: -// pDescriptor: address where to return the sub effect descriptors. -// -// Output: -// returned value: 0 successful operation. -// -ENODEV factory failed to initialize -// -EINVAL invalid pEffectUuid or pDescriptor -// -ENOENT no effect with this uuid found -// *pDescriptor: updated with the sub effect descriptors. -// -//////////////////////////////////////////////////////////////////////////////// -int EffectGetSubEffects(const effect_uuid_t *pEffectUuid, effect_descriptor_t *pDescriptors, size_t size); - #if __cplusplus } // extern "C" #endif diff --git a/include/media/IAudioFlinger.h b/include/media/IAudioFlinger.h index eaf7780..282f275 100644 --- a/include/media/IAudioFlinger.h +++ b/include/media/IAudioFlinger.h @@ -74,6 +74,7 @@ public: // output: server's description of IAudioTrack for display in logs. // Don't attempt to parse, as the format could change. String8& name, + int clientUid, status_t *status) = 0; virtual sp<IAudioRecord> openRecord( @@ -166,10 +167,10 @@ public: virtual status_t setVoiceVolume(float volume) = 0; - virtual status_t getRenderPosition(size_t *halFrames, size_t *dspFrames, + virtual status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames, audio_io_handle_t output) const = 0; - virtual size_t getInputFramesLost(audio_io_handle_t ioHandle) const = 0; + virtual uint32_t getInputFramesLost(audio_io_handle_t ioHandle) const = 0; virtual int newAudioSessionId() = 0; diff --git a/include/media/MediaPlayerInterface.h b/include/media/MediaPlayerInterface.h index 3b151ef..26d8729 100644 --- a/include/media/MediaPlayerInterface.h +++ b/include/media/MediaPlayerInterface.h @@ -99,6 +99,8 @@ public: virtual status_t getPosition(uint32_t *position) const = 0; virtual status_t getFramesWritten(uint32_t *frameswritten) const = 0; virtual int getSessionId() const = 0; + virtual audio_stream_type_t getAudioStreamType() const = 0; + virtual uint32_t getSampleRate() const = 0; // If no callback is specified, use the "write" API below to submit // audio data. diff --git a/include/media/stagefright/ACodec.h b/include/media/stagefright/ACodec.h index a8ffd4a..e796ab3 100644 --- a/include/media/stagefright/ACodec.h +++ b/include/media/stagefright/ACodec.h @@ -264,6 +264,7 @@ private: status_t setupMPEG4EncoderParameters(const sp<AMessage> &msg); status_t setupH263EncoderParameters(const sp<AMessage> &msg); status_t setupAVCEncoderParameters(const sp<AMessage> &msg); + status_t setupVPXEncoderParameters(const sp<AMessage> &msg); status_t verifySupportForProfileAndLevel(int32_t profile, int32_t level); diff --git a/include/media/stagefright/AudioPlayer.h b/include/media/stagefright/AudioPlayer.h index 912a43c..14afb85 100644 --- a/include/media/stagefright/AudioPlayer.h +++ b/include/media/stagefright/AudioPlayer.h @@ -129,7 +129,7 @@ private: void reset(); uint32_t getNumFramesPendingPlayout() const; - int64_t getOutputPlayPositionUs_l() const; + int64_t getOutputPlayPositionUs_l(); bool allowDeepBuffering() const { return (mCreateFlags & ALLOW_DEEP_BUFFERING) != 0; } bool useOffload() const { return (mCreateFlags & USE_OFFLOAD) != 0; } diff --git a/include/media/stagefright/CameraSourceTimeLapse.h b/include/media/stagefright/CameraSourceTimeLapse.h index 6b7a63c..34213be 100644 --- a/include/media/stagefright/CameraSourceTimeLapse.h +++ b/include/media/stagefright/CameraSourceTimeLapse.h @@ -41,7 +41,8 @@ public: Size videoSize, int32_t videoFrameRate, const sp<IGraphicBufferProducer>& surface, - int64_t timeBetweenTimeLapseFrameCaptureUs); + int64_t timeBetweenTimeLapseFrameCaptureUs, + bool storeMetaDataInVideoBuffers = true); virtual ~CameraSourceTimeLapse(); @@ -116,7 +117,8 @@ private: Size videoSize, int32_t videoFrameRate, const sp<IGraphicBufferProducer>& surface, - int64_t timeBetweenTimeLapseFrameCaptureUs); + int64_t timeBetweenTimeLapseFrameCaptureUs, + bool storeMetaDataInVideoBuffers = true); // Wrapper over CameraSource::signalBufferReturned() to implement quick stop. // It only handles the case when mLastReadBufferCopy is signalled. Otherwise diff --git a/include/media/stagefright/DataSource.h b/include/media/stagefright/DataSource.h index 742bc0e..157b1aa 100644 --- a/include/media/stagefright/DataSource.h +++ b/include/media/stagefright/DataSource.h @@ -80,7 +80,6 @@ public: const sp<DataSource> &source, String8 *mimeType, float *confidence, sp<AMessage> *meta); - static void RegisterSniffer(SnifferFunc func); static void RegisterDefaultSniffers(); // for DRM @@ -101,6 +100,9 @@ protected: private: static Mutex gSnifferMutex; static List<SnifferFunc> gSniffers; + static bool gSniffersRegistered; + + static void RegisterSniffer_l(SnifferFunc func); DataSource(const DataSource &); DataSource &operator=(const DataSource &); diff --git a/include/media/stagefright/MetaData.h b/include/media/stagefright/MetaData.h index de3fc36..db8216b 100644 --- a/include/media/stagefright/MetaData.h +++ b/include/media/stagefright/MetaData.h @@ -134,6 +134,7 @@ enum { kKeyRequiresSecureBuffers = 'secu', // bool (int32_t) kKeyIsADTS = 'adts', // bool (int32_t) + kKeyAACAOT = 'aaot', // int32_t // If a MediaBuffer's data represents (at least partially) encrypted // data, the following fields aid in decryption. @@ -214,6 +215,8 @@ public: bool findData(uint32_t key, uint32_t *type, const void **data, size_t *size) const; + bool hasData(uint32_t key) const; + void dumpToLog() const; protected: diff --git a/include/media/stagefright/Utils.h b/include/media/stagefright/Utils.h index c24f612..bbad271 100644 --- a/include/media/stagefright/Utils.h +++ b/include/media/stagefright/Utils.h @@ -57,7 +57,8 @@ status_t mapMimeToAudioFormat(audio_format_t& format, const char* mime); status_t sendMetaDataToHal(sp<MediaPlayerBase::AudioSink>& sink, const sp<MetaData>& meta); // Check whether the stream defined by meta can be offloaded to hardware -bool canOffloadStream(const sp<MetaData>& meta, bool hasVideo, bool isStreaming); +bool canOffloadStream(const sp<MetaData>& meta, bool hasVideo, + bool isStreaming, audio_stream_type_t streamType); } // namespace android diff --git a/include/private/media/AudioTrackShared.h b/include/private/media/AudioTrackShared.h index 395f164..2d033e6 100644 --- a/include/private/media/AudioTrackShared.h +++ b/include/private/media/AudioTrackShared.h @@ -65,7 +65,9 @@ typedef SingleStateQueue<StaticAudioTrackState> StaticAudioTrackSingleStateQueue struct AudioTrackSharedStatic { StaticAudioTrackSingleStateQueue::Shared mSingleStateQueue; - size_t mBufferPosition; // updated asynchronously by server, + // This field should be a size_t, but since it is located in shared memory we + // force to 32-bit. The client and server may have different typedefs for size_t. + uint32_t mBufferPosition; // updated asynchronously by server, // "for entertainment purposes only" }; @@ -108,7 +110,9 @@ struct audio_track_cblk_t private: - size_t mMinimum; // server wakes up client if available >= mMinimum + // This field should be a size_t, but since it is located in shared memory we + // force to 32-bit. The client and server may have different typedefs for size_t. + uint32_t mMinimum; // server wakes up client if available >= mMinimum // Channel volumes are fixed point U4.12, so 0x1000 means 1.0. // Left channel is in [0:15], right channel is in [16:31]. @@ -245,7 +249,11 @@ public: } void setMinimum(size_t minimum) { - mCblk->mMinimum = minimum; + // This can only happen on a 64-bit client + if (minimum > UINT32_MAX) { + minimum = UINT32_MAX; + } + mCblk->mMinimum = (uint32_t) minimum; } // Return the number of frames that would need to be obtained and released @@ -360,6 +368,7 @@ public: // which must be > 0. // buffer->mNonContig is unused. // buffer->mRaw is unused. + // ackFlush is true iff being called from Track::start to acknowledge a pending flush. // On exit: // buffer->mFrameCount has the actual number of contiguous available frames, // which is always 0 when the return status != NO_ERROR. @@ -370,7 +379,7 @@ public: // NO_ERROR Success, buffer->mFrameCount > 0. // WOULD_BLOCK No frames are available. // NO_INIT Shared memory is corrupt. - virtual status_t obtainBuffer(Buffer* buffer); + virtual status_t obtainBuffer(Buffer* buffer, bool ackFlush = false); // Release (some of) the frames last obtained. // On entry, buffer->mFrameCount should have the number of frames to release, @@ -437,7 +446,7 @@ protected: public: virtual size_t framesReady(); virtual void framesReadyIsCalledByMultipleThreads(); - virtual status_t obtainBuffer(Buffer* buffer); + virtual status_t obtainBuffer(Buffer* buffer, bool ackFlush); virtual void releaseBuffer(Buffer* buffer); virtual void tallyUnderrunFrames(uint32_t frameCount); virtual uint32_t getUnderrunFrames() const { return 0; } diff --git a/include/private/media/StaticAudioTrackState.h b/include/private/media/StaticAudioTrackState.h index 46a5946..d483061 100644 --- a/include/private/media/StaticAudioTrackState.h +++ b/include/private/media/StaticAudioTrackState.h @@ -25,9 +25,13 @@ namespace android { // state is wrapped by a SingleStateQueue. struct StaticAudioTrackState { // do not define constructors, destructors, or virtual methods - size_t mLoopStart; - size_t mLoopEnd; - int mLoopCount; + + // These fields should both be size_t, but since they are located in shared memory we + // force to 32-bit. The client and server may have different typedefs for size_t. + uint32_t mLoopStart; + uint32_t mLoopEnd; + + int mLoopCount; }; } // namespace android diff --git a/libvideoeditor/lvpp/VideoEditorAudioPlayer.cpp b/libvideoeditor/lvpp/VideoEditorAudioPlayer.cpp index 176f8e9..e503936 100755 --- a/libvideoeditor/lvpp/VideoEditorAudioPlayer.cpp +++ b/libvideoeditor/lvpp/VideoEditorAudioPlayer.cpp @@ -671,8 +671,9 @@ size_t VideoEditorAudioPlayer::fillBuffer(void *data, size_t size) { M4OSA_Void* ptr; - ptr = (M4OSA_Void*)((unsigned int)mInputBuffer->data() + - mInputBuffer->range_offset()); + ptr = reinterpret_cast<M4OSA_Void*>( + reinterpret_cast<uintptr_t>(mInputBuffer->data()) + + mInputBuffer->range_offset()); M4OSA_UInt32 len = mInputBuffer->range_length(); M4OSA_Context fp = M4OSA_NULL; diff --git a/libvideoeditor/lvpp/VideoEditorPlayer.cpp b/libvideoeditor/lvpp/VideoEditorPlayer.cpp index 5aeba4f..8d656c4 100755 --- a/libvideoeditor/lvpp/VideoEditorPlayer.cpp +++ b/libvideoeditor/lvpp/VideoEditorPlayer.cpp @@ -585,4 +585,11 @@ int VideoEditorPlayer::VeAudioOutput::getSessionId() const { return mSessionId; } +uint32_t VideoEditorPlayer::VeAudioOutput::getSampleRate() const { + if (mMsecsPerFrame == 0) { + return 0; + } + return (uint32_t)(1.e3 / mMsecsPerFrame); +} + } // namespace android diff --git a/libvideoeditor/lvpp/VideoEditorPlayer.h b/libvideoeditor/lvpp/VideoEditorPlayer.h index ab6d731..b8c1254 100755 --- a/libvideoeditor/lvpp/VideoEditorPlayer.h +++ b/libvideoeditor/lvpp/VideoEditorPlayer.h @@ -48,6 +48,7 @@ class VideoEditorPlayer : public MediaPlayerInterface { virtual status_t getPosition(uint32_t *position) const; virtual status_t getFramesWritten(uint32_t*) const; virtual int getSessionId() const; + virtual uint32_t getSampleRate() const; virtual status_t open( uint32_t sampleRate, int channelCount, audio_channel_mask_t channelMask, @@ -62,6 +63,7 @@ class VideoEditorPlayer : public MediaPlayerInterface { virtual void pause(); virtual void close(); void setAudioStreamType(audio_stream_type_t streamType) { mStreamType = streamType; } + virtual audio_stream_type_t getAudioStreamType() const { return mStreamType; } void setVolume(float left, float right); virtual status_t dump(int fd,const Vector<String16>& args) const; diff --git a/libvideoeditor/lvpp/VideoEditorPreviewController.cpp b/libvideoeditor/lvpp/VideoEditorPreviewController.cpp index 149c4ea..c3cd3d0 100755 --- a/libvideoeditor/lvpp/VideoEditorPreviewController.cpp +++ b/libvideoeditor/lvpp/VideoEditorPreviewController.cpp @@ -1248,7 +1248,7 @@ void VideoEditorPreviewController::notify( case MEDIA_SET_VIDEO_SIZE: ALOGV("MEDIA_SET_VIDEO_SIZE; New video size %d x %d", ext1, ext2); break; - case 0xAAAAAAAA: + case static_cast<int>(0xAAAAAAAA): ALOGV("VIDEO PLAYBACK ALMOST over, prepare next player"); // Select next player and prepare it // If there is a clip after this one @@ -1268,7 +1268,7 @@ void VideoEditorPreviewController::notify( } } break; - case 0xBBBBBBBB: + case static_cast<int>(0xBBBBBBBB): { ALOGV("VIDEO PLAYBACK, Update Overlay"); int overlayIndex = ext2; diff --git a/libvideoeditor/lvpp/VideoEditorSRC.cpp b/libvideoeditor/lvpp/VideoEditorSRC.cpp index 36d0812..6beabfa 100755 --- a/libvideoeditor/lvpp/VideoEditorSRC.cpp +++ b/libvideoeditor/lvpp/VideoEditorSRC.cpp @@ -284,7 +284,7 @@ status_t VideoEditorSRC::getNextBuffer(AudioBufferProvider::Buffer *pBuffer, int void VideoEditorSRC::releaseBuffer(AudioBufferProvider::Buffer *pBuffer) { - ALOGV("releaseBuffer: %p", pBuffers); + ALOGV("releaseBuffer: %p", pBuffer); free(pBuffer->raw); pBuffer->raw = NULL; pBuffer->frameCount = 0; diff --git a/libvideoeditor/osal/inc/M4OSA_Error.h b/libvideoeditor/osal/inc/M4OSA_Error.h index 4d59529..75c3177 100755 --- a/libvideoeditor/osal/inc/M4OSA_Error.h +++ b/libvideoeditor/osal/inc/M4OSA_Error.h @@ -57,7 +57,7 @@ typedef M4OSA_UInt32 M4OSA_ERR; * @arg coreID: (IN) [M4OSA_UInt32] CoreID to put in the error code * @arg errorID: (IN) [M4OSA_UInt32] ErrorID to put in the error code*/ #define M4OSA_ERR_CREATE(severity, coreID, errorID)\ - (M4OSA_Int32)((((M4OSA_UInt32)severity)<<30)+((((M4OSA_UInt32)coreID)&0x003FFF)<<16)+(((M4OSA_UInt32)errorID)&0x00FFFF)) + (M4OSA_UInt32)((((M4OSA_UInt32)severity)<<30)+((((M4OSA_UInt32)coreID)&0x003FFF)<<16)+(((M4OSA_UInt32)errorID)&0x00FFFF)) /** This macro extracts the 3 fields from the error: * @arg error: (IN) [M4OSA_ERR] Error code diff --git a/libvideoeditor/vss/src/M4DECODER_Null.c b/libvideoeditor/vss/src/M4DECODER_Null.c index a0dad30..ce260e5 100755 --- a/libvideoeditor/vss/src/M4DECODER_Null.c +++ b/libvideoeditor/vss/src/M4DECODER_Null.c @@ -210,7 +210,7 @@ M4OSA_ERR M4DECODER_NULL_setOption(M4OSA_Context context, break;
case M4DECODER_kOptionID_EnableYuvWithEffect:
- pStreamContext->bYuvWithEffectSet = (M4OSA_Bool)pValue;
+ pStreamContext->bYuvWithEffectSet = (M4OSA_Bool)(intptr_t)pValue;
break;
case M4DECODER_kOptionID_YuvWithEffectNonContiguous:
diff --git a/libvideoeditor/vss/stagefrightshells/src/VideoEditor3gpReader.cpp b/libvideoeditor/vss/stagefrightshells/src/VideoEditor3gpReader.cpp index 3c8915a..99cf9ec 100755 --- a/libvideoeditor/vss/stagefrightshells/src/VideoEditor3gpReader.cpp +++ b/libvideoeditor/vss/stagefrightshells/src/VideoEditor3gpReader.cpp @@ -776,16 +776,16 @@ M4OSA_ERR VideoEditor3gpReader_setOption(M4OSA_Context context, case M4READER_kOptionID_SetOsaFileReaderFctsPtr: break; - case M4READER_3GP_kOptionID_AudioOnly: + case static_cast<M4OSA_OptionID>(M4READER_3GP_kOptionID_AudioOnly): break; - case M4READER_3GP_kOptionID_VideoOnly: + case static_cast<M4OSA_OptionID>(M4READER_3GP_kOptionID_VideoOnly): break; - case M4READER_3GP_kOptionID_FastOpenMode: + case static_cast<M4OSA_OptionID>(M4READER_3GP_kOptionID_FastOpenMode): break; - case M4READER_kOptionID_MaxMetadataSize: + case static_cast<M4OSA_OptionID>(M4READER_kOptionID_MaxMetadataSize): break; default: diff --git a/libvideoeditor/vss/stagefrightshells/src/VideoEditorAudioDecoder.cpp b/libvideoeditor/vss/stagefrightshells/src/VideoEditorAudioDecoder.cpp index 9b35d07..e4c7ea1 100755 --- a/libvideoeditor/vss/stagefrightshells/src/VideoEditorAudioDecoder.cpp +++ b/libvideoeditor/vss/stagefrightshells/src/VideoEditorAudioDecoder.cpp @@ -809,7 +809,7 @@ M4OSA_ERR VideoEditorAudioDecoder_setOption(M4AD_Context pContext, pDecoderContext = (VideoEditorAudioDecoder_Context*)pContext; switch( optionID ) { - case M4AD_kOptionID_UserParam: + case static_cast<M4OSA_UInt32>(M4AD_kOptionID_UserParam): ALOGV("VideoEditorAudioDecodersetOption UserParam is not supported"); err = M4ERR_NOT_IMPLEMENTED; break; diff --git a/libvideoeditor/vss/stagefrightshells/src/VideoEditorUtils.cpp b/libvideoeditor/vss/stagefrightshells/src/VideoEditorUtils.cpp index 5a7237d..d264a2e 100755 --- a/libvideoeditor/vss/stagefrightshells/src/VideoEditorUtils.cpp +++ b/libvideoeditor/vss/stagefrightshells/src/VideoEditorUtils.cpp @@ -84,17 +84,17 @@ void displayMetaData(const sp<MetaData> meta) { LOG1("displayMetaData kKeyBitRate %d", int32Data); } if (meta->findData(kKeyESDS, &type, &data, &size)) { - LOG1("displayMetaData kKeyESDS type=%d size=%d", type, size); + LOG1("displayMetaData kKeyESDS type=%d size=%zu", type, size); } if (meta->findData(kKeyAVCC, &type, &data, &size)) { - LOG1("displayMetaData kKeyAVCC data=0x%X type=%d size=%d", + LOG1("displayMetaData kKeyAVCC data=0x%X type=%d size=%zu", *((unsigned int*)data), type, size); } if (meta->findData(kKeyVorbisInfo, &type, &data, &size)) { - LOG1("displayMetaData kKeyVorbisInfo type=%d size=%d", type, size); + LOG1("displayMetaData kKeyVorbisInfo type=%d size=%zu", type, size); } if (meta->findData(kKeyVorbisBooks, &type, &data, &size)) { - LOG1("displayMetaData kKeyVorbisBooks type=%d size=%d", type, size); + LOG1("displayMetaData kKeyVorbisBooks type=%d size=%zu", type, size); } if (meta->findInt32(kKeyWantsNALFragments, &int32Data)) { LOG1("displayMetaData kKeyWantsNALFragments %d", int32Data); @@ -115,7 +115,7 @@ void displayMetaData(const sp<MetaData> meta) { LOG1("displayMetaData kKeyColorFormat %d", int32Data); } if (meta->findPointer(kKeyPlatformPrivate, &ptr)) { - LOG1("displayMetaData kKeyPlatformPrivate pointer=0x%x", (int32_t) ptr); + LOG1("displayMetaData kKeyPlatformPrivate pointer=%p", ptr); } if (meta->findCString(kKeyDecoderComponent, &charData)) { LOG1("displayMetaData kKeyDecoderComponent %s", charData); @@ -151,7 +151,7 @@ void displayMetaData(const sp<MetaData> meta) { LOG1("displayMetaData kKeyYear %s", charData); } if (meta->findData(kKeyAlbumArt, &type, &data, &size)) { - LOG1("displayMetaData kKeyAlbumArt type=%d size=%d", type, size); + LOG1("displayMetaData kKeyAlbumArt type=%d size=%zu", type, size); } if (meta->findCString(kKeyAlbumArtMIME, &charData)) { LOG1("displayMetaData kKeyAlbumArtMIME %s", charData); @@ -277,7 +277,7 @@ status_t buildAVCCodecSpecificData(uint8_t **pOutputData, size_t *pOutputSize, } if (size < 4) { - ALOGE("Codec specific data length too short: %d", size); + ALOGE("Codec specific data length too short: %zu", size); return ERROR_MALFORMED; } @@ -286,7 +286,7 @@ status_t buildAVCCodecSpecificData(uint8_t **pOutputData, size_t *pOutputSize, // 2 bytes for each of the parameter set length field // plus the 7 bytes for the header if (size < 4 + 7) { - ALOGE("Codec specific data length too short: %d", size); + ALOGE("Codec specific data length too short: %zu", size); return ERROR_MALFORMED; } @@ -355,7 +355,7 @@ status_t buildAVCCodecSpecificData(uint8_t **pOutputData, size_t *pOutputSize, } if (nSeqParamSets > 0x1F) { - ALOGE("Too many seq parameter sets (%d) found", nSeqParamSets); + ALOGE("Too many seq parameter sets (%zu) found", nSeqParamSets); return ERROR_MALFORMED; } } @@ -368,7 +368,7 @@ status_t buildAVCCodecSpecificData(uint8_t **pOutputData, size_t *pOutputSize, return ERROR_MALFORMED; } if (nPicParamSets > 0xFF) { - ALOGE("Too many pic parameter sets (%d) found", nPicParamSets); + ALOGE("Too many pic parameter sets (%zu) found", nPicParamSets); return ERROR_MALFORMED; } } diff --git a/media/libeffects/downmix/Android.mk b/media/libeffects/downmix/Android.mk index 5d0a87c..2bb6dbe 100644 --- a/media/libeffects/downmix/Android.mk +++ b/media/libeffects/downmix/Android.mk @@ -13,7 +13,7 @@ LOCAL_MODULE:= libdownmix LOCAL_MODULE_TAGS := optional -LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/soundfx +LOCAL_MODULE_RELATIVE_PATH := soundfx ifeq ($(TARGET_OS)-$(TARGET_SIMULATOR),linux-true) LOCAL_LDLIBS += -ldl diff --git a/media/libeffects/downmix/EffectDownmix.c b/media/libeffects/downmix/EffectDownmix.c index f779876..4ee05f2 100644 --- a/media/libeffects/downmix/EffectDownmix.c +++ b/media/libeffects/downmix/EffectDownmix.c @@ -707,7 +707,7 @@ int Downmix_setParameter(downmix_object_t *pDownmixer, int32_t param, size_t siz case DOWNMIX_PARAM_TYPE: if (size != sizeof(downmix_type_t)) { - ALOGE("Downmix_setParameter(DOWNMIX_PARAM_TYPE) invalid size %d, should be %d", + ALOGE("Downmix_setParameter(DOWNMIX_PARAM_TYPE) invalid size %zu, should be %zu", size, sizeof(downmix_type_t)); return -EINVAL; } @@ -760,7 +760,7 @@ int Downmix_getParameter(downmix_object_t *pDownmixer, int32_t param, size_t *pS case DOWNMIX_PARAM_TYPE: if (*pSize < sizeof(int16_t)) { - ALOGE("Downmix_getParameter invalid parameter size %d for DOWNMIX_PARAM_TYPE", *pSize); + ALOGE("Downmix_getParameter invalid parameter size %zu for DOWNMIX_PARAM_TYPE", *pSize); return -EINVAL; } pValue16 = (int16_t *)pValue; diff --git a/media/libeffects/factory/Android.mk b/media/libeffects/factory/Android.mk index 60a6ce5..a932af7 100644 --- a/media/libeffects/factory/Android.mk +++ b/media/libeffects/factory/Android.mk @@ -9,7 +9,6 @@ LOCAL_SRC_FILES:= \ LOCAL_SHARED_LIBRARIES := \ libcutils liblog -LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES) LOCAL_MODULE:= libeffects LOCAL_SHARED_LIBRARIES += libdl diff --git a/media/libeffects/factory/EffectsFactory.c b/media/libeffects/factory/EffectsFactory.c index f8d6041..6d30d64 100644 --- a/media/libeffects/factory/EffectsFactory.c +++ b/media/libeffects/factory/EffectsFactory.c @@ -368,27 +368,21 @@ int EffectRelease(effect_handle_t handle) } if (e1 == NULL) { ret = -ENOENT; - pthread_mutex_unlock(&gLibLock); goto exit; } // release effect in library if (fx->lib == NULL) { ALOGW("EffectRelease() fx %p library already unloaded", handle); - pthread_mutex_unlock(&gLibLock); } else { pthread_mutex_lock(&fx->lib->lock); - // Releasing the gLibLock here as the list access is over as the - // effect is removed from the list. - // If the gLibLock is not released, we will have a deadlock situation - // since we call the sub effect release inside the EffectRelease of Proxy - pthread_mutex_unlock(&gLibLock); fx->lib->desc->release_effect(fx->subItfe); pthread_mutex_unlock(&fx->lib->lock); } free(fx); exit: + pthread_mutex_unlock(&gLibLock); return ret; } @@ -404,8 +398,8 @@ int EffectIsNullUuid(const effect_uuid_t *uuid) // is pointed by the first argument. It searches the gSubEffectList for the // matching uuid and then copies the corresponding sub effect descriptors // to the inout param -int EffectGetSubEffects(const effect_uuid_t *uuid, - effect_descriptor_t *pDescriptors, size_t size) +int EffectGetSubEffects(const effect_uuid_t *uuid, sub_effect_entry_t **pSube, + size_t size) { ALOGV("EffectGetSubEffects() UUID: %08X-%04X-%04X-%04X-%02X%02X%02X%02X%02X" "%02X\n",uuid->timeLow, uuid->timeMid, uuid->timeHiAndVersion, @@ -413,8 +407,7 @@ int EffectGetSubEffects(const effect_uuid_t *uuid, uuid->node[3],uuid->node[4],uuid->node[5]); // Check if the size of the desc buffer is large enough for 2 subeffects - if ((uuid == NULL) || (pDescriptors == NULL) || - (size < 2*sizeof(effect_descriptor_t))) { + if ((uuid == NULL) || (pSube == NULL) || (size < 2)) { ALOGW("NULL pointer or insufficient memory. Cannot query subeffects"); return -EINVAL; } @@ -432,11 +425,10 @@ int EffectGetSubEffects(const effect_uuid_t *uuid, list_elem_t *subefx = e->sub_elem; while (subefx != NULL) { subeffect = (sub_effect_entry_t*)subefx->object; - d = (effect_descriptor_t*)(subeffect->object); - pDescriptors[count++] = *d; + pSube[count++] = subeffect; subefx = subefx->next; } - ALOGV("EffectGetSubEffects end - copied the sub effect descriptors"); + ALOGV("EffectGetSubEffects end - copied the sub effect structures"); return count; } e = e->next; diff --git a/media/libeffects/factory/EffectsFactory.h b/media/libeffects/factory/EffectsFactory.h index 147ff18..560b485 100644 --- a/media/libeffects/factory/EffectsFactory.h +++ b/media/libeffects/factory/EffectsFactory.h @@ -20,7 +20,7 @@ #include <cutils/log.h> #include <pthread.h> #include <dirent.h> -#include <media/EffectsFactoryApi.h> +#include <hardware/audio_effect.h> #if __cplusplus extern "C" { @@ -66,6 +66,32 @@ typedef struct sub_effect_entry_s { void *object; } sub_effect_entry_t; + +//////////////////////////////////////////////////////////////////////////////// +// +// Function: EffectGetSubEffects +// +// Description: Returns the descriptors of the sub effects of the effect +// whose uuid is pointed to by first argument. +// +// Input: +// pEffectUuid: pointer to the effect uuid. +// size: max number of sub_effect_entry_t * in pSube. +// +// Input/Output: +// pSube: address where to return the sub effect structures. +// Output: +// returned value: 0 successful operation. +// -ENODEV factory failed to initialize +// -EINVAL invalid pEffectUuid or pDescriptor +// -ENOENT no effect with this uuid found +// *pDescriptor: updated with the sub effect descriptors. +// +//////////////////////////////////////////////////////////////////////////////// +int EffectGetSubEffects(const effect_uuid_t *pEffectUuid, + sub_effect_entry_t **pSube, + size_t size); + #if __cplusplus } // extern "C" #endif diff --git a/media/libeffects/loudness/Android.mk b/media/libeffects/loudness/Android.mk index dcb7b27..edf964e 100644 --- a/media/libeffects/loudness/Android.mk +++ b/media/libeffects/loudness/Android.mk @@ -14,7 +14,7 @@ LOCAL_SHARED_LIBRARIES := \ liblog \ libstlport -LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/soundfx +LOCAL_MODULE_RELATIVE_PATH := soundfx LOCAL_MODULE:= libldnhncr LOCAL_C_INCLUDES := \ diff --git a/media/libeffects/loudness/EffectLoudnessEnhancer.cpp b/media/libeffects/loudness/EffectLoudnessEnhancer.cpp index 91ed677..3c2b320 100644 --- a/media/libeffects/loudness/EffectLoudnessEnhancer.cpp +++ b/media/libeffects/loudness/EffectLoudnessEnhancer.cpp @@ -453,13 +453,13 @@ const struct effect_interface_s gLEInterface = { // This is the only symbol that needs to be exported __attribute__ ((visibility ("default"))) audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = { - tag : AUDIO_EFFECT_LIBRARY_TAG, - version : EFFECT_LIBRARY_API_VERSION, - name : "Loudness Enhancer Library", - implementor : "The Android Open Source Project", - create_effect : LELib_Create, - release_effect : LELib_Release, - get_descriptor : LELib_GetDescriptor, + .tag = AUDIO_EFFECT_LIBRARY_TAG, + .version = EFFECT_LIBRARY_API_VERSION, + .name = "Loudness Enhancer Library", + .implementor = "The Android Open Source Project", + .create_effect = LELib_Create, + .release_effect = LELib_Release, + .get_descriptor = LELib_GetDescriptor, }; }; // extern "C" diff --git a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Init.c b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Init.c index c4767a8..e01c1c5 100644 --- a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Init.c +++ b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Init.c @@ -25,6 +25,7 @@ #include "LVEQNB.h" #include "LVEQNB_Private.h" #include "InstAlloc.h" +#include <string.h> /* For memset */ /****************************************************************************************/ /* */ diff --git a/media/libeffects/lvm/wrapper/Android.mk b/media/libeffects/lvm/wrapper/Android.mk index f1af389..68ba34c 100644 --- a/media/libeffects/lvm/wrapper/Android.mk +++ b/media/libeffects/lvm/wrapper/Android.mk @@ -13,7 +13,7 @@ LOCAL_CFLAGS += -fvisibility=hidden LOCAL_MODULE:= libbundlewrapper -LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/soundfx +LOCAL_MODULE_RELATIVE_PATH := soundfx LOCAL_STATIC_LIBRARIES += libmusicbundle @@ -42,7 +42,7 @@ LOCAL_CFLAGS += -fvisibility=hidden LOCAL_MODULE:= libreverbwrapper -LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/soundfx +LOCAL_MODULE_RELATIVE_PATH := soundfx LOCAL_STATIC_LIBRARIES += libreverb diff --git a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp index 28d239a..58d7767 100644 --- a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp +++ b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp @@ -138,22 +138,22 @@ void Effect_getConfig (EffectContext *pContext, effect_config_t *pConfi int BassBoost_setParameter (EffectContext *pContext, void *pParam, void *pValue); int BassBoost_getParameter (EffectContext *pContext, void *pParam, - size_t *pValueSize, + uint32_t *pValueSize, void *pValue); int Virtualizer_setParameter (EffectContext *pContext, void *pParam, void *pValue); int Virtualizer_getParameter (EffectContext *pContext, void *pParam, - size_t *pValueSize, + uint32_t *pValueSize, void *pValue); int Equalizer_setParameter (EffectContext *pContext, void *pParam, void *pValue); int Equalizer_getParameter (EffectContext *pContext, void *pParam, - size_t *pValueSize, + uint32_t *pValueSize, void *pValue); int Volume_setParameter (EffectContext *pContext, void *pParam, void *pValue); int Volume_getParameter (EffectContext *pContext, void *pParam, - size_t *pValueSize, + uint32_t *pValueSize, void *pValue); int Effect_setEnabled(EffectContext *pContext, bool enabled); @@ -1758,7 +1758,7 @@ int32_t VolumeEnableStereoPosition(EffectContext *pContext, uint32_t enabled){ int BassBoost_getParameter(EffectContext *pContext, void *pParam, - size_t *pValueSize, + uint32_t *pValueSize, void *pValue){ int status = 0; int32_t *pParamTemp = (int32_t *)pParam; @@ -1876,7 +1876,7 @@ int BassBoost_setParameter (EffectContext *pContext, void *pParam, void *pValue) int Virtualizer_getParameter(EffectContext *pContext, void *pParam, - size_t *pValueSize, + uint32_t *pValueSize, void *pValue){ int status = 0; int32_t *pParamTemp = (int32_t *)pParam; @@ -1994,7 +1994,7 @@ int Virtualizer_setParameter (EffectContext *pContext, void *pParam, void *pValu //---------------------------------------------------------------------------- int Equalizer_getParameter(EffectContext *pContext, void *pParam, - size_t *pValueSize, + uint32_t *pValueSize, void *pValue){ int status = 0; int bMute = 0; @@ -2252,7 +2252,7 @@ int Equalizer_setParameter (EffectContext *pContext, void *pParam, void *pValue) int Volume_getParameter(EffectContext *pContext, void *pParam, - size_t *pValueSize, + uint32_t *pValueSize, void *pValue){ int status = 0; int bMute = 0; @@ -2830,7 +2830,7 @@ int Effect_command(effect_handle_t self, p->status = android::BassBoost_getParameter(pContext, p->data, - (size_t *)&p->vsize, + &p->vsize, p->data + voffset); *replySize = sizeof(effect_param_t) + voffset + p->vsize; @@ -2860,8 +2860,8 @@ int Effect_command(effect_handle_t self, int voffset = ((p->psize - 1) / sizeof(int32_t) + 1) * sizeof(int32_t); p->status = android::Virtualizer_getParameter(pContext, - (void *)p->data, - (size_t *)&p->vsize, + (void *)p->data, + &p->vsize, p->data + voffset); *replySize = sizeof(effect_param_t) + voffset + p->vsize; @@ -2925,7 +2925,7 @@ int Effect_command(effect_handle_t self, p->status = android::Volume_getParameter(pContext, (void *)p->data, - (size_t *)&p->vsize, + &p->vsize, p->data + voffset); *replySize = sizeof(effect_param_t) + voffset + p->vsize; diff --git a/media/libeffects/preprocessing/Android.mk b/media/libeffects/preprocessing/Android.mk index c344352..9e8cb83 100644 --- a/media/libeffects/preprocessing/Android.mk +++ b/media/libeffects/preprocessing/Android.mk @@ -5,7 +5,7 @@ include $(CLEAR_VARS) LOCAL_MODULE:= libaudiopreprocessing LOCAL_MODULE_TAGS := optional -LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/soundfx +LOCAL_MODULE_RELATIVE_PATH := soundfx LOCAL_SRC_FILES:= \ PreProcessing.cpp diff --git a/media/libeffects/preprocessing/PreProcessing.cpp b/media/libeffects/preprocessing/PreProcessing.cpp index d72eaf5..c56ff72 100644 --- a/media/libeffects/preprocessing/PreProcessing.cpp +++ b/media/libeffects/preprocessing/PreProcessing.cpp @@ -1233,8 +1233,8 @@ int PreProcessingFx_Process(effect_handle_t self, if (session->framesIn < session->frameCount) { return 0; } - size_t frIn = session->framesIn; - size_t frOut = session->apmFrameCount; + spx_uint32_t frIn = session->framesIn; + spx_uint32_t frOut = session->apmFrameCount; if (session->inChannelCount == 1) { speex_resampler_process_int(session->inResampler, 0, @@ -1290,8 +1290,8 @@ int PreProcessingFx_Process(effect_handle_t self, } if (session->outResampler != NULL) { - size_t frIn = session->apmFrameCount; - size_t frOut = session->frameCount; + spx_uint32_t frIn = session->apmFrameCount; + spx_uint32_t frOut = session->frameCount; if (session->inChannelCount == 1) { speex_resampler_process_int(session->outResampler, 0, @@ -1754,8 +1754,8 @@ int PreProcessingFx_ProcessReverse(effect_handle_t self, if (session->framesRev < session->frameCount) { return 0; } - size_t frIn = session->framesRev; - size_t frOut = session->apmFrameCount; + spx_uint32_t frIn = session->framesRev; + spx_uint32_t frOut = session->apmFrameCount; if (session->inChannelCount == 1) { speex_resampler_process_int(session->revResampler, 0, diff --git a/media/libeffects/proxy/Android.mk b/media/libeffects/proxy/Android.mk index 01b3be1..b438796 100644 --- a/media/libeffects/proxy/Android.mk +++ b/media/libeffects/proxy/Android.mk @@ -15,7 +15,7 @@ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE:= libeffectproxy -LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/soundfx +LOCAL_MODULE_RELATIVE_PATH := soundfx LOCAL_MODULE_TAGS := optional @@ -28,7 +28,8 @@ LOCAL_SHARED_LIBRARIES := liblog libcutils libutils libdl libeffects LOCAL_C_INCLUDES := \ system/media/audio_effects/include \ - bionic/libc/include + bionic/libc/include \ + frameworks/av/media/libeffects/factory include $(BUILD_SHARED_LIBRARY) diff --git a/media/libeffects/proxy/EffectProxy.cpp b/media/libeffects/proxy/EffectProxy.cpp index dd4ad08..62d3fd3 100644 --- a/media/libeffects/proxy/EffectProxy.cpp +++ b/media/libeffects/proxy/EffectProxy.cpp @@ -56,6 +56,8 @@ int EffectProxyCreate(const effect_uuid_t *uuid, effect_handle_t *pHandle) { effect_descriptor_t* desc; + audio_effect_library_t** aeli; + sub_effect_entry_t** sube; EffectContext* pContext; if (pHandle == NULL || uuid == NULL) { ALOGE("EffectProxyCreate() called with NULL pointer"); @@ -74,31 +76,52 @@ int EffectProxyCreate(const effect_uuid_t *uuid, // Get the HW and SW sub effect descriptors from the effects factory desc = new effect_descriptor_t[SUB_FX_COUNT]; + aeli = new audio_effect_library_t*[SUB_FX_COUNT]; + sube = new sub_effect_entry_t*[SUB_FX_COUNT]; + pContext->sube = new sub_effect_entry_t*[SUB_FX_COUNT]; pContext->desc = new effect_descriptor_t[SUB_FX_COUNT]; - int retValue = EffectGetSubEffects(uuid, desc, - sizeof(effect_descriptor_t) * SUB_FX_COUNT); + pContext->aeli = new audio_effect_library_t*[SUB_FX_COUNT]; + int retValue = EffectGetSubEffects(uuid, sube, SUB_FX_COUNT); // EffectGetSubEffects returns the number of sub-effects copied. if (retValue != SUB_FX_COUNT) { ALOGE("EffectCreate() could not get the sub effects"); - delete desc; - delete pContext->desc; + delete[] sube; + delete[] desc; + delete[] aeli; + delete[] pContext->sube; + delete[] pContext->desc; + delete[] pContext->aeli; return -EINVAL; } // Check which is the HW descriptor and copy the descriptors // to the Context desc array // Also check if there is only one HW and one SW descriptor. // HW descriptor alone has the HW_TUNNEL flag. + desc[0] = *(effect_descriptor_t*)(sube[0])->object; + desc[1] = *(effect_descriptor_t*)(sube[1])->object; + aeli[0] = sube[0]->lib->desc; + aeli[1] = sube[1]->lib->desc; if ((desc[0].flags & EFFECT_FLAG_HW_ACC_TUNNEL) && !(desc[1].flags & EFFECT_FLAG_HW_ACC_TUNNEL)) { + pContext->sube[SUB_FX_OFFLOAD] = sube[0]; pContext->desc[SUB_FX_OFFLOAD] = desc[0]; + pContext->aeli[SUB_FX_OFFLOAD] = aeli[0]; + pContext->sube[SUB_FX_HOST] = sube[1]; pContext->desc[SUB_FX_HOST] = desc[1]; + pContext->aeli[SUB_FX_HOST] = aeli[1]; } else if ((desc[1].flags & EFFECT_FLAG_HW_ACC_TUNNEL) && !(desc[0].flags & EFFECT_FLAG_HW_ACC_TUNNEL)) { + pContext->sube[SUB_FX_HOST] = sube[0]; pContext->desc[SUB_FX_HOST] = desc[0]; + pContext->aeli[SUB_FX_HOST] = aeli[0]; + pContext->sube[SUB_FX_OFFLOAD] = sube[1]; pContext->desc[SUB_FX_OFFLOAD] = desc[1]; + pContext->aeli[SUB_FX_OFFLOAD] = aeli[1]; } - delete desc; + delete[] desc; + delete[] aeli; + delete[] sube; #if (LOG_NDEBUG == 0) effect_uuid_t uuid_print = pContext->desc[SUB_FX_HOST].uuid; ALOGV("EffectCreate() UUID of HOST: %08X-%04X-%04X-%04X-%02X%02X%02X%02X" @@ -128,13 +151,15 @@ int EffectProxyRelease(effect_handle_t handle) { return -EINVAL; } ALOGV("EffectRelease"); - delete pContext->desc; + delete[] pContext->desc; free(pContext->replyData); if (pContext->eHandle[SUB_FX_HOST]) - EffectRelease(pContext->eHandle[SUB_FX_HOST]); + pContext->aeli[SUB_FX_HOST]->release_effect(pContext->eHandle[SUB_FX_HOST]); if (pContext->eHandle[SUB_FX_OFFLOAD]) - EffectRelease(pContext->eHandle[SUB_FX_OFFLOAD]); + pContext->aeli[SUB_FX_OFFLOAD]->release_effect(pContext->eHandle[SUB_FX_OFFLOAD]); + delete[] pContext->aeli; + delete[] pContext->sube; delete pContext; pContext = NULL; return 0; @@ -187,7 +212,8 @@ int Effect_command(effect_handle_t self, } if (pContext->eHandle[SUB_FX_HOST] == NULL) { ALOGV("Effect_command() Calling HOST EffectCreate"); - status = EffectCreate(&pContext->desc[SUB_FX_HOST].uuid, + status = pContext->aeli[SUB_FX_HOST]->create_effect( + &pContext->desc[SUB_FX_HOST].uuid, pContext->sessionId, pContext->ioId, &(pContext->eHandle[SUB_FX_HOST])); if (status != NO_ERROR || (pContext->eHandle[SUB_FX_HOST] == NULL)) { @@ -197,11 +223,13 @@ int Effect_command(effect_handle_t self, } if (pContext->eHandle[SUB_FX_OFFLOAD] == NULL) { ALOGV("Effect_command() Calling OFFLOAD EffectCreate"); - status = EffectCreate(&pContext->desc[SUB_FX_OFFLOAD].uuid, + status = pContext->aeli[SUB_FX_OFFLOAD]->create_effect( + &pContext->desc[SUB_FX_OFFLOAD].uuid, pContext->sessionId, pContext->ioId, &(pContext->eHandle[SUB_FX_OFFLOAD])); if (status != NO_ERROR || (pContext->eHandle[SUB_FX_OFFLOAD] == NULL)) { ALOGV("Effect_command() Error creating HW effect"); + pContext->eHandle[SUB_FX_OFFLOAD] = NULL; // Do not return error here as SW effect is created // Return error if the CMD_OFFLOAD sends the index as OFFLOAD } @@ -233,11 +261,17 @@ int Effect_command(effect_handle_t self, // Update the DSP wrapper with the new ioHandle. // Pass the OFFLOAD command to the wrapper. // The DSP wrapper needs to handle this CMD - if (pContext->eHandle[SUB_FX_OFFLOAD]) - status = (*pContext->eHandle[SUB_FX_OFFLOAD])->command( - pContext->eHandle[SUB_FX_OFFLOAD], cmdCode, cmdSize, - pCmdData, replySize, pReplyData); - return status; + if (pContext->eHandle[SUB_FX_OFFLOAD]) { + ALOGV("Effect_command: Calling OFFLOAD command"); + return (*pContext->eHandle[SUB_FX_OFFLOAD])->command( + pContext->eHandle[SUB_FX_OFFLOAD], cmdCode, cmdSize, + pCmdData, replySize, pReplyData); + } + *(int*)pReplyData = NO_ERROR; + ALOGV("Effect_command OFFLOAD return 0, replyData %d", + *(int*)pReplyData); + + return NO_ERROR; } int index = pContext->index; @@ -329,11 +363,11 @@ int Effect_getDescriptor(effect_handle_t self, __attribute__ ((visibility ("default"))) audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = { - tag : AUDIO_EFFECT_LIBRARY_TAG, - version : EFFECT_LIBRARY_API_VERSION, - name : "Effect Proxy", - implementor : "AOSP", - create_effect : android::EffectProxyCreate, - release_effect : android::EffectProxyRelease, - get_descriptor : android::EffectProxyGetDescriptor, + .tag = AUDIO_EFFECT_LIBRARY_TAG, + .version = EFFECT_LIBRARY_API_VERSION, + .name = "Effect Proxy", + .implementor = "AOSP", + .create_effect = android::EffectProxyCreate, + .release_effect = android::EffectProxyRelease, + .get_descriptor = android::EffectProxyGetDescriptor, }; diff --git a/media/libeffects/proxy/EffectProxy.h b/media/libeffects/proxy/EffectProxy.h index acbe17e..046b93e 100644 --- a/media/libeffects/proxy/EffectProxy.h +++ b/media/libeffects/proxy/EffectProxy.h @@ -16,6 +16,8 @@ #include <hardware/audio.h> #include <hardware/audio_effect.h> +#include "EffectsFactory.h" + namespace android { enum { SUB_FX_HOST, // Index of HOST in the descriptor and handle arrays @@ -62,7 +64,9 @@ const struct effect_interface_s gEffectInterface = { struct EffectContext { const struct effect_interface_s *common_itfe; // Holds the itfe of the Proxy + sub_effect_entry_t** sube; // Points to the sub effects effect_descriptor_t* desc; // Points to the sub effect descriptors + audio_effect_library_t** aeli; // Points to the sub effect aeli effect_handle_t eHandle[SUB_FX_COUNT]; // The effect handles of the sub effects int index; // The index that is currently active - HOST or OFFLOAD int32_t sessionId; // The sessiond in which the effect is created. diff --git a/media/libeffects/testlibs/Android.mk_ b/media/libeffects/testlibs/Android.mk_ index 2954908..672ebba 100644 --- a/media/libeffects/testlibs/Android.mk_ +++ b/media/libeffects/testlibs/Android.mk_ @@ -11,7 +11,7 @@ LOCAL_CFLAGS+= -O2 LOCAL_SHARED_LIBRARIES := \ libcutils -LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/soundfx +LOCAL_MODULE_RELATIVE_PATH := soundfx LOCAL_MODULE:= libreverbtest ifeq ($(TARGET_OS)-$(TARGET_SIMULATOR),linux-true) @@ -47,7 +47,7 @@ LOCAL_CFLAGS+= -O2 LOCAL_SHARED_LIBRARIES := \ libcutils -LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/soundfx +LOCAL_MODULE_RELATIVE_PATH := soundfx LOCAL_MODULE:= libequalizertest ifeq ($(TARGET_OS)-$(TARGET_SIMULATOR),linux-true) diff --git a/media/libeffects/visualizer/Android.mk b/media/libeffects/visualizer/Android.mk index e196eb2..dd2d306 100644 --- a/media/libeffects/visualizer/Android.mk +++ b/media/libeffects/visualizer/Android.mk @@ -13,7 +13,7 @@ LOCAL_SHARED_LIBRARIES := \ liblog \ libdl -LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/soundfx +LOCAL_MODULE_RELATIVE_PATH := soundfx LOCAL_MODULE:= libvisualizer LOCAL_C_INCLUDES := \ diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp index 8033c2c..cc5b810 100644 --- a/media/libmedia/AudioSystem.cpp +++ b/media/libmedia/AudioSystem.cpp @@ -370,8 +370,8 @@ status_t AudioSystem::setVoiceVolume(float value) return af->setVoiceVolume(value); } -status_t AudioSystem::getRenderPosition(audio_io_handle_t output, size_t *halFrames, - size_t *dspFrames, audio_stream_type_t stream) +status_t AudioSystem::getRenderPosition(audio_io_handle_t output, uint32_t *halFrames, + uint32_t *dspFrames, audio_stream_type_t stream) { const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); if (af == 0) return PERMISSION_DENIED; diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp index fe5cd9e..a9d6993 100644 --- a/media/libmedia/AudioTrack.cpp +++ b/media/libmedia/AudioTrack.cpp @@ -101,7 +101,8 @@ AudioTrack::AudioTrack( int notificationFrames, int sessionId, transfer_type transferType, - const audio_offload_info_t *offloadInfo) + const audio_offload_info_t *offloadInfo, + int uid) : mStatus(NO_INIT), mIsTimed(false), mPreviousPriority(ANDROID_PRIORITY_NORMAL), @@ -109,7 +110,8 @@ AudioTrack::AudioTrack( { mStatus = set(streamType, sampleRate, format, channelMask, frameCount, flags, cbf, user, notificationFrames, - 0 /*sharedBuffer*/, false /*threadCanCallJava*/, sessionId, transferType, offloadInfo); + 0 /*sharedBuffer*/, false /*threadCanCallJava*/, sessionId, transferType, + offloadInfo, uid); } AudioTrack::AudioTrack( @@ -124,7 +126,8 @@ AudioTrack::AudioTrack( int notificationFrames, int sessionId, transfer_type transferType, - const audio_offload_info_t *offloadInfo) + const audio_offload_info_t *offloadInfo, + int uid) : mStatus(NO_INIT), mIsTimed(false), mPreviousPriority(ANDROID_PRIORITY_NORMAL), @@ -132,7 +135,7 @@ AudioTrack::AudioTrack( { mStatus = set(streamType, sampleRate, format, channelMask, 0 /*frameCount*/, flags, cbf, user, notificationFrames, - sharedBuffer, false /*threadCanCallJava*/, sessionId, transferType, offloadInfo); + sharedBuffer, false /*threadCanCallJava*/, sessionId, transferType, offloadInfo, uid); } AudioTrack::~AudioTrack() @@ -169,7 +172,8 @@ status_t AudioTrack::set( bool threadCanCallJava, int sessionId, transfer_type transferType, - const audio_offload_info_t *offloadInfo) + const audio_offload_info_t *offloadInfo, + int uid) { switch (transferType) { case TRANSFER_DEFAULT: @@ -313,6 +317,11 @@ status_t AudioTrack::set( mNotificationFramesReq = notificationFrames; mNotificationFramesAct = 0; mSessionId = sessionId; + if (uid == -1 || (IPCThreadState::self()->getCallingPid() != getpid())) { + mClientUid = IPCThreadState::self()->getCallingUid(); + } else { + mClientUid = uid; + } mAuxEffectId = 0; mFlags = flags; mCbf = cbf; @@ -594,6 +603,19 @@ uint32_t AudioTrack::getSampleRate() const } AutoMutex lock(mLock); + + // sample rate can be updated during playback by the offloaded decoder so we need to + // query the HAL and update if needed. +// FIXME use Proxy return channel to update the rate from server and avoid polling here + if (isOffloaded()) { + if (mOutput != 0) { + uint32_t sampleRate = 0; + status_t status = AudioSystem::getSamplingRate(mOutput, mStreamType, &sampleRate); + if (status == NO_ERROR) { + mSampleRate = sampleRate; + } + } + } return mSampleRate; } @@ -738,7 +760,7 @@ status_t AudioTrack::getPosition(uint32_t *position) const return NO_ERROR; } -status_t AudioTrack::getBufferPosition(size_t *position) +status_t AudioTrack::getBufferPosition(uint32_t *position) { if (mSharedBuffer == 0 || mIsTimed) { return INVALID_OPERATION; @@ -856,8 +878,15 @@ status_t AudioTrack::createTrack_l( } ALOGV("createTrack_l() output %d afLatency %d", output, afLatency); + if ((flags & AUDIO_OUTPUT_FLAG_FAST) && sampleRate != afSampleRate) { + ALOGW("AUDIO_OUTPUT_FLAG_FAST denied by client due to mismatching sample rate (%d vs %d)", + sampleRate, afSampleRate); + flags = (audio_output_flags_t) (flags & ~AUDIO_OUTPUT_FLAG_FAST); + } + // The client's AudioTrack buffer is divided into n parts for purpose of wakeup by server, where - // n = 1 fast track; nBuffering is ignored + // n = 1 fast track with single buffering; nBuffering is ignored + // n = 2 fast track with double buffering // n = 2 normal track, no sample rate conversion // n = 3 normal track, with sample rate conversion // (pessimistic; some non-1:1 conversion ratios don't actually need triple-buffering) @@ -886,7 +915,7 @@ status_t AudioTrack::createTrack_l( // More than 2 channels does not require stronger alignment than stereo alignment <<= 1; } - if (((size_t)sharedBuffer->pointer() & (alignment - 1)) != 0) { + if (((uintptr_t)sharedBuffer->pointer() & (alignment - 1)) != 0) { ALOGE("Invalid buffer alignment: address %p, channel count %u", sharedBuffer->pointer(), mChannelCount); return BAD_VALUE; @@ -962,6 +991,7 @@ status_t AudioTrack::createTrack_l( tid, &mSessionId, mName, + mClientUid, &status); if (track == 0) { @@ -996,9 +1026,11 @@ status_t AudioTrack::createTrack_l( ALOGV("AUDIO_OUTPUT_FLAG_FAST successful; frameCount %u", frameCount); mAwaitBoost = true; if (sharedBuffer == 0) { - // double-buffering is not required for fast tracks, due to tighter scheduling - if (mNotificationFramesAct == 0 || mNotificationFramesAct > frameCount) { - mNotificationFramesAct = frameCount; + // Theoretically double-buffering is not required for fast tracks, + // due to tighter scheduling. But in practice, to accommodate kernels with + // scheduling jitter, and apps with computation jitter, we use double-buffering. + if (mNotificationFramesAct == 0 || mNotificationFramesAct > frameCount/nBuffering) { + mNotificationFramesAct = frameCount/nBuffering; } } } else { @@ -1212,7 +1244,7 @@ ssize_t AudioTrack::write(const void* buffer, size_t userSize) if (ssize_t(userSize) < 0 || (buffer == NULL && userSize != 0)) { // Sanity-check: user is most-likely passing an error code, and it would // make the return value ambiguous (actualSize vs error). - ALOGE("AudioTrack::write(buffer=%p, size=%u (%d)", buffer, userSize, userSize); + ALOGE("AudioTrack::write(buffer=%p, size=%zu (%zd)", buffer, userSize, userSize); return BAD_VALUE; } @@ -1665,7 +1697,6 @@ status_t AudioTrack::restoreTrack_l(const char *from) // take the frames that will be lost by track recreation into account in saved position size_t position = mProxy->getPosition() + mProxy->getFramesFilled(); - mNewPosition = position + mUpdatePeriod; size_t bufferPosition = mStaticProxy != NULL ? mStaticProxy->getBufferPosition() : 0; result = createTrack_l(mStreamType, mSampleRate, @@ -1756,7 +1787,7 @@ status_t AudioTrack::dump(int fd, const Vector<String16>& args) const snprintf(buffer, 255, " stream type(%d), left - right volume(%f, %f)\n", mStreamType, mVolume[0], mVolume[1]); result.append(buffer); - snprintf(buffer, 255, " format(%d), channel count(%d), frame count(%d)\n", mFormat, + snprintf(buffer, 255, " format(%d), channel count(%d), frame count(%zu)\n", mFormat, mChannelCount, mFrameCount); result.append(buffer); snprintf(buffer, 255, " sample rate(%u), status(%d)\n", mSampleRate, mStatus); diff --git a/media/libmedia/AudioTrackShared.cpp b/media/libmedia/AudioTrackShared.cpp index da73d65..e898109 100644 --- a/media/libmedia/AudioTrackShared.cpp +++ b/media/libmedia/AudioTrackShared.cpp @@ -475,9 +475,14 @@ void StaticAudioTrackClientProxy::flush() void StaticAudioTrackClientProxy::setLoop(size_t loopStart, size_t loopEnd, int loopCount) { + // This can only happen on a 64-bit client + if (loopStart > UINT32_MAX || loopEnd > UINT32_MAX) { + // FIXME Should return an error status + return; + } StaticAudioTrackState newState; - newState.mLoopStart = loopStart; - newState.mLoopEnd = loopEnd; + newState.mLoopStart = (uint32_t) loopStart; + newState.mLoopEnd = (uint32_t) loopEnd; newState.mLoopCount = loopCount; mBufferPosition = loopStart; (void) mMutator.push(newState); @@ -487,7 +492,7 @@ size_t StaticAudioTrackClientProxy::getBufferPosition() { size_t bufferPosition; if (mMutator.ack()) { - bufferPosition = mCblk->u.mStatic.mBufferPosition; + bufferPosition = (size_t) mCblk->u.mStatic.mBufferPosition; if (bufferPosition > mFrameCount) { bufferPosition = mFrameCount; } @@ -506,7 +511,7 @@ ServerProxy::ServerProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCo { } -status_t ServerProxy::obtainBuffer(Buffer* buffer) +status_t ServerProxy::obtainBuffer(Buffer* buffer, bool ackFlush) { LOG_ALWAYS_FATAL_IF(buffer == NULL || buffer->mFrameCount == 0); if (mIsShutdown) { @@ -579,7 +584,11 @@ status_t ServerProxy::obtainBuffer(Buffer* buffer) buffer->mRaw = part1 > 0 ? &((char *) mBuffers)[(mIsOut ? front : rear) * mFrameSize] : NULL; buffer->mNonContig = availToServer - part1; - mUnreleased = part1; + // After flush(), allow releaseBuffer() on a previously obtained buffer; + // see "Acknowledge any pending flush()" in audioflinger/Tracks.cpp. + if (!ackFlush) { + mUnreleased = part1; + } return part1 > 0 ? NO_ERROR : WOULD_BLOCK; } no_init: @@ -618,7 +627,7 @@ void ServerProxy::releaseBuffer(Buffer* buffer) if (half == 0) { half = 1; } - size_t minimum = cblk->mMinimum; + size_t minimum = (size_t) cblk->mMinimum; if (minimum == 0) { minimum = mIsOut ? half : 1; } else if (minimum > half) { @@ -756,12 +765,13 @@ ssize_t StaticAudioTrackServerProxy::pollPosition() mIsShutdown = true; return (ssize_t) NO_INIT; } - mCblk->u.mStatic.mBufferPosition = position; + // This may overflow, but client is not supposed to rely on it + mCblk->u.mStatic.mBufferPosition = (uint32_t) position; } return (ssize_t) position; } -status_t StaticAudioTrackServerProxy::obtainBuffer(Buffer* buffer) +status_t StaticAudioTrackServerProxy::obtainBuffer(Buffer* buffer, bool ackFlush) { if (mIsShutdown) { buffer->mFrameCount = 0; @@ -832,7 +842,8 @@ void StaticAudioTrackServerProxy::releaseBuffer(Buffer* buffer) mPosition = newPosition; cblk->mServer += stepCount; - cblk->u.mStatic.mBufferPosition = newPosition; + // This may overflow, but client is not supposed to rely on it + cblk->u.mStatic.mBufferPosition = (uint32_t) newPosition; if (setFlags != 0) { (void) android_atomic_or(setFlags, &cblk->mFlags); // this would be a good place to wake a futex diff --git a/media/libmedia/IAudioFlinger.cpp b/media/libmedia/IAudioFlinger.cpp index 448a82e..86ff8bd 100644 --- a/media/libmedia/IAudioFlinger.cpp +++ b/media/libmedia/IAudioFlinger.cpp @@ -96,6 +96,7 @@ public: pid_t tid, int *sessionId, String8& name, + int clientUid, status_t *status) { Parcel data, reply; @@ -121,6 +122,7 @@ public: lSessionId = *sessionId; } data.writeInt32(lSessionId); + data.writeInt32(clientUid); status_t lStatus = remote()->transact(CREATE_TRACK, data, &reply); if (lStatus != NO_ERROR) { ALOGE("createTrack error: %s", strerror(-lStatus)); @@ -523,7 +525,7 @@ public: return reply.readInt32(); } - virtual status_t getRenderPosition(size_t *halFrames, size_t *dspFrames, + virtual status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames, audio_io_handle_t output) const { Parcel data, reply; @@ -544,7 +546,7 @@ public: return status; } - virtual size_t getInputFramesLost(audio_io_handle_t ioHandle) const + virtual uint32_t getInputFramesLost(audio_io_handle_t ioHandle) const { Parcel data, reply; data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); @@ -762,6 +764,7 @@ status_t BnAudioFlinger::onTransact( audio_io_handle_t output = (audio_io_handle_t) data.readInt32(); pid_t tid = (pid_t) data.readInt32(); int sessionId = data.readInt32(); + int clientUid = data.readInt32(); String8 name; status_t status; sp<IAudioTrack> track; @@ -773,7 +776,7 @@ status_t BnAudioFlinger::onTransact( track = createTrack( (audio_stream_type_t) streamType, sampleRate, format, channelMask, frameCount, &flags, buffer, output, tid, - &sessionId, name, &status); + &sessionId, name, clientUid, &status); } reply->writeInt32(flags); reply->writeInt32(sessionId); @@ -1010,8 +1013,8 @@ status_t BnAudioFlinger::onTransact( case GET_RENDER_POSITION: { CHECK_INTERFACE(IAudioFlinger, data, reply); audio_io_handle_t output = (audio_io_handle_t) data.readInt32(); - size_t halFrames; - size_t dspFrames; + uint32_t halFrames; + uint32_t dspFrames; status_t status = getRenderPosition(&halFrames, &dspFrames, output); reply->writeInt32(status); if (status == NO_ERROR) { diff --git a/media/libmedia/MemoryLeakTrackUtil.cpp b/media/libmedia/MemoryLeakTrackUtil.cpp index 6a108ae..f004ca4 100644 --- a/media/libmedia/MemoryLeakTrackUtil.cpp +++ b/media/libmedia/MemoryLeakTrackUtil.cpp @@ -49,7 +49,7 @@ struct MyString8 { } void append(const char *s) { - strcat(mPtr, s); + strncat(mPtr, s, MAX_SIZE - size() - 1); } const char *string() const { @@ -60,6 +60,10 @@ struct MyString8 { return strlen(mPtr); } + void clear() { + *mPtr = '\0'; + } + private: char *mPtr; @@ -139,6 +143,9 @@ void dumpMemoryAddresses(int fd) } } while (moved); + write(fd, result.string(), result.size()); + result.clear(); + for (size_t i = 0; i < count; i++) { AllocEntry *e = &entries[i]; @@ -152,13 +159,14 @@ void dumpMemoryAddresses(int fd) result.append(buffer); } result.append("\n"); + + write(fd, result.string(), result.size()); + result.clear(); } delete[] entries; free_malloc_leak_info(info); } - - write(fd, result.string(), result.size()); } #else diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp index 9553458..a392b76 100644 --- a/media/libmediaplayerservice/MediaPlayerService.cpp +++ b/media/libmediaplayerservice/MediaPlayerService.cpp @@ -319,7 +319,7 @@ status_t MediaPlayerService::AudioCache::dump(int fd, const Vector<String16>& ar result.append(" AudioCache\n"); if (mHeap != 0) { - snprintf(buffer, 255, " heap base(%p), size(%d), flags(%d)\n", + snprintf(buffer, 255, " heap base(%p), size(%zu), flags(%d)\n", mHeap->getBase(), mHeap->getSize(), mHeap->getFlags()); result.append(buffer); } @@ -590,7 +590,7 @@ sp<MediaPlayerBase> MediaPlayerService::Client::setDataSource_pre( } if (!p->hardwareOutput()) { - mAudioOutput = new AudioOutput(mAudioSessionId); + mAudioOutput = new AudioOutput(mAudioSessionId, IPCThreadState::self()->getCallingUid()); static_cast<MediaPlayerInterface*>(p.get())->setAudioSink(mAudioOutput); } @@ -1296,12 +1296,13 @@ Exit: #undef LOG_TAG #define LOG_TAG "AudioSink" -MediaPlayerService::AudioOutput::AudioOutput(int sessionId) +MediaPlayerService::AudioOutput::AudioOutput(int sessionId, int uid) : mCallback(NULL), mCallbackCookie(NULL), mCallbackData(NULL), mBytesWritten(0), mSessionId(sessionId), + mUid(uid), mFlags(AUDIO_OUTPUT_FLAG_NONE) { ALOGV("AudioOutput(%d)", sessionId); mStreamType = AUDIO_STREAM_MUSIC; @@ -1549,7 +1550,8 @@ status_t MediaPlayerService::AudioOutput::open( 0, // notification frames mSessionId, AudioTrack::TRANSFER_CALLBACK, - offloadInfo); + offloadInfo, + mUid); } else { t = new AudioTrack( mStreamType, @@ -1558,10 +1560,13 @@ status_t MediaPlayerService::AudioOutput::open( channelMask, frameCount, flags, - NULL, - NULL, - 0, - mSessionId); + NULL, // callback + NULL, // user data + 0, // notification frames + mSessionId, + AudioTrack::TRANSFER_DEFAULT, + NULL, // offload info + mUid); } if ((t == 0) || (t->initCheck() != NO_ERROR)) { @@ -1808,6 +1813,12 @@ int MediaPlayerService::AudioOutput::getSessionId() const return mSessionId; } +uint32_t MediaPlayerService::AudioOutput::getSampleRate() const +{ + if (mTrack == 0) return 0; + return mTrack->getSampleRate(); +} + #undef LOG_TAG #define LOG_TAG "AudioCache" MediaPlayerService::AudioCache::AudioCache(const sp<IMemoryHeap>& heap) : @@ -2010,6 +2021,14 @@ int MediaPlayerService::AudioCache::getSessionId() const return 0; } +uint32_t MediaPlayerService::AudioCache::getSampleRate() const +{ + if (mMsecsPerFrame == 0) { + return 0; + } + return (uint32_t)(1.e3 / mMsecsPerFrame); +} + void MediaPlayerService::addBatteryData(uint32_t params) { Mutex::Autolock lock(mLock); diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h index 21f4117..9c084e1 100644 --- a/media/libmediaplayerservice/MediaPlayerService.h +++ b/media/libmediaplayerservice/MediaPlayerService.h @@ -72,7 +72,7 @@ class MediaPlayerService : public BnMediaPlayerService class CallbackData; public: - AudioOutput(int sessionId); + AudioOutput(int sessionId, int uid); virtual ~AudioOutput(); virtual bool ready() const { return mTrack != 0; } @@ -86,6 +86,7 @@ class MediaPlayerService : public BnMediaPlayerService virtual status_t getPosition(uint32_t *position) const; virtual status_t getFramesWritten(uint32_t *frameswritten) const; virtual int getSessionId() const; + virtual uint32_t getSampleRate() const; virtual status_t open( uint32_t sampleRate, int channelCount, audio_channel_mask_t channelMask, @@ -100,7 +101,10 @@ class MediaPlayerService : public BnMediaPlayerService virtual void flush(); virtual void pause(); virtual void close(); - void setAudioStreamType(audio_stream_type_t streamType) { mStreamType = streamType; } + void setAudioStreamType(audio_stream_type_t streamType) { + mStreamType = streamType; } + virtual audio_stream_type_t getAudioStreamType() const { return mStreamType; } + void setVolume(float left, float right); virtual status_t setPlaybackRatePermille(int32_t ratePermille); status_t setAuxEffectSendLevel(float level); @@ -135,6 +139,7 @@ class MediaPlayerService : public BnMediaPlayerService uint32_t mSampleRateHz; // sample rate of the content, as set in open() float mMsecsPerFrame; int mSessionId; + int mUid; float mSendLevel; int mAuxEffectId; static bool mIsOnEmulator; @@ -191,6 +196,7 @@ class MediaPlayerService : public BnMediaPlayerService virtual status_t getPosition(uint32_t *position) const; virtual status_t getFramesWritten(uint32_t *frameswritten) const; virtual int getSessionId() const; + virtual uint32_t getSampleRate() const; virtual status_t open( uint32_t sampleRate, int channelCount, audio_channel_mask_t channelMask, @@ -206,6 +212,9 @@ class MediaPlayerService : public BnMediaPlayerService virtual void pause() {} virtual void close() {} void setAudioStreamType(audio_stream_type_t streamType) {} + // stream type is not used for AudioCache + virtual audio_stream_type_t getAudioStreamType() const { return AUDIO_STREAM_DEFAULT; } + void setVolume(float left, float right) {} virtual status_t setPlaybackRatePermille(int32_t ratePermille) { return INVALID_OPERATION; } uint32_t sampleRate() const { return mSampleRate; } diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp index 095d5ca..4da74e1 100644 --- a/media/libmediaplayerservice/StagefrightRecorder.cpp +++ b/media/libmediaplayerservice/StagefrightRecorder.cpp @@ -16,6 +16,7 @@ //#define LOG_NDEBUG 0 #define LOG_TAG "StagefrightRecorder" +#include <inttypes.h> #include <utils/Log.h> #include "StagefrightRecorder.h" @@ -70,8 +71,9 @@ StagefrightRecorder::StagefrightRecorder() mOutputFd(-1), mAudioSource(AUDIO_SOURCE_CNT), mVideoSource(VIDEO_SOURCE_LIST_END), - mStarted(false), mSurfaceMediaSource(NULL), - mCaptureTimeLapse(false) { + mCaptureTimeLapse(false), + mStarted(false), + mSurfaceMediaSource(NULL) { ALOGV("Constructor"); reset(); @@ -1089,7 +1091,22 @@ void StagefrightRecorder::clipVideoFrameWidth() { } } -status_t StagefrightRecorder::checkVideoEncoderCapabilities() { +status_t StagefrightRecorder::checkVideoEncoderCapabilities( + bool *supportsCameraSourceMetaDataMode) { + /* hardware codecs must support camera source meta data mode */ + Vector<CodecCapabilities> codecs; + OMXClient client; + CHECK_EQ(client.connect(), (status_t)OK); + QueryCodecs( + client.interface(), + (mVideoEncoder == VIDEO_ENCODER_H263 ? MEDIA_MIMETYPE_VIDEO_H263 : + mVideoEncoder == VIDEO_ENCODER_MPEG_4_SP ? MEDIA_MIMETYPE_VIDEO_MPEG4 : + mVideoEncoder == VIDEO_ENCODER_H264 ? MEDIA_MIMETYPE_VIDEO_AVC : ""), + false /* decoder */, true /* hwCodec */, &codecs); + *supportsCameraSourceMetaDataMode = codecs.size() > 0; + ALOGV("encoder %s camera source meta-data mode", + *supportsCameraSourceMetaDataMode ? "supports" : "DOES NOT SUPPORT"); + if (!mCaptureTimeLapse) { // Dont clip for time lapse capture as encoder will have enough // time to encode because of slow capture rate of time lapse. @@ -1307,7 +1324,9 @@ status_t StagefrightRecorder::setupSurfaceMediaSource() { status_t StagefrightRecorder::setupCameraSource( sp<CameraSource> *cameraSource) { status_t err = OK; - if ((err = checkVideoEncoderCapabilities()) != OK) { + bool encoderSupportsCameraSourceMetaDataMode; + if ((err = checkVideoEncoderCapabilities( + &encoderSupportsCameraSourceMetaDataMode)) != OK) { return err; } Size videoSize; @@ -1323,13 +1342,14 @@ status_t StagefrightRecorder::setupCameraSource( mCameraSourceTimeLapse = CameraSourceTimeLapse::CreateFromCamera( mCamera, mCameraProxy, mCameraId, mClientName, mClientUid, videoSize, mFrameRate, mPreviewSurface, - mTimeBetweenTimeLapseFrameCaptureUs); + mTimeBetweenTimeLapseFrameCaptureUs, + encoderSupportsCameraSourceMetaDataMode); *cameraSource = mCameraSourceTimeLapse; } else { *cameraSource = CameraSource::CreateFromCamera( mCamera, mCameraProxy, mCameraId, mClientName, mClientUid, videoSize, mFrameRate, - mPreviewSurface, true /*storeMetaDataInVideoBuffers*/); + mPreviewSurface, encoderSupportsCameraSourceMetaDataMode); } mCamera.clear(); mCameraProxy.clear(); @@ -1728,15 +1748,15 @@ status_t StagefrightRecorder::dump( result.append(buffer); snprintf(buffer, SIZE, " File format: %d\n", mOutputFormat); result.append(buffer); - snprintf(buffer, SIZE, " Max file size (bytes): %lld\n", mMaxFileSizeBytes); + snprintf(buffer, SIZE, " Max file size (bytes): %" PRId64 "\n", mMaxFileSizeBytes); result.append(buffer); - snprintf(buffer, SIZE, " Max file duration (us): %lld\n", mMaxFileDurationUs); + snprintf(buffer, SIZE, " Max file duration (us): %" PRId64 "\n", mMaxFileDurationUs); result.append(buffer); snprintf(buffer, SIZE, " File offset length (bits): %d\n", mUse64BitFileOffset? 64: 32); result.append(buffer); snprintf(buffer, SIZE, " Interleave duration (us): %d\n", mInterleaveDurationUs); result.append(buffer); - snprintf(buffer, SIZE, " Progress notification: %lld us\n", mTrackEveryTimeDurationUs); + snprintf(buffer, SIZE, " Progress notification: %" PRId64 " us\n", mTrackEveryTimeDurationUs); result.append(buffer); snprintf(buffer, SIZE, " Audio\n"); result.append(buffer); diff --git a/media/libmediaplayerservice/StagefrightRecorder.h b/media/libmediaplayerservice/StagefrightRecorder.h index c864207..31f09e0 100644 --- a/media/libmediaplayerservice/StagefrightRecorder.h +++ b/media/libmediaplayerservice/StagefrightRecorder.h @@ -139,7 +139,8 @@ private: status_t startRTPRecording(); status_t startMPEG2TSRecording(); sp<MediaSource> createAudioSource(); - status_t checkVideoEncoderCapabilities(); + status_t checkVideoEncoderCapabilities( + bool *supportsCameraSourceMetaDataMode); status_t checkAudioEncoderCapabilities(); // Generic MediaSource set-up. Returns the appropriate // source (CameraSource or SurfaceMediaSource) diff --git a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp index d8b35d7..f1782cc 100644 --- a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp +++ b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp @@ -201,7 +201,16 @@ void NuPlayer::HTTPLiveSource::onSessionNotify(const sp<AMessage> &msg) { switch (what) { case LiveSession::kWhatPrepared: { - notifyVideoSizeChanged(0, 0); + // notify the current size here if we have it, otherwise report an initial size of (0,0) + sp<AMessage> format = getFormat(false /* audio */); + int32_t width; + int32_t height; + if (format != NULL && + format->findInt32("width", &width) && format->findInt32("height", &height)) { + notifyVideoSizeChanged(width, height); + } else { + notifyVideoSizeChanged(0, 0); + } uint32_t flags = FLAG_CAN_PAUSE; if (mLiveSession->isSeekable()) { diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp index 750287f..3669a5b 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp @@ -32,6 +32,8 @@ #include "ATSParser.h" +#include "SoftwareRenderer.h" + #include <cutils/properties.h> // for property_get #include <media/stagefright/foundation/hexdump.h> #include <media/stagefright/foundation/ABuffer.h> @@ -146,6 +148,7 @@ NuPlayer::NuPlayer() : mUIDValid(false), mSourceFlags(0), mVideoIsAVC(false), + mNeedsSwRenderer(false), mAudioEOS(false), mVideoEOS(false), mScanSourcesPending(false), @@ -444,6 +447,7 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { ALOGV("kWhatStart"); mVideoIsAVC = false; + mNeedsSwRenderer = false; mAudioEOS = false; mVideoEOS = false; mSkipRenderingAudioUntilMediaTimeUs = -1; @@ -680,6 +684,20 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { notifyListener( MEDIA_SET_VIDEO_SIZE, displayWidth, displayHeight); + + if (mNeedsSwRenderer && mNativeWindow != NULL) { + int32_t colorFormat; + CHECK(codecRequest->findInt32("color-format", &colorFormat)); + + sp<MetaData> meta = new MetaData; + meta->setInt32(kKeyWidth, width); + meta->setInt32(kKeyHeight, height); + meta->setRect(kKeyCropRect, cropLeft, cropTop, cropRight, cropBottom); + meta->setInt32(kKeyColorFormat, colorFormat); + + mRenderer->setSoftRenderer( + new SoftwareRenderer(mNativeWindow->getNativeWindow(), meta)); + } } } else if (what == ACodec::kWhatShutdownCompleted) { ALOGV("%s shutdown completed", audio ? "audio" : "video"); @@ -703,8 +721,13 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { mRenderer->queueEOS(audio, UNKNOWN_ERROR); } else if (what == ACodec::kWhatDrainThisBuffer) { renderBuffer(audio, codecRequest); - } else if (what != ACodec::kWhatComponentAllocated - && what != ACodec::kWhatComponentConfigured + } else if (what == ACodec::kWhatComponentAllocated) { + if (!audio) { + AString name; + CHECK(codecRequest->findString("componentName", &name)); + mNeedsSwRenderer = name.startsWith("OMX.google."); + } + } else if (what != ACodec::kWhatComponentConfigured && what != ACodec::kWhatBuffersAllocated) { ALOGV("Unhandled codec notification %d '%c%c%c%c'.", what, diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.h b/media/libmediaplayerservice/nuplayer/NuPlayer.h index 13350f3..590e1f2 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayer.h +++ b/media/libmediaplayerservice/nuplayer/NuPlayer.h @@ -116,6 +116,7 @@ private: sp<MediaPlayerBase::AudioSink> mAudioSink; sp<Decoder> mVideoDecoder; bool mVideoIsAVC; + bool mNeedsSwRenderer; sp<Decoder> mAudioDecoder; sp<Renderer> mRenderer; diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp index 47834fd..239296e 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp @@ -16,6 +16,7 @@ //#define LOG_NDEBUG 0 #define LOG_TAG "NuPlayerDriver" +#include <inttypes.h> #include <utils/Log.h> #include "NuPlayerDriver.h" @@ -499,7 +500,7 @@ status_t NuPlayerDriver::dump(int fd, const Vector<String16> &args) const { FILE *out = fdopen(dup(fd), "w"); fprintf(out, " NuPlayer\n"); - fprintf(out, " numFramesTotal(%lld), numFramesDropped(%lld), " + fprintf(out, " numFramesTotal(%" PRId64 "), numFramesDropped(%" PRId64 "), " "percentageDropped(%.2f)\n", mNumFramesTotal, mNumFramesDropped, diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp index 3b2784b..bf5271e 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp @@ -20,6 +20,8 @@ #include "NuPlayerRenderer.h" +#include "SoftwareRenderer.h" + #include <media/stagefright/foundation/ABuffer.h> #include <media/stagefright/foundation/ADebug.h> #include <media/stagefright/foundation/AMessage.h> @@ -34,6 +36,7 @@ NuPlayer::Renderer::Renderer( const sp<AMessage> ¬ify, uint32_t flags) : mAudioSink(sink), + mSoftRenderer(NULL), mNotify(notify), mFlags(flags), mNumFramesWritten(0), @@ -57,6 +60,12 @@ NuPlayer::Renderer::Renderer( } NuPlayer::Renderer::~Renderer() { + delete mSoftRenderer; +} + +void NuPlayer::Renderer::setSoftRenderer(SoftwareRenderer *softRenderer) { + delete mSoftRenderer; + mSoftRenderer = softRenderer; } void NuPlayer::Renderer::queueBuffer( @@ -413,7 +422,12 @@ void NuPlayer::Renderer::onDrainVideoQueue() { ALOGV("video late by %lld us (%.2f secs)", mVideoLateByUs, mVideoLateByUs / 1E6); } else { - ALOGV("rendering video at media time %.2f secs", mediaTimeUs / 1E6); + ALOGV("rendering video at media time %.2f secs", + (mFlags & FLAG_REAL_TIME ? realTimeUs : + (realTimeUs + mAnchorTimeMediaUs - mAnchorTimeRealUs)) / 1E6); + if (mSoftRenderer != NULL) { + mSoftRenderer->render(entry->mBuffer->data(), entry->mBuffer->size(), NULL); + } } entry->mNotifyConsumed->setInt32("render", !tooLate); diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h index 94a05ea..9124e03 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h +++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h @@ -23,6 +23,7 @@ namespace android { struct ABuffer; +class SoftwareRenderer; struct NuPlayer::Renderer : public AHandler { enum Flags { @@ -56,6 +57,8 @@ struct NuPlayer::Renderer : public AHandler { kWhatMediaRenderingStart = 'mdrd', }; + void setSoftRenderer(SoftwareRenderer *softRenderer); + protected: virtual ~Renderer(); @@ -83,6 +86,7 @@ private: static const int64_t kMinPositionUpdateDelayUs; sp<MediaPlayerBase::AudioSink> mAudioSink; + SoftwareRenderer *mSoftRenderer; sp<AMessage> mNotify; uint32_t mFlags; List<QueueEntry> mAudioQueue; diff --git a/media/libmediaplayerservice/nuplayer/mp4/MP4Source.cpp b/media/libmediaplayerservice/nuplayer/mp4/MP4Source.cpp index d31d947..2aae4dd 100644 --- a/media/libmediaplayerservice/nuplayer/mp4/MP4Source.cpp +++ b/media/libmediaplayerservice/nuplayer/mp4/MP4Source.cpp @@ -86,7 +86,7 @@ struct StreamSource : public FragmentedMP4Parser::Source { total += n; } - ALOGV("read %ld bytes at offset %lld", n, mPosition); + ALOGV("read %ld bytes at offset %lld", total, mPosition); mPosition += total; diff --git a/media/libnbaio/MonoPipe.cpp b/media/libnbaio/MonoPipe.cpp index de0ad28..3c61b60 100644 --- a/media/libnbaio/MonoPipe.cpp +++ b/media/libnbaio/MonoPipe.cpp @@ -183,7 +183,7 @@ ssize_t MonoPipe::write(const void *buffer, size_t count) } } if (ns > 0) { - const struct timespec req = {0, ns}; + const struct timespec req = {0, static_cast<long>(ns)}; nanosleep(&req, NULL); } // record the time that this write() completed diff --git a/media/libnbaio/NBLog.cpp b/media/libnbaio/NBLog.cpp index 045bf64..d74a7a6 100644 --- a/media/libnbaio/NBLog.cpp +++ b/media/libnbaio/NBLog.cpp @@ -340,7 +340,7 @@ void NBLog::Reader::dump(int fd, size_t indent) if (i > 0) { lost += i; if (fd >= 0) { - fdprintf(fd, "%*swarning: lost %u bytes worth of events\n", indent, "", lost); + fdprintf(fd, "%*swarning: lost %zu bytes worth of events\n", indent, "", lost); } else { ALOGI("%*swarning: lost %u bytes worth of events\n", indent, "", lost); } diff --git a/media/libstagefright/AACWriter.cpp b/media/libstagefright/AACWriter.cpp index a6f7cfb..c9bcaba 100644 --- a/media/libstagefright/AACWriter.cpp +++ b/media/libstagefright/AACWriter.cpp @@ -171,7 +171,7 @@ status_t AACWriter::reset() { void *dummy; pthread_join(mThread, &dummy); - status_t err = (status_t) dummy; + status_t err = static_cast<status_t>(reinterpret_cast<uintptr_t>(dummy)); { status_t status = mSource->stop(); if (err == OK && @@ -200,7 +200,7 @@ bool AACWriter::exceedsFileDurationLimit() { // static void *AACWriter::ThreadWrapper(void *me) { - return (void *) static_cast<AACWriter *>(me)->threadFunc(); + return (void *)(uintptr_t)static_cast<AACWriter *>(me)->threadFunc(); } /* diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp index 1adab38..76a3358 100644 --- a/media/libstagefright/ACodec.cpp +++ b/media/libstagefright/ACodec.cpp @@ -1909,6 +1909,11 @@ status_t ACodec::setupVideoEncoder(const char *mime, const sp<AMessage> &msg) { err = setupAVCEncoderParameters(msg); break; + case OMX_VIDEO_CodingVP8: + case OMX_VIDEO_CodingVP9: + err = setupVPXEncoderParameters(msg); + break; + default: break; } @@ -2240,6 +2245,17 @@ status_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) { return configureBitrate(bitrate, bitrateMode); } +status_t ACodec::setupVPXEncoderParameters(const sp<AMessage> &msg) { + int32_t bitrate; + if (!msg->findInt32("bitrate", &bitrate)) { + return INVALID_OPERATION; + } + + OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg); + + return configureBitrate(bitrate, bitrateMode); +} + status_t ACodec::verifySupportForProfileAndLevel( int32_t profile, int32_t level) { OMX_VIDEO_PARAM_PROFILELEVELTYPE params; @@ -3072,11 +3088,16 @@ void ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) { /* these are unfilled buffers returned by client */ CHECK(msg->findInt32("err", &err)); - ALOGV("[%s] saw error %d instead of an input buffer", - mCodec->mComponentName.c_str(), err); + if (err == OK) { + /* buffers with no errors are returned on MediaCodec.flush */ + mode = KEEP_BUFFERS; + } else { + ALOGV("[%s] saw error %d instead of an input buffer", + mCodec->mComponentName.c_str(), err); + eos = true; + } buffer.clear(); - mode = KEEP_BUFFERS; } int32_t tmp; @@ -3394,7 +3415,7 @@ void ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) { int32_t render; if (mCodec->mNativeWindow != NULL && msg->findInt32("render", &render) && render != 0 - && (info->mData == NULL || info->mData->size() != 0)) { + && info->mData != NULL && info->mData->size() != 0) { // The client wants this buffer to be rendered. status_t err; diff --git a/media/libstagefright/AMRWriter.cpp b/media/libstagefright/AMRWriter.cpp index 8d5eec8..3fe247a 100644 --- a/media/libstagefright/AMRWriter.cpp +++ b/media/libstagefright/AMRWriter.cpp @@ -162,7 +162,7 @@ status_t AMRWriter::reset() { void *dummy; pthread_join(mThread, &dummy); - status_t err = (status_t) dummy; + status_t err = static_cast<status_t>(reinterpret_cast<uintptr_t>(dummy)); { status_t status = mSource->stop(); if (err == OK && @@ -191,7 +191,7 @@ bool AMRWriter::exceedsFileDurationLimit() { // static void *AMRWriter::ThreadWrapper(void *me) { - return (void *) static_cast<AMRWriter *>(me)->threadFunc(); + return (void *)(uintptr_t) static_cast<AMRWriter *>(me)->threadFunc(); } status_t AMRWriter::threadFunc() { diff --git a/media/libstagefright/AudioPlayer.cpp b/media/libstagefright/AudioPlayer.cpp index a8a8786..05ee34e 100644 --- a/media/libstagefright/AudioPlayer.cpp +++ b/media/libstagefright/AudioPlayer.cpp @@ -721,16 +721,27 @@ int64_t AudioPlayer::getRealTimeUsLocked() const { return result + diffUs; } -int64_t AudioPlayer::getOutputPlayPositionUs_l() const +int64_t AudioPlayer::getOutputPlayPositionUs_l() { uint32_t playedSamples = 0; + uint32_t sampleRate; if (mAudioSink != NULL) { mAudioSink->getPosition(&playedSamples); + sampleRate = mAudioSink->getSampleRate(); } else { mAudioTrack->getPosition(&playedSamples); + sampleRate = mAudioTrack->getSampleRate(); + } + if (sampleRate != 0) { + mSampleRate = sampleRate; } - const int64_t playedUs = (static_cast<int64_t>(playedSamples) * 1000000 ) / mSampleRate; + int64_t playedUs; + if (mSampleRate != 0) { + playedUs = (static_cast<int64_t>(playedSamples) * 1000000 ) / mSampleRate; + } else { + playedUs = 0; + } // HAL position is relative to the first buffer we sent at mStartPosUs const int64_t renderedDuration = mStartPosUs + playedUs; diff --git a/media/libstagefright/AudioSource.cpp b/media/libstagefright/AudioSource.cpp index bdd842f..f0d1a14 100644 --- a/media/libstagefright/AudioSource.cpp +++ b/media/libstagefright/AudioSource.cpp @@ -236,10 +236,10 @@ status_t AudioSource::read( memset((uint8_t *) buffer->data(), 0, buffer->range_length()); } else if (elapsedTimeUs < kAutoRampStartUs + kAutoRampDurationUs) { int32_t autoRampDurationFrames = - (kAutoRampDurationUs * mSampleRate + 500000LL) / 1000000LL; + ((int64_t)kAutoRampDurationUs * mSampleRate + 500000LL) / 1000000LL; //Need type casting int32_t autoRampStartFrames = - (kAutoRampStartUs * mSampleRate + 500000LL) / 1000000LL; + ((int64_t)kAutoRampStartUs * mSampleRate + 500000LL) / 1000000LL; //Need type casting int32_t nFrames = mNumFramesReceived - autoRampStartFrames; rampVolume(nFrames, autoRampDurationFrames, @@ -308,7 +308,7 @@ status_t AudioSource::dataCallback(const AudioRecord::Buffer& audioBuffer) { if (numLostBytes > 0) { // Loss of audio frames should happen rarely; thus the LOGW should // not cause a logging spam - ALOGW("Lost audio record data: %d bytes", numLostBytes); + ALOGW("Lost audio record data: %zu bytes", numLostBytes); } while (numLostBytes > 0) { diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp index c912f75..29c007a 100644 --- a/media/libstagefright/AwesomePlayer.cpp +++ b/media/libstagefright/AwesomePlayer.cpp @@ -19,6 +19,7 @@ //#define LOG_NDEBUG 0 #define LOG_TAG "AwesomePlayer" #define ATRACE_TAG ATRACE_TAG_VIDEO +#include <inttypes.h> #include <utils/Log.h> #include <utils/Trace.h> @@ -606,6 +607,9 @@ void AwesomePlayer::reset_l() { mWatchForAudioSeekComplete = false; mWatchForAudioEOS = false; + + mMediaRenderingStartGeneration = 0; + mStartGeneration = 0; } void AwesomePlayer::notifyListener_l(int msg, int ext1, int ext2) { @@ -722,7 +726,7 @@ void AwesomePlayer::onBufferingUpdate() { if ((mFlags & PLAYING) && !eos && (cachedDataRemaining < kLowWaterMarkBytes)) { - ALOGI("cache is running low (< %d) , pausing.", + ALOGI("cache is running low (< %zu) , pausing.", kLowWaterMarkBytes); modifyFlags(CACHE_UNDERRUN, SET); pause_l(); @@ -731,12 +735,12 @@ void AwesomePlayer::onBufferingUpdate() { notifyListener_l(MEDIA_INFO, MEDIA_INFO_BUFFERING_START); } else if (eos || cachedDataRemaining > kHighWaterMarkBytes) { if (mFlags & CACHE_UNDERRUN) { - ALOGI("cache has filled up (> %d), resuming.", + ALOGI("cache has filled up (> %zu), resuming.", kHighWaterMarkBytes); modifyFlags(CACHE_UNDERRUN, CLEAR); play_l(); } else if (mFlags & PREPARING) { - ALOGV("cache has filled up (> %d), prepare is done", + ALOGV("cache has filled up (> %zu), prepare is done", kHighWaterMarkBytes); finishAsyncPrepare_l(); } @@ -798,7 +802,7 @@ void AwesomePlayer::onBufferingUpdate() { } } - if (mFlags & (PLAYING | PREPARING)) { + if (mFlags & (PLAYING | PREPARING | CACHE_UNDERRUN)) { postBufferingEvent_l(); } } @@ -895,6 +899,8 @@ status_t AwesomePlayer::play_l() { return OK; } + mMediaRenderingStartGeneration = ++mStartGeneration; + if (!(mFlags & PREPARED)) { status_t err = prepare_l(); @@ -1197,8 +1203,7 @@ void AwesomePlayer::initRenderer_l() { setVideoScalingMode_l(mVideoScalingMode); if (USE_SURFACE_ALLOC && !strncmp(component, "OMX.", 4) - && strncmp(component, "OMX.google.", 11) - && strcmp(component, "OMX.Nvidia.mpeg2v.decode")) { + && strncmp(component, "OMX.google.", 11)) { // Hardware decoders avoid the CPU color conversion by decoding // directly to ANativeBuffers, so we must use a renderer that // just pushes those buffers to the ANativeWindow. @@ -1495,7 +1500,13 @@ status_t AwesomePlayer::initAudioDecoder() { // This doesn't guarantee that the hardware has a free stream // but it avoids us attempting to open (and re-open) an offload // stream to hardware that doesn't have the necessary codec - mOffloadAudio = canOffloadStream(meta, (mVideoSource != NULL), isStreamingHTTP()); + audio_stream_type_t streamType = AUDIO_STREAM_MUSIC; + if (mAudioSink != NULL) { + streamType = mAudioSink->getAudioStreamType(); + } + + mOffloadAudio = canOffloadStream(meta, (mVideoSource != NULL), + isStreamingHTTP(), streamType); if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) { ALOGV("createAudioPlayer: bypass OMX (raw)"); @@ -1927,7 +1938,7 @@ void AwesomePlayer::onVideoEvent() { ++mStats.mNumVideoFramesDropped; } - postVideoEvent_l(); + postVideoEvent_l(0); return; } } @@ -1967,6 +1978,41 @@ void AwesomePlayer::onVideoEvent() { return; } + /* get next frame time */ + if (wasSeeking == NO_SEEK) { + MediaSource::ReadOptions options; + for (;;) { + status_t err = mVideoSource->read(&mVideoBuffer, &options); + if (err != OK) { + // deal with any errors next time + CHECK(mVideoBuffer == NULL); + postVideoEvent_l(0); + return; + } + + if (mVideoBuffer->range_length() != 0) { + break; + } + + // Some decoders, notably the PV AVC software decoder + // return spurious empty buffers that we just want to ignore. + + mVideoBuffer->release(); + mVideoBuffer = NULL; + } + + { + Mutex::Autolock autoLock(mStatsLock); + ++mStats.mNumVideoFramesDecoded; + } + + int64_t nextTimeUs; + CHECK(mVideoBuffer->meta_data()->findInt64(kKeyTime, &nextTimeUs)); + int64_t delayUs = nextTimeUs - ts->getRealTimeUs() + mTimeSourceDeltaUs; + postVideoEvent_l(delayUs > 10000 ? 10000 : delayUs < 0 ? 0 : delayUs); + return; + } + postVideoEvent_l(); } @@ -2051,7 +2097,10 @@ void AwesomePlayer::onCheckAudioStatus() { mSeekNotificationSent = true; } - mSeeking = NO_SEEK; + if (mVideoSource == NULL) { + // For video the mSeeking flag is always reset in finishSeekIfNecessary + mSeeking = NO_SEEK; + } notifyIfMediaStarted_l(); } @@ -2247,8 +2296,8 @@ status_t AwesomePlayer::finishSetDataSource_l() { sniffedMIME = tmp.string(); if (meta == NULL - || !meta->findInt64( - "meta-data-size", &metaDataSize)) { + || !meta->findInt64("meta-data-size", + reinterpret_cast<int64_t*>(&metaDataSize))) { metaDataSize = kHighWaterMarkBytes; } @@ -2535,12 +2584,12 @@ status_t AwesomePlayer::getTrackInfo(Parcel *reply) const { status_t AwesomePlayer::selectAudioTrack_l( const sp<MediaSource>& source, size_t trackIndex) { - ALOGI("selectAudioTrack_l: trackIndex=%d, mFlags=0x%x", trackIndex, mFlags); + ALOGI("selectAudioTrack_l: trackIndex=%zu, mFlags=0x%x", trackIndex, mFlags); { Mutex::Autolock autoLock(mStatsLock); if ((ssize_t)trackIndex == mActiveAudioTrackIndex) { - ALOGI("Track %d is active. Does nothing.", trackIndex); + ALOGI("Track %zu is active. Does nothing.", trackIndex); return OK; } //mStats.mFlags = mFlags; @@ -2613,7 +2662,7 @@ status_t AwesomePlayer::selectTrack(size_t trackIndex, bool select) { trackCount += mTextDriver->countExternalTracks(); } if (trackIndex >= trackCount) { - ALOGE("Track index (%d) is out of range [0, %d)", trackIndex, trackCount); + ALOGE("Track index (%zu) is out of range [0, %zu)", trackIndex, trackCount); return ERROR_OUT_OF_RANGE; } @@ -2625,14 +2674,14 @@ status_t AwesomePlayer::selectTrack(size_t trackIndex, bool select) { isAudioTrack = !strncasecmp(mime, "audio/", 6); if (!isAudioTrack && strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP) != 0) { - ALOGE("Track %d is not either audio or timed text", trackIndex); + ALOGE("Track %zu is not either audio or timed text", trackIndex); return ERROR_UNSUPPORTED; } } if (isAudioTrack) { if (!select) { - ALOGE("Deselect an audio track (%d) is not supported", trackIndex); + ALOGE("Deselect an audio track (%zu) is not supported", trackIndex); return ERROR_UNSUPPORTED; } return selectAudioTrack_l(mExtractor->getTrack(trackIndex), trackIndex); @@ -2770,7 +2819,7 @@ status_t AwesomePlayer::dump(int fd, const Vector<String16> &args) const { fprintf(out, ", flags(0x%08x)", mStats.mFlags); if (mStats.mBitrate >= 0) { - fprintf(out, ", bitrate(%lld bps)", mStats.mBitrate); + fprintf(out, ", bitrate(%" PRId64 " bps)", mStats.mBitrate); } fprintf(out, "\n"); @@ -2778,7 +2827,7 @@ status_t AwesomePlayer::dump(int fd, const Vector<String16> &args) const { for (size_t i = 0; i < mStats.mTracks.size(); ++i) { const TrackStat &stat = mStats.mTracks.itemAt(i); - fprintf(out, " Track %d\n", i + 1); + fprintf(out, " Track %zu\n", i + 1); fprintf(out, " MIME(%s)", stat.mMIME.string()); if (!stat.mDecoderName.isEmpty()) { @@ -2790,8 +2839,8 @@ status_t AwesomePlayer::dump(int fd, const Vector<String16> &args) const { if ((ssize_t)i == mStats.mVideoTrackIndex) { fprintf(out, " videoDimensions(%d x %d), " - "numVideoFramesDecoded(%lld), " - "numVideoFramesDropped(%lld)\n", + "numVideoFramesDecoded(%" PRId64 "), " + "numVideoFramesDropped(%" PRId64 ")\n", mStats.mVideoWidth, mStats.mVideoHeight, mStats.mNumVideoFramesDecoded, diff --git a/media/libstagefright/CameraSourceTimeLapse.cpp b/media/libstagefright/CameraSourceTimeLapse.cpp index 20214e8..5772316 100644 --- a/media/libstagefright/CameraSourceTimeLapse.cpp +++ b/media/libstagefright/CameraSourceTimeLapse.cpp @@ -41,13 +41,15 @@ CameraSourceTimeLapse *CameraSourceTimeLapse::CreateFromCamera( Size videoSize, int32_t videoFrameRate, const sp<IGraphicBufferProducer>& surface, - int64_t timeBetweenFrameCaptureUs) { + int64_t timeBetweenFrameCaptureUs, + bool storeMetaDataInVideoBuffers) { CameraSourceTimeLapse *source = new CameraSourceTimeLapse(camera, proxy, cameraId, clientName, clientUid, videoSize, videoFrameRate, surface, - timeBetweenFrameCaptureUs); + timeBetweenFrameCaptureUs, + storeMetaDataInVideoBuffers); if (source != NULL) { if (source->initCheck() != OK) { @@ -67,9 +69,11 @@ CameraSourceTimeLapse::CameraSourceTimeLapse( Size videoSize, int32_t videoFrameRate, const sp<IGraphicBufferProducer>& surface, - int64_t timeBetweenFrameCaptureUs) + int64_t timeBetweenFrameCaptureUs, + bool storeMetaDataInVideoBuffers) : CameraSource(camera, proxy, cameraId, clientName, clientUid, - videoSize, videoFrameRate, surface, true), + videoSize, videoFrameRate, surface, + storeMetaDataInVideoBuffers), mTimeBetweenTimeLapseVideoFramesUs(1E6/videoFrameRate), mLastTimeLapseFrameRealTimestampUs(0), mSkipCurrentFrame(false) { diff --git a/media/libstagefright/DataSource.cpp b/media/libstagefright/DataSource.cpp index fc6fd9c..97987e2 100644 --- a/media/libstagefright/DataSource.cpp +++ b/media/libstagefright/DataSource.cpp @@ -107,6 +107,7 @@ status_t DataSource::getSize(off64_t *size) { Mutex DataSource::gSnifferMutex; List<DataSource::SnifferFunc> DataSource::gSniffers; +bool DataSource::gSniffersRegistered = false; bool DataSource::sniff( String8 *mimeType, float *confidence, sp<AMessage> *meta) { @@ -114,7 +115,13 @@ bool DataSource::sniff( *confidence = 0.0f; meta->clear(); - Mutex::Autolock autoLock(gSnifferMutex); + { + Mutex::Autolock autoLock(gSnifferMutex); + if (!gSniffersRegistered) { + return false; + } + } + for (List<SnifferFunc>::iterator it = gSniffers.begin(); it != gSniffers.end(); ++it) { String8 newMimeType; @@ -133,9 +140,7 @@ bool DataSource::sniff( } // static -void DataSource::RegisterSniffer(SnifferFunc func) { - Mutex::Autolock autoLock(gSnifferMutex); - +void DataSource::RegisterSniffer_l(SnifferFunc func) { for (List<SnifferFunc>::iterator it = gSniffers.begin(); it != gSniffers.end(); ++it) { if (*it == func) { @@ -148,23 +153,29 @@ void DataSource::RegisterSniffer(SnifferFunc func) { // static void DataSource::RegisterDefaultSniffers() { - RegisterSniffer(SniffMPEG4); - RegisterSniffer(SniffMatroska); - RegisterSniffer(SniffOgg); - RegisterSniffer(SniffWAV); - RegisterSniffer(SniffFLAC); - RegisterSniffer(SniffAMR); - RegisterSniffer(SniffMPEG2TS); - RegisterSniffer(SniffMP3); - RegisterSniffer(SniffAAC); - RegisterSniffer(SniffMPEG2PS); - RegisterSniffer(SniffWVM); + Mutex::Autolock autoLock(gSnifferMutex); + if (gSniffersRegistered) { + return; + } + + RegisterSniffer_l(SniffMPEG4); + RegisterSniffer_l(SniffMatroska); + RegisterSniffer_l(SniffOgg); + RegisterSniffer_l(SniffWAV); + RegisterSniffer_l(SniffFLAC); + RegisterSniffer_l(SniffAMR); + RegisterSniffer_l(SniffMPEG2TS); + RegisterSniffer_l(SniffMP3); + RegisterSniffer_l(SniffAAC); + RegisterSniffer_l(SniffMPEG2PS); + RegisterSniffer_l(SniffWVM); char value[PROPERTY_VALUE_MAX]; if (property_get("drm.service.enabled", value, NULL) && (!strcmp(value, "1") || !strcasecmp(value, "true"))) { - RegisterSniffer(SniffDRM); + RegisterSniffer_l(SniffDRM); } + gSniffersRegistered = true; } // static diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp index cbc169b..6a33ce6 100644 --- a/media/libstagefright/MPEG4Extractor.cpp +++ b/media/libstagefright/MPEG4Extractor.cpp @@ -39,6 +39,7 @@ #include <utils/String8.h> #include <byteswap.h> +#include "include/ID3.h" namespace android { @@ -259,7 +260,7 @@ static void hexdump(const void *_data, size_t size) { const uint8_t *data = (const uint8_t *)_data; size_t offset = 0; while (offset < size) { - printf("0x%04x ", offset); + printf("0x%04zx ", offset); size_t n = size - offset; if (n > 16) { @@ -682,8 +683,9 @@ status_t MPEG4Extractor::parseDrmSINF(off64_t *offset, off64_t data_offset) { } sinf->len = dataLen - 3; sinf->IPMPData = new char[sinf->len]; + data_offset += 2; - if (mDataSource->readAt(data_offset + 2, sinf->IPMPData, sinf->len) < sinf->len) { + if (mDataSource->readAt(data_offset, sinf->IPMPData, sinf->len) < sinf->len) { return ERROR_IO; } data_offset += sinf->len; @@ -962,6 +964,12 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { mLastTrack->meta->setInt32(kKeyEncoderDelay, delay); int64_t paddingus = duration - (segment_duration + media_time); + if (paddingus < 0) { + // track duration from media header (which is what kKeyDuration is) might + // be slightly shorter than the segment duration, which would make the + // padding negative. Clamp to zero. + paddingus = 0; + } int64_t paddingsamples = (paddingus * samplerate + 500000) / 1000000; mLastTrack->meta->setInt32(kKeyEncoderPadding, paddingsamples); } @@ -1379,19 +1387,33 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { } else { // No size was specified. Pick a conservatively large size. int32_t width, height; - if (mLastTrack->meta->findInt32(kKeyWidth, &width) && - mLastTrack->meta->findInt32(kKeyHeight, &height)) { - mLastTrack->meta->setInt32(kKeyMaxInputSize, width * height * 3 / 2); - } else { + if (!mLastTrack->meta->findInt32(kKeyWidth, &width) || + !mLastTrack->meta->findInt32(kKeyHeight, &height)) { ALOGE("No width or height, assuming worst case 1080p"); - mLastTrack->meta->setInt32(kKeyMaxInputSize, 3110400); + width = 1920; + height = 1080; + } + + const char *mime; + CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime)); + if (!strcmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) { + // AVC requires compression ratio of at least 2, and uses + // macroblocks + max_size = ((width + 15) / 16) * ((height + 15) / 16) * 192; + } else { + // For all other formats there is no minimum compression + // ratio. Use compression ratio of 1. + max_size = width * height * 3 / 2; } + mLastTrack->meta->setInt32(kKeyMaxInputSize, max_size); } *offset += chunk_size; - // Calculate average frame rate. + // NOTE: setting another piece of metadata invalidates any pointers (such as the + // mimetype) previously obtained, so don't cache them. const char *mime; CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime)); + // Calculate average frame rate. if (!strncasecmp("video/", mime, 6)) { size_t nSamples = mLastTrack->sampleTable->countSamples(); int64_t durationUs; @@ -1766,6 +1788,18 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { break; } + case FOURCC('I', 'D', '3', '2'): + { + if (chunk_data_size < 6) { + return ERROR_MALFORMED; + } + + parseID3v2MetaData(data_offset + 6); + + *offset += chunk_size; + break; + } + case FOURCC('-', '-', '-', '-'): { mLastCommentMean.clear(); @@ -2146,7 +2180,7 @@ status_t MPEG4Extractor::parseITunesMetaData(off64_t offset, size_t size) { break; } - if (size >= 8 && metadataKey) { + if (size >= 8 && metadataKey && !mFileMetaData->hasData(metadataKey)) { if (metadataKey == kKeyAlbumArt) { mFileMetaData->setData( kKeyAlbumArt, MetaData::TYPE_NONE, @@ -2295,6 +2329,62 @@ status_t MPEG4Extractor::parse3GPPMetaData(off64_t offset, size_t size, int dept return OK; } +void MPEG4Extractor::parseID3v2MetaData(off64_t offset) { + ID3 id3(mDataSource, true /* ignorev1 */, offset); + + if (id3.isValid()) { + struct Map { + int key; + const char *tag1; + const char *tag2; + }; + static const Map kMap[] = { + { kKeyAlbum, "TALB", "TAL" }, + { kKeyArtist, "TPE1", "TP1" }, + { kKeyAlbumArtist, "TPE2", "TP2" }, + { kKeyComposer, "TCOM", "TCM" }, + { kKeyGenre, "TCON", "TCO" }, + { kKeyTitle, "TIT2", "TT2" }, + { kKeyYear, "TYE", "TYER" }, + { kKeyAuthor, "TXT", "TEXT" }, + { kKeyCDTrackNumber, "TRK", "TRCK" }, + { kKeyDiscNumber, "TPA", "TPOS" }, + { kKeyCompilation, "TCP", "TCMP" }, + }; + static const size_t kNumMapEntries = sizeof(kMap) / sizeof(kMap[0]); + + for (size_t i = 0; i < kNumMapEntries; ++i) { + if (!mFileMetaData->hasData(kMap[i].key)) { + ID3::Iterator *it = new ID3::Iterator(id3, kMap[i].tag1); + if (it->done()) { + delete it; + it = new ID3::Iterator(id3, kMap[i].tag2); + } + + if (it->done()) { + delete it; + continue; + } + + String8 s; + it->getString(&s); + delete it; + + mFileMetaData->setCString(kMap[i].key, s); + } + } + + size_t dataSize; + String8 mime; + const void *data = id3.getAlbumArt(&dataSize, &mime); + + if (data) { + mFileMetaData->setData(kKeyAlbumArt, MetaData::TYPE_NONE, data, dataSize); + mFileMetaData->setCString(kKeyAlbumArtMIME, mime.string()); + } + } +} + sp<MediaSource> MPEG4Extractor::getTrack(size_t index) { status_t err; if ((err = readMetaData()) != OK) { @@ -2398,6 +2488,11 @@ status_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio( return ERROR_MALFORMED; } + static uint32_t kSamplingRate[] = { + 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, + 16000, 12000, 11025, 8000, 7350 + }; + ABitReader br(csd, csd_size); uint32_t objectType = br.getBits(5); @@ -2405,6 +2500,9 @@ status_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio( objectType = 32 + br.getBits(6); } + //keep AOT type + mLastTrack->meta->setInt32(kKeyAACAOT, objectType); + uint32_t freqIndex = br.getBits(4); int32_t sampleRate = 0; @@ -2417,29 +2515,30 @@ status_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio( numChannels = br.getBits(4); } else { numChannels = br.getBits(4); - if (objectType == 5) { - // SBR specific config per 14496-3 table 1.13 - freqIndex = br.getBits(4); - if (freqIndex == 15) { - if (csd_size < 8) { - return ERROR_MALFORMED; - } - sampleRate = br.getBits(24); - } + + if (freqIndex == 13 || freqIndex == 14) { + return ERROR_MALFORMED; } - if (sampleRate == 0) { - static uint32_t kSamplingRate[] = { - 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, - 16000, 12000, 11025, 8000, 7350 - }; + sampleRate = kSamplingRate[freqIndex]; + } - if (freqIndex == 13 || freqIndex == 14) { + if (objectType == 5 || objectType == 29) { // SBR specific config per 14496-3 table 1.13 + uint32_t extFreqIndex = br.getBits(4); + int32_t extSampleRate; + if (extFreqIndex == 15) { + if (csd_size < 8) { return ERROR_MALFORMED; } - - sampleRate = kSamplingRate[freqIndex]; + extSampleRate = br.getBits(24); + } else { + if (extFreqIndex == 13 || extFreqIndex == 14) { + return ERROR_MALFORMED; + } + extSampleRate = kSamplingRate[extFreqIndex]; } + //TODO: save the extension sampling rate value in meta data => + // mLastTrack->meta->setInt32(kKeyExtSampleRate, extSampleRate); } if (numChannels == 0) { diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp index a0f17b5..e7d3cc2 100644 --- a/media/libstagefright/MPEG4Writer.cpp +++ b/media/libstagefright/MPEG4Writer.cpp @@ -16,6 +16,7 @@ //#define LOG_NDEBUG 0 #define LOG_TAG "MPEG4Writer" +#include <inttypes.h> #include <utils/Log.h> #include <arpa/inet.h> @@ -417,7 +418,7 @@ status_t MPEG4Writer::Track::dump( result.append(buffer); snprintf(buffer, SIZE, " frames encoded : %d\n", mStszTableEntries->count()); result.append(buffer); - snprintf(buffer, SIZE, " duration encoded : %lld us\n", mTrackDurationUs); + snprintf(buffer, SIZE, " duration encoded : %" PRId64 " us\n", mTrackDurationUs); result.append(buffer); ::write(fd, result.string(), result.size()); return OK; @@ -1404,7 +1405,7 @@ void MPEG4Writer::Track::addOneSttsTableEntry( size_t sampleCount, int32_t duration) { if (duration == 0) { - ALOGW("0-duration samples found: %d", sampleCount); + ALOGW("0-duration samples found: %zu", sampleCount); } mSttsTableEntries->add(htonl(sampleCount)); mSttsTableEntries->add(htonl(duration)); @@ -1584,7 +1585,7 @@ void MPEG4Writer::writeAllChunks() { sendSessionSummary(); mChunkInfos.clear(); - ALOGD("%d chunks are written in the last batch", outstandingChunks); + ALOGD("%zu chunks are written in the last batch", outstandingChunks); } bool MPEG4Writer::findChunkToWrite(Chunk *chunk) { @@ -1774,7 +1775,7 @@ status_t MPEG4Writer::Track::stop() { void *dummy; pthread_join(mThread, &dummy); - status_t err = (status_t) dummy; + status_t err = static_cast<status_t>(reinterpret_cast<uintptr_t>(dummy)); ALOGD("Stopping %s track source", mIsAudio? "Audio": "Video"); { @@ -1797,7 +1798,7 @@ void *MPEG4Writer::Track::ThreadWrapper(void *me) { Track *track = static_cast<Track *>(me); status_t err = track->threadEntry(); - return (void *) err; + return (void *)(uintptr_t)err; } static void getNalUnitType(uint8_t byte, uint8_t* type) { @@ -1869,7 +1870,7 @@ status_t MPEG4Writer::Track::copyAVCCodecSpecificData( // 2 bytes for each of the parameter set length field // plus the 7 bytes for the header if (size < 4 + 7) { - ALOGE("Codec specific data length too short: %d", size); + ALOGE("Codec specific data length too short: %zu", size); return ERROR_MALFORMED; } @@ -1938,7 +1939,7 @@ status_t MPEG4Writer::Track::parseAVCCodecSpecificData( } if (nSeqParamSets > 0x1F) { - ALOGE("Too many seq parameter sets (%d) found", nSeqParamSets); + ALOGE("Too many seq parameter sets (%zu) found", nSeqParamSets); return ERROR_MALFORMED; } } @@ -1951,7 +1952,7 @@ status_t MPEG4Writer::Track::parseAVCCodecSpecificData( return ERROR_MALFORMED; } if (nPicParamSets > 0xFF) { - ALOGE("Too many pic parameter sets (%d) found", nPicParamSets); + ALOGE("Too many pic parameter sets (%zd) found", nPicParamSets); return ERROR_MALFORMED; } } @@ -1981,7 +1982,7 @@ status_t MPEG4Writer::Track::makeAVCCodecSpecificData( } if (size < 4) { - ALOGE("Codec specific data length too short: %d", size); + ALOGE("Codec specific data length too short: %zu", size); return ERROR_MALFORMED; } diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp index e299caf..c4c47b3 100644 --- a/media/libstagefright/MediaCodec.cpp +++ b/media/libstagefright/MediaCodec.cpp @@ -1506,7 +1506,8 @@ void MediaCodec::returnBuffersToCodecOnPort(int32_t portIndex) { info->mOwnedByClient = false; if (portIndex == kPortIndexInput) { - msg->setInt32("err", ERROR_END_OF_STREAM); + /* no error, just returning buffers */ + msg->setInt32("err", OK); } msg->post(); } @@ -1679,7 +1680,7 @@ status_t MediaCodec::onReleaseOutputBuffer(const sp<AMessage> &msg) { return -EACCES; } - if (render && (info->mData == NULL || info->mData->size() != 0)) { + if (render && info->mData != NULL && info->mData->size() != 0) { info->mNotify->setInt32("render", true); if (mSoftRenderer != NULL) { diff --git a/media/libstagefright/MetaData.cpp b/media/libstagefright/MetaData.cpp index ae6ae2d..74234a6 100644 --- a/media/libstagefright/MetaData.cpp +++ b/media/libstagefright/MetaData.cpp @@ -16,6 +16,7 @@ //#define LOG_NDEBUG 0 #define LOG_TAG "MetaData" +#include <inttypes.h> #include <utils/Log.h> #include <stdlib.h> @@ -89,6 +90,9 @@ bool MetaData::setRect( return setData(key, TYPE_RECT, &r, sizeof(r)); } +/** + * Note that the returned pointer becomes invalid when additional metadata is set. + */ bool MetaData::findCString(uint32_t key, const char **value) { uint32_t type; const void *data; @@ -218,6 +222,16 @@ bool MetaData::findData(uint32_t key, uint32_t *type, return true; } +bool MetaData::hasData(uint32_t key) const { + ssize_t i = mItems.indexOfKey(key); + + if (i < 0) { + return false; + } + + return true; +} + MetaData::typed_data::typed_data() : mType(0), mSize(0) { @@ -294,7 +308,7 @@ String8 MetaData::typed_data::asString() const { const void *data = storage(); switch(mType) { case TYPE_NONE: - out = String8::format("no type, size %d)", mSize); + out = String8::format("no type, size %zu)", mSize); break; case TYPE_C_STRING: out = String8::format("(char*) %s", (const char *)data); @@ -303,7 +317,7 @@ String8 MetaData::typed_data::asString() const { out = String8::format("(int32_t) %d", *(int32_t *)data); break; case TYPE_INT64: - out = String8::format("(int64_t) %lld", *(int64_t *)data); + out = String8::format("(int64_t) %" PRId64, *(int64_t *)data); break; case TYPE_FLOAT: out = String8::format("(float) %f", *(float *)data); @@ -320,7 +334,7 @@ String8 MetaData::typed_data::asString() const { } default: - out = String8::format("(unknown type %d, size %d)", mType, mSize); + out = String8::format("(unknown type %d, size %zu)", mType, mSize); if (mSize <= 48) { // if it's less than three lines of hex data, dump it AString foo; hexdump(data, mSize, 0, &foo); diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp index 7f56af8..43736ad 100644 --- a/media/libstagefright/OMXCodec.cpp +++ b/media/libstagefright/OMXCodec.cpp @@ -359,12 +359,7 @@ sp<MediaSource> OMXCodec::Create( observer->setCodec(codec); err = codec->configureCodec(meta); - if (err == OK) { - if (!strcmp("OMX.Nvidia.mpeg2v.decode", componentName)) { - codec->mFlags |= kOnlySubmitOneInputBufferAtOneTime; - } - return codec; } @@ -1346,8 +1341,7 @@ OMXCodec::OMXCodec( mLeftOverBuffer(NULL), mPaused(false), mNativeWindow( - (!strncmp(componentName, "OMX.google.", 11) - || !strcmp(componentName, "OMX.Nvidia.mpeg2v.decode")) + (!strncmp(componentName, "OMX.google.", 11)) ? NULL : nativeWindow) { mPortStatus[kPortIndexInput] = ENABLED; mPortStatus[kPortIndexOutput] = ENABLED; diff --git a/media/libstagefright/StagefrightMetadataRetriever.cpp b/media/libstagefright/StagefrightMetadataRetriever.cpp index 19af4fb..fcd9a85 100644 --- a/media/libstagefright/StagefrightMetadataRetriever.cpp +++ b/media/libstagefright/StagefrightMetadataRetriever.cpp @@ -16,6 +16,7 @@ //#define LOG_NDEBUG 0 #define LOG_TAG "StagefrightMetadataRetriever" +#include <inttypes.h> #include <utils/Log.h> #include "include/StagefrightMetadataRetriever.h" @@ -488,7 +489,7 @@ void StagefrightMetadataRetriever::parseMetaData() { size_t numTracks = mExtractor->countTracks(); char tmp[32]; - sprintf(tmp, "%d", numTracks); + sprintf(tmp, "%zu", numTracks); mMetaData.add(METADATA_KEY_NUM_TRACKS, String8(tmp)); @@ -545,7 +546,7 @@ void StagefrightMetadataRetriever::parseMetaData() { } // The duration value is a string representing the duration in ms. - sprintf(tmp, "%lld", (maxDurationUs + 500) / 1000); + sprintf(tmp, "%" PRId64, (maxDurationUs + 500) / 1000); mMetaData.add(METADATA_KEY_DURATION, String8(tmp)); if (hasAudio) { @@ -573,7 +574,7 @@ void StagefrightMetadataRetriever::parseMetaData() { if (mSource->getSize(&sourceSize) == OK) { int64_t avgBitRate = (int64_t)(sourceSize * 8E6 / maxDurationUs); - sprintf(tmp, "%lld", avgBitRate); + sprintf(tmp, "%" PRId64, avgBitRate); mMetaData.add(METADATA_KEY_BITRATE, String8(tmp)); } } diff --git a/media/libstagefright/TimedEventQueue.cpp b/media/libstagefright/TimedEventQueue.cpp index 6a16bb4..0afac69 100644 --- a/media/libstagefright/TimedEventQueue.cpp +++ b/media/libstagefright/TimedEventQueue.cpp @@ -38,11 +38,14 @@ namespace android { +static int64_t kWakelockMinDelay = 100000ll; // 100ms + TimedEventQueue::TimedEventQueue() : mNextEventID(1), mRunning(false), mStopped(false), - mDeathRecipient(new PMDeathRecipient(this)) { + mDeathRecipient(new PMDeathRecipient(this)), + mWakeLockCount(0) { } TimedEventQueue::~TimedEventQueue() { @@ -87,9 +90,7 @@ void TimedEventQueue::stop(bool flush) { // some events may be left in the queue if we did not flush and the wake lock // must be released. - if (!mQueue.empty()) { - releaseWakeLock_l(); - } + releaseWakeLock_l(true /*force*/); mQueue.clear(); mRunning = false; @@ -126,13 +127,15 @@ TimedEventQueue::event_id TimedEventQueue::postTimedEvent( QueueItem item; item.event = event; item.realtime_us = realtime_us; + item.has_wakelock = false; if (it == mQueue.begin()) { mQueueHeadChangedCondition.signal(); } - if (mQueue.empty()) { + if (realtime_us > ALooper::GetNowUs() + kWakelockMinDelay) { acquireWakeLock_l(); + item.has_wakelock = true; } mQueue.insert(it, item); @@ -188,10 +191,10 @@ void TimedEventQueue::cancelEvents( ALOGV("cancelling event %d", (*it).event->eventID()); (*it).event->setEventID(0); - it = mQueue.erase(it); - if (mQueue.empty()) { + if ((*it).has_wakelock) { releaseWakeLock_l(); } + it = mQueue.erase(it); if (stopAfterFirstMatch) { return; } @@ -214,6 +217,7 @@ void TimedEventQueue::threadEntry() { for (;;) { int64_t now_us = 0; sp<Event> event; + bool wakeLocked = false; { Mutex::Autolock autoLock(mLock); @@ -280,28 +284,29 @@ void TimedEventQueue::threadEntry() { // removeEventFromQueue_l will return NULL. // Otherwise, the QueueItem will be removed // from the queue and the referenced event returned. - event = removeEventFromQueue_l(eventID); + event = removeEventFromQueue_l(eventID, &wakeLocked); } if (event != NULL) { // Fire event with the lock NOT held. event->fire(this, now_us); + if (wakeLocked) { + Mutex::Autolock autoLock(mLock); + releaseWakeLock_l(); + } } } } sp<TimedEventQueue::Event> TimedEventQueue::removeEventFromQueue_l( - event_id id) { + event_id id, bool *wakeLocked) { for (List<QueueItem>::iterator it = mQueue.begin(); it != mQueue.end(); ++it) { if ((*it).event->eventID() == id) { sp<Event> event = (*it).event; event->setEventID(0); - + *wakeLocked = (*it).has_wakelock; mQueue.erase(it); - if (mQueue.empty()) { - releaseWakeLock_l(); - } return event; } } @@ -313,51 +318,61 @@ sp<TimedEventQueue::Event> TimedEventQueue::removeEventFromQueue_l( void TimedEventQueue::acquireWakeLock_l() { - if (mWakeLockToken != 0) { - return; - } - if (mPowerManager == 0) { - // use checkService() to avoid blocking if power service is not up yet - sp<IBinder> binder = - defaultServiceManager()->checkService(String16("power")); - if (binder == 0) { - ALOGW("cannot connect to the power manager service"); - } else { - mPowerManager = interface_cast<IPowerManager>(binder); - binder->linkToDeath(mDeathRecipient); + if (mWakeLockCount == 0) { + CHECK(mWakeLockToken == 0); + if (mPowerManager == 0) { + // use checkService() to avoid blocking if power service is not up yet + sp<IBinder> binder = + defaultServiceManager()->checkService(String16("power")); + if (binder == 0) { + ALOGW("cannot connect to the power manager service"); + } else { + mPowerManager = interface_cast<IPowerManager>(binder); + binder->linkToDeath(mDeathRecipient); + } } - } - if (mPowerManager != 0) { - sp<IBinder> binder = new BBinder(); - int64_t token = IPCThreadState::self()->clearCallingIdentity(); - status_t status = mPowerManager->acquireWakeLock(POWERMANAGER_PARTIAL_WAKE_LOCK, - binder, - String16("TimedEventQueue"), - String16("media")); - IPCThreadState::self()->restoreCallingIdentity(token); - if (status == NO_ERROR) { - mWakeLockToken = binder; + if (mPowerManager != 0) { + sp<IBinder> binder = new BBinder(); + int64_t token = IPCThreadState::self()->clearCallingIdentity(); + status_t status = mPowerManager->acquireWakeLock(POWERMANAGER_PARTIAL_WAKE_LOCK, + binder, + String16("TimedEventQueue"), + String16("media")); + IPCThreadState::self()->restoreCallingIdentity(token); + if (status == NO_ERROR) { + mWakeLockToken = binder; + mWakeLockCount++; + } } + } else { + mWakeLockCount++; } } -void TimedEventQueue::releaseWakeLock_l() +void TimedEventQueue::releaseWakeLock_l(bool force) { - if (mWakeLockToken == 0) { + if (mWakeLockCount == 0) { return; } - if (mPowerManager != 0) { - int64_t token = IPCThreadState::self()->clearCallingIdentity(); - mPowerManager->releaseWakeLock(mWakeLockToken, 0); - IPCThreadState::self()->restoreCallingIdentity(token); + if (force) { + // Force wakelock release below by setting reference count to 1. + mWakeLockCount = 1; + } + if (--mWakeLockCount == 0) { + CHECK(mWakeLockToken != 0); + if (mPowerManager != 0) { + int64_t token = IPCThreadState::self()->clearCallingIdentity(); + mPowerManager->releaseWakeLock(mWakeLockToken, 0); + IPCThreadState::self()->restoreCallingIdentity(token); + } + mWakeLockToken.clear(); } - mWakeLockToken.clear(); } void TimedEventQueue::clearPowerManager() { Mutex::Autolock _l(mLock); - releaseWakeLock_l(); + releaseWakeLock_l(true /*force*/); mPowerManager.clear(); } diff --git a/media/libstagefright/Utils.cpp b/media/libstagefright/Utils.cpp index 4db8e80..216a329 100644 --- a/media/libstagefright/Utils.cpp +++ b/media/libstagefright/Utils.cpp @@ -540,7 +540,8 @@ const struct mime_conv_t* p = &mimeLookup[0]; return BAD_VALUE; } -bool canOffloadStream(const sp<MetaData>& meta, bool hasVideo, bool isStreaming) +bool canOffloadStream(const sp<MetaData>& meta, bool hasVideo, + bool isStreaming, audio_stream_type_t streamType) { const char *mime; CHECK(meta->findCString(kKeyMIMEType, &mime)); @@ -561,6 +562,17 @@ bool canOffloadStream(const sp<MetaData>& meta, bool hasVideo, bool isStreaming) return false; } + // check whether it is ELD/LD content -> no offloading + // FIXME: this should depend on audio DSP capabilities. mapMimeToAudioFormat() should use the + // metadata to refine the AAC format and the audio HAL should only list supported profiles. + int32_t aacaot = -1; + if (meta->findInt32(kKeyAACAOT, &aacaot)) { + if (aacaot == 23 || aacaot == 39 ) { + ALOGV("track of type '%s' is ELD/LD content", mime); + return false; + } + } + int32_t srate = -1; if (!meta->findInt32(kKeySampleRate, &srate)) { ALOGV("track of type '%s' does not publish sample rate", mime); @@ -594,7 +606,7 @@ bool canOffloadStream(const sp<MetaData>& meta, bool hasVideo, bool isStreaming) info.bit_rate = brate; - info.stream_type = AUDIO_STREAM_MUSIC; + info.stream_type = streamType; info.has_video = hasVideo; info.is_streaming = isStreaming; diff --git a/media/libstagefright/codecs/avc/enc/SoftAVCEncoder.cpp b/media/libstagefright/codecs/avc/enc/SoftAVCEncoder.cpp index 4a21a3e..1d398fb 100644 --- a/media/libstagefright/codecs/avc/enc/SoftAVCEncoder.cpp +++ b/media/libstagefright/codecs/avc/enc/SoftAVCEncoder.cpp @@ -593,6 +593,17 @@ OMX_ERRORTYPE SoftAVCEncoder::internalSetParameter( mVideoHeight = def->format.video.nFrameHeight; mVideoFrameRate = def->format.video.xFramerate >> 16; mVideoColorFormat = def->format.video.eColorFormat; + + OMX_PARAM_PORTDEFINITIONTYPE *portDef = + &editPortInfo(0)->mDef; + portDef->format.video.nFrameWidth = mVideoWidth; + portDef->format.video.nFrameHeight = mVideoHeight; + portDef->format.video.xFramerate = def->format.video.xFramerate; + portDef->format.video.eColorFormat = + (OMX_COLOR_FORMATTYPE) mVideoColorFormat; + portDef = &editPortInfo(1)->mDef; + portDef->format.video.nFrameWidth = mVideoWidth; + portDef->format.video.nFrameHeight = mVideoHeight; } else { mVideoBitRate = def->format.video.nBitrate; } diff --git a/media/libstagefright/codecs/avc/enc/src/bitstream_io.cpp b/media/libstagefright/codecs/avc/enc/src/bitstream_io.cpp index 0e3037f..d71c327 100644 --- a/media/libstagefright/codecs/avc/enc/src/bitstream_io.cpp +++ b/media/libstagefright/codecs/avc/enc/src/bitstream_io.cpp @@ -103,6 +103,15 @@ AVCEnc_Status AVCBitstreamSaveWord(AVCEncBitstream *stream) { num_bits -= 8; byte = (current_word >> num_bits) & 0xFF; + if (stream->count_zeros == 2) + { /* for num_bits = 32, this can add 2 more bytes extra for EPBS */ + if (byte <= 3) + { + *write_pnt++ = 0x3; + stream->write_pos++; + stream->count_zeros = 0; + } + } if (byte != 0) { *write_pnt++ = byte; @@ -114,12 +123,6 @@ AVCEnc_Status AVCBitstreamSaveWord(AVCEncBitstream *stream) stream->count_zeros++; *write_pnt++ = byte; stream->write_pos++; - if (stream->count_zeros == 2) - { /* for num_bits = 32, this can add 2 more bytes extra for EPBS */ - *write_pnt++ = 0x3; - stream->write_pos++; - stream->count_zeros = 0; - } } } diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/get_pred_adv_b_add.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/get_pred_adv_b_add.cpp index e23f23d..fe9e7dc 100644 --- a/media/libstagefright/codecs/m4v_h263/dec/src/get_pred_adv_b_add.cpp +++ b/media/libstagefright/codecs/m4v_h263/dec/src/get_pred_adv_b_add.cpp @@ -96,7 +96,7 @@ int GetPredAdvancedBy0x0( offset = width - B_SIZE; /* offset for prev */ offset2 = (pred_width_rnd >> 1) - 4; /* offset for pred_block */ - tmp = (uint32)prev & 0x3; + tmp = (uintptr_t)prev & 0x3; pred_block -= offset2; /* preset */ if (tmp == 0) /* word-aligned */ @@ -203,7 +203,7 @@ int GetPredAdvancedBy0x1( /* Branch based on pixel location (half-pel or full-pel) for x and y */ pred_block -= offset2; /* preset */ - tmp = (uint32)prev & 3; + tmp = (uintptr_t)prev & 3; mask = 254; mask |= (mask << 8); mask |= (mask << 16); /* 0xFEFEFEFE */ @@ -532,7 +532,7 @@ int GetPredAdvancedBy1x0( /* Branch based on pixel location (half-pel or full-pel) for x and y */ pred_block -= offset2; /* preset */ - tmp = (uint32)prev & 3; + tmp = (uintptr_t)prev & 3; mask = 254; mask |= (mask << 8); mask |= (mask << 16); /* 0xFEFEFEFE */ @@ -884,7 +884,7 @@ int GetPredAdvancedBy1x1( mask |= (mask << 8); mask |= (mask << 16); /* 0x3f3f3f3f */ - tmp = (uint32)prev & 3; + tmp = (uintptr_t)prev & 3; pred_block -= 4; /* preset */ diff --git a/media/libstagefright/codecs/m4v_h263/enc/src/dct.cpp b/media/libstagefright/codecs/m4v_h263/enc/src/dct.cpp index fa50eeb..fa4ae23 100644 --- a/media/libstagefright/codecs/m4v_h263/enc/src/dct.cpp +++ b/media/libstagefright/codecs/m4v_h263/enc/src/dct.cpp @@ -250,7 +250,7 @@ extern "C" out[40] = k4 ; /* row 5 */ out++; } - while ((UInt)out < (UInt)dst) ; + while ((uintptr_t)out < (uintptr_t)dst) ; return ; } @@ -455,7 +455,7 @@ extern "C" out[8] = k5 ; /* row 1 */ out++; } - while ((UInt)out < (UInt)dst) ; + while ((uintptr_t)out < (uintptr_t)dst) ; return ; } @@ -635,7 +635,7 @@ extern "C" out[8] = k5 ; /* row 1 */ out++; } - while ((UInt)out < (UInt)dst) ; + while ((uintptr_t)out < (uintptr_t)dst) ; return ; } @@ -846,7 +846,7 @@ extern "C" out[40] = k4 ; /* row 5 */ out++; } - while ((UInt)out < (UInt)dst) ; + while ((uintptr_t)out < (uintptr_t)dst) ; return ; } @@ -1033,7 +1033,7 @@ extern "C" out[8] = k5 ; /* row 1 */ out++; } - while ((UInt)out < (UInt)dst) ; + while ((uintptr_t)out < (uintptr_t)dst) ; return ; } @@ -1195,7 +1195,7 @@ extern "C" out[8] = k5 ; /* row 1 */ out++; } - while ((UInt)out < (UInt)dst) ; + while ((uintptr_t)out < (uintptr_t)dst) ; return ; } diff --git a/media/libstagefright/codecs/m4v_h263/enc/src/fastcodemb.cpp b/media/libstagefright/codecs/m4v_h263/enc/src/fastcodemb.cpp index 6fd41c3..0ad39a6 100644 --- a/media/libstagefright/codecs/m4v_h263/enc/src/fastcodemb.cpp +++ b/media/libstagefright/codecs/m4v_h263/enc/src/fastcodemb.cpp @@ -572,7 +572,7 @@ Int Sad8x8(UChar *cur, UChar *prev, Int width) cur2 = cur2 & (mask << 8); /* mask first and third bytes */ sum2 = sum2 + ((UInt)cur2 >> 8); } - while ((UInt)curInt < (UInt)end); + while ((uintptr_t)curInt < (uintptr_t)end); cur1 = sum4 - (sum2 << 8); /* get even-sum */ cur1 = cur1 + sum2; /* add 16 bit even-sum and odd-sum*/ @@ -611,7 +611,7 @@ Int getBlockSum(UChar *cur, Int width) load2 = load2 & (mask << 8); /* even bytes */ sum2 += ((UInt)load2 >> 8); /* sum even bytes, 16 bit */ } - while ((UInt)curInt < (UInt)end); + while ((uintptr_t)curInt < (uintptr_t)end); load1 = sum4 - (sum2 << 8); /* get even-sum */ load1 = load1 + sum2; /* add 16 bit even-sum and odd-sum*/ load1 = load1 + (load1 << 16); /* add upper and lower 16 bit sum */ diff --git a/media/libstagefright/codecs/m4v_h263/enc/src/motion_comp.cpp b/media/libstagefright/codecs/m4v_h263/enc/src/motion_comp.cpp index b81d278..06e8926 100644 --- a/media/libstagefright/codecs/m4v_h263/enc/src/motion_comp.cpp +++ b/media/libstagefright/codecs/m4v_h263/enc/src/motion_comp.cpp @@ -1959,7 +1959,7 @@ void PutSkippedBlock(UChar *rec, UChar *prev, Int lx) dst += offset; src += offset; } - while ((UInt)src < (UInt)end); + while ((uintptr_t)src < (uintptr_t)end); return ; } diff --git a/media/libstagefright/codecs/m4v_h263/enc/src/sad_inline.h b/media/libstagefright/codecs/m4v_h263/enc/src/sad_inline.h index ba77dfd..b865f23 100644 --- a/media/libstagefright/codecs/m4v_h263/enc/src/sad_inline.h +++ b/media/libstagefright/codecs/m4v_h263/enc/src/sad_inline.h @@ -85,7 +85,7 @@ extern "C" x9 = 0x80808080; /* const. */ - x8 = (uint32)ref & 0x3; + x8 = (uintptr_t)ref & 0x3; if (x8 == 3) goto SadMBOffset3; if (x8 == 2) diff --git a/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp b/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp index 8375cac..5efe022 100644 --- a/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp +++ b/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp @@ -677,6 +677,9 @@ OMX_ERRORTYPE SoftVPXEncoder::internalSetPortParams( def->format.video.nFrameHeight = mHeight; def->format.video.xFramerate = port->format.video.xFramerate; def->format.video.eColorFormat = mColorFormat; + def = &editPortInfo(kOutputPortIndex)->mDef; + def->format.video.nFrameWidth = mWidth; + def->format.video.nFrameHeight = mHeight; return OMX_ErrorNone; } else if (port->nPortIndex == kOutputPortIndex) { diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_util.h b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_util.h index cb3adda..216ad04 100755 --- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_util.h +++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_util.h @@ -42,6 +42,7 @@ #include <stdio.h> #endif +#include <stdint.h> #include "basetype.h" #include "h264bsd_stream.h" #include "h264bsd_image.h" @@ -150,7 +151,7 @@ } #define ALIGN(ptr, bytePos) \ - (ptr + ( ((bytePos - (int)ptr) & (bytePos - 1)) / sizeof(*ptr) )) + (ptr + ( ((bytePos - (uintptr_t)ptr) & (bytePos - 1)) / sizeof(*ptr) )) extern const u32 h264bsdQpC[52]; diff --git a/media/libstagefright/httplive/LiveSession.cpp b/media/libstagefright/httplive/LiveSession.cpp index d4fd2b3..fc1353a 100644 --- a/media/libstagefright/httplive/LiveSession.cpp +++ b/media/libstagefright/httplive/LiveSession.cpp @@ -640,9 +640,6 @@ sp<M3UParser> LiveSession::fetchPlaylist( // playlist unchanged *unchanged = true; - ALOGV("Playlist unchanged, refresh state is now %d", - (int)mRefreshState); - return NULL; } diff --git a/media/libstagefright/httplive/M3UParser.cpp b/media/libstagefright/httplive/M3UParser.cpp index 243888c..5ef7c0f 100644 --- a/media/libstagefright/httplive/M3UParser.cpp +++ b/media/libstagefright/httplive/M3UParser.cpp @@ -416,22 +416,32 @@ static bool MakeURL(const char *baseURL, const char *url, AString *out) { } else { // URL is a relative path - size_t n = strlen(baseURL); - if (baseURL[n - 1] == '/') { - out->setTo(baseURL); - out->append(url); + // Check for a possible query string + const char *qsPos = strchr(baseURL, '?'); + size_t end; + if (qsPos != NULL) { + end = qsPos - baseURL; } else { - const char *slashPos = strrchr(baseURL, '/'); - - if (slashPos > &baseURL[6]) { - out->setTo(baseURL, slashPos - baseURL); - } else { - out->setTo(baseURL); + end = strlen(baseURL); + } + // Check for the last slash before a potential query string + for (ssize_t pos = end - 1; pos >= 0; pos--) { + if (baseURL[pos] == '/') { + end = pos; + break; } + } - out->append("/"); - out->append(url); + // Check whether the found slash actually is part of the path + // and not part of the "http://". + if (end > 6) { + out->setTo(baseURL, end); + } else { + out->setTo(baseURL); } + + out->append("/"); + out->append(url); } ALOGV("base:'%s', url:'%s' => '%s'", baseURL, url, out->c_str()); @@ -608,7 +618,7 @@ status_t M3UParser::parseMetaDataDuration( if (meta->get() == NULL) { *meta = new AMessage; } - (*meta)->setInt64(key, (int64_t)x * 1E6); + (*meta)->setInt64(key, (int64_t)(x * 1E6)); return OK; } diff --git a/media/libstagefright/id3/ID3.cpp b/media/libstagefright/id3/ID3.cpp index 34d671a..1ec4a40 100644 --- a/media/libstagefright/id3/ID3.cpp +++ b/media/libstagefright/id3/ID3.cpp @@ -56,14 +56,14 @@ private: DISALLOW_EVIL_CONSTRUCTORS(MemorySource); }; -ID3::ID3(const sp<DataSource> &source, bool ignoreV1) +ID3::ID3(const sp<DataSource> &source, bool ignoreV1, off64_t offset) : mIsValid(false), mData(NULL), mSize(0), mFirstFrameOffset(0), mVersion(ID3_UNKNOWN), mRawSize(0) { - mIsValid = parseV2(source); + mIsValid = parseV2(source, offset); if (!mIsValid && !ignoreV1) { mIsValid = parseV1(source); @@ -79,7 +79,7 @@ ID3::ID3(const uint8_t *data, size_t size, bool ignoreV1) mRawSize(0) { sp<MemorySource> source = new MemorySource(data, size); - mIsValid = parseV2(source); + mIsValid = parseV2(source, 0); if (!mIsValid && !ignoreV1) { mIsValid = parseV1(source); @@ -115,7 +115,7 @@ bool ID3::ParseSyncsafeInteger(const uint8_t encoded[4], size_t *x) { return true; } -bool ID3::parseV2(const sp<DataSource> &source) { +bool ID3::parseV2(const sp<DataSource> &source, off64_t offset) { struct id3_header { char id[3]; uint8_t version_major; @@ -126,7 +126,7 @@ struct id3_header { id3_header header; if (source->readAt( - 0, &header, sizeof(header)) != (ssize_t)sizeof(header)) { + offset, &header, sizeof(header)) != (ssize_t)sizeof(header)) { return false; } @@ -185,7 +185,7 @@ struct id3_header { mSize = size; mRawSize = mSize + sizeof(header); - if (source->readAt(sizeof(header), mData, mSize) != (ssize_t)mSize) { + if (source->readAt(offset + sizeof(header), mData, mSize) != (ssize_t)mSize) { free(mData); mData = NULL; diff --git a/media/libstagefright/id3/testid3.cpp b/media/libstagefright/id3/testid3.cpp index bc4572c..b2f4188 100644 --- a/media/libstagefright/id3/testid3.cpp +++ b/media/libstagefright/id3/testid3.cpp @@ -33,7 +33,7 @@ static void hexdump(const void *_data, size_t size) { const uint8_t *data = (const uint8_t *)_data; size_t offset = 0; while (offset < size) { - printf("0x%04x ", offset); + printf("0x%04zx ", offset); size_t n = size - offset; if (n > 16) { @@ -101,7 +101,7 @@ void scanFile(const char *path) { const void *data = tag.getAlbumArt(&dataSize, &mime); if (data) { - printf("found album art: size=%d mime='%s'\n", dataSize, + printf("found album art: size=%zu mime='%s'\n", dataSize, mime.string()); hexdump(data, dataSize > 128 ? 128 : dataSize); diff --git a/media/libstagefright/include/ID3.h b/media/libstagefright/include/ID3.h index cca83ab..e83f3ef 100644 --- a/media/libstagefright/include/ID3.h +++ b/media/libstagefright/include/ID3.h @@ -35,7 +35,7 @@ struct ID3 { ID3_V2_4, }; - ID3(const sp<DataSource> &source, bool ignoreV1 = false); + ID3(const sp<DataSource> &source, bool ignoreV1 = false, off64_t offset = 0); ID3(const uint8_t *data, size_t size, bool ignoreV1 = false); ~ID3(); @@ -86,7 +86,7 @@ private: size_t mRawSize; bool parseV1(const sp<DataSource> &source); - bool parseV2(const sp<DataSource> &source); + bool parseV2(const sp<DataSource> &source, off64_t offset); void removeUnsynchronization(); bool removeUnsynchronizationV2_4(bool iTunesHack); diff --git a/media/libstagefright/include/MPEG4Extractor.h b/media/libstagefright/include/MPEG4Extractor.h index bd5e4b9..7b4bc6d 100644 --- a/media/libstagefright/include/MPEG4Extractor.h +++ b/media/libstagefright/include/MPEG4Extractor.h @@ -97,6 +97,7 @@ private: status_t parseChunk(off64_t *offset, int depth); status_t parseITunesMetaData(off64_t offset, size_t size); status_t parse3GPPMetaData(off64_t offset, size_t size, int depth); + void parseID3v2MetaData(off64_t offset); status_t updateAudioTrackInfoFromESDS_MPEG4Audio( const void *esds_data, size_t esds_size); diff --git a/media/libstagefright/include/TimedEventQueue.h b/media/libstagefright/include/TimedEventQueue.h index 4e49c83..3e84256 100644 --- a/media/libstagefright/include/TimedEventQueue.h +++ b/media/libstagefright/include/TimedEventQueue.h @@ -118,6 +118,7 @@ private: struct QueueItem { sp<Event> event; int64_t realtime_us; + bool has_wakelock; }; struct StopEvent : public TimedEventQueue::Event { @@ -139,14 +140,15 @@ private: sp<IPowerManager> mPowerManager; sp<IBinder> mWakeLockToken; const sp<PMDeathRecipient> mDeathRecipient; + uint32_t mWakeLockCount; static void *ThreadWrapper(void *me); void threadEntry(); - sp<Event> removeEventFromQueue_l(event_id id); + sp<Event> removeEventFromQueue_l(event_id id, bool *wakeLocked); void acquireWakeLock_l(); - void releaseWakeLock_l(); + void releaseWakeLock_l(bool force = false); TimedEventQueue(const TimedEventQueue &); TimedEventQueue &operator=(const TimedEventQueue &); diff --git a/media/libstagefright/mpeg2ts/ATSParser.cpp b/media/libstagefright/mpeg2ts/ATSParser.cpp index 9850a46..175a263 100644 --- a/media/libstagefright/mpeg2ts/ATSParser.cpp +++ b/media/libstagefright/mpeg2ts/ATSParser.cpp @@ -1193,7 +1193,10 @@ status_t ATSParser::parseTS(ABitReader *br) { unsigned sync_byte = br->getBits(8); CHECK_EQ(sync_byte, 0x47u); - MY_LOGV("transport_error_indicator = %u", br->getBits(1)); + if (br->getBits(1)) { // transport_error_indicator + // silently ignore. + return OK; + } unsigned payload_unit_start_indicator = br->getBits(1); ALOGV("payload_unit_start_indicator = %u", payload_unit_start_indicator); diff --git a/media/libstagefright/mpeg2ts/ESQueue.cpp b/media/libstagefright/mpeg2ts/ESQueue.cpp index 8f9c9c8..e0ff0d1 100644 --- a/media/libstagefright/mpeg2ts/ESQueue.cpp +++ b/media/libstagefright/mpeg2ts/ESQueue.cpp @@ -604,7 +604,9 @@ sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitH264() { dstOffset += pos.nalSize + 4; } +#if !LOG_NDEBUG ALOGV("accessUnit contains nal types %s", out.c_str()); +#endif const NALPosition &pos = nals.itemAt(nals.size() - 1); size_t nextScan = pos.nalOffset + pos.nalSize; diff --git a/media/libstagefright/omx/GraphicBufferSource.cpp b/media/libstagefright/omx/GraphicBufferSource.cpp index cf43e94..b8970ad 100644 --- a/media/libstagefright/omx/GraphicBufferSource.cpp +++ b/media/libstagefright/omx/GraphicBufferSource.cpp @@ -148,6 +148,18 @@ void GraphicBufferSource::omxExecuting() { } } +void GraphicBufferSource::omxIdle() { + ALOGV("omxIdle"); + + Mutex::Autolock autoLock(mMutex); + + if (mExecuting) { + // We are only interested in the transition from executing->idle, + // not loaded->idle. + mExecuting = false; + } +} + void GraphicBufferSource::omxLoaded(){ Mutex::Autolock autoLock(mMutex); if (!mExecuting) { @@ -194,7 +206,9 @@ void GraphicBufferSource::addCodecBuffer(OMX_BUFFERHEADERTYPE* header) { void GraphicBufferSource::codecBufferEmptied(OMX_BUFFERHEADERTYPE* header) { Mutex::Autolock autoLock(mMutex); - CHECK(mExecuting); // could this happen if app stop()s early? + if (!mExecuting) { + return; + } int cbi = findMatchingCodecBuffer_l(header); if (cbi < 0) { @@ -213,7 +227,12 @@ void GraphicBufferSource::codecBufferEmptied(OMX_BUFFERHEADERTYPE* header) { // see if the GraphicBuffer reference was null, which should only ever // happen for EOS. if (codecBuffer.mGraphicBuffer == NULL) { - CHECK(mEndOfStream && mEndOfStreamSent); + if (!(mEndOfStream && mEndOfStreamSent)) { + // This can happen when broken code sends us the same buffer + // twice in a row. + ALOGE("ERROR: codecBufferEmptied on non-EOS null buffer " + "(buffer emptied twice?)"); + } // No GraphicBuffer to deal with, no additional input or output is // expected, so just return. return; @@ -384,6 +403,23 @@ bool GraphicBufferSource::repeatLatestSubmittedBuffer_l() { if (mLatestSubmittedBufferId < 0 || mSuspended) { return false; } + if (mBufferSlot[mLatestSubmittedBufferId] == NULL) { + // This can happen if the remote side disconnects, causing + // onBuffersReleased() to NULL out our copy of the slots. The + // buffer is gone, so we have nothing to show. + // + // To be on the safe side we try to release the buffer. + ALOGD("repeatLatestSubmittedBuffer_l: slot was NULL"); + mBufferQueue->releaseBuffer( + mLatestSubmittedBufferId, + mLatestSubmittedBufferFrameNum, + EGL_NO_DISPLAY, + EGL_NO_SYNC_KHR, + Fence::NO_FENCE); + mLatestSubmittedBufferId = -1; + mLatestSubmittedBufferFrameNum = 0; + return false; + } int cbi = findAvailableCodecBuffer_l(); if (cbi < 0) { diff --git a/media/libstagefright/omx/GraphicBufferSource.h b/media/libstagefright/omx/GraphicBufferSource.h index 244a843..9e5eee6 100644 --- a/media/libstagefright/omx/GraphicBufferSource.h +++ b/media/libstagefright/omx/GraphicBufferSource.h @@ -69,6 +69,11 @@ public: // sitting in the BufferQueue, this will send them to the codec. void omxExecuting(); + // This is called when OMX transitions to OMX_StateIdle, indicating that + // the codec is meant to return all buffers back to the client for them + // to be freed. Do NOT submit any more buffers to the component. + void omxIdle(); + // This is called when OMX transitions to OMX_StateLoaded, indicating that // we are shutting down. void omxLoaded(); diff --git a/media/libstagefright/omx/OMX.cpp b/media/libstagefright/omx/OMX.cpp index 84a0e10..274f2eb 100644 --- a/media/libstagefright/omx/OMX.cpp +++ b/media/libstagefright/omx/OMX.cpp @@ -479,7 +479,7 @@ OMX_ERRORTYPE OMX::OnFillBufferDone( OMX::node_id OMX::makeNodeID(OMXNodeInstance *instance) { // mLock is already held. - node_id node = (node_id)++mNodeCounter; + node_id node = (node_id)(uintptr_t)++mNodeCounter; mNodeIDToInstance.add(node, instance); return node; diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp index 46e5d71..5f104fc 100644 --- a/media/libstagefright/omx/OMXNodeInstance.cpp +++ b/media/libstagefright/omx/OMXNodeInstance.cpp @@ -243,13 +243,18 @@ status_t OMXNodeInstance::freeNode(OMXMaster *master) { status_t OMXNodeInstance::sendCommand( OMX_COMMANDTYPE cmd, OMX_S32 param) { const sp<GraphicBufferSource>& bufferSource(getGraphicBufferSource()); - if (bufferSource != NULL - && cmd == OMX_CommandStateSet - && param == OMX_StateLoaded) { - // Initiating transition from Executing -> Loaded - // Buffers are about to be freed. - bufferSource->omxLoaded(); - setGraphicBufferSource(NULL); + if (bufferSource != NULL && cmd == OMX_CommandStateSet) { + if (param == OMX_StateIdle) { + // Initiating transition from Executing -> Idle + // ACodec is waiting for all buffers to be returned, do NOT + // submit any more buffers to the codec. + bufferSource->omxIdle(); + } else if (param == OMX_StateLoaded) { + // Initiating transition from Idle/Executing -> Loaded + // Buffers are about to be freed. + bufferSource->omxLoaded(); + setGraphicBufferSource(NULL); + } // fall through } diff --git a/media/libstagefright/omx/tests/OMXHarness.cpp b/media/libstagefright/omx/tests/OMXHarness.cpp index 4bee808..44e4f9d 100644 --- a/media/libstagefright/omx/tests/OMXHarness.cpp +++ b/media/libstagefright/omx/tests/OMXHarness.cpp @@ -16,6 +16,7 @@ //#define LOG_NDEBUG 0 #define LOG_TAG "OMXHarness" +#include <inttypes.h> #include <utils/Log.h> #include "OMXHarness.h" @@ -711,11 +712,11 @@ status_t Harness::testSeek( int64_t bufferTimeUs; CHECK(buffer->meta_data()->findInt64(kKeyTime, &bufferTimeUs)); if (!CloseEnough(bufferTimeUs, actualSeekTimeUs)) { - printf("\n * Attempted seeking to %lld us (%.2f secs)", + printf("\n * Attempted seeking to %" PRId64 " us (%.2f secs)", requestedSeekTimeUs, requestedSeekTimeUs / 1E6); - printf("\n * Nearest keyframe is at %lld us (%.2f secs)", + printf("\n * Nearest keyframe is at %" PRId64 " us (%.2f secs)", actualSeekTimeUs, actualSeekTimeUs / 1E6); - printf("\n * Returned buffer was at %lld us (%.2f secs)\n\n", + printf("\n * Returned buffer was at %" PRId64 " us (%.2f secs)\n\n", bufferTimeUs, bufferTimeUs / 1E6); buffer->release(); diff --git a/media/libstagefright/tests/DummyRecorder.cpp b/media/libstagefright/tests/DummyRecorder.cpp index ac37b28..8f17088 100644 --- a/media/libstagefright/tests/DummyRecorder.cpp +++ b/media/libstagefright/tests/DummyRecorder.cpp @@ -61,7 +61,7 @@ status_t DummyRecorder::stop() { mSource->stop(); void *dummy; pthread_join(mThread, &dummy); - status_t err = (status_t) dummy; + status_t err = static_cast<status_t>(reinterpret_cast<uintptr_t>(dummy)); ALOGV("Ending the reading thread"); return err; diff --git a/media/libstagefright/wifi-display/source/TSPacketizer.cpp b/media/libstagefright/wifi-display/source/TSPacketizer.cpp index c674700..edcc087 100644 --- a/media/libstagefright/wifi-display/source/TSPacketizer.cpp +++ b/media/libstagefright/wifi-display/source/TSPacketizer.cpp @@ -565,7 +565,7 @@ status_t TSPacketizer::packetize( } } - // size_t numPaddingBytes = sizeAvailableForPayload - numBytesOfPayload; + size_t numPaddingBytes = sizeAvailableForPayload - numBytesOfPayload; ALOGV("packet 1 contains %zd padding bytes and %zd bytes of payload", numPaddingBytes, numBytesOfPayload); diff --git a/media/mtp/MtpDataPacket.cpp b/media/mtp/MtpDataPacket.cpp index 930f0b0..c4f87a0 100644 --- a/media/mtp/MtpDataPacket.cpp +++ b/media/mtp/MtpDataPacket.cpp @@ -331,7 +331,7 @@ void MtpDataPacket::putString(const char* s) { void MtpDataPacket::putString(const uint16_t* string) { int count = 0; - for (int i = 0; i < 256; i++) { + for (int i = 0; i <= MTP_STRING_MAX_CHARACTER_NUMBER; i++) { if (string[i]) count++; else diff --git a/media/mtp/MtpProperty.cpp b/media/mtp/MtpProperty.cpp index 64dd45b..375ed9a 100644 --- a/media/mtp/MtpProperty.cpp +++ b/media/mtp/MtpProperty.cpp @@ -16,6 +16,7 @@ #define LOG_TAG "MtpProperty" +#include <inttypes.h> #include "MtpDataPacket.h" #include "MtpDebug.h" #include "MtpProperty.h" @@ -385,10 +386,10 @@ void MtpProperty::print(MtpPropertyValue& value, MtpString& buffer) { buffer.appendFormat("%d", value.u.u32); break; case MTP_TYPE_INT64: - buffer.appendFormat("%lld", value.u.i64); + buffer.appendFormat("%" PRId64, value.u.i64); break; case MTP_TYPE_UINT64: - buffer.appendFormat("%lld", value.u.u64); + buffer.appendFormat("%" PRIu64, value.u.u64); break; case MTP_TYPE_INT128: buffer.appendFormat("%08X%08X%08X%08X", value.u.i128[0], value.u.i128[1], diff --git a/media/mtp/MtpStringBuffer.cpp b/media/mtp/MtpStringBuffer.cpp index fe8cf04..f3420a4 100644 --- a/media/mtp/MtpStringBuffer.cpp +++ b/media/mtp/MtpStringBuffer.cpp @@ -56,42 +56,47 @@ MtpStringBuffer::~MtpStringBuffer() { } void MtpStringBuffer::set(const char* src) { - int length = strlen(src); - if (length >= sizeof(mBuffer)) - length = sizeof(mBuffer) - 1; - memcpy(mBuffer, src, length); - // count the characters int count = 0; char ch; - while ((ch = *src++) != 0) { + char* dest = (char*)mBuffer; + + while ((ch = *src++) != 0 && count < MTP_STRING_MAX_CHARACTER_NUMBER) { if ((ch & 0x80) == 0) { // single byte character + *dest++ = ch; } else if ((ch & 0xE0) == 0xC0) { // two byte character - if (! *src++) { + char ch1 = *src++; + if (! ch1) { // last character was truncated, so ignore last byte - length--; break; } + + *dest++ = ch; + *dest++ = ch1; } else if ((ch & 0xF0) == 0xE0) { // 3 byte char - if (! *src++) { + char ch1 = *src++; + if (! ch1) { // last character was truncated, so ignore last byte - length--; break; } - if (! *src++) { - // last character was truncated, so ignore last two bytes - length -= 2; + char ch2 = *src++; + if (! ch2) { + // last character was truncated, so ignore last byte break; } + + *dest++ = ch; + *dest++ = ch1; + *dest++ = ch2; } count++; } - mByteCount = length + 1; - mBuffer[length] = 0; + *dest++ = 0; + mByteCount = dest - (char*)mBuffer; mCharCount = count; } @@ -100,7 +105,7 @@ void MtpStringBuffer::set(const uint16_t* src) { uint16_t ch; uint8_t* dest = mBuffer; - while ((ch = *src++) != 0 && count < 255) { + while ((ch = *src++) != 0 && count < MTP_STRING_MAX_CHARACTER_NUMBER) { if (ch >= 0x0800) { *dest++ = (uint8_t)(0xE0 | (ch >> 12)); *dest++ = (uint8_t)(0x80 | ((ch >> 6) & 0x3F)); diff --git a/media/mtp/MtpStringBuffer.h b/media/mtp/MtpStringBuffer.h index cbc8307..e5150df 100644 --- a/media/mtp/MtpStringBuffer.h +++ b/media/mtp/MtpStringBuffer.h @@ -19,6 +19,9 @@ #include <stdint.h> +// Max Character number of a MTP String +#define MTP_STRING_MAX_CHARACTER_NUMBER 255 + namespace android { class MtpDataPacket; @@ -29,7 +32,7 @@ class MtpStringBuffer { private: // mBuffer contains string in UTF8 format // maximum 3 bytes/character, with 1 extra for zero termination - uint8_t mBuffer[255 * 3 + 1]; + uint8_t mBuffer[MTP_STRING_MAX_CHARACTER_NUMBER * 3 + 1]; int mCharCount; int mByteCount; diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp index a9c9b56..e9c38e3 100644 --- a/services/audioflinger/AudioFlinger.cpp +++ b/services/audioflinger/AudioFlinger.cpp @@ -448,6 +448,7 @@ sp<IAudioTrack> AudioFlinger::createTrack( pid_t tid, int *sessionId, String8& name, + int clientUid, status_t *status) { sp<PlaybackThread::Track> track; @@ -483,6 +484,7 @@ sp<IAudioTrack> AudioFlinger::createTrack( } pid_t pid = IPCThreadState::self()->getCallingPid(); + client = registerPid_l(pid); ALOGV("createTrack() sessionId: %d", (sessionId == NULL) ? -2 : *sessionId); @@ -510,7 +512,7 @@ sp<IAudioTrack> AudioFlinger::createTrack( ALOGV("createTrack() lSessionId: %d", lSessionId); track = thread->createTrack_l(client, streamType, sampleRate, format, - channelMask, frameCount, sharedBuffer, lSessionId, flags, tid, &lStatus); + channelMask, frameCount, sharedBuffer, lSessionId, flags, tid, clientUid, &lStatus); // move effect chain to this output thread if an effect on same session was waiting // for a track to be created @@ -1008,7 +1010,7 @@ size_t AudioFlinger::getInputBufferSize(uint32_t sampleRate, audio_format_t form return size; } -unsigned int AudioFlinger::getInputFramesLost(audio_io_handle_t ioHandle) const +uint32_t AudioFlinger::getInputFramesLost(audio_io_handle_t ioHandle) const { Mutex::Autolock _l(mLock); @@ -1040,7 +1042,7 @@ status_t AudioFlinger::setVoiceVolume(float value) return ret; } -status_t AudioFlinger::getRenderPosition(size_t *halFrames, size_t *dspFrames, +status_t AudioFlinger::getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames, audio_io_handle_t output) const { status_t status; @@ -1284,8 +1286,11 @@ sp<IAudioRecord> AudioFlinger::openRecord( } // create new record track. // The record track uses one track in mHardwareMixerThread by convention. + // TODO: the uid should be passed in as a parameter to openRecord recordTrack = thread->createRecordTrack_l(client, sampleRate, format, channelMask, - frameCount, lSessionId, flags, tid, &lStatus); + frameCount, lSessionId, + IPCThreadState::self()->getCallingUid(), + flags, tid, &lStatus); LOG_ALWAYS_FATAL_IF((recordTrack != 0) != (lStatus == NO_ERROR)); } if (lStatus != NO_ERROR) { @@ -2335,6 +2340,7 @@ status_t AudioFlinger::moveEffectChain_l(int sessionId, strategy, sessionId, effect->id()); + AudioSystem::setEffectEnabled(effect->id(), effect->isEnabled()); } effect = chain->getEffectFromId_l(0); } @@ -2349,6 +2355,7 @@ status_t AudioFlinger::moveEffectChain_l(int sessionId, strategy, sessionId, removed[i]->id()); + AudioSystem::setEffectEnabled(effect->id(), effect->isEnabled()); } } } diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h index 2aeb263..7320144 100644 --- a/services/audioflinger/AudioFlinger.h +++ b/services/audioflinger/AudioFlinger.h @@ -109,6 +109,7 @@ public: pid_t tid, int *sessionId, String8& name, + int clientUid, status_t *status); virtual sp<IAudioRecord> openRecord( @@ -185,10 +186,10 @@ public: virtual status_t setVoiceVolume(float volume); - virtual status_t getRenderPosition(size_t *halFrames, size_t *dspFrames, + virtual status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames, audio_io_handle_t output) const; - virtual unsigned int getInputFramesLost(audio_io_handle_t ioHandle) const; + virtual uint32_t getInputFramesLost(audio_io_handle_t ioHandle) const; virtual int newAudioSessionId(); diff --git a/services/audioflinger/AudioMixer.cpp b/services/audioflinger/AudioMixer.cpp index df4e029..f92421e 100644 --- a/services/audioflinger/AudioMixer.cpp +++ b/services/audioflinger/AudioMixer.cpp @@ -421,15 +421,16 @@ void AudioMixer::setParameter(int name, int target, int param, void *value) ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name); track_t& track = mState.tracks[name]; - int valueInt = (int)value; - int32_t *valueBuf = (int32_t *)value; + int valueInt = static_cast<int>(reinterpret_cast<uintptr_t>(value)); + int32_t *valueBuf = reinterpret_cast<int32_t*>(value); switch (target) { case TRACK: switch (param) { case CHANNEL_MASK: { - audio_channel_mask_t mask = (audio_channel_mask_t) value; + audio_channel_mask_t mask = + static_cast<audio_channel_mask_t>(reinterpret_cast<uintptr_t>(value)); if (track.channelMask != mask) { uint32_t channelCount = popcount(mask); ALOG_ASSERT((channelCount <= MAX_NUM_CHANNELS_TO_DOWNMIX) && channelCount); @@ -1122,10 +1123,6 @@ void AudioMixer::process__genericNoResampling(state_t* state, int64_t pts) t.bufferProvider->getNextBuffer(&t.buffer, pts); t.frameCount = t.buffer.frameCount; t.in = t.buffer.raw; - // t.in == NULL can happen if the track was flushed just after having - // been enabled for mixing. - if (t.in == NULL) - enabledTracks &= ~(1<<i); } e0 = enabledTracks; @@ -1161,6 +1158,13 @@ void AudioMixer::process__genericNoResampling(state_t* state, int64_t pts) aux = t.auxBuffer + numFrames; } while (outFrames) { + // t.in == NULL can happen if the track was flushed just after having + // been enabled for mixing. + if (t.in == NULL) { + enabledTracks &= ~(1<<i); + e1 &= ~(1<<i); + break; + } size_t inFrames = (t.frameCount > outFrames)?outFrames:t.frameCount; if (inFrames) { t.hook(&t, outTemp + (BLOCKSIZE-outFrames)*MAX_NUM_CHANNELS, inFrames, diff --git a/services/audioflinger/AudioPolicyService.cpp b/services/audioflinger/AudioPolicyService.cpp index 35e816b..646a317 100644 --- a/services/audioflinger/AudioPolicyService.cpp +++ b/services/audioflinger/AudioPolicyService.cpp @@ -1433,6 +1433,14 @@ status_t AudioPolicyService::loadPreProcessorConfig(const char *path) loadEffects(root, effects); loadInputSources(root, effects); + // delete effects to fix memory leak. + // as effects is local var and valgrind would treat this as memory leak + // and although it only did in mediaserver init, but free it in case mediaserver reboot + size_t i; + for (i = 0; i < effects.size(); i++) { + delete effects[i]; + } + config_free(root); free(root); free(data); diff --git a/services/audioflinger/AudioResampler.cpp b/services/audioflinger/AudioResampler.cpp index 2c3c719..e5cceb1 100644 --- a/services/audioflinger/AudioResampler.cpp +++ b/services/audioflinger/AudioResampler.cpp @@ -526,7 +526,7 @@ void AudioResamplerOrder1::AsmMono16Loop(int16_t *in, int32_t* maxOutPt, int32_t " ldr r8, [sp, #" MO_PARAM5 " + 4]\n" // out " ldr r0, [sp, #" MO_PARAM5 " + 0]\n" // &outputIndex " ldr r0, [r0]\n" // outputIndex - " add r8, r0, asl #2\n" // curOut + " add r8, r8, r0, asl #2\n" // curOut " ldr r9, [sp, #" MO_PARAM5 " + 24]\n" // phaseIncrement " ldr r10, [sp, #" MO_PARAM5 " + 12]\n" // vl " ldr r11, [sp, #" MO_PARAM5 " + 16]\n" // vr @@ -636,7 +636,7 @@ void AudioResamplerOrder1::AsmStereo16Loop(int16_t *in, int32_t* maxOutPt, int32 " ldr r8, [sp, #" ST_PARAM5 " + 4]\n" // out " ldr r0, [sp, #" ST_PARAM5 " + 0]\n" // &outputIndex " ldr r0, [r0]\n" // outputIndex - " add r8, r0, asl #2\n" // curOut + " add r8, r8, r0, asl #2\n" // curOut " ldr r9, [sp, #" ST_PARAM5 " + 24]\n" // phaseIncrement " ldr r10, [sp, #" ST_PARAM5 " + 12]\n" // vl " ldr r11, [sp, #" ST_PARAM5 " + 16]\n" // vr diff --git a/services/audioflinger/Configuration.h b/services/audioflinger/Configuration.h index bc2038a..0754d9d 100644 --- a/services/audioflinger/Configuration.h +++ b/services/audioflinger/Configuration.h @@ -32,9 +32,6 @@ // uncomment to enable fast mixer to take performance samples for later statistical analysis #define FAST_MIXER_STATISTICS -// uncomment to allow fast tracks at non-native sample rate -//#define FAST_TRACKS_AT_NON_NATIVE_SAMPLE_RATE - // uncomment for debugging timing problems related to StateQueue::push() //#define STATE_QUEUE_DUMP diff --git a/services/audioflinger/Effects.cpp b/services/audioflinger/Effects.cpp index a8a5169..010e233 100644 --- a/services/audioflinger/Effects.cpp +++ b/services/audioflinger/Effects.cpp @@ -820,8 +820,8 @@ void AudioFlinger::EffectModule::dump(int fd, const Vector<String16>& args) } result.append("\t\tSession Status State Engine:\n"); - snprintf(buffer, SIZE, "\t\t%05d %03d %03d 0x%08x\n", - mSessionId, mStatus, mState, (uint32_t)mEffectInterface); + snprintf(buffer, SIZE, "\t\t%05d %03d %03d %p\n", + mSessionId, mStatus, mState, mEffectInterface); result.append(buffer); result.append("\t\tDescriptor:\n"); @@ -850,26 +850,26 @@ void AudioFlinger::EffectModule::dump(int fd, const Vector<String16>& args) result.append(buffer); result.append("\t\t- Input configuration:\n"); - result.append("\t\t\tBuffer Frames Smp rate Channels Format\n"); - snprintf(buffer, SIZE, "\t\t\t0x%08x %05d %05d %08x %d\n", - (uint32_t)mConfig.inputCfg.buffer.raw, + result.append("\t\t\tFrames Smp rate Channels Format Buffer\n"); + snprintf(buffer, SIZE, "\t\t\t%05zu %05d %08x %6d %p\n", mConfig.inputCfg.buffer.frameCount, mConfig.inputCfg.samplingRate, mConfig.inputCfg.channels, - mConfig.inputCfg.format); + mConfig.inputCfg.format, + mConfig.inputCfg.buffer.raw); result.append(buffer); result.append("\t\t- Output configuration:\n"); result.append("\t\t\tBuffer Frames Smp rate Channels Format\n"); - snprintf(buffer, SIZE, "\t\t\t0x%08x %05d %05d %08x %d\n", - (uint32_t)mConfig.outputCfg.buffer.raw, + snprintf(buffer, SIZE, "\t\t\t%p %05zu %05d %08x %d\n", + mConfig.outputCfg.buffer.raw, mConfig.outputCfg.buffer.frameCount, mConfig.outputCfg.samplingRate, mConfig.outputCfg.channels, mConfig.outputCfg.format); result.append(buffer); - snprintf(buffer, SIZE, "\t\t%d Clients:\n", mHandles.size()); + snprintf(buffer, SIZE, "\t\t%zu Clients:\n", mHandles.size()); result.append(buffer); result.append("\t\t\tPid Priority Ctrl Locked client server\n"); for (size_t i = 0; i < mHandles.size(); ++i) { @@ -1578,10 +1578,10 @@ void AudioFlinger::EffectChain::dump(int fd, const Vector<String16>& args) } result.append("\tNum fx In buffer Out buffer Active tracks:\n"); - snprintf(buffer, SIZE, "\t%02d 0x%08x 0x%08x %d\n", + snprintf(buffer, SIZE, "\t%02zu %p %p %d\n", mEffects.size(), - (uint32_t)mInBuffer, - (uint32_t)mOutBuffer, + mInBuffer, + mOutBuffer, mActiveTrackCnt); result.append(buffer); write(fd, result.string(), result.size()); diff --git a/services/audioflinger/FastMixer.cpp b/services/audioflinger/FastMixer.cpp index f27ea17..85d637e 100644 --- a/services/audioflinger/FastMixer.cpp +++ b/services/audioflinger/FastMixer.cpp @@ -236,7 +236,6 @@ bool FastMixer::threadLoop() sampleRate = Format_sampleRate(format); ALOG_ASSERT(Format_channelCount(format) == FCC_2); } - dumpState->mSampleRate = sampleRate; } if ((format != previousFormat) || (frameCount != previous->mFrameCount)) { @@ -321,12 +320,8 @@ bool FastMixer::threadLoop() mixer->setParameter(name, AudioMixer::TRACK, AudioMixer::MAIN_BUFFER, (void *) mixBuffer); // newly allocated track names default to full scale volume - if (fastTrack->mSampleRate != 0 && fastTrack->mSampleRate != sampleRate) { - mixer->setParameter(name, AudioMixer::RESAMPLE, - AudioMixer::SAMPLE_RATE, (void*) fastTrack->mSampleRate); - } mixer->setParameter(name, AudioMixer::TRACK, AudioMixer::CHANNEL_MASK, - (void *) fastTrack->mChannelMask); + (void *)(uintptr_t)fastTrack->mChannelMask); mixer->enable(name); } generations[i] = fastTrack->mGeneration; @@ -353,16 +348,10 @@ bool FastMixer::threadLoop() mixer->setParameter(name, AudioMixer::VOLUME, AudioMixer::VOLUME1, (void *)0x1000); } - if (fastTrack->mSampleRate != 0 && - fastTrack->mSampleRate != sampleRate) { - mixer->setParameter(name, AudioMixer::RESAMPLE, - AudioMixer::SAMPLE_RATE, (void*) fastTrack->mSampleRate); - } else { - mixer->setParameter(name, AudioMixer::RESAMPLE, - AudioMixer::REMOVE, NULL); - } + mixer->setParameter(name, AudioMixer::RESAMPLE, + AudioMixer::REMOVE, NULL); mixer->setParameter(name, AudioMixer::TRACK, AudioMixer::CHANNEL_MASK, - (void *) fastTrack->mChannelMask); + (void *)(uintptr_t) fastTrack->mChannelMask); // already enabled } generations[i] = fastTrack->mGeneration; @@ -392,16 +381,8 @@ bool FastMixer::threadLoop() // Refresh the per-track timestamp if (timestampStatus == NO_ERROR) { - uint32_t trackFramesWrittenButNotPresented; - uint32_t trackSampleRate = fastTrack->mSampleRate; - // There is currently no sample rate conversion for fast tracks currently - if (trackSampleRate != 0 && trackSampleRate != sampleRate) { - trackFramesWrittenButNotPresented = - ((int64_t) nativeFramesWrittenButNotPresented * trackSampleRate) / - sampleRate; - } else { - trackFramesWrittenButNotPresented = nativeFramesWrittenButNotPresented; - } + uint32_t trackFramesWrittenButNotPresented = + nativeFramesWrittenButNotPresented; uint32_t trackFramesWritten = fastTrack->mBufferProvider->framesReleased(); // Can't provide an AudioTimestamp before first frame presented, // or during the brief 32-bit wraparound window @@ -419,9 +400,9 @@ bool FastMixer::threadLoop() if (fastTrack->mVolumeProvider != NULL) { uint32_t vlr = fastTrack->mVolumeProvider->getVolumeLR(); mixer->setParameter(name, AudioMixer::VOLUME, AudioMixer::VOLUME0, - (void *)(vlr & 0xFFFF)); + (void *)(uintptr_t)(vlr & 0xFFFF)); mixer->setParameter(name, AudioMixer::VOLUME, AudioMixer::VOLUME1, - (void *)(vlr >> 16)); + (void *)(uintptr_t)(vlr >> 16)); } // FIXME The current implementation of framesReady() for fast tracks // takes a tryLock, which can block @@ -750,7 +731,7 @@ void FastMixerDumpState::dump(int fd) const double mixPeriodSec = (double) mFrameCount / (double) mSampleRate; fdprintf(fd, "FastMixer command=%s writeSequence=%u framesWritten=%u\n" " numTracks=%u writeErrors=%u underruns=%u overruns=%u\n" - " sampleRate=%u frameCount=%u measuredWarmup=%.3g ms, warmupCycles=%u\n" + " sampleRate=%u frameCount=%zu measuredWarmup=%.3g ms, warmupCycles=%u\n" " mixPeriod=%.2f ms\n", string, mWriteSequence, mFramesWritten, mNumTracks, mWriteErrors, mUnderruns, mOverruns, @@ -864,7 +845,7 @@ void FastMixerDumpState::dump(int fd) const mostRecent = "?"; break; } - fdprintf(fd, "%5u %6s %4u %7u %5u %7s %5u\n", i, isActive ? "yes" : "no", + fdprintf(fd, "%5u %6s %4u %7u %5u %7s %5zu\n", i, isActive ? "yes" : "no", (underruns.mBitFields.mFull) & UNDERRUN_MASK, (underruns.mBitFields.mPartial) & UNDERRUN_MASK, (underruns.mBitFields.mEmpty) & UNDERRUN_MASK, diff --git a/services/audioflinger/FastMixerState.cpp b/services/audioflinger/FastMixerState.cpp index 737de97..43ff233 100644 --- a/services/audioflinger/FastMixerState.cpp +++ b/services/audioflinger/FastMixerState.cpp @@ -20,7 +20,7 @@ namespace android { FastTrack::FastTrack() : - mBufferProvider(NULL), mVolumeProvider(NULL), mSampleRate(0), + mBufferProvider(NULL), mVolumeProvider(NULL), mChannelMask(AUDIO_CHANNEL_OUT_STEREO), mGeneration(0) { } diff --git a/services/audioflinger/FastMixerState.h b/services/audioflinger/FastMixerState.h index f6e7903..9739fe9 100644 --- a/services/audioflinger/FastMixerState.h +++ b/services/audioflinger/FastMixerState.h @@ -43,7 +43,6 @@ struct FastTrack { ExtendedAudioBufferProvider* mBufferProvider; // must be NULL if inactive, or non-NULL if active VolumeProvider* mVolumeProvider; // optional; if NULL then full-scale - unsigned mSampleRate; // optional; if zero then use mixer sample rate audio_channel_mask_t mChannelMask; // AUDIO_CHANNEL_OUT_MONO or AUDIO_CHANNEL_OUT_STEREO int mGeneration; // increment when any field is assigned }; diff --git a/services/audioflinger/PlaybackTracks.h b/services/audioflinger/PlaybackTracks.h index a2e2511..43b77f3 100644 --- a/services/audioflinger/PlaybackTracks.h +++ b/services/audioflinger/PlaybackTracks.h @@ -31,6 +31,7 @@ public: size_t frameCount, const sp<IMemory>& sharedBuffer, int sessionId, + int uid, IAudioFlinger::track_flags_t flags); virtual ~Track(); @@ -165,7 +166,8 @@ class TimedTrack : public Track { audio_channel_mask_t channelMask, size_t frameCount, const sp<IMemory>& sharedBuffer, - int sessionId); + int sessionId, + int uid); virtual ~TimedTrack(); class TimedBuffer { @@ -208,7 +210,8 @@ class TimedTrack : public Track { audio_channel_mask_t channelMask, size_t frameCount, const sp<IMemory>& sharedBuffer, - int sessionId); + int sessionId, + int uid); void timedYieldSamples_l(AudioBufferProvider::Buffer* buffer); void timedYieldSilence_l(uint32_t numFrames, @@ -255,7 +258,8 @@ public: uint32_t sampleRate, audio_format_t format, audio_channel_mask_t channelMask, - size_t frameCount); + size_t frameCount, + int uid); virtual ~OutputTrack(); virtual status_t start(AudioSystem::sync_event_t event = diff --git a/services/audioflinger/RecordTracks.h b/services/audioflinger/RecordTracks.h index cd8f70c..57de568 100644 --- a/services/audioflinger/RecordTracks.h +++ b/services/audioflinger/RecordTracks.h @@ -28,7 +28,8 @@ public: audio_format_t format, audio_channel_mask_t channelMask, size_t frameCount, - int sessionId); + int sessionId, + int uid); virtual ~RecordTrack(); virtual status_t start(AudioSystem::sync_event_t event, int triggerSession); diff --git a/services/audioflinger/StateQueue.cpp b/services/audioflinger/StateQueue.cpp index c2d3bbd..48399c0 100644 --- a/services/audioflinger/StateQueue.cpp +++ b/services/audioflinger/StateQueue.cpp @@ -58,7 +58,11 @@ template<typename T> StateQueue<T>::~StateQueue() template<typename T> const T* StateQueue<T>::poll() { +#ifdef __LP64__ + const T *next = (const T *) android_atomic_acquire_load64((volatile int64_t *) &mNext); +#else const T *next = (const T *) android_atomic_acquire_load((volatile int32_t *) &mNext); +#endif if (next != mCurrent) { mAck = next; // no additional barrier needed mCurrent = next; @@ -140,7 +144,11 @@ template<typename T> bool StateQueue<T>::push(StateQueue<T>::block_t block) } // publish +#ifdef __LP64__ + android_atomic_release_store64((int64_t) mMutating, (volatile int64_t *) &mNext); +#else android_atomic_release_store((int32_t) mMutating, (volatile int32_t *) &mNext); +#endif mExpecting = mMutating; // copy with circular wraparound diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp index 47dcca6..498ddb6 100644 --- a/services/audioflinger/Threads.cpp +++ b/services/audioflinger/Threads.cpp @@ -135,12 +135,12 @@ static const int kPriorityFastMixer = 3; // IAudioFlinger::createTrack() reports back to client the total size of shared memory area // for the track. The client then sub-divides this into smaller buffers for its use. -// Currently the client uses double-buffering by default, but doesn't tell us about that. -// So for now we just assume that client is double-buffered. -// FIXME It would be better for client to tell AudioFlinger whether it wants double-buffering or -// N-buffering, so AudioFlinger could allocate the right amount of memory. +// Currently the client uses N-buffering by default, but doesn't tell us about the value of N. +// So for now we just assume that client is double-buffered for fast tracks. +// FIXME It would be better for client to tell AudioFlinger the value of N, +// so AudioFlinger could allocate the right amount of memory. // See the client's minBufCount and mNotificationFramesAct calculations for details. -static const int kFastTrackMultiplier = 1; +static const int kFastTrackMultiplier = 2; // ---------------------------------------------------------------------------- @@ -272,6 +272,7 @@ AudioFlinger::ThreadBase::ThreadBase(const sp<AudioFlinger>& audioFlinger, audio // mSampleRate, mFrameCount, mChannelMask, mChannelCount, mFrameSize, and mFormat are // set by PlaybackThread::readOutputParameters() or RecordThread::readInputParameters() mParamStatus(NO_ERROR), + //FIXME: mStandby should be true here. Is this some kind of hack? mStandby(false), mOutDevice(outDevice), mInDevice(inDevice), mAudioSource(AUDIO_SOURCE_DEFAULT), mId(id), // mName will be set by concrete (non-virtual) subclass @@ -424,7 +425,7 @@ void AudioFlinger::ThreadBase::dumpBase(int fd, const Vector<String16>& args) result.append(buffer); snprintf(buffer, SIZE, "Sample rate: %u\n", mSampleRate); result.append(buffer); - snprintf(buffer, SIZE, "HAL frame count: %d\n", mFrameCount); + snprintf(buffer, SIZE, "HAL frame count: %zu\n", mFrameCount); result.append(buffer); snprintf(buffer, SIZE, "Channel Count: %u\n", mChannelCount); result.append(buffer); @@ -432,14 +433,14 @@ void AudioFlinger::ThreadBase::dumpBase(int fd, const Vector<String16>& args) result.append(buffer); snprintf(buffer, SIZE, "Format: %d\n", mFormat); result.append(buffer); - snprintf(buffer, SIZE, "Frame size: %u\n", mFrameSize); + snprintf(buffer, SIZE, "Frame size: %zu\n", mFrameSize); result.append(buffer); snprintf(buffer, SIZE, "\nPending setParameters commands: \n"); result.append(buffer); result.append(" Index Command"); for (size_t i = 0; i < mNewParameters.size(); ++i) { - snprintf(buffer, SIZE, "\n %02d ", i); + snprintf(buffer, SIZE, "\n %02zu ", i); result.append(buffer); result.append(mNewParameters[i]); } @@ -465,7 +466,7 @@ void AudioFlinger::ThreadBase::dumpEffectChains(int fd, const Vector<String16>& char buffer[SIZE]; String8 result; - snprintf(buffer, SIZE, "\n- %d Effect Chains:\n", mEffectChains.size()); + snprintf(buffer, SIZE, "\n- %zu Effect Chains:\n", mEffectChains.size()); write(fd, buffer, strlen(buffer)); for (size_t i = 0; i < mEffectChains.size(); ++i) { @@ -503,17 +504,7 @@ String16 AudioFlinger::ThreadBase::getWakeLockTag() void AudioFlinger::ThreadBase::acquireWakeLock_l(int uid) { - if (mPowerManager == 0) { - // use checkService() to avoid blocking if power service is not up yet - sp<IBinder> binder = - defaultServiceManager()->checkService(String16("power")); - if (binder == 0) { - ALOGW("Thread %s cannot connect to the power manager service", mName); - } else { - mPowerManager = interface_cast<IPowerManager>(binder); - binder->linkToDeath(mDeathRecipient); - } - } + getPowerManager_l(); if (mPowerManager != 0) { sp<IBinder> binder = new BBinder(); status_t status; @@ -553,6 +544,41 @@ void AudioFlinger::ThreadBase::releaseWakeLock_l() } } +void AudioFlinger::ThreadBase::updateWakeLockUids(const SortedVector<int> &uids) { + Mutex::Autolock _l(mLock); + updateWakeLockUids_l(uids); +} + +void AudioFlinger::ThreadBase::getPowerManager_l() { + + if (mPowerManager == 0) { + // use checkService() to avoid blocking if power service is not up yet + sp<IBinder> binder = + defaultServiceManager()->checkService(String16("power")); + if (binder == 0) { + ALOGW("Thread %s cannot connect to the power manager service", mName); + } else { + mPowerManager = interface_cast<IPowerManager>(binder); + binder->linkToDeath(mDeathRecipient); + } + } +} + +void AudioFlinger::ThreadBase::updateWakeLockUids_l(const SortedVector<int> &uids) { + + getPowerManager_l(); + if (mWakeLockToken == NULL) { + ALOGE("no wake lock to update!"); + return; + } + if (mPowerManager != 0) { + sp<IBinder> binder = new BBinder(); + status_t status; + status = mPowerManager->updateWakeLockUids(mWakeLockToken, uids.size(), uids.array()); + ALOGV("acquireWakeLock_l() %s status %d", mName, status); + } +} + void AudioFlinger::ThreadBase::clearPowerManager() { Mutex::Autolock _l(mLock); @@ -977,6 +1003,7 @@ AudioFlinger::PlaybackThread::PlaybackThread(const sp<AudioFlinger>& audioFlinge : ThreadBase(audioFlinger, id, device, AUDIO_DEVICE_NONE, type), mNormalFrameCount(0), mMixBuffer(NULL), mAllocMixBuffer(NULL), mSuspended(0), mBytesWritten(0), + mActiveTracksGeneration(0), // mStreamTypes[] initialized in constructor body mOutput(output), mLastWriteTime(0), mNumWrites(0), mNumDelayedWrites(0), mInWrite(false), @@ -1101,7 +1128,7 @@ void AudioFlinger::PlaybackThread::dumpInternals(int fd, const Vector<String16>& snprintf(buffer, SIZE, "\nOutput thread %p internals\n", this); result.append(buffer); - snprintf(buffer, SIZE, "Normal frame count: %d\n", mNormalFrameCount); + snprintf(buffer, SIZE, "Normal frame count: %zu\n", mNormalFrameCount); result.append(buffer); snprintf(buffer, SIZE, "last write occurred (msecs): %llu\n", ns2ms(systemTime() - mLastWriteTime)); @@ -1160,6 +1187,7 @@ sp<AudioFlinger::PlaybackThread::Track> AudioFlinger::PlaybackThread::createTrac int sessionId, IAudioFlinger::track_flags_t *flags, pid_t tid, + int uid, status_t *status) { sp<Track> track; @@ -1182,7 +1210,7 @@ sp<AudioFlinger::PlaybackThread::Track> AudioFlinger::PlaybackThread::createTrac ( (tid != -1) && ((frameCount == 0) || - (frameCount >= (mFrameCount * kFastTrackMultiplier))) + (frameCount >= mFrameCount)) ) ) && // PCM data @@ -1190,10 +1218,8 @@ sp<AudioFlinger::PlaybackThread::Track> AudioFlinger::PlaybackThread::createTrac // mono or stereo ( (channelMask == AUDIO_CHANNEL_OUT_MONO) || (channelMask == AUDIO_CHANNEL_OUT_STEREO) ) && -#ifndef FAST_TRACKS_AT_NON_NATIVE_SAMPLE_RATE // hardware sample rate (sampleRate == mSampleRate) && -#endif // normal mixer has an associated fast mixer hasFastMixer() && // there are sufficient fast track slots available @@ -1293,10 +1319,10 @@ sp<AudioFlinger::PlaybackThread::Track> AudioFlinger::PlaybackThread::createTrac if (!isTimed) { track = new Track(this, client, streamType, sampleRate, format, - channelMask, frameCount, sharedBuffer, sessionId, *flags); + channelMask, frameCount, sharedBuffer, sessionId, uid, *flags); } else { track = TimedTrack::create(this, client, streamType, sampleRate, format, - channelMask, frameCount, sharedBuffer, sessionId); + channelMask, frameCount, sharedBuffer, sessionId, uid); } if (track == 0 || track->getCblk() == NULL || track->name() < 0) { lStatus = NO_MEMORY; @@ -1432,6 +1458,9 @@ status_t AudioFlinger::PlaybackThread::addTrack_l(const sp<Track>& track) track->mResetDone = false; track->mPresentationCompleteFrames = 0; mActiveTracks.add(track); + mWakeLockUids.add(track->uid()); + mActiveTracksGeneration++; + mLatestActiveTrack = track; sp<EffectChain> chain = getEffectChain_l(track->sessionId()); if (chain != 0) { ALOGV("addTrack_l() starting track on chain %p for session %d", chain.get(), @@ -1687,7 +1716,7 @@ void AudioFlinger::PlaybackThread::readOutputParameters() } -status_t AudioFlinger::PlaybackThread::getRenderPosition(size_t *halFrames, size_t *dspFrames) +status_t AudioFlinger::PlaybackThread::getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames) { if (halFrames == NULL || dspFrames == NULL) { return BAD_VALUE; @@ -1705,7 +1734,11 @@ status_t AudioFlinger::PlaybackThread::getRenderPosition(size_t *halFrames, size *dspFrames = framesWritten >= latencyFrames ? framesWritten - latencyFrames : 0; return NO_ERROR; } else { - return mOutput->stream->get_render_position(mOutput->stream, dspFrames); + status_t status; + uint32_t frames; + status = mOutput->stream->get_render_position(mOutput->stream, &frames); + *dspFrames = (size_t)frames; + return status; } } @@ -1905,7 +1938,7 @@ ssize_t AudioFlinger::PlaybackThread::threadLoop_write() mNumWrites++; mInWrite = false; - + mStandby = false; return bytesWritten; } @@ -2127,6 +2160,8 @@ bool AudioFlinger::PlaybackThread::threadLoop() // FIXME could this be made local to while loop? writeFrames = 0; + int lastGeneration = 0; + cacheParameters_l(); sleepTime = idleSleepTime; @@ -2183,6 +2218,8 @@ bool AudioFlinger::PlaybackThread::threadLoop() break; } releaseWakeLock_l(); + mWakeLockUids.clear(); + mActiveTracksGeneration++; ALOGV("wait async completion"); mWaitWorkCV.wait(mLock); ALOGV("async completion/wake"); @@ -2213,6 +2250,8 @@ bool AudioFlinger::PlaybackThread::threadLoop() } releaseWakeLock_l(); + mWakeLockUids.clear(); + mActiveTracksGeneration++; // wait until we have something to do... ALOGV("%s going to sleep", myName.string()); mWaitWorkCV.wait(mLock); @@ -2237,11 +2276,18 @@ bool AudioFlinger::PlaybackThread::threadLoop() // mMixerStatusIgnoringFastTracks is also updated internally mMixerStatus = prepareTracks_l(&tracksToRemove); + // compare with previously applied list + if (lastGeneration != mActiveTracksGeneration) { + // update wakelock + updateWakeLockUids_l(mWakeLockUids); + lastGeneration = mActiveTracksGeneration; + } + // prevent any changes in effect chain list and in each effect chain // during mixing and effect process as the audio buffers could be deleted // or modified if an effect is created or deleted lockEffectChains_l(effectChains); - } + } // mLock scope ends if (mBytesRemaining == 0) { mCurrentWriteLength = 0; @@ -2315,7 +2361,6 @@ if (mType == MIXER) { } } - mStandby = false; } else { usleep(sleepTime); } @@ -2351,6 +2396,8 @@ if (mType == MIXER) { } releaseWakeLock(); + mWakeLockUids.clear(); + mActiveTracksGeneration++; ALOGV("Thread %p type %d exiting", this, mType); return false; @@ -2364,6 +2411,8 @@ void AudioFlinger::PlaybackThread::removeTracks_l(const Vector< sp<Track> >& tra for (size_t i=0 ; i<count ; i++) { const sp<Track>& track = tracksToRemove.itemAt(i); mActiveTracks.remove(track); + mWakeLockUids.remove(track->uid()); + mActiveTracksGeneration++; ALOGV("removeTracks_l removing track on session %d", track->sessionId()); sp<EffectChain> chain = getEffectChain_l(track->sessionId()); if (chain != 0) { @@ -2926,7 +2975,6 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTrac VolumeProvider *vp = track; fastTrack->mBufferProvider = eabp; fastTrack->mVolumeProvider = vp; - fastTrack->mSampleRate = track->mSampleRate; fastTrack->mChannelMask = track->mChannelMask; fastTrack->mGeneration++; state->mTrackMask |= 1 << j; @@ -2989,15 +3037,8 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTrac (mMixerStatusIgnoringFastTracks == MIXER_TRACKS_READY)) { minFrames = desiredFrames; } - // It's not safe to call framesReady() for a static buffer track, so assume it's ready - size_t framesReady; - if (track->sharedBuffer() == 0) { - framesReady = track->framesReady(); - } else if (track->isStopped()) { - framesReady = 0; - } else { - framesReady = 1; - } + + size_t framesReady = track->framesReady(); if ((framesReady >= minFrames) && track->isReady() && !track->isPaused() && !track->isTerminated()) { @@ -3110,9 +3151,9 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTrac mAudioMixer->setBufferProvider(name, track); mAudioMixer->enable(name); - mAudioMixer->setParameter(name, param, AudioMixer::VOLUME0, (void *)vl); - mAudioMixer->setParameter(name, param, AudioMixer::VOLUME1, (void *)vr); - mAudioMixer->setParameter(name, param, AudioMixer::AUXLEVEL, (void *)va); + mAudioMixer->setParameter(name, param, AudioMixer::VOLUME0, (void *)(uintptr_t)vl); + mAudioMixer->setParameter(name, param, AudioMixer::VOLUME1, (void *)(uintptr_t)vr); + mAudioMixer->setParameter(name, param, AudioMixer::AUXLEVEL, (void *)(uintptr_t)va); mAudioMixer->setParameter( name, AudioMixer::TRACK, @@ -3120,7 +3161,7 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTrac mAudioMixer->setParameter( name, AudioMixer::TRACK, - AudioMixer::CHANNEL_MASK, (void *)track->channelMask()); + AudioMixer::CHANNEL_MASK, (void *)(uintptr_t)track->channelMask()); // limit track sample rate to 2 x output sample rate, which changes at re-configuration uint32_t maxSampleRate = mSampleRate * 2; uint32_t reqSampleRate = track->mAudioTrackServerProxy->getSampleRate(); @@ -3133,7 +3174,7 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTrac name, AudioMixer::RESAMPLE, AudioMixer::SAMPLE_RATE, - (void *)reqSampleRate); + (void *)(uintptr_t)reqSampleRate); mAudioMixer->setParameter( name, AudioMixer::TRACK, @@ -3559,6 +3600,12 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prep Track* const track = t.get(); audio_track_cblk_t* cblk = track->cblk(); + // Only consider last track started for volume and mixer state control. + // In theory an older track could underrun and restart after the new one starts + // but as we only care about the transition phase between two tracks on a + // direct output, it is not a problem to ignore the underrun case. + sp<Track> l = mLatestActiveTrack.promote(); + bool last = l.get() == track; // The first time a track is added we wait // for all its buffers to be filled before processing it @@ -3568,11 +3615,6 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prep } else { minFrames = 1; } - // Only consider last track started for volume and mixer state control. - // This is the last entry in mActiveTracks unless a track underruns. - // As we only care about the transition phase between two tracks on a - // direct output, it is not a problem to ignore the underrun case. - bool last = (i == (count - 1)); if ((track->framesReady() >= minFrames) && track->isReady() && !track->isPaused() && !track->isTerminated()) @@ -3599,7 +3641,7 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prep } else { // clear effect chain input buffer if the last active track started underruns // to avoid sending previous audio buffer again to effects - if (!mEffectChains.isEmpty() && (i == (count -1))) { + if (!mEffectChains.isEmpty() && last) { mEffectChains[0]->clearInputBuffer(); } @@ -3611,7 +3653,8 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prep // TODO: implement behavior for compressed audio size_t audioHALFrames = (latency_l() * mSampleRate) / 1000; size_t framesWritten = mBytesWritten / mFrameSize; - if (mStandby || track->presentationComplete(framesWritten, audioHALFrames)) { + if (mStandby || !last || + track->presentationComplete(framesWritten, audioHALFrames)) { if (track->isStopped()) { track->reset(); } @@ -3624,6 +3667,9 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prep if (--(track->mRetryCount) <= 0) { ALOGV("BUFFER TIMEOUT: remove(%d) from active list", track->name()); tracksToRemove->add(track); + // indicate to client process that the track was disabled because of underrun; + // it will then automatically call start() when data is available + android_atomic_or(CBLK_DISABLED, &cblk->mFlags); } else if (last) { mixerStatus = MIXER_TRACKS_ENABLED; } @@ -3809,7 +3855,12 @@ bool AudioFlinger::AsyncCallbackThread::threadLoop() { Mutex::Autolock _l(mLock); - mWaitWorkCV.wait(mLock); + while (!((mWriteAckSequence & 1) || + (mDrainSequence & 1) || + exitPending())) { + mWaitWorkCV.wait(mLock); + } + if (exitPending()) { break; } @@ -3886,11 +3937,8 @@ AudioFlinger::OffloadThread::OffloadThread(const sp<AudioFlinger>& audioFlinger, mFlushPending(false), mPausedBytesRemaining(0) { -} - -AudioFlinger::OffloadThread::~OffloadThread() -{ - mPreviousTrack.clear(); + //FIXME: mStandby should be set to true by ThreadBase constructor + mStandby = true; } void AudioFlinger::OffloadThread::threadLoop_exit() @@ -3927,24 +3975,13 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::OffloadThread::prepareTr } Track* const track = t.get(); audio_track_cblk_t* cblk = track->cblk(); - if (mPreviousTrack != NULL) { - if (t != mPreviousTrack) { - // Flush any data still being written from last track - mBytesRemaining = 0; - if (mPausedBytesRemaining) { - // Last track was paused so we also need to flush saved - // mixbuffer state and invalidate track so that it will - // re-submit that unwritten data when it is next resumed - mPausedBytesRemaining = 0; - // Invalidate is a bit drastic - would be more efficient - // to have a flag to tell client that some of the - // previously written data was lost - mPreviousTrack->invalidate(); - } - } - } - mPreviousTrack = t; - bool last = (i == (count - 1)); + // Only consider last track started for volume and mixer state control. + // In theory an older track could underrun and restart after the new one starts + // but as we only care about the transition phase between two tracks on a + // direct output, it is not a problem to ignore the underrun case. + sp<Track> l = mLatestActiveTrack.promote(); + bool last = l.get() == track; + if (track->isPausing()) { track->setPaused(); if (last) { @@ -3992,6 +4029,31 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::OffloadThread::prepareTr } if (last) { + sp<Track> previousTrack = mPreviousTrack.promote(); + if (previousTrack != 0) { + if (track != previousTrack.get()) { + // Flush any data still being written from last track + mBytesRemaining = 0; + if (mPausedBytesRemaining) { + // Last track was paused so we also need to flush saved + // mixbuffer state and invalidate track so that it will + // re-submit that unwritten data when it is next resumed + mPausedBytesRemaining = 0; + // Invalidate is a bit drastic - would be more efficient + // to have a flag to tell client that some of the + // previously written data was lost + previousTrack->invalidate(); + } + // flush data already sent to the DSP if changing audio session as audio + // comes from a different source. Also invalidate previous track to force a + // seek when resuming. + if (previousTrack->sessionId() != track->sessionId()) { + previousTrack->invalidate(); + mFlushPending = true; + } + } + } + mPreviousTrack = track; // reset retry count track->mRetryCount = kMaxTrackRetriesOffload; mActiveTrack = t; @@ -4008,22 +4070,27 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::OffloadThread::prepareTr // has been written ALOGV("OffloadThread: underrun and STOPPING_1 -> draining, STOPPING_2"); track->mState = TrackBase::STOPPING_2; // so presentation completes after drain - if (last) { - sleepTime = 0; - standbyTime = systemTime() + standbyDelay; - mixerStatus = MIXER_DRAIN_TRACK; - mDrainSequence += 2; + // do not drain if no data was ever sent to HAL (mStandby == true) + if (last && !mStandby) { + // do not modify drain sequence if we are already draining. This happens + // when resuming from pause after drain. + if ((mDrainSequence & 1) == 0) { + sleepTime = 0; + standbyTime = systemTime() + standbyDelay; + mixerStatus = MIXER_DRAIN_TRACK; + mDrainSequence += 2; + } if (mHwPaused) { // It is possible to move from PAUSED to STOPPING_1 without // a resume so we must ensure hardware is running - mOutput->stream->resume(mOutput->stream); + doHwResume = true; mHwPaused = false; } } } } else if (track->isStopping_2()) { - // Drain has completed, signal presentation complete - if (!(mDrainSequence & 1) || !last) { + // Drain has completed or we are in standby, signal presentation complete + if (!(mDrainSequence & 1) || !last || mStandby) { track->mState = TrackBase::STOPPED; size_t audioHALFrames = (mOutput->stream->get_latency(mOutput->stream)*mSampleRate) / 1000; @@ -4040,6 +4107,9 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::OffloadThread::prepareTr ALOGV("OffloadThread: BUFFER TIMEOUT: remove(%d) from active list", track->name()); tracksToRemove->add(track); + // indicate to client process that the track was disabled because of underrun; + // it will then automatically call start() when data is available + android_atomic_or(CBLK_DISABLED, &cblk->mFlags); } else if (last){ mixerStatus = MIXER_TRACKS_ENABLED; } @@ -4053,7 +4123,7 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::OffloadThread::prepareTr // If a flush is pending and a track is active but the HW is not paused, force a HW pause // before flush and then resume HW. This can happen in case of pause/flush/resume // if resume is received before pause is executed. - if (doHwPause || (mFlushPending && !mHwPaused && (count != 0))) { + if (!mStandby && (doHwPause || (mFlushPending && !mHwPaused && (count != 0)))) { mOutput->stream->pause(mOutput->stream); if (!doHwPause) { doHwResume = true; @@ -4063,7 +4133,7 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::OffloadThread::prepareTr flushHw_l(); mFlushPending = false; } - if (doHwResume) { + if (!mStandby && doHwResume) { mOutput->stream->resume(mOutput->stream); } @@ -4185,6 +4255,7 @@ ssize_t AudioFlinger::DuplicatingThread::threadLoop_write() for (size_t i = 0; i < outputTracks.size(); i++) { outputTracks[i]->write(mMixBuffer, writeFrames); } + mStandby = false; return (ssize_t)mixBufferSize; } @@ -4216,7 +4287,8 @@ void AudioFlinger::DuplicatingThread::addOutputTrack(MixerThread *thread) mSampleRate, mFormat, mChannelMask, - frameCount); + frameCount, + IPCThreadState::self()->getCallingUid()); if (outputTrack->cblk() != NULL) { thread->setStreamVolume(AUDIO_STREAM_CNT, 1.0f); mOutputTracks.add(outputTrack); @@ -4318,7 +4390,6 @@ AudioFlinger::RecordThread::RecordThread(const sp<AudioFlinger>& audioFlinger, snprintf(mName, kNameLength, "AudioIn_%X", id); readInputParameters(); - mClientUid = IPCThreadState::self()->getCallingUid(); } @@ -4350,7 +4421,11 @@ bool AudioFlinger::RecordThread::threadLoop() nsecs_t lastWarning = 0; inputStandBy(); - acquireWakeLock(mClientUid); + { + Mutex::Autolock _l(mLock); + activeTrack = mActiveTrack; + acquireWakeLock_l(activeTrack != 0 ? activeTrack->uid() : -1); + } // used to verify we've read at least once before evaluating how many bytes were read bool readOnce = false; @@ -4363,6 +4438,12 @@ bool AudioFlinger::RecordThread::threadLoop() { // scope for mLock Mutex::Autolock _l(mLock); checkForNewParameters_l(); + if (mActiveTrack != 0 && activeTrack != mActiveTrack) { + SortedVector<int> tmp; + tmp.add(mActiveTrack->uid()); + updateWakeLockUids_l(tmp); + } + activeTrack = mActiveTrack; if (mActiveTrack == 0 && mConfigEvents.isEmpty()) { standby(); @@ -4375,7 +4456,7 @@ bool AudioFlinger::RecordThread::threadLoop() // go to sleep mWaitWorkCV.wait(mLock); ALOGV("RecordThread: loop starting"); - acquireWakeLock_l(mClientUid); + acquireWakeLock_l(mActiveTrack != 0 ? mActiveTrack->uid() : -1); continue; } if (mActiveTrack != 0) { @@ -4585,6 +4666,7 @@ sp<AudioFlinger::RecordThread::RecordTrack> AudioFlinger::RecordThread::createR audio_channel_mask_t channelMask, size_t frameCount, int sessionId, + int uid, IAudioFlinger::track_flags_t *flags, pid_t tid, status_t *status) @@ -4604,7 +4686,7 @@ sp<AudioFlinger::RecordThread::RecordTrack> AudioFlinger::RecordThread::createR ( (tid != -1) && ((frameCount == 0) || - (frameCount >= (mFrameCount * kFastTrackMultiplier))) + (frameCount >= mFrameCount)) ) && // FIXME when record supports non-PCM data, also check for audio_is_linear_pcm(format) // mono or stereo @@ -4654,7 +4736,7 @@ sp<AudioFlinger::RecordThread::RecordTrack> AudioFlinger::RecordThread::createR Mutex::Autolock _l(mLock); track = new RecordTrack(this, client, sampleRate, - format, channelMask, frameCount, sessionId); + format, channelMask, frameCount, sessionId, uid); if (track->getCblk() == 0) { ALOGE("createRecordTrack_l() no control block"); @@ -4876,9 +4958,9 @@ void AudioFlinger::RecordThread::dumpInternals(int fd, const Vector<String16>& a result.append(buffer); if (mActiveTrack != 0) { - snprintf(buffer, SIZE, "In index: %d\n", mRsmpInIndex); + snprintf(buffer, SIZE, "In index: %zu\n", mRsmpInIndex); result.append(buffer); - snprintf(buffer, SIZE, "Buffer size: %u bytes\n", mBufferSize); + snprintf(buffer, SIZE, "Buffer size: %zu bytes\n", mBufferSize); result.append(buffer); snprintf(buffer, SIZE, "Resampling: %d\n", (mResampler != NULL)); result.append(buffer); diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h index 802b784..a2fb874 100644 --- a/services/audioflinger/Threads.h +++ b/services/audioflinger/Threads.h @@ -241,6 +241,9 @@ protected: void acquireWakeLock_l(int uid = -1); void releaseWakeLock(); void releaseWakeLock_l(); + void updateWakeLockUids(const SortedVector<int> &uids); + void updateWakeLockUids_l(const SortedVector<int> &uids); + void getPowerManager_l(); void setEffectSuspended_l(const effect_uuid_t *type, bool suspend, int sessionId); @@ -421,6 +424,7 @@ public: int sessionId, IAudioFlinger::track_flags_t *flags, pid_t tid, + int uid, status_t *status); AudioStreamOut* getOutput() const; @@ -442,7 +446,7 @@ public: virtual String8 getParameters(const String8& keys); virtual void audioConfigChanged_l(int event, int param = 0); - status_t getRenderPosition(size_t *halFrames, size_t *dspFrames); + status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames); int16_t *mixBuffer() const { return mMixBuffer; }; virtual void detachAuxEffect_l(int effectId); @@ -495,6 +499,9 @@ private: void setMasterMute_l(bool muted) { mMasterMute = muted; } protected: SortedVector< wp<Track> > mActiveTracks; // FIXME check if this could be sp<> + SortedVector<int> mWakeLockUids; + int mActiveTracksGeneration; + wp<Track> mLatestActiveTrack; // latest track added to mActiveTracks // Allocate a track name for a given channel mask. // Returns name >= 0 if successful, -1 on failure. @@ -735,7 +742,7 @@ public: OffloadThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, audio_io_handle_t id, uint32_t device); - virtual ~OffloadThread(); + virtual ~OffloadThread() {}; protected: // threadLoop snippets @@ -755,7 +762,7 @@ private: bool mFlushPending; size_t mPausedWriteLength; // length in bytes of write interrupted by pause size_t mPausedBytesRemaining; // bytes still waiting in mixbuffer after resume - sp<Track> mPreviousTrack; // used to detect track switch + wp<Track> mPreviousTrack; // used to detect track switch }; class AsyncCallbackThread : public Thread { @@ -873,6 +880,7 @@ public: audio_channel_mask_t channelMask, size_t frameCount, int sessionId, + int uid, IAudioFlinger::track_flags_t *flags, pid_t tid, status_t *status); @@ -953,5 +961,4 @@ private: // For dumpsys const sp<NBAIO_Sink> mTeeSink; - int mClientUid; }; diff --git a/services/audioflinger/TrackBase.h b/services/audioflinger/TrackBase.h index 523e4b2..cd201d9 100644 --- a/services/audioflinger/TrackBase.h +++ b/services/audioflinger/TrackBase.h @@ -45,6 +45,7 @@ public: size_t frameCount, const sp<IMemory>& sharedBuffer, int sessionId, + int uid, bool isOut); virtual ~TrackBase(); @@ -54,6 +55,7 @@ public: sp<IMemory> getCblk() const { return mCblkMemory; } audio_track_cblk_t* cblk() const { return mCblk; } int sessionId() const { return mSessionId; } + int uid() const { return mUid; } virtual status_t setSyncEvent(const sp<SyncEvent>& event); protected: @@ -132,6 +134,7 @@ protected: // openRecord(), and then adjusted as needed const int mSessionId; + int mUid; Vector < sp<SyncEvent> >mSyncEvents; const bool mIsOut; ServerProxy* mServerProxy; diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp index 9c6e724..fccc7b8 100644 --- a/services/audioflinger/Tracks.cpp +++ b/services/audioflinger/Tracks.cpp @@ -68,6 +68,7 @@ AudioFlinger::ThreadBase::TrackBase::TrackBase( size_t frameCount, const sp<IMemory>& sharedBuffer, int sessionId, + int clientUid, bool isOut) : RefBase(), mThread(thread), @@ -88,6 +89,18 @@ AudioFlinger::ThreadBase::TrackBase::TrackBase( mId(android_atomic_inc(&nextTrackId)), mTerminated(false) { + // if the caller is us, trust the specified uid + if (IPCThreadState::self()->getCallingPid() != getpid_cached || clientUid == -1) { + int newclientUid = IPCThreadState::self()->getCallingUid(); + if (clientUid != -1 && clientUid != newclientUid) { + ALOGW("uid %d tried to pass itself off as %d", newclientUid, clientUid); + } + clientUid = newclientUid; + } + // clientUid contains the uid of the app that is responsible for this track, so we can blame + // battery usage on it. + mUid = clientUid; + // client == 0 implies sharedBuffer == 0 ALOG_ASSERT(!(client == 0 && sharedBuffer != 0)); @@ -313,9 +326,10 @@ AudioFlinger::PlaybackThread::Track::Track( size_t frameCount, const sp<IMemory>& sharedBuffer, int sessionId, + int uid, IAudioFlinger::track_flags_t flags) : TrackBase(thread, client, sampleRate, format, channelMask, frameCount, sharedBuffer, - sessionId, true /*isOut*/), + sessionId, uid, true /*isOut*/), mFillingUpStatus(FS_INVALID), // mRetryCount initialized later when needed mSharedBuffer(sharedBuffer), @@ -473,8 +487,8 @@ void AudioFlinger::PlaybackThread::Track::dump(char* buffer, size_t size) nowInUnderrun = '?'; break; } - snprintf(&buffer[7], size-7, " %6u %4u %08X %08X %7u %6u %1c %1d %5u %5.2g %5.2g " - "%08X %08X %08X 0x%03X %9u%c\n", + snprintf(&buffer[7], size-7, " %6u %4u %08X %08X %7u %6zu %1c %1d %5u %5.2g %5.2g " + "%08X %p %p 0x%03X %9u%c\n", (mClient == 0) ? getpid_cached : mClient->pid(), mStreamType, mFormat, @@ -487,8 +501,8 @@ void AudioFlinger::PlaybackThread::Track::dump(char* buffer, size_t size) 20.0 * log10((vlr & 0xFFFF) / 4096.0), 20.0 * log10((vlr >> 16) / 4096.0), mCblk->mServer, - (int)mMainBuffer, - (int)mAuxBuffer, + mMainBuffer, + mAuxBuffer, mCblk->mFlags, mAudioTrackServerProxy->getUnderrunFrames(), nowInUnderrun); @@ -600,6 +614,15 @@ status_t AudioFlinger::PlaybackThread::Track::start(AudioSystem::sync_event_t ev // track was already in the active list, not a problem if (status == ALREADY_EXISTS) { status = NO_ERROR; + } else { + // Acknowledge any pending flush(), so that subsequent new data isn't discarded. + // It is usually unsafe to access the server proxy from a binder thread. + // But in this case we know the mixer thread (whether normal mixer or fast mixer) + // isn't looking at this track yet: we still hold the normal mixer thread lock, + // and for fast tracks the track is not yet in the fast mixer thread's active set. + ServerProxy::Buffer buffer; + buffer.mFrameCount = 1; + (void) mAudioTrackServerProxy->obtainBuffer(&buffer, true /*ackFlush*/); } } else { status = BAD_VALUE; @@ -829,6 +852,7 @@ status_t AudioFlinger::PlaybackThread::Track::attachAuxEffect(int EffectId) dstChain->strategy(), AUDIO_SESSION_OUTPUT_MIX, effect->id()); + AudioSystem::setEffectEnabled(effect->id(), effect->isEnabled()); } status = playbackThread->attachAuxEffect(this, EffectId); } @@ -954,13 +978,14 @@ AudioFlinger::PlaybackThread::TimedTrack::create( audio_channel_mask_t channelMask, size_t frameCount, const sp<IMemory>& sharedBuffer, - int sessionId) { + int sessionId, + int uid) { if (!client->reserveTimedTrack()) return 0; return new TimedTrack( thread, client, streamType, sampleRate, format, channelMask, frameCount, - sharedBuffer, sessionId); + sharedBuffer, sessionId, uid); } AudioFlinger::PlaybackThread::TimedTrack::TimedTrack( @@ -972,9 +997,10 @@ AudioFlinger::PlaybackThread::TimedTrack::TimedTrack( audio_channel_mask_t channelMask, size_t frameCount, const sp<IMemory>& sharedBuffer, - int sessionId) + int sessionId, + int uid) : Track(thread, client, streamType, sampleRate, format, channelMask, - frameCount, sharedBuffer, sessionId, IAudioFlinger::TRACK_TIMED), + frameCount, sharedBuffer, sessionId, uid, IAudioFlinger::TRACK_TIMED), mQueueHeadInFlight(false), mTrimQueueHeadOnRelease(false), mFramesPendingInQueue(0), @@ -1467,9 +1493,10 @@ AudioFlinger::PlaybackThread::OutputTrack::OutputTrack( uint32_t sampleRate, audio_format_t format, audio_channel_mask_t channelMask, - size_t frameCount) + size_t frameCount, + int uid) : Track(playbackThread, NULL, AUDIO_STREAM_CNT, sampleRate, format, channelMask, frameCount, - NULL, 0, IAudioFlinger::TRACK_DEFAULT), + NULL, 0, uid, IAudioFlinger::TRACK_DEFAULT), mActive(false), mSourceThread(sourceThread), mClientProxy(NULL) { @@ -1729,9 +1756,10 @@ AudioFlinger::RecordThread::RecordTrack::RecordTrack( audio_format_t format, audio_channel_mask_t channelMask, size_t frameCount, - int sessionId) + int sessionId, + int uid) : TrackBase(thread, client, sampleRate, format, - channelMask, frameCount, 0 /*sharedBuffer*/, sessionId, false /*isOut*/), + channelMask, frameCount, 0 /*sharedBuffer*/, sessionId, uid, false /*isOut*/), mOverflow(false) { ALOGV("RecordTrack constructor"); @@ -1822,7 +1850,7 @@ void AudioFlinger::RecordThread::RecordTrack::invalidate() void AudioFlinger::RecordThread::RecordTrack::dump(char* buffer, size_t size) { - snprintf(buffer, size, "%6u %3u %08X %7u %1d %08X %6u\n", + snprintf(buffer, size, "%6u %3u %08X %7u %1d %08X %6zu\n", (mClient == 0) ? getpid_cached : mClient->pid(), mFormat, mChannelMask, diff --git a/services/camera/libcameraservice/Android.mk b/services/camera/libcameraservice/Android.mk index d23f8b9..51ba698 100644 --- a/services/camera/libcameraservice/Android.mk +++ b/services/camera/libcameraservice/Android.mk @@ -35,6 +35,7 @@ LOCAL_SRC_FILES:= \ device3/Camera3ZslStream.cpp \ device3/StatusTracker.cpp \ gui/RingBufferConsumer.cpp \ + utils/CameraTraces.cpp \ LOCAL_SHARED_LIBRARIES:= \ libui \ diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp index 34a5b15..87027f7 100644 --- a/services/camera/libcameraservice/CameraService.cpp +++ b/services/camera/libcameraservice/CameraService.cpp @@ -42,6 +42,7 @@ #include "api1/Camera2Client.h" #include "api_pro/ProCamera2Client.h" #include "api2/CameraDeviceClient.h" +#include "utils/CameraTraces.h" #include "CameraDeviceFactory.h" namespace android { @@ -1041,13 +1042,13 @@ void CameraService::BasicClient::opChanged(int32_t op, const String16& packageNa // ---------------------------------------------------------------------------- Mutex* CameraService::Client::getClientLockFromCookie(void* user) { - return gCameraService->getClientLockById((int) user); + return gCameraService->getClientLockById((int)(intptr_t) user); } // Provide client pointer for callbacks. Client lock returned from getClientLockFromCookie should // be acquired for this to be safe CameraService::Client* CameraService::Client::getClientFromCookie(void* user) { - BasicClient *basicClient = gCameraService->getClientByIdUnsafe((int) user); + BasicClient *basicClient = gCameraService->getClientByIdUnsafe((int)(intptr_t) user); // OK: only CameraClient calls this, and they already cast anyway. Client* client = static_cast<Client*>(basicClient); @@ -1219,6 +1220,10 @@ status_t CameraService::dump(int fd, const Vector<String16>& args) { if (locked) mServiceLock.unlock(); + // Dump camera traces if there were any + write(fd, "\n", 1); + camera3::CameraTraces::dump(fd, args); + // change logging level int n = args.size(); for (int i = 0; i + 1 < n; i++) { diff --git a/services/camera/libcameraservice/api1/Camera2Client.cpp b/services/camera/libcameraservice/api1/Camera2Client.cpp index df3b162..ba1e772 100644 --- a/services/camera/libcameraservice/api1/Camera2Client.cpp +++ b/services/camera/libcameraservice/api1/Camera2Client.cpp @@ -18,6 +18,7 @@ #define ATRACE_TAG ATRACE_TAG_CAMERA //#define LOG_NDEBUG 0 +#include <inttypes.h> #include <utils/Log.h> #include <utils/Trace.h> @@ -76,13 +77,15 @@ status_t Camera2Client::initialize(camera_module_t *module) return res; } - SharedParameters::Lock l(mParameters); + { + SharedParameters::Lock l(mParameters); - res = l.mParameters.initialize(&(mDevice->info())); - if (res != OK) { - ALOGE("%s: Camera %d: unable to build defaults: %s (%d)", - __FUNCTION__, mCameraId, strerror(-res), res); - return NO_INIT; + res = l.mParameters.initialize(&(mDevice->info())); + if (res != OK) { + ALOGE("%s: Camera %d: unable to build defaults: %s (%d)", + __FUNCTION__, mCameraId, strerror(-res), res); + return NO_INIT; + } } String8 threadName; @@ -135,6 +138,7 @@ status_t Camera2Client::initialize(camera_module_t *module) mCallbackProcessor->run(threadName.string()); if (gLogLevel >= 1) { + SharedParameters::Lock l(mParameters); ALOGD("%s: Default parameters converted from camera %d:", __FUNCTION__, mCameraId); ALOGD("%s", l.mParameters.paramsFlattened.string()); @@ -190,7 +194,7 @@ status_t Camera2Client::dump(int fd, const Vector<String16>& args) { result.appendFormat(" GPS lat x long x alt: %f x %f x %f\n", p.gpsCoordinates[0], p.gpsCoordinates[1], p.gpsCoordinates[2]); - result.appendFormat(" GPS timestamp: %lld\n", + result.appendFormat(" GPS timestamp: %" PRId64 "\n", p.gpsTimestamp); result.appendFormat(" GPS processing method: %s\n", p.gpsProcessingMethod.string()); @@ -353,6 +357,10 @@ status_t Camera2Client::dump(int fd, const Vector<String16>& args) { result.appendFormat(" meteringCropRegion\n"); haveQuirk = true; } + if (p.quirks.partialResults) { + result.appendFormat(" usePartialResult\n"); + haveQuirk = true; + } if (!haveQuirk) { result.appendFormat(" none\n"); } diff --git a/services/camera/libcameraservice/api1/CameraClient.cpp b/services/camera/libcameraservice/api1/CameraClient.cpp index bd6805d..30b7bb8 100644 --- a/services/camera/libcameraservice/api1/CameraClient.cpp +++ b/services/camera/libcameraservice/api1/CameraClient.cpp @@ -85,7 +85,7 @@ status_t CameraClient::initialize(camera_module_t *module) { mHardware->setCallbacks(notifyCallback, dataCallback, dataCallbackTimestamp, - (void *)mCameraId); + (void *)(uintptr_t)mCameraId); // Enable zoom, error, focus, and metadata messages by default enableMsgType(CAMERA_MSG_ERROR | CAMERA_MSG_ZOOM | CAMERA_MSG_FOCUS | diff --git a/services/camera/libcameraservice/api1/client2/FrameProcessor.cpp b/services/camera/libcameraservice/api1/client2/FrameProcessor.cpp index c34cb12..19acae4 100644 --- a/services/camera/libcameraservice/api1/client2/FrameProcessor.cpp +++ b/services/camera/libcameraservice/api1/client2/FrameProcessor.cpp @@ -29,13 +29,27 @@ namespace android { namespace camera2 { FrameProcessor::FrameProcessor(wp<CameraDeviceBase> device, - wp<Camera2Client> client) : + sp<Camera2Client> client) : FrameProcessorBase(device), mClient(client), - mLastFrameNumberOfFaces(0) { + mLastFrameNumberOfFaces(0), + mLast3AFrameNumber(-1) { sp<CameraDeviceBase> d = device.promote(); mSynthesize3ANotify = !(d->willNotify3A()); + + { + SharedParameters::Lock l(client->getParameters()); + mUsePartialQuirk = l.mParameters.quirks.partialResults; + + // Initialize starting 3A state + m3aState.afTriggerId = l.mParameters.afTriggerCounter; + m3aState.aeTriggerId = l.mParameters.precaptureTriggerCounter; + // Check if lens is fixed-focus + if (l.mParameters.focusMode == Parameters::FOCUS_MODE_FIXED) { + m3aState.afMode = ANDROID_CONTROL_AF_MODE_OFF; + } + } } FrameProcessor::~FrameProcessor() { @@ -49,20 +63,25 @@ bool FrameProcessor::processSingleFrame(CameraMetadata &frame, return false; } - if (processFaceDetect(frame, client) != OK) { + bool partialResult = false; + if (mUsePartialQuirk) { + camera_metadata_entry_t entry; + entry = frame.find(ANDROID_QUIRKS_PARTIAL_RESULT); + if (entry.count > 0 && + entry.data.u8[0] == ANDROID_QUIRKS_PARTIAL_RESULT_PARTIAL) { + partialResult = true; + } + } + + if (!partialResult && processFaceDetect(frame, client) != OK) { return false; } if (mSynthesize3ANotify) { - // Ignoring missing fields for now process3aState(frame, client); } - if (!FrameProcessorBase::processSingleFrame(frame, device)) { - return false; - } - - return true; + return FrameProcessorBase::processSingleFrame(frame, device); } status_t FrameProcessor::processFaceDetect(const CameraMetadata &frame, @@ -198,86 +217,75 @@ status_t FrameProcessor::process3aState(const CameraMetadata &frame, ATRACE_CALL(); camera_metadata_ro_entry_t entry; - int mId = client->getCameraId(); + int cameraId = client->getCameraId(); entry = frame.find(ANDROID_REQUEST_FRAME_COUNT); int32_t frameNumber = entry.data.i32[0]; + // Don't send 3A notifications for the same frame number twice + if (frameNumber <= mLast3AFrameNumber) { + ALOGV("%s: Already sent 3A for frame number %d, skipping", + __FUNCTION__, frameNumber); + return OK; + } + + mLast3AFrameNumber = frameNumber; + // Get 3A states from result metadata bool gotAllStates = true; AlgState new3aState; - entry = frame.find(ANDROID_CONTROL_AE_STATE); - if (entry.count == 0) { - ALOGE("%s: Camera %d: No AE state provided by HAL for frame %d!", - __FUNCTION__, mId, frameNumber); - gotAllStates = false; - } else { - new3aState.aeState = - static_cast<camera_metadata_enum_android_control_ae_state>( - entry.data.u8[0]); - } + // TODO: Also use AE mode, AE trigger ID - entry = frame.find(ANDROID_CONTROL_AF_STATE); - if (entry.count == 0) { - ALOGE("%s: Camera %d: No AF state provided by HAL for frame %d!", - __FUNCTION__, mId, frameNumber); - gotAllStates = false; - } else { - new3aState.afState = - static_cast<camera_metadata_enum_android_control_af_state>( - entry.data.u8[0]); - } + gotAllStates &= get3aResult<uint8_t>(frame, ANDROID_CONTROL_AF_MODE, + &new3aState.afMode, frameNumber, cameraId); - entry = frame.find(ANDROID_CONTROL_AWB_STATE); - if (entry.count == 0) { - ALOGE("%s: Camera %d: No AWB state provided by HAL for frame %d!", - __FUNCTION__, mId, frameNumber); - gotAllStates = false; - } else { - new3aState.awbState = - static_cast<camera_metadata_enum_android_control_awb_state>( - entry.data.u8[0]); - } + gotAllStates &= get3aResult<uint8_t>(frame, ANDROID_CONTROL_AWB_MODE, + &new3aState.awbMode, frameNumber, cameraId); - int32_t afTriggerId = 0; - entry = frame.find(ANDROID_CONTROL_AF_TRIGGER_ID); - if (entry.count == 0) { - ALOGE("%s: Camera %d: No AF trigger ID provided by HAL for frame %d!", - __FUNCTION__, mId, frameNumber); - gotAllStates = false; - } else { - afTriggerId = entry.data.i32[0]; - } + gotAllStates &= get3aResult<uint8_t>(frame, ANDROID_CONTROL_AE_STATE, + &new3aState.aeState, frameNumber, cameraId); - int32_t aeTriggerId = 0; - entry = frame.find(ANDROID_CONTROL_AE_PRECAPTURE_ID); - if (entry.count == 0) { - ALOGE("%s: Camera %d: No AE precapture trigger ID provided by HAL" - " for frame %d!", - __FUNCTION__, mId, frameNumber); - gotAllStates = false; - } else { - aeTriggerId = entry.data.i32[0]; - } + gotAllStates &= get3aResult<uint8_t>(frame, ANDROID_CONTROL_AF_STATE, + &new3aState.afState, frameNumber, cameraId); + + gotAllStates &= get3aResult<uint8_t>(frame, ANDROID_CONTROL_AWB_STATE, + &new3aState.awbState, frameNumber, cameraId); + + gotAllStates &= get3aResult<int32_t>(frame, ANDROID_CONTROL_AF_TRIGGER_ID, + &new3aState.afTriggerId, frameNumber, cameraId); + + gotAllStates &= get3aResult<int32_t>(frame, ANDROID_CONTROL_AE_PRECAPTURE_ID, + &new3aState.aeTriggerId, frameNumber, cameraId); if (!gotAllStates) return BAD_VALUE; if (new3aState.aeState != m3aState.aeState) { - ALOGV("%s: AE state changed from 0x%x to 0x%x", - __FUNCTION__, m3aState.aeState, new3aState.aeState); - client->notifyAutoExposure(new3aState.aeState, aeTriggerId); + ALOGV("%s: Camera %d: AE state %d->%d", + __FUNCTION__, cameraId, + m3aState.aeState, new3aState.aeState); + client->notifyAutoExposure(new3aState.aeState, new3aState.aeTriggerId); } - if (new3aState.afState != m3aState.afState) { - ALOGV("%s: AF state changed from 0x%x to 0x%x", - __FUNCTION__, m3aState.afState, new3aState.afState); - client->notifyAutoFocus(new3aState.afState, afTriggerId); + + if (new3aState.afState != m3aState.afState || + new3aState.afMode != m3aState.afMode || + new3aState.afTriggerId != m3aState.afTriggerId) { + ALOGV("%s: Camera %d: AF state %d->%d. AF mode %d->%d. Trigger %d->%d", + __FUNCTION__, cameraId, + m3aState.afState, new3aState.afState, + m3aState.afMode, new3aState.afMode, + m3aState.afTriggerId, new3aState.afTriggerId); + client->notifyAutoFocus(new3aState.afState, new3aState.afTriggerId); } - if (new3aState.awbState != m3aState.awbState) { - ALOGV("%s: AWB state changed from 0x%x to 0x%x", - __FUNCTION__, m3aState.awbState, new3aState.awbState); - client->notifyAutoWhitebalance(new3aState.awbState, aeTriggerId); + if (new3aState.awbState != m3aState.awbState || + new3aState.awbMode != m3aState.awbMode) { + ALOGV("%s: Camera %d: AWB state %d->%d. AWB mode %d->%d", + __FUNCTION__, cameraId, + m3aState.awbState, new3aState.awbState, + m3aState.awbMode, new3aState.awbMode); + client->notifyAutoWhitebalance(new3aState.awbState, + new3aState.aeTriggerId); } m3aState = new3aState; @@ -285,6 +293,39 @@ status_t FrameProcessor::process3aState(const CameraMetadata &frame, return OK; } +template<typename Src, typename T> +bool FrameProcessor::get3aResult(const CameraMetadata& result, int32_t tag, + T* value, int32_t frameNumber, int cameraId) { + camera_metadata_ro_entry_t entry; + if (value == NULL) { + ALOGE("%s: Camera %d: Value to write to is NULL", + __FUNCTION__, cameraId); + return false; + } + + entry = result.find(tag); + if (entry.count == 0) { + ALOGE("%s: Camera %d: No %s provided by HAL for frame %d!", + __FUNCTION__, cameraId, + get_camera_metadata_tag_name(tag), frameNumber); + return false; + } else { + switch(sizeof(Src)){ + case sizeof(uint8_t): + *value = static_cast<T>(entry.data.u8[0]); + break; + case sizeof(int32_t): + *value = static_cast<T>(entry.data.i32[0]); + break; + default: + ALOGE("%s: Camera %d: Unsupported source", + __FUNCTION__, cameraId); + return false; + } + } + return true; +} + void FrameProcessor::callbackFaceDetection(sp<Camera2Client> client, const camera_frame_metadata &metadata) { diff --git a/services/camera/libcameraservice/api1/client2/FrameProcessor.h b/services/camera/libcameraservice/api1/client2/FrameProcessor.h index 2a17d45..856ad32 100644 --- a/services/camera/libcameraservice/api1/client2/FrameProcessor.h +++ b/services/camera/libcameraservice/api1/client2/FrameProcessor.h @@ -39,7 +39,7 @@ namespace camera2 { */ class FrameProcessor : public FrameProcessorBase { public: - FrameProcessor(wp<CameraDeviceBase> device, wp<Camera2Client> client); + FrameProcessor(wp<CameraDeviceBase> device, sp<Camera2Client> client); ~FrameProcessor(); private: @@ -61,18 +61,44 @@ class FrameProcessor : public FrameProcessorBase { status_t process3aState(const CameraMetadata &frame, const sp<Camera2Client> &client); + // Helper for process3aState + template<typename Src, typename T> + bool get3aResult(const CameraMetadata& result, int32_t tag, T* value, + int32_t frameNumber, int cameraId); + + struct AlgState { + // TODO: also track AE mode + camera_metadata_enum_android_control_af_mode afMode; + camera_metadata_enum_android_control_awb_mode awbMode; + camera_metadata_enum_android_control_ae_state aeState; camera_metadata_enum_android_control_af_state afState; camera_metadata_enum_android_control_awb_state awbState; + int32_t afTriggerId; + int32_t aeTriggerId; + + // These defaults need to match those in Parameters.cpp AlgState() : + afMode(ANDROID_CONTROL_AF_MODE_AUTO), + awbMode(ANDROID_CONTROL_AWB_MODE_AUTO), aeState(ANDROID_CONTROL_AE_STATE_INACTIVE), afState(ANDROID_CONTROL_AF_STATE_INACTIVE), - awbState(ANDROID_CONTROL_AWB_STATE_INACTIVE) { + awbState(ANDROID_CONTROL_AWB_STATE_INACTIVE), + afTriggerId(0), + aeTriggerId(0) { } } m3aState; + // Whether the partial result quirk is enabled for this device + bool mUsePartialQuirk; + + // Track most recent frame number for which 3A notifications were sent for. + // Used to filter against sending 3A notifications for the same frame + // several times. + int32_t mLast3AFrameNumber; + // Emit FaceDetection event to java if faces changed void callbackFaceDetection(sp<Camera2Client> client, const camera_frame_metadata &metadata); diff --git a/services/camera/libcameraservice/api1/client2/Parameters.cpp b/services/camera/libcameraservice/api1/client2/Parameters.cpp index 8a4e75c..08af566 100644 --- a/services/camera/libcameraservice/api1/client2/Parameters.cpp +++ b/services/camera/libcameraservice/api1/client2/Parameters.cpp @@ -183,8 +183,7 @@ status_t Parameters::initialize(const CameraMetadata *info) { // still have to do something sane for them // NOTE: Not scaled like FPS range values are. - previewFps = fpsFromRange(previewFpsRange[0], previewFpsRange[1]); - lastSetPreviewFps = previewFps; + int previewFps = fpsFromRange(previewFpsRange[0], previewFpsRange[1]); params.set(CameraParameters::KEY_PREVIEW_FRAME_RATE, previewFps); @@ -1047,6 +1046,11 @@ status_t Parameters::buildQuirks() { ALOGV_IF(quirks.meteringCropRegion, "Camera %d: Quirk meteringCropRegion" " enabled", cameraId); + entry = info->find(ANDROID_QUIRKS_USE_PARTIAL_RESULT); + quirks.partialResults = (entry.count != 0 && entry.data.u8[0] == 1); + ALOGV_IF(quirks.partialResults, "Camera %d: Quirk usePartialResult" + " enabled", cameraId); + return OK; } @@ -1129,13 +1133,22 @@ status_t Parameters::set(const String8& paramString) { // PREVIEW_FPS_RANGE bool fpsRangeChanged = false; + int32_t lastSetFpsRange[2]; + + params.getPreviewFpsRange(&lastSetFpsRange[0], &lastSetFpsRange[1]); + lastSetFpsRange[0] /= kFpsToApiScale; + lastSetFpsRange[1] /= kFpsToApiScale; + newParams.getPreviewFpsRange(&validatedParams.previewFpsRange[0], &validatedParams.previewFpsRange[1]); validatedParams.previewFpsRange[0] /= kFpsToApiScale; validatedParams.previewFpsRange[1] /= kFpsToApiScale; - if (validatedParams.previewFpsRange[0] != previewFpsRange[0] || - validatedParams.previewFpsRange[1] != previewFpsRange[1]) { + // Compare the FPS range value from the last set() to the current set() + // to determine if the client has changed it + if (validatedParams.previewFpsRange[0] != lastSetFpsRange[0] || + validatedParams.previewFpsRange[1] != lastSetFpsRange[1]) { + fpsRangeChanged = true; camera_metadata_ro_entry_t availablePreviewFpsRanges = staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, 2); @@ -1153,16 +1166,6 @@ status_t Parameters::set(const String8& paramString) { validatedParams.previewFpsRange[1]); return BAD_VALUE; } - validatedParams.previewFps = - fpsFromRange(validatedParams.previewFpsRange[0], - validatedParams.previewFpsRange[1]); - - // Update our last-seen single preview FPS, needed for disambiguating - // when the application is intending to use the deprecated single-FPS - // setting vs. the range FPS setting - validatedParams.lastSetPreviewFps = newParams.getPreviewFrameRate(); - - newParams.setPreviewFrameRate(validatedParams.previewFps); } // PREVIEW_FORMAT @@ -1200,12 +1203,11 @@ status_t Parameters::set(const String8& paramString) { // PREVIEW_FRAME_RATE Deprecated, only use if the preview fps range is // unchanged this time. The single-value FPS is the same as the minimum of // the range. To detect whether the application has changed the value of - // previewFps, compare against their last-set preview FPS instead of the - // single FPS we may have synthesized from a range FPS set. + // previewFps, compare against their last-set preview FPS. if (!fpsRangeChanged) { - validatedParams.previewFps = newParams.getPreviewFrameRate(); - if (validatedParams.previewFps != lastSetPreviewFps || - recordingHintChanged) { + int previewFps = newParams.getPreviewFrameRate(); + int lastSetPreviewFps = params.getPreviewFrameRate(); + if (previewFps != lastSetPreviewFps || recordingHintChanged) { camera_metadata_ro_entry_t availableFrameRates = staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES); /** @@ -1218,8 +1220,8 @@ status_t Parameters::set(const String8& paramString) { * Either way, in case of multiple ranges, break the tie by * selecting the smaller range. */ - int targetFps = validatedParams.previewFps; - // all ranges which have targetFps + + // all ranges which have previewFps Vector<Range> candidateRanges; for (i = 0; i < availableFrameRates.count; i+=2) { Range r = { @@ -1227,13 +1229,13 @@ status_t Parameters::set(const String8& paramString) { availableFrameRates.data.i32[i+1] }; - if (r.min <= targetFps && targetFps <= r.max) { + if (r.min <= previewFps && previewFps <= r.max) { candidateRanges.push(r); } } if (candidateRanges.isEmpty()) { ALOGE("%s: Requested preview frame rate %d is not supported", - __FUNCTION__, validatedParams.previewFps); + __FUNCTION__, previewFps); return BAD_VALUE; } // most applicable range with targetFps @@ -1272,14 +1274,6 @@ status_t Parameters::set(const String8& paramString) { validatedParams.previewFpsRange[1], validatedParams.recordingHint); } - newParams.set(CameraParameters::KEY_PREVIEW_FPS_RANGE, - String8::format("%d,%d", - validatedParams.previewFpsRange[0] * kFpsToApiScale, - validatedParams.previewFpsRange[1] * kFpsToApiScale)); - // Update our last-seen single preview FPS, needed for disambiguating - // when the application is intending to use the deprecated single-FPS - // setting vs. the range FPS setting - validatedParams.lastSetPreviewFps = validatedParams.previewFps; } // PICTURE_SIZE diff --git a/services/camera/libcameraservice/api1/client2/Parameters.h b/services/camera/libcameraservice/api1/client2/Parameters.h index bcbdb99..32dbd42 100644 --- a/services/camera/libcameraservice/api1/client2/Parameters.h +++ b/services/camera/libcameraservice/api1/client2/Parameters.h @@ -46,8 +46,6 @@ struct Parameters { int previewWidth, previewHeight; int32_t previewFpsRange[2]; - int lastSetPreviewFps; // the last single FPS value seen in a set call - int previewFps; // deprecated, here only for tracking changes int previewFormat; int previewTransform; // set by CAMERA_CMD_SET_DISPLAY_ORIENTATION @@ -209,6 +207,7 @@ struct Parameters { bool triggerAfWithAuto; bool useZslFormat; bool meteringCropRegion; + bool partialResults; } quirks; /** diff --git a/services/camera/libcameraservice/api1/client2/ZslProcessor.cpp b/services/camera/libcameraservice/api1/client2/ZslProcessor.cpp index 4207ba9..453d54c 100644 --- a/services/camera/libcameraservice/api1/client2/ZslProcessor.cpp +++ b/services/camera/libcameraservice/api1/client2/ZslProcessor.cpp @@ -540,7 +540,7 @@ void ZslProcessor::dumpZslQueue(int fd) const { if (entry.count > 0) frameAeState = entry.data.u8[0]; } String8 result = - String8::format(" %d: b: %lld\tf: %lld, AE state: %d", i, + String8::format(" %zu: b: %lld\tf: %lld, AE state: %d", i, bufferTimestamp, frameTimestamp, frameAeState); ALOGV("%s", result.string()); if (fd != -1) { diff --git a/services/camera/libcameraservice/api1/client2/ZslProcessor3.cpp b/services/camera/libcameraservice/api1/client2/ZslProcessor3.cpp index 776ebe2..6b4e57a 100644 --- a/services/camera/libcameraservice/api1/client2/ZslProcessor3.cpp +++ b/services/camera/libcameraservice/api1/client2/ZslProcessor3.cpp @@ -355,7 +355,7 @@ void ZslProcessor3::dumpZslQueue(int fd) const { if (entry.count > 0) frameAeState = entry.data.u8[0]; } String8 result = - String8::format(" %d: b: %lld\tf: %lld, AE state: %d", i, + String8::format(" %zu: b: %lld\tf: %lld, AE state: %d", i, bufferTimestamp, frameTimestamp, frameAeState); ALOGV("%s", result.string()); if (fd != -1) { diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp index 72126c1..1cdf8dc 100644 --- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp +++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp @@ -81,7 +81,8 @@ status_t CameraDeviceClient::initialize(camera_module_t *module) mFrameProcessor->registerListener(FRAME_PROCESSOR_LISTENER_MIN_ID, FRAME_PROCESSOR_LISTENER_MAX_ID, - /*listener*/this); + /*listener*/this, + /*quirkSendPartials*/true); return OK; } diff --git a/services/camera/libcameraservice/common/FrameProcessorBase.cpp b/services/camera/libcameraservice/common/FrameProcessorBase.cpp index 52906ee..f2064fb 100644 --- a/services/camera/libcameraservice/common/FrameProcessorBase.cpp +++ b/services/camera/libcameraservice/common/FrameProcessorBase.cpp @@ -37,11 +37,11 @@ FrameProcessorBase::~FrameProcessorBase() { } status_t FrameProcessorBase::registerListener(int32_t minId, - int32_t maxId, wp<FilteredListener> listener) { + int32_t maxId, wp<FilteredListener> listener, bool quirkSendPartials) { Mutex::Autolock l(mInputMutex); ALOGV("%s: Registering listener for frame id range %d - %d", __FUNCTION__, minId, maxId); - RangeListener rListener = { minId, maxId, listener }; + RangeListener rListener = { minId, maxId, listener, quirkSendPartials }; mRangeListeners.push_back(rListener); return OK; } @@ -145,6 +145,16 @@ status_t FrameProcessorBase::processListeners(const CameraMetadata &frame, ATRACE_CALL(); camera_metadata_ro_entry_t entry; + // Quirks: Don't deliver partial results to listeners that don't want them + bool quirkIsPartial = false; + entry = frame.find(ANDROID_QUIRKS_PARTIAL_RESULT); + if (entry.count != 0 && + entry.data.u8[0] == ANDROID_QUIRKS_PARTIAL_RESULT_PARTIAL) { + ALOGV("%s: Camera %d: Not forwarding partial result to listeners", + __FUNCTION__, device->getId()); + quirkIsPartial = true; + } + entry = frame.find(ANDROID_REQUEST_ID); if (entry.count == 0) { ALOGE("%s: Camera %d: Error reading frame id", @@ -160,7 +170,8 @@ status_t FrameProcessorBase::processListeners(const CameraMetadata &frame, List<RangeListener>::iterator item = mRangeListeners.begin(); while (item != mRangeListeners.end()) { if (requestId >= item->minId && - requestId < item->maxId) { + requestId < item->maxId && + (!quirkIsPartial || item->quirkSendPartials) ) { sp<FilteredListener> listener = item->listener.promote(); if (listener == 0) { item = mRangeListeners.erase(item); diff --git a/services/camera/libcameraservice/common/FrameProcessorBase.h b/services/camera/libcameraservice/common/FrameProcessorBase.h index 4d80ebf..89b608a 100644 --- a/services/camera/libcameraservice/common/FrameProcessorBase.h +++ b/services/camera/libcameraservice/common/FrameProcessorBase.h @@ -44,9 +44,11 @@ class FrameProcessorBase: public Thread { }; // Register a listener for a range of IDs [minId, maxId). Multiple listeners - // can be listening to the same range + // can be listening to the same range. + // QUIRK: sendPartials controls whether partial results will be sent. status_t registerListener(int32_t minId, int32_t maxId, - wp<FilteredListener> listener); + wp<FilteredListener> listener, + bool quirkSendPartials = true); status_t removeListener(int32_t minId, int32_t maxId, wp<FilteredListener> listener); @@ -64,6 +66,7 @@ class FrameProcessorBase: public Thread { int32_t minId; int32_t maxId; wp<FilteredListener> listener; + bool quirkSendPartials; }; List<RangeListener> mRangeListeners; diff --git a/services/camera/libcameraservice/device2/Camera2Device.cpp b/services/camera/libcameraservice/device2/Camera2Device.cpp index 2bc1a8a..dc97c47 100644 --- a/services/camera/libcameraservice/device2/Camera2Device.cpp +++ b/services/camera/libcameraservice/device2/Camera2Device.cpp @@ -25,6 +25,7 @@ #define ALOGVV(...) ((void)0) #endif +#include <inttypes.h> #include <utils/Log.h> #include <utils/Trace.h> #include <utils/Timers.h> @@ -822,7 +823,7 @@ status_t Camera2Device::MetadataQueue::dump(int fd, result.append(" Stream slot: Empty\n"); write(fd, result.string(), result.size()); } else { - result.appendFormat(" Stream slot: %d entries\n", + result.appendFormat(" Stream slot: %zu entries\n", mStreamSlot.size()); int i = 0; for (List<camera_metadata_t*>::iterator r = mStreamSlot.begin(); @@ -837,7 +838,7 @@ status_t Camera2Device::MetadataQueue::dump(int fd, result = " Main queue is empty\n"; write(fd, result.string(), result.size()); } else { - result = String8::format(" Main queue has %d entries:\n", + result = String8::format(" Main queue has %zu entries:\n", mEntries.size()); int i = 0; for (List<camera_metadata_t*>::iterator r = mEntries.begin(); @@ -1214,11 +1215,11 @@ status_t Camera2Device::StreamAdapter::dump(int fd, ATRACE_CALL(); String8 result = String8::format(" Stream %d: %d x %d, format 0x%x\n", mId, mWidth, mHeight, mFormat); - result.appendFormat(" size %d, usage 0x%x, requested format 0x%x\n", + result.appendFormat(" size %zu, usage 0x%x, requested format 0x%x\n", mSize, mUsage, mFormatRequested); result.appendFormat(" total buffers: %d, dequeued buffers: %d\n", mTotalBuffers, mActiveBuffers); - result.appendFormat(" frame count: %d, last timestamp %lld\n", + result.appendFormat(" frame count: %d, last timestamp %" PRId64 "\n", mFrameCount, mLastTimestamp); write(fd, result.string(), result.size()); return OK; diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp index 6f2dc85..3dbc1b0 100644 --- a/services/camera/libcameraservice/device3/Camera3Device.cpp +++ b/services/camera/libcameraservice/device3/Camera3Device.cpp @@ -41,6 +41,7 @@ #include <utils/Trace.h> #include <utils/Timers.h> +#include "utils/CameraTraces.h" #include "device3/Camera3Device.h" #include "device3/Camera3OutputStream.h" #include "device3/Camera3InputStream.h" @@ -54,6 +55,7 @@ Camera3Device::Camera3Device(int id): mId(id), mHal3Device(NULL), mStatus(STATUS_UNINITIALIZED), + mUsePartialResultQuirk(false), mNextResultFrameNumber(0), mNextShutterFrameNumber(0), mListener(NULL) @@ -192,6 +194,15 @@ status_t Camera3Device::initialize(camera_module_t *module) mNeedConfig = true; mPauseStateNotify = false; + /** Check for quirks */ + + // Will the HAL be sending in early partial result metadata? + camera_metadata_entry partialResultsQuirk = + mDeviceInfo.find(ANDROID_QUIRKS_USE_PARTIAL_RESULT); + if (partialResultsQuirk.count > 0 && partialResultsQuirk.data.u8[0] == 1) { + mUsePartialResultQuirk = true; + } + return OK; } @@ -1363,6 +1374,10 @@ void Camera3Device::setErrorStateLockedV(const char *fmt, va_list args) { // But only do error state transition steps for the first error if (mStatus == STATUS_ERROR || mStatus == STATUS_UNINITIALIZED) return; + // Save stack trace. View by dumping it later. + CameraTraces::saveTrace(); + // TODO: consider adding errorCause and client pid/procname + mErrorCause = errorCause; mRequestThread->setPaused(true); @@ -1386,6 +1401,175 @@ status_t Camera3Device::registerInFlight(int32_t frameNumber, } /** + * QUIRK(partial results) + * Check if all 3A fields are ready, and send off a partial 3A-only result + * to the output frame queue + */ +bool Camera3Device::processPartial3AQuirk( + int32_t frameNumber, int32_t requestId, + const CameraMetadata& partial) { + + // Check if all 3A states are present + // The full list of fields is + // android.control.afMode + // android.control.awbMode + // android.control.aeState + // android.control.awbState + // android.control.afState + // android.control.afTriggerID + // android.control.aePrecaptureID + // TODO: Add android.control.aeMode + + bool gotAllStates = true; + + uint8_t afMode; + uint8_t awbMode; + uint8_t aeState; + uint8_t afState; + uint8_t awbState; + int32_t afTriggerId; + int32_t aeTriggerId; + + gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AF_MODE, + &afMode, frameNumber); + + gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AWB_MODE, + &awbMode, frameNumber); + + gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AE_STATE, + &aeState, frameNumber); + + gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AF_STATE, + &afState, frameNumber); + + gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AWB_STATE, + &awbState, frameNumber); + + gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AF_TRIGGER_ID, + &afTriggerId, frameNumber); + + gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AE_PRECAPTURE_ID, + &aeTriggerId, frameNumber); + + if (!gotAllStates) return false; + + ALOGVV("%s: Camera %d: Frame %d, Request ID %d: AF mode %d, AWB mode %d, " + "AF state %d, AE state %d, AWB state %d, " + "AF trigger %d, AE precapture trigger %d", + __FUNCTION__, mId, frameNumber, requestId, + afMode, awbMode, + afState, aeState, awbState, + afTriggerId, aeTriggerId); + + // Got all states, so construct a minimal result to send + // In addition to the above fields, this means adding in + // android.request.frameCount + // android.request.requestId + // android.quirks.partialResult + + const size_t kMinimal3AResultEntries = 10; + + Mutex::Autolock l(mOutputLock); + + CameraMetadata& min3AResult = + *mResultQueue.insert( + mResultQueue.end(), + CameraMetadata(kMinimal3AResultEntries, /*dataCapacity*/ 0)); + + if (!insert3AResult(min3AResult, ANDROID_REQUEST_FRAME_COUNT, + &frameNumber, frameNumber)) { + return false; + } + + if (!insert3AResult(min3AResult, ANDROID_REQUEST_ID, + &requestId, frameNumber)) { + return false; + } + + static const uint8_t partialResult = ANDROID_QUIRKS_PARTIAL_RESULT_PARTIAL; + if (!insert3AResult(min3AResult, ANDROID_QUIRKS_PARTIAL_RESULT, + &partialResult, frameNumber)) { + return false; + } + + if (!insert3AResult(min3AResult, ANDROID_CONTROL_AF_MODE, + &afMode, frameNumber)) { + return false; + } + + if (!insert3AResult(min3AResult, ANDROID_CONTROL_AWB_MODE, + &awbMode, frameNumber)) { + return false; + } + + if (!insert3AResult(min3AResult, ANDROID_CONTROL_AE_STATE, + &aeState, frameNumber)) { + return false; + } + + if (!insert3AResult(min3AResult, ANDROID_CONTROL_AF_STATE, + &afState, frameNumber)) { + return false; + } + + if (!insert3AResult(min3AResult, ANDROID_CONTROL_AWB_STATE, + &awbState, frameNumber)) { + return false; + } + + if (!insert3AResult(min3AResult, ANDROID_CONTROL_AF_TRIGGER_ID, + &afTriggerId, frameNumber)) { + return false; + } + + if (!insert3AResult(min3AResult, ANDROID_CONTROL_AE_PRECAPTURE_ID, + &aeTriggerId, frameNumber)) { + return false; + } + + mResultSignal.signal(); + + return true; +} + +template<typename T> +bool Camera3Device::get3AResult(const CameraMetadata& result, int32_t tag, + T* value, int32_t frameNumber) { + (void) frameNumber; + + camera_metadata_ro_entry_t entry; + + entry = result.find(tag); + if (entry.count == 0) { + ALOGVV("%s: Camera %d: Frame %d: No %s provided by HAL!", __FUNCTION__, + mId, frameNumber, get_camera_metadata_tag_name(tag)); + return false; + } + + if (sizeof(T) == sizeof(uint8_t)) { + *value = entry.data.u8[0]; + } else if (sizeof(T) == sizeof(int32_t)) { + *value = entry.data.i32[0]; + } else { + ALOGE("%s: Unexpected type", __FUNCTION__); + return false; + } + return true; +} + +template<typename T> +bool Camera3Device::insert3AResult(CameraMetadata& result, int32_t tag, + const T* value, int32_t frameNumber) { + if (result.update(tag, value, 1) != NO_ERROR) { + mResultQueue.erase(--mResultQueue.end(), mResultQueue.end()); + SET_ERR("Frame %d: Failed to set %s in partial metadata", + frameNumber, get_camera_metadata_tag_name(tag)); + return false; + } + return true; +} + +/** * Camera HAL device callback methods */ @@ -1400,6 +1584,8 @@ void Camera3Device::processCaptureResult(const camera3_capture_result *result) { frameNumber); return; } + bool partialResultQuirk = false; + CameraMetadata collectedQuirkResult; // Get capture timestamp from list of in-flight requests, where it was added // by the shutter notification for this frame. Then update the in-flight @@ -1415,24 +1601,58 @@ void Camera3Device::processCaptureResult(const camera3_capture_result *result) { return; } InFlightRequest &request = mInFlightMap.editValueAt(idx); + + // Check if this result carries only partial metadata + if (mUsePartialResultQuirk && result->result != NULL) { + camera_metadata_ro_entry_t partialResultEntry; + res = find_camera_metadata_ro_entry(result->result, + ANDROID_QUIRKS_PARTIAL_RESULT, &partialResultEntry); + if (res != NAME_NOT_FOUND && + partialResultEntry.count > 0 && + partialResultEntry.data.u8[0] == + ANDROID_QUIRKS_PARTIAL_RESULT_PARTIAL) { + // A partial result. Flag this as such, and collect this + // set of metadata into the in-flight entry. + partialResultQuirk = true; + request.partialResultQuirk.collectedResult.append( + result->result); + request.partialResultQuirk.collectedResult.erase( + ANDROID_QUIRKS_PARTIAL_RESULT); + // Fire off a 3A-only result if possible + if (!request.partialResultQuirk.haveSent3A) { + request.partialResultQuirk.haveSent3A = + processPartial3AQuirk(frameNumber, + request.requestId, + request.partialResultQuirk.collectedResult); + } + } + } + timestamp = request.captureTimestamp; /** - * One of the following must happen before it's legal to call process_capture_result: + * One of the following must happen before it's legal to call process_capture_result, + * unless partial metadata is being provided: * - CAMERA3_MSG_SHUTTER (expected during normal operation) * - CAMERA3_MSG_ERROR (expected during flush) */ - if (request.requestStatus == OK && timestamp == 0) { + if (request.requestStatus == OK && timestamp == 0 && !partialResultQuirk) { SET_ERR("Called before shutter notify for frame %d", frameNumber); return; } - if (result->result != NULL) { + // Did we get the (final) result metadata for this capture? + if (result->result != NULL && !partialResultQuirk) { if (request.haveResultMetadata) { SET_ERR("Called multiple times with metadata for frame %d", frameNumber); return; } + if (mUsePartialResultQuirk && + !request.partialResultQuirk.collectedResult.isEmpty()) { + collectedQuirkResult.acquire( + request.partialResultQuirk.collectedResult); + } request.haveResultMetadata = true; } @@ -1444,6 +1664,7 @@ void Camera3Device::processCaptureResult(const camera3_capture_result *result) { return; } + // Check if everything has arrived for this result (buffers and metadata) if (request.haveResultMetadata && request.numBuffersLeft == 0) { ATRACE_ASYNC_END("frame capture", frameNumber); mInFlightMap.removeItemsAt(idx, 1); @@ -1458,9 +1679,12 @@ void Camera3Device::processCaptureResult(const camera3_capture_result *result) { } // Process the result metadata, if provided - if (result->result != NULL) { + bool gotResult = false; + if (result->result != NULL && !partialResultQuirk) { Mutex::Autolock l(mOutputLock); + gotResult = true; + if (frameNumber != mNextResultFrameNumber) { SET_ERR("Out-of-order capture result metadata submitted! " "(got frame number %d, expecting %d)", @@ -1469,19 +1693,26 @@ void Camera3Device::processCaptureResult(const camera3_capture_result *result) { } mNextResultFrameNumber++; - CameraMetadata &captureResult = - *mResultQueue.insert(mResultQueue.end(), CameraMetadata()); - + CameraMetadata captureResult; captureResult = result->result; + if (captureResult.update(ANDROID_REQUEST_FRAME_COUNT, (int32_t*)&frameNumber, 1) != OK) { SET_ERR("Failed to set frame# in metadata (%d)", frameNumber); + gotResult = false; } else { ALOGVV("%s: Camera %d: Set frame# in metadata (%d)", __FUNCTION__, mId, frameNumber); } + // Append any previous partials to form a complete result + if (mUsePartialResultQuirk && !collectedQuirkResult.isEmpty()) { + captureResult.append(collectedQuirkResult); + } + + captureResult.sort(); + // Check that there's a timestamp in the result metadata camera_metadata_entry entry = @@ -1489,10 +1720,19 @@ void Camera3Device::processCaptureResult(const camera3_capture_result *result) { if (entry.count == 0) { SET_ERR("No timestamp provided by HAL for frame %d!", frameNumber); + gotResult = false; } else if (timestamp != entry.data.i64[0]) { SET_ERR("Timestamp mismatch between shutter notify and result" " metadata for frame %d (%lld vs %lld respectively)", frameNumber, timestamp, entry.data.i64[0]); + gotResult = false; + } + + if (gotResult) { + // Valid result, insert into queue + CameraMetadata& queuedResult = + *mResultQueue.insert(mResultQueue.end(), CameraMetadata()); + queuedResult.swap(captureResult); } } // scope for mOutputLock @@ -1512,7 +1752,7 @@ void Camera3Device::processCaptureResult(const camera3_capture_result *result) { // Finally, signal any waiters for new frames - if (result->result != NULL) { + if (gotResult) { mResultSignal.signal(); } diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h index 12252c8..468f641 100644 --- a/services/camera/libcameraservice/device3/Camera3Device.h +++ b/services/camera/libcameraservice/device3/Camera3Device.h @@ -188,6 +188,9 @@ class Camera3Device : // Need to hold on to stream references until configure completes. Vector<sp<camera3::Camera3StreamInterface> > mDeletedStreams; + // Whether quirk ANDROID_QUIRKS_USE_PARTIAL_RESULT is enabled + bool mUsePartialResultQuirk; + /**** End scope for mLock ****/ class CaptureRequest : public LightRefBase<CaptureRequest> { @@ -445,6 +448,18 @@ class Camera3Device : // buffers int numBuffersLeft; + // Fields used by the partial result quirk only + struct PartialResultQuirkInFlight { + // Set by process_capture_result once 3A has been sent to clients + bool haveSent3A; + // Result metadata collected so far, when partial results are in use + CameraMetadata collectedResult; + + PartialResultQuirkInFlight(): + haveSent3A(false) { + } + } partialResultQuirk; + // Default constructor needed by KeyedVector InFlightRequest() : requestId(0), @@ -472,6 +487,22 @@ class Camera3Device : int32_t numBuffers); /** + * For the partial result quirk, check if all 3A state fields are available + * and if so, queue up 3A-only result to the client. Returns true if 3A + * is sent. + */ + bool processPartial3AQuirk(int32_t frameNumber, int32_t requestId, + const CameraMetadata& partial); + + // Helpers for reading and writing 3A metadata into to/from partial results + template<typename T> + bool get3AResult(const CameraMetadata& result, int32_t tag, + T* value, int32_t frameNumber); + + template<typename T> + bool insert3AResult(CameraMetadata &result, int32_t tag, const T* value, + int32_t frameNumber); + /** * Tracking for idle detection */ sp<camera3::StatusTracker> mStatusTracker; diff --git a/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp b/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp index da51228..42e02d8 100644 --- a/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp +++ b/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp @@ -70,12 +70,12 @@ void Camera3IOStreamBase::dump(int fd, const Vector<String16> &args) const { lines.appendFormat(" Dims: %d x %d, format 0x%x\n", camera3_stream::width, camera3_stream::height, camera3_stream::format); - lines.appendFormat(" Max size: %d\n", mMaxSize); + lines.appendFormat(" Max size: %zu\n", mMaxSize); lines.appendFormat(" Usage: %d, max HAL buffers: %d\n", camera3_stream::usage, camera3_stream::max_buffers); lines.appendFormat(" Frames produced: %d, last timestamp: %lld ns\n", mFrameCount, mLastTimestamp); - lines.appendFormat(" Total buffers: %d, currently dequeued: %d\n", + lines.appendFormat(" Total buffers: %zu, currently dequeued: %zu\n", mTotalBufferCount, mDequeuedBufferCount); write(fd, lines.string(), lines.size()); } diff --git a/services/camera/libcameraservice/device3/Camera3ZslStream.cpp b/services/camera/libcameraservice/device3/Camera3ZslStream.cpp index 04f5dc5..1a54923 100644 --- a/services/camera/libcameraservice/device3/Camera3ZslStream.cpp +++ b/services/camera/libcameraservice/device3/Camera3ZslStream.cpp @@ -271,7 +271,7 @@ void Camera3ZslStream::dump(int fd, const Vector<String16> &args) const { Camera3IOStreamBase::dump(fd, args); lines = String8(); - lines.appendFormat(" Input buffers pending: %d, in flight %d\n", + lines.appendFormat(" Input buffers pending: %zu, in flight %zu\n", mInputBufferQueue.size(), mBuffersInFlight.size()); write(fd, lines.string(), lines.size()); } diff --git a/services/camera/libcameraservice/gui/RingBufferConsumer.cpp b/services/camera/libcameraservice/gui/RingBufferConsumer.cpp index ebc7ea7..9a6dc28 100644 --- a/services/camera/libcameraservice/gui/RingBufferConsumer.cpp +++ b/services/camera/libcameraservice/gui/RingBufferConsumer.cpp @@ -21,11 +21,11 @@ #include <gui/RingBufferConsumer.h> -#define BI_LOGV(x, ...) ALOGV("[%s] "x, mName.string(), ##__VA_ARGS__) -#define BI_LOGD(x, ...) ALOGD("[%s] "x, mName.string(), ##__VA_ARGS__) -#define BI_LOGI(x, ...) ALOGI("[%s] "x, mName.string(), ##__VA_ARGS__) -#define BI_LOGW(x, ...) ALOGW("[%s] "x, mName.string(), ##__VA_ARGS__) -#define BI_LOGE(x, ...) ALOGE("[%s] "x, mName.string(), ##__VA_ARGS__) +#define BI_LOGV(x, ...) ALOGV("[%s] " x, mName.string(), ##__VA_ARGS__) +#define BI_LOGD(x, ...) ALOGD("[%s] " x, mName.string(), ##__VA_ARGS__) +#define BI_LOGI(x, ...) ALOGI("[%s] " x, mName.string(), ##__VA_ARGS__) +#define BI_LOGW(x, ...) ALOGW("[%s] " x, mName.string(), ##__VA_ARGS__) +#define BI_LOGE(x, ...) ALOGE("[%s] " x, mName.string(), ##__VA_ARGS__) #undef assert #define assert(x) ALOG_ASSERT((x), #x) diff --git a/services/camera/libcameraservice/utils/CameraTraces.cpp b/services/camera/libcameraservice/utils/CameraTraces.cpp new file mode 100644 index 0000000..346e15f --- /dev/null +++ b/services/camera/libcameraservice/utils/CameraTraces.cpp @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "CameraTraces" +#define ATRACE_TAG ATRACE_TAG_CAMERA +//#define LOG_NDEBUG 0 + +#include "utils/CameraTraces.h" +#include <utils/ProcessCallStack.h> + +#include <utils/Mutex.h> +#include <utils/List.h> + +#include <utils/Log.h> +#include <cutils/trace.h> + +namespace android { +namespace camera3 { + +struct CameraTracesImpl { + Mutex tracesLock; + List<ProcessCallStack> pcsList; +}; // class CameraTraces::Impl; + +static CameraTracesImpl gImpl; +CameraTracesImpl& CameraTraces::sImpl = gImpl; + +void CameraTraces::saveTrace() { + ALOGV("%s: begin", __FUNCTION__); + ATRACE_BEGIN("CameraTraces::saveTrace"); + Mutex::Autolock al(sImpl.tracesLock); + + List<ProcessCallStack>& pcsList = sImpl.pcsList; + + // Insert new ProcessCallStack, and immediately crawl all the threads + pcsList.push_front(ProcessCallStack()); + ProcessCallStack& pcs = *pcsList.begin(); + pcs.update(); + + if (pcsList.size() > MAX_TRACES) { + // Prune list periodically and discard oldest entry + pcsList.erase(--pcsList.end()); + } + + IF_ALOGV() { + pcs.log(LOG_TAG, ANDROID_LOG_VERBOSE); + } + + ALOGD("Process trace saved. Use dumpsys media.camera to view."); + + ATRACE_END(); +} + +status_t CameraTraces::dump(int fd, const Vector<String16> &args __attribute__((unused))) { + ALOGV("%s: fd = %d", __FUNCTION__, fd); + Mutex::Autolock al(sImpl.tracesLock); + List<ProcessCallStack>& pcsList = sImpl.pcsList; + + if (fd < 0) { + ALOGW("%s: Negative FD (%d)", __FUNCTION__, fd); + return BAD_VALUE; + } + + fdprintf(fd, "Camera traces (%zu):\n", pcsList.size()); + + if (pcsList.empty()) { + fdprintf(fd, " No camera traces collected.\n"); + } + + // Print newest items first + List<ProcessCallStack>::iterator it, end; + for (it = pcsList.begin(), end = pcsList.end(); it != end; ++it) { + const ProcessCallStack& pcs = *it; + pcs.dump(fd, DUMP_INDENT); + } + + return OK; +} + +}; // namespace camera3 +}; // namespace android diff --git a/services/camera/libcameraservice/utils/CameraTraces.h b/services/camera/libcameraservice/utils/CameraTraces.h new file mode 100644 index 0000000..d10dbc9 --- /dev/null +++ b/services/camera/libcameraservice/utils/CameraTraces.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_SERVERS_CAMERA_TRACES_H_ +#define ANDROID_SERVERS_CAMERA_TRACES_H_ + +#include <utils/Errors.h> +#include <utils/String16.h> +#include <utils/Vector.h> + +namespace android { +namespace camera3 { + +class CameraTracesImpl; + +// Collect a list of the process's stack traces +class CameraTraces { +public: + /** + * Save the current stack trace for each thread in the process. At most + * MAX_TRACES will be saved, after which the oldest traces will be discarded. + * + * <p>Use CameraTraces::dump to print out the traces.</p> + */ + static void saveTrace(); + + /** + * Prints all saved traces to the specified file descriptor. + * + * <p>Each line is indented by DUMP_INDENT spaces.</p> + */ + static status_t dump(int fd, const Vector<String16>& args); + +private: + enum { + // Don't collect more than 100 traces. Discard oldest. + MAX_TRACES = 100, + + // Insert 2 spaces when dumping the traces + DUMP_INDENT = 2, + }; + + CameraTraces(); + ~CameraTraces(); + CameraTraces(CameraTraces& rhs); + + static CameraTracesImpl& sImpl; +}; // class CameraTraces + +}; // namespace camera3 +}; // namespace android + +#endif // ANDROID_SERVERS_CAMERA_TRACES_H_ |