'url here' which contains a data key and the value is a string which contains items in the format: key=STRING, age=INTEGER. My goal is to count how many items exist that have an age equal to or greater than 50, and print this final value.
$ch = curl_init('url here');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, 0);
$data = curl_exec($ch);
curl_close($ch);
print_r(json_decode($data, true));
$data getting data as follows:
Array
(
[data] => key=IAfpK, age=58,
key=WNVdi, age=64,
key=jp9zt, age=47,
key=0Sr4C, age=68,
key=CGEqo, age=76,
key=IxKVQ, age=79, key=eD221, age=29, key=XZbHV, age=32, key=k1SN5, age=88, key=4SCsU, age=65, key=q3kG6, age=33, key=MGQpf, age=13, key=Kj6xW, age=14, key=tg2VM, age=30, key=WSnCU, age=24, key=f1Vvz, age=46, key=dOS7A, age=72, key=tDojg, age=82, key=nZyJA, age=48, key=R8JTk, age=29, key=005Ot, age=66, key=HHROm, age=12, key=5yzG8, age=51, key=xMJ5D, age=38, key=TXtVu, age=82, key=Hz38B, age=84, key=WfObU, age=27, key=mmqYB, age=14, key=4Z3Ay, age=62, key=x3B0i, age=55, key=QCiQB, age=72, key=zGtmR, age=66, key=nlIN9, age=8, key=hKalB, age=50, key=Na33O, age=17, key=jMeXm, age=15, key=OO2Mc, age=32, key=hhowx, age=32 )
Not getting how to match value and get count.
Example Input
{"data":"key=IAfpK, age=58, key=WNVdi, age=64, key=jp9zt, age=47"}
Example Output
2
If anyone have idea then please let me know
I originally missed the over 50 part.
If your goal is to just count, and your data is as uniform as you say, you can still just search on age= followed by one or more digits using RegEx, then count the over 50 items:
$data = 'key=IAfpK, age=58, key=WNVdi, age=64, key=jp9zt, age=47';
$itemsOverFifty = [];
if(preg_match_all('/age=(?<age>\d+)/', $data, $matches)) {
$itemsOverFifty = array_filter($matches['age'], fn($item) => $item >= 50 );
}
echo count($itemsOverFifty);
Demo: https://3v4l.org/8eqnR
This is rather messy and a REGEX person may be able to clean this up a bit, but it seems to work
function fixTheNonsenseJson($nonsense)
{
$a = json_decode($nonsense);
$s = str_replace( ['key=', ', age=', ', "key'], ['"key":"', '","age":"', '", "key'], $a->data);
$bits = explode(',', $s);
$usable = [];
foreach ($bits as $bit) {
$j = json_decode('{' . $bit. '}');
if ( isset($j->key) ) {
$t = new stdClass();
$t->key = $j->key;
}
if ( isset($j->age) ) {
$t->age = $j->age;
$usable[] = $t;
$t = null;
}
}
return $usable;
}
$badJson = '{"data" : "key=IAfpK, age=58, key=WNVdi, age=64, key=jp9zt, age=47, key=0Sr4C, age=68, key=CGEqo, age=76, key=IxKVQ, age=79, key=eD221, age=29, key=XZbHV, age=32, key=k1SN5, age=88, key=4SCsU, age=65, key=q3kG6, age=33, key=MGQpf, age=13, key=Kj6xW, age=14, key=tg2VM, age=30, key=WSnCU, age=24, key=f1Vvz, age=46, key=dOS7A, age=72, key=tDojg, age=82, key=nZyJA, age=48, key=R8JTk, age=29, key=005Ot, age=66, key=HHROm, age=12, key=5yzG8, age=51, key=xMJ5D, age=38, key=TXtVu, age=82, key=Hz38B, age=84, key=WfObU, age=27, key=mmqYB, age=14, key=4Z3Ay, age=62, key=x3B0i, age=55, key=QCiQB, age=72, key=zGtmR, age=66, key=nlIN9, age=8, key=hKalB, age=50, key=Na33O, age=17, key=jMeXm, age=15, key=OO2Mc, age=32, key=hhowx, age=32"}';
$usable = fixTheNonsenseJson($badJson);
// the actual code to do the count
$count = 0;
foreach( $usable as $u){
if ( $u->age > 50 ) {
$count++;
}
}
echo "Count > 50 = $count";
Related
Country.csv
this is countries.csv file, and i want to extract all the timezones from it, which is its 14th colomn, and the data in there is not properly json formatted. I'm trying to parse the json but it failed. Actually, I want to create an array of timezones like this
[0] => {zoneName:'Asia -> Kabul',gmtOffset:16200,gmtOffsetName:'UTC+04:30',abbreviation:'AFT',tzName:'Afghanistan Time'}
[1] => {zoneName:'Europe -> Mariehamn',gmtOffset:7200,gmtOffsetName:'UTC+02:00',abbreviation:'EET',tzName:'Eastern European Time'}
[2] => {zoneName:'Europe -> Tirane',gmtOffset:3600,gmtOffsetName:'UTC+01:00',abbreviation:'CET',tzName:'Central European Time'}
[3] => {zoneName:'Africa -> Algiers',gmtOffset:3600,gmtOffsetName:'UTC+01:00',abbreviation:'CET',tzName:'Central European Time'}
[4] => {zoneName:'Pacific -> Pago_Pago',gmtOffset:-39600,gmtOffsetName:'UTC-11:00',abbreviation:'SST',tzName:'Samoa Standard Time'}
[5] => {zoneName:'Europe -> Andorra',gmtOffset:3600,gmtOffsetName:'UTC+01:00',abbreviation:'CET',tzName:'Central European Time'}
[6] => {zoneName:'Africa -> Luanda',gmtOffset:3600,gmtOffsetName:'UTC+01:00',abbreviation:'WAT',tzName:'West Africa Time'}
what i'm doing, is this in App\Http\Controllers\TestController::class is this
public function timezone(): void {
$data = [];
if (($open = fopen(__DIR__ . '/countries.csv', 'r + b')) !== FALSE) {
while (($singleRecord = fgetcsv($open, NULL, ',')) !== FALSE) {
$data[] = $singleRecord;
}
fclose($open);
}
$data = $this->removeCharacters($data, ['[', ']']);
$data = $this->removeCharacters($data, (array)'\/', " -> ");
// $data = $this->removeCharacters($data, (array)'{}', '');
// dd(explode('},', $data[33][14]));
// dd(explode('},', $this->longJson));
// dd(explode(',', str_replace(['{', '}'], '', $data[167][14])));
$singleArray = [];
$count = count($data);
$itemsArray = [];
for ($i = 1; $i < $count; $i++) {
$singleArray[] = explode('},', $data[$i][14]);
foreach ($singleArray as $item) {
foreach ($item as $singleItem) {
$itemsArray[] = $singleItem;
}
}
}
$itemsArray = array_unique($itemsArray);
$this->printFormattedData($itemsArray);
}
private function removeCharacters($hayStack, array $charsArray, $character = ''): array {
$tempArray = [];
foreach ($hayStack as $item) {
$tempArray[] = str_replace($charsArray, $character, $item);
}
return $tempArray;
}
private function printFormattedData($data): void {
echo '<pre>';
print_r($data);
echo '</pre>';
}
Using regexp its not perfect solution, but you can transform timezone data to correct json format using function like this:
public function fixJson(string $str): string {
return preg_replace(
'/(?<=(\{|\,))(\w+)(?=\:)/',
'"$2"',
str_replace("'", '"', $zoneRaw) // may not work properly, if values may contain apostroph symbols, but seems not actual for your case
);
}
So, use this function:
$this->fixJson($data[$i][14]); // returns json string
json_decode($this->fixJson($data[$i][14])); // returns json decoded array
See usage example here https://sandbox.onlinephpfunctions.com/c/88f21
Following code would do, what you aim.
Please do not forget to mark this answer as ACCEPTED and thumbs up if it solves your problem, so that the work of the developers who help is appreciated and other developers can see in question list, that your question has already an accepted answer.
$lines = file("countries.csv");
array_shift($lines); // remove the first line with column names
$searchReplace = ['\/' => '->'];
$search = array_keys($searchReplace);
$replace = array_values($searchReplace);
$jsonFormattedTimeZones = [];
foreach($lines as $line)
{
$line = trim(str_getcsv($line)[14], " []");
$line = str_replace($search, $replace, $line);
$jsonFormattedTimeZones[] = $line;
}
print_r($jsonFormattedTimeZones);
I'm trying to filter an array (derived from a json object), so as to return the array key based on the value. I'm not sure if array search $key = array_search($value, $array); is the best way to do this (I can't make it work), and I think there must be a better way.
So far I've got this, but it isn't working. Grateful for any help!
public function getBedroomData(array $data,$num_beds = null,$type) {
$data = (array) $data;
if($num_beds > 0) {
$searchstring = "avg_".$num_beds."bed_property_".$type."_monthly";
} else {
$searchstring = "avg_property_".$type."_monthly";
}
$avg_string = array_search($data, $searchstring);
return $avg_string;
}
The array consists of average property prices taken from the nestoria api as follows:
http://api.nestoria.co.uk/api?country=uk&pretty=1&action=metadata&place_name=Clapham&price_type=fixed&encoding=json
This returns a long json object. My problem is that the data isn't consistent - and I'm looking for the quickest (run time) way to do the following:
$data['response']['metadata']['0'] //= data to return, [0] unknown
$data['response']['metadata']['0']['metadata_name'] = "avg_1bed_property_rent_monthly" //= string I know!
$data['response']['metadata']['1'] //= data to return, [1] unknown
$data['response']['metadata']['1']['metadata_name'] = "avg_1bed_property_buy_monthly" //= string I know!
$data['response']['metadata']['2'] = //= data to return, [2] unknown
$data['response']['metadata']['2']['metadata_name'] = "avg_2bed_property_buy_monthly" //= string I know!
.....
.....
.....
$data['response']['metadata']['10'] = avg_property_rent_monthly
$data['response']['metadata']['11'] = avg_property_buy_monthly
$data['response']['metadata'][most_recent_month] = the month reference for getting the data from each metadata list..
It isn't possible to filter the initial search query by number of bedrooms as far as I can work out. So, I've just been array slicing the output to get the information I've needed if bedrooms are selected, but as the data isn't consistent this often fails.
To search inside that particular json response from nestoria, a simple foreach loop can be used. First off, of course call the json data that you need. Then, extract the whole data, the the next step if pretty straightforward. Consider this example:
$url = 'http://api.nestoria.co.uk/api?country=uk&pretty=1&action=metadata&place_name=Clapham&price_type=fixed&encoding=json';
$contents = file_get_contents($url);
$data = json_decode($contents, true);
$metadata = $data['response']['metadata'];
// dummy values
$num_beds = 1; // null or 0 or greater than 0
$type = 'buy'; // buy or rent
function getBedroomData($metadata, $num_beds = null, $type) {
$data = array();
$searchstring = (!$num_beds) ? "avg_property_".$type."_monthly" : "avg_".$num_beds."bed_property_".$type."_monthly";
$data['metadata_name'] = $searchstring;
$data['data'] = null;
foreach($metadata as $key => $value) {
if($value['metadata_name'] == $searchstring) {
$raw_data = $value['data']; // main data
// average price and data points
$avg_price = 0;
$data_points = 0;
foreach($raw_data as $index => $element) {
$avg_price += $element['avg_price'];
$data_points += $element['datapoints'];
}
$data_count = count($raw_data);
$price_average = $avg_price / $data_count;
$data_points_average = $data_points / $data_count;
$data['data'][] = array(
'average_price' => $price_average,
'average_datapoints' => $data_points_average,
'data' => $raw_data,
);
}
}
return $data;
}
$final = getBedroomData($metadata, $num_beds, $type);
print_r($final);
Let's say I have this string which I want to put in a multidimensional array.
Edit : The number of subfolders in the string are dynamic .. from zero sub folders to 10
<?php
$string ="Folder1/Folder2/Folder3/filename1\n";
$string .=" Folder1/Folder2/Folder3/filename2\n";
$string .=" Folder4/Folder2/Folder3/filename3\n";
?>
I want the following array returned
<?php
Array
(
[Folder1] => Array
(
[Folder2] => Array
(
[Folder3] => Array
(
[0] => filename1
[1] => filename2
)
)
)
[Folder4] => Array
(
[Folder2] => Array
(
[Folder3] => Array
(
[0] => filename3
)
)
)
)
?>
What would be the most efficient way to accomplish this ?
And for the fun of it let's say this array will be send to the other side of the world and it wants to return to a string. How would we do that ?
You could borrow pieces of code from this class (link no longer available), specifically the _processContentEntry method.
Here's a modified version of the method that does the job:
function stringToArray($path)
{
$separator = '/';
$pos = strpos($path, $separator);
if ($pos === false) {
return array($path);
}
$key = substr($path, 0, $pos);
$path = substr($path, $pos + 1);
$result = array(
$key => stringToArray($path),
);
return $result;
}
The output of
var_dump(stringToArray('a/b/c/d'));
Will be
array(1) {
["a"]=>
array(1) {
["b"]=>
array(1) {
["c"]=>
array(1) {
[0]=>
string(1) "d"
}
}
}
}
I suppose that's what you need :)
UPDATE
As per your comment, here's how you can process a string separated by new line characters:
$string = "Folder1/Folder2/Folder3/filename1\n";
$string .= " Folder1/Folder2/Folder3/filename2\n";
$string .= " Folder4/Folder2/Folder3/filename3\n";
// split string into lines
$lines = explode(PHP_EOL, $string);
// trim all entries
$lines = array_map('trim', $lines);
// remove all empty entries
$lines = array_filter($lines);
$output = array();
// process each path
foreach ($lines as $line) {
// split each line by /
$struct = stringToArray($line);
// merge new path into the output array
$output = array_merge_recursive($output, $struct);
}
print_r($output);
P.S.
To convert this array to a string, just call json_encode, however I see no reason to convert it to an array and then back to what it was.
I think this what you want,
$string ="Folder1/Folder2/Folder3/filename1\n";
$string .="Folder1/Folder2/Folder3/filename2\n";
$string .="Folder4/Folder2/Folder3/filename3\n";
$string_array_1 = explode("\n", $string);
$array_need = array();
foreach($string_array_1 as $array_values)
{
if($array_values)
{
$folders = explode("/", $array_values);
$array_need[$folders[0]][$folders[1]][$folders[2]][] = $folders[3];
}
}
print_r($array_need);
This can be solved recursively in another way by taking the items from the beginning of the array and when the last item is reached just return it.
function make_tree( $arr ){
if( count($arr) === 1){
return array_pop( $arr );
}else{
$result[ array_shift( $arr )] = make_tree( $arr ) ;
}
return $result;
}
$string = "Folder1/Folder2/Folder3/filename1\n";
$string .= "Folder1/Folder2/Folder3/filename2\n";
$string .= "Folder4/Folder2/Folder3/filename3\n";
$string = trim( $string );
$files_paths = explode( PHP_EOL, $string);
$result = [];
foreach ($files_paths as $key => $value) {
$parted = explode( '/', $value );
$tree = make_tree( $parted );
$result = array_merge_recursive( $result, $tree );
}
var_dump( $result );
I'm retrieving data from Yahoo Weather currently and able to display the elements I need so far. I'm stumped on how to use the Condition Codes (i think i need to turn the number into an integer) to have a string such that I can display my own custom icons. As the weather in the region I am tracking is fairly mild I want to assign only a small number of icons but have each cover a string of Condition Codes. So far this is my code that is working–
function bm_getWeather ($code = '', $temp = 'c') {
$file = 'http://weather.yahooapis.com/forecastrss?w=' . $code . '&u=' . $temp;
$request = new WP_Http;
$result = $request->request($file);
if (isset($result->errors)) {
return FALSE;
}
$data = $result['body'];
$output = array (
'temperature' => bm_getWeatherProperties('temp', $data),
'weather_code' => bm_getWeatherProperties('code', $data),
'class' => bm_getWeatherProperties('code', $data),
'weather' => bm_getWeatherProperties('text', $data),
);
return $output;
}
function weather_icon() {
$data = bm_getWeather($code = '', $temp = 'c');
// Error is here
$nums = (int)$data['weather_code']; // Needs to be cast as an integer
$severe = array(12, 13, 14, 16, 19);
$rain = array(3200);
// Therefore the maths is wrong
switch($nums) {
case (in_array($nums, $severe)):
$cat = 'severe';
break;
case (in_array($nums,$rain)):
$cat = 'snow';
break;
default:
$cat = 'happy';
break;
}
return $cat;
}
function bm_getWeatherProperties ($needle, $data) {
$regex = '<yweather:condition.*' . $needle . '="(.*?)".*/>';
preg_match($regex, $data, $matches);
return (string)$matches[1];
}
Any help would be much appreciated as my php skills are less than adequate right now.
I have an array of my inventory (ITEMS A & B)
Items A & B are sold as sets of 1 x A & 2 x B.
The items also have various properties which don't affect how they are distributed into sets.
For example:
$inventory=array(
array("A","PINK"),
array("A","MAUVE"),
array("A","ORANGE"),
array("A","GREY"),
array("B","RED"),
array("B","BLUE"),
array("B","YELLOW"),
array("B","GREEN"),
array("B","BLACK")
);
I want to redistribute the array $inventory to create $set(s) such that
$set[0] => Array
(
[0] => array(A,PINK)
[1] => array(B,RED)
[2] => array(B,BLUE)
)
$set[1] => Array
(
[0] => array(A,MAUVE)
[1] => array(B,YELLOW)
[2] => array(B,GREEN)
)
$set[2] => Array
(
[0] => array(A,ORANGE)
[1] => array(B,BLACK)
[2] => NULL
)
$set[3] => Array
(
[0] => array(A,GREY)
[1] => NULL
[2] => NULL
)
As you can see. The items are redistributed in the order in which they appear in the inventory to create a set of 1 x A & 2 x B. The colour doesn't matter when creating the set. But I need to be able to find out what colour went into which set after the $set array is created. Sets are created until all inventory is exhausted. Where an inventory item doesn't exist to go into a set, a NULL value is inserted.
Thanks in advance!
I've assumed that all A's come before all B's:
$inventory=array(
array("A","PINK"),
array("A","MAUVE"),
array("A","ORANGE"),
array("A","GREY"),
array("B","RED"),
array("B","BLUE"),
array("B","YELLOW"),
array("B","GREEN"),
array("B","BLACK")
);
for($b_start_index = 0;$b_start_index<count($inventory);$b_start_index++) {
if($inventory[$b_start_index][0] == 'B') {
break;
}
}
$set = array();
for($i=0,$j=$b_start_index;$i!=$b_start_index;$i++,$j+=2) {
isset($inventory[$j])?$temp1=$inventory[$j]:$temp1 = null;
isset($inventory[$j+1])?$temp2=$inventory[$j+1]:$temp2 = null;
$set[] = array( $inventory[$i], $temp1, $temp2);
}
To make it easier to use your array, you should make it something like this
$inv['A'] = array(
'PINK',
'MAUVE',
'ORANGE',
'GREY'
);
$inv['B'] = array(
'RED',
'BLUE',
'YELLOW',
'GREEN',
'BLACK'
);
This way you can loop through them separately.
$createdSets = $setsRecord = $bTemp = array();
$bMarker = 1;
$aIndex = $bIndex = 0;
foreach($inv['A'] as $singles){
$bTemp[] = $singles;
$setsRecord[$singles][] = $aIndex;
for($i=$bIndex; $i < ($bMarker*2); ++$i) {
//echo $bIndex.' - '.($bMarker*2).'<br/>';
if(empty($inv['B'][$i])) {
$bTemp[] = 'null';
} else {
$bTemp[] = $inv['B'][$i];
$setsRecord[$inv['B'][$i]][] = $aIndex;
}
}
$createdSets[] = $bTemp;
$bTemp = array();
++$bMarker;
++$aIndex;
$bIndex = $bIndex + 2;
}
echo '<pre>';
print_r($createdSets);
print_r($setsRecord);
echo '</pre>';
To turn your array into an associative array, something like this can be done
<?php
$inventory=array(
array("A","PINK"),
array("A","MAUVE"),
array("A","ORANGE"),
array("A","GREY"),
array("B","RED"),
array("B","BLUE"),
array("B","YELLOW"),
array("B","GREEN"),
array("B","BLACK")
);
$inv = array();
foreach($inventory as $item){
$inv[$item[0]][] = $item[1];
}
echo '<pre>';
print_r($inv);
echo '</pre>';
Maybe you can use this function, assuming that:
... $inventory is already sorted (all A come before B)
... $inventory is a numeric array staring at index zero
// $set is the collection to which the generated sets are appended
// $inventory is your inventory, see the assumptions above
// $aCount - the number of A elements in a set
// $bCount - the number of B elements in a set
function makeSets(array &$sets, array $inventory, $aCount, $bCount) {
// extract $aItems from $inventory and shorten $inventory by $aCount
$aItems = array_splice($inventory, 0, $aCount);
$bItems = array();
// iterate over $inventory until a B item is found
foreach($inventory as $index => $item) {
if($item[0] == 'B') {
// extract $bItems from $inventory and shorten $inventory by $bCount
// break out of foreach loop after that
$bItems = array_splice($inventory, $index, $bCount);
break;
}
}
// append $aItems and $bItems to $sets, padd this array with null if
// less then $aCount + $bCount added
$sets[] = array_pad(array_merge($aItems, $bItems), $aCount + $bCount, null);
// if there are still values left in $inventory, call 'makeSets' again
if(count($inventory) > 0) makeSets($sets, $inventory, $aCount, $bCount);
}
$sets = array();
makeSets($sets, $inventory, 1, 2);
print_r($sets);
Since you mentioned that you dont have that much experience with arrays, here are the links to the php documentation for the functions I used in the above code:
array_splice — Remove a portion of the array and replace it with something else
array_merge — Merge one or more arrays
array_pad — Pad array to the specified length with a value
This code sorts inventory without any assumption on inventory ordering. You can specify pattern (in $aPattern), and order is obeyed. It also fills lacking entries with given default value.
<?php
# config
$aInventory=array(
array("A","PINK"),
array("A","MAUVE"),
array("A","ORANGE"),
array("A","GREY"),
array("B","RED"),
array("B","BLUE"),
array("B","YELLOW"),
array("B","GREEN"),
array("B","BLACK"),
array("C","cRED"),
array("C","cBLUE"),
array("C","cYELLOW"),
array("C","cGREEN"),
array("C","cBLACK")
);
$aPattern = array('A','B','A','C');
$mDefault = null;
# preparation
$aCounter = array_count_values($aPattern);
$aCurrentCounter = $aCurrentIndex = array_fill_keys(array_unique($aPattern),0);
$aPositions = array();
$aFill = array();
foreach ($aPattern as $nPosition=>$sElement){
$aPositions[$sElement] = array_keys($aPattern, $sElement);
$aFill[$sElement] = array_fill_keys($aPositions[$sElement], $mDefault);
} // foreach
$nTotalLine = count ($aPattern);
$aResult = array();
# main loop
foreach ($aInventory as $aItem){
$sElement = $aItem[0];
$nNeed = $aCounter[$sElement];
$nHas = $aCurrentCounter[$sElement];
if ($nHas == $nNeed){
$aCurrentIndex[$sElement]++;
$aCurrentCounter[$sElement] = 1;
} else {
$aCurrentCounter[$sElement]++;
} // if
$nCurrentIndex = $aCurrentIndex[$sElement];
if (!isset($aResult[$nCurrentIndex])){
$aResult[$nCurrentIndex] = array();
} // if
$nCurrentPosition = $aPositions[$sElement][$aCurrentCounter[$sElement]-1];
$aResult[$nCurrentIndex][$nCurrentPosition] = $aItem;
} // foreach
foreach ($aResult as &$aLine){
if (count($aLine)<$nTotalLine){
foreach ($aPositions as $sElement=>$aElementPositions){
$nCurrentElements = count(array_keys($aLine,$sElement));
if ($aCounter[$sElement] != $nCurrentElements){
$aLine = $aLine + $aFill[$sElement];
} // if
} // foreach
} // if
ksort($aLine);
# add empty items here
} // foreach
# output
var_dump($aResult);
Generic solution that requires you to specify a pattern of the form
$pattern = array('A','B','B');
The output will be in
$result = array();
The code :
// Convert to associative array
$inv = array();
foreach($inventory as $item)
$inv[$item[0]][] = $item[1];
// Position counters : int -> int
$count = array_fill(0, count($pattern),0);
$out = 0; // Number of counters that are "out" == "too far"
// Progression
while($out < count($count))
{
$elem = array();
// Select and increment corresponding counter
foreach($pattern as $i => $pat)
{
$elem[] = $inv[ $pat ][ $count[$i]++ ];
if($count[$i] == count($inv[$pat]))
$out++;
}
$result[] = $elem;
}