Ghost Mouse / Mbed 2 deprecated ghost_mouse

Dependencies:   mbed

Committer:
jennabarton
Date:
Sun Apr 02 21:33:40 2017 +0000
Revision:
13:4f2181174071
Parent:
12:e127fa20d609
Child:
14:568d4dac4fb6
pre ticker update

Who changed what in which revision?

UserRevisionLine numberNew contents of line
daviwang 0:1c15cf9cc4f9 1 #include "mbed.h"
daviwang 0:1c15cf9cc4f9 2
jennabarton 8:d27efcac2dd7 3 //******************************************************************
jennabarton 8:d27efcac2dd7 4 // All variables defined below
jennabarton 8:d27efcac2dd7 5 //******************************************************************
jennabarton 8:d27efcac2dd7 6
jennabarton 8:d27efcac2dd7 7 //communication
daviwang 0:1c15cf9cc4f9 8 DigitalOut myled(LED1);
daviwang 1:2e895e5272ab 9 Serial pc(USBTX, USBRX);
jennabarton 4:1f443e7a0122 10 Serial keyOut(p13, p14);
daviwang 1:2e895e5272ab 11 I2C camera1(p9, p10);
daviwang 1:2e895e5272ab 12
jennabarton 2:f501e506d62b 13 //initial camera data
daviwang 1:2e895e5272ab 14 int IRsensorAddress = 0xB0;
daviwang 1:2e895e5272ab 15 int slaveAddress;
daviwang 1:2e895e5272ab 16 char data_buf[16];
jennabarton 2:f501e506d62b 17 char s;
daviwang 1:2e895e5272ab 18 int i;
daviwang 1:2e895e5272ab 19
jennabarton 2:f501e506d62b 20 //point variables
jennabarton 2:f501e506d62b 21 int point1x = 0;
jennabarton 2:f501e506d62b 22 int point1y = 0;
jennabarton 2:f501e506d62b 23 int point2x = 0;
jennabarton 2:f501e506d62b 24 int point2y = 0;
jennabarton 2:f501e506d62b 25 int point3x = 0;
jennabarton 2:f501e506d62b 26 int point3y = 0;
jennabarton 2:f501e506d62b 27 int point4x = 0;
jennabarton 2:f501e506d62b 28 int point4y = 0;
jennabarton 2:f501e506d62b 29
daviwang 1:2e895e5272ab 30 //sensitivity
daviwang 1:2e895e5272ab 31 //Level 5: p0 = 0x96, p1 = 0xFE, p2 = 0xFE, p3 = 0x05
jennabarton 8:d27efcac2dd7 32 //highest sensitivity to more accurately detect points
daviwang 1:2e895e5272ab 33 int sen0 = 0x96;
daviwang 1:2e895e5272ab 34 int sen1 = 0xFE;
daviwang 1:2e895e5272ab 35 int sen2 = 0xFE;
daviwang 1:2e895e5272ab 36 int sen3 = 0x00;
daviwang 1:2e895e5272ab 37
jennabarton 12:e127fa20d609 38 //previous point values
jennabarton 12:e127fa20d609 39 int prevX = 1023;
jennabarton 12:e127fa20d609 40 int prevY = 1023;
jennabarton 12:e127fa20d609 41
jennabarton 8:d27efcac2dd7 42 //matrices of x and y coordinates from the first camera
jennabarton 2:f501e506d62b 43 int onex[4];
jennabarton 2:f501e506d62b 44 int oney[4];
daviwang 1:2e895e5272ab 45
jennabarton 12:e127fa20d609 46 //matrices of x and y coordinates from prev point
jennabarton 12:e127fa20d609 47 int prevx[4];
jennabarton 12:e127fa20d609 48 int prevy[4];
jennabarton 12:e127fa20d609 49
jennabarton 12:e127fa20d609 50 //movement
jennabarton 12:e127fa20d609 51 int deadzone = 5;
jennabarton 12:e127fa20d609 52
jennabarton 12:e127fa20d609 53 //counts for clicks
jennabarton 12:e127fa20d609 54 int clickDeadzone = 10;
jennabarton 12:e127fa20d609 55 int fingerDownCount = 0;
jennabarton 12:e127fa20d609 56 int fingerUpCount = 0;
jennabarton 12:e127fa20d609 57 int minLeftClickDur = 4;
jennabarton 12:e127fa20d609 58 int minRightClickDur = 10;
jennabarton 12:e127fa20d609 59 int delayForClick = 2;
jennabarton 12:e127fa20d609 60 int instabilityLimit = 3;
jennabarton 12:e127fa20d609 61 int instabilityCount = 0;
jennabarton 13:4f2181174071 62
jennabarton 13:4f2181174071 63
jennabarton 13:4f2181174071 64
jennabarton 8:d27efcac2dd7 65 //******************************************************************
jennabarton 8:d27efcac2dd7 66 // All methods defined below
jennabarton 8:d27efcac2dd7 67 //******************************************************************
daviwang 1:2e895e5272ab 68
jennabarton 12:e127fa20d609 69 //takes in values for the movement in the x and y direction
jennabarton 12:e127fa20d609 70 //also can indicate whether you want to "click"
jennabarton 12:e127fa20d609 71 //NOTE: hard coded wait of 0.1
jennabarton 10:d67a15ba5748 72 void mouseCommand(char buttons, char x, char y) {
jennabarton 10:d67a15ba5748 73 keyOut.putc(0xFD);
jennabarton 10:d67a15ba5748 74 keyOut.putc(0x00);
jennabarton 10:d67a15ba5748 75 keyOut.putc(0x03);
jennabarton 10:d67a15ba5748 76 keyOut.putc(buttons);
jennabarton 10:d67a15ba5748 77 keyOut.putc(x);
jennabarton 10:d67a15ba5748 78 keyOut.putc(y);
jennabarton 10:d67a15ba5748 79 keyOut.putc(0x00);
jennabarton 10:d67a15ba5748 80 keyOut.putc(0x00);
jennabarton 10:d67a15ba5748 81 keyOut.putc(0x00);
jennabarton 10:d67a15ba5748 82
jennabarton 10:d67a15ba5748 83 //delay for pushing data
jennabarton 12:e127fa20d609 84 wait(0.1); //how large does this need to be?
jennabarton 10:d67a15ba5748 85 }
jennabarton 10:d67a15ba5748 86
jennabarton 4:1f443e7a0122 87
jennabarton 12:e127fa20d609 88 //moves mouse on screen from one finger input
jennabarton 12:e127fa20d609 89 //param
jennabarton 12:e127fa20d609 90 // current point (currx, curry)
jennabarton 12:e127fa20d609 91 // previous point (prevx, prevy)
jennabarton 12:e127fa20d609 92 void oneFingerResponse(int currx, int curry, int prevx, int prevy){
jennabarton 12:e127fa20d609 93 //look at delta btwn prev val and current
jennabarton 12:e127fa20d609 94 //TODO: moving average
jennabarton 12:e127fa20d609 95 if((prevx != 1023 || prevy != 1023) && (currx != 1023 && curry != 1023)){
jennabarton 12:e127fa20d609 96 int diffX = currx - prevx;
jennabarton 12:e127fa20d609 97 int diffY = -1*(curry - prevy);
jennabarton 12:e127fa20d609 98
jennabarton 12:e127fa20d609 99 //fix diffX
jennabarton 12:e127fa20d609 100 if(diffX > deadzone){
jennabarton 12:e127fa20d609 101 diffX -= deadzone;
jennabarton 12:e127fa20d609 102 } else if (diffX < -1*deadzone){
jennabarton 12:e127fa20d609 103 diffX += deadzone;
jennabarton 12:e127fa20d609 104 } else{
jennabarton 12:e127fa20d609 105 diffX = 0;
jennabarton 12:e127fa20d609 106 }
jennabarton 12:e127fa20d609 107 //fix diffY
jennabarton 12:e127fa20d609 108 if(diffY > deadzone){
jennabarton 12:e127fa20d609 109 diffY -= deadzone;
jennabarton 12:e127fa20d609 110 } else if (diffX < -1*deadzone){
jennabarton 12:e127fa20d609 111 diffY += deadzone;
jennabarton 12:e127fa20d609 112 } else{
jennabarton 12:e127fa20d609 113 diffY = 0;
jennabarton 12:e127fa20d609 114 }
jennabarton 12:e127fa20d609 115
jennabarton 12:e127fa20d609 116 //move x and y
jennabarton 12:e127fa20d609 117 mouseCommand(0, (char) diffX, (char) diffY);
jennabarton 12:e127fa20d609 118 }
jennabarton 12:e127fa20d609 119 }
jennabarton 12:e127fa20d609 120
jennabarton 12:e127fa20d609 121
jennabarton 12:e127fa20d609 122 //writes two bytes to the camera
jennabarton 12:e127fa20d609 123 void write2bytes(char data1, char data2){
jennabarton 12:e127fa20d609 124 char out[2];
jennabarton 12:e127fa20d609 125 out[0] = data1;
jennabarton 12:e127fa20d609 126 out[1] = data2;
jennabarton 12:e127fa20d609 127 camera1.write(slaveAddress, out, 2);
jennabarton 12:e127fa20d609 128 wait(0.01);
jennabarton 12:e127fa20d609 129 }
jennabarton 12:e127fa20d609 130
jennabarton 12:e127fa20d609 131
jennabarton 12:e127fa20d609 132
jennabarton 8:d27efcac2dd7 133 // Initialize WiiMote Camera
daviwang 1:2e895e5272ab 134 void initCamera(void){
daviwang 1:2e895e5272ab 135 write2bytes(0x30, 0x01);
daviwang 1:2e895e5272ab 136 write2bytes(0x00, 0x02);
daviwang 1:2e895e5272ab 137 write2bytes(0x00, 0x00);
daviwang 1:2e895e5272ab 138 write2bytes(0x71, 0x01);
daviwang 1:2e895e5272ab 139 write2bytes(0x00, sen0);
daviwang 1:2e895e5272ab 140 write2bytes(0x07, 0x00);
daviwang 1:2e895e5272ab 141 write2bytes(sen1, 0x1A);
daviwang 1:2e895e5272ab 142 write2bytes(sen2, sen3);
daviwang 1:2e895e5272ab 143 write2bytes(0x33, 0x03);
daviwang 1:2e895e5272ab 144 write2bytes(0x30, 0x08);
jennabarton 3:7b0c215eb6a7 145 //wait(0.1);
daviwang 1:2e895e5272ab 146
daviwang 1:2e895e5272ab 147 }
daviwang 0:1c15cf9cc4f9 148
jennabarton 12:e127fa20d609 149
jennabarton 12:e127fa20d609 150 //update counts for click
jennabarton 12:e127fa20d609 151 void updateClickState(int currx, int curry, int prevx, int prevy){
jennabarton 12:e127fa20d609 152 bool xStable = false;
jennabarton 12:e127fa20d609 153 bool yStable = false;
jennabarton 12:e127fa20d609 154
jennabarton 12:e127fa20d609 155 //TODO: update to handle cases where just one is 1023
jennabarton 12:e127fa20d609 156 if(currx != 1023 || curry != 1023){
jennabarton 12:e127fa20d609 157 //check x stability
jennabarton 12:e127fa20d609 158 if( currx > prevx ){
jennabarton 12:e127fa20d609 159 if(currx-prevx < clickDeadzone){
jennabarton 12:e127fa20d609 160 //barely moved in x dir
jennabarton 12:e127fa20d609 161 xStable = true;
jennabarton 12:e127fa20d609 162 }
jennabarton 12:e127fa20d609 163 } else if( currx < prevx) {
jennabarton 12:e127fa20d609 164 if(prevx-currx < clickDeadzone){
jennabarton 12:e127fa20d609 165 //barely moved in x dir
jennabarton 12:e127fa20d609 166 xStable = true;
jennabarton 12:e127fa20d609 167 }
jennabarton 12:e127fa20d609 168 } else {
jennabarton 12:e127fa20d609 169 //no movement in x
jennabarton 12:e127fa20d609 170 xStable = true;
jennabarton 12:e127fa20d609 171 }
jennabarton 12:e127fa20d609 172
jennabarton 12:e127fa20d609 173 //check y stability
jennabarton 12:e127fa20d609 174 if( curry > prevy ){
jennabarton 12:e127fa20d609 175 if(curry-prevy < clickDeadzone){
jennabarton 12:e127fa20d609 176 //barely moved in y dir
jennabarton 12:e127fa20d609 177 yStable = true;
jennabarton 12:e127fa20d609 178 }
jennabarton 12:e127fa20d609 179 } else if( curry < prevy) {
jennabarton 12:e127fa20d609 180 if(prevy-curry < clickDeadzone){
jennabarton 12:e127fa20d609 181 //barely moved in y dir
jennabarton 12:e127fa20d609 182 yStable = true;
jennabarton 12:e127fa20d609 183 }
jennabarton 12:e127fa20d609 184 } else {
jennabarton 12:e127fa20d609 185 //no movement in y
jennabarton 12:e127fa20d609 186 yStable = true;
jennabarton 12:e127fa20d609 187 }
jennabarton 12:e127fa20d609 188
jennabarton 12:e127fa20d609 189 //update finger down count
jennabarton 12:e127fa20d609 190 if(xStable && yStable){
jennabarton 12:e127fa20d609 191 //both are stable
jennabarton 12:e127fa20d609 192 fingerDownCount++;
jennabarton 12:e127fa20d609 193 //pc.printf("finger down \t");
jennabarton 12:e127fa20d609 194
jennabarton 12:e127fa20d609 195 } else{
jennabarton 12:e127fa20d609 196 //unstable, increase instability count
jennabarton 12:e127fa20d609 197 instabilityCount++;
jennabarton 12:e127fa20d609 198 if(instabilityCount > instabilityLimit){
jennabarton 12:e127fa20d609 199 //too many instable points, reset to zero
jennabarton 12:e127fa20d609 200 fingerDownCount = 0;
jennabarton 12:e127fa20d609 201 instabilityCount = 0;
jennabarton 12:e127fa20d609 202 }
jennabarton 12:e127fa20d609 203 }
jennabarton 12:e127fa20d609 204
jennabarton 12:e127fa20d609 205 } else {
jennabarton 12:e127fa20d609 206 //both are up, increment up count
jennabarton 12:e127fa20d609 207 fingerUpCount++;
jennabarton 12:e127fa20d609 208 if(fingerUpCount >= delayForClick && fingerDownCount >= minLeftClickDur){
jennabarton 12:e127fa20d609 209 //finger was down for long enough to be a click
jennabarton 12:e127fa20d609 210 //finger was lifted for long enough to indicate click
jennabarton 12:e127fa20d609 211 if(fingerDownCount >= minRightClickDur){
jennabarton 12:e127fa20d609 212 //initiate right click
jennabarton 12:e127fa20d609 213 mouseCommand(0x02, 0 , 0);
jennabarton 12:e127fa20d609 214
jennabarton 12:e127fa20d609 215 //TODO: remove. for debugging purposes only
jennabarton 12:e127fa20d609 216 pc.printf("#########RIGHT mouse click \t");
jennabarton 12:e127fa20d609 217 } else {
jennabarton 12:e127fa20d609 218 //initiate left click
jennabarton 12:e127fa20d609 219 mouseCommand(0x01, 0 , 0);
jennabarton 12:e127fa20d609 220
jennabarton 12:e127fa20d609 221 //TODO: remove. for debugging purposes only
jennabarton 12:e127fa20d609 222 pc.printf("********LEFT mouse click \t");
jennabarton 12:e127fa20d609 223 }
jennabarton 12:e127fa20d609 224
jennabarton 12:e127fa20d609 225 //reset counters
jennabarton 12:e127fa20d609 226 fingerUpCount = 0;
jennabarton 12:e127fa20d609 227 fingerDownCount = 0;
jennabarton 12:e127fa20d609 228
jennabarton 12:e127fa20d609 229 }
jennabarton 12:e127fa20d609 230 }
jennabarton 12:e127fa20d609 231
jennabarton 12:e127fa20d609 232
jennabarton 12:e127fa20d609 233 }
jennabarton 12:e127fa20d609 234
jennabarton 12:e127fa20d609 235
jennabarton 8:d27efcac2dd7 236 //get data from camera one
jennabarton 8:d27efcac2dd7 237 //populates onex and oney with values depending on the measured points
jennabarton 8:d27efcac2dd7 238 //NOTE: 1023 means nothing was detected
jennabarton 2:f501e506d62b 239 void readCameraData(void){
jennabarton 2:f501e506d62b 240
jennabarton 2:f501e506d62b 241 //request data from camera
jennabarton 2:f501e506d62b 242 char out[1];
jennabarton 2:f501e506d62b 243 out[0] = 0x36;
jennabarton 2:f501e506d62b 244 camera1.write(slaveAddress, out, 1);
jennabarton 2:f501e506d62b 245 //wait(0.2); //do we need this?
jennabarton 2:f501e506d62b 246
jennabarton 2:f501e506d62b 247 //get data from camera
jennabarton 2:f501e506d62b 248 camera1.read(slaveAddress, data_buf, 16);
jennabarton 8:d27efcac2dd7 249
jennabarton 2:f501e506d62b 250 //POINT 1
jennabarton 2:f501e506d62b 251 //get data
jennabarton 2:f501e506d62b 252 point1x = data_buf[1];
jennabarton 2:f501e506d62b 253 point1y = data_buf[2];
jennabarton 2:f501e506d62b 254 s = data_buf[3];
jennabarton 3:7b0c215eb6a7 255 //load x,y
jennabarton 3:7b0c215eb6a7 256 onex[0] = point1x + ((s & 0x30) << 4);
jennabarton 3:7b0c215eb6a7 257 oney[0] = point1y + ((s & 0xC0) << 2);
jennabarton 2:f501e506d62b 258
jennabarton 8:d27efcac2dd7 259
jennabarton 11:cd450ce343a8 260 //>>>>>>>>>>>>>>>>>Begin unfinished code for moving
jennabarton 11:cd450ce343a8 261
jennabarton 12:e127fa20d609 262 oneFingerResponse(onex[0], oney[0], prevX, prevY);
jennabarton 12:e127fa20d609 263 updateClickState(onex[0], oney[0], prevX, prevY);
jennabarton 11:cd450ce343a8 264
jennabarton 7:6b27977d1800 265
jennabarton 7:6b27977d1800 266 //update prev values
jennabarton 7:6b27977d1800 267 prevX = onex[0];
jennabarton 7:6b27977d1800 268 prevY = oney[0];
jennabarton 7:6b27977d1800 269
jennabarton 7:6b27977d1800 270
jennabarton 8:d27efcac2dd7 271 //<<<<<<<<<<<<<<<<End unfinished code for moving averages
jennabarton 8:d27efcac2dd7 272
jennabarton 2:f501e506d62b 273 //POINT 2
jennabarton 2:f501e506d62b 274 //get data
jennabarton 2:f501e506d62b 275 point2x = data_buf[4];
jennabarton 2:f501e506d62b 276 point2y = data_buf[5];
jennabarton 2:f501e506d62b 277 s = data_buf[6];
jennabarton 2:f501e506d62b 278 //load x,y
jennabarton 2:f501e506d62b 279 onex[1] = point2x + ((s & 0x30) << 4);
jennabarton 2:f501e506d62b 280 oney[1] = point2y + ((s & 0xC0) << 2);
jennabarton 3:7b0c215eb6a7 281
jennabarton 2:f501e506d62b 282 //POINT 3
jennabarton 2:f501e506d62b 283 //get data
jennabarton 2:f501e506d62b 284 point3x = data_buf[7];
jennabarton 2:f501e506d62b 285 point3y = data_buf[8];
jennabarton 2:f501e506d62b 286 s = data_buf[9];
jennabarton 2:f501e506d62b 287 //load x,y
jennabarton 2:f501e506d62b 288 onex[2] = point3x + ((s & 0x30) << 4);
jennabarton 2:f501e506d62b 289 oney[2] = point3y + ((s & 0xC0) << 2);
jennabarton 2:f501e506d62b 290
jennabarton 2:f501e506d62b 291 //POINT 4
jennabarton 2:f501e506d62b 292 //get data
jennabarton 2:f501e506d62b 293 point4x = data_buf[10];
jennabarton 2:f501e506d62b 294 point4y = data_buf[11];
jennabarton 2:f501e506d62b 295 s = data_buf[12];
jennabarton 2:f501e506d62b 296 //load x,y
jennabarton 2:f501e506d62b 297 onex[3] = point4x + ((s & 0x30) << 4);
jennabarton 2:f501e506d62b 298 oney[3] = point4y + ((s & 0xC0) << 2);
jennabarton 2:f501e506d62b 299
jennabarton 2:f501e506d62b 300 }
jennabarton 2:f501e506d62b 301
jennabarton 8:d27efcac2dd7 302 //print to serial monitor the coordinates of the points stored in
jennabarton 8:d27efcac2dd7 303 //the passed x and y arrays
jennabarton 2:f501e506d62b 304 void printCamData(int xcor[4], int ycor[4]){
jennabarton 2:f501e506d62b 305 for(int i = 0; i<4; i++){
jennabarton 2:f501e506d62b 306 int x = xcor[i];
jennabarton 2:f501e506d62b 307 int y = ycor[i];
jennabarton 2:f501e506d62b 308 //determine what to print
jennabarton 2:f501e506d62b 309 //x coordinate
jennabarton 3:7b0c215eb6a7 310 pc.printf(" %d,", x);
jennabarton 2:f501e506d62b 311
jennabarton 2:f501e506d62b 312 //y coordinate
jennabarton 8:d27efcac2dd7 313 pc.printf(" %d\t", y);
jennabarton 2:f501e506d62b 314 }
jennabarton 2:f501e506d62b 315
jennabarton 2:f501e506d62b 316 //new line and delay
jennabarton 2:f501e506d62b 317 pc.printf("\n");
jennabarton 3:7b0c215eb6a7 318 //wait(0.01);
jennabarton 2:f501e506d62b 319 }
jennabarton 2:f501e506d62b 320
jennabarton 4:1f443e7a0122 321
jennabarton 4:1f443e7a0122 322
jennabarton 4:1f443e7a0122 323
jennabarton 8:d27efcac2dd7 324 //entrance to the code
daviwang 0:1c15cf9cc4f9 325 int main() {
daviwang 1:2e895e5272ab 326 myled = 0;
jennabarton 3:7b0c215eb6a7 327 //slaveAddress = IRsensorAddress >> 1;
jennabarton 3:7b0c215eb6a7 328 slaveAddress = IRsensorAddress;
daviwang 1:2e895e5272ab 329 initCamera();
daviwang 1:2e895e5272ab 330
jennabarton 3:7b0c215eb6a7 331 //update baud rate
jennabarton 3:7b0c215eb6a7 332 pc.baud(115200);
jennabarton 3:7b0c215eb6a7 333
jennabarton 8:d27efcac2dd7 334 //loop to search for new info using the camera
daviwang 0:1c15cf9cc4f9 335 while(1) {
jennabarton 8:d27efcac2dd7 336
jennabarton 8:d27efcac2dd7 337 //wait
jennabarton 12:e127fa20d609 338 //wait(0.04);
jennabarton 8:d27efcac2dd7 339
jennabarton 8:d27efcac2dd7 340 //toggle test LED
jennabarton 2:f501e506d62b 341 myled = 1 - myled;
jennabarton 2:f501e506d62b 342
jennabarton 2:f501e506d62b 343 //get the camera data
jennabarton 2:f501e506d62b 344 readCameraData();
daviwang 1:2e895e5272ab 345
jennabarton 2:f501e506d62b 346 //print points
jennabarton 3:7b0c215eb6a7 347 printCamData(onex, oney);
daviwang 1:2e895e5272ab 348
jennabarton 8:d27efcac2dd7 349 //uncomment below to test infinite print
jennabarton 6:4ade0e1a3723 350 //keyOut.putc(0x41);
jennabarton 10:d67a15ba5748 351
jennabarton 4:1f443e7a0122 352
jennabarton 12:e127fa20d609 353 //uncomment below to infinitely move mouse in a square
jennabarton 10:d67a15ba5748 354 // double delay = 0.1;
jennabarton 10:d67a15ba5748 355 // int change = 75;
jennabarton 10:d67a15ba5748 356 // mouseCommand(0,0, (char) -1*change);
jennabarton 10:d67a15ba5748 357 // wait(delay);
jennabarton 10:d67a15ba5748 358 // mouseCommand(0,(char) -1*change,0);
jennabarton 10:d67a15ba5748 359 // wait(delay);
jennabarton 10:d67a15ba5748 360 // mouseCommand(0,0, (char) change);
jennabarton 10:d67a15ba5748 361 // wait(delay);
jennabarton 10:d67a15ba5748 362 // mouseCommand(0,(char) change,0);
jennabarton 10:d67a15ba5748 363 // wait(delay);
jennabarton 9:55473409c585 364
jennabarton 9:55473409c585 365
daviwang 0:1c15cf9cc4f9 366 }
daviwang 0:1c15cf9cc4f9 367 }