function xajax() { if (gp('gp_xajax') != '1') { return $this->xAjaxColSave(); } // No conditionals here, this is always ajax echo "xajax|"; $tid = gp('gp_table_id'); $parms['gp_table_id'] = $tid; $parms['gp_page'] = 'x_import'; $parms['gp_xajax'] = '1'; $parms['gp_map'] = gp('gp_map', ''); //$a1=aFromgp('gp_'); //hprint_r($a1); //$a2=aFromgp('txt_'); //hprint_r($a2); // Look for a map delete command if (gpExists('gp_del')) { SQL("Delete from importmaps where importmap=" . SQLFC(gp('gp_del'))); if (gp('gp_del') == gp('gp_map')) { gpSet('gp_map', ''); $parms['gp_map'] = ''; } } // Look for a map insert command. If found and works, automatically // select this as the map we want. $row = aFromGP('txt_'); if (count($row) > 0 && gpExists('gp_new')) { $dd = DD_TableRef('importmaps'); $row['table_id'] = gp('gp_table_id'); SQLX_Insert($dd, $row); if (!Errors()) { gpSet('gp_map', $row['importmap']); $parms['gp_map'] = gp('gp_map'); } } // Display a list of maps we may use $maps = SQL_AllRows("Select importmap,name_prefix from importmaps\n where table_id=" . SQLFC($tid), 'importmap'); //hprint_r($maps); ?> <h2>Map Selection</h2> <p>Please choose a map to use. If no map exists, please create a new one. After a map is chosen you can map individual columns. </p> <table id="x2data1"> <thead> <tr><th>Map Name <th>Select <th>Delete </thead> <tbody> <?php foreach ($maps as $map) { $px = $parms; $px['gp_map'] = $map['importmap']; $hp1 = http_build_query($px); $px['gp_del'] = $map['importmap']; $hp2 = http_build_query($px); echo $map['importmap'] == $parms['gp_map'] ? '<tr class="hilite">' : '<tr>'; ?> <td><?php echo $map['importmap']; ?> <td><a href="javascript:andrax('?<?php echo $hp1; ?> ')">Select</a> <td><a href="javascript:andrax('?<?php echo $hp2; ?> ')">Delete</a> <?php } // Now the row for a new entry $px = $parms; $px['gp_new'] = 1; $hp = "'?" . http_build_query($px); $hp .= "&txt_importmap='+ob('txt_importmap').value"; ?> <tr><td><input name="txt_importmap" id="txt_importmap"> <td> <td><a href="javascript:andrax(<?php echo $hp; ?> )">Create</a> </table> <?php // If they have not picked a map, we are done. If we continue // we will let them pick individual columns. if ($parms['gp_map'] == '') { return; } // Get column listing from dictionary $dd = DD_TableRef(gp('gp_table_id')); $cols = array_keys($dd['flat']); // Get cols available from import $fi = SessionGet('importfile'); $FILE = fopen($fi['uname'], 'r'); $sline = fsGets($FILE); $aline = explode('|', $sline); array_unshift($aline, ''); $aline = array_combine($aline, $aline); // make keys and values the same fclose($FILE); // Get current map $mapcols = SQL_AllRows("Select column_id,column_id_src FROM importmapcolumns\n WHERE importmap=" . SQLFC(gp('gp_map')) . "\n AND table_id =" . SQLFC(gp('gp_table_id')), 'column_id'); ?> <hr /> <h2>Individual Column Mappings</h2> <table id="x2data1"> <thead><tr><th>Destination Column</td> <th>Caption</td> <th>Source Column</td> </thead> <tbody> <?php foreach ($cols as $col) { $value = ArraySafe($mapcols, $col, array()); $value = ArraySafe($value, 'column_id_src', ''); $px = $parms; $px['gp_xajax'] = $col; $andrax = "?" . http_build_query($px); $extra = "onchange=\"andrax('{$andrax}&gp_xval='+this.value)\""; $hSelect = hSelectFromAA($aline, 'anycol', $value, $extra); if ($dd['flat'][$col]['uino'] != 'Y') { ?> <tr><td><?php echo $col; ?> <td><?php echo $dd['flat'][$col]['description']; ?> <td><?php echo $hSelect; ?> <?php } } ?> </tbody> </table> <?php $href = '?gp_page=x_import&gp_table_id=' . $tid . '&gp_fbproc=1' . '&gp_map=' . $parms['gp_map']; ?> <hr /> <h2>File Process</h2> <p>The file <?php echo $fi['name']; ?> was uploaded, size <?php echo number_format($fi['size']); ?> bytes. </p> <p><a href="javascript:SetAndPost('gp_nofile',1)"> Upload A Different File </a> </p> <p><a href="javascript:Popup('<?php echo $href; ?> ')">Process Now</a> </p> <?php }
/** * Execute an skey-based update * */ function update() { $row = aFromGP('x4v_'); $skey = 0; $table_id = $this->dd['table_id']; # KFD 6/12/08, allow functions to modify or prevent a write $tbefore = $table_id . "_writeBefore"; $tafter = $table_id . "_writeAfter"; if (function_exists($tbefore)) { $message = $tbefore($row); if ($message != '') { x4Error($message); return; } } # KFD 6/28/08, a non-empty date must be valid $errors = false; foreach ($row as $col => $value) { if (!isset($this->dd['flat'][$col])) { unset($row[$col]); continue; } $ermsg = "Invalid date format for " . $this->dd['flat'][$col]['description']; $ermsg2 = "Invalid date value for " . $this->dd['flat'][$col]['description']; if ($this->dd['flat'][$col]['type_id'] == 'date') { if (trim($value) == '') { continue; } if (strpos($value, '/') === false && strpos($value, '-') === false) { x4Error($ermsg); $errors = true; continue; } if (strpos($value, '/') !== false) { $parsed = explode('/', $value); if (count($parsed) != 3) { $errors = true; x4Error($ermsg); continue; } if (!checkdate($parsed[0], $parsed[1], $parsed[2])) { x4Error($ermsg2); $errors = true; continue; } } if (strpos($value, '-') !== false) { $parsed = explode('-', $value); if (count($parsed) != 3) { $errors = true; x4Error($ermsg); continue; } if (!checkdate($parsed[1], $parsed[2], $parsed[0])) { x4Error($ermsg2); $errors = true; continue; } } } } if ($errors) { return; } if ($row['skey'] == 0 || !isset($row['skey'])) { unset($row['skey']); $skey = SQLX_Insert($this->dd, $row); if (!errors()) { $row = SQL_OneRow("Select * FROM {$this->view_id} WHERE skey = {$skey}"); } x4Data('row', $row); } else { SQLX_Update($this->dd, $row); if (!errors()) { $skey = $row['skey']; $row = SQL_OneRow("Select * FROM {$this->view_id} WHERE skey = {$skey}"); x4Data('row', $row); } } # KFD 6/12/08, allow functions to modify or prevent a write if (Errors()) { return; } if (function_exists($tafter)) { $message = $tafter($row); if ($message != '') { x4Error($message); return; } } }
function processSubmit() { // Get the submitted data $table = gp('gp_table_upd', ''); // Get the flat table def $table_dd = dd_TableRef($table); $tabflat = ArraySafe($table_dd, 'flat'); //hprint_r($table); $row = aFromGP('gp_upd_'); //hprint_r($row); //hprint_r($row); // Build a WHERE clause $where = array(); foreach ($row as $col => $val) { if (ArraySafe($tabflat[$col], 'primary_key', 'N') != 'Y') { continue; } $where[] = $col . " = '" . $val . "'"; } //hprint_r($where); $where = implode(' AND ', $where); // Build a SELECT $sql = "SELECT skey\n FROM " . ddTable_IDResolve($table) . "\n WHERE " . $where; //hprint_r($sql); $records = SQL_AllRows($sql); if (count($records) != 1) { echo "Invalid or non-unique key supplied\n<br>"; return; } // Well, we haven't failed yet, let's add the skey before the update, just to be safe. $row['skey'] = $records[0]['skey']; $skey = $records[0]['skey']; //hprint_r($row); SQLX_Update($table_dd, $row); if (Errors()) { echo hErrors(); } else { echo "Update Successful. <a href=\"?gp_page={$table}&gp_skey={$skey}\">View Record</a> <br>\n"; } }
function processPost() { // If they are doing a dupe check, convert it into a // search if (gp('gp_action') == 'dupecheck') { gpSet('gpx_mode', 'search'); } // 5/10/06 Added this call. See routine for details. //KenDebug('Entered process post'); $row = aFromGP('x2t_'); if (count($row) > 0) { //KenDebug('Going into textboxes'); processPost_TextBoxes($row); } // this is database inserts/updates, gets its own subroutine // Unless AddControl() was used to build controls, gpControls will // be blank and this is not called. // // AS OF 5/10/06, these are not regularly used in x_table2 // if (gp('gpControls', '') != '') { $data = processPost_Database(); vgfSet('array_post', $data); } // Database deletions, form: gp_delskey_<table>=<skey_value> // // AS OF 5/29/07, revived for Ajax_x3 initiative // AS OF 5/10/06, these are not regularly used in x_table2 // $dels = aFromGP("gp_delskey_"); foreach ($dels as $table_id => $skey) { if (intval($skey) > 0) { $view_id = DDTable_IDResolve($table_id); $sq = "DELETE FROM {$view_id} where skey={$skey}"; SQL($sq); processPost_TableSearchResultsClear($table_id); } } // Look for gp_ob controls, change order-by. Only make // a change if you find a value, no action on blanks $obs = aFromGP("gp_ob_"); foreach ($obs as $table_id => $obnew) { $table = DD_TableRef($table_id); $obold = ConGet("table", $table_id, "orderby"); $obascold = ConGet("table", $table_id, "orderasc"); if ($obnew != '') { if ($obold != $obnew) { // for new column, always go ascending ConSet("table", $table_id, "orderasc", "ASC"); } else { // if repeating the same column, flip ascending/descending $obascnew = $obascold == "ASC" ? "DESC" : "ASC"; ConSet("table", $table_id, "orderasc", $obascnew); } ConSet("table", $table_id, "orderby", $obnew); processPost_TableSearchResultsClear($table_id); } } // Now look for page-turners, where they are advancing to // a new page on a search results display $obs = aFromGP("gp_spage_"); foreach ($obs as $table_id => $pagecommand) { list($spage, $srows, $srppg, $maxpage) = arrPageInfo($table_id); switch ($pagecommand) { case '': $newpage = 0; case '0': $newpage = 1; break; case '1': $newpage = $spage <= 1 ? 1 : $spage - 1; break; case '2': $newpage = $spage >= $maxpage ? $maxpage : $spage + 1; break; case '3': $newpage = $maxpage; break; } if ($newpage != 0) { ConSet('table', $table_id, 'spage', $newpage); } } // Check to see if an onscreen child table row was saved if (gp('gp_child_onscreen', '') != '') { $parent_skey = gp('gp_skey'); $table = gp('gp_child_onscreen'); $cols = aFromGP('gp_onscreen_' . $table . '_'); $table_dd = dd_tableRef($table); SQLX_Insert($table_dd, $cols); gpSet('gp_skey', $parent_skey); } }
function hBoxes($mode) { // Obtain a row depending on the mode we are in. If there // wdas an error then reload the first row for this table if (is_array(vgfGet('ErrorRow_' . $this->table_id, ''))) { $row = vgfGet('ErrorRow_' . $this->table_id); $row['skey'] = gp('gpx_skey'); } else { switch ($mode) { case 'search': // if a previous search, use that, else fall through // to using current row $row = ConGet('table', $this->table_id, 'search', array()); if (count($row) != 0) { break; } case 'ins': $row = DrillDownMatches(); if (count($row) == 0) { $row = aFromGP('pre_'); } // KFD 8/13/07, part of COPY ability if (gp('gp_action') == 'copy') { $row2 = SQL_OneRow("SELECT * FROM " . $this->table_id . " where skey=" . SQLFN(gp('gp_skey'))); foreach ($row2 as $column_id => $colvalue) { if (is_numeric($column_id)) { continue; } if (!isset($this->table['flat'][$column_id])) { continue; } $aid = $this->table['flat'][$column_id]['automation_id']; if ($aid == 'SEQUENCE' || $column_id == gp('gp_exclude')) { unset($row2[$column_id]); } } $row = array_merge($row, $row2); } break; case 'upd': $skey = gp('gp_skey'); hidden('gp_skey', ''); if (trim($skey) == '') { $row = array(); } else { $skey = " WHERE skey=" . $skey; $sq = "Select * FROM " . $this->view_id . $skey; $row = SQL_OneRow($sq); } } } // Save the row for other routines $this->row = $row; // Find out what skey we are on, give a next/prev // kind of button for stuff like that. // Set the next/prev stuff based on rows $HTML_PagePrev = $HTML_PageNext = $HTML_ViewingPage = ""; if ($mode == "upd") { $lprev = $lnext = false; $skey = $this->row['skey']; $sess_skeys = ConGet("table", $this->table_id, "skeys", array()); if (count($sess_skeys) > 1) { $sess_srows = array_flip($sess_skeys); $sess_srow = $sess_srows[$row['skey']]; $lprev = $sess_srow == 0 ? false : true; $skeyf = $sess_srow == 0 ? 0 : $sess_skeys[0]; $skeyp = $sess_srow == 0 ? 0 : $sess_skeys[$sess_srow - 1]; $skeyn = $sess_srow >= count($sess_srows) - 1 ? 0 : $sess_skeys[$sess_srow + 1]; $skeyl = $sess_srow >= count($sess_srows) - 1 ? 0 : $sess_skeys[count($sess_srows) - 1]; $hprev = hLinkImage('first', 'First', 'gp_skey', $skeyf, $lprev) . hLinkImage('previous', 'Previous', 'gp_skey', $skeyp, $lprev); $lnext = $sess_srow < count($sess_srows) - 1 ? true : false; $hnext = hLinkImage('next', 'Next', 'gp_skey', $skeyn, $lnext) . hLinkImage('last', 'Last', 'gp_skey', $skeyl, $lnext); $HTML_ViewingPage = "Page " . ($sess_srow + 1) . " of " . count($sess_srows); } } // Output and save the navbar ob_start(); if ($HTML_ViewingPage != '') { $hprev = $this->hTextButton('\\First', 'gp_skey', $skeyf, $lprev) . $this->hTextButton('\\Previous', 'gp_skey', $skeyp, $lprev); $hnext = $this->hTextButton('Ne\\xt', 'gp_skey', $skeyn, $lnext) . $this->hTextButton('Las\\t', 'gp_skey', $skeyl, $lnext); if (vgfget('buttons_in_commands')) { $this->h['NavBar'] = ''; vgfSet('html_navbar', $hprev . $hnext); } else { $this->h['NavBar'] = "\n<div class=\"x2menubar\">\n" . $hprev . $HTML_ViewingPage . " " . $hnext . "\n</div><br>"; } } // Second output is main content // KFD 8/9/07, Project DUPECHECK // If a "dupecheck" projection exists, and they are // doing a new entry, we first ask them to enter // those values $dc = ArraySafe($this->table['projections'], 'dupecheck'); if ($dc != '' && $mode == 'ins' && !gpExists('gp_nodupecheck')) { hidden('gp_action', 'dupecheck'); $this->h['Content'] = $this->hBoxesX3($mode, 'dupecheck'); $this->h['Content'] .= '<br/><br/>' . '<button class="btn btn-primary id="object_for_enter" onclick="formSubmit()">(ENTER) Check For Duplicates</button>'; } else { $this->h['Content'] = $this->hBoxesDefault($mode); } }
function checkboxSave() { $row = aFromGP('cbval_'); x6Data('row', $row); $table_id = gp('x6page'); if (gp('checked') == 'true') { SQLX_Insert($table_id, $row); } else { SQLX_Delete($table_id, $row); } }
function index_hidden_page() { global $AG; $sessok = !LoggedIn() ? false : true; // KFD 3/6/08, moved here from the main stream of index_hidden // because these are relevant only to page processing if (gpExists('x_module')) { SessionSet('AGMENU_MODULE', gp('x_module')); } elseif (vgaGet('nomodule') != '' && SessionGet('AGMENU_MODULE') == '') { SessionSet('AGMENU_MODULE', vgaGet('nomodule')); } // If the search flag is set, we need to know what class for this // application handles searchs if (gpExists('gp_search')) { gpSet('gp_page', vgaGet('SEARCH_CLASS')); } // Load up a list of pages that public users are allowed to see, // with home and password always there. global $MPPages; // allows it to be in applib $MP = array(); //$MPPages= array(); // This is the old method, load $MPPages from its own file if (file_exists_incpath('appPublicMenu.php')) { include_once 'appPublicMenu.php'; } if (!is_array($MPPages)) { $MPPages = array(); } $MPPages['x_home'] = 'Home Page'; $MPPages['x_login'] = '******'; $MPPages['x_noauth'] = 'Authorization Required'; $MPPages['x_password'] = "******"; $MPPages['x_mpassword'] = "******"; $MPPages['x_paypalipn'] = 'Paypal IPN'; // If the install page exists, it will be used, no getting // around it. $install = $GLOBALS['AG']['dirs']['application'] . 'install.php'; $instal2 = $GLOBALS['AG']['dirs']['application'] . 'install.done.php'; if (file_exists($install)) { if (gp('gp_install') == 'finish') { rename($install, $instal2); } else { $MPPages['install'] = 'install'; gpSet('gp_page', 'install'); } } // First pass is to look for the "flaglogin" flag. This says save all // current page settings and go to login screen. They will be restored // on a successful login. Very useful for links that say "Login to // see nifty stuff..." if (gp('gp_flaglogin') == '1') { gpSet('gp_flaglogin', ''); gpToSession(); gpSet('gp_page', 'x_login'); } // Second pass redirection, pick default page if there // is none, and verify public pages. // $gp_page = gp('gp_page'); if ($gp_page == '') { if (vgfGet('LoginAttemptOK') === true && vgfGet('x4') === true) { $gp_page = 'x4init'; gpSet('gp_page', 'x4init'); SessionSet('TEMPLATE', 'x4'); } else { if (function_exists('appNoPage')) { $gp_page = appNoPage(); } else { if (!LoggedIn()) { $gp_page = FILE_EXISTS_INCPATH('x_home.php') ? 'x_home' : 'x_login'; } else { // KFD 3/2/07, pull vga stuff to figure defaults if (vgaGet('nopage') != '') { $gp_page = vgaGet('nopage'); } else { $gp_page = 'x_welcome'; } } } } } // If they are trying to access a restricted page and are not // logged in, cache their request and redirect to login page if (!$sessok && !isset($MPPages[$gp_page])) { if (vgfGet('loglogins', false)) { fwLogEntry('1014', 'Page access w/o login', $gp_page); } gpToSession(); $gp_page = 'x_login'; } // If pos is activated and the current requested page does not // match what they are cleared for, redirect to login if (vgaGet('POS_SECURITY', false) == true && SessionGet('ADMIN') == false) { if (SessionGet('POS_PAGE', '', 'FW') != $gp_page) { gpToSession(); $gp_page = 'x_login'; } } gpSet('gp_page', $gp_page); // Make any database saves. Do this universally, even if save // was not selected. If errors, reset to previous request. //if(gp('gp_save')=='1') processPost(); processPost(); if (Errors()) { gpSetFromArray('gp_', aFromGp('gpx_')); } // Put Userid where HTML forms can find it //vgfSet("UID",SessionGet("UID")); //if (vgfSet("UID")=="") { vgfSet("UID","Not Logged In"); } // THIS IS NEWER X_TABLE2 version of drilldown commands, // considerably simpler than the older ones. It makes use of // three gp_dd variables. // // Notice how we process drillbacks FIRST, allowing a link // to contain both drillback and drilldown, for the super-nifty // effect of a "drill-across" hidden('gp_dd_page'); hidden('gp_dd_skey'); hidden('gp_dd_back'); if (intval(gp('gp_dd_back')) > 0 && $sessok) { // this is drillback $dd = ContextGet('drilldown', array()); $back = intval(gp('gp_dd_back')); if (count($dd) >= $back) { $spot = count($dd) - $back; $aback = $dd[$spot]; gpSet('gp_skey', $aback['skey']); gpSet('gp_page', $aback['page']); $gp_page = $aback['page']; gpSet('gpx_skey', $aback['skey']); gpSet('gpx_page', $aback['page']); gpSetFromArray('parent_', $aback['parent']); if (!gpExists('gp_mode')) { gpSet('gp_mode', 'upd'); } $dd = $spot == 0 ? array() : array_slice($dd, 0, $spot); ContextSet('drilldown', $dd); ContextSet('drilldown_top', $aback['page']); //ContextSet('drilldown_level',count($dd)); } } if (gp('gp_dd_page') != '' && $sessok) { // this is drilldown... $matches = DrillDownMatches(); $matches = array_merge($matches, aFromGP('parent_')); $dd = ContextGet('drilldown', array()); $newdd = array('matches' => $matches, 'parent' => aFromGP('parent_'), 'skey' => gp('gpx_skey'), 'page' => gp('gpx_page')); $dd[] = $newdd; ContextSet('drilldown', $dd); ContextSet('drilldown_top', gp('gp_dd_page')); //ContextSet('drilldown_level',count($dd)); // having saved the stack, redirect to new page. $tnew = gp('gp_dd_page'); $gp_page = $tnew; gpSet('gp_page', $tnew); if (gp('gp_dd_skey') != '') { gpSet('gp_skey', gp('gp_dd_skey')); gpSet('gp_mode', 'upd'); } // Clear search of new page, set filters to blank processPost_TableSearchResultsClear($tnew); ConSet('table', $tnew, 'search', array()); } // If no drilldown commands were received, and we are not on // the page that is the top, user must have picked a new page // altogether, wipe out the drilldown stack if (gp('gp_page') != ContextGet('drilldown_top', '')) { ContextSet('drilldown', array()); ContextSet('drilldown_top', ''); } // Must always have these on the user's form. These can // be retired with x_Table, they are for old drilldown // hidden("dd_page", ""); hidden("dd_ddc", ""); hidden("dd_ddv", ""); hidden("dd_ddback", ""); hidden("dd_action", "searchexecute"); hidden("dd_skey", ""); // Load user preferences just before display UserPrefsLoad(); $dir = $GLOBALS['AG']['dirs']['root'] . 'application/'; if (file_exists($dir . $gp_page . ".page.yaml")) { include 'androPage.php'; $obj_page = new androPage(); if ($obj_page->flag_buffer) { ob_start(); } $obj_page->main($gp_page); if ($obj_page->flag_buffer) { vgfSet("HTML", ob_get_clean()); //ob_end_clean(); } vgfSet("PageSubtitle", $obj_page->PageSubtitle); } else { $obj_page = DispatchObject($gp_page); if ($obj_page->flag_buffer) { ob_start(); } $obj_page->main(); if ($obj_page->flag_buffer && vgfGet('HTML') == '') { vgfSet("HTML", ob_get_contents()); ob_end_clean(); } vgfSet("PageSubtitle", $obj_page->PageSubtitle); } // Save context onto the page. Note that it is not really // protected by these methods, just compressed and obscured. // $t2 = serialize($GLOBALS['AG']['clean']['gpContext']); $t2 = gzcompress($t2); $t2 = base64_encode($t2); Hidden('gpContext', $t2); // KFD 3/7/07, give the app the final opportunity to process // things before the display, while logged in. if (function_exists('appdisplaypre')) { appDisplayPre(); } // ...and write output and we are done. Assume if there was // no buffering that the output is already done. if ($obj_page->flag_buffer != false) { // Work out what template we are using index_hidden_template('x2'); // KFD 5/30/07, send back only main content if asked if (gp('ajxBUFFER') == 1) { echo "andromeda_main_content|"; ehStandardContent(); echo "|-|_focus|" . vgfGet('HTML_focus'); $ajax = ElementReturn('ajax', array()); echo '|-|' . implode('|-|', $ajax); echo '|-|_title|' . vgfGet('PageTitle'); } elseif (defined('_VALID_MOS')) { // This is the default branch, using a Joomla template // DUPLICATE ALERT: This code copied into // index_hidden_x4Dispatch() above global $J; $mainframe = $J['mainframe']; $my = $J['my']; $mosConfig_absolute_path = $J['mC_absolute_path']; $mosConfig_live_site = $J['mC_live_site']; $template_color = $J['template_color']; $template_color = 'red'; $file = $GLOBALS['AG']['dirs']['root'] . '/templates/' . $mainframe->GetTemplate() . "/index.php"; include $file; } elseif ($obj_page->html_template !== '') { // This is newer style, let the class specify the template. include $obj_page->html_template . '.php'; } else { // This is old style, defaults to "html_main.php", can be // set also by vgaSet() or by gp(gp_out) $html_main = vgaGet('html_main') == '' ? 'html_main' : vgaGet('html_main'); switch (CleanGet("gp_out", "", false)) { case "print": include "html_print.php"; break; case "info": include "html_info.php"; break; case "": include $html_main . ".php"; break; default: } } } }