diff --git a/README.md b/README.md index 0179ba160..3414f3d3d 100644 --- a/README.md +++ b/README.md @@ -1 +1,1031 @@ M...mmmh...Winamp...please shove me with your Closed Open Source Violating GitHub ToS Open Source Freedom license in my Skibidi Sigma Gyatt.. +```cpp +#include "stdafx.h" +#include "sfthost.h" +#include "userpane.h" + +CUserPane::CUserPane() +{ + ASSERT(_hwnd == NULL); + ASSERT(*_szUserName == 0); + ASSERT(_crColor == 0); + ASSERT(_hFont == NULL); + ASSERT(_hbmUserPicture== NULL); + + //Initialize the _rcColor to an invalid color + _crColor = CLR_INVALID; +} + +CUserPane::~CUserPane() +{ + if (_uidChangeRegister) + SHChangeNotifyDeregister(_uidChangeRegister); + + if (_hFont) + DeleteObject(_hFont); + + if (_hbmUserPicture) + DeleteObject(_hbmUserPicture); +} + +LRESULT CALLBACK CUserPane::s_WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + CUserPane *pThis = reinterpret_cast(GetWindowPtr(hwnd, GWLP_USERDATA)); + + if (!pThis && (WM_NCDESTROY != uMsg)) + { + pThis = new CUserPane; + SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)pThis); + } + + if (pThis) + return pThis->WndProc(hwnd, uMsg, wParam, lParam); + + return DefWindowProc(hwnd, uMsg, wParam, lParam); +} + +BOOL CUserPane::_IsCursorInPicture() +{ + if (!_hbmUserPicture) + return FALSE; + + RECT rc; + POINT p; + + GetCursorPos(&p); + MapWindowPoints(NULL, _hwnd, &p, 1); + + GetClientRect(_hwnd, &rc); + int iOffset = (RECTHEIGHT(rc) - _iFramedPicHeight) / 2; + + return ((p.x > iOffset && p.x < iOffset + _iFramedPicWidth) && + (p.y > iOffset && p.y < iOffset + _iFramedPicHeight)); +} + +void CUserPane::OnDrawItem(DRAWITEMSTRUCT *pdis) +{ + HFONT hfPrev = SelectFont(pdis->hDC, _hFont); + int cchName = lstrlen(_szUserName); + + int iOldMode = SetBkMode(pdis->hDC, TRANSPARENT); + + // display the text centered + SIZE siz; + RECT rc; + int iOffset=0; + int iOffsetX = 0; + GetTextExtentPoint32(pdis->hDC, _szUserName, cchName, &siz); + GetClientRect(_hwnd, &rc); + + iOffset = (RECTHEIGHT(rc) - siz.cy)/2; + if (!_hbmUserPicture) + iOffsetX = iOffset; + + if (iOffset < 0) + iOffset = 0; + + // later - read more precise offsets from theme file + if (_hTheme) + { + RECT rcUser; + rcUser.left = pdis->rcItem.left+ iOffsetX; + rcUser.top = pdis->rcItem.top+iOffset; + rcUser.bottom = pdis->rcItem.bottom + iOffset; + rcUser.right = pdis->rcItem.right + iOffsetX; + + // First calculate the bounding rectangle to reduce the cost of DrawShadowText + DrawText(pdis->hDC, _szUserName, cchName, &rcUser, DT_SINGLELINE | DT_NOPREFIX | DT_END_ELLIPSIS | DT_CALCRECT); + + DrawThemeText(_hTheme, pdis->hDC, SPP_USERPANE, 0, _szUserName, cchName, DT_SINGLELINE | DT_NOPREFIX | DT_END_ELLIPSIS, 0, &rcUser); + } + else + { + ExtTextOut(pdis->hDC, pdis->rcItem.left+ iOffsetX, pdis->rcItem.top+iOffset, 0, NULL, _szUserName, cchName, NULL); + } + + SetBkMode(pdis->hDC, iOldMode); + + SelectFont(pdis->hDC, hfPrev); +} + + +LRESULT CALLBACK CUserPane::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + LRESULT lr = 0L; + + switch (uMsg) + { + case WM_NCCREATE: + { + _hwnd = hwnd; + + _hTheme = (PaneDataFromCreateStruct(lParam))->hTheme; + + //Check for policy restrictions. + //If No Name policy is in place, the username will continue to be a NULL string! + ASSERT(*_szUserName == 0); + + _UpdateUserInfo(); + + if (_hTheme) + { + GetThemeColor(_hTheme, SPP_USERPANE, 0, TMT_TEXTCOLOR, &_crColor); + _hFont = LoadControlFont(_hTheme, SPP_USERPANE, FALSE, 150); + } + else + { + HFONT hfTemp = (HFONT) GetStockObject(DEFAULT_GUI_FONT); + LOGFONT lf = {0}; + GetObject(hfTemp, sizeof(lf), &lf); + lf.lfItalic = TRUE; + lf.lfHeight = (lf.lfHeight * 175) / 100; + lf.lfWidth = 0; // get the closest based on aspect ratio + lf.lfWeight = FW_BOLD; + lf.lfQuality = DEFAULT_QUALITY; + SHAdjustLOGFONT(&lf); // apply locale-specific adjustments + _hFont = CreateFontIndirect(&lf); + _crColor = GetSysColor(COLOR_CAPTIONTEXT); + // no need to free hfTemp + } + + + return TRUE; + } + + + case WM_NCDESTROY: + { + lr = DefWindowProc(hwnd, uMsg, wParam, lParam); + + SetWindowLongPtr(hwnd, GWLP_USERDATA, 0); + delete this; + + return lr; + } + + case WM_CREATE: + { + // create the user name static control and set its font if specified + DWORD dwStyle = WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_VISIBLE | + SS_OWNERDRAW | SS_NOTIFY; + + _hwndStatic = CreateWindowEx(0, TEXT("static"), NULL, dwStyle, + 0, 0, 0, 0, // we'll be sized properly on WM_SIZE + _hwnd, NULL, _Module.GetModuleInstance(), NULL); + if (_hwndStatic) + { + if (_hFont) + SetWindowFont(_hwndStatic, _hFont, FALSE); + + if (*_szUserName) + SetWindowText(_hwndStatic, _szUserName); + + return TRUE; + } + + return FALSE; + } + + case WM_SIZE: + { + return OnSize(); + } + + case WM_PAINT: + { + PAINTSTRUCT ps; + HDC hdc; + + hdc = BeginPaint(_hwnd, &ps); + if (hdc) + { + Paint(hdc); + EndPaint(_hwnd, &ps); + } + + return lr; + } + + case WM_ERASEBKGND: + { + RECT rc; + GetClientRect(_hwnd, &rc); + if (!_hTheme) + { + // DrawCaption will draw the caption in its gradient glory so we don't + // have to! Since we don't want any text to be drawn (we'll draw it ourselves) + // we pass the handle of a window which has blank text. And despite + // the documentation, you have to pass DC_TEXT or nothing draws! + UINT uFlags = DC_ACTIVE | DC_TEXT; + if (SHGetCurColorRes() > 8) + uFlags |= DC_GRADIENT; + + DrawCaption(hwnd, (HDC)wParam, &rc, uFlags); + } + else + { + DrawThemeBackground(_hTheme, (HDC)wParam, SPP_USERPANE, 0, &rc, 0); + } + return TRUE; + } + + + case WM_PRINTCLIENT: + { + // paint user picture + Paint((HDC)wParam); + + // Then forward the message to the static child window. + lParam = lParam & ~PRF_ERASEBKGND; //Strip out the erase bkgnd. We want transparency! + // We need to pass this message to the children, or else, they do not paint! + // This break will result in calling DefWindowProc below and that in turn passes + // this message to the children of this window. + break; + } + + case WM_CTLCOLORSTATIC: + SetTextColor((HDC)wParam, _crColor); + return (LRESULT)(GetStockObject(HOLLOW_BRUSH)); + + case WM_DRAWITEM: + OnDrawItem((LPDRAWITEMSTRUCT)lParam); + return 0; + + case WM_SETCURSOR: + // Change the cursor to a hand when its over the user picture + if (_IsCursorInPicture()) + { + SetCursor(LoadCursor(NULL, IDC_HAND)); + return TRUE; + } + break; + + case WM_LBUTTONUP: + // Launch the cpl to change the picture, if the user clicks on it. + // note that this is not exposed to accessibility, as this is a secondary access point for changing the picture + // and we don't want to clutter the start panel's keyboard navigation for a minor fluff helper like this... + if (_IsCursorInPicture()) + { + // wow this is slow, should we shellexec "mshta.exe res://nusrmgr.cpl/nusrmgr.hta" ourselves, + // since this will only happen when we know we are not on a domain. + SHRunControlPanel(TEXT("nusrmgr.cpl ,initialTask=ChangePicture"), _hwnd); + return 0; + } + break; + + case WM_SYSCOLORCHANGE: + case WM_DISPLAYCHANGE: + case WM_SETTINGCHANGE: + SHPropagateMessage(hwnd, uMsg, wParam, lParam, SPM_SEND | SPM_ONELEVEL); + break; + + + case WM_NOTIFY: + { + NMHDR *pnm = (NMHDR*)lParam; + switch (pnm->code) + { + case SMN_APPLYREGION: + return HandleApplyRegion(_hwnd, _hTheme, (SMNMAPPLYREGION *)lParam, SPP_USERPANE, 0); + } + } + break; + + case UPM_CHANGENOTIFY: + { + LPITEMIDLIST *ppidl; + LONG lEvent; + LPSHChangeNotificationLock pshcnl; + pshcnl = SHChangeNotification_Lock((HANDLE)wParam, (DWORD)lParam, &ppidl, &lEvent); + + if (pshcnl) + { + if (lEvent == SHCNE_EXTENDED_EVENT && ppidl[0]) + { + SHChangeDWORDAsIDList *pdwidl = (SHChangeDWORDAsIDList *)ppidl[0]; + if (pdwidl->dwItem1 == SHCNEE_USERINFOCHANGED) + { + _UpdateUserInfo(); + } + } + SHChangeNotification_Unlock(pshcnl); + } + } + break; + + } + + return ::DefWindowProc(hwnd, uMsg, wParam, lParam); +} + +void CUserPane::Paint(HDC hdc) +{ + // paint user picture if there is one + if (_hbmUserPicture) + { + RECT rc; + int iOffset; + BITMAP bm; + HDC hdcTmp; + + GetClientRect(_hwnd, &rc); + iOffset = (RECTHEIGHT(rc) - _iFramedPicHeight) / 2; + GetObject(_hbmUserPicture, sizeof(bm), &bm); + + hdcTmp = CreateCompatibleDC(hdc); + if (hdcTmp) + { + // draw the frame behind the user picture + if (_hTheme && (_iFramedPicWidth != USERPICWIDTH || _iFramedPicHeight != USERPICHEIGHT)) + { + RECT rcFrame; + rcFrame.left = iOffset; + rcFrame.top = iOffset; + rcFrame.right = rcFrame.left + _iFramedPicWidth; + rcFrame.bottom = rcFrame.top + _iFramedPicHeight; + + DrawThemeBackground(_hTheme, hdc, SPP_USERPICTURE, 0, &rcFrame, 0); + } + + // draw the user picture + SelectObject(hdcTmp, _hbmUserPicture); + int iStretchMode = SetStretchBltMode(hdc, COLORONCOLOR); + StretchBlt(hdc, iOffset + _mrgnPictureFrame.cxLeftWidth + (USERPICWIDTH - _iUnframedPicWidth)/2, iOffset + _mrgnPictureFrame.cyTopHeight + (USERPICHEIGHT - _iUnframedPicHeight)/2, _iUnframedPicWidth, _iUnframedPicHeight, + hdcTmp, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY); + SetStretchBltMode(hdc, iStretchMode); + DeleteDC(hdcTmp); + } + } +} + +LRESULT CUserPane::OnSize() +{ + RECT rc; + GetClientRect(_hwnd, &rc); + + if (_hbmUserPicture) + { + // if we've got a picture, start the text 2 edges over from the right edge of the user picture + // note - temp code - we'll read margins from the theme file shortly + int iPicOffset = (RECTHEIGHT(rc) - _iFramedPicHeight) / 2; + if (iPicOffset < 0) + iPicOffset = 0; + rc.left += iPicOffset + _iFramedPicWidth + GetSystemMetrics(SM_CYEDGE) * 2; + } + + if (_hwndStatic) + MoveWindow(_hwndStatic, rc.left, rc.top, RECTWIDTH(rc), RECTHEIGHT(rc), FALSE); + + return 0; +} + + +HRESULT CUserPane::_UpdateUserInfo() +{ + HRESULT hr = S_OK; + + if(!SHRestricted(REST_NOUSERNAMEINSTARTPANEL)) + { + //No restrictions! + //Try to get the fiendly name or if it fails get the login name. + ULONG uLen = ARRAYSIZE(_szUserName); + SHGetUserDisplayName(_szUserName, &uLen); // Ignore failure. The string will be empty by default + } + + // see if we should load the picture + BOOL bShowPicture = FALSE; + if (_hTheme) + GetThemeBool(_hTheme, SPP_USERPANE, 0, TMT_USERPICTURE, &bShowPicture); + + // add FriendlyLogonUI check here, since SHGetUserPicturePath + if (bShowPicture && IsOS(OS_FRIENDLYLOGONUI)) + { + TCHAR szUserPicturePath[MAX_PATH]; + szUserPicturePath[0] = _T('0'); + + SHGetUserPicturePath(NULL, SHGUPP_FLAG_CREATE, szUserPicturePath); + + if (szUserPicturePath[0]) + { + if (_hbmUserPicture) + { + DeleteObject(_hbmUserPicture); + _hbmUserPicture = NULL; + } + + _hbmUserPicture = (HBITMAP)LoadImage(NULL, szUserPicturePath, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION); + if (_hbmUserPicture) + { + BITMAP bm; + + GetObject(_hbmUserPicture, sizeof(bm), &bm); + + // Preferred dimensions + _iUnframedPicHeight = USERPICHEIGHT; + _iUnframedPicWidth = USERPICWIDTH; + + // If it's not square, scale the smaller dimension + // to maintain the aspect ratio. + if (bm.bmWidth > bm.bmHeight) + { + _iUnframedPicHeight = MulDiv(_iUnframedPicWidth, bm.bmHeight, bm.bmWidth); + } + else if (bm.bmHeight > bm.bmWidth) + { + _iUnframedPicWidth = MulDiv(_iUnframedPicHeight, bm.bmWidth, bm.bmHeight); + } + + _iFramedPicHeight = USERPICHEIGHT; + _iFramedPicWidth = USERPICWIDTH; + + if (_hTheme) + { + if (SUCCEEDED(GetThemeMargins(_hTheme, NULL, SPP_USERPICTURE, 0, TMT_CONTENTMARGINS, NULL, + &_mrgnPictureFrame))) + { + _iFramedPicHeight += _mrgnPictureFrame.cyTopHeight + _mrgnPictureFrame.cyBottomHeight; + _iFramedPicWidth += _mrgnPictureFrame.cxLeftWidth + _mrgnPictureFrame.cxRightWidth; + } + else + { + // Sometimes GetThemeMargins gets confused and returns failure + // *and* puts garbage data in _mrgnPictureFrame. + ZeroMemory(&_mrgnPictureFrame, sizeof(_mrgnPictureFrame)); + } + } + } + } + + if (!_uidChangeRegister) + { + SHChangeNotifyEntry fsne; + fsne.fRecursive = FALSE; + fsne.pidl = NULL; + + _uidChangeRegister = SHChangeNotifyRegister(_hwnd, SHCNRF_NewDelivery | SHCNRF_ShellLevel, SHCNE_EXTENDED_EVENT, + UPM_CHANGENOTIFY, 1, &fsne); + } + } + + OnSize(); + NMHDR nm; + nm.hwndFrom = _hwnd; + nm.idFrom = 0; + nm.code = SMN_NEEDREPAINT; + SendMessage(GetParent(_hwnd), WM_NOTIFY, nm.idFrom, (LPARAM)&nm); + + + return hr; +} + +BOOL WINAPI UserPane_RegisterClass() +{ + WNDCLASSEX wc; + ZeroMemory(&wc, sizeof(wc)); + + wc.cbSize = sizeof(wc); + wc.style = CS_GLOBALCLASS; + wc.lpfnWndProc = CUserPane::s_WndProc; + wc.hInstance = _Module.GetModuleInstance(); + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground = (HBRUSH)(NULL); + wc.lpszClassName = WC_USERPANE; + + return RegisterClassEx(&wc); +} + +#include "stdafx.h" +#include "sfthost.h" +#include "proglist.h" + +BOOL UserPane_RegisterClass(); +BOOL MorePrograms_RegisterClass(); +BOOL LogoffPane_RegisterClass(); + +void RegisterDesktopControlClasses() +{ + SFTBarHost::Register(); + UserPane_RegisterClass(); + MorePrograms_RegisterClass(); + LogoffPane_RegisterClass(); +} +``` +```c +#define PC98NTFSBOOTCODE_SIZE 8192 + + +unsigned char PC98NtfsBootCode[] = { +235,82,0,78,84,70,83,32,32,32,32,0,2,1,0,0, +0,0,0,0,0,248,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,250,51,192,142,208,188,0,124,251,86,140,200, +142,216,102,51,192,142,192,38,160,132,5,162,36,0,199,6, +28,0,0,0,199,6,30,0,0,0,199,6,16,0,0,0, +199,6,18,0,0,0,199,6,14,0,2,0,184,0,13,142, +192,102,51,219,232,68,0,161,26,0,38,139,92,10,102,247, +227,139,30,24,0,102,247,227,102,163,28,0,199,6,16,0, +0,0,199,6,18,0,0,0,198,6,14,0,16,184,0,13, +142,192,51,219,232,20,0,138,14,36,0,139,30,28,0,139, +22,30,0,94,104,0,13,104,106,2,203,96,6,139,54,14, +0,139,235,139,14,16,0,139,22,18,0,82,81,184,64,0, +59,240,115,2,139,198,80,82,247,38,11,0,90,80,139,216, +3,14,28,0,19,22,30,0,160,36,0,36,127,180,86,205, +27,95,91,89,90,114,11,3,203,131,210,0,3,239,43,243, +117,201,137,54,14,0,137,14,16,0,137,22,18,0,7,97, +195,80,83,81,82,6,255,54,14,0,255,54,16,0,255,54, +18,0,139,195,193,232,4,140,193,3,193,37,255,15,45,0, +16,247,216,80,161,14,0,139,14,11,0,193,233,4,247,225, +139,200,88,81,59,193,118,2,139,193,80,139,14,11,0,193, +233,4,51,210,247,241,163,14,0,232,95,255,88,89,43,200, +118,11,140,194,3,208,142,194,184,0,16,235,214,143,6,18, +0,143,6,16,0,143,6,14,0,7,90,89,91,88,195,160, +248,1,180,1,5,2,0,139,240,232,3,0,251,235,254,184, +0,160,142,192,50,228,172,60,0,116,3,171,235,241,195,13, +10,65,32,100,105,115,107,32,114,101,97,100,32,101,114,114, +111,114,32,111,99,99,117,114,114,101,100,0,13,10,78,84, +76,68,82,32,105,115,32,109,105,115,115,105,110,103,0,0, +0,0,0,0,0,0,0,0,191,220,0,0,0,0,85,170, +5,0,78,0,84,0,76,0,68,0,82,0,4,0,36,0, +73,0,51,0,48,0,0,224,0,0,0,48,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,235,18,144,144,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,140,200,142,216,193,224, +4,250,139,224,251,138,193,162,36,0,137,30,28,0,137,22, +30,0,86,102,15,183,6,11,0,102,15,182,30,13,0,102, +247,227,102,163,78,2,102,139,14,64,0,128,249,0,15,143, +14,0,246,217,102,184,1,0,0,0,102,211,224,235,8,144, +102,161,78,2,102,247,225,102,163,82,2,102,15,183,30,11, +0,102,51,210,102,247,243,102,163,86,2,232,14,4,102,139, +14,74,2,102,137,14,34,2,102,3,14,82,2,102,137,14, +38,2,102,3,14,82,2,102,137,14,42,2,102,3,14,82, +2,102,137,14,58,2,102,3,14,82,2,102,137,14,66,2, +102,184,144,0,0,0,102,139,14,34,2,232,237,8,102,11, +192,15,132,138,254,102,163,46,2,102,184,160,0,0,0,102, +139,14,38,2,232,212,8,102,163,50,2,102,184,176,0,0, +0,102,139,14,42,2,232,194,8,102,163,54,2,102,161,46, +2,102,11,192,15,132,87,254,103,128,120,8,0,15,133,78, +254,103,102,141,80,16,103,3,66,4,103,102,15,182,72,12, +102,137,14,98,2,103,102,139,72,8,102,137,14,94,2,102, +161,94,2,102,15,183,14,11,0,102,51,210,102,247,241,102, +163,102,2,102,161,66,2,102,3,6,94,2,102,163,70,2, +102,131,62,50,2,0,15,132,25,0,102,131,62,54,2,0, +15,132,251,253,102,139,30,54,2,30,7,102,139,62,70,2, +232,147,1,102,15,183,14,0,2,102,184,2,2,0,0,232, +151,7,102,11,192,15,132,11,9,103,102,139,0,30,7,102, +139,62,58,2,232,207,5,102,161,58,2,102,187,128,0,0, +0,102,185,0,0,0,0,102,186,0,0,0,0,232,173,0, +102,11,192,15,133,62,0,102,185,128,0,0,0,102,161,58, +2,232,90,8,102,11,192,15,132,201,8,30,7,102,139,62, +58,2,232,145,5,102,161,58,2,102,187,128,0,0,0,102, +185,0,0,0,0,102,186,0,0,0,0,232,111,0,102,11, +192,15,132,159,8,103,102,15,183,88,12,102,129,227,255,0, +0,0,15,133,142,8,102,139,216,104,0,32,7,102,43,255, +232,243,0,138,22,36,0,184,232,3,142,192,141,54,11,0, +43,192,93,104,0,32,80,203,6,30,102,96,102,139,218,102, +15,182,14,13,0,102,247,225,102,163,16,0,102,139,195,102, +247,225,163,14,0,139,223,131,227,15,140,192,102,193,239,4, +3,199,80,7,232,154,252,102,97,144,31,7,195,103,3,64, +20,103,102,131,56,255,15,132,76,0,103,102,57,24,15,133, +51,0,102,11,201,15,133,10,0,103,128,120,9,0,15,133, +35,0,195,103,58,72,9,15,133,26,0,102,139,240,103,3, +112,10,232,89,6,102,81,30,7,102,139,250,243,167,102,89, +15,133,1,0,195,103,102,131,120,4,0,15,132,7,0,103, +102,3,64,4,235,171,102,43,192,195,102,139,243,232,46,6, +103,102,3,0,103,247,64,12,2,0,15,133,52,0,103,102, +141,80,16,103,58,74,64,15,133,24,0,103,102,141,114,66, +232,11,6,102,81,30,7,102,139,251,243,167,102,89,15,133, +1,0,195,103,131,120,8,0,15,132,6,0,103,3,64,8, +235,194,102,51,192,195,103,128,123,8,0,15,133,28,0,6, +30,102,96,103,102,141,83,16,103,102,139,10,102,139,243,103, +3,114,4,243,164,102,97,144,31,7,195,103,102,141,83,16, +103,102,139,74,8,102,65,102,43,192,232,1,0,195,6,30, +102,96,103,128,123,8,1,15,132,3,0,233,17,252,102,131, +249,0,15,133,6,0,102,97,144,31,7,195,102,83,102,80, +102,81,102,87,6,232,115,4,102,139,209,7,102,95,102,89, +102,59,202,15,141,3,0,102,139,209,232,171,254,102,43,202, +102,139,218,102,139,194,102,15,182,22,13,0,102,247,226,102, +15,183,22,11,0,102,247,226,102,3,248,102,88,102,3,195, +102,91,235,170,6,30,102,96,103,128,123,8,1,15,132,3, +0,233,171,251,102,131,249,0,15,133,6,0,102,97,144,31, +7,195,102,83,102,80,102,81,102,87,6,102,81,102,51,210, +102,15,182,14,13,0,102,247,241,102,82,232,253,3,102,15, +182,30,13,0,102,247,227,102,90,102,3,194,102,80,102,15, +182,6,13,0,102,247,225,102,139,208,102,88,102,89,7,102, +95,102,89,102,59,202,15,141,3,0,102,139,209,102,163,16, +0,137,22,14,0,6,30,102,96,139,223,131,227,15,140,192, +102,193,239,4,3,199,80,7,232,198,250,102,97,144,31,7, +102,43,202,102,139,218,102,139,194,102,15,183,22,11,0,102, +247,226,102,3,248,102,88,102,3,195,102,91,233,101,255,6, +30,102,96,38,103,102,15,183,95,4,38,103,102,15,183,79, +6,102,11,201,15,132,247,250,102,3,223,102,131,195,2,102, +129,199,254,1,0,0,102,73,102,11,201,15,132,23,0,38, +103,139,3,38,103,137,7,102,131,195,2,102,129,199,0,2, +0,0,102,73,235,226,102,97,144,31,7,195,6,30,102,96, +102,184,1,0,0,0,102,163,30,2,102,161,26,2,102,3, +6,82,2,102,163,90,2,102,3,6,82,2,102,163,74,2, +102,161,48,0,102,15,182,30,13,0,102,247,227,102,139,30, +74,2,102,137,7,102,163,16,0,131,195,4,102,161,86,2, +102,137,7,163,14,0,131,195,4,102,137,30,74,2,102,139, +30,26,2,30,7,232,249,249,102,139,251,232,81,255,102,161, +26,2,102,187,32,0,0,0,102,185,0,0,0,0,102,186, +0,0,0,0,232,70,253,102,11,192,15,132,22,1,102,139, +216,30,7,102,139,62,22,2,232,219,253,102,139,30,22,2, +102,129,63,128,0,0,0,15,132,235,0,3,95,4,235,240, +102,83,102,139,71,16,102,247,38,86,2,102,80,102,51,210, +102,15,182,30,13,0,102,247,243,102,82,232,220,0,102,11, +192,15,132,250,249,102,139,14,86,2,102,15,182,30,13,0, +102,247,227,102,90,102,3,194,102,139,30,74,2,102,137,7, +131,195,4,102,15,182,6,13,0,102,43,194,102,59,193,15, +134,3,0,102,139,193,102,137,7,102,43,200,102,90,15,132, +117,0,102,3,194,102,80,102,51,210,102,15,182,30,13,0, +102,247,243,102,81,232,130,0,102,89,102,11,192,15,132,158, +249,102,15,182,30,13,0,102,247,227,102,139,30,74,2,102, +139,23,131,195,4,102,3,23,102,59,208,15,133,21,0,102, +15,182,6,13,0,102,59,193,15,134,3,0,102,139,193,102, +1,7,235,165,131,195,4,102,137,30,74,2,102,137,7,131, +195,4,102,15,182,6,13,0,102,59,193,15,134,3,0,102, +139,193,102,137,7,235,130,131,195,4,102,255,6,30,2,102, +137,30,74,2,102,91,3,95,4,102,129,63,128,0,0,0, +15,132,12,255,102,97,144,31,7,195,102,139,208,102,139,14, +30,2,102,139,54,90,2,102,3,54,82,2,102,82,102,81, +102,82,102,139,30,90,2,102,139,62,86,2,102,139,4,102, +163,16,0,131,198,4,102,139,4,163,14,0,131,198,4,30, +7,232,125,248,102,43,248,15,132,8,0,247,38,11,0,3, +216,235,217,102,139,62,90,2,30,7,232,194,253,102,161,90, +2,102,187,128,0,0,0,102,185,0,0,0,0,102,139,209, +232,186,251,102,11,192,15,132,181,248,102,139,216,102,88,102, +86,232,39,1,102,94,102,11,192,15,132,5,0,102,91,102, +91,195,102,89,102,90,226,132,102,51,192,195,6,30,102,96, +102,80,102,81,102,51,210,102,15,182,30,13,0,102,247,243, +102,82,102,87,232,83,255,102,95,102,11,192,15,132,111,248, +102,15,182,30,13,0,102,247,227,102,90,102,3,194,102,163, +16,0,102,89,102,15,182,30,13,0,102,59,203,15,142,19, +0,137,30,14,0,102,43,203,102,88,102,3,195,102,80,102, +81,235,20,144,102,88,102,3,193,102,80,137,14,14,0,102, +185,0,0,0,0,102,81,6,102,87,139,223,131,227,15,140, +192,102,193,239,4,3,199,80,7,232,165,247,102,95,7,102, +3,62,78,2,102,89,102,88,102,131,249,0,15,143,112,255, +102,97,144,31,7,195,6,30,102,96,102,247,38,86,2,102, +139,14,86,2,232,85,255,232,213,252,102,97,144,31,7,195, +6,30,102,96,102,247,38,102,2,102,139,30,50,2,102,139, +14,102,2,30,7,102,139,62,66,2,232,7,252,232,175,252, +102,97,144,31,7,195,102,80,102,83,102,81,102,139,30,70, +2,102,139,200,102,193,232,3,102,131,225,7,102,3,216,102, +184,1,0,0,0,102,211,224,103,132,3,15,132,4,0,248, +235,2,144,249,102,89,102,91,102,88,195,103,128,123,8,1, +15,132,4,0,102,43,192,195,103,102,141,115,16,103,102,139, +86,8,102,59,194,15,135,11,0,103,102,139,22,102,59,194, +15,131,4,0,102,43,192,195,103,3,94,16,102,43,246,103, +128,59,0,15,132,62,0,232,129,0,102,3,241,232,57,0, +102,3,202,102,59,193,15,140,33,0,102,139,209,102,80,103, +102,15,182,11,102,139,193,102,131,224,15,102,193,233,4,102, +3,217,102,3,216,102,67,102,88,235,196,102,43,200,102,43, +194,102,3,198,195,102,43,192,195,102,43,201,103,138,11,128, +225,15,102,131,249,0,15,133,4,0,102,43,201,195,102,83, +102,82,102,3,217,103,102,15,190,19,102,73,102,75,102,131, +249,0,15,132,13,0,102,193,226,8,103,138,19,102,75,102, +73,235,235,102,139,202,102,90,102,91,195,102,83,102,82,102, +43,210,103,138,19,102,131,226,15,102,43,201,103,138,11,192, +233,4,102,131,249,0,15,133,8,0,102,43,201,102,90,102, +91,195,102,3,218,102,3,217,103,102,15,190,19,102,73,102, +75,102,131,249,0,15,132,13,0,102,193,226,8,103,138,19, +102,75,102,73,235,235,102,139,202,102,90,102,91,195,102,11, +201,15,133,1,0,195,102,81,102,86,103,131,62,97,15,140, +12,0,103,131,62,122,15,143,4,0,103,131,46,32,102,131, +198,2,226,230,102,94,102,89,195,102,80,102,81,102,139,208, +102,161,46,2,103,102,141,88,16,103,3,67,4,103,102,141, +64,16,102,139,218,232,130,249,102,11,192,15,132,5,0,102, +89,102,89,195,102,161,50,2,102,11,192,15,133,8,0,102, +89,102,89,102,51,192,195,102,139,22,50,2,103,102,141,82, +16,103,102,139,66,8,102,64,102,139,30,78,2,102,247,227, +102,51,210,102,247,54,94,2,102,80,102,88,102,11,192,15, +132,48,0,102,72,102,80,232,28,254,114,238,232,241,253,102, +90,102,89,102,91,102,83,102,81,102,82,102,161,66,2,103, +102,141,64,24,232,19,249,102,11,192,116,206,102,89,102,89, +102,89,195,102,89,102,89,102,51,192,195,102,81,102,80,102, +184,5,0,0,0,30,7,102,139,249,232,153,253,102,139,193, +102,91,102,83,102,15,183,14,12,2,102,186,14,2,0,0, +232,122,248,102,91,102,89,102,11,192,15,133,47,0,102,139, +193,102,139,203,102,80,102,83,232,35,0,102,91,102,95,102, +11,192,15,132,23,0,30,7,232,91,253,102,139,199,102,15, +183,14,12,2,102,186,14,2,0,0,232,64,248,195,102,81, +102,187,32,0,0,0,102,185,0,0,0,0,102,186,0,0, +0,0,232,40,248,102,11,192,15,132,82,0,102,139,216,30, +7,102,139,62,22,2,232,189,248,30,7,102,139,30,22,2, +102,89,38,102,57,15,15,132,46,0,38,102,131,63,255,15, +132,45,0,38,131,127,4,0,15,132,36,0,38,102,15,183, +71,4,3,216,139,195,37,0,128,116,215,140,192,5,0,8, +142,192,129,227,255,127,235,202,38,102,139,71,16,195,102,89, +102,51,192,195,160,249,1,233,200,244,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +}; +```