![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
grove stream updated gerard 31/08
Dependencies: F7_Ethernet mbed MbedJSONValue LCD_DISCO_F746NG mbed-rtos BSP_DISCO_F746NG CANMsg NetworkAPI SDFileSystem_Warning_Fixed GroveStreamsmodified LcdDiscoF746NgTracer JSON
touchScreen.cpp@0:48863a0964f5, 2020-08-31 (annotated)
- Committer:
- 38domo
- Date:
- Mon Aug 31 19:19:48 2020 +0000
- Revision:
- 0:48863a0964f5
grove stream upated 31/08
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
38domo | 0:48863a0964f5 | 1 | |
38domo | 0:48863a0964f5 | 2 | #include "stm32746g_discovery_lcd.h" |
38domo | 0:48863a0964f5 | 3 | #include "stm32746g_discovery_ts.h" |
38domo | 0:48863a0964f5 | 4 | #include "mbed.h" |
38domo | 0:48863a0964f5 | 5 | #include "GroveStreams.h" |
38domo | 0:48863a0964f5 | 6 | #include "MbedJSONValue.h" |
38domo | 0:48863a0964f5 | 7 | |
38domo | 0:48863a0964f5 | 8 | int initDisplayTemp(); |
38domo | 0:48863a0964f5 | 9 | |
38domo | 0:48863a0964f5 | 10 | // GroveStreams Settings |
38domo | 0:48863a0964f5 | 11 | //extern const char gsApiKey[];// = "YOUR_SECRET_API_KEY_HERE"; //Change This!!! |
38domo | 0:48863a0964f5 | 12 | extern const char gsCompName[];// = "STM32F746+Discovery"; //Optionally change. Set this to give your component a name when it initially registers. Encode special chars such as spaces. |
38domo | 0:48863a0964f5 | 13 | |
38domo | 0:48863a0964f5 | 14 | extern const char gsCompTmplId[]; //Optional. Tells GS what template to use when the feed initially arrives and a new component needs to be created. |
38domo | 0:48863a0964f5 | 15 | |
38domo | 0:48863a0964f5 | 16 | ////GroveStreams groveStreams(gsApiKey, &lcd); |
38domo | 0:48863a0964f5 | 17 | extern GroveStreams groveStreams; |
38domo | 0:48863a0964f5 | 18 | |
38domo | 0:48863a0964f5 | 19 | extern const char* myMac; |
38domo | 0:48863a0964f5 | 20 | |
38domo | 0:48863a0964f5 | 21 | extern time_t seconds; |
38domo | 0:48863a0964f5 | 22 | time_t seconds_touches = 0; |
38domo | 0:48863a0964f5 | 23 | extern time_t lastToucheTime; |
38domo | 0:48863a0964f5 | 24 | |
38domo | 0:48863a0964f5 | 25 | int touchInitJPA1() |
38domo | 0:48863a0964f5 | 26 | { //touch screen init |
38domo | 0:48863a0964f5 | 27 | //touch screen |
38domo | 0:48863a0964f5 | 28 | uint8_t status; |
38domo | 0:48863a0964f5 | 29 | BSP_LCD_Init(); |
38domo | 0:48863a0964f5 | 30 | BSP_LCD_LayerDefaultInit(LTDC_ACTIVE_LAYER, LCD_FB_START_ADDRESS); |
38domo | 0:48863a0964f5 | 31 | BSP_LCD_SelectLayer(LTDC_ACTIVE_LAYER); |
38domo | 0:48863a0964f5 | 32 | BSP_LCD_SetFont(&Font12); |
38domo | 0:48863a0964f5 | 33 | status = BSP_TS_Init(BSP_LCD_GetXSize(), BSP_LCD_GetYSize()); |
38domo | 0:48863a0964f5 | 34 | if (status != TS_OK) { |
38domo | 0:48863a0964f5 | 35 | BSP_LCD_Clear(LCD_COLOR_RED); |
38domo | 0:48863a0964f5 | 36 | BSP_LCD_SetBackColor(LCD_COLOR_RED); |
38domo | 0:48863a0964f5 | 37 | BSP_LCD_SetTextColor(LCD_COLOR_WHITE); |
38domo | 0:48863a0964f5 | 38 | BSP_LCD_DisplayStringAt(0, LINE(5), (uint8_t *)"TOUCHSCREEN INIT FAIL", CENTER_MODE); |
38domo | 0:48863a0964f5 | 39 | } |
38domo | 0:48863a0964f5 | 40 | else { |
38domo | 0:48863a0964f5 | 41 | BSP_LCD_Clear(LCD_COLOR_DARKBLUE); |
38domo | 0:48863a0964f5 | 42 | BSP_LCD_SetBackColor(LCD_COLOR_BLACK); |
38domo | 0:48863a0964f5 | 43 | BSP_LCD_SetTextColor(LCD_COLOR_GREEN); |
38domo | 0:48863a0964f5 | 44 | //BSP_LCD_DisplayStringAt(0, LINE(5), (uint8_t *)"TOUCHSCREEN INIT OK", CENTER_MODE); |
38domo | 0:48863a0964f5 | 45 | } |
38domo | 0:48863a0964f5 | 46 | |
38domo | 0:48863a0964f5 | 47 | return 0; |
38domo | 0:48863a0964f5 | 48 | } |
38domo | 0:48863a0964f5 | 49 | |
38domo | 0:48863a0964f5 | 50 | int xButton[5],yButton[5],dxButton[5],dyButton[5],xTxtButton[5],yTxtButton[5]; |
38domo | 0:48863a0964f5 | 51 | uint32_t backColorButton[5], txtColorButton[5]; |
38domo | 0:48863a0964f5 | 52 | char textButton[5][30]; |
38domo | 0:48863a0964f5 | 53 | char text1Button[5][30]; |
38domo | 0:48863a0964f5 | 54 | char statusButton[5][30]; |
38domo | 0:48863a0964f5 | 55 | |
38domo | 0:48863a0964f5 | 56 | int touchButtonJPA1(int numButton) |
38domo | 0:48863a0964f5 | 57 | { |
38domo | 0:48863a0964f5 | 58 | if ((numButton > 0) && (numButton < 5)) |
38domo | 0:48863a0964f5 | 59 | { |
38domo | 0:48863a0964f5 | 60 | BSP_LCD_SetBackColor(backColorButton[numButton]); |
38domo | 0:48863a0964f5 | 61 | BSP_LCD_SetTextColor(backColorButton[numButton]); |
38domo | 0:48863a0964f5 | 62 | BSP_LCD_FillRect(xButton[numButton], yButton[numButton], dxButton[numButton], dyButton[numButton]); |
38domo | 0:48863a0964f5 | 63 | BSP_LCD_SetTextColor(txtColorButton[numButton]); |
38domo | 0:48863a0964f5 | 64 | BSP_LCD_DrawRect(xButton[numButton], yButton[numButton], dxButton[numButton], dyButton[numButton]); |
38domo | 0:48863a0964f5 | 65 | BSP_LCD_SetFont(&Font20); |
38domo | 0:48863a0964f5 | 66 | BSP_LCD_DisplayStringAt(xTxtButton[numButton]+52, yTxtButton[numButton], (uint8_t *)statusButton[numButton], LEFT_MODE); |
38domo | 0:48863a0964f5 | 67 | BSP_LCD_DisplayStringAt(xTxtButton[numButton], yTxtButton[numButton]+28, (uint8_t *)textButton[numButton], LEFT_MODE); |
38domo | 0:48863a0964f5 | 68 | BSP_LCD_DisplayStringAt(xTxtButton[numButton], yTxtButton[numButton]+48, (uint8_t *)text1Button[numButton], LEFT_MODE); |
38domo | 0:48863a0964f5 | 69 | } |
38domo | 0:48863a0964f5 | 70 | return 0; |
38domo | 0:48863a0964f5 | 71 | } |
38domo | 0:48863a0964f5 | 72 | |
38domo | 0:48863a0964f5 | 73 | |
38domo | 0:48863a0964f5 | 74 | // generation de fonts : http://omz-software.com/pythonista/docs/ios/ImageFont.html |
38domo | 0:48863a0964f5 | 75 | int touchInitGuiJPA1() |
38domo | 0:48863a0964f5 | 76 | { |
38domo | 0:48863a0964f5 | 77 | xButton[1]=10;yButton[1]=185;dxButton[1]=100;dyButton[1]=80;xTxtButton[1]=12;yTxtButton[1]=190; |
38domo | 0:48863a0964f5 | 78 | backColorButton[1] = LCD_COLOR_GRAY; txtColorButton[1] = LCD_COLOR_GREEN; |
38domo | 0:48863a0964f5 | 79 | sprintf(textButton[1],"Lampe "); |
38domo | 0:48863a0964f5 | 80 | sprintf(text1Button[1],"Sejour"); |
38domo | 0:48863a0964f5 | 81 | sprintf(statusButton[1],"off"); |
38domo | 0:48863a0964f5 | 82 | |
38domo | 0:48863a0964f5 | 83 | xButton[2]=130;yButton[2]=185;dxButton[2]=100;dyButton[2]=80;xTxtButton[2]=132;yTxtButton[2]=190; |
38domo | 0:48863a0964f5 | 84 | backColorButton[2] = LCD_COLOR_GRAY; txtColorButton[2] = LCD_COLOR_GREEN; |
38domo | 0:48863a0964f5 | 85 | sprintf(textButton[2],"Lampe "); |
38domo | 0:48863a0964f5 | 86 | sprintf(text1Button[2],"Sejours"); |
38domo | 0:48863a0964f5 | 87 | sprintf(statusButton[2],"off"); |
38domo | 0:48863a0964f5 | 88 | |
38domo | 0:48863a0964f5 | 89 | xButton[3]=250;yButton[3]=185;dxButton[3]=100;dyButton[3]=80;xTxtButton[3]=252;yTxtButton[3]=190; |
38domo | 0:48863a0964f5 | 90 | backColorButton[3] = LCD_COLOR_GRAY; txtColorButton[3] = LCD_COLOR_GREEN; |
38domo | 0:48863a0964f5 | 91 | sprintf(textButton[3],"Lampe "); |
38domo | 0:48863a0964f5 | 92 | sprintf(text1Button[3],"Sejour"); |
38domo | 0:48863a0964f5 | 93 | sprintf(statusButton[3],"off"); |
38domo | 0:48863a0964f5 | 94 | |
38domo | 0:48863a0964f5 | 95 | xButton[4]=370;yButton[4]=185;dxButton[4]=100;dyButton[4]=80;xTxtButton[4]=372;yTxtButton[4]=190; |
38domo | 0:48863a0964f5 | 96 | backColorButton[4] = LCD_COLOR_GRAY; txtColorButton[4] = LCD_COLOR_GREEN; |
38domo | 0:48863a0964f5 | 97 | sprintf(textButton[4],"Lampe "); |
38domo | 0:48863a0964f5 | 98 | sprintf(text1Button[4],"Sejour"); |
38domo | 0:48863a0964f5 | 99 | sprintf(statusButton[4],"off"); |
38domo | 0:48863a0964f5 | 100 | |
38domo | 0:48863a0964f5 | 101 | touchButtonJPA1(1); |
38domo | 0:48863a0964f5 | 102 | touchButtonJPA1(2); |
38domo | 0:48863a0964f5 | 103 | touchButtonJPA1(3); |
38domo | 0:48863a0964f5 | 104 | touchButtonJPA1(4); |
38domo | 0:48863a0964f5 | 105 | |
38domo | 0:48863a0964f5 | 106 | BSP_LCD_SetFont(&FontFreeMono64); |
38domo | 0:48863a0964f5 | 107 | //BSP_LCD_DisplayStringAt(20, 30, (uint8_t *)"0123456789", LEFT_MODE); |
38domo | 0:48863a0964f5 | 108 | //BSP_LCD_DisplayCharJPA(20, 90, '8'); |
38domo | 0:48863a0964f5 | 109 | BSP_LCD_SetFont(&Font12); |
38domo | 0:48863a0964f5 | 110 | return 0; |
38domo | 0:48863a0964f5 | 111 | } |
38domo | 0:48863a0964f5 | 112 | |
38domo | 0:48863a0964f5 | 113 | int touchJPA1() |
38domo | 0:48863a0964f5 | 114 | { |
38domo | 0:48863a0964f5 | 115 | //touch screen |
38domo | 0:48863a0964f5 | 116 | TS_StateTypeDef TS_State; |
38domo | 0:48863a0964f5 | 117 | uint16_t x, y; |
38domo | 0:48863a0964f5 | 118 | uint8_t text[30]; |
38domo | 0:48863a0964f5 | 119 | uint8_t status = 0; |
38domo | 0:48863a0964f5 | 120 | uint8_t idx; |
38domo | 0:48863a0964f5 | 121 | static uint8_t cleared = 0; |
38domo | 0:48863a0964f5 | 122 | uint8_t prev_nb_touches = 0; |
38domo | 0:48863a0964f5 | 123 | |
38domo | 0:48863a0964f5 | 124 | |
38domo | 0:48863a0964f5 | 125 | //touch screen |
38domo | 0:48863a0964f5 | 126 | BSP_TS_GetState(&TS_State); |
38domo | 0:48863a0964f5 | 127 | if (TS_State.touchDetected) { |
38domo | 0:48863a0964f5 | 128 | // Clear lines corresponding to old touches coordinates |
38domo | 0:48863a0964f5 | 129 | if (TS_State.touchDetected < prev_nb_touches) { |
38domo | 0:48863a0964f5 | 130 | for (idx = (TS_State.touchDetected + 1); idx <= 5; idx++) { |
38domo | 0:48863a0964f5 | 131 | //BSP_LCD_ClearStringLine(idx); |
38domo | 0:48863a0964f5 | 132 | } |
38domo | 0:48863a0964f5 | 133 | } |
38domo | 0:48863a0964f5 | 134 | prev_nb_touches = TS_State.touchDetected; |
38domo | 0:48863a0964f5 | 135 | |
38domo | 0:48863a0964f5 | 136 | cleared = 0; |
38domo | 0:48863a0964f5 | 137 | |
38domo | 0:48863a0964f5 | 138 | //sprintf((char*)text, "Touches: %d", TS_State.touchDetected); |
38domo | 0:48863a0964f5 | 139 | //BSP_LCD_DisplayStringAt(0, LINE(0), (uint8_t *)&text, LEFT_MODE); |
38domo | 0:48863a0964f5 | 140 | |
38domo | 0:48863a0964f5 | 141 | for (idx = 0; idx < TS_State.touchDetected; idx++) { |
38domo | 0:48863a0964f5 | 142 | x = TS_State.touchX[idx]; |
38domo | 0:48863a0964f5 | 143 | y = TS_State.touchY[idx]; |
38domo | 0:48863a0964f5 | 144 | //sprintf((char*)text, "Touch %d: x=%d y=%d ", idx+1, x, y); |
38domo | 0:48863a0964f5 | 145 | //BSP_LCD_DisplayStringAt(0, LINE(idx+1), (uint8_t *)&text, LEFT_MODE); |
38domo | 0:48863a0964f5 | 146 | } |
38domo | 0:48863a0964f5 | 147 | |
38domo | 0:48863a0964f5 | 148 | //BSP_LCD_DrawPixel(TS_State.touchX[0], TS_State.touchY[0], LCD_COLOR_ORANGE); |
38domo | 0:48863a0964f5 | 149 | |
38domo | 0:48863a0964f5 | 150 | if ((TS_State.touchY[0] > 160) && (TS_State.touchY[0] < (160+80))) |
38domo | 0:48863a0964f5 | 151 | { |
38domo | 0:48863a0964f5 | 152 | int numTouche = 0; |
38domo | 0:48863a0964f5 | 153 | if ((TS_State.touchX[0] > 10) && (TS_State.touchX[0] < (10+100))) {numTouche = 1;} |
38domo | 0:48863a0964f5 | 154 | if ((TS_State.touchX[0] > 130) && (TS_State.touchX[0] < (130+100))) {numTouche = 2;} |
38domo | 0:48863a0964f5 | 155 | if ((TS_State.touchX[0] > 250) && (TS_State.touchX[0] < (250+100))) {numTouche = 3;} |
38domo | 0:48863a0964f5 | 156 | if ((TS_State.touchX[0] > 370) && (TS_State.touchX[0] < (370+100))) {numTouche = 4;} |
38domo | 0:48863a0964f5 | 157 | if (numTouche >0) |
38domo | 0:48863a0964f5 | 158 | { |
38domo | 0:48863a0964f5 | 159 | printf("Touche : %d", numTouche); |
38domo | 0:48863a0964f5 | 160 | sprintf((char*)text, "Touche : %d", numTouche); |
38domo | 0:48863a0964f5 | 161 | //BSP_LCD_DisplayStringAt(200,0, (uint8_t *)&text, LEFT_MODE); |
38domo | 0:48863a0964f5 | 162 | status = numTouche; |
38domo | 0:48863a0964f5 | 163 | } |
38domo | 0:48863a0964f5 | 164 | else {lastToucheTime = 0;} |
38domo | 0:48863a0964f5 | 165 | } |
38domo | 0:48863a0964f5 | 166 | } else { |
38domo | 0:48863a0964f5 | 167 | lastToucheTime = 0; |
38domo | 0:48863a0964f5 | 168 | if (!cleared) { |
38domo | 0:48863a0964f5 | 169 | //BSP_LCD_Clear(LCD_COLOR_DARKBLUE); |
38domo | 0:48863a0964f5 | 170 | //sprintf((char*)text, "Touches: 0"); |
38domo | 0:48863a0964f5 | 171 | //BSP_LCD_DisplayStringAt(0, LINE(0), (uint8_t *)&text, LEFT_MODE); |
38domo | 0:48863a0964f5 | 172 | //cleared = 1; |
38domo | 0:48863a0964f5 | 173 | //int ss = touchInitGuiJPA1(); |
38domo | 0:48863a0964f5 | 174 | //ss=initDisplayTemp(); |
38domo | 0:48863a0964f5 | 175 | } |
38domo | 0:48863a0964f5 | 176 | } |
38domo | 0:48863a0964f5 | 177 | //touch screen |
38domo | 0:48863a0964f5 | 178 | return status; |
38domo | 0:48863a0964f5 | 179 | } |
38domo | 0:48863a0964f5 | 180 | |
38domo | 0:48863a0964f5 | 181 | int sendTouchJPA(int xx) |
38domo | 0:48863a0964f5 | 182 | { |
38domo | 0:48863a0964f5 | 183 | uint8_t status = 0; |
38domo | 0:48863a0964f5 | 184 | seconds = time(NULL); |
38domo | 0:48863a0964f5 | 185 | if((seconds - lastToucheTime) > 1) |
38domo | 0:48863a0964f5 | 186 | { |
38domo | 0:48863a0964f5 | 187 | char samples[64] = {0};char resultBuffer[2000]= {0}; |
38domo | 0:48863a0964f5 | 188 | sprintf(samples,"&Touche=%i",xx); |
38domo | 0:48863a0964f5 | 189 | printf("\nSend Touche=%i\n",xx); |
38domo | 0:48863a0964f5 | 190 | int sendResult = groveStreams.sendJPA(myMac, samples, gsCompName, gsCompTmplId, resultBuffer, sizeof resultBuffer); |
38domo | 0:48863a0964f5 | 191 | if (sendResult == 0) { |
38domo | 0:48863a0964f5 | 192 | ////lcd.printf("Send Successful"); |
38domo | 0:48863a0964f5 | 193 | printf("Send Successful\n"); |
38domo | 0:48863a0964f5 | 194 | if (strlen(resultBuffer) > 0) { |
38domo | 0:48863a0964f5 | 195 | //printf("HTTP string : %s\n", resultBuffer); |
38domo | 0:48863a0964f5 | 196 | MbedJSONValue mbedJson; |
38domo | 0:48863a0964f5 | 197 | parse(mbedJson, resultBuffer); |
38domo | 0:48863a0964f5 | 198 | |
38domo | 0:48863a0964f5 | 199 | int displayOn = 0; |
38domo | 0:48863a0964f5 | 200 | string s; |
38domo | 0:48863a0964f5 | 201 | if (mbedJson.hasMember("Touche1")) { |
38domo | 0:48863a0964f5 | 202 | s = mbedJson["Touche1"]["BackColor"].get<std::string>(); |
38domo | 0:48863a0964f5 | 203 | backColorButton[1] = (uint32_t)strtoul(s.c_str(), NULL,16); |
38domo | 0:48863a0964f5 | 204 | s = mbedJson["Touche1"]["TextColor"].get<std::string>(); |
38domo | 0:48863a0964f5 | 205 | txtColorButton[1] = (uint32_t)strtoul(s.c_str(), NULL,16); |
38domo | 0:48863a0964f5 | 206 | s = mbedJson["Touche1"]["Status"].get<std::string>(); |
38domo | 0:48863a0964f5 | 207 | sprintf(statusButton[1],s.c_str()); |
38domo | 0:48863a0964f5 | 208 | displayOn = (0x02 | displayOn);} |
38domo | 0:48863a0964f5 | 209 | |
38domo | 0:48863a0964f5 | 210 | if (mbedJson.hasMember("Touche2")) { |
38domo | 0:48863a0964f5 | 211 | s = mbedJson["Touche2"]["BackColor"].get<std::string>(); |
38domo | 0:48863a0964f5 | 212 | backColorButton[2] = (uint32_t)strtoul(s.c_str(), NULL,16); |
38domo | 0:48863a0964f5 | 213 | s = mbedJson["Touche2"]["TextColor"].get<std::string>(); |
38domo | 0:48863a0964f5 | 214 | txtColorButton[2] = (uint32_t)strtoul(s.c_str(), NULL,16); |
38domo | 0:48863a0964f5 | 215 | s = mbedJson["Touche2"]["Status"].get<std::string>(); |
38domo | 0:48863a0964f5 | 216 | sprintf(statusButton[2],s.c_str()); |
38domo | 0:48863a0964f5 | 217 | displayOn = (0x04 | displayOn);} |
38domo | 0:48863a0964f5 | 218 | |
38domo | 0:48863a0964f5 | 219 | if (mbedJson.hasMember("Touche3")) { |
38domo | 0:48863a0964f5 | 220 | s = mbedJson["Touche3"]["BackColor"].get<std::string>(); |
38domo | 0:48863a0964f5 | 221 | backColorButton[3] = (uint32_t)strtoul(s.c_str(), NULL,16); |
38domo | 0:48863a0964f5 | 222 | s = mbedJson["Touche3"]["TextColor"].get<std::string>(); |
38domo | 0:48863a0964f5 | 223 | txtColorButton[3] = (uint32_t)strtoul(s.c_str(), NULL,16); |
38domo | 0:48863a0964f5 | 224 | s = mbedJson["Touche3"]["Status"].get<std::string>(); |
38domo | 0:48863a0964f5 | 225 | sprintf(statusButton[3],s.c_str()); |
38domo | 0:48863a0964f5 | 226 | displayOn = (0x08 | displayOn);} |
38domo | 0:48863a0964f5 | 227 | |
38domo | 0:48863a0964f5 | 228 | if (mbedJson.hasMember("Touche4")) { |
38domo | 0:48863a0964f5 | 229 | s = mbedJson["Touche4"]["BackColor"].get<std::string>(); |
38domo | 0:48863a0964f5 | 230 | backColorButton[4] = (uint32_t)strtoul(s.c_str(), NULL,16); |
38domo | 0:48863a0964f5 | 231 | s = mbedJson["Touche4"]["TextColor"].get<std::string>(); |
38domo | 0:48863a0964f5 | 232 | txtColorButton[4] = (uint32_t)strtoul(s.c_str(), NULL,16); |
38domo | 0:48863a0964f5 | 233 | s = mbedJson["Touche4"]["Status"].get<std::string>(); |
38domo | 0:48863a0964f5 | 234 | sprintf(statusButton[4],s.c_str()); |
38domo | 0:48863a0964f5 | 235 | displayOn = (0x10 | displayOn);} |
38domo | 0:48863a0964f5 | 236 | |
38domo | 0:48863a0964f5 | 237 | if ((displayOn & 0x02) > 0) {touchButtonJPA1(1);} |
38domo | 0:48863a0964f5 | 238 | if ((displayOn & 0x04) > 0) {touchButtonJPA1(2);} |
38domo | 0:48863a0964f5 | 239 | if ((displayOn & 0x08) > 0) {touchButtonJPA1(3);} |
38domo | 0:48863a0964f5 | 240 | if ((displayOn & 0x10) > 0) {touchButtonJPA1(4);} |
38domo | 0:48863a0964f5 | 241 | } |
38domo | 0:48863a0964f5 | 242 | } |
38domo | 0:48863a0964f5 | 243 | } |
38domo | 0:48863a0964f5 | 244 | |
38domo | 0:48863a0964f5 | 245 | return status; |
38domo | 0:48863a0964f5 | 246 | } |