void write_sto_conf(const char *outfile, const char *title, t_atoms *atoms, rvec x[], rvec *v, int ePBC, matrix box) { FILE *out; int ftp; t_trxframe fr; ftp = fn2ftp(outfile); switch (ftp) { case efGRO: write_conf(outfile, title, atoms, x, v, box); break; case efG96: clear_trxframe(&fr, TRUE); fr.bTitle = TRUE; fr.title = title; fr.natoms = atoms->nr; fr.bAtoms = TRUE; fr.atoms = atoms; fr.bX = TRUE; fr.x = x; if (v) { fr.bV = TRUE; fr.v = v; } fr.bBox = TRUE; copy_mat(box, fr.box); out = gmx_fio_fopen(outfile, "w"); write_g96_conf(out, &fr, -1, NULL); gmx_fio_fclose(out); break; case efPDB: case efBRK: case efENT: out = gmx_fio_fopen(outfile, "w"); write_pdbfile(out, title, atoms, x, ePBC, box, ' ', -1, NULL, TRUE); gmx_fio_fclose(out); break; case efESP: out = gmx_fio_fopen(outfile, "w"); write_espresso_conf_indexed(out, title, atoms, atoms->nr, NULL, x, v, box); gmx_fio_fclose(out); break; case efTPR: case efTPB: case efTPA: gmx_fatal(FARGS, "Sorry, can not write a topology to %s", outfile); break; default: gmx_incons("Not supported in write_sto_conf"); } }
static int check_conf(void) { int data[10]; char *buffer; int ret; struct stat s; /* check conf file */ if (stat(cf_file, &s) == 0) { /* conf file already existed */ cf_fd = open(cf_file, O_RDWR); if (cf_fd >= 0) { if(touch_type == TOUCH_PANEL_TYPE_RESISTIVE_MULTIPOINT_ULTRACHIP) { buffer = calloc(1, s.st_size + 1); read(cf_fd, buffer, s.st_size); ret = sscanf(buffer, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,", &data[0], &data[1], &data[2], &data[3], &data[4], &data[5], &data[6], &data[7], &data[8], &data[9]); if (ret == 10) { free(buffer); /* write to driver */ //write_conf(data); close(cf_fd); return 1; } } else { buffer = calloc(1, s.st_size + 1); read(cf_fd, buffer, s.st_size); ret = sscanf(buffer, "%d\n%d\n%d\n%d\n%d\n%d\n%d", &data[0], &data[1], &data[2], &data[3], &data[4], &data[5], &data[6]); if (ret == 7) { free(buffer); /* write to driver */ write_conf(data); close(cf_fd); return 1; } } log_write("Failed to get datas from conf file: %d\n", ret); free(buffer); close(cf_fd); } } return 0; }
static int create_conf(const char *spec) { char *devname, *unitname, *confpath, *p; int ret; devname = evaluate_spec(spec); if (!devname) { error("Cannot convert '%s' to device name: %s", spec, strerror(errno)); return -1; } unitname = path_escape(devname); if (!unitname) { error("Cannot convert '%s' to systemd unit name: %s", devname, strerror(errno)); free(devname); return -1; } free(devname); confpath = malloc(unitdirlen + 1 + strlen(unitname) + sizeof(".device.d/timeout.conf")); if (!confpath) { error("Cannot allocate path for '%s': %s", unitname, strerror(errno)); free(unitname); return -1; } p = stpcpy(confpath, unitdir); *p++ = '/'; p = stpcpy(p, unitname); p = stpcpy(p, ".device.d"); free(unitname); if (mkdir(confpath, S_IRWXU | S_IRWXG | S_IRWXO) && errno != EEXIST) { error("Cannot create directory '%s': %s", confpath, strerror(errno)); free(confpath); return -1; } p = stpcpy(p, "/timeout.conf"); ret = write_conf(confpath); free(confpath); return ret; }
static void write_versionfile(bool use_stdout) { FILE *fp = stdout; if (!use_stdout) { char targetfile[256]; fp = fopen(get_tmp_dir_filename(targetfile, sizeof(targetfile), "oscam.version"), "w"); if (!fp) { cs_log("Cannot open %s (errno=%d %s)", targetfile, errno, strerror(errno)); return; } struct tm st; time_t now = time(NULL); localtime_r(&now, &st); fprintf(fp, "Unix starttime: %ld\n", (long)now); fprintf(fp, "Starttime: %02d.%02d.%04d %02d:%02d:%02d\n", st.tm_mday, st.tm_mon + 1, st.tm_year + 1900, st.tm_hour, st.tm_min, st.tm_sec); } fprintf(fp, "Version: oscam-%s-r%s\n", CS_VERSION, CS_SVN_VERSION); fprintf(fp, "\n"); write_conf(WEBIF, "Web interface support"); write_conf(TOUCH, "Touch interface support"); write_conf(WITH_SSL, "SSL support"); write_conf(HAVE_DVBAPI, "DVB API support"); if (config_enabled(HAVE_DVBAPI)) { write_conf(WITH_AZBOX, "DVB API with AZBOX support"); write_conf(WITH_MCA, "DVB API with MCA support"); write_conf(WITH_COOLAPI, "DVB API with COOLAPI support"); write_conf(WITH_STAPI, "DVB API with STAPI support"); } write_conf(CS_ANTICASC, "Anti-cascading support"); write_conf(IRDETO_GUESSING, "Irdeto guessing"); write_conf(WITH_DEBUG, "Debug mode"); write_conf(MODULE_MONITOR, "Monitor"); write_conf(WITH_LB, "Loadbalancing support"); write_conf(CW_CYCLE_CHECK, "CW Cycle Check support"); write_conf(LCDSUPPORT, "LCD support"); write_conf(LEDSUPPORT, "LED support"); write_conf(IPV6SUPPORT, "IPv6 support"); write_conf(CS_CACHEEX, "Cache exchange support"); fprintf(fp, "\n"); write_conf(MODULE_CAMD33, "camd 3.3x"); write_conf(MODULE_CAMD35, "camd 3.5 UDP"); write_conf(MODULE_CAMD35_TCP, "camd 3.5 TCP"); write_conf(MODULE_NEWCAMD, "newcamd"); write_conf(MODULE_CCCAM, "CCcam"); write_conf(MODULE_CCCSHARE, "CCcam share"); write_conf(MODULE_PANDORA, "Pandora"); write_conf(MODULE_GHTTP, "ghttp"); write_conf(MODULE_GBOX, "gbox"); write_conf(MODULE_RADEGAST, "radegast"); write_conf(MODULE_SERIAL, "serial"); write_conf(MODULE_CONSTCW, "constant CW"); fprintf(fp, "\n"); write_conf(WITH_CARDREADER, "Reader support"); if (config_enabled(WITH_CARDREADER)) { fprintf(fp, "\n"); write_readerconf(READER_NAGRA, "Nagra"); write_readerconf(READER_IRDETO, "Irdeto"); write_readerconf(READER_CONAX, "Conax"); write_readerconf(READER_CRYPTOWORKS, "Cryptoworks"); write_readerconf(READER_SECA, "Seca"); write_readerconf(READER_VIACCESS, "Viaccess"); write_readerconf(READER_VIDEOGUARD, "NDS Videoguard"); write_readerconf(READER_DRE, "DRE Crypt"); write_readerconf(READER_TONGFANG, "TONGFANG"); write_readerconf(READER_BULCRYPT, "Bulcrypt"); write_readerconf(READER_GRIFFIN, "Griffin"); write_readerconf(READER_DGCRYPT, "DGCrypt"); fprintf(fp, "\n"); write_cardreaderconf(CARDREADER_PHOENIX, "phoenix"); write_cardreaderconf(CARDREADER_INTERNAL_AZBOX, "internal_azbox"); write_cardreaderconf(CARDREADER_INTERNAL_COOLAPI, "internal_coolapi"); write_cardreaderconf(CARDREADER_INTERNAL_SCI, "internal_sci"); write_cardreaderconf(CARDREADER_SC8IN1, "sc8in1"); write_cardreaderconf(CARDREADER_MP35, "mp35"); write_cardreaderconf(CARDREADER_SMARGO, "smargo"); write_cardreaderconf(CARDREADER_PCSC, "pcsc"); write_cardreaderconf(CARDREADER_SMART, "smartreader"); write_cardreaderconf(CARDREADER_DB2COM, "db2com"); write_cardreaderconf(CARDREADER_STAPI, "stapi"); } else { write_readerconf(WITH_CARDREADER, "Reader Support"); } if (!use_stdout) fclose(fp); }
void run(Par *par) { int i, itherm, nstep, istep, isamp, iblock, st; int nsamp = par->nsamp, nblock = par->nblock; char wfile[FNAMESIZE]; Vec *pos, *vel, *force; double ekin, epot; double v0[NV], v1[NV], v2[NV]; FILE *estream = NULL; // Initialize if (par->alpha > 0.0) { printf("Seed for random number generator: %d.\n", par->seed); init_ran(par->seed); } pos = malloc(par->n * sizeof(Vec)); force = malloc(par->n * sizeof(Vec)); vel = malloc(par->n * sizeof(Vec)); // Read from file... if (par->readfile) st = read_conf(par->n, pos, vel, par->readfile); else { init_pos(par->n, &par->L, pos); set_temperature(par->n, par->t, vel); } // Get file name for writing to. get_filename(par, wfile); // Open file for writing energy results estream = fopen_wfile("efile/", wfile); if (!estream) return; measure(par->n, &par->L, pos, vel, &epot, &ekin); printf("Energy = %g \n", epot); double test; for(i=0; i<par->ntherm; i++) { test = pos[5].x; step(par, pos, vel, force); if(test == pos[5].x) printf("aha!\n"); } //printf("rx ry vx vy = %g %g %g %g\n", pos[0].x, pos[0].y, vel[0].x, vel[0].y); // Run and collect values printf("\nSimulate %d blocks x %d samples each: ", par->nblock, par->nsamp); fflush(stdout); init_vcorr(par->n, par->deltat, 0.1, 5.0); // Initialize for measuring a histogram of particle distances for // distances up to 5.0 and bin size 0.02. // init_pcorr(par->n, 0.02, 5.0); for (i = 0; i < NV; i++) v1[i] = v2[i] = 0.0; nstep = rint(1.0 / par->deltat); for (iblock = 0; iblock < nblock; iblock++) { for (i = 0; i < NV; i++) v0[i] = 0.0; for (isamp = 0; isamp < nsamp; isamp++) { for (istep = 0; istep < nstep; istep++) { step(par, pos, vel, force); measure_vcorr(par->n, vel); } // measure_pcorr(par->n, &par->L, pos); measure(par->n, &par->L, pos, vel, &epot, &ekin); if (estream) fprintf(estream, "%d %g\n", isamp + nsamp * iblock, epot + ekin); v0[0] += epot; //v0[1] += ekin; //v0[2] += epot + ekin; } for (i = 0; i < NV; i++) { v0[i] /= nsamp; v1[i] += v0[i]; v2[i] += v0[i] * v0[i]; } printf("%d ", iblock + 1); fflush(stdout); } printf("\n"); if (estream) fclose(estream); for (i = 0; i < NV; i++) { v1[i] /= nblock; v2[i] /= nblock; } // Write configuration to the named file. write_conf(par->n, pos, vel, "conf/", wfile); // Write velocity correlation results to files. write_vcorr(par->n, wfile); // write_pcorr(par->n, wfile); // Print out some results printf("\n"); printf("v1: %.3f v2: %.3f nblock: %d \n",v1[0],v2[0],nblock); print_standard_error("Potential E: ", v1[0], v2[0], nblock); //print_standard_error("Kinetic E: ", v1[1], v2[1], nblock); //print_standard_error("Total energy: ", v1[2], v2[2], nblock); // From the virial theorem: pressure = N * T + Virial / Dimensionality free(vel); free(pos); }
static void write_versionfile(bool use_stdout) { FILE *fp = stdout; if(!use_stdout) { char targetfile[256]; fp = fopen(get_tmp_dir_filename(targetfile, sizeof(targetfile), "oscam.version"), "w"); if(!fp) { cs_log("Cannot open %s (errno=%d %s)", targetfile, errno, strerror(errno)); return; } struct tm st; time_t walltime = cs_time(); localtime_r(&walltime, &st); fprintf(fp, "Unix starttime: %ld\n", walltime); fprintf(fp, "Starttime: %02d.%02d.%04d %02d:%02d:%02d\n", st.tm_mday, st.tm_mon + 1, st.tm_year + 1900, st.tm_hour, st.tm_min, st.tm_sec); } fprintf(fp, "Version: oscam-%s-r%s\n", CS_VERSION, CS_SVN_VERSION); fprintf(fp, "Compiler: %s\n", CS_TARGET); fprintf(fp, "Box type: %s (%s)\n", boxtype_get(), boxname_get()); fprintf(fp, "TempDir: %s\n", cs_tmpdir); fprintf(fp, "ConfigDir: %s\n", cs_confdir); #ifdef WEBIF fprintf(fp, "WebifPort: %d\n", cfg.http_port); #endif fprintf(fp, "\n"); write_conf(WEBIF, "Web interface support"); write_conf(WEBIF_LIVELOG, "LiveLog support"); write_conf(WEBIF_JQUERY, "jQuery support intern"); write_conf(TOUCH, "Touch interface support"); write_conf(WITH_SSL, "SSL support"); write_conf(HAVE_DVBAPI, "DVB API support"); if(config_enabled(HAVE_DVBAPI)) { write_conf(WITH_AZBOX, "DVB API with AZBOX support"); write_conf(WITH_MCA, "DVB API with MCA support"); write_conf(WITH_COOLAPI, "DVB API with COOLAPI support"); write_conf(WITH_STAPI, "DVB API with STAPI support"); write_conf(WITH_STAPI5, "DVB API with STAPI5 support"); write_conf(READ_SDT_CHARSETS, "DVB API read-sdt charsets"); } write_conf(IRDETO_GUESSING, "Irdeto guessing"); write_conf(CS_ANTICASC, "Anti-cascading support"); write_conf(WITH_DEBUG, "Debug mode"); write_conf(MODULE_MONITOR, "Monitor"); write_conf(WITH_LB, "Loadbalancing support"); write_conf(CS_CACHEEX, "Cache exchange support"); write_conf(CW_CYCLE_CHECK, "CW Cycle Check support"); write_conf(LCDSUPPORT, "LCD support"); write_conf(LEDSUPPORT, "LED support"); switch (cs_getclocktype()) { case CLOCK_TYPE_UNKNOWN : write_conf(CLOCKFIX, "Clockfix with UNKNOWN clock"); break; case CLOCK_TYPE_REALTIME : write_conf(CLOCKFIX, "Clockfix with realtime clock"); break; case CLOCK_TYPE_MONOTONIC: write_conf(CLOCKFIX, "Clockfix with monotonic clock"); break; } write_conf(IPV6SUPPORT, "IPv6 support"); fprintf(fp, "\n"); write_conf(MODULE_CAMD33, "camd 3.3x"); write_conf(MODULE_CAMD35, "camd 3.5 UDP"); write_conf(MODULE_CAMD35_TCP, "camd 3.5 TCP"); write_conf(MODULE_NEWCAMD, "newcamd"); write_conf(MODULE_CCCAM, "CCcam"); write_conf(MODULE_CCCSHARE, "CCcam share"); write_conf(MODULE_GBOX, "gbox"); write_conf(MODULE_RADEGAST, "radegast"); write_conf(MODULE_SCAM, "scam"); write_conf(MODULE_SERIAL, "serial"); write_conf(MODULE_CONSTCW, "constant CW"); write_conf(MODULE_PANDORA, "Pandora"); write_conf(MODULE_GHTTP, "ghttp"); fprintf(fp, "\n"); write_conf(WITH_CARDREADER, "Reader support"); if(config_enabled(WITH_CARDREADER)) { fprintf(fp, "\n"); write_readerconf(READER_NAGRA, "Nagra"); write_readerconf(READER_IRDETO, "Irdeto"); write_readerconf(READER_CONAX, "Conax"); write_readerconf(READER_CRYPTOWORKS, "Cryptoworks"); write_readerconf(READER_SECA, "Seca"); write_readerconf(READER_VIACCESS, "Viaccess"); write_readerconf(READER_VIDEOGUARD, "NDS Videoguard"); write_readerconf(READER_DRE, "DRE Crypt"); write_readerconf(READER_TONGFANG, "TONGFANG"); write_readerconf(READER_BULCRYPT, "Bulcrypt"); write_readerconf(READER_GRIFFIN, "Griffin"); write_readerconf(READER_DGCRYPT, "DGCrypt"); fprintf(fp, "\n"); write_cardreaderconf(CARDREADER_PHOENIX, "phoenix"); write_cardreaderconf(CARDREADER_INTERNAL_AZBOX, "internal_azbox"); write_cardreaderconf(CARDREADER_INTERNAL_COOLAPI, "internal_coolapi"); write_cardreaderconf(CARDREADER_INTERNAL_SCI, "internal_sci"); write_cardreaderconf(CARDREADER_SC8IN1, "sc8in1"); write_cardreaderconf(CARDREADER_MP35, "mp35"); write_cardreaderconf(CARDREADER_SMARGO, "smargo"); write_cardreaderconf(CARDREADER_PCSC, "pcsc"); write_cardreaderconf(CARDREADER_SMART, "smartreader"); write_cardreaderconf(CARDREADER_DB2COM, "db2com"); write_cardreaderconf(CARDREADER_STAPI, "stapi"); write_cardreaderconf(CARDREADER_STAPI5, "stapi5"); write_cardreaderconf(CARDREADER_STINGER, "stinger"); } else { write_readerconf(WITH_CARDREADER, "Reader Support"); } if(!use_stdout) { fclose(fp); } }
static void do_calibration_da9052(int do_calib) { int i, x, y; int dx[3], dy[3]; int tx[3], ty[3]; int delta, delta_x[3], delta_y[3]; struct input_absinfo absX, absY; if (do_calib) { /* calculate the expected point */ x = info.xres / 4; y = info.yres / 4; dx[0] = x; dy[0] = info.yres / 2; dx[1] = info.xres / 2; dy[1] = y; dx[2] = info.xres - x; dy[2] = info.yres - y; for (i = 0; i < 3; i ++) { draw_cross(dx[i], dy[i], 0); get_input(&tx[i], &ty[i]); log_write("Received x,y -> Expected x,y\n"); log_write("%d,%d -> %d,%d\n", tx[i], ty[i], dx[i], dy[i]); draw_cross(dx[i], dy[i], 1); } /* check ok, calulate the result */ delta = (tx[0] - tx[2]) * (ty[1] - ty[2]) - (tx[1] - tx[2]) * (ty[0] - ty[2]); delta_x[0] = (dx[0] - dx[2]) * (ty[1] - ty[2]) - (dx[1] - dx[2]) * (ty[0] - ty[2]); delta_x[1] = (tx[0] - tx[2]) * (dx[1] - dx[2]) - (tx[1] - tx[2]) * (dx[0] - dx[2]); delta_x[2] = dx[0] * (tx[1] * ty[2] - tx[2] * ty[1]) - dx[1] * (tx[0] * ty[2] - tx[2] * ty[0]) + dx[2] * (tx[0] * ty[1] - tx[1] * ty[0]); delta_y[0] = (dy[0] - dy[2]) * (ty[1] - ty[2]) - (dy[1] - dy[2]) * (ty[0] - ty[2]); delta_y[1] = (tx[0] - tx[2]) * (dy[1] - dy[2]) - (tx[1] - tx[2]) * (dy[0] - dy[2]); delta_y[2] = dy[0] * (tx[1] * ty[2] - tx[2] * ty[1]) - dy[1] * (tx[0] * ty[2] - tx[2] * ty[0]) + dy[2] * (tx[0] * ty[1] - tx[1] * ty[0]); cal_val[0] = delta_x[0]; cal_val[1] = delta_x[1]; cal_val[2] = delta_x[2]; cal_val[3] = delta_y[0]; cal_val[4] = delta_y[1]; cal_val[5] = delta_y[2]; cal_val[6] = delta; save_conf(cal_val); write_conf(cal_val); } /* Android input framework expects values based on the absmax. Now that the touchscreen is calibrated set the input maximum according to screen resolution, not the touch sensor resolution */ if (ioctl(ts_fd, EVIOCGABS(ABS_X), &absX) == -1) { log_write("EVIOCGABS( failed\n"); } else { log_write("Modifying x.max:%i -> %i\n", absX.maximum, info.xres); absX.maximum = info.xres; if (ioctl(ts_fd, EVIOCSABS(ABS_X), &absX) == -1) log_write("EVIOCSABS( failed\n"); } if (ioctl(ts_fd, EVIOCGABS(ABS_Y), &absY) == -1) { log_write("EVIOCGABS( failed\n"); } else { log_write("Modifying y.max:%i -> %i\n", absY.maximum, info.yres); absY.maximum = info.yres; if (ioctl(ts_fd, EVIOCSABS(ABS_Y), &absY) == -1) log_write("EVIOCSABS( failed\n"); } }
static int do_calibration(void) { int i, x, y; int dx[6], dy[6]; int tx[6], ty[6]; int delta, delta_x[6], delta_y[6]; int status=0; /* calculate the expected point */ x = info.xres / 4; y = info.yres / 4; dx[0] = x; dy[0] = info.yres / 2; dx[1] = info.xres / 2; dy[1] = y; dx[2] = info.xres - x; dy[2] = info.yres - y; dx[3] = 400; dy[3] = 360; dx[4] = 200; dy[4] = 360; dx[5] = 600; dy[5] = 240; retry: for (i = 0; i < 3; i ++) { draw_cross(dx[i], dy[i], 0); get_input(&tx[i], &ty[i]); log_write("get event: %d,%d -> %d,%d\n", tx[i], ty[i], dx[i], dy[i]); draw_cross(dx[i], dy[i], 1); } if( (dx[0] == 0) || (dx[1] == 0) || (dx[2] == 0) || (dy[0] == 0) || (dy[1] == 0) || (dy[2] == 0)){ log_write("Calibration Got ZERO Value\n"); goto retry; } if( (dy[0] < dy[1]) && (dy[1] - dy[0] < 10)){ log_write("Point 0 and Point 1 Get too Closed\n"); goto retry; }else if( dy[0] > dx[1]){ goto retry; } if( (dy[1] < dy[2]) && (dy[2] - dy[1] < 10)) goto retry; else if( dy[1] > dy[2]) goto retry; /* check ok, calulate the result */ delta = (tx[0] - tx[2]) * (ty[1] - ty[2]) - (tx[1] - tx[2]) * (ty[0] - ty[2]); delta_x[0] = (dx[0] - dx[2]) * (ty[1] - ty[2]) - (dx[1] - dx[2]) * (ty[0] - ty[2]); delta_x[1] = (tx[0] - tx[2]) * (dx[1] - dx[2]) - (tx[1] - tx[2]) * (dx[0] - dx[2]); delta_x[2] = dx[0] * (tx[1] * ty[2] - tx[2] * ty[1]) - dx[1] * (tx[0] * ty[2] - tx[2] * ty[0]) + dx[2] * (tx[0] * ty[1] - tx[1] * ty[0]); delta_y[0] = (dy[0] - dy[2]) * (ty[1] - ty[2]) - (dy[1] - dy[2]) * (ty[0] - ty[2]); delta_y[1] = (tx[0] - tx[2]) * (dy[1] - dy[2]) - (tx[1] - tx[2]) * (dy[0] - dy[2]); delta_y[2] = dy[0] * (tx[1] * ty[2] - tx[2] * ty[1]) - dy[1] * (tx[0] * ty[2] - tx[2] * ty[0]) + dy[2] * (tx[0] * ty[1] - tx[1] * ty[0]); cal_val[0] = delta_x[0]; cal_val[1] = delta_x[1]; cal_val[2] = delta_x[2]; cal_val[3] = delta_y[0]; cal_val[4] = delta_y[1]; cal_val[5] = delta_y[2]; cal_val[6] = delta; for (i = 3; i < 6; i ++) { draw_cross(dx[i], dy[i], 0); get_input(&tx[i], &ty[i]); get_calibration_value(&tx[i],&ty[i]); if(tx[i] >= dx[i] ) status = (tx[i] - dx[i] > status) ? tx[i] - dx[i]: status; else if(dx[i] > tx[i] ){ status = (dx[i] - tx[i] > status) ? dx[i] - tx[i]: status; } if(ty[i] >= dy[i] ) status = (ty[i] - dy[i] > status) ? ty[i] - dy[i]: status; else if(dy[i] > ty[i] ){ status = (dy[i] - ty[i] > status) ? dy[i] - ty[i]: status; } log_write("get event: %d,%d -> %d,%d status=%d\n", tx[i], ty[i], dx[i], dy[i],status); draw_cross(dx[i], dy[i], 1); } if(status > DIFF_VALUE){ return status; } save_conf(cal_val); write_conf(cal_val); return 0; }