protected function queryLoad($ids) { $multifields = multifield_get_fields(); foreach (array_keys($multifields) as $field_name) { $query = new EntityFieldQuery(); if ($ids) { $query->fieldCondition($field_name, 'id', $ids, 'IN'); } else { $query->fieldCondition($field_name, 'id', 0, '>'); } if ($results = $query->execute()) { $pseudo_entities = array(); $field = field_info_field($field_name); foreach ($results as $entity_type => $entities) { // Simply doing an entity load on the entities with multifield values // will cause the cacheSet() from multifield_field_load() to get // invoked. $entities = entity_load($entity_type, array_keys($entities)); foreach ($entities as $entity) { if ($items = field_get_items($entity_type, $entity, $field_name)) { foreach ($items as $item) { $pseudo_entities[$item['id']] = _multifield_field_item_to_entity($field['type'], $item); } } } } $this->cacheSet($pseudo_entities); } } return array_intersect_key($this->entityCache, drupal_map_assoc($ids, $ids)); }
private function scanReports () { $this->affected = array(); $query = new \EntityFieldQuery(); $query->entityCondition('entity_type', 'node'); $query->propertyCondition('type', NODE_TYPE_REPORT); $query->addTag('DANGEROUS_ACCESS_CHECK_OPT_OUT'); $result = $query->execute(); $reportNids = isset($result['node']) ? array_keys($result['node']) : NULL; $reportNodes = node_load_multiple($reportNids); foreach ( $reportNodes as $node ) { $datasetName = get_node_field_value($node,'field_report_dataset_sysnames'); if ( empty($datasetName) ) { $patient = array( 'info' => array( 'reportNodeId' => $node->nid, 'reportTitle' => $node->title, 'published' => $node->status, 'type' => $node->type, 'datasetName' => $datasetName ), 'notes' => 'Dataset field is empty.' ); $this->attachTreatment($patient); $this->affected[] = $patient; continue; } // lookup dataset $datasourceQuery = new \EntityFieldQuery(); $datasourceQuery->entityCondition('entity_type', 'node'); $datasourceQuery->propertyCondition('type', NODE_TYPE_DATASET); $datasourceQuery->addTag('DANGEROUS_ACCESS_CHECK_OPT_OUT'); $datasourceQuery->fieldCondition('field_dataset_sysname', 'value', $datasetName); $datasourceQuery->fieldCondition('field_dataset_datasource', 'value', get_node_field_value($node,'field_report_datasource')); $datasourceEntities = $datasourceQuery->execute(); $datasource_nids = isset($datasourceEntities['node']) ? array_keys($datasourceEntities['node']) : NULL; if (count($datasource_nids) != 1) { $patient = array( 'info' => array( 'reportNodeId' => $node->nid, 'reportTitle' => $node->title, 'published' => $node->status, 'type' => $node->type, 'datasetName' => $datasetName ), 'notes' => 'Dataset does not exist.' ); $this->attachTreatment($patient); $this->affected[] = $patient; continue; } } }
/** * @param string $calendarId * @return int */ function cob_calendar_node_id($calendarId) { $query = new EntityFieldQuery(); $query->fieldCondition('field_google_calendar_id', 'value', $calendarId, '='); $result = $query->execute(); if (count($result)) { return array_keys($result['node'])[0]; } }
/** * Forbid a field update from occurring. * * Any module may forbid any update for any reason. For example, the * field's storage module might forbid an update if it would change * the storage schema while data for the field exists. A field type * module might forbid an update if it would change existing data's * semantics, or if there are external dependencies on field settings * that cannot be updated. * * To forbid the update from occurring, throw a FieldUpdateForbiddenException. * * @param $field * The field as it will be post-update. * @param $prior_field * The field as it is pre-update. * @param $has_data * Whether any data already exists for this field. */ function hook_field_update_forbid($field, $prior_field, $has_data) { // A 'list' field stores integer keys mapped to display values. If // the new field will have fewer values, and any data exists for the // abandoned keys, the field will have no way to display them. So, // forbid such an update. if ($has_data && count($field['settings']['allowed_values']) < count($prior_field['settings']['allowed_values'])) { // Identify the keys that will be lost. $lost_keys = array_diff(array_keys($field['settings']['allowed_values']), array_keys($prior_field['settings']['allowed_values'])); // If any data exist for those keys, forbid the update. $query = new EntityFieldQuery(); $found = $query->fieldCondition($prior_field['field_name'], 'value', $lost_keys)->range(0, 1)->execute(); if ($found) { throw new FieldUpdateForbiddenException("Cannot update a list field not to include keys with existing data"); } } }
/** * Returns the number of entities with this state. * * @return int * Counted number. * * @todo: add $options to select on entity type, etc. */ public function count() { $sid = $this->sid; // Get the numbers for Workflow Node. $result = db_select('workflow_node', 'wn')->fields('wn')->condition('sid', $sid, '=')->execute(); $count = count($result->fetchAll()); // @see #2285983 for using SQLite. // Get the numbers for Workflow Field. $fields = _workflow_info_fields(); foreach ($fields as $field_name => $field_map) { if ($field_map['type'] == 'workflow') { $query = new EntityFieldQuery(); $query->fieldCondition($field_name, 'value', $sid, '=')->count(); // We only need the count. $result = $query->execute(); $count += $result; } } return $count; }
/** * Filter the query for list. * * @param \EntityFieldQuery $query * The query object. * * @throws \RestfulBadRequestException * * @see \RestfulEntityBase::getQueryForList */ protected function queryForListFilter(\EntityFieldQuery $query) { $public_fields = $this->getPublicFields(); foreach ($this->parseRequestForListFilter() as $filter) { // Determine if filtering is by field or property. if (!$property_name = $public_fields[$filter['public_field']]['property']) { throw new \RestfulBadRequestException('The current filter selection does not map to any entity property or Field API field.'); } if (field_info_field($property_name)) { if (in_array(strtoupper($filter['operator'][0]), array('IN', 'BETWEEN'))) { $query->fieldCondition($public_fields[$filter['public_field']]['property'], $public_fields[$filter['public_field']]['column'], $filter['value'], $filter['operator'][0]); continue; } for ($index = 0; $index < count($filter['value']); $index++) { $query->fieldCondition($public_fields[$filter['public_field']]['property'], $public_fields[$filter['public_field']]['column'], $filter['value'][$index], $filter['operator'][$index]); } } else { if (in_array(strtoupper($filter['operator'][0]), array('IN', 'BETWEEN'))) { $query->propertyCondition($property_name, $filter['value'], $filter['operator'][0]); continue; } $column = $this->getColumnFromProperty($property_name); for ($index = 0; $index < count($filter['value']); $index++) { $query->propertyCondition($column, $filter['value'][$index], $filter['operator'][$index]); } } } }
function get_posts_array($polling_station, $user_party_id) { global $user, $language; $station_id = $polling_station->nid; $field_digital_election_list = field_get_items('node', $polling_station, 'field_digital_election_list'); $posts_to_fill = array(); $existing = array(); $volunteers_2 = array(); $extra_array = array(); $res = db_select('node', 'n')->fields('n', array('nid', 'title'))->condition('n.type', 'roles')->execute(); while ($rec = $res->fetchAssoc()) { $nids[$rec['nid']] = $rec['title']; } if ($volunteers_pr_party = field_get_items('node', $polling_station, 'field_volunteers_pr_party_1')) { foreach ($volunteers_pr_party as $item) { $field_collection_item = entity_load('field_collection_item', array($item['value'])); $party_id = field_get_items('field_collection_item', $field_collection_item[$item['value']], 'field_party_list'); if ($party_id[0]["party_list"] == $user_party_id) { foreach ($nids as $nid => $title) { $field_name = 'field_role_n' . $nid; $field = field_get_items('field_collection_item', $field_collection_item[$item['value']], $field_name); if ($field && (int) $field[0]['number_vo'] > 0) { $posts_to_fill = array_merge($posts_to_fill, array_fill(0, $field[0]['number_vo'], strtolower($title))); } } } } } // tth: Get all roles, query all content from bundle 'roles' $role_array = _valhalla_helper_get_role_array(); // tth: Loop through the roles used on the pollingstation, and load the volunteers // $station_role_id is the "uniqe" id for the current role from the current party on the // current station. This is set during the add volunteer to station routine $post_id = rand(1, 20) . rand(1, 20); foreach ($posts_to_fill as $key => $value) { $station_role_id = $user_party_id . $role_array[$value] . $station_id; $volunteer_query = new EntityFieldQuery(); $volunteer_query->fieldCondition('field_polling_station_post', 'value', $station_role_id, 'like')->entityCondition('bundle', 'volunteers')->entityCondition('entity_type', 'node')->propertyCondition('status', 1); $reset_query = $volunteer_query->execute(); $volunteers[$value] = reset($reset_query); // yani: this array contains all the existed volunteers, used to compare with $existing later. $volunteers_2[$value] = $volunteers[$value]; } // tth: Populate "existing"-array with volunteer data foreach ($posts_to_fill as $key => $value) { unset($posts_to_fill[$key]); $id = NULL; $station_role_id = $user_party_id . $role_array[$value] . $station_id; // tth: Check if there is a volunteer with the role if (!empty($volunteers[$value])) { $reset_array = array_shift($volunteers[$value]); $id = reset($reset_array); } if ($id) { $existing[$id] = array('data' => _valhalla_helper_wrap_name(node_load($id)), 'nid' => $id); } else { // tth: The id is used when the js inserts the volunteer info on the page // previously the id was just a running number, which caused the volunteer // info to be places in numerous fields on the list, although the volunteer // was only added to one post. // The problem only existed when watching multiple parties on the polling // station. Fix: insert a number that is not repeated. $id = "p" . $user_party_id . $post_id; $post_id++; $value = $value; } $posts_to_fill[$id] = array('title' => $value, 'party_id' => $user_party_id); $id = NULL; } // yani: make a array of whole volunteers. if (!empty($volunteers_2)) { foreach ($volunteers_2 as $role_name => $people) { if (!empty($people)) { foreach ($people as $key => $object) { $id = $object->nid; $extra_array[$id] = array('data' => _valhalla_helper_wrap_name(node_load($id), 'p', 1), 'nid' => $id, 'title' => $role_name); } } } } // Yani: compare $volunteers and $existing to find out if the number of the place and the number of existed volunteers are the same. $extra = array(); if (count($extra_array) > count($existing)) { $extra = array_diff_assoc($extra_array, $existing); } return array('posts_to_fill' => $posts_to_fill, 'party_id' => $user_party_id, 'station_id' => $station_id, 'existing' => isset($existing) ? $existing : "", 'extra' => isset($extra) ? $extra : ""); }
public function deliver(array $output = array()) { $recipients = array(); $message = $this->message; if (in_array($message->type, array('private_message', 'response', 'confirm', 'payremindexec'))) { $wrapper = entity_metadata_wrapper('message', $message); $users = $wrapper->field_message_user_ref->value(); if (is_array($users)) { foreach ($users as $user) { $recipients[] = $user->uid; } } } elseif ($message->type == 'task_created') { $wrapper = entity_metadata_wrapper('message', $message); $group = $wrapper->field_group->raw(); $career = $wrapper->field_career->raw(); $members = group_membership_load_by_group($group); foreach ($members as $mid => $member) { $subscribers[] = $member->uid; } //query for subscriber // Build an EFQ based on the arguments. $query = new EntityFieldQuery(); $query->entityCondition('entity_type', 'profile2')->propertyCondition('type', 'employee')->propertyCondition('uid', $subscribers, "IN"); $query->fieldCondition('field_career', 'tid', $career); $result = $query->execute(); if (!empty($result)) { $profiles = entity_load('profile2', array_keys($result['profile2'])); foreach ($profiles as $pid => $profile) { $recipients[] = $profile->uid; } } //watchdog('debug', 'debug info:<pre>@A1</pre>', array('@A1' => print_r($subscribers, TRUE))); //watchdog('debug', 'debug info:<pre>@A1</pre>', array('@A1' => print_r($recipients, TRUE))); } elseif ($message->type == 'task_updated') { $recipients[] = $message->field_display_author[LANGUAGE_NONE][0]['target_id']; } else { $recipients[] = $message->uid; } /* $clone_message = clone($message); unset($clone_message->language); unset($clone_message->arguments); unset($clone_message->data); unset($clone_message->field_message_body); unset($clone_message->field_message_subject); $this->flatten_fields('message',$clone_message); $clone_message-> */ $msg = str_replace(array("\r", "\n", " "), ' ', strip_tags($output['message_notify_push_body'])); $payload = $msg; //drupal_json_encode($clone_message); watchdog('payload', 'payload:<pre>@A1</pre>', array('@A1' => print_r($payload, TRUE))); watchdog('output', 'output:<pre>@A2</pre>', array('@A2' => print_r($recipients, TRUE))); $result = push_notifications_send_message($recipients, $payload); if ($result) { watchdog('output', 'output:<pre>@A2</pre>', array('@A2' => print_r($result['message'], TRUE))); //$dsm_type = ($result['success']) ? 'status' : 'error'; //drupal_set_message($result['message'], $dsm_type); } return $result; }
public function load(AbstractMetaModel $metamodel, array $filters = NULL) { $environment_metamodel = data_controller_get_environment_metamodel(); LogHelper::log_notice(t('Loading Meta Model from GovDashboard Content Types ...')); $loaderName = $this->getName(); $datasetQuery = new EntityFieldQuery(); $datasetQuery->entityCondition('entity_type', 'node'); $datasetQuery->propertyCondition('type', NODE_TYPE_DATASET); $datasetQuery->propertyCondition('status', NODE_PUBLISHED); $datasetQuery->addTag('DANGEROUS_ACCESS_CHECK_OPT_OUT'); // applying filters. Note that we have custom mapping for filter properties $datasetFilters = isset($filters['DatasetMetaData']) ? $filters['DatasetMetaData'] : NULL; if (isset($datasetFilters)) { foreach ($datasetFilters as $propertyName => $filterValues) { switch ($propertyName) { case 'datasourceName': $selectedDataSourceNames = FALSE; // checking if any of the data sources are actually data marts foreach ($filterValues as $datasourceName) { $datasource = $environment_metamodel->findDataSource($datasourceName); if (isset($datasource->nid)) { $selectedDataSourceNames[] = $datasourceName; } } if (isset($selectedDataSourceNames)) { $datasetQuery->fieldCondition('field_dataset_datasource', 'value', $selectedDataSourceNames); } else { // there is no selected datamarts for this request return; } break; default: throw new UnsupportedOperationException(t( 'Unsupported mapping for the property for filtering during dataset loading: %propertyName', array('%propertyName' => $propertyName))); } } } $datasetEntities = $datasetQuery->execute(); $dataset_nids = isset($datasetEntities['node']) ? array_keys($datasetEntities['node']) : NULL; if (!isset($dataset_nids)) { return; } $datasetNodes = node_load_multiple($dataset_nids); // loading columns for selected datasets $columnNodes = gd_column_get_columns_4_dataset($dataset_nids, LOAD_ENTITY, INCLUDE_UNPUBLISHED); // grouping nodes in context of dataset $datasetsColumnNodes = $this->groupNodesByDataset($columnNodes, 'field_column_dataset'); // preparing dataset & cubes $processedDatasetCount = 0; foreach ($datasetNodes as $datasetNode) { $dataset_nid = $datasetNode->nid; $datasourceName = get_node_field_value($datasetNode, 'field_dataset_datasource'); $datasource = isset($datasourceName) ? $environment_metamodel->findDataSource($datasourceName) : NULL; if (!isset($datasource)) { // the data mart could be unpublished or ... continue; } $datasetColumnNodes = isset($datasetsColumnNodes[$dataset_nid]) ? $datasetsColumnNodes[$dataset_nid] : NULL; // preparing dataset $dataset = GD_DatasetMetaModelLoaderHelper::prepareDataset($metamodel, $datasetNode, $datasetColumnNodes, $datasource); // assigning a loader which created the dataset $dataset->loaderName = $loaderName; $processedDatasetCount++; } LogHelper::log_info(t('Processed @datasetCount dataset node(s)', array('@datasetCount' => $processedDatasetCount))); }
/** * Build an EntityFieldQuery to get referencable entities. */ protected function buildEntityFieldQuery($match = NULL, $match_operator = 'CONTAINS') { $query = new EntityFieldQuery(); global $user; $query->entityCondition('entity_type', 'commerce_store'); if (!user_access('add products to any store')) { $query->fieldCondition('cmp_m_store', 'target_id', $user->uid); } if (isset($match)) { $entity_info = entity_get_info('commerce_store'); if (isset($entity_info['entity keys']['label'])) { $query->propertyCondition($entity_info['entity keys']['label'], $match, $match_operator); } } // Add a generic entity access tag to the query. $query->addTag($this->field['settings']['target_type'] . '_access'); $query->addTag('entityreference'); $query->addMetaData('field', $this->field); $query->addMetaData('entityreference_selection_handler', $this); return $query; }
function getContentFromBBDD2($trip, $month, $limit = 0) { switch ($trip) { case 3: $tabla = 'productos_premium'; $trip = 0; //No tiene campo tipo de producto $campoLugar = 'field_premium_lugar'; break; default: $tabla = 'productos'; $campoLugar = 'field_lugar'; break; } //var_dump(OpinnoBikespainHelper::getCurrentLang()); $dfx_lang = OpinnoBikespainHelper::getCurrentLang() == 'es' ? 'en' : 'es'; $language = OpinnoBikespainHelper::getCurrentLang(); $query = new EntityFieldQuery(); $query->entityCondition('entity_type', 'node')->entityCondition('bundle', 'hoteles')->propertyCondition('status', 1)->propertyCondition('language', $dfx_lang)->addTag('efq_debug')->range(0, 50); if ($trip > 0) { $query->fieldCondition('field_tipo_de_producto', 'tid', array($trip)); } $result = $query->execute(); $res = array(); if (isset($result['node'])) { $news_items_nids = array_keys($result['node']); $news_items = entity_load('node', $news_items_nids); if ($month > 0) { foreach ($news_items as $producto) { $field_dates = GetListByLangOrUnd($producto, $language, 'field_dates'); foreach ($field_dates as $value) { if (fechaDisponible($value, $month)) { $res[] = $producto; break; } } } } else { $res = $news_items; } } return $res; }
/** * As seen in commerce_services: filtering. * * Adds property and field conditions to an index EntityFieldQuery. * * @param \EntityFieldQuery $query * The EntityFieldQuery object being built for the index query. * @param string $entity_type * Machine-name of the entity type of the index query. * @param array $filter * An associative array of property names, single column field names, or * multi-column field column names with their values to use to filter the * result set of the index request. * @param array $filter_op * An associative array of field and property names with the operators to * use when applying their filter conditions to the index request query. */ public static function indexQueryFilter(\EntityFieldQuery $query, $entity_type, array $filter, array $filter_op) { // Loop over each filter field to add them as property or field conditions // on the query object. This function assumes the $filter and $filter_op // arrays contain matching keys to set the correct operator to the filter // fields. foreach ($filter as $filter_field => $filter_value) { // Determine the corresponding operator for this filter field, defaulting // to = in case of an erroneous request. $operator = '='; if (!empty($filter_op[$filter_field])) { $operator = $filter_op[$filter_field]; } // If operator is IN, try to turn the filter into an array. if ($operator == 'IN') { $filter_value = explode(',', $filter_value); } // If the current filter field is a property, use a property condition. $properties = self::entityTypeProperties($entity_type); if (in_array($filter_field, array_keys($properties), TRUE)) { $query->propertyCondition($properties[$filter_field], $filter_value, $operator); } else { // Look for the field name among the entity type's field list. foreach (self::entityTypeFields($entity_type) as $field_name => $field_type) { // If the filter field begins with a field name, then either the // filter field is the field name or is a column of the field. if (strpos($filter_field, $field_name) === 0) { $field_info = field_info_field($field_name); // If field is list_boolean, convert true => 1 and false => 0. if ($field_info['type'] == 'list_boolean') { if ($filter_value === 'true') { $filter_value = 1; } if ($filter_value === 'false') { $filter_value = 0; } } // If it is the field name and the field type has a single column // schema, add the field condition to the index query. if ($field_name == $filter_field && count($field_info['columns']) == 1) { $column = key($field_info['columns']); $query->fieldCondition($field_name, $column, $filter_value, $operator); break; } else { // Otherwise if the filter field contains a valid column // specification for the field type, add the field condition to // the index query. $column = substr($filter_field, strlen($field_name) + 1); if (in_array($column, array_keys($field_info['columns']))) { $query->fieldCondition($field_name, $column, $filter_value, $operator); break; } } } } } } }
function check_if_article_exists($id) { //Queries the brafton_id table and checks for the id $query = new EntityFieldQuery(); $query->entityCondition('entity_type', 'node'); $query->fieldCondition('field_brafton_id', 'value', $id, '='); $query->propertyCondition('status', 1); //checks for published nodes $result = $query->execute(); if (empty($result)) { $query = new EntityFieldQuery(); $query->entityCondition('entity_type', 'node'); $query->fieldCondition('field_brafton_id', 'value', $id, '='); $query->propertyCondition('status', 0); //checks for unpublished nodes $result = $query->execute(); debug($result); } //debug($result); return $result; }
/** * Filter files by vsite */ protected function queryForListFilter(EntityFieldQuery $query) { if ($this->request['vsite']) { if ($vsite = vsite_get_vsite($this->request['vsite'])) { $query->fieldCondition(OG_AUDIENCE_FIELD, 'target_id', $this->request['vsite']); } else { throw new RestfulBadRequestException(t('No vsite with the id @id', array('@id' => $this->request['vsite']))); } } // Make getting private files explicit // Private files currently require PIN authentication before they can even be access checked if (!isset($this->request['private'])) { $query->propertyCondition('uri', 'private://%', 'NOT LIKE'); } elseif ($this->request['private'] == 'only') { $query->propertyCondition('uri', 'private://%', 'LIKE'); } }
/** * Allow you to hook in during autocomplete suggestions generation. * * Allow you to include entities for autocomplete suggestion that are possible * candidates based on your field as a source of synonyms. This method is * void, however, you have to alter and add your condition to $query * parameter. * * @param string $tag * What user has typed in into autocomplete widget. Normally you would * run LIKE '%$tag%' on your column * @param EntityFieldQuery $query * EntityFieldQuery object where you should add your conditions to * @param array $field * Array of field definition according to Field API, autocomplete on which * is fired * @param array $instance * Array of instance definition according to Field API, autocomplete on * which is fired */ public static function processEntityFieldQuery($tag, EntityFieldQuery $query, $field, $instance) { $query->fieldCondition($field, 'value', '%' . $tag . '%', 'LIKE'); }
* Complete documentation for this file is available online. * @see https://drupal.org/node/1728164 */ $related_nodes = array(); $tag_arr = array(); $ts = $node->field_themes['und']; foreach ($ts as $t) { if ($t) { array_push($tag_arr, $t['taxonomy_term']->tid); } } $related_nodes = array(); if (count($tag_arr) > 0) { $query = new EntityFieldQuery(); $query->entityCondition('entity_type', 'node')->entityCondition('bundle', 'browse_item')->propertyCondition('status', 1)->fieldCondition('field_institution', 'value', $node->field_institution['und'][0]['value'], '!='); $query->fieldCondition('field_themes', 'tid', $tag_arr)->range(0, 25); $result = $query->execute(); $related_keys = array_keys($result['node']); shuffle($related_keys); $related_nodes = array_slice(entity_load('node', $related_keys), 0, 6, TRUE); } else { } global $base_path; global $base_url; ?> <article class="node-<?php print $node->nid; ?> "<?php print $attributes;
private function attachTreatment ( &$diagnosis ) { $diagnosis['treatments'] = array(); $diagnosis['treatments'][] = 'ReportConfigRemoveColumnLevel'; $reportNode = node_load($diagnosis['info']['reportNodeId']); // lookup datasource $datasourceQuery = new \EntityFieldQuery(); $datasourceQuery->entityCondition('entity_type', 'node'); $datasourceQuery->propertyCondition('type', NODE_TYPE_DATAMART); $datasourceQuery->addTag('DANGEROUS_ACCESS_CHECK_OPT_OUT'); $datasourceQuery->fieldCondition('field_datamart_sysname', 'value', get_node_field_value($reportNode, 'field_report_datasource', 0, 'value', FALSE)); $datasourceEntities = $datasourceQuery->execute(); $datasource_nids = isset($datasourceEntities['node']) ? array_keys($datasourceEntities['node']) : NULL; if (count($datasource_nids) != 1) { $diagnosis['treatments'][] = 'ReportDelete'; $diagnosis['notes'] .= ' Datasource could not be found.'; } else { $datamartNode = node_load($datasource_nids[0]); if ( $datamartNode->status == NODE_PUBLISHED ) { $diagnosis['notes'] .= ' Datasource is published.'; } else { $diagnosis['treatments'][] = 'ReportDelete'; $diagnosis['notes'] .= ' Datasource is not published.'; } } }