diff --git a/.htaccess b/.htaccess index 41854420566..8500b50a8fa 100644 --- a/.htaccess +++ b/.htaccess @@ -134,9 +134,9 @@ DirectoryIndex index.php index.html index.htm RewriteCond %{REQUEST_FILENAME}\.gz -s RewriteRule ^(.*)\.js $1\.js\.gz [QSA] - # Serve correct content types, and prevent mod_deflate double gzip. - RewriteRule \.css\.gz$ - [T=text/css,E=no-gzip:1] - RewriteRule \.js\.gz$ - [T=text/javascript,E=no-gzip:1] + # Serve correct content types, and prevent double compression. + RewriteRule \.css\.gz$ - [T=text/css,E=no-gzip:1,E=no-brotli:1] + RewriteRule \.js\.gz$ - [T=text/javascript,E=no-gzip:1,E=no-brotli:1] # Serve correct encoding type. @@ -147,8 +147,10 @@ DirectoryIndex index.php index.html index.htm -# Add headers to all responses. +# Various header fixes. # Disable content sniffing, since it's an attack vector. Header always set X-Content-Type-Options nosniff + # Disable Proxy header, since it's an attack vector. + RequestHeader unset Proxy diff --git a/CHANGELOG.txt b/CHANGELOG.txt index dcef8ea97fc..62db1411389 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,3 +1,14 @@ +Drupal 7.82, 2021-07-21 +----------------------- +- Fixed security issues: + - SA-CORE-2021-004 + +Drupal 7.81, 2021-06-02 +----------------------- +- Block Google FLoC by default +- Testing and accessibility enhancements +- Various bug fixes, optimizations and improvements + Drupal 7.80, 2021-04-20 ----------------------- - Fixed security issues: diff --git a/includes/bootstrap.inc b/includes/bootstrap.inc index 72c92911d2d..ec3e85fd6cd 100644 --- a/includes/bootstrap.inc +++ b/includes/bootstrap.inc @@ -8,7 +8,7 @@ /** * The current system version. */ -define('VERSION', '7.80'); +define('VERSION', '7.82'); /** * Core API compatibility. diff --git a/includes/common.inc b/includes/common.inc index a19a5eaacc6..4dec37379ae 100644 --- a/includes/common.inc +++ b/includes/common.inc @@ -2696,6 +2696,19 @@ function drupal_deliver_html_page($page_callback_result) { drupal_add_http_header('X-Frame-Options', $frame_options); } + if (variable_get('block_interest_cohort', TRUE)) { + $permissions_policy = drupal_get_http_header('Permissions-Policy'); + if (is_null($permissions_policy)) { + drupal_add_http_header('Permissions-Policy', 'interest-cohort=()'); + } + else { + // Only add interest-cohort if the header does not contain it already. + if (strpos($permissions_policy, 'interest-cohort') === FALSE) { + drupal_add_http_header('Permissions-Policy', 'interest-cohort=()', TRUE); + } + } + } + // Menu status constants are integers; page content is a string or array. if (is_int($page_callback_result)) { // @todo: Break these up into separate functions? @@ -3392,7 +3405,7 @@ function drupal_group_css($css) { * @see system_element_info() */ function drupal_aggregate_css(&$css_groups) { - $preprocess_css = (variable_get('preprocess_css', FALSE) && (!defined('MAINTENANCE_MODE') || MAINTENANCE_MODE != 'update')); + $preprocess_css = (variable_get('preprocess_css', FALSE) && !defined('MAINTENANCE_MODE')); // For each group that needs aggregation, aggregate its items. foreach ($css_groups as $key => $group) { @@ -3851,8 +3864,10 @@ function drupal_load_stylesheet_content($contents, $optimize = FALSE) { // whitespace. // @see http://php.net/manual/regexp.reference.subpatterns.php $contents = preg_replace('< + # Do not strip any space from within single or double quotes + (' . $double_quot . '|' . $single_quot . ') # Strip leading and trailing whitespace. - \s*([@{};,])\s* + | \s*([@{};,])\s* # Strip only leading whitespace from: # - Closing parenthesis: Retain "@media (bar) and foo". | \s+([\)]) @@ -3860,11 +3875,11 @@ function drupal_load_stylesheet_content($contents, $optimize = FALSE) { # - Opening parenthesis: Retain "@media (bar) and foo". # - Colon: Retain :pseudo-selectors. | ([\(:])\s+ - >xS', - // Only one of the three capturing groups will match, so its reference + >xSs', + // Only one of the four capturing groups will match, so its reference // will contain the wanted value and the references for the // two non-matching groups will be replaced with empty strings. - '$1$2$3', + '$1$2$3$4', $contents ); // End the file with a new line. @@ -4505,7 +4520,7 @@ function drupal_get_js($scope = 'header', $javascript = NULL, $skip_alter = FALS * @see drupal_add_js() */ function drupal_pre_render_scripts(array $elements) { - $preprocess_js = (variable_get('preprocess_js', FALSE) && (!defined('MAINTENANCE_MODE') || MAINTENANCE_MODE != 'update')); + $preprocess_js = (variable_get('preprocess_js', FALSE) && !defined('MAINTENANCE_MODE')); // A dummy query-string is added to filenames, to gain control over // browser-caching. The string changes on every update or full cache @@ -6941,7 +6956,7 @@ function drupal_array_set_nested_value(array &$array, array $parents, $value, $f function &drupal_array_get_nested_value(array &$array, array $parents, &$key_exists = NULL) { $ref = &$array; foreach ($parents as $parent) { - if (is_array($ref) && array_key_exists($parent, $ref)) { + if (is_array($ref) && (isset($ref[$parent]) || array_key_exists($parent, $ref))) { $ref = &$ref[$parent]; } else { diff --git a/includes/form.inc b/includes/form.inc index f2557e83233..3f6c7661adc 100644 --- a/includes/form.inc +++ b/includes/form.inc @@ -3924,6 +3924,11 @@ function theme_button($variables) { $element['#attributes']['type'] = 'submit'; element_set_attributes($element, array('id', 'name', 'value')); + // Remove name attribute, if empty, for W3C compliance. + if (isset($element['#attributes']['name']) && $element['#attributes']['name'] === '') { + unset($element['#attributes']['name']); + } + $element['#attributes']['class'][] = 'form-' . $element['#button_type']; if (!empty($element['#attributes']['disabled'])) { $element['#attributes']['class'][] = 'form-button-disabled'; diff --git a/includes/menu.inc b/includes/menu.inc index fb99aac8a25..4965ae3fcc2 100644 --- a/includes/menu.inc +++ b/includes/menu.inc @@ -1500,13 +1500,25 @@ function menu_tree_check_access(&$tree, $node_links = array()) { $nids = array_keys($node_links); $select = db_select('node', 'n'); $select->addField('n', 'nid'); - $select->condition('n.status', 1); + // When a menu administrator who we know has permission to see unpublished + // nodes is administering the menu, included the unpublished nodes in the + // tree, with a special flag so that the Menu module can label them. + // Otherwise, exclude these nodes from the tree. + if (!empty($GLOBALS['menu_admin']) && user_access('bypass node access')) { + $select->addField('n', 'status'); + } + else { + $select->condition('n.status', 1); + } $select->condition('n.nid', $nids, 'IN'); $select->addTag('node_access'); - $nids = $select->execute()->fetchCol(); - foreach ($nids as $nid) { - foreach ($node_links[$nid] as $mlid => $link) { - $node_links[$nid][$mlid]['access'] = TRUE; + $node_objects = $select->execute()->fetchAll(); + foreach ($node_objects as $node_object) { + foreach ($node_links[$node_object->nid] as $mlid => $link) { + $node_links[$node_object->nid][$mlid]['access'] = TRUE; + if (isset($node_object->status)) { + $node_links[$node_object->nid][$mlid]['node_unpublished'] = !$node_object->status; + } } } } @@ -1868,7 +1880,7 @@ function menu_navigation_links($menu_name, $level = 0) { $router_item = menu_get_item(); $links = array(); foreach ($tree as $item) { - if (!$item['link']['hidden']) { + if ($item['link']['access'] && !$item['link']['hidden']) { $class = ''; $l = $item['link']['localized_options']; $l['href'] = $item['link']['href']; diff --git a/includes/theme.inc b/includes/theme.inc index 5b602f8d7f3..a1b9324a0c9 100644 --- a/includes/theme.inc +++ b/includes/theme.inc @@ -418,7 +418,7 @@ class ThemeRegistry Extends DrupalCacheArray { // are not registered, just check the existence of the key in the registry. // Use array_key_exists() here since a NULL value indicates that the theme // hook exists but has not yet been requested. - return array_key_exists($offset, $this->storage); + return isset($this->storage[$offset]) || array_key_exists($offset, $this->storage); } public function offsetGet($offset) { diff --git a/misc/autocomplete.js b/misc/autocomplete.js index 09ceeec0f14..5c8b57be46d 100644 --- a/misc/autocomplete.js +++ b/misc/autocomplete.js @@ -17,7 +17,7 @@ Drupal.behaviors.autocomplete = { $($input[0].form).submit(Drupal.autocompleteSubmit); $input.parent() .attr('role', 'application') - .append($('') + .append($('') .attr('id', $input.attr('id') + '-autocomplete-aria-live') ); new Drupal.jsAC($input, acdb[uri]); diff --git a/modules/field/field.form.inc b/modules/field/field.form.inc index 280f778ffba..1d5a632b1ab 100644 --- a/modules/field/field.form.inc +++ b/modules/field/field.form.inc @@ -213,14 +213,25 @@ function field_multiple_value_form($field, $instance, $langcode, $items, &$form, '#language' => $langcode, '#field_parents' => $parents, '#columns' => array_keys($field['columns']), - // For multiple fields, title and description are handled by the wrapping table. - '#title' => $multiple ? '' : $title, - '#description' => $multiple ? '' : $description, + '#title' => $title, + '#description' => $description, // Only the first widget should be required. '#required' => $delta == 0 && $instance['required'], '#delta' => $delta, '#weight' => $delta, ); + // For multiple fields, title and description are handled by the wrapping + // table. + if ($multiple) { + if ($delta == 0) { + $element['#title'] = $title; + } + else { + $element['#title'] = t('!title (value @number)', array('@number' => $delta + 1, '!title' => $title)); + } + $element['#title_display'] = 'invisible'; + $element['#description'] = ''; + } if ($element = $function($form, $form_state, $field, $instance, $langcode, $items, $delta, $element)) { // Input field for the delta (drag-n-drop reordering). if ($multiple) { diff --git a/modules/field/tests/field.test b/modules/field/tests/field.test index adf2413ba7b..5312f2d4557 100644 --- a/modules/field/tests/field.test +++ b/modules/field/tests/field.test @@ -1810,6 +1810,27 @@ class FieldFormTestCase extends FieldTestCase { // Test with several multiple fields in a form } + /** + * Tests the position of the required label. + */ + public function testFieldFormUnlimitedRequired() { + $this->field = $this->field_unlimited; + $this->field_name = $this->field['field_name']; + $this->instance['field_name'] = $this->field_name; + $this->instance['required'] = TRUE; + field_create_field($this->field); + field_create_instance($this->instance); + + // Display creation form -> 1 widget. + $this->drupalGet('test-entity/add/test-bundle'); + $result = $this->xpath("//label[not(contains(@class, 'element-invisible')) and contains(text(), :label)]/span/text()", array(':label' => $this->instance['label'])); + $this->assertEqual($result[0], '*', 'Required symbol added to field label.'); + // Check that the label of the field input is visually hidden and contains + // the field title and an indication of the delta for a11y. + $result = $this->xpath("//label[contains(@class, 'element-invisible') and contains(text(), :label)]/span/text()", array(':label' => $this->instance['label'])); + $this->assertEqual($result[0], '*', 'Required symbol and field label are visually hidden.'); + } + /** * Tests widget handling of multiple required radios. */ diff --git a/modules/menu/menu.admin.inc b/modules/menu/menu.admin.inc index a24703c9fcd..4d0a792dda0 100644 --- a/modules/menu/menu.admin.inc +++ b/modules/menu/menu.admin.inc @@ -59,6 +59,9 @@ function menu_overview_form($form, &$form_state, $menu) { foreach ($result as $item) { $links[] = $item; } + $link_count = db_query("SELECT COUNT(*) AS counter FROM {menu_links} WHERE menu_name = :menu AND link_path NOT LIKE :link_path", array(':menu' => $menu['menu_name'], ':link_path' => '%\%%'))->fetchObject(); + $counter = intval($link_count->counter / 2 ) + 1; + $tree = menu_tree_data($links); $node_links = array(); menu_tree_collect_node_links($tree, $node_links); @@ -67,7 +70,8 @@ function menu_overview_form($form, &$form_state, $menu) { menu_tree_check_access($tree, $node_links); $menu_admin = FALSE; - $form = array_merge($form, _menu_overview_tree_form($tree)); + $delta = _menu_get_menu_weight_delta($menu['menu_name'], $counter); + $form = array_merge($form, _menu_overview_tree_form($tree, $delta)); $form['#menu'] = $menu; if (element_children($form)) { @@ -88,8 +92,10 @@ function menu_overview_form($form, &$form_state, $menu) { * * @param $tree * The menu_tree retrieved by menu_tree_data. + * @param $delta + * The number of items to use in the menu weight selector. Defaults to 50. */ -function _menu_overview_tree_form($tree) { +function _menu_overview_tree_form($tree, $delta = 50) { $form = &drupal_static(__FUNCTION__, array('#tree' => TRUE)); foreach ($tree as $data) { $title = ''; @@ -100,12 +106,7 @@ function _menu_overview_tree_form($tree) { $form[$mlid]['#item'] = $item; $form[$mlid]['#attributes'] = $item['hidden'] ? array('class' => array('menu-disabled')) : array('class' => array('menu-enabled')); $form[$mlid]['title']['#markup'] = l($item['title'], $item['href'], $item['localized_options']); - if ($item['hidden']) { - $form[$mlid]['title']['#markup'] .= ' (' . t('disabled') . ')'; - } - elseif ($item['link_path'] == 'user' && $item['module'] == 'system') { - $form[$mlid]['title']['#markup'] .= ' (' . t('logged in users only') . ')'; - } + menu_add_link_labels($form[$mlid]['title']['#markup'], $item); $form[$mlid]['hidden'] = array( '#type' => 'checkbox', @@ -115,7 +116,7 @@ function _menu_overview_tree_form($tree) { ); $form[$mlid]['weight'] = array( '#type' => 'weight', - '#delta' => 50, + '#delta' => $delta, '#default_value' => $item['weight'], '#title_display' => 'invisible', '#title' => t('Weight for @title', array('@title' => $item['title'])), @@ -143,7 +144,7 @@ function _menu_overview_tree_form($tree) { } if ($data['below']) { - _menu_overview_tree_form($data['below']); + _menu_overview_tree_form($data['below'], $delta); } } return $form; @@ -358,10 +359,22 @@ function menu_edit_item($form, &$form_state, $type, $item, $menu) { '#description' => t('The maximum depth for a link and all its children is fixed at !maxdepth. Some menu links may not be available as parents if selecting them would exceed this limit.', array('!maxdepth' => MENU_MAX_DEPTH)), '#attributes' => array('class' => array('menu-title-select')), ); + // Get number of items in all possible parent menus so the weight selector is + // sized appropriately. + $menu_names = array_keys(menu_get_menus()); + $menu_options = array(); + foreach ($menu_names as $menu_name) { + if (isset($options[$menu_name . ':0'])) { + $menu_options[] = $menu_name; + } + } + // Make sure that we always have values in menu_options. + $menu_options = !empty($menu_options) ? $menu_options : $menu_names; + $form['weight'] = array( '#type' => 'weight', '#title' => t('Weight'), - '#delta' => 50, + '#delta' => _menu_get_menu_weight_delta($menu_options), '#default_value' => $item['weight'], '#description' => t('Optional. In the menu, the heavier links will sink and the lighter links will be positioned nearer the top.'), ); diff --git a/modules/menu/menu.module b/modules/menu/menu.module index 27b1675a39e..9578f59271f 100644 --- a/modules/menu/menu.module +++ b/modules/menu/menu.module @@ -401,6 +401,9 @@ function menu_parent_options_js() { * Helper function to get the items of the given menu. */ function _menu_get_options($menus, $available_menus, $item) { + global $menu_admin; + $menu_admin = TRUE; + // If the item has children, there is an added limit to the depth of valid parents. if (isset($item['parent_depth_limit'])) { $limit = $item['parent_depth_limit']; @@ -417,6 +420,8 @@ function _menu_get_options($menus, $available_menus, $item) { _menu_parents_recurse($tree, $menu_name, '--', $options, $item['mlid'], $limit); } } + + $menu_admin = FALSE; return $options; } @@ -431,9 +436,7 @@ function _menu_parents_recurse($tree, $menu_name, $indent, &$options, $exclude, } if ($data['link']['mlid'] != $exclude && $data['link']['hidden'] >= 0) { $title = $indent . ' ' . truncate_utf8($data['link']['title'], 30, TRUE, FALSE); - if ($data['link']['hidden']) { - $title .= ' (' . t('disabled') . ')'; - } + menu_add_link_labels($title, $data['link']); $options[$menu_name . ':' . $data['link']['mlid']] = $title; if ($data['below']) { _menu_parents_recurse($data['below'], $menu_name, $indent . '--', $options, $exclude, $depth_limit); @@ -442,6 +445,27 @@ function _menu_parents_recurse($tree, $menu_name, $indent, &$options, $exclude, } } +/** + * Adds labels to the title of a hidden, unpublished or logged-in menu link. + * + * @param string $title + * The title of the menu link. This will be modified as necessary to add the + * appropriate label in parentheses at the end. + * @param array $item + * An array representing the menu link item. + */ +function menu_add_link_labels(&$title, $item) { + if ($item['hidden']) { + $title .= ' (' . t('disabled') . ')'; + } + elseif (!empty($item['node_unpublished'])) { + $title .= ' (' . t('unpublished') . ')'; + } + elseif ($item['link_path'] == 'user' && $item['module'] == 'system') { + $title .= ' (' . t('logged in users only') . ')'; + } +} + /** * Reset a system-defined menu link. */ @@ -616,6 +640,39 @@ function _menu_parent_depth_limit($item) { return MENU_MAX_DEPTH - 1 - (($item['mlid'] && $item['has_children']) ? menu_link_children_relative_depth($item) : 0); } +/** + * Calculate the delta for the weight element for a given set of menus. + * + * @param string|array $menu_names + * Menu name or an array of menu names. + * @param int $max_delta + * Optional maximum value. + * + * @return int + * Delta value. + */ +function _menu_get_menu_weight_delta($menu_names, $max_delta = NULL) { + + if (is_string($menu_names)) { + $menu_names = array($menu_names); + } + + $weight_info = db_query("SELECT MAX(weight) AS max_weight, MIN(weight) as min_weight FROM {menu_links} WHERE menu_name IN (:menu_names)", array(':menu_names' => $menu_names))->fetchObject(); + + $delta = max(abs($weight_info->min_weight), abs($weight_info->max_weight)) + 1; + + // Honor max param, if given. + if (!is_null($max_delta) && $delta > $max_delta) { + $delta = $max_delta; + } + + // Provide a minimum. + if ($delta < 50) { + $delta = 50; + } + return $delta; +} + /** * Implements hook_form_BASE_FORM_ID_alter(). * @@ -702,10 +759,22 @@ function menu_form_node_form_alter(&$form, $form_state) { '#options' => $options, '#attributes' => array('class' => array('menu-parent-select')), ); + // Get number of items in all possible parent menus so the weight selector is + // sized appropriately. + $menu_names = array_keys(menu_get_menus()); + $menu_options = array(); + foreach ($menu_names as $menu_name) { + if (isset($options[$menu_name . ':0'])) { + $menu_options[] = $menu_name; + } + } + // Make sure that we always have values in menu_options. + $menu_options = !empty($menu_options) ? $menu_options : $menu_names; + $form['menu']['link']['weight'] = array( '#type' => 'weight', '#title' => t('Weight'), - '#delta' => 50, + '#delta' => _menu_get_menu_weight_delta($menu_options), '#default_value' => $link['weight'], '#description' => t('Menu links with smaller weights are displayed before links with larger weights.'), ); diff --git a/modules/menu/menu.test b/modules/menu/menu.test index bb792ee8edf..e1a7f3fbfe4 100644 --- a/modules/menu/menu.test +++ b/modules/menu/menu.test @@ -222,6 +222,14 @@ class MenuTestCase extends DrupalWebTestCase { $this->assertMenuLink($item2['mlid'], array('depth' => 2, 'has_children' => 1, 'p1' => $item1['mlid'], 'p2' => $item2['mlid'], 'p3' => 0)); $this->assertMenuLink($item3['mlid'], array('depth' => 3, 'has_children' => 0, 'p1' => $item1['mlid'], 'p2' => $item2['mlid'], 'p3' => $item3['mlid'], 'p4' => 0)); + // Add 102 menu links with increasing weights, then make sure the last-added + // item's weight doesn't get changed because of the old hardcoded delta = 50 + $items = array(); + for ($i = -50; $i <= 51; $i++) { + $items[$i] = $this->addMenuLink(0, 'node/' . $node1->nid, $menu_name, TRUE, strval($i)); + } + $this->assertMenuLink($items[51]['mlid'], array('weight' => '51')); + // Verify menu links. $this->verifyMenuLink($item1, $node1); $this->verifyMenuLink($item2, $node2, $item1, $node1); @@ -286,15 +294,37 @@ class MenuTestCase extends DrupalWebTestCase { $this->assertFieldByName('link_path', $path, 'Path no longer has query or fragment.'); } + /** + * Tries to use the navigation menu as the source for secondary links. + */ + function testNavigationAsSecondaryMenu() { + $this->drupalLogin($this->big_user); + + // Go to the menu settings page and make the navigation the source for the + // secondary menu. + $edit = array( + 'menu_main_links_source' => 'main-menu', + 'menu_secondary_links_source' => 'navigation', + ); + $this->drupalGet('admin/structure/menu/settings'); + $this->drupalPost(NULL, $edit, t('Save configuration')); + + // Now visit the user page. There should be an 'Add content' link in the + // navigation block and one in the secondary menu. + $this->drupalGet('user'); + $this->assertNoUniqueText(t('Add content')); + } + /** * Add a menu link using the menu module UI. * * @param integer $plid Parent menu link id. * @param string $link Link path. * @param string $menu_name Menu name. + * @param string $weight Menu link weight * @return array Menu link created. */ - function addMenuLink($plid = 0, $link = '', $menu_name = 'navigation', $expanded = TRUE) { + function addMenuLink($plid = 0, $link = '', $menu_name = 'navigation', $expanded = TRUE, $weight = '0') { // View add menu link page. $this->drupalGet("admin/structure/menu/manage/$menu_name/add"); $this->assertResponse(200); @@ -307,7 +337,7 @@ class MenuTestCase extends DrupalWebTestCase { 'enabled' => TRUE, // Use this to disable the menu and test. 'expanded' => $expanded, // Setting this to true should test whether it works when we do the std_user tests. 'parent' => $menu_name . ':' . $plid, - 'weight' => '0', + 'weight' => $weight, ); // Add menu link. @@ -604,6 +634,50 @@ class MenuTestCase extends DrupalWebTestCase { $this->assertText(t('Menus'), 'Add menu node was displayed'); } } + + /** + * Tests that menu admin lists can include menu items for unpublished nodes. + */ + function testUnpublishedNodeMenuItem() { + // Log in as an administrator who can view unpublished nodes. + $menu_and_node_admin_user = $this->drupalCreateUser(array( + 'bypass node access', + 'administer menu', + )); + $this->drupalLogin($menu_and_node_admin_user); + + // Create an unpublished node with a menu link. + $title = $this->randomName(); + $node = $this->drupalCreateNode(array( + 'type' => 'article', + 'title' => $title, + 'status' => NODE_NOT_PUBLISHED, + )); + $edit = array( + 'link_path' => 'node/' . $node->nid, + 'link_title' => $title, + 'description' => '', + 'enabled' => TRUE, + 'expanded' => TRUE, + 'parent' => 'navigation:0', + 'weight' => '0', + ); + $this->drupalPost('admin/structure/menu/manage/navigation/add', $edit, t('Save')); + + // Verify that the administrator can see the menu link (with a label + // indicating that it is unpublished) on the menu management page. + $this->drupalGet('admin/structure/menu/manage/navigation'); + $this->assertText($title . ' (unpublished)', 'Menu link to unpublished node is visible to users with "bypass node access" permission.'); + + // Verify that a user who cannot view unpublished nodes does not see the + // menu link on the menu management page. + $menu_admin_user = $this->drupalCreateUser(array('administer menu')); + $this->drupalLogin($menu_admin_user); + $this->drupalGet('admin/structure/menu/manage/navigation'); + $this->assertResponse(200); + $this->assertNoText($title, 'Menu link to unpublished node is not visible to users without the "bypass node access" permission.'); + } + } /** @@ -758,4 +832,5 @@ class MenuNodeTestCase extends DrupalWebTestCase { $options = $this->xpath('//select[@id=:id]//option[@value=:option]', array(':id' => $id, ':option' => $option)); return $this->assertTrue(isset($selects[0]) && !isset($options[0]), $message ? $message : t('Option @option for field @id does not exist.', array('@option' => $option, '@id' => $id)), t('Browser')); } + } diff --git a/modules/node/content_types.inc b/modules/node/content_types.inc index c451dc7e03f..446da7d69e1 100644 --- a/modules/node/content_types.inc +++ b/modules/node/content_types.inc @@ -417,14 +417,16 @@ function node_type_delete_confirm($form, &$form_state, $type) { $form['name'] = array('#type' => 'value', '#value' => $type->name); $message = t('Are you sure you want to delete the content type %type?', array('%type' => $type->name)); - $caption = ''; $num_nodes = db_query("SELECT COUNT(*) FROM {node} WHERE type = :type", array(':type' => $type->type))->fetchField(); if ($num_nodes) { - $caption .= '

' . format_plural($num_nodes, '%type is used by 1 piece of content on your site. If you remove this content type, you will not be able to edit the %type content and it may not display correctly.', '%type is used by @count pieces of content on your site. If you remove %type, you will not be able to edit the %type content and it may not display correctly.', array('%type' => $type->name)) . '

'; + drupal_set_title($message, PASS_THROUGH); + $caption = '

' . format_plural($num_nodes, '%type is used by 1 piece of content on your site. You cannot remove this content type until you have removed all of the %type content.', '%type is used by @count pieces of content on your site. You cannot remove this content type until you have removed all of the %type content.', array('%type' => $type->name)) . '

'; + $form['description'] = array('#markup' => $caption); + return $form; } - $caption .= '

' . t('This action cannot be undone.') . '

'; + $caption = '

' . t('This action cannot be undone.') . '

'; return confirm_form($form, $message, 'admin/structure/types', $caption, t('Delete')); } diff --git a/modules/node/node.module b/modules/node/node.module index 1c0e518696b..cf41ce7145e 100644 --- a/modules/node/node.module +++ b/modules/node/node.module @@ -3055,18 +3055,12 @@ function node_access($op, $node, $account = NULL) { $query->condition($nids); $query->range(0, 1); - $grants = db_or(); - foreach (node_access_grants($op, $account) as $realm => $gids) { - foreach ($gids as $gid) { - $grants->condition(db_and() - ->condition('gid', $gid) - ->condition('realm', $realm) - ); - } - } + $grants = node_add_node_grants_to_query(node_access_grants($op, $account)); + if (count($grants) > 0) { $query->condition($grants); } + $result = (bool) $query ->execute() ->fetchField(); @@ -3084,6 +3078,31 @@ function node_access($op, $node, $account = NULL) { return FALSE; } +/** + * Helper function to create the or condition for a node grants check. + * + * @param $account + * The grants to add to the query, usually gotten via node_access_grants(). + * @param $table_alias + * Optional, the alias to the node access table. + * + * @return + * TRUE if the operation may be performed, FALSE otherwise. + */ +function node_add_node_grants_to_query($node_access_grants, $table_alias = '') { + $grants = db_or(); + $prefix = $table_alias ? $table_alias . '.' : ''; + foreach ($node_access_grants as $realm => $gids) { + if (!empty($gids)) { + $grants->condition(db_and() + ->condition($prefix . 'gid', $gids, 'IN') + ->condition($prefix . 'realm', $realm) + ); + } + } + return $grants; +} + /** * Implements hook_node_access(). */ @@ -3252,15 +3271,8 @@ function node_access_view_all_nodes($account = NULL) { ->condition('nid', 0) ->condition('grant_view', 1, '>='); - $grants = db_or(); - foreach (node_access_grants('view', $account) as $realm => $gids) { - foreach ($gids as $gid) { - $grants->condition(db_and() - ->condition('gid', $gid) - ->condition('realm', $realm) - ); - } - } + $grants = node_add_node_grants_to_query(node_access_grants('view', $account)); + if (count($grants) > 0 ) { $query->condition($grants); } @@ -3422,17 +3434,7 @@ function _node_query_node_access_alter($query, $type) { $subquery = db_select('node_access', 'na') ->fields('na', array('nid')); - $grant_conditions = db_or(); - // If any grant exists for the specified user, then user has access - // to the node for the specified operation. - foreach ($grants as $realm => $gids) { - foreach ($gids as $gid) { - $grant_conditions->condition(db_and() - ->condition('na.gid', $gid) - ->condition('na.realm', $realm) - ); - } - } + $grant_conditions = node_add_node_grants_to_query($grants, 'na'); // Attach conditions to the subquery for nodes. if (count($grant_conditions->conditions())) { diff --git a/modules/node/node.test b/modules/node/node.test index e8eb459e3bb..f0ff8e7d6e5 100644 --- a/modules/node/node.test +++ b/modules/node/node.test @@ -1614,6 +1614,48 @@ class NodeTypeTestCase extends DrupalWebTestCase { $this->assertTrue(isset($types[$type]->disabled) && empty($types[$type]->disabled), format_string('%type type is enabled.', array('%type' => $type))); } } + + /** + * Tests deleting a content type that still has content. + */ + function testNodeTypeDeletion() { + // Create a content type programmatically. + $type = $this->drupalCreateContentType(); + + // Log in a test user. + $web_user = $this->drupalCreateUser(array( + 'bypass node access', + 'administer content types', + )); + $this->drupalLogin($web_user); + + // Add a new node of this type. + $node = $this->drupalCreateNode(array('type' => $type->type)); + // Attempt to delete the content type, which should not be allowed. + $this->drupalGet('admin/structure/types/manage/' . $type->name . '/delete'); + $this->assertRaw( + t( + '%type is used by 1 piece of content on your site. You cannot remove this content type until you have removed all of the %type content.', + array('%type' => $type->name) + ), + 'The content type will not be deleted until all nodes of that type are removed.' + ); + $this->assertNoText(t('This action cannot be undone.'), 'The node type deletion confirmation form is not available.'); + + // Delete the node. + node_delete($node->nid); + // Attempt to delete the content type, which should now be allowed. + $this->drupalGet('admin/structure/types/manage/' . $type->name . '/delete'); + $this->assertRaw( + t( + 'Are you sure you want to delete the content type %type?', + array('%type' => $type->name) + ), + 'The content type is available for deletion.' + ); + $this->assertText(t('This action cannot be undone.'), 'The node type deletion confirmation form is available.'); + } + } /** diff --git a/modules/path/path.admin.inc b/modules/path/path.admin.inc index 28b06189b36..248971f4f7c 100644 --- a/modules/path/path.admin.inc +++ b/modules/path/path.admin.inc @@ -11,7 +11,11 @@ * When filter key passed, perform a standard search on the given key, * and return the list of matching URL aliases. */ -function path_admin_overview($keys = NULL) { +function path_admin_overview() { + // Get search keys. + $args = func_get_args(); + $keys = implode('/', $args); + // Add the filter form above the overview table. $build['path_admin_filter_form'] = drupal_get_form('path_admin_filter_form', $keys); // Enable language column if locale is enabled or if we have any alias with language diff --git a/modules/path/path.test b/modules/path/path.test index f6131ce62bf..57882518273 100644 --- a/modules/path/path.test +++ b/modules/path/path.test @@ -107,6 +107,55 @@ class PathTestCase extends DrupalWebTestCase { $this->drupalGet($edit['alias']); $this->assertNoText($node1->title, 'Alias was successfully deleted.'); $this->assertResponse(404); + + // Create third and fourth test node. + $node3 = $this->drupalCreateNode(); + $node4 = $this->drupalCreateNode(); + + // Give the node aliases a common first part. + $name = $this->randomName(4); + + // Create aliases containing a slash. + $edit = array(); + $edit['source'] = 'node/' . $node3->nid; + $alias3 = $name . '/' . $this->randomName(5); + $edit['alias'] = $alias3; + $this->drupalPost('admin/config/search/path/add', $edit, t('Save')); + $edit['source'] = 'node/' . $node4->nid; + $alias4 = $name . '/' . $this->randomName(4); + $edit['alias'] = $alias4; + $this->drupalPost('admin/config/search/path/add', $edit, t('Save')); + + // Confirm that the aliases work. + $this->drupalGet($alias3); + $this->assertText($node3->title, 'Alias works.'); + $this->assertResponse(200); + $this->drupalGet($alias4); + $this->assertText($node4->title, 'Alias works.'); + $this->assertResponse(200); + + // Confirm that filters containing slashes work. + $this->drupalGet('admin/config/search/path/list/' . $alias3); + $this->assertFieldByName('filter', $alias3); + $this->assertText($alias3, 'Searched-for alias with slash found.'); + $this->assertNoText($alias4, 'Different alias with slash not found.'); + $this->assertResponse(200); + + // Delete aliases. + $pid = $this->getPID($alias3); + $this->drupalPost('admin/config/search/path/edit/' . $pid, array(), t('Delete')); + $this->drupalPost(NULL, array(), t('Confirm')); + $pid = $this->getPID($alias4); + $this->drupalPost('admin/config/search/path/edit/' . $pid, array(), t('Delete')); + $this->drupalPost(NULL, array(), t('Confirm')); + + // Confirm that the aliases no longer work. + $this->drupalGet($alias3); + $this->assertNoText($node3->title, 'Alias was successfully deleted.'); + $this->assertResponse(404); + $this->drupalGet($alias4); + $this->assertNoText($node4->title, 'Alias was successfully deleted.'); + $this->assertResponse(404); } /** diff --git a/modules/simpletest/drupal_web_test_case.php b/modules/simpletest/drupal_web_test_case.php index f212b0eb534..e2dc2322def 100644 --- a/modules/simpletest/drupal_web_test_case.php +++ b/modules/simpletest/drupal_web_test_case.php @@ -51,6 +51,20 @@ abstract class DrupalTestCase { */ protected $timeLimit = 500; + /** + * Whether to cache the installation part of the setUp() method. + * + * @var bool + */ + public $useSetupInstallationCache = FALSE; + + /** + * Whether to cache the modules installation part of the setUp() method. + * + * @var bool + */ + public $useSetupModulesCache = FALSE; + /** * Current results of this test case. * @@ -1448,6 +1462,159 @@ protected function prepareEnvironment() { $this->setupEnvironment = TRUE; } + /** + * Copies the cached tables and files for a cached installation setup. + * + * @param string $cache_key_prefix + * (optional) Additional prefix for the cache key. + * + * @return bool + * TRUE when the cache was usable and loaded, FALSE when cache was not + * available. + * + * @see DrupalWebTestCase::setUp() + */ + protected function loadSetupCache($cache_key_prefix = '') { + $cache_key = $this->getSetupCacheKey($cache_key_prefix); + $cache_file = $this->originalFileDirectory . '/simpletest/' . $cache_key . '/simpletest-cache-setup'; + + if (file_exists($cache_file)) { + return $this->copySetupCache($cache_key, substr($this->databasePrefix, 10)); + } + + return FALSE; + } + + /** + * Returns the cache key used for the setup caching. + * + * @param string $cache_key_prefix + * (optional) Additional prefix for the cache key. + * + * @return string + * The cache key to use, by default only based on the profile used by the + * test. + */ + protected function getSetupCacheKey($cache_key_prefix = '') { + // The cache key needs to start with a numeric character, so that the cached + // installation gets cleaned up properly. + $cache_key_prefix = hash('crc32b', $cache_key_prefix . $this->profile); + return '1c' . $cache_key_prefix; + } + + /** + * Store the installation setup to a cache. + * + * @param string $cache_key_prefix + * (optional) Additional prefix for the cache key. + * + * @return bool + * TRUE if the installation was stored in the cache, FALSE otherwise. + */ + protected function storeSetupCache($cache_key_prefix = '') { + $cache_key = $this->getSetupCacheKey($cache_key_prefix); + $lock_key = 'simpletest_store_cache_' . $cache_key . '_' . $this->testId; + + // All concurrent tests share the same test id. Therefore it is possible to + // use the lock to ensure that only one process will store the cache. This + // is important as else DB tables created by one process could be deleted + // by another as the cache copying is idempotent. + if (! lock_acquire($lock_key)) { + return FALSE; + } + + // Try to copy the installation to the setup cache - now that we have a + // lock to do so. + if (!$this->copySetupCache(substr($this->databasePrefix, 10), $cache_key)) { + // It is non-fatal if the cache cannot be copied as the next test run + // will try it again. + $this->assert('debug', t('Storing cache with key @key failed', array('@key' => $cache_key)), 'storeSetupCache'); + + lock_release($lock_key); + return FALSE; + } + + // Inform others that this cache is usable now. + $cache_file = $this->originalFileDirectory . '/simpletest/' . $cache_key . '/simpletest-cache-setup'; + file_put_contents($cache_file, time(NULL)); + + lock_release($lock_key); + return TRUE; + } + + /** + * Copy the setup cache from/to another table and files directory. + * + * @param string $from + * The prefix_id / cache_key from where to copy. + * @param string $to + * The prefix_id / cache_key to where to copy. + * + * @return bool + * TRUE if the setup cache was copied to the current installation, FALSE + * otherwise. + */ + protected function copySetupCache($from, $to) { + $from_prefix = 'simpletest' . $from; + $to_prefix = 'simpletest' . $to; + + try { + $tables = db_query("SHOW TABLES LIKE :prefix", array(':prefix' => db_like($from_prefix) . '%' ))->fetchCol(); + + if (count($tables) == 0) { + return FALSE; + } + + foreach ($tables as $from_table) { + $table = substr($from_table, strlen($from_prefix)); + $to_table = $to_prefix . $table; + + // Remove the table in case the copying process was interrupted. + db_query('DROP TABLE IF EXISTS ' . $to_table); + db_query('CREATE TABLE ' . $to_table . ' LIKE ' . $from_table); + db_query('ALTER TABLE ' . $to_table . ' DISABLE KEYS'); + db_query('INSERT ' . $to_table . ' SELECT * FROM ' . $from_table); + db_query('ALTER TABLE ' . $to_table . ' ENABLE KEYS'); + } + } + catch (Exception $e) { + return FALSE; + } + + $from_dir = $this->originalFileDirectory . '/simpletest/' . $from; + $to_dir = $this->originalFileDirectory . '/simpletest/' . $to; + $this->recursiveDirectoryCopy($from_dir, $to_dir); + + return TRUE; + } + + /** + * Recursively copy one directory to another. + * + * @param $src + * The source directory. + * @param $dest + * The destination directory. + */ + protected function recursiveDirectoryCopy($src, $dst) { + $dir = opendir($src); + + if (!file_exists($dst)){ + mkdir($dst); + } + while (($file = readdir($dir)) !== FALSE) { + if ($file != '.' && $file != '..') { + if (is_dir($src . '/' . $file)) { + $this->recursiveDirectoryCopy($src . '/' . $file, $dst . '/' . $file); + } + else { + copy($src . '/' . $file, $dst . '/' . $file); + } + } + } + closedir($dir); + } + /** * Sets up a Drupal site for running functional and integration tests. * @@ -1501,57 +1668,108 @@ protected function setUp() { // profile's hook_install() and other hook implementations are never invoked. $conf['install_profile'] = $this->profile; - // Perform the actual Drupal installation. - include_once DRUPAL_ROOT . '/includes/install.inc'; - drupal_install_system(); + $has_installation_cache = FALSE; + $has_modules_cache = FALSE; - $this->preloadRegistry(); + if ($this->useSetupModulesCache) { + $modules = func_get_args(); + // Modules can be either one parameter or multiple. + if (isset($modules[0]) && is_array($modules[0])) { + $modules = $modules[0]; + } + $modules = array_unique($modules); + sort($modules); - // Set path variables. - variable_set('file_public_path', $this->public_files_directory); - variable_set('file_private_path', $this->private_files_directory); - variable_set('file_temporary_path', $this->temp_files_directory); + $modules_cache_key_prefix = hash('crc32b', serialize($modules)) . '_'; + $has_modules_cache = $this->loadSetupCache($modules_cache_key_prefix); + } - // Set the 'simpletest_parent_profile' variable to add the parent profile's - // search path to the child site's search paths. - // @see drupal_system_listing() - // @todo This may need to be primed like 'install_profile' above. - variable_set('simpletest_parent_profile', $this->originalProfile); + if (!$has_modules_cache && $this->useSetupInstallationCache) { + $has_installation_cache = $this->loadSetupCache(); + } - // Include the testing profile. - variable_set('install_profile', $this->profile); - $profile_details = install_profile_info($this->profile, 'en'); + if ($has_modules_cache || $has_installation_cache) { + // Reset path variables. + variable_set('file_public_path', $this->public_files_directory); + variable_set('file_private_path', $this->private_files_directory); + variable_set('file_temporary_path', $this->temp_files_directory); + $this->refreshVariables(); - // Install the modules specified by the testing profile. - module_enable($profile_details['dependencies'], FALSE); + // Load all enabled modules + module_load_all(); - // Install modules needed for this test. This could have been passed in as - // either a single array argument or a variable number of string arguments. - // @todo Remove this compatibility layer in Drupal 8, and only accept - // $modules as a single array argument. - $modules = func_get_args(); - if (isset($modules[0]) && is_array($modules[0])) { - $modules = $modules[0]; - } - if ($modules) { - $success = module_enable($modules, TRUE); - $this->assertTrue($success, t('Enabled modules: %modules', array('%modules' => implode(', ', $modules)))); + $this->pass(t('Using cache: @cache (@key)', array( + '@cache' => $has_modules_cache ? t('Modules Cache') : t('Installation Cache'), + '@key' => $this->getSetupCacheKey($has_modules_cache ? $modules_cache_key_prefix : ''), + ))); } + else { + // Perform the actual Drupal installation. + include_once DRUPAL_ROOT . '/includes/install.inc'; + drupal_install_system(); + + $this->preloadRegistry(); + + // Set path variables. + variable_set('file_public_path', $this->public_files_directory); + variable_set('file_private_path', $this->private_files_directory); + variable_set('file_temporary_path', $this->temp_files_directory); + + // Set the 'simpletest_parent_profile' variable to add the parent profile's + // search path to the child site's search paths. + // @see drupal_system_listing() + // @todo This may need to be primed like 'install_profile' above. + variable_set('simpletest_parent_profile', $this->originalProfile); + + // Include the testing profile. + variable_set('install_profile', $this->profile); + $profile_details = install_profile_info($this->profile, 'en'); + + // Install the modules specified by the testing profile. + module_enable($profile_details['dependencies'], FALSE); - // Run the profile tasks. - $install_profile_module_exists = db_query("SELECT 1 FROM {system} WHERE type = 'module' AND name = :name", array( - ':name' => $this->profile, - ))->fetchField(); - if ($install_profile_module_exists) { - module_enable(array($this->profile), FALSE); + if ($this->useSetupInstallationCache) { + $this->storeSetupCache(); + } } - // Reset/rebuild all data structures after enabling the modules. - $this->resetAll(); + if (!$has_modules_cache) { + // Install modules needed for this test. This could have been passed in as + // either a single array argument or a variable number of string arguments. + // @todo Remove this compatibility layer in Drupal 8, and only accept + // $modules as a single array argument. + $modules = func_get_args(); + if (isset($modules[0]) && is_array($modules[0])) { + $modules = $modules[0]; + } + if ($modules) { + $success = module_enable($modules, TRUE); + $this->assertTrue($success, t('Enabled modules: %modules', array('%modules' => implode(', ', $modules)))); + } + + // Run the profile tasks. + $install_profile_module_exists = db_query("SELECT 1 FROM {system} WHERE type = 'module' AND name = :name", array( + ':name' => $this->profile, + ))->fetchField(); + if ($install_profile_module_exists) { + module_enable(array($this->profile), FALSE); + } + + // Reset/rebuild all data structures after enabling the modules. + $this->resetAll(); - // Run cron once in that environment, as install.php does at the end of - // the installation process. - drupal_cron_run(); + // Run cron once in that environment, as install.php does at the end of + // the installation process. + drupal_cron_run(); + + if ($this->useSetupModulesCache) { + $this->storeSetupCache($modules_cache_key_prefix); + } + } + else { + // Reset/rebuild all data structures after enabling the modules. + $this->resetAll(); + } // Ensure that the session is not written to the new environment and replace // the global $user session with uid 1 from the new test site. diff --git a/modules/simpletest/files/css_test_files/comment_hacks.css b/modules/simpletest/files/css_test_files/comment_hacks.css index c47e8429ac2..ed8c15c5038 100644 --- a/modules/simpletest/files/css_test_files/comment_hacks.css +++ b/modules/simpletest/files/css_test_files/comment_hacks.css @@ -7,6 +7,11 @@ A large comment block to test for segfaults and speed. This is 60K a's. Extreme but useful to demonstrate flaws in comment striping regexp. aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa*/ .test1 { display:block;} +/* A pseudo selector with essential whitespace wrapped in quotes. */ +img[style*="float: right"] { + padding-left:5px; +} + /* A multiline IE-mac hack (v.2) taken fron Zen theme*/ /* Hides from IE-mac \*/ html .clear-block { diff --git a/modules/simpletest/files/css_test_files/comment_hacks.css.optimized.css b/modules/simpletest/files/css_test_files/comment_hacks.css.optimized.css index 1feb8f1bd7d..65823082e73 100644 --- a/modules/simpletest/files/css_test_files/comment_hacks.css.optimized.css +++ b/modules/simpletest/files/css_test_files/comment_hacks.css.optimized.css @@ -1 +1 @@ -.test1{display:block;}html .clear-block{height:1%;}.clear-block{display:block;font:italic bold 12px/30px Georgia,serif;}.test2{display:block;}.bkslshv1{background-color:#C00;}.test3{display:block;}.test4{display:block;}.comment-in-double-quotes:before{content:"/* ";}.this_rule_must_stay{color:#F00;background-color:#FFF;}.comment-in-double-quotes:after{content:" */";}.comment-in-single-quotes:before{content:'/*';}.this_rule_must_stay{color:#F00;background-color:#FFF;}.comment-in-single-quotes:after{content:'*/';}.comment-in-mixed-quotes:before{content:'"/*"';}.this_rule_must_stay{color:#F00;background-color:#FFF;}.comment-in-mixed-quotes:after{content:"'*/'";}.comment-in-quotes-with-escaped:before{content:'/* \" \' */';}.this_rule_must_stay{color:#F00;background-color:#FFF;}.comment-in-quotes-with-escaped:after{content:"*/ \" \ '";} +.test1{display:block;}img[style*="float: right"]{padding-left:5px;}html .clear-block{height:1%;}.clear-block{display:block;font:italic bold 12px/30px Georgia,serif;}.test2{display:block;}.bkslshv1{background-color:#C00;}.test3{display:block;}.test4{display:block;}.comment-in-double-quotes:before{content:"/* ";}.this_rule_must_stay{color:#F00;background-color:#FFF;}.comment-in-double-quotes:after{content:" */";}.comment-in-single-quotes:before{content:'/*';}.this_rule_must_stay{color:#F00;background-color:#FFF;}.comment-in-single-quotes:after{content:'*/';}.comment-in-mixed-quotes:before{content:'"/*"';}.this_rule_must_stay{color:#F00;background-color:#FFF;}.comment-in-mixed-quotes:after{content:"'*/'";}.comment-in-quotes-with-escaped:before{content:'/* \" \' */';}.this_rule_must_stay{color:#F00;background-color:#FFF;}.comment-in-quotes-with-escaped:after{content:"*/ \" \ '";} diff --git a/modules/simpletest/files/css_test_files/comment_hacks.css.unoptimized.css b/modules/simpletest/files/css_test_files/comment_hacks.css.unoptimized.css index c47e8429ac2..ed8c15c5038 100644 --- a/modules/simpletest/files/css_test_files/comment_hacks.css.unoptimized.css +++ b/modules/simpletest/files/css_test_files/comment_hacks.css.unoptimized.css @@ -7,6 +7,11 @@ A large comment block to test for segfaults and speed. This is 60K a's. Extreme but useful to demonstrate flaws in comment striping regexp. aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa*/ .test1 { display:block;} +/* A pseudo selector with essential whitespace wrapped in quotes. */ +img[style*="float: right"] { + padding-left:5px; +} + /* A multiline IE-mac hack (v.2) taken fron Zen theme*/ /* Hides from IE-mac \*/ html .clear-block { diff --git a/modules/simpletest/files/css_test_files/css_input_without_import.css.optimized.css b/modules/simpletest/files/css_test_files/css_input_without_import.css.optimized.css index c7bb9dcd17c..e22077a21d7 100644 --- a/modules/simpletest/files/css_test_files/css_input_without_import.css.optimized.css +++ b/modules/simpletest/files/css_test_files/css_input_without_import.css.optimized.css @@ -1,4 +1,4 @@ body{margin:0;padding:0;background:#edf5fa;font:76%/170% Verdana,sans-serif;color:#494949;}.this .is .a .test{font:1em/100% Verdana,sans-serif;color:#494949;}.this .is .a -.test{font:1em/100% Verdana,sans-serif;color:#494949;}some :pseudo .thing{-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;filter:progid:DXImageTransform.Microsoft.Shadow(color=#000000,direction='180',strength='10');-ms-filter:"progid:DXImageTransform.Microsoft.Shadow(color=#000000,direction='180',strength='10')";}::-moz-selection{background:#000;color:#fff;}::selection{background:#000;color:#fff;}@media print{*{background:#000 !important;color:#fff !important;}@page{margin:0.5cm;}}@media screen and (max-device-width:480px){background:#000;color:#fff;}textarea,select{font:1em/160% Verdana,sans-serif;color:#494949;} +.test{font:1em/100% Verdana,sans-serif;color:#494949;}some :pseudo .thing{-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;filter:progid:DXImageTransform.Microsoft.Shadow(color=#000000,direction='180',strength='10');-ms-filter:"progid:DXImageTransform.Microsoft.Shadow(color=#000000, direction='180', strength='10')";}::-moz-selection{background:#000;color:#fff;}::selection{background:#000;color:#fff;}@media print{*{background:#000 !important;color:#fff !important;}@page{margin:0.5cm;}}@media screen and (max-device-width:480px){background:#000;color:#fff;}textarea,select{font:1em/160% Verdana,sans-serif;color:#494949;} diff --git a/modules/simpletest/files/css_test_files/quotes.css b/modules/simpletest/files/css_test_files/quotes.css new file mode 100644 index 00000000000..3fe0f7d503f --- /dev/null +++ b/modules/simpletest/files/css_test_files/quotes.css @@ -0,0 +1,31 @@ +/* Example from https://www.w3.org/TR/CSS2/syndata.html#rule-sets */ +q[example="public class foo\ +{\ + private int x;\ +\ + foo(int x) {\ + this.x = x;\ + }\ +\ +}"] { color: red } + +/* A pseudo selector with essential whitespace wrapped in quotes. */ +q[style*="quotes: none"] { + quotes: none; +} + +q[style*='quotes: none'] { + quotes: none; +} + +q:after { + content: ": colon & escaped double \" quotes \"."; +} + +q:after { + content: ' (brackets & escaped single \' quotes \') '; +} + +q:after { + content: "I'm Quote"; +} diff --git a/modules/simpletest/files/css_test_files/quotes.css.optimized.css b/modules/simpletest/files/css_test_files/quotes.css.optimized.css new file mode 100644 index 00000000000..716cef729f7 --- /dev/null +++ b/modules/simpletest/files/css_test_files/quotes.css.optimized.css @@ -0,0 +1,9 @@ +q[example="public class foo\ +{\ + private int x;\ +\ + foo(int x) {\ + this.x = x;\ + }\ +\ +}"]{color:red}q[style*="quotes: none"]{quotes:none;}q[style*='quotes: none']{quotes:none;}q:after{content:": colon & escaped double \" quotes \".";}q:after{content:' (brackets & escaped single \' quotes \') ';}q:after{content:"I'm Quote";} diff --git a/modules/simpletest/files/css_test_files/quotes.css.unoptimized.css b/modules/simpletest/files/css_test_files/quotes.css.unoptimized.css new file mode 100644 index 00000000000..3fe0f7d503f --- /dev/null +++ b/modules/simpletest/files/css_test_files/quotes.css.unoptimized.css @@ -0,0 +1,31 @@ +/* Example from https://www.w3.org/TR/CSS2/syndata.html#rule-sets */ +q[example="public class foo\ +{\ + private int x;\ +\ + foo(int x) {\ + this.x = x;\ + }\ +\ +}"] { color: red } + +/* A pseudo selector with essential whitespace wrapped in quotes. */ +q[style*="quotes: none"] { + quotes: none; +} + +q[style*='quotes: none'] { + quotes: none; +} + +q:after { + content: ": colon & escaped double \" quotes \"."; +} + +q:after { + content: ' (brackets & escaped single \' quotes \') '; +} + +q:after { + content: "I'm Quote"; +} diff --git a/modules/simpletest/simpletest.module b/modules/simpletest/simpletest.module index 6a60d594926..ebc9b4bf05c 100644 --- a/modules/simpletest/simpletest.module +++ b/modules/simpletest/simpletest.module @@ -592,7 +592,8 @@ function simpletest_clean_temporary_directories() { $files = scandir('public://simpletest'); foreach ($files as $file) { $path = 'public://simpletest/' . $file; - if (is_dir($path) && is_numeric($file)) { + // Ensure that cache directories are cleaned as well. + if (is_dir($path) && (is_numeric($file) || strpos($file, '1c') === 0)) { file_unmanaged_delete_recursive($path); $count++; } diff --git a/modules/simpletest/tests/common.test b/modules/simpletest/tests/common.test index ff399676305..f5b85bad0ba 100644 --- a/modules/simpletest/tests/common.test +++ b/modules/simpletest/tests/common.test @@ -1069,7 +1069,8 @@ class CascadingStylesheetsUnitTest extends DrupalUnitTestCase { 'css_input_without_import.css', 'css_input_with_import.css', 'css_subfolder/css_input_with_import.css', - 'comment_hacks.css' + 'comment_hacks.css', + 'quotes.css', ); $path = drupal_get_path('module', 'simpletest') . '/files/css_test_files'; foreach ($testfiles as $file) { @@ -3244,3 +3245,55 @@ class DrupalGetQueryArrayTestCase extends DrupalWebTestCase { } } + +/** + * Test for block_interest_cohort. + */ +class BlockInterestCohortTest extends DrupalWebTestCase { + + public static function getInfo() { + return array( + 'name' => 'Block Interest Cohort', + 'description' => 'Check Permissions-Policy header to disable Google FLoC', + 'group' => 'System', + ); + } + + function setUp() { + parent::setUp('common_test'); + } + + /** + * Tests that FLoC is blocked by default. + */ + function testDefaultBlocking() { + $this->drupalGet('node'); + $this->assertEqual($this->drupalGetHeader('Permissions-Policy'), 'interest-cohort=()', 'FLoC is blocked by default.'); + } + + /** + * Tests that an existing interest-cohort policy is not overwritten. + */ + function testExistingInterestCohortPolicy() { + $this->drupalGet('common-test/existing_interest_cohort_policy'); + $this->assertEqual($this->drupalGetHeader('Permissions-Policy'), 'interest-cohort=*', 'Existing interest-cohort policy is not overwritten.'); + } + + /** + * Tests that an existing header is appended to correctly. + */ + function testExistingPolicyHeader() { + $this->drupalGet('common-test/existing_permissions_policy_header'); + $this->assertTrue((strpos($this->drupalGetHeader('Permissions-Policy'), 'geolocation=(),interest-cohort=()') !== FALSE), 'The existing header is appended to.'); + } + + /** + * Tests that FLoC blocking can be disabled. + */ + function testDisableBlocking() { + variable_set('block_interest_cohort', FALSE); + $this->drupalGet('node'); + $this->assertFalse($this->drupalGetHeader('Permissions-Policy'), 'FLoC blocking can be disabled.'); + } + +} diff --git a/modules/simpletest/tests/common_test.module b/modules/simpletest/tests/common_test.module index d092c9249c0..d7b97bc892b 100644 --- a/modules/simpletest/tests/common_test.module +++ b/modules/simpletest/tests/common_test.module @@ -52,6 +52,18 @@ function common_test_menu() { 'access arguments' => array('access content'), 'type' => MENU_CALLBACK, ); + $items['common-test/existing_interest_cohort_policy'] = array( + 'title' => 'Test existing interest-cohort policy', + 'page callback' => 'existing_interest_cohort_policy', + 'access arguments' => array('access content'), + 'type' => MENU_CALLBACK, + ); + $items['common-test/existing_permissions_policy_header'] = array( + 'title' => 'Test existing Permissions-Policy header', + 'page callback' => 'existing_permissions_policy_header', + 'access arguments' => array('access content'), + 'type' => MENU_CALLBACK, + ); return $items; } @@ -286,3 +298,19 @@ function common_test_js_and_css_querystring() { function common_test_cron() { throw new Exception(t('Uncaught exception')); } + +/** + * Page callback. + */ +function existing_interest_cohort_policy() { + drupal_add_http_header('Permissions-Policy', 'interest-cohort=*'); + print __FUNCTION__; +} + +/** + * Page callback. + */ +function existing_permissions_policy_header() { + drupal_add_http_header('Permissions-Policy', 'geolocation=()'); + print __FUNCTION__; +} diff --git a/modules/simpletest/tests/form.test b/modules/simpletest/tests/form.test index 23af5f4c7fc..a4213241e04 100644 --- a/modules/simpletest/tests/form.test +++ b/modules/simpletest/tests/form.test @@ -852,6 +852,12 @@ class FormsElementsLabelsTestCase extends DrupalWebTestCase { $this->assertEqual($elements[0]['title'], 'Checkboxes test' . ' (' . t('Required') . ')', 'Title attribute found.'); $elements = $this->xpath('//div[@id="edit-form-radios-title-attribute"]'); $this->assertEqual($elements[0]['title'], 'Radios test' . ' (' . t('Required') . ')', 'Title attribute found.'); + + // Check that empty name attribute is not printed on buttons. + $elements = $this->xpath('//input[@id="edit-form-button-with-name"]'); + $this->assertTrue($elements[0]['name'] == 'op', 'Name attribute found.'); + $elements = $this->xpath('//input[@id="edit-form-button-without-name"]'); + $this->assertFalse(isset($elements[0]['name']), 'No name attribute found.'); } } diff --git a/modules/simpletest/tests/form_test.module b/modules/simpletest/tests/form_test.module index 9f071826e5c..63730c9fd06 100644 --- a/modules/simpletest/tests/form_test.module +++ b/modules/simpletest/tests/form_test.module @@ -1022,6 +1022,16 @@ function form_label_test_form() { '#title_display' => 'attribute', '#required' => TRUE, ); + // Button elements with and without name attribute. + $form['form_button_with_name'] = array( + '#type' => 'button', + '#value' => t('Button with name'), + ); + $form['form_button_without_name'] = array( + '#type' => 'button', + '#value' => t('Button without name'), + '#name' => '', + ); return $form; } diff --git a/modules/system/system.install b/modules/system/system.install index 43dc90c4e9c..0b79c105b04 100644 --- a/modules/system/system.install +++ b/modules/system/system.install @@ -535,6 +535,37 @@ function system_requirements($phase) { } } + // Warning for httpoxy on IIS with affected PHP versions. + // @see https://www.drupal.org/node/2783079 + if (strpos($software, 'Microsoft-IIS') !== FALSE && (version_compare(PHP_VERSION, '5.5.38', '<') + || (version_compare(PHP_VERSION, '5.6.0', '>=') && version_compare(PHP_VERSION, '5.6.24', '<')) + || (version_compare(PHP_VERSION, '7.0.0', '>=') && version_compare(PHP_VERSION, '7.0.9', '<')) + )) { + $dom = new \DOMDocument('1.0', 'UTF-8'); + $webconfig = file_get_contents('web.config'); + // If you are here the web.config file must - of course - be well formed. + // But the PHP DOM component will throw warnings on some XML compliant + // stuff, so silently parse the configuration file. + @$dom->loadHTML($webconfig); + $httpoxy_rewrite = FALSE; + foreach ($dom->getElementsByTagName('rule') as $rule) { + foreach ($rule->attributes as $attr) { + if (@$attr->name == 'name' && @$attr->nodeValue == 'Erase HTTP_PROXY') { + $httpoxy_rewrite = TRUE; + break 2; + } + } + } + if (!$httpoxy_rewrite) { + $requirements['iis_httpoxy_protection'] = array( + 'title' => t('IIS httpoxy protection'), + 'value' => t('Your PHP runtime version is affected by the httpoxy vulnerability.'), + 'description' => t('Either update your PHP runtime version or uncomment the "Erase HTTP_PROXY" rule in your web.config file and add HTTP_PROXY to the allowed headers list. See more details in the security advisory.', array('@link' => 'https://www.drupal.org/SA-CORE-2016-003')), + 'severity' => REQUIREMENT_ERROR, + ); + } + } + return $requirements; } diff --git a/modules/system/system.tar.inc b/modules/system/system.tar.inc index 7a0719e5850..505f2c0ba71 100644 --- a/modules/system/system.tar.inc +++ b/modules/system/system.tar.inc @@ -2178,14 +2178,6 @@ class Archive_Tar } } } elseif ($v_header['typeflag'] == "2") { - if (strpos(realpath(dirname($v_header['link'])), realpath($p_path)) !== 0) { - $this->_error( - 'Out-of-path file extraction {' - . $v_header['filename'] . ' --> ' . - $v_header['link'] . '}' - ); - return false; - } if (!$p_symlinks) { $this->_warning('Symbolic links are not allowed. ' . 'Unable to extract {' @@ -2193,6 +2185,40 @@ class Archive_Tar ); return false; } + $absolute_link = FALSE; + $link_depth = 0; + if (strpos($v_header['link'], "/") === 0 || strpos($v_header['link'], ':') !== FALSE) { + $absolute_link = TRUE; + } + else { + $s_filename = preg_replace('@^' . preg_quote($p_path) . '@', "", $v_header['filename']); + $s_linkname = str_replace('\\', '/', $v_header['link']); + foreach (explode("/", $s_filename) as $dir) { + if ($dir === "..") { + $link_depth--; + } elseif ($dir !== "" && $dir !== "." ) { + $link_depth++; + } + } + foreach (explode("/", $s_linkname) as $dir){ + if ($link_depth <= 0) { + break; + } + if ($dir === "..") { + $link_depth--; + } elseif ($dir !== "" && $dir !== ".") { + $link_depth++; + } + } + } + if ($absolute_link || $link_depth <= 0) { + $this->_error( + 'Out-of-path file extraction {' + . $v_header['filename'] . ' --> ' . + $v_header['link'] . '}' + ); + return false; + } if (@file_exists($v_header['filename'])) { @drupal_unlink($v_header['filename']); } diff --git a/modules/user/user.test b/modules/user/user.test index 70556bff8ee..ec2f90d6f1f 100644 --- a/modules/user/user.test +++ b/modules/user/user.test @@ -679,84 +679,6 @@ class UserPasswordResetTestCase extends DrupalWebTestCase { $this->assertText(t('Sorry, too many password reset attempts from your IP address. This IP address is temporarily blocked.'), 'Flood control was triggered by excessive password resets from one IP.'); } - /** - * Test user-based flood control on password reset. - */ - function testPasswordResetFloodControlPerUser() { - // Set a very low limit for testing. - variable_set('user_pass_reset_user_limit', 2); - - // Create a user. - $account = $this->drupalCreateUser(); - $this->drupalLogin($account); - $this->drupalLogout(); - - $edit = array('name' => $account->name); - - // Try 2 requests that should not trigger flood control. - for ($i = 0; $i < 2; $i++) { - $this->drupalPost('user/password', $edit, t('E-mail new password')); - // Confirm the password reset. - $this->assertText(t('Further instructions have been sent to your e-mail address.'), 'Password reset instructions mailed message displayed.'); - // Ensure that flood control was not triggered. - $this->assertNoText(t('is temporarily blocked. Try again later'), 'Flood control was not triggered by password reset.'); - } - - // A successful password reset should clear flood events. - $resetURL = $this->getResetURL(); - $this->drupalGet($resetURL); - - // Check successful login. - $this->drupalPost(NULL, NULL, t('Log in')); - $this->drupalLogout(); - - // Try 2 requests that should not trigger flood control. - for ($i = 0; $i < 2; $i++) { - $this->drupalPost('user/password', $edit, t('E-mail new password')); - // Confirm the password reset. - $this->assertText(t('Further instructions have been sent to your e-mail address.'), 'Password reset instructions mailed message displayed.'); - // Ensure that flood control was not triggered. - $this->assertNoText(t('is temporarily blocked. Try again later'), 'Flood control was not triggered by password reset.'); - } - - // The next request should trigger flood control - $this->drupalPost('user/password', $edit, t('E-mail new password')); - // Confirm the password reset was blocked. - $this->assertNoText(t('Further instructions have been sent to your e-mail address.'), 'Password reset instructions mailed message not displayed for excessive password resets.'); - // Ensure that flood control was triggered. - $this->assertText(t('Sorry, there have been more than 2 password reset attempts for this account. It is temporarily blocked.'), 'Flood control was triggered by excessive password resets for one user.'); - } - - /** - * Test IP-based flood control on password reset. - */ - function testPasswordResetFloodControlPerIp() { - // Set a very low limit for testing. - variable_set('user_pass_reset_ip_limit', 2); - - // Try 2 requests that should not trigger flood control. - for ($i = 0; $i < 2; $i++) { - $name = $this->randomName(); - $edit = array('name' => $name); - $this->drupalPost('user/password', $edit, t('E-mail new password')); - // Confirm the password reset was not blocked. Note that @name is used - // instead of %name as assertText() works with plain text not HTML. - $this->assertText(t('Sorry, @name is not recognized as a user name or an e-mail address.', array('@name' => $name)), 'User name not recognized message displayed.'); - // Ensure that flood control was not triggered. - $this->assertNoText(t('is temporarily blocked. Try again later'), 'Flood control was not triggered by password reset.'); - } - - // The next request should trigger flood control - $name = $this->randomName(); - $edit = array('name' => $name); - $this->drupalPost('user/password', $edit, t('E-mail new password')); - // Confirm the password reset was blocked early. Note that @name is used - // instead of %name as assertText() works with plain text not HTML. - $this->assertNoText(t('Sorry, @name is not recognized as a user name or an e-mail address.', array('@name' => $name)), 'User name not recognized message not displayed.'); - // Ensure that flood control was triggered. - $this->assertText(t('Sorry, too many password reset attempts from your IP address. This IP address is temporarily blocked.'), 'Flood control was triggered by excessive password resets from one IP.'); - } - /** * Test user password reset while logged in. */ diff --git a/profiles/dkan/.probo.yml b/profiles/dkan/.probo.yml index a76edb96c20..6ed60caae90 100644 --- a/profiles/dkan/.probo.yml +++ b/profiles/dkan/.probo.yml @@ -1,4 +1,4 @@ -image: proboci/ubuntu:18.04-php7.3 +image: proboci/ubuntu:18.04-php7.4 steps: - name: Setup QA site plugin: Script diff --git a/profiles/dkan/README.md b/profiles/dkan/README.md index aa097c1a5a3..3c1471c4c25 100644 --- a/profiles/dkan/README.md +++ b/profiles/dkan/README.md @@ -1,4 +1,4 @@ -# DKAN Open Data Platform (7.x-1.18.16) +# DKAN Open Data Platform (7.x-1.18.17) DKAN is an open source open data platform with a full suite of cataloging, publishing and visualization features that allow organizations to easily publish data to the public. diff --git a/profiles/dkan/dkan.info b/profiles/dkan/dkan.info index 1d86dbb8095..ba8c745053b 100644 --- a/profiles/dkan/dkan.info +++ b/profiles/dkan/dkan.info @@ -127,4 +127,4 @@ dependencies[] = dkan_datastore_simple_import dependencies[] = dkan_datastore_api dependencies[] = open_data_schema_map_dkan dependencies[] = visualization_entity_charts_dkan -version = 7.x-1.18.16 +version = 7.x-1.18.17 diff --git a/profiles/dkan/drupal-org-core.make b/profiles/dkan/drupal-org-core.make index 2a81631345e..dfcd5b49d49 100644 --- a/profiles/dkan/drupal-org-core.make +++ b/profiles/dkan/drupal-org-core.make @@ -3,7 +3,7 @@ core: 7.x projects: drupal: type: core - version: '7.80' + version: '7.82' # Use vocabulary machine name for permissions, see http://drupal.org/node/995156 patch: 995156: 'https://drupal.org/files/issues/995156-5_portable_taxonomy_permissions.patch' diff --git a/profiles/dkan/modules/contrib/entity/README.txt b/profiles/dkan/modules/contrib/entity/README.txt index 745dd7fe831..c2a3731deae 100644 --- a/profiles/dkan/modules/contrib/entity/README.txt +++ b/profiles/dkan/modules/contrib/entity/README.txt @@ -84,7 +84,7 @@ developing, you may stop reading now. To see how to provide a separate class have a look at the "EntityClass" from the "entity_test.module". - * Implement hook_entity_info() for your entity. At least specifiy the + * Implement hook_entity_info() for your entity. At least specify the controller class (EntityAPIController, EntityAPIControllerExportable or your own), your db table and your entity's keys. Again just look at "entity_test.module"'s hook_entity_info() for guidance. diff --git a/profiles/dkan/modules/contrib/entity/ctools/relationships/entity_property.inc b/profiles/dkan/modules/contrib/entity/ctools/relationships/entity_property.inc index 6869146f9a5..458f018291c 100644 --- a/profiles/dkan/modules/contrib/entity/ctools/relationships/entity_property.inc +++ b/profiles/dkan/modules/contrib/entity/ctools/relationships/entity_property.inc @@ -19,7 +19,7 @@ $plugin = array( 'defaults' => array( 'selector' => '', 'target_context' => 'entity', - 'concatenator' => ',' + 'concatenator' => ',', ), ); @@ -90,7 +90,7 @@ function entity_entity_property_edit_form($form, &$form_state) { '#type' => 'textfield', '#title' => t('Data selector'), '#description' => t('Any valid data selector, e.g. "title" to select a node\'s title, or "field_tags:1" to select the second tag.'), - '#default_value' => $conf['selector'], + '#default_value' => $conf['selector'], '#required' => TRUE, ); $form['concatenator'] = array( @@ -116,7 +116,7 @@ function entity_entity_property_edit_form_validate($form, &$form_state) { $parts = explode(':', $form_state['values']['selector']); foreach ($parts as $part) { if (!($wrapper instanceof EntityStructureWrapper || $wrapper instanceof EntityListWrapper)) { - form_set_error('selector', t('Unable to apply the data selector part %key.'. array('%key' => $part))); + form_set_error('selector', t('Unable to apply the data selector part %key.', array('%key' => $part))); continue; } $wrapper = $wrapper->get($part); @@ -142,7 +142,7 @@ function entity_entity_property_map_data_type($type) { while ($item_type = entity_property_list_extract_type($type)) { $type = $item_type; } - // Massage data type of entites to c + // Massage data type of entities to ctools type. if (entity_get_info($type)) { $type = "entity:$type"; } diff --git a/profiles/dkan/modules/contrib/entity/entity.api.php b/profiles/dkan/modules/contrib/entity/entity.api.php index 3f777526582..9b77e2b196b 100644 --- a/profiles/dkan/modules/contrib/entity/entity.api.php +++ b/profiles/dkan/modules/contrib/entity/entity.api.php @@ -256,7 +256,7 @@ function entity_metadata_hook_entity_info() { * by entity_metadata_wrapper(). * For providing property information for fields see entity_hook_field_info(). * - * @return + * @return array * An array whose keys are entity type names and whose values are arrays * containing the keys: * - properties: The array describing all properties for this entity. Entries @@ -462,6 +462,96 @@ function hook_entity_views_field_handlers_alter(array &$field_handlers) { $field_handlers['node'] = 'example_node_handler'; } +/** + * Act after default entities have been rebuilt. + * + * This hook is invoked after default entities have been fully saved to the + * database, but with the lock still active. + * + * @param array $entities + * An array of the entities that have been saved, keyed by name. + * @param array $originals + * An array of the original copies of the entities that have been saved, + * keyed by name. + * + * @see _entity_defaults_rebuild() + */ +function hook_ENTITY_TYPE_defaults_rebuild($entities, $originals) { + +} + +/** + * Act on an entity before it is about to be created or updated. + * + * @param $entity + * The entity object. + * + * @see hook_entity_presave() + */ +function hook_ENTITY_TYPE_presave($entity) { + $entity->changed = REQUEST_TIME; +} + +/** + * Act on entities when inserted. + * + * @param $entity + * The entity object. + * + * @see hook_entity_insert() + */ +function hook_ENTITY_TYPE_insert($entity) { + // Insert the new entity into a fictional table of all entities. + list($id) = entity_extract_ids($type, $entity); + db_insert('example_entity') + ->fields(array( + 'type' => $type, + 'id' => $id, + 'created' => REQUEST_TIME, + 'updated' => REQUEST_TIME, + )) + ->execute(); +} + +/** + * Act on entities when updated. + * + * @param $entity + * The entity object. + * + * @see hook_entity_update() + */ +function hook_ENTITY_TYPE_update($entity) { + // Update the entity's entry in a fictional table of all entities. + $info = entity_get_info($type); + list($id) = entity_extract_ids($type, $entity); + db_update('example_entity') + ->fields(array( + 'updated' => REQUEST_TIME, + )) + ->condition('type', $type) + ->condition('id', $id) + ->execute(); +} + +/** + * Act on entities when deleted. + * + * @param $entity + * The entity object. + * + * @see hook_entity_delete() + */ +function hook_ENTITY_TYPE_delete($entity) { + // Delete the entity's entry from a fictional table of all entities. + $info = entity_get_info($type); + list($id) = entity_extract_ids($type, $entity); + db_delete('example_entity') + ->condition('type', $type) + ->condition('id', $id) + ->execute(); +} + /** * @} End of "addtogroup hooks". */ diff --git a/profiles/dkan/modules/contrib/entity/entity.features.inc b/profiles/dkan/modules/contrib/entity/entity.features.inc index 0ec3e618f0e..cdefd6da78f 100644 --- a/profiles/dkan/modules/contrib/entity/entity.features.inc +++ b/profiles/dkan/modules/contrib/entity/entity.features.inc @@ -86,7 +86,7 @@ class EntityDefaultFeaturesController { else { $export['features'][$this->type][$name] = $name; - // If this is a bundle of a fieldable entity, add its fields to the pipe. + // If this is a bundle of a fieldable entity add its fields to the pipe. if (!empty($this->info['bundle of'])) { $fields = field_info_instances($this->info['bundle of'], $entity->{$this->bundleKey}); foreach ($fields as $name => $field) { @@ -110,11 +110,11 @@ class EntityDefaultFeaturesController { /** * Generates the result for hook_features_export_render(). */ - function export_render($module, $data, $export = NULL) { + public function export_render($module, $data, $export = NULL) { $output = array(); $output[] = ' $items = array();'; foreach (entity_load_multiple_by_name($this->type, $data) as $name => $entity) { - $export = " \$items['$name'] = entity_import('{$this->type}', '"; + $export = " \$items['$name'] = entity_import('{$this->type}', '"; // Make sure to escape the characters \ and '. $export .= addcslashes(entity_export($this->type, $entity, ' '), '\\\''); $export .= "');"; @@ -130,11 +130,12 @@ class EntityDefaultFeaturesController { /** * Generates the result for hook_features_revert(). */ - function revert($module = NULL) { + public function revert($module = NULL) { if ($defaults = features_get_default($this->type, $module)) { entity_delete_multiple($this->type, array_keys($defaults)); } } + } /** @@ -168,7 +169,7 @@ function entity_features_export_options($a1, $a2 = NULL) { * * Features component callback. */ -function entity_features_export($data, &$export, $module_name = '', $entity_type) { +function entity_features_export($data, &$export, $module_name, $entity_type) { return entity_features_get_controller($entity_type)->export($data, $export, $module_name); } @@ -177,7 +178,7 @@ function entity_features_export($data, &$export, $module_name = '', $entity_type * * Features component callback. */ -function entity_features_export_render($module, $data, $export = NULL, $entity_type) { +function entity_features_export_render($module, $data, $export, $entity_type) { return entity_features_get_controller($entity_type)->export_render($module, $data, $export); } @@ -186,7 +187,7 @@ function entity_features_export_render($module, $data, $export = NULL, $entity_t * * Features component callback. */ -function entity_features_revert($module = NULL, $entity_type) { +function entity_features_revert($module, $entity_type) { return entity_features_get_controller($entity_type)->revert($module); } diff --git a/profiles/dkan/modules/contrib/entity/entity.i18n.inc b/profiles/dkan/modules/contrib/entity/entity.i18n.inc index 8347eaa7c4d..71c076a861d 100644 --- a/profiles/dkan/modules/contrib/entity/entity.i18n.inc +++ b/profiles/dkan/modules/contrib/entity/entity.i18n.inc @@ -1,4 +1,5 @@ entityType, FALSE); } + } diff --git a/profiles/dkan/modules/contrib/entity/entity.info b/profiles/dkan/modules/contrib/entity/entity.info index 1adbf778433..74f253948e3 100644 --- a/profiles/dkan/modules/contrib/entity/entity.info +++ b/profiles/dkan/modules/contrib/entity/entity.info @@ -1,15 +1,22 @@ name = Entity API description = Enables modules to work with any entity type and to provide entities. core = 7.x +test_dependencies[] = rules +test_dependencies[] = i18n_string + files[] = entity.features.inc files[] = entity.i18n.inc files[] = entity.info.inc files[] = entity.rules.inc -files[] = entity.test files[] = includes/entity.inc files[] = includes/entity.controller.inc files[] = includes/entity.ui.inc files[] = includes/entity.wrapper.inc + +; Test cases +files[] = entity.test + +; Views handlers files[] = views/entity.views.inc files[] = views/handlers/entity_views_field_handler_helper.inc files[] = views/handlers/entity_views_handler_area_entity.inc @@ -25,7 +32,8 @@ files[] = views/handlers/entity_views_handler_field_uri.inc files[] = views/handlers/entity_views_handler_relationship_by_bundle.inc files[] = views/handlers/entity_views_handler_relationship.inc files[] = views/plugins/entity_views_plugin_row_entity_view.inc -; Information added by drush on 2018-02-14 + +; Information added by drush on 2021-09-03 version = "7.x-1.9" project = "entity" -datestamp = "1518619994" \ No newline at end of file +datestamp = "1630704438" \ No newline at end of file diff --git a/profiles/dkan/modules/contrib/entity/entity.info.inc b/profiles/dkan/modules/contrib/entity/entity.info.inc index 3b8ae4b4aba..0192f09bc10 100644 --- a/profiles/dkan/modules/contrib/entity/entity.info.inc +++ b/profiles/dkan/modules/contrib/entity/entity.info.inc @@ -135,6 +135,7 @@ class EntityDefaultMetadataController { protected function convertSchema() { return entity_metadata_convert_schema($this->info['base table']); } + } /** @@ -142,7 +143,8 @@ class EntityDefaultMetadataController { * * @param $table * The name of the table as used in hook_schema(). - * @return + * + * @return array * An array of property info as suiting for hook_entity_property_info(). */ function entity_metadata_convert_schema($table) { @@ -172,9 +174,11 @@ function _entity_metadata_convert_schema_type($type) { case 'serial': case 'date': return 'integer'; + case 'float': case 'numeric': return 'decimal'; + case 'char': case 'varchar': case 'text': @@ -193,9 +197,10 @@ interface EntityExtraFieldsControllerInterface { /** * Returns extra fields for this entity type. * - * @see hook_field_extra_fields(). + * @see hook_field_extra_fields() */ public function fieldExtraFields(); + } /** @@ -263,4 +268,5 @@ class EntityDefaultExtraFieldsController implements EntityExtraFieldsControllerI } return $info; } + } diff --git a/profiles/dkan/modules/contrib/entity/entity.install b/profiles/dkan/modules/contrib/entity/entity.install index 118820b80c0..1cde907e773 100644 --- a/profiles/dkan/modules/contrib/entity/entity.install +++ b/profiles/dkan/modules/contrib/entity/entity.install @@ -119,11 +119,11 @@ function entity_entitycache_uninstalled_modules($modules = NULL) { */ function _entity_entitycache_get_module_info($modules) { // Prepare a keyed array of all modules with their entity types and infos. - // Structure: [module][entity][info] + // Structure: [module][entity][info]. $entity_crud_info = entity_crud_get_info(); $info = array(); foreach ($entity_crud_info as $entity_name => $entity_info) { - // Make sure that the entity info specifies a module and supports entitycache. + // Make sure that entity_info specifies a module and supports entitycache. if (!isset($entity_info['module']) || empty($entity_info['entity cache'])) { continue; } diff --git a/profiles/dkan/modules/contrib/entity/entity.module b/profiles/dkan/modules/contrib/entity/entity.module index da0acf69798..1877da2c185 100644 --- a/profiles/dkan/modules/contrib/entity/entity.module +++ b/profiles/dkan/modules/contrib/entity/entity.module @@ -35,7 +35,7 @@ define('ENTITY_IN_CODE', 0x02); /** * A bit flag used to mark entities as overridden, e.g. they were originally - * definded in code and are saved now in the database. Same as + * defined in code and are saved now in the database. Same as * (ENTITY_CUSTOM | ENTITY_IN_CODE). */ define('ENTITY_OVERRIDDEN', 0x03); @@ -46,8 +46,6 @@ define('ENTITY_OVERRIDDEN', 0x03); */ define('ENTITY_FIXED', 0x04 | 0x02); - - /** * Determines whether for the given entity type a given operation is available. * @@ -57,7 +55,7 @@ define('ENTITY_FIXED', 0x04 | 0x02); * One of 'create', 'view', 'save', 'delete', 'revision delete', 'access' or * 'form'. * - * @return boolean + * @return bool * Whether the entity type supports the given operation. */ function entity_type_supports($entity_type, $op) { @@ -69,7 +67,7 @@ function entity_type_supports($entity_type, $op) { 'revision delete' => 'revision deletion callback', 'save' => 'save callback', 'access' => 'access callback', - 'form' => 'form callback' + 'form' => 'form callback', ); if (isset($info[$keys[$op]])) { return TRUE; @@ -105,7 +103,8 @@ function entity_type_supports($entity_type, $op) { * The ID of the entity to load, passed by the menu URL. * @param $entity_type * The type of the entity to load. - * @return + * + * @return object|false * A fully loaded entity object, or FALSE in case of error. */ function entity_object_load($entity_id, $entity_type) { @@ -198,14 +197,19 @@ function entity_ui_get_page_title($op, $entity_type, $entity = NULL) { switch ($op) { case 'view': return $label; + case 'edit': return t('Edit @label', array('@label' => $label)); + case 'clone': return t('Clone @label', array('@label' => $label)); + case 'revert': return t('Revert @label', array('@label' => $label)); + case 'delete': return t('Delete @label', array('@label' => $label)); + case 'export': return t('Export @label', array('@label' => $label)); } @@ -216,7 +220,7 @@ function entity_ui_get_page_title($op, $entity_type, $entity = NULL) { /** * A wrapper around entity_load() to load a single entity by name or numeric id. * - * @todo: Re-name entity_load() to entity_load_multiple() in d8 core and this + * @todo Re-name entity_load() to entity_load_multiple() in d8 core and this * to entity_load(). * * @param $entity_type @@ -226,7 +230,7 @@ function entity_ui_get_page_title($op, $entity_type, $entity = NULL) { * type has specified a name key, both the numeric id and the name may be * passed. * - * @return + * @return object|false * The entity object, or FALSE. * * @see entity_load() @@ -249,7 +253,7 @@ function entity_load_single($entity_type, $id) { * fields must have. Instead, it is preferable to use EntityFieldQuery to * retrieve a list of entity IDs loadable by this function. * - * @return + * @return array * An array of entity objects indexed by their names (or ids if the entity * type has no name key). * @@ -274,7 +278,7 @@ function entity_load_multiple_by_name($entity_type, $names = FALSE, $conditions * @param $entity * The entity to save. * - * @return + * @return int|false * For entity types provided by the CRUD API, SAVED_NEW or SAVED_UPDATED is * returned depending on the operation performed. If there is no information * how to save the entity, FALSE is returned. @@ -324,6 +328,7 @@ function entity_delete($entity_type, $id) { * @param $ids * An array of entity ids of the entities to delete. In case the entity makes * use of a name key, both the names or numeric ids may be passed. + * * @return * FALSE if the given entity type isn't compatible to the CRUD API. */ @@ -350,7 +355,7 @@ function entity_delete_multiple($entity_type, $ids) { * @param $revision_id * The id of the revision to load. * - * @return + * @return object|false * The entity object, or FALSE if there is no entity with the given revision * id. */ @@ -371,7 +376,7 @@ function entity_revision_load($entity_type, $revision_id) { * @param $revision_id * The revision ID to delete. * - * @return + * @return bool * TRUE if the entity revision could be deleted, FALSE otherwise. */ function entity_revision_delete($entity_type, $revision_id) { @@ -396,7 +401,7 @@ function entity_revision_delete($entity_type, $revision_id) { * @param $entity * The entity object to check. * - * @return boolean + * @return bool * A boolean indicating whether the entity is in default revision is returned. * If the entity is not revisionable or is new, TRUE is returned. * @@ -453,7 +458,8 @@ function entity_revision_set_default($entity_type, $entity) { * @param $values * An array of values to set, keyed by property name. If the entity type has * bundles the bundle key has to be specified. - * @return + * + * @return object|false * A new instance of the entity type or FALSE if there is no information for * the given entity type. * @@ -482,7 +488,8 @@ function entity_create($entity_type, array $values) { * The entity to export. * @param $prefix * An optional prefix for each line. - * @return + * + * @return string * The exported entity as serialized string. The format is determined by the * respective entity controller, e.g. it is JSON for the EntityAPIController. * The output is suitable for entity_import(). @@ -508,7 +515,8 @@ function entity_export($entity_type, $entity, $prefix = '') { * @param string $export * The string containing the serialized entity as produced by * entity_export(). - * @return + * + * @return object * The imported entity object not yet saved. */ function entity_import($entity_type, $export) { @@ -524,7 +532,7 @@ function entity_import($entity_type, $export) { * @param $entity_type * The type of the entity. * - * @return + * @return bool * TRUE if the entity type is fieldable, FALSE otherwise. */ function entity_type_is_fieldable($entity_type) { @@ -550,7 +558,8 @@ function entity_type_is_fieldable($entity_type) { * @param $langcode * (optional) A language code to use for rendering. Defaults to the global * content language of the current request. - * @return + * + * @return array * The renderable array. */ function entity_build_content($entity_type, $entity, $view_mode = 'full', $langcode = NULL) { @@ -611,7 +620,8 @@ function entity_id($entity_type, $entity) { * of the entity, as returned by entity_uri(). * This parameter is only supported for entities which controller is a * EntityAPIControllerInterface. - * @return + * + * @return array * The renderable array, keyed by the entity type and by entity identifiers, * for which the entity name is used if existing - see entity_id(). If there * is no information on how to view an entity, FALSE is returned. @@ -650,7 +660,7 @@ function entity_view($entity_type, $entities, $view_mode = 'full', $langcode = N * @param $account * The user to check for. Leave it to NULL to check for the global user. * - * @return boolean + * @return bool * Whether access is allowed or not. If the entity type does not specify any * access information, NULL is returned. * @@ -675,7 +685,8 @@ function entity_access($op, $entity_type, $entity = NULL, $account = NULL) { * The type of the entity. * @param $entity * The entity to show the edit form for. - * @return + * + * @return array|false * The renderable array of the form. If there is no entity form or missing * metadata, FALSE is returned. * @@ -718,9 +729,9 @@ function entity_key_array_by_property(array $entities, $property) { /** * Get the entity info for the entity types provided via the entity CRUD API. * - * @return - * An array in the same format as entity_get_info(), containing the entities - * whose controller class implements the EntityAPIControllerInterface. + * @return array + * An array in the same format as entity_get_info(), containing the entities + * whose controller class implements the EntityAPIControllerInterface. */ function entity_crud_get_info() { $types = array(); @@ -743,7 +754,7 @@ function entity_crud_get_info() { * The constant status like ENTITY_CUSTOM, ENTITY_IN_CODE, ENTITY_OVERRIDDEN * or ENTITY_FIXED. * - * @return + * @return bool * TRUE if the entity has the status, FALSE otherwise. */ function entity_has_status($entity_type, $entity, $status) { @@ -1128,7 +1139,7 @@ function entity_theme() { ), 'entity_ui_overview_item' => array( 'variables' => array('label' => NULL, 'entity_type' => NULL, 'url' => FALSE, 'name' => FALSE), - 'file' => 'includes/entity.ui.inc' + 'file' => 'includes/entity.ui.inc', ), ); } @@ -1246,7 +1257,7 @@ function entity_forms($form_id, $args) { * (optional) A pre-populated form state, e.g. to add in form include files. * See entity_metadata_form_entity_ui(). * - * @return + * @return array * The fully built and processed form, ready to be rendered. * * @see EntityDefaultUIController::hook_forms() @@ -1283,18 +1294,17 @@ function entity_ui_get_form($entity_type, $entity, $op = 'edit', $form_state = a return drupal_build_form($form_id, $form_state); } - /** * Gets the page/menu title for local action operations. * * @param $op - * The current operation. One of 'add' or 'import'. + * The current operation. One of 'add' or 'import'. * @param $entity_type - * The entity type. + * The entity type. * @param $bundle_name - * (Optional) The name of the bundle. May be NULL if the bundle name is not - * relevant to the current page. If the entity type has only one bundle, or no - * bundles, this will be the same as the entity type. + * (Optional) The name of the bundle. May be NULL if the bundle name is not + * relevant to the current page. If the entity type has only one bundle, or no + * bundles, this will be the same as the entity type. */ function entity_ui_get_action_title($op, $entity_type, $bundle_name = NULL) { $info = entity_get_info($entity_type); @@ -1392,7 +1402,7 @@ function entity_get_extra_fields_controller($type = NULL) { * without any data for getting information about properties. * @param $info * (optional) Specify additional information for the passed data: - * - langcode: (optional) If the data is language specific, its langauge + * - langcode: (optional) If the data is language specific, its language * code. Defaults to NULL, what means language neutral. * - bundle: (optional) If an entity is wrapped but not passed, use this key * to specify the bundle to return a wrapper for. @@ -1403,8 +1413,9 @@ function entity_get_extra_fields_controller($type = NULL) { * info before it is utilized by the wrapper. * - property defaults: (optional) An array of defaults for the info of * each property of the wrapped data item. + * * @return EntityMetadataWrapper - * Dependend on the passed data the right wrapper is returned. + * Dependent on the passed data the right wrapper is returned. */ function entity_metadata_wrapper($type, $data = NULL, array $info = array()) { if ($type == 'entity' || (($entity_info = entity_get_info()) && isset($entity_info[$type]))) { diff --git a/profiles/dkan/modules/contrib/entity/entity.test b/profiles/dkan/modules/contrib/entity/entity.test index fd8cea122ef..4d27683ab11 100644 --- a/profiles/dkan/modules/contrib/entity/entity.test +++ b/profiles/dkan/modules/contrib/entity/entity.test @@ -39,6 +39,7 @@ abstract class EntityWebTestCase extends DrupalWebTestCase { file_save($file); return $file; } + } /** @@ -54,14 +55,14 @@ class EntityAPITestCase extends EntityWebTestCase { ); } - function setUp() { + protected function setUp() { parent::setUp('entity', 'entity_test'); } /** * Tests CRUD. */ - function testCRUD() { + public function testCRUD() { module_enable(array('entity_feature')); $user1 = $this->drupalCreateUser(); @@ -98,7 +99,7 @@ class EntityAPITestCase extends EntityWebTestCase { /** * Tests CRUD for entities supporting revisions. */ - function testCRUDRevisisions() { + public function testCRUDRevisisions() { module_enable(array('entity_feature')); // Add text field to entity. @@ -205,7 +206,7 @@ class EntityAPITestCase extends EntityWebTestCase { /** * Tests CRUD API functions: entity_(create|delete|save) */ - function testCRUDAPIfunctions() { + public function testCRUDAPIfunctions() { module_enable(array('entity_feature')); $user1 = $this->drupalCreateUser(); @@ -246,7 +247,7 @@ class EntityAPITestCase extends EntityWebTestCase { /** * Test loading entities defined in code. */ - function testExportables() { + public function testExportables() { module_enable(array('entity_feature')); $types = entity_load_multiple_by_name('entity_test_type', array('test2', 'test')); @@ -325,7 +326,7 @@ class EntityAPITestCase extends EntityWebTestCase { /** * Make sure insert() and update() hooks for exportables are invoked. */ - function testExportableHooks() { + public function testExportableHooks() { $_SESSION['entity_hook_test'] = array(); // Enabling the module should invoke the enabled hook for the other // entities provided in code. @@ -382,12 +383,12 @@ class EntityAPITestCase extends EntityWebTestCase { /** * Tests determining changes. */ - function testChanges() { + public function testChanges() { module_enable(array('entity_feature')); $types = entity_load_multiple_by_name('entity_test_type'); // Override the default entity, such it gets saved in the DB. - $types['test']->label ='test_changes'; + $types['test']->label = 'test_changes'; $types['test']->save(); // Now test an update without applying any changes. @@ -408,11 +409,10 @@ class EntityAPITestCase extends EntityWebTestCase { $this->assertEqual($types['test']->label, 'updated_presave', 'Static cache has been cleared.'); } - /** - * Tests viewing entites. + * Tests viewing entities. */ - function testRendering() { + public function testRendering() { module_enable(array('entity_feature')); $user1 = $this->drupalCreateUser(); @@ -428,7 +428,7 @@ class EntityAPITestCase extends EntityWebTestCase { /** * Test uninstall of the entity_test module. */ - function testUninstall() { + public function testUninstall() { // Add a test type and add a field instance, uninstall, then re-install and // make sure the field instance can be re-created. $test_type = entity_create('entity_test_type', array( @@ -482,6 +482,7 @@ class EntityAPITestCase extends EntityWebTestCase { $instance_read = field_info_instance('entity_test', 'field_test_fullname', 'test'); $this->assertTrue((bool) $instance_read, 'Field instance has been re-created.'); } + } /** @@ -498,7 +499,7 @@ class EntityAPIRulesIntegrationTestCase extends EntityWebTestCase { ); } - function setUp() { + protected function setUp() { parent::setUp('entity', 'entity_test', 'rules'); // Make sure the logger is enabled so the debug log is saved. variable_set('rules_debug_log', 1); @@ -507,7 +508,7 @@ class EntityAPIRulesIntegrationTestCase extends EntityWebTestCase { /** * Test the events. */ - function testEvents() { + public function testEvents() { $rule = rules_reaction_rule(); $rule->event('entity_test_presave'); $rule->event('entity_test_insert'); @@ -533,6 +534,7 @@ class EntityAPIRulesIntegrationTestCase extends EntityWebTestCase { $this->assertTrue($count == 5, 'Events have been properly invoked.'); RulesLog::logger()->checkLog(); } + } /** @@ -548,7 +550,7 @@ class EntityAPICommentNodeAccessTestCase extends CommentHelperCase { ); } - function setUp() { + public function setUp() { DrupalWebTestCase::setUp('comment', 'entity', 'node_access_test'); node_access_rebuild(); @@ -563,7 +565,7 @@ class EntityAPICommentNodeAccessTestCase extends CommentHelperCase { /** * Tests comment access when node access is enabled. */ - function testCommentNodeAccess() { + public function testCommentNodeAccess() { // Post comment. $this->drupalLogin($this->accessUser); $comment_text = $this->randomName(); @@ -584,6 +586,7 @@ class EntityAPICommentNodeAccessTestCase extends CommentHelperCase { $this->assertFalse(entity_access('update', 'comment', $comment_loaded, $this->noAccessUser), 'Access to update comment was denied for no access user'); $this->assertFalse(entity_access('delete', 'comment', $comment_loaded, $this->noAccessUser), 'Access to delete comment was denied for no access user'); } + } /** @@ -600,7 +603,7 @@ class EntityAPIi18nItegrationTestCase extends EntityWebTestCase { ); } - function setUp() { + protected function setUp() { parent::setUp('entity_test_i18n'); $this->admin_user = $this->drupalCreateUser(array('bypass node access', 'administer nodes', 'administer languages', 'administer content types', 'administer blocks', 'access administration pages')); $this->drupalLogin($this->admin_user); @@ -646,7 +649,7 @@ class EntityAPIi18nItegrationTestCase extends EntityWebTestCase { /** * Tests the provided default controller. */ - function testDefaultController() { + public function testDefaultController() { // Create test entities for the user1 and unrelated to a user. $entity = entity_create('entity_test_type', array( 'name' => 'test', @@ -686,6 +689,7 @@ class EntityAPIi18nItegrationTestCase extends EntityWebTestCase { $translation = entity_i18n_string("entity_test:entity_test_type:{$entity->name}:label", 'label-en', 'de'); $this->assertEqual($translation, 'label-en', 'Translation has been deleted.'); } + } /** @@ -701,7 +705,7 @@ class EntityMetadataTestCase extends EntityWebTestCase { ); } - function setUp() { + protected function setUp() { parent::setUp('entity', 'entity_test', 'locale'); // Create a field having 4 values for testing multiple value support. $this->field_name = drupal_strtolower($this->randomName() . '_field_name'); @@ -723,7 +727,7 @@ class EntityMetadataTestCase extends EntityWebTestCase { 'label' => 'Test Field', 'settings' => array( 'size' => 64, - ) + ), ) ); field_create_instance($this->instance); @@ -738,9 +742,9 @@ class EntityMetadataTestCase extends EntityWebTestCase { /** * Creates a user and a node, then tests getting the properties. */ - function testEntityMetadataWrapper() { + public function testEntityMetadataWrapper() { $account = $this->drupalCreateUser(); - // For testing sanitizing give the user a malicious user name + // For testing sanitizing give the user a malicious user name. $account = user_save($account, array('name' => 'BadName')); $title = 'Is it bold?'; $body[LANGUAGE_NONE][0] = array('value' => 'The body & nothing.', 'summary' => 'The body.'); @@ -807,7 +811,6 @@ class EntityMetadataTestCase extends EntityWebTestCase { $wrapper->author->set($GLOBALS['user']); $this->assertEqual($wrapper->author->uid->value(), $GLOBALS['user']->uid, 'Successfully set referenced entity using the entity.'); - // Test getting by the field API processed values like the node body. $body_value = $wrapper->body->value; $this->assertEqual("

The body & nothing.

\n", $body_value->value(), "Getting processed value."); @@ -888,7 +891,7 @@ class EntityMetadataTestCase extends EntityWebTestCase { /** * Test supporting multi-valued fields. */ - function testListMetadataWrappers() { + public function testListMetadataWrappers() { $property = $this->field_name; $values = array(); $values[LANGUAGE_NONE][0] = array('value' => '2009-09-05'); @@ -902,10 +905,10 @@ class EntityMetadataTestCase extends EntityWebTestCase { $this->assertEqual('2009-09-05', $wrapper->{$property}->get(1)->value(), 'Getting array entry.'); $this->assertEqual(3, count($wrapper->{$property}->value()), 'Getting the whole array.'); - // Test sanitizing + // Test sanitizing. $this->assertEqual(check_plain('2009-09-05'), $wrapper->{$property}[0]->value(array('sanitize' => TRUE)), 'Getting array entry.'); - // Test iterator + // Test iterator. $this->assertEqual(array_keys(iterator_to_array($wrapper->$property->getIterator())), array_keys($wrapper->$property->value()), 'Iterator is working.'); foreach ($wrapper->$property as $p) { $this->assertTrue($p instanceof EntityMetadataWrapper, 'Iterate over list wrapper properties.'); @@ -962,7 +965,7 @@ class EntityMetadataTestCase extends EntityWebTestCase { /** * Tests using the wrapper without any data. */ - function testWithoutData() { + public function testWithoutData() { $wrapper = entity_metadata_wrapper('node', NULL, array('bundle' => 'page')); $this->assertTrue(isset($wrapper->title), 'Bundle properties have been added.'); $info = $wrapper->author->mail->info(); @@ -972,7 +975,7 @@ class EntityMetadataTestCase extends EntityWebTestCase { /** * Test using access() method. */ - function testAccess() { + public function testAccess() { // Test without data. $account = $this->drupalCreateUser(array('bypass node access')); $this->assertTrue(entity_access('view', 'node', NULL, $account), 'Access without data checked.'); @@ -1032,7 +1035,7 @@ class EntityMetadataTestCase extends EntityWebTestCase { /** * Tests using a data structure with passed in metadata. */ - function testDataStructureWrapper() { + public function testDataStructureWrapper() { $log_entry = array( 'type' => 'entity', 'message' => $this->randomName(8), @@ -1053,8 +1056,8 @@ class EntityMetadataTestCase extends EntityWebTestCase { /** * Tests using entity_property_query(). */ - function testEntityQuery() { - // Creat a test node. + public function testEntityQuery() { + // Create a test node. $title = 'Is it bold?'; $values[LANGUAGE_NONE][0] = array('value' => 'foo'); $node = $this->drupalCreateNode(array($this->field_name => $values, 'title' => $title, 'uid' => $GLOBALS['user']->uid)); @@ -1069,12 +1072,12 @@ class EntityMetadataTestCase extends EntityWebTestCase { $this->assertEqual($results, array($node->nid), 'Queried nodes with a list of possible values.'); $results = entity_property_query('node', 'author', $GLOBALS['user']); - $this->assertEqual($results, array($node->nid), 'Queried nodes with a given auhtor.'); + $this->assertEqual($results, array($node->nid), 'Queried nodes with a given author.'); // Create another test node and try querying for tags. $tag = entity_property_values_create_entity('taxonomy_term', array( - 'name' => $this->randomName(), - 'vocabulary' => 1, + 'name' => $this->randomName(), + 'vocabulary' => 1, ))->save(); $field_tag_value[LANGUAGE_NONE][0]['tid'] = $tag->getIdentifier(); $node = $this->drupalCreateNode(array('type' => 'article', 'field_tags' => $field_tag_value)); @@ -1094,7 +1097,7 @@ class EntityMetadataTestCase extends EntityWebTestCase { /** * Tests serializing data wrappers, in particular for EntityDrupalWrapper. */ - function testWrapperSerialization() { + public function testWrapperSerialization() { $node = $this->drupalCreateNode(); $wrapper = entity_metadata_wrapper('node', $node); $this->assertTrue($wrapper->value() == $node, 'Data correctly wrapped.'); @@ -1115,6 +1118,7 @@ class EntityMetadataTestCase extends EntityWebTestCase { $value = unserialize($s)->value(); $this->assertNull($value, 'Tried to load not existing node.'); } + } /** @@ -1125,6 +1129,7 @@ class EntityMetadataTestCase extends EntityWebTestCase { * @see NodeAccessTestCase */ class EntityMetadataNodeAccessTestCase extends EntityWebTestCase { + public static function getInfo() { return array( 'name' => 'Entity Metadata Node Access', @@ -1136,7 +1141,7 @@ class EntityMetadataNodeAccessTestCase extends EntityWebTestCase { /** * Asserts node_access() correctly grants or denies access. */ - function assertNodeMetadataAccess($ops, $node, $account) { + protected function assertNodeMetadataAccess($ops, $node, $account) { foreach ($ops as $op => $result) { $msg = t("entity_access() returns @result with operation '@op'.", array('@result' => $result ? 'TRUE' : 'FALSE', '@op' => $op)); $access = entity_access($op, 'node', $node, $account); @@ -1144,7 +1149,7 @@ class EntityMetadataNodeAccessTestCase extends EntityWebTestCase { } } - function setUp() { + protected function setUp() { parent::setUp('entity', 'node'); // Clear permissions for authenticated users. db_delete('role_permission') @@ -1155,7 +1160,7 @@ class EntityMetadataNodeAccessTestCase extends EntityWebTestCase { /** * Runs basic tests for entity_access() function. */ - function testNodeMetadataAccess() { + public function testNodeMetadataAccess() { // Author user. $node_author_account = $this->drupalCreateUser(array()); // Make a node object. @@ -1194,12 +1199,14 @@ class EntityMetadataNodeAccessTestCase extends EntityWebTestCase { $node5 = $this->drupalCreateNode(); $this->assertNodeMetadataAccess(array('view' => TRUE, 'update' => FALSE, 'delete' => FALSE, 'create' => FALSE), $node5, $web_user3); } + } /** * Test user permissions for node creation. */ class EntityMetadataNodeCreateAccessTestCase extends EntityWebTestCase { + public static function getInfo() { return array( 'name' => 'Entity Metadata Node Create Access', @@ -1208,7 +1215,7 @@ class EntityMetadataNodeCreateAccessTestCase extends EntityWebTestCase { ); } - function setUp() { + protected function setUp() { parent::setUp('entity', 'node'); } @@ -1247,6 +1254,7 @@ class EntityMetadataNodeCreateAccessTestCase extends EntityWebTestCase { $this->assertTrue(entity_access('create', 'node', $node, $creator_account), 'Create access allowed for CREATOR, for entity_access().'); $this->assertFalse(entity_access('create', 'node', $node, $auth_only_account), 'Create access denied for USER, for entity_access().'); } + } /** @@ -1258,7 +1266,7 @@ class EntityMetadataNodeRevisionAccessTestCase extends DrupalWebTestCase { protected $node_revisions = array(); protected $accounts = array(); - // Map revision permission names to node revision access ops. + /** Map revision permission names to node revision access ops. */ protected $map = array( 'view' => 'view revisions', 'update' => 'revert revisions', @@ -1273,7 +1281,7 @@ class EntityMetadataNodeRevisionAccessTestCase extends DrupalWebTestCase { ); } - function setUp() { + protected function setUp() { parent::setUp('entity', 'node'); // Create a node with several revisions. @@ -1318,7 +1326,7 @@ class EntityMetadataNodeRevisionAccessTestCase extends DrupalWebTestCase { /** * Tests the entity_access() function for revisions. */ - function testNodeRevisionAccess() { + public function testNodeRevisionAccess() { // $node_revisions[1] won't be the latest revision. $revision = $this->node_revisions[1]; @@ -1340,12 +1348,14 @@ class EntityMetadataNodeRevisionAccessTestCase extends DrupalWebTestCase { } } } + } /** * Tests basic entity_access() functionality for taxonomy terms. */ class EntityMetadataTaxonomyAccessTestCase extends EntityWebTestCase { + public static function getInfo() { return array( 'name' => 'Entity Metadata Taxonomy Access', @@ -1357,7 +1367,7 @@ class EntityMetadataTaxonomyAccessTestCase extends EntityWebTestCase { /** * Asserts entity_access() correctly grants or denies access. */ - function assertTaxonomyMetadataAccess($ops, $term, $account) { + public function assertTaxonomyMetadataAccess($ops, $term, $account) { foreach ($ops as $op => $result) { $msg = t("entity_access() returns @result with operation '@op'.", array('@result' => $result ? 'TRUE' : 'FALSE', '@op' => $op)); $access = entity_access($op, 'taxonomy_term', $term, $account); @@ -1368,7 +1378,7 @@ class EntityMetadataTaxonomyAccessTestCase extends EntityWebTestCase { /** * @inheritdoc */ - function setUp() { + protected function setUp() { parent::setUp('entity', 'taxonomy'); // Clear permissions for authenticated users. db_delete('role_permission') @@ -1379,7 +1389,7 @@ class EntityMetadataTaxonomyAccessTestCase extends EntityWebTestCase { /** * Runs basic tests for entity_access() function. */ - function testTaxonomyMetadataAccess() { + public function testTaxonomyMetadataAccess() { $vocab = $this->createVocabulary(); $term = entity_property_values_create_entity('taxonomy_term', array( 'name' => $this->randomName(), @@ -1408,6 +1418,7 @@ class EntityMetadataTaxonomyAccessTestCase extends EntityWebTestCase { $user5 = $this->drupalCreateUser(array('administer taxonomy')); $this->assertTaxonomyMetadataAccess(array('create' => TRUE, 'view' => TRUE, 'update' => TRUE, 'delete' => TRUE), $term, $user5); } + } /** @@ -1423,14 +1434,14 @@ class EntityTokenTestCase extends EntityWebTestCase { ); } - function setUp() { + protected function setUp() { parent::setUp('entity_token'); } /** * Tests whether token support is basically working. */ - function testTokenSupport() { + public function testTokenSupport() { // Test basic tokens. $node = $this->drupalCreateNode(array('sticky' => TRUE, 'promote' => FALSE)); $text = "Sticky: [node:sticky] Promote: [node:promote] User: [site:current-user:name]"; @@ -1475,6 +1486,7 @@ class EntityTokenTestCase extends EntityWebTestCase { $replace = token_replace("[node:field-image:file:name]", array('node' => $node)); $this->assertEqual($replace, $wrapper->field_image->file->name->value(), 'Token replacements of an image field have been replaced.'); } + } /** @@ -1490,7 +1502,7 @@ class EntityMetadataIntegrationTestCase extends EntityWebTestCase { ); } - function setUp() { + protected function setUp() { parent::setUp('entity', 'book', 'statistics', 'locale'); } @@ -1520,7 +1532,7 @@ class EntityMetadataIntegrationTestCase extends EntityWebTestCase { $this->assertTrue($wrapper->$key->value() !== NULL, check_plain($key) . ' property returned.'); $info = $wrapper->$key->info(); if (!empty($info['raw getter callback'])) { - // Also test getting the raw value + // Also test getting the raw value. $this->assertTrue($wrapper->$key->raw() !== NULL, check_plain($key) . ' raw value returned.'); } } @@ -1528,7 +1540,7 @@ class EntityMetadataIntegrationTestCase extends EntityWebTestCase { /** * Test book module integration. */ - function testBookModule() { + public function testBookModule() { $title = 'Book 1'; $node = $this->drupalCreateNode(array('title' => $title, 'type' => 'book', 'book' => array('bid' => 'new'))); $book = array('bid' => $node->nid, 'plid' => $node->book['mlid']); @@ -1555,11 +1567,11 @@ class EntityMetadataIntegrationTestCase extends EntityWebTestCase { /** * Test properties of a comment. */ - function testComments() { + public function testComments() { $title = 'Node 1'; $node = $this->drupalCreateNode(array('title' => $title, 'type' => 'page')); $author = $this->drupalCreateUser(array('access comments', 'post comments', 'edit own comments')); - $comment = (object)array( + $comment = (object) array( 'subject' => 'topic', 'nid' => $node->nid, 'uid' => $author->uid, @@ -1648,7 +1660,7 @@ class EntityMetadataIntegrationTestCase extends EntityWebTestCase { /** * Test all properties of a node. */ - function testNodeProperties() { + public function testNodeProperties() { $title = 'Book 1'; $node = $this->drupalCreateNode(array('title' => $title, 'type' => 'page')); $wrapper = entity_metadata_wrapper('node', $node); @@ -1685,7 +1697,7 @@ class EntityMetadataIntegrationTestCase extends EntityWebTestCase { /** * Tests properties provided by the taxonomy module. */ - function testTaxonomyProperties() { + public function testTaxonomyProperties() { $vocab = $this->createVocabulary(); $term_parent = entity_property_values_create_entity('taxonomy_term', array( 'name' => $this->randomName(), @@ -1759,7 +1771,7 @@ class EntityMetadataIntegrationTestCase extends EntityWebTestCase { 'widget' => array( 'type' => 'options_select', 'label' => 'Test term field', - ) + ), ); field_create_instance($field_instance); $term_field[LANGUAGE_NONE][0]['tid'] = $term->tid; @@ -1773,7 +1785,7 @@ class EntityMetadataIntegrationTestCase extends EntityWebTestCase { /** * Test all properties of a user. */ - function testUserProperties() { + public function testUserProperties() { $account = $this->drupalCreateUser(array('access user profiles', 'change own username')); $account->login = REQUEST_TIME; $account->access = REQUEST_TIME; @@ -1817,7 +1829,7 @@ class EntityMetadataIntegrationTestCase extends EntityWebTestCase { /** * Test properties provided by system module. */ - function testSystemProperties() { + public function testSystemProperties() { $wrapper = entity_metadata_site_wrapper(); foreach ($wrapper as $key => $value) { $this->assertValue($wrapper, $key); @@ -1839,7 +1851,7 @@ class EntityMetadataIntegrationTestCase extends EntityWebTestCase { /** * Runs some generic tests on each entity. */ - function testCRUDfunctions() { + public function testCRUDfunctions() { $info = entity_get_info(); foreach ($info as $entity_type => $entity_info) { // Test using access callback. @@ -1886,7 +1898,7 @@ class EntityMetadataIntegrationTestCase extends EntityWebTestCase { /** * Test making use of a text fields. */ - function testTextFields() { + public function testTextFields() { // Create a simple text field without text processing. $field = array( 'field_name' => 'field_text', @@ -1971,7 +1983,7 @@ class EntityMetadataIntegrationTestCase extends EntityWebTestCase { /** * Test making use of a file field. */ - function testFileFields() { + public function testFileFields() { $file = $this->createFile(); // Create a file field. @@ -2040,7 +2052,7 @@ class EntityMetadataIntegrationTestCase extends EntityWebTestCase { /** * Test making use of an image field. */ - function testImageFields() { + public function testImageFields() { $file = $this->createFile('image'); // Just use the image field on the article node. @@ -2103,16 +2115,22 @@ class EntityMetadataIntegrationTestCase extends EntityWebTestCase { case 'integer': case 'duration': return 1; + case 'date': return REQUEST_TIME; + case 'boolean': return TRUE; + case 'token': return drupal_strtolower($this->randomName(8)); + case 'text': return $this->randomName(32); + case 'text_formatted': return array('value' => $this->randomName(16)); + case 'list': return array(); @@ -2120,4 +2138,5 @@ class EntityMetadataIntegrationTestCase extends EntityWebTestCase { return $this->{$wrapper->type()}; } } + } diff --git a/profiles/dkan/modules/contrib/entity/entity_token.info b/profiles/dkan/modules/contrib/entity/entity_token.info index 68ae88b0160..f49020d3efc 100644 --- a/profiles/dkan/modules/contrib/entity/entity_token.info +++ b/profiles/dkan/modules/contrib/entity/entity_token.info @@ -1,11 +1,11 @@ name = Entity tokens description = Provides token replacements for all properties that have no tokens and are known to the entity API. core = 7.x -files[] = entity_token.tokens.inc -files[] = entity_token.module dependencies[] = entity -; Information added by drush on 2018-02-14 +files[] = entity_token.tokens.inc + +; Information added by drush on 2021-09-03 version = "7.x-1.9" project = "entity" -datestamp = "1518619994" \ No newline at end of file +datestamp = "1630704438" \ No newline at end of file diff --git a/profiles/dkan/modules/contrib/entity/entity_token.tokens.inc b/profiles/dkan/modules/contrib/entity/entity_token.tokens.inc index 66c03ba6e2e..cedcd485efb 100644 --- a/profiles/dkan/modules/contrib/entity/entity_token.tokens.inc +++ b/profiles/dkan/modules/contrib/entity/entity_token.tokens.inc @@ -8,7 +8,7 @@ /** * Defines the types of properties to be added as token. * - * @return + * @return array * An array mapping token types to the usual (entity) type names. */ function entity_token_types() { @@ -19,7 +19,7 @@ function entity_token_types() { /** * Defines a list of token types that need to be chained. * - * @return + * @return bool|array * If a (token) type is given, whether the given type needs to be chained. * Else a full list of token types to be chained as returned by * entity_token_token_types(). @@ -321,20 +321,25 @@ function _entity_token_get_token($wrapper, $options) { switch ($wrapper->type()) { case 'integer': return $wrapper->value(); + case 'decimal': return number_format($wrapper->value(), 2); + case 'date': return format_date($wrapper->value(), 'medium', '', NULL, $langcode); + case 'duration': return format_interval($wrapper->value(), 2, $langcode); + case 'boolean': return $wrapper->value() ? t('true') : t('false'); + case 'uri': case 'text': return $wrapper->value($options); } - // Care for outputing list values. + // Care for outputting list values. if ($wrapper instanceof EntityListWrapper) { $output = array(); foreach ($wrapper as $item) { diff --git a/profiles/dkan/modules/contrib/entity/includes/entity.controller.inc b/profiles/dkan/modules/contrib/entity/includes/entity.controller.inc index 5e86b529110..549d4e4e42e 100644 --- a/profiles/dkan/modules/contrib/entity/includes/entity.controller.inc +++ b/profiles/dkan/modules/contrib/entity/includes/entity.controller.inc @@ -35,7 +35,7 @@ interface EntityAPIControllerInterface extends DrupalEntityControllerInterface { * @param $entity * The entity to save. * - * @return + * @return int * SAVED_NEW or SAVED_UPDATED is returned depending on the operation * performed. */ @@ -46,7 +46,8 @@ interface EntityAPIControllerInterface extends DrupalEntityControllerInterface { * * @param array $values * An array of values to set, keyed by property name. - * @return + * + * @return object * A new instance of the entity type. */ public function create(array $values = array()); @@ -59,7 +60,7 @@ interface EntityAPIControllerInterface extends DrupalEntityControllerInterface { * @param $prefix * An optional prefix for each line. * - * @return + * @return string * The exported entity as serialized string. The format is determined by * the controller and has to be compatible with the format that is accepted * by the import() method. @@ -72,7 +73,7 @@ interface EntityAPIControllerInterface extends DrupalEntityControllerInterface { * @param string $export * An exported entity as serialized string. * - * @return + * @return object * An entity object not yet saved. */ public function import($export); @@ -90,7 +91,8 @@ interface EntityAPIControllerInterface extends DrupalEntityControllerInterface { * @param $langcode * (optional) A language code to use for rendering. Defaults to the global * content language of the current request. - * @return + * + * @return array * The renderable array. */ public function buildContent($entity, $view_mode = 'full', $langcode = NULL); @@ -114,10 +116,12 @@ interface EntityAPIControllerInterface extends DrupalEntityControllerInterface { * of the entity, as returned by entity_uri(). * This parameter is only supported for entities which controller is a * EntityAPIControllerInterface. - * @return + * + * @return array * The renderable array, keyed by entity name or numeric id. */ public function view($entities, $view_mode = 'full', $langcode = NULL, $page = NULL); + } /** @@ -133,7 +137,7 @@ interface EntityAPIControllerRevisionableInterface extends EntityAPIControllerIn * @param $revision_id * The ID of the revision to delete. * - * @return boolean + * @return bool * TRUE if the entity revision could be deleted, FALSE otherwise. */ public function deleteRevision($revision_id); @@ -151,6 +155,7 @@ class EntityAPIController extends DrupalDefaultEntityController implements Entit /** * Overridden. + * * @see DrupalDefaultEntityController#__construct() */ public function __construct($entityType) { @@ -179,7 +184,8 @@ class EntityAPIController extends DrupalDefaultEntityController implements Entit /** * Builds and executes the query for loading. * - * @return The results in a Traversable object. + * @return Traversable + * The results in a Traversable object. */ public function query($ids, $conditions, $revision_id = FALSE) { // Build the query. @@ -193,6 +199,7 @@ class EntityAPIController extends DrupalDefaultEntityController implements Entit /** * Overridden. + * * @see DrupalDefaultEntityController#load($ids, $conditions) * * In contrast to the parent implementation we factor out query execution, so @@ -501,8 +508,6 @@ class EntityAPIController extends DrupalDefaultEntityController implements Entit $entity->revision = &$entity->is_new_revision; $entity->{$this->defaultRevisionKey} = !empty($entity->{$this->defaultRevisionKey}) || $entity->is_new; - - // When saving a new revision, set any existing revision ID to NULL so as to // ensure that a new revision will actually be created. if ($entity->is_new_revision && isset($record[$this->revisionKey])) { @@ -515,7 +520,7 @@ class EntityAPIController extends DrupalDefaultEntityController implements Entit } else { drupal_write_record($this->revisionTable, $record, $this->revisionKey); - // @todo: Fix original entity to be of the same revision and check whether + // @todo Fix original entity to be of the same revision and check whether // the default revision key has been set. $update_default_revision = $entity->{$this->defaultRevisionKey} && $entity->{$this->revisionKey} != $entity->original->{$this->revisionKey}; } @@ -547,7 +552,7 @@ class EntityAPIController extends DrupalDefaultEntityController implements Entit /** * Implements EntityAPIControllerInterface. * - * @return + * @return string * A serialized string in JSON format suitable for the import() method. */ public function export($entity, $prefix = '') { @@ -574,7 +579,7 @@ class EntityAPIController extends DrupalDefaultEntityController implements Entit * Implements EntityAPIControllerInterface. * * @param $content - * Optionally. Allows pre-populating the built content to ease overridding + * Optionally. Allows pre-populating the built content to ease overriding * this method. */ public function buildContent($entity, $view_mode = 'full', $langcode = NULL, $content = array()) { @@ -679,6 +684,7 @@ class EntityAPIController extends DrupalDefaultEntityController implements Entit } return $view; } + } /** @@ -766,6 +772,7 @@ class EntityAPIControllerExportable extends EntityAPIController { /** * Overridden. + * * @see DrupalDefaultEntityController::cacheGet() */ protected function cacheGet($ids, $conditions = array()) { @@ -795,7 +802,7 @@ class EntityAPIControllerExportable extends EntityAPIController { foreach ($entities as $key => $entity) { $entity_values = (array) $entity; // We cannot use array_diff_assoc() here because condition values can - // also be arrays, e.g. '$conditions = array('status' => array(1, 2))' + // also be arrays, e.g. '$conditions = array('status' => array(1, 2))'. foreach ($conditions as $condition_key => $condition_value) { if (is_array($condition_value)) { if (!isset($entity_values[$condition_key]) || !in_array($entity_values[$condition_key], $condition_value)) { @@ -813,6 +820,7 @@ class EntityAPIControllerExportable extends EntityAPIController { /** * Overridden. + * * @see DrupalDefaultEntityController::cacheSet() */ protected function cacheSet($entities) { @@ -978,4 +986,5 @@ class EntityAPIControllerExportable extends EntityAPIController { } return $view; } + } diff --git a/profiles/dkan/modules/contrib/entity/includes/entity.inc b/profiles/dkan/modules/contrib/entity/includes/entity.inc index 2f504f36ad2..605646f1dd5 100644 --- a/profiles/dkan/modules/contrib/entity/includes/entity.inc +++ b/profiles/dkan/modules/contrib/entity/includes/entity.inc @@ -23,7 +23,7 @@ interface EntityInterface { /** * Returns the entity identifier, i.e. the entities name or numeric id. * - * @return + * @return string|int * The identifier of the entity. If the entity type makes use of a name key, * the name is returned, else the numeric id. * @@ -46,7 +46,7 @@ interface EntityInterface { /** * Returns the bundle of the entity. * - * @return + * @return string * The bundle of the entity. Defaults to the entity type if the entity type * does not make use of different bundles. */ @@ -148,7 +148,7 @@ interface EntityInterface { * be translated. If set to NULL, the default display language is being * used. * - * @return + * @return string * The raw, translated property value; or the raw, un-translated value if no * translation is available. * @@ -159,7 +159,8 @@ interface EntityInterface { /** * Checks whether the entity is the default revision. * - * @return Boolean + * @return bool + * TRUE if it is the default revision, FALSE otherwise. * * @see entity_revision_is_default() */ @@ -412,6 +413,7 @@ class Entity implements EntityInterface { public function __wakeup() { $this->setUp(); } + } /** diff --git a/profiles/dkan/modules/contrib/entity/includes/entity.property.inc b/profiles/dkan/modules/contrib/entity/includes/entity.property.inc index e8714e67fdd..91c64b51d95 100644 --- a/profiles/dkan/modules/contrib/entity/includes/entity.property.inc +++ b/profiles/dkan/modules/contrib/entity/includes/entity.property.inc @@ -46,7 +46,7 @@ function entity_get_property_info($entity_type = NULL) { /** * Returns the default information for an entity property. * - * @return + * @return array * An array of optional property information keys mapped to their defaults. * * @see hook_entity_property_info() @@ -68,7 +68,7 @@ function entity_property_info_defaults() { * @param $entity_type * (optiona) The entity type to return properties for. * - * @return + * @return array * An array of info about properties. If the type is omitted, all known * properties are returned. */ @@ -102,9 +102,9 @@ function entity_get_all_property_info($entity_type = NULL) { * @param $value * A single property value or an array of possible values to query for. * @param $limit - * Limit the numer of results. Defaults to 30. + * Limit the number of results. Defaults to 30. * - * @return + * @return array * An array of entity ids or NULL if there is no information how to query for * the given property. */ @@ -231,7 +231,7 @@ function entity_field_update_instance() { * of the PHP variable type of $data. Example: the string "15" is a valid * integer, but "15nodes" is not. * - * @return + * @return bool * Whether the data is valid for the given type. */ function entity_property_verify_data_type($data, $type) { @@ -264,26 +264,35 @@ function entity_property_verify_data_type($data, $type) { case 'site': case 'unknown': return TRUE; + case 'date': case 'duration': case 'integer': return is_numeric($data) && strpos($data, '.') === FALSE; + case 'decimal': return is_numeric($data); + case 'text': return is_scalar($data); + case 'token': return is_scalar($data) && preg_match('!^[a-z][a-z0-9_]*$!', $data); + case 'boolean': return is_scalar($data) && (is_bool($data) || $data == 0 || $data == 1); + case 'uri': return valid_url($data, TRUE); + case 'list': return (is_array($data) && array_values($data) == $data) || (is_object($data) && $data instanceof EntityMetadataArrayObject); + case 'entity': return is_object($data) && $data instanceof EntityDrupalWrapper; - default: + case 'struct': + default: return is_object($data) || is_array($data); } } @@ -301,7 +310,7 @@ function entity_property_verify_data_type($data, $type) { * assigned to the entity directly, without the use of the metadata-wrapper * property. * - * @return EntityDrupalWrapper + * @return EntityDrupalWrapper|false * An EntityDrupalWrapper wrapping the newly created entity or FALSE, if * there were no information how to create the entity. */ @@ -333,22 +342,21 @@ function entity_property_values_create_entity($entity_type, $values = array()) { } } } - // @todo: Once we require Drupal 7.7 or later, verify the entity has + // @todo Once we require Drupal 7.7 or later, verify the entity has // now a valid bundle and throw the EntityMalformedException if not. return $wrapper; } return FALSE; } - /** * Extracts the contained type for a list type string like list. * - * @return + * @return string|false * The contained type or FALSE, if the given type string is no list. */ function entity_property_list_extract_type($type) { - if (strpos($type, 'list<') === 0 && $type[strlen($type)-1] == '>') { + if (strpos($type, 'list<') === 0 && $type[strlen($type) - 1] == '>') { return substr($type, 5, -1); } return FALSE; @@ -360,11 +368,11 @@ function entity_property_list_extract_type($type) { * @param $type * The type to examine. * - * @return + * @return string * For list types, the innermost type. The type itself otherwise. */ function entity_property_extract_innermost_type($type) { - while (strpos($type, 'list<') === 0 && $type[strlen($type)-1] == '>') { + while (strpos($type, 'list<') === 0 && $type[strlen($type) - 1] == '>') { $type = substr($type, 5, -1); } return $type; @@ -584,7 +592,6 @@ function entity_property_field_item_image_info() { return $properties; } - /** * Previously, hook_entity_property_info() has been provided by the removed * entity metadata module. To provide backward compatibility for provided @@ -597,7 +604,7 @@ function entity_property_field_item_image_info() { * Do not make use of this function, instead use the new one. */ function entity_metadata_verbatim_get($data, array $options, $name) { - return entity_property_verbatim_get($data, $options, $name); + return entity_property_verbatim_get($data, $options, $name, NULL, array()); } /** diff --git a/profiles/dkan/modules/contrib/entity/includes/entity.ui.inc b/profiles/dkan/modules/contrib/entity/includes/entity.ui.inc index 24e3c2b99df..924ff137014 100644 --- a/profiles/dkan/modules/contrib/entity/includes/entity.ui.inc +++ b/profiles/dkan/modules/contrib/entity/includes/entity.ui.inc @@ -178,7 +178,8 @@ class EntityDefaultUIController { * @param $form_state * The overview form state which will be used for validating. */ - public function overviewFormValidate($form, &$form_state) {} + public function overviewFormValidate($form, &$form_state) { + } /** * Overview form submit callback. @@ -188,8 +189,8 @@ class EntityDefaultUIController { * @param $form_state * The overview form state which will be used for submitting. */ - public function overviewFormSubmit($form, &$form_state) {} - + public function overviewFormSubmit($form, &$form_state) { + } /** * Generates the render array for a overview table for arbitrary entities @@ -197,8 +198,8 @@ class EntityDefaultUIController { * * @param $conditions * An array of conditions as needed by entity_load(). - - * @return Array + * + * @return array * A renderable array. */ public function overviewTable($conditions = array()) { @@ -331,7 +332,6 @@ class EntityDefaultUIController { return $row; } - /** * Builds the operation form. * @@ -431,7 +431,7 @@ class EntityDefaultUIController { * @param $entity * The entity to manipulate. * - * @return + * @return string * The status message of what has been applied. */ public function applyOperation($op, $entity) { @@ -479,7 +479,7 @@ class EntityDefaultUIController { * entity_form_submit_build_entity() provided by core, which already invokes * the field API attacher for fieldable entities. * - * @return + * @return object * The updated entity. * * @see entity_ui_form_submit_build_entity() @@ -495,6 +495,7 @@ class EntityDefaultUIController { entity_form_submit_build_entity($this->entityType, $form_state[$this->entityType], $form, $form_state); return $form_state[$this->entityType]; } + } /** @@ -519,7 +520,7 @@ class EntityContentUIController extends EntityDefaultUIController { $defaults = array( 'file' => $this->entityInfo['admin ui']['file'], - 'file path' => isset($this->entityInfo['admin ui']['file path']) ? $this->entityInfo['admin ui']['file path'] : drupal_get_path('module', $this->entityInfo['module']), + 'file path' => isset($this->entityInfo['admin ui']['file path']) ? $this->entityInfo['admin ui']['file path'] : drupal_get_path('module', $this->entityInfo['module']), ); // Add view, edit and delete menu items for content entities. @@ -572,6 +573,7 @@ class EntityContentUIController extends EntityDefaultUIController { // The manage entity path is unset for the content entity UI. $form_state['redirect'] = ''; } + } /** @@ -617,6 +619,7 @@ class EntityBundleableUIController extends EntityContentUIController { return $items; } + } /** @@ -652,7 +655,7 @@ function entity_ui_main_form_defaults($form, &$form_state, $entity = NULL, $op = /** * Clones the entity object and makes sure it will get saved as new entity. * - * @return + * @return object * The cloned entity object. */ function entity_ui_clone_entity($entity_type, $entity) { @@ -730,7 +733,7 @@ function entity_ui_controller_form_submit($form, &$form_state) { * This is a helper function for entities making use of the entity UI * controller. * - * @return + * @return object * The updated entity. * * @see EntityDefaultUIController::hook_forms() @@ -764,4 +767,3 @@ function theme_entity_ui_overview_item($variables) { } return $output; } - diff --git a/profiles/dkan/modules/contrib/entity/includes/entity.wrapper.inc b/profiles/dkan/modules/contrib/entity/includes/entity.wrapper.inc index 860d2c3339d..e4f4c88ae1c 100644 --- a/profiles/dkan/modules/contrib/entity/includes/entity.wrapper.inc +++ b/profiles/dkan/modules/contrib/entity/includes/entity.wrapper.inc @@ -39,7 +39,7 @@ abstract class EntityMetadataWrapper { /** * Gets info about the wrapped data. * - * @return Array + * @return array * Keys set are all keys as specified for a property in hook_entity_info() * as well as possible the following keys: * - name: If this wraps a property, the name of the property. @@ -68,15 +68,15 @@ abstract class EntityMetadataWrapper { * - decode: If set to TRUE and some textual data is already sanitized, it * strips HTML tags and decodes HTML entities. Defaults to FALSE. * - * @return - * The value of the wrapped data. If the data property is not set, NULL - * is returned. + * @return mixed|null + * The value of the wrapped data. If the data property is not set, NULL + * is returned. * - * @throws EntityMetadataWrapperException - * In case there are no data values available to the wrapper, an exception - * is thrown. E.g. if the value for an entity property is to be retrieved - * and there is no entity available, the exception is thrown. However, if - * an entity is available but the property is not set, NULL is returned. + * @throws EntityMetadataWrapperException + * In case there are no data values available to the wrapper, an exception + * is thrown. E.g. if the value for an entity property is to be retrieved + * and there is no entity available, the exception is thrown. However, if + * an entity is available but the property is not set, NULL is returned. */ public function value(array $options = array()) { if (!$this->dataAvailable() && isset($this->info['parent'])) { @@ -107,7 +107,7 @@ abstract class EntityMetadataWrapper { /** * Returns whether data is available to work with. * - * @return + * @return bool * If we operate without any data FALSE, else TRUE. */ protected function dataAvailable() { @@ -187,7 +187,7 @@ abstract class EntityMetadataWrapper { * account. So their options would be included for 'view', but for 'edit' * not. * - * @return + * @return array|false * An array as used by hook_options_list() or FALSE. */ public function optionsList($op = 'edit') { @@ -225,7 +225,8 @@ abstract class EntityMetadataWrapper { * The operation being performed. One of 'view' or 'edit. * @param $account * The user to check for. Leave it to NULL to check for the global user. - * @return boolean + * + * @return bool * Whether access to entity property is allowed for the given operation. * However if we wrap no data, it returns whether access is allowed to the * property of all entities of this type. @@ -238,9 +239,9 @@ abstract class EntityMetadataWrapper { /** * Returns a string to use to identify this wrapper in error messages. * - * @return - * A string that identifies this wrapper and its chain of ancestors, of the - * form 'grandparentidentifier->parentidentifier->identifier'. + * @return string + * A string that identifies this wrapper and its chain of ancestors, of the + * form 'grandparentidentifier->parentidentifier->identifier'. */ public function debugIdentifierLocation() { $debug = $this->info['name']; @@ -258,6 +259,7 @@ abstract class EntityMetadataWrapper { unset($vars['cache']); return drupal_map_assoc(array_keys($vars)); } + } /** @@ -283,6 +285,7 @@ class EntityValueWrapper extends EntityMetadataWrapper { } return $data; } + } /** @@ -340,10 +343,12 @@ class EntityStructureWrapper extends EntityMetadataWrapper implements IteratorAg * @param $name * The name of the property. If not given, info about all properties will * be returned. + * + * @return array + * An array of info about the property. + * * @throws EntityMetadataWrapperException * If there is no such property. - * @return - * An array of info about the property. */ public function getPropertyInfo($name = NULL) { $this->spotInfo(); @@ -372,6 +377,7 @@ class EntityStructureWrapper extends EntityMetadataWrapper implements IteratorAg * * @param $langcode * The language code of the language to set. + * * @return EntityWrapper */ public function language($langcode = LANGUAGE_NONE) { @@ -385,7 +391,7 @@ class EntityStructureWrapper extends EntityMetadataWrapper implements IteratorAg /** * Gets the language used for retrieving properties. * - * @return String + * @return string|null * The language object of the language or NULL for the default language. * * @see EntityStructureWrapper::language() @@ -402,7 +408,7 @@ class EntityStructureWrapper extends EntityMetadataWrapper implements IteratorAg /** * Get the wrapper for a property. * - * @return + * @return EntityMetadataWrapper * An instance of EntityMetadataWrapper. */ public function get($name) { @@ -572,6 +578,7 @@ class EntityStructureWrapper extends EntityMetadataWrapper implements IteratorAg $this->propertyInfoAltered = FALSE; parent::clear(); } + } /** @@ -919,7 +926,8 @@ class EntityDrupalWrapper extends EntityStructureWrapper { * * @param $name * One of 'id', 'name', 'bundle' or 'revision'. - * @return + * + * @return string * The name of the key used by the entity. */ public function entityKey($name) { @@ -979,6 +987,7 @@ class EntityDrupalWrapper extends EntityStructureWrapper { $this->data = FALSE; } } + } /** @@ -1001,7 +1010,6 @@ class EntityListWrapper extends EntityMetadataWrapper implements IteratorAggrega */ protected $isEntityList; - public function __construct($type, $data = NULL, $info = array()) { parent::__construct($type, NULL, $info); @@ -1019,7 +1027,7 @@ class EntityListWrapper extends EntityMetadataWrapper implements IteratorAggrega /** * Get the wrapper for a single item. * - * @return + * @return EntityMetadataWrapper * An instance of EntityMetadataWrapper. */ public function get($delta) { @@ -1178,13 +1186,14 @@ class EntityListWrapper extends EntityMetadataWrapper implements IteratorAggrega } return isset($labels) ? implode(', ', $labels) : NULL; } + } /** * Provide a separate Exception so it can be caught separately. */ -class EntityMetadataWrapperException extends Exception { } - +class EntityMetadataWrapperException extends Exception { +} /** * Allows to easily iterate over existing child wrappers. @@ -1199,23 +1208,23 @@ class EntityMetadataWrapperIterator implements RecursiveIterator { $this->keys = $keys; } - function rewind() { + public function rewind() { $this->position = 0; } - function current() { + public function current() { return $this->wrapper->get($this->keys[$this->position]); } - function key() { + public function key() { return $this->keys[$this->position]; } - function next() { + public function next() { $this->position++; } - function valid() { + public function valid() { return isset($this->keys[$this->position]); } @@ -1226,6 +1235,7 @@ class EntityMetadataWrapperIterator implements RecursiveIterator { public function getChildren() { return $this->current()->getIterator(); } + } /** @@ -1270,4 +1280,5 @@ class EntityMetadataArrayObject implements ArrayAccess, Countable, IteratorAggre public function getIterator() { return new ArrayIterator($this->data); } + } diff --git a/profiles/dkan/modules/contrib/entity/modules/callbacks.inc b/profiles/dkan/modules/contrib/entity/modules/callbacks.inc index ee156ab3732..9d8f0950443 100644 --- a/profiles/dkan/modules/contrib/entity/modules/callbacks.inc +++ b/profiles/dkan/modules/contrib/entity/modules/callbacks.inc @@ -17,6 +17,7 @@ function entity_metadata_entity_get_properties($entity, array $options, $name, $ /** * Callback for getting book node properties. + * * @see entity_metadata_book_entity_info_alter() */ function entity_metadata_book_get_properties($node, array $options, $name, $entity_type) { @@ -40,6 +41,7 @@ function entity_metadata_book_get_properties($node, array $options, $name, $enti /** * Callback for getting comment properties. + * * @see entity_metadata_comment_entity_info_alter() */ function entity_metadata_comment_get_properties($comment, array $options, $name) { @@ -68,6 +70,7 @@ function entity_metadata_comment_get_properties($comment, array $options, $name) /** * Callback for setting comment properties. + * * @see entity_metadata_comment_entity_info_alter() */ function entity_metadata_comment_setter($comment, $name, $value) { @@ -83,6 +86,7 @@ function entity_metadata_comment_setter($comment, $name, $value) { /** * Callback for getting comment related node properties. + * * @see entity_metadata_comment_entity_info_alter() */ function entity_metadata_comment_get_node_properties($node, array $options, $name, $entity_type) { @@ -150,7 +154,7 @@ function entity_metadata_node_get_properties($node, array $options, $name, $enti } /** - * Callback for determing access for node revision related properties. + * Callback for determining access for node revision related properties. */ function entity_metadata_node_revision_access($op, $name, $entity = NULL, $account = NULL) { return $op == 'view' ? user_access('view revisions', $account) : user_access('administer nodes', $account); @@ -158,6 +162,7 @@ function entity_metadata_node_revision_access($op, $name, $entity = NULL, $accou /** * Callback for getting poll properties. + * * @see entity_metadata_poll_entity_info_alter() */ function entity_metadata_poll_node_get_properties($node, array $options, $name) { @@ -182,18 +187,19 @@ function entity_metadata_poll_node_get_properties($node, array $options, $name) } switch ($name) { case 'poll_winner_votes': - return $winner['chvotes']; + return $winner['chvotes']; case 'poll_winner': - return $winner['chtext']; + return $winner['chtext']; case 'poll_winner_percent': - return ($winner['chvotes'] / $total_votes) * 100; + return ($winner['chvotes'] / $total_votes) * 100; } } /** * Callback for getting statistics properties. + * * @see entity_metadata_statistics_entity_info_alter() */ function entity_metadata_statistics_node_get_properties($node, array $options, $name) { @@ -224,9 +230,10 @@ function entity_metadata_statistics_properties_access($op, $property, $entity = /** * Callback for getting site-wide properties. + * * @see entity_metadata_system_entity_info_alter() */ -function entity_metadata_system_get_properties($data = FALSE, array $options, $name) { +function entity_metadata_system_get_properties($data, array $options, $name) { switch ($name) { case 'name': return variable_get('site_name', 'Drupal'); @@ -254,9 +261,10 @@ function entity_metadata_system_get_properties($data = FALSE, array $options, $n /** * Callback for getting properties for the current page request. + * * @see entity_metadata_system_entity_info_alter() */ -function entity_metadata_system_get_page_properties($data = array(), array $options, $name) { +function entity_metadata_system_get_page_properties($data, array $options, $name) { switch ($name) { case 'url': return $GLOBALS['base_root'] . request_uri(); @@ -265,6 +273,7 @@ function entity_metadata_system_get_page_properties($data = array(), array $opti /** * Callback for getting file properties. + * * @see entity_metadata_system_entity_info_alter() */ function entity_metadata_system_get_file_properties($file, array $options, $name) { @@ -328,6 +337,7 @@ function entity_metadata_taxonomy_term_setter($term, $name, $value) { $vocabulary = is_numeric($value) ? taxonomy_vocabulary_load($value) : taxonomy_vocabulary_machine_name_load($value); $term->vocabulary_machine_name = $vocabulary->machine_name; return $term->vid = $vocabulary->vid; + case 'parent': return $term->parent = $value; } @@ -335,6 +345,7 @@ function entity_metadata_taxonomy_term_setter($term, $name, $value) { /** * Callback for getting vocabulary properties. + * * @see entity_metadata_taxonomy_entity_info_alter() */ function entity_metadata_taxonomy_vocabulary_get_properties($vocabulary, array $options, $name) { @@ -347,6 +358,7 @@ function entity_metadata_taxonomy_vocabulary_get_properties($vocabulary, array $ /** * Callback for getting user properties. + * * @see entity_metadata_user_entity_info_alter() */ function entity_metadata_user_get_properties($account, array $options, $name, $entity_type) { @@ -381,6 +393,7 @@ function entity_metadata_user_get_properties($account, array $options, $name, $e /** * Callback for setting user properties. + * * @see entity_metadata_user_entity_info_alter() */ function entity_metadata_user_set_properties($account, $name, $value) { @@ -546,7 +559,7 @@ function entity_metadata_field_verbatim_set($entity, $name, $items, $langcode, $ * (optional) Whether to fall back to the entity default language, if no * value is available for the given language code yet. * - * @return + * @return string * The language code to use. */ function entity_metadata_field_get_language($entity_type, $entity, $field, $langcode = LANGUAGE_NONE, $fallback = FALSE) { @@ -664,7 +677,7 @@ function entity_metadata_field_file_validate_item($items, $context) { * * @throws EntityMalformedException * - * @return boolean + * @return bool * TRUE if access is allowed, FALSE otherwise. */ function entity_metadata_no_hook_node_access($op, $node = NULL, $account = NULL) { @@ -736,9 +749,11 @@ function entity_metadata_user_properties_access($op, $property, $entity = NULL, } // Allow edit access for own user name if the permission is satisfied. return $is_own_account && user_access('change own username', $account); + case 'mail': // Allow access to own mail address. return $is_own_account; + case 'roles': // Allow view access for own roles. return ($op == 'view' && $is_own_account); @@ -808,11 +823,13 @@ function entity_metadata_taxonomy_access($op, $entity = NULL, $account = NULL, $ return TRUE; } break; + case "update": if ($entity_type == 'taxonomy_term') { return user_access("edit terms in $entity->vid", $account); } break; + case "create": if ($entity_type == 'taxonomy_term') { // Check for taxonomy_access_fix contrib module which adds additional @@ -822,19 +839,21 @@ function entity_metadata_taxonomy_access($op, $entity = NULL, $account = NULL, $ } } break; + case "delete": if ($entity_type == 'taxonomy_term') { return user_access("delete terms in $entity->vid", $account); } break; } + return FALSE; } /** * Access callback for file entities. */ -function entity_metadata_file_access($op, $file = NULL, $account = NULL, $entity_type) { +function entity_metadata_file_access($op, $file, $account, $entity_type) { // We can only check access for the current user, so return FALSE on other accounts. global $user; if ($op == 'view' && isset($file) && (!isset($account) || $user->uid == $account->uid)) { @@ -850,11 +869,10 @@ function entity_metadata_file_access($op, $file = NULL, $account = NULL, $entity return FALSE; } - /** * Callback to determine access for properties which are fields. */ -function entity_metadata_field_access_callback($op, $name, $entity = NULL, $account = NULL, $entity_type) { +function entity_metadata_field_access_callback($op, $name, $entity, $account, $entity_type) { $field = field_info_field($name); return field_access($op, $field, $entity_type, $entity, $account); } @@ -862,7 +880,7 @@ function entity_metadata_field_access_callback($op, $name, $entity = NULL, $acco /** * Callback to create entity objects. */ -function entity_metadata_create_object($values = array(), $entity_type) { +function entity_metadata_create_object($values, $entity_type) { $info = entity_get_info($entity_type); // Make sure at least the bundle and label properties are set. if (isset($info['entity keys']['bundle']) && $key = $info['entity keys']['bundle']) { @@ -968,7 +986,7 @@ function entity_metadata_view_comment($entities, $view_mode = 'full', $langcode /** * Callback to view an entity, for which just ENTITYTYPE_view() is available. */ -function entity_metadata_view_single($entities, $view_mode = 'full', $langcode = NULL, $entity_type) { +function entity_metadata_view_single($entities, $view_mode, $langcode, $entity_type) { $function = $entity_type . '_view'; $build = array(); foreach ($entities as $key => $entity) { diff --git a/profiles/dkan/modules/contrib/entity/modules/comment.info.inc b/profiles/dkan/modules/contrib/entity/modules/comment.info.inc index 663c09c36a3..be260e5ad70 100644 --- a/profiles/dkan/modules/contrib/entity/modules/comment.info.inc +++ b/profiles/dkan/modules/contrib/entity/modules/comment.info.inc @@ -125,6 +125,7 @@ function entity_metadata_comment_entity_property_info() { /** * Implements hook_entity_property_info_alter() on top of comment module. + * * @see entity_entity_property_info_alter() */ function entity_metadata_comment_entity_property_info_alter(&$info) { diff --git a/profiles/dkan/modules/contrib/entity/modules/field.info.inc b/profiles/dkan/modules/contrib/entity/modules/field.info.inc index aeea79a19e8..1831f20d011 100644 --- a/profiles/dkan/modules/contrib/entity/modules/field.info.inc +++ b/profiles/dkan/modules/contrib/entity/modules/field.info.inc @@ -27,7 +27,12 @@ function entity_metadata_field_entity_property_info() { if ($instance && empty($instance['deleted'])) { foreach ($field_type['property_callbacks'] as $callback) { - $callback($info, $entity_type, $field, $instance, $field_type); + if (function_exists($callback)) { + $callback($info, $entity_type, $field, $instance, $field_type); + } + else { + watchdog($entity_type, 'Missing property callback %callback.', array('%callback' => $callback), WATCHDOG_ERROR); + } } } } @@ -39,7 +44,8 @@ function entity_metadata_field_entity_property_info() { /** * Callback to add in property info defaults per field instance. - * @see entity_metadata_field_entity_property_info(). + * + * @see entity_metadata_field_entity_property_info() */ function entity_metadata_field_default_property_callback(&$info, $entity_type, $field, $instance, $field_type) { if (!empty($field_type['property_type'])) { @@ -76,8 +82,8 @@ function entity_metadata_field_default_property_callback(&$info, $entity_type, $ /** * Additional callback to adapt the property info for text fields. If a text * field is processed we make use of a separate data structure so that format - * filters are available too. For the text value the sanitized, thus processed - * value is returned by default. + * filters are available too. For the text value that is sanitized, this + * processed value is returned by default. * * @see entity_metadata_field_entity_property_info() * @see entity_field_info_alter() @@ -94,7 +100,7 @@ function entity_metadata_field_text_property_callback(&$info, $entity_type, $fie unset($property['query callback']); if (empty($instance['settings']['text_processing'])) { - $property['property info'] = entity_property_field_item_textsummary_info(); + $property['property info'] = entity_property_field_item_textsummary_info(); } else { // For formatted text we use the type name 'text_formatted'. @@ -113,7 +119,8 @@ function entity_metadata_field_text_property_callback(&$info, $entity_type, $fie /** * Additional callback to adapt the property info for term reference fields. - * @see entity_metadata_field_entity_property_info(). + * + * @see entity_metadata_field_entity_property_info() */ function entity_metadata_field_term_reference_callback(&$info, $entity_type, $field, $instance, $field_type) { $property = &$info[$entity_type]['bundles'][$instance['bundle']]['properties'][$field['field_name']]; @@ -130,7 +137,8 @@ function entity_metadata_field_term_reference_callback(&$info, $entity_type, $fi /** * Additional callback to adapt the property info for file fields. - * @see entity_metadata_field_entity_property_info(). + * + * @see entity_metadata_field_entity_property_info() */ function entity_metadata_field_file_callback(&$info, $entity_type, $field, $instance, $field_type) { $property = &$info[$entity_type]['bundles'][$instance['bundle']]['properties'][$field['field_name']]; @@ -157,7 +165,8 @@ function entity_metadata_field_file_callback(&$info, $entity_type, $field, $inst /** * Additional callback to adapt the property info for image fields. * This callback gets invoked after entity_metadata_field_file_callback(). - * @see entity_metadata_field_entity_property_info(). + * + * @see entity_metadata_field_entity_property_info() */ function entity_metadata_field_image_callback(&$info, $entity_type, $field, $instance, $field_type) { $property = &$info[$entity_type]['bundles'][$instance['bundle']]['properties'][$field['field_name']]; diff --git a/profiles/dkan/modules/contrib/entity/modules/node.info.inc b/profiles/dkan/modules/contrib/entity/modules/node.info.inc index f146a7e8b1c..78122b9ed5c 100644 --- a/profiles/dkan/modules/contrib/entity/modules/node.info.inc +++ b/profiles/dkan/modules/contrib/entity/modules/node.info.inc @@ -149,6 +149,7 @@ function entity_metadata_node_entity_property_info() { /** * Implements hook_entity_property_info_alter() on top of node module. + * * @see entity_metadata_entity_property_info_alter() */ function entity_metadata_node_entity_property_info_alter(&$info) { diff --git a/profiles/dkan/modules/contrib/entity/modules/user.info.inc b/profiles/dkan/modules/contrib/entity/modules/user.info.inc index 67a62b547d2..a399d83086b 100644 --- a/profiles/dkan/modules/contrib/entity/modules/user.info.inc +++ b/profiles/dkan/modules/contrib/entity/modules/user.info.inc @@ -107,4 +107,3 @@ function entity_metadata_user_entity_property_info() { ); return $info; } - diff --git a/profiles/dkan/modules/contrib/entity/tests/entity_feature.info b/profiles/dkan/modules/contrib/entity/tests/entity_feature.info index b770b7be826..eac1b060dc3 100644 --- a/profiles/dkan/modules/contrib/entity/tests/entity_feature.info +++ b/profiles/dkan/modules/contrib/entity/tests/entity_feature.info @@ -6,7 +6,7 @@ files[] = entity_feature.module dependencies[] = entity_test hidden = TRUE -; Information added by drush on 2018-02-14 +; Information added by drush on 2021-09-03 version = "7.x-1.9" project = "entity" -datestamp = "1518619994" \ No newline at end of file +datestamp = "1630704438" \ No newline at end of file diff --git a/profiles/dkan/modules/contrib/entity/tests/entity_feature.module b/profiles/dkan/modules/contrib/entity/tests/entity_feature.module index c2c9fbf04e1..9a82d3b642a 100644 --- a/profiles/dkan/modules/contrib/entity/tests/entity_feature.module +++ b/profiles/dkan/modules/contrib/entity/tests/entity_feature.module @@ -23,9 +23,9 @@ function entity_feature_default_entity_test_type() { 'weight' => 0, )); $types['test2'] = entity_create('entity_test_type', array( - 'name' => 'test2', - 'label' => 'label2', - 'weight' => 2, + 'name' => 'test2', + 'label' => 'label2', + 'weight' => 2, )); return $types; diff --git a/profiles/dkan/modules/contrib/entity/tests/entity_test.info b/profiles/dkan/modules/contrib/entity/tests/entity_test.info index 7f74e4be6c6..1de739830ad 100644 --- a/profiles/dkan/modules/contrib/entity/tests/entity_test.info +++ b/profiles/dkan/modules/contrib/entity/tests/entity_test.info @@ -7,7 +7,7 @@ files[] = entity_test.install dependencies[] = entity hidden = TRUE -; Information added by drush on 2018-02-14 +; Information added by drush on 2021-09-03 version = "7.x-1.9" project = "entity" -datestamp = "1518619994" \ No newline at end of file +datestamp = "1630704438" \ No newline at end of file diff --git a/profiles/dkan/modules/contrib/entity/tests/entity_test.install b/profiles/dkan/modules/contrib/entity/tests/entity_test.install index a9693230cc7..69bb30630c0 100644 --- a/profiles/dkan/modules/contrib/entity/tests/entity_test.install +++ b/profiles/dkan/modules/contrib/entity/tests/entity_test.install @@ -53,11 +53,11 @@ function entity_test_schema() { 'foreign keys' => array( 'uid' => array( 'table' => 'users', - 'columns' => array('uid' => 'uid') + 'columns' => array('uid' => 'uid'), ), 'name' => array( 'table' => 'entity_test_types', - 'columns' => array('name' => 'name') + 'columns' => array('name' => 'name'), ), ), 'primary key' => array('pid'), @@ -167,4 +167,3 @@ function entity_test_schema() { return $schema; } - diff --git a/profiles/dkan/modules/contrib/entity/tests/entity_test.module b/profiles/dkan/modules/contrib/entity/tests/entity_test.module index 727797ae74b..e8d92a6b60e 100644 --- a/profiles/dkan/modules/contrib/entity/tests/entity_test.module +++ b/profiles/dkan/modules/contrib/entity/tests/entity_test.module @@ -108,7 +108,8 @@ function entity_test_get_types($name = NULL) { * An array of conditions to match against the {entity} table. * @param $reset * A boolean indicating that the internal cache should be reset. - * @return + * + * @return array * An array of test entity objects, indexed by pid. */ function entity_test_load_multiple($pids = array(), $conditions = array(), $reset = FALSE) { @@ -125,7 +126,6 @@ function entity_test_delete_multiple(array $pids) { entity_get_controller('entity_test')->delete($pids); } - /** * Main class for test entities. */ @@ -140,7 +140,7 @@ class EntityClass extends Entity { */ public function buildContent($view_mode = 'full', $langcode = NULL) { $content['user'] = array( - '#markup' => "User: ". format_username(user_load($this->uid)), + '#markup' => "User: " . format_username(user_load($this->uid)), ); return entity_get_controller($this->entityType)->buildContent($this, $view_mode, $langcode, $content); } @@ -159,6 +159,7 @@ class EntityClass extends Entity { protected function defaultURI() { return array('path' => 'custom/' . $this->identifier()); } + } /** @@ -173,14 +174,9 @@ class EntityClassRevision extends EntityClass { } /** - * - * * Some hook implementations used by the tests. - * - * */ - /** * Implements hook_entity_insert(). */ diff --git a/profiles/dkan/modules/contrib/entity/tests/entity_test_i18n.info b/profiles/dkan/modules/contrib/entity/tests/entity_test_i18n.info index ba91a49ccc2..e5307444aff 100644 --- a/profiles/dkan/modules/contrib/entity/tests/entity_test_i18n.info +++ b/profiles/dkan/modules/contrib/entity/tests/entity_test_i18n.info @@ -5,7 +5,8 @@ dependencies[] = i18n_string package = Multilingual - Internationalization core = 7.x hidden = TRUE -; Information added by drush on 2018-02-14 + +; Information added by drush on 2021-09-03 version = "7.x-1.9" project = "entity" -datestamp = "1518619994" \ No newline at end of file +datestamp = "1630704438" \ No newline at end of file diff --git a/profiles/dkan/modules/contrib/entity/theme/entity.theme.css b/profiles/dkan/modules/contrib/entity/theme/entity.theme.css index a57318dfc95..1478489eee2 100644 --- a/profiles/dkan/modules/contrib/entity/theme/entity.theme.css +++ b/profiles/dkan/modules/contrib/entity/theme/entity.theme.css @@ -1,4 +1,3 @@ - .entity-property-label { font-weight: bold; } diff --git a/profiles/dkan/modules/contrib/entity/theme/entity.theme.inc b/profiles/dkan/modules/contrib/entity/theme/entity.theme.inc index fc0ba7c1816..e055907a34d 100644 --- a/profiles/dkan/modules/contrib/entity/theme/entity.theme.inc +++ b/profiles/dkan/modules/contrib/entity/theme/entity.theme.inc @@ -106,6 +106,7 @@ function entity_property_default_render_value_by_type(EntityMetadataWrapper $pro switch ($property->type()) { case 'boolean': return $property->value() ? t('yes') : t('no'); + default: return check_plain($property->value()); } @@ -201,8 +202,12 @@ function template_preprocess_entity(&$variables) { // Add RDF type and about URI. if (module_exists('rdf')) { - $variables['attributes_array']['about'] = empty($uri['path']) ? NULL: url($uri['path']); - $variables['attributes_array']['typeof'] = empty($entity->rdf_mapping['rdftype']) ? NULL : $entity->rdf_mapping['rdftype']; + if (!empty($uri['path'])) { + $variables['attributes_array']['about'] = url($uri['path']); + } + if (!empty($entity->rdf_mapping['rdftype'])) { + $variables['attributes_array']['typeof'] = $entity->rdf_mapping['rdftype']; + } } // Add suggestions. diff --git a/profiles/dkan/modules/contrib/entity/views/entity.views.inc b/profiles/dkan/modules/contrib/entity/views/entity.views.inc index a0179c0c0ca..5f7d0fa9a39 100644 --- a/profiles/dkan/modules/contrib/entity/views/entity.views.inc +++ b/profiles/dkan/modules/contrib/entity/views/entity.views.inc @@ -123,7 +123,7 @@ function entity_views_data() { * excluded. Defaults to TRUE, as they are available for all views tables for * the entity type anyways. * - * @return + * @return array * An array containing the data selection Views table definition for the * entity type. * @@ -372,7 +372,7 @@ class EntityDefaultViewsController { $table = $this->info['base table']; // Define the base group of this table. Fields that don't // have a group defined will go into this field by default. - $data[$table]['table']['group'] = drupal_ucfirst($this->info['label']); + $data[$table]['table']['group'] = drupal_ucfirst($this->info['label']); $data[$table]['table']['entity type'] = $this->type; // If the plural label isn't available, use the regular label. @@ -401,7 +401,7 @@ class EntityDefaultViewsController { // Define the base group of this table. Fields that don't // have a group defined will go into this field by default. - $data[$revision_table]['table']['group'] = drupal_ucfirst($this->info['label']) . ' ' . t('Revisions'); + $data[$revision_table]['table']['group'] = drupal_ucfirst($this->info['label']) . ' ' . t('Revisions'); $data[$revision_table]['table']['entity type'] = $this->type; // If the plural label isn't available, use the regular label. @@ -495,7 +495,7 @@ class EntityDefaultViewsController { 'help' => isset($property_info['description']) ? $property_info['description'] : NULL, ); - // Add in relationships to related entities. + // Add in relationships to related entities. if (($info = entity_get_info($type)) && !empty($info['base table'])) { // Prepare reversed relationship data. @@ -543,7 +543,7 @@ class EntityDefaultViewsController { 'real field' => $views_field_name, 'handler' => 'views_handler_field', 'click sortable' => TRUE, - ), + ), 'sort' => array( 'real field' => $views_field_name, 'handler' => 'views_handler_sort', @@ -557,7 +557,7 @@ class EntityDefaultViewsController { 'handler' => 'views_handler_argument_string', ), ); - break; + break; case 'decimal': case 'integer': @@ -567,7 +567,7 @@ class EntityDefaultViewsController { 'handler' => 'views_handler_field_numeric', 'click sortable' => TRUE, 'float' => ($type == 'decimal'), - ), + ), 'sort' => array( 'real field' => $views_field_name, 'handler' => 'views_handler_sort', @@ -581,7 +581,7 @@ class EntityDefaultViewsController { 'handler' => 'views_handler_argument_numeric', ), ); - break; + break; case 'date': $return += $description + array( @@ -589,7 +589,7 @@ class EntityDefaultViewsController { 'real field' => $views_field_name, 'handler' => 'views_handler_field_date', 'click sortable' => TRUE, - ), + ), 'sort' => array( 'real field' => $views_field_name, 'handler' => 'views_handler_sort_date', @@ -603,7 +603,7 @@ class EntityDefaultViewsController { 'handler' => 'views_handler_argument_date', ), ); - break; + break; case 'duration': $return += $description + array( @@ -611,7 +611,7 @@ class EntityDefaultViewsController { 'real field' => $views_field_name, 'handler' => 'entity_views_handler_field_duration', 'click sortable' => TRUE, - ), + ), 'sort' => array( 'real field' => $views_field_name, 'handler' => 'views_handler_sort', @@ -625,7 +625,7 @@ class EntityDefaultViewsController { 'handler' => 'views_handler_argument_numeric', ), ); - break; + break; case 'uri': $return += $description + array( @@ -633,7 +633,7 @@ class EntityDefaultViewsController { 'real field' => $views_field_name, 'handler' => 'views_handler_field_url', 'click sortable' => TRUE, - ), + ), 'sort' => array( 'real field' => $views_field_name, 'handler' => 'views_handler_sort', @@ -647,7 +647,7 @@ class EntityDefaultViewsController { 'handler' => 'views_handler_argument_string', ), ); - break; + break; case 'boolean': $return += $description + array( @@ -655,7 +655,7 @@ class EntityDefaultViewsController { 'real field' => $views_field_name, 'handler' => 'views_handler_field_boolean', 'click sortable' => TRUE, - ), + ), 'sort' => array( 'real field' => $views_field_name, 'handler' => 'views_handler_sort', @@ -669,7 +669,7 @@ class EntityDefaultViewsController { 'handler' => 'views_handler_argument_string', ), ); - break; + break; } // If there is an options list callback, add to the filter and field. @@ -678,7 +678,7 @@ class EntityDefaultViewsController { $return['filter']['options callback'] = array('EntityDefaultViewsController', 'optionsListCallback'); $return['filter']['options arguments'] = array($this->type, $property_name, 'view'); } - // @todo: This class_exists is needed until views 3.2. + // @todo This class_exists is needed until views 3.2. if (isset($return['field']) && !empty($property_info['options list']) && class_exists('views_handler_field_machine_name')) { $return['field']['handler'] = 'views_handler_field_machine_name'; $return['field']['options callback'] = array('EntityDefaultViewsController', 'optionsListCallback'); @@ -695,7 +695,7 @@ class EntityDefaultViewsController { * @param $left_type * The data type from which to join. */ - function getRelationshipHandlerClass($entity_type, $left_type) { + public function getRelationshipHandlerClass($entity_type, $left_type) { // Look for an entity type which is used as bundle for the given entity // type. If there is one, allow filtering the relation by bundle by using // our own handler. @@ -720,4 +720,5 @@ class EntityDefaultViewsController { } return $wrapper->optionsList($op); } + } diff --git a/profiles/dkan/modules/contrib/entity/views/entity_views_example_query.php b/profiles/dkan/modules/contrib/entity/views/entity_views_example_query.php index 7e98e2c267e..9123aa77028 100644 --- a/profiles/dkan/modules/contrib/entity/views/entity_views_example_query.php +++ b/profiles/dkan/modules/contrib/entity/views/entity_views_example_query.php @@ -33,7 +33,7 @@ abstract class entity_views_example_query extends views_plugin_query { * @param $order * The order to sort items in - either 'ASC' or 'DESC'. Defaults to 'ASC'. */ - public abstract function add_selector_orderby($selector, $order = 'ASC'); + abstract public function add_selector_orderby($selector, $order = 'ASC'); /** * Returns the according entity objects for the given query results. @@ -56,14 +56,14 @@ public abstract function add_selector_orderby($selector, $order = 'ASC'); * using a relationship. For example, if the node's field "author:name" is * used, the user entity would be returned instead of the node entity. * - * @return + * @return array * A numerically indexed array containing two items: the entity type of * entities returned by this method; and the array of entities, keyed by the * same indexes as the results. * * @see EntityFieldHandlerHelper::extract_property_multiple() */ - public abstract function get_result_entities($results, $relationship = NULL, $field = NULL); + abstract public function get_result_entities($results, $relationship = NULL, $field = NULL); /** * Returns the according metadata wrappers for the given query results. @@ -78,11 +78,11 @@ public abstract function get_result_entities($results, $relationship = NULL, $fi * @param $field * (optional) The field of which a wrapper should be returned. * - * @return + * @return array * A numerically indexed array containing two items: the data type of * the wrappers returned by this method; and the array of retrieved * EntityMetadataWrapper objects, keyed by the same indexes as the results. */ - public abstract function get_result_wrappers($results, $relationship = NULL, $field = NULL); + abstract public function get_result_wrappers($results, $relationship = NULL, $field = NULL); } diff --git a/profiles/dkan/modules/contrib/entity/views/handlers/entity_views_field_handler_helper.inc b/profiles/dkan/modules/contrib/entity/views/handlers/entity_views_field_handler_helper.inc index 6bb4fbff5cc..549f34cd803 100644 --- a/profiles/dkan/modules/contrib/entity/views/handlers/entity_views_field_handler_helper.inc +++ b/profiles/dkan/modules/contrib/entity/views/handlers/entity_views_field_handler_helper.inc @@ -108,7 +108,7 @@ class EntityFieldHandlerHelper { * @param $selector * The data selector. * - * @return + * @return string * The last component of the data selector. */ public static function get_selector_field_name($selector) { @@ -188,7 +188,7 @@ class EntityFieldHandlerHelper { * If TRUE, the complete selector for the field is returned, not just the * one for its parent. Defaults to FALSE. * - * @return + * @return string * An Entity API data selector for the given handler's relationship. */ public static function construct_property_selector($handler, $complete = FALSE) { @@ -239,7 +239,7 @@ class EntityFieldHandlerHelper { * An array with numeric indices, containing the type of the extracted * wrappers in the first element. The second element of the array contains * the extracted property value(s) for each wrapper, keyed to the same key - * that was used for the respecive wrapper in $wrappers. All extracted + * that was used for the respective wrapper in $wrappers. All extracted * properties are returned as metadata wrappers. */ public static function extract_property_multiple(array $wrappers, $selector) { @@ -399,7 +399,7 @@ class EntityFieldHandlerHelper { * The values for the current row retrieved from the Views query, as an * object. * - * @return + * @return string * The rendered value for the field. */ public static function render($handler, $values) { @@ -421,7 +421,7 @@ class EntityFieldHandlerHelper { * The values for the current row retrieved from the Views query, as an * object. * - * @return + * @return string * The rendered value for the given list. */ public static function render_list($handler, $list, $values) { @@ -479,7 +479,7 @@ class EntityFieldHandlerHelper { * The values for the current row retrieved from the Views query, as an * object. * - * @return + * @return string * The rendered value. */ public static function render_entity_link($handler, $value, $values) { @@ -509,7 +509,7 @@ class EntityFieldHandlerHelper { * The values for the current row retrieved from the Views query, as an * object. * - * @return + * @return string * The rendered value. */ public static function render_single_value($handler, $value, $values) { diff --git a/profiles/dkan/modules/contrib/entity/views/handlers/entity_views_handler_area_entity.inc b/profiles/dkan/modules/contrib/entity/views/handlers/entity_views_handler_area_entity.inc index 0c5b7143f79..c9c988ba131 100644 --- a/profiles/dkan/modules/contrib/entity/views/handlers/entity_views_handler_area_entity.inc +++ b/profiles/dkan/modules/contrib/entity/views/handlers/entity_views_handler_area_entity.inc @@ -1,10 +1,12 @@ 'node'); @@ -14,7 +16,7 @@ class entity_views_handler_area_entity extends views_handler_area { return $options; } - function options_form(&$form, &$form_state) { + public function options_form(&$form, &$form_state) { parent::options_form($form, $form_state); $entity_type_options = array(); @@ -128,7 +130,7 @@ class entity_views_handler_area_entity extends views_handler_area { * are available and gets their values. This will then be * used in one giant str_replace(). */ - function get_render_tokens() { + public function get_render_tokens() { $tokens = array(); if (!empty($this->view->build_info['substitutions'])) { $tokens = $this->view->build_info['substitutions']; @@ -147,4 +149,5 @@ class entity_views_handler_area_entity extends views_handler_area { return $tokens; } + } diff --git a/profiles/dkan/modules/contrib/entity/views/handlers/entity_views_handler_field_boolean.inc b/profiles/dkan/modules/contrib/entity/views/handlers/entity_views_handler_field_boolean.inc index 42943d9ad31..48139d2c91f 100644 --- a/profiles/dkan/modules/contrib/entity/views/handlers/entity_views_handler_field_boolean.inc +++ b/profiles/dkan/modules/contrib/entity/views/handlers/entity_views_handler_field_boolean.inc @@ -16,6 +16,7 @@ * selection. * * @see entity_views_field_definition() + * * @ingroup views_field_handlers */ class entity_views_handler_field_boolean extends views_handler_field_boolean { diff --git a/profiles/dkan/modules/contrib/entity/views/handlers/entity_views_handler_field_date.inc b/profiles/dkan/modules/contrib/entity/views/handlers/entity_views_handler_field_date.inc index 89401cd0940..4c5f102aeca 100644 --- a/profiles/dkan/modules/contrib/entity/views/handlers/entity_views_handler_field_date.inc +++ b/profiles/dkan/modules/contrib/entity/views/handlers/entity_views_handler_field_date.inc @@ -16,6 +16,7 @@ * selection. * * @see entity_views_field_definition() + * * @ingroup views_field_handlers */ class entity_views_handler_field_date extends views_handler_field_date { diff --git a/profiles/dkan/modules/contrib/entity/views/handlers/entity_views_handler_field_duration.inc b/profiles/dkan/modules/contrib/entity/views/handlers/entity_views_handler_field_duration.inc index 2850e6a7993..3ddda80f1a1 100644 --- a/profiles/dkan/modules/contrib/entity/views/handlers/entity_views_handler_field_duration.inc +++ b/profiles/dkan/modules/contrib/entity/views/handlers/entity_views_handler_field_duration.inc @@ -13,6 +13,7 @@ * selection. * * @see entity_views_field_definition() + * * @ingroup views_field_handlers */ class entity_views_handler_field_duration extends views_handler_field { diff --git a/profiles/dkan/modules/contrib/entity/views/handlers/entity_views_handler_field_entity.inc b/profiles/dkan/modules/contrib/entity/views/handlers/entity_views_handler_field_entity.inc index d9fe73b244a..a9976ba38a7 100644 --- a/profiles/dkan/modules/contrib/entity/views/handlers/entity_views_handler_field_entity.inc +++ b/profiles/dkan/modules/contrib/entity/views/handlers/entity_views_handler_field_entity.inc @@ -13,6 +13,7 @@ * selection. * * @see entity_views_field_definition() + * * @ingroup views_field_handlers */ class entity_views_handler_field_entity extends views_handler_field { diff --git a/profiles/dkan/modules/contrib/entity/views/handlers/entity_views_handler_field_field.inc b/profiles/dkan/modules/contrib/entity/views/handlers/entity_views_handler_field_field.inc index f3cd7da2681..c5ce789a4aa 100644 --- a/profiles/dkan/modules/contrib/entity/views/handlers/entity_views_handler_field_field.inc +++ b/profiles/dkan/modules/contrib/entity/views/handlers/entity_views_handler_field_field.inc @@ -16,6 +16,7 @@ * selection. * * @see entity_views_field_definition() + * * @ingroup views_field_handlers */ class entity_views_handler_field_field extends views_handler_field_field { @@ -59,7 +60,8 @@ class entity_views_handler_field_field extends views_handler_field_field { /** * Override so it doesn't do any harm (or, anything at all). */ - public function post_execute(&$values) { } + public function post_execute(&$values) { + } /** * Load the entities for all rows that are about to be displayed. @@ -97,9 +99,10 @@ class entity_views_handler_field_field extends views_handler_field_field { /** * Overridden to force displaying multiple values in a single row. */ - function multiple_options_form(&$form, &$form_state) { + public function multiple_options_form(&$form, &$form_state) { parent::multiple_options_form($form, $form_state); $form['group_rows']['#default_value'] = TRUE; $form['group_rows']['#disabled'] = TRUE; } + } diff --git a/profiles/dkan/modules/contrib/entity/views/handlers/entity_views_handler_field_numeric.inc b/profiles/dkan/modules/contrib/entity/views/handlers/entity_views_handler_field_numeric.inc index bf981491033..195066e2211 100644 --- a/profiles/dkan/modules/contrib/entity/views/handlers/entity_views_handler_field_numeric.inc +++ b/profiles/dkan/modules/contrib/entity/views/handlers/entity_views_handler_field_numeric.inc @@ -16,6 +16,7 @@ * selection. * * @see entity_views_field_definition() + * * @ingroup views_field_handlers */ class entity_views_handler_field_numeric extends views_handler_field_numeric { diff --git a/profiles/dkan/modules/contrib/entity/views/handlers/entity_views_handler_field_options.inc b/profiles/dkan/modules/contrib/entity/views/handlers/entity_views_handler_field_options.inc index 8792c8360f1..a5530e04032 100644 --- a/profiles/dkan/modules/contrib/entity/views/handlers/entity_views_handler_field_options.inc +++ b/profiles/dkan/modules/contrib/entity/views/handlers/entity_views_handler_field_options.inc @@ -13,6 +13,7 @@ * selection. * * @see entity_views_field_definition() + * * @ingroup views_field_handlers */ class entity_views_handler_field_options extends views_handler_field { diff --git a/profiles/dkan/modules/contrib/entity/views/handlers/entity_views_handler_field_text.inc b/profiles/dkan/modules/contrib/entity/views/handlers/entity_views_handler_field_text.inc index 425abf27e78..68566d50f40 100644 --- a/profiles/dkan/modules/contrib/entity/views/handlers/entity_views_handler_field_text.inc +++ b/profiles/dkan/modules/contrib/entity/views/handlers/entity_views_handler_field_text.inc @@ -16,6 +16,7 @@ * selection. * * @see entity_views_field_definition() + * * @ingroup views_field_handlers */ class entity_views_handler_field_text extends views_handler_field { diff --git a/profiles/dkan/modules/contrib/entity/views/handlers/entity_views_handler_field_uri.inc b/profiles/dkan/modules/contrib/entity/views/handlers/entity_views_handler_field_uri.inc index c01882af4f8..87fb2646f08 100644 --- a/profiles/dkan/modules/contrib/entity/views/handlers/entity_views_handler_field_uri.inc +++ b/profiles/dkan/modules/contrib/entity/views/handlers/entity_views_handler_field_uri.inc @@ -16,6 +16,7 @@ * selection. * * @see entity_views_field_definition() + * * @ingroup views_field_handlers */ class entity_views_handler_field_uri extends views_handler_field_url { diff --git a/profiles/dkan/modules/contrib/entity/views/handlers/entity_views_handler_relationship.inc b/profiles/dkan/modules/contrib/entity/views/handlers/entity_views_handler_relationship.inc index a15c056600c..0291a44c8be 100644 --- a/profiles/dkan/modules/contrib/entity/views/handlers/entity_views_handler_relationship.inc +++ b/profiles/dkan/modules/contrib/entity/views/handlers/entity_views_handler_relationship.inc @@ -13,6 +13,7 @@ * selection. * * @see entity_views_field_definition() + * * @ingroup views_field_handlers */ class entity_views_handler_relationship extends views_handler_relationship { diff --git a/profiles/dkan/modules/contrib/entity/views/handlers/entity_views_handler_relationship_by_bundle.inc b/profiles/dkan/modules/contrib/entity/views/handlers/entity_views_handler_relationship_by_bundle.inc index a4d09d3e170..b88162bd6aa 100644 --- a/profiles/dkan/modules/contrib/entity/views/handlers/entity_views_handler_relationship_by_bundle.inc +++ b/profiles/dkan/modules/contrib/entity/views/handlers/entity_views_handler_relationship_by_bundle.inc @@ -1,4 +1,5 @@ array()); @@ -27,7 +30,7 @@ class entity_views_handler_relationship_by_bundle extends views_handler_relation /** * Add an entity type option. */ - function options_form(&$form, &$form_state) { + public function options_form(&$form, &$form_state) { parent::options_form($form, $form_state); // Get the entity type and info from the table data for the base on the @@ -62,7 +65,7 @@ class entity_views_handler_relationship_by_bundle extends views_handler_relation /** * Make sure only checked bundle types are left. */ - function options_submit(&$form, &$form_state) { + public function options_submit(&$form, &$form_state) { $form_state['values']['options']['bundle_types'] = array_filter($form_state['values']['options']['bundle_types']); parent::options_submit($form, $form_state); } @@ -73,7 +76,7 @@ class entity_views_handler_relationship_by_bundle extends views_handler_relation * Mostly the same as the parent method, except we add an extra clause to * the join. */ - function query() { + public function query() { $table_data = views_fetch_data($this->definition['base']); $base_field = empty($this->definition['base field']) ? $table_data['table']['base']['field'] : $this->definition['base field']; $this->ensure_my_table(); @@ -114,4 +117,5 @@ class entity_views_handler_relationship_by_bundle extends views_handler_relation $alias = $def['table'] . '_' . $this->table; $this->alias = $this->query->add_relationship($alias, $join, $this->definition['base'], $this->relationship); } + } diff --git a/profiles/dkan/modules/contrib/entity/views/plugins/entity_views_plugin_row_entity_view.inc b/profiles/dkan/modules/contrib/entity/views/plugins/entity_views_plugin_row_entity_view.inc index 5e738a8ca10..1413be00159 100644 --- a/profiles/dkan/modules/contrib/entity/views/plugins/entity_views_plugin_row_entity_view.inc +++ b/profiles/dkan/modules/contrib/entity/views/plugins/entity_views_plugin_row_entity_view.inc @@ -82,7 +82,7 @@ class entity_views_plugin_row_entity_view extends views_plugin_row { /** * Overridden to return the entity object. */ - function get_value($values, $field = NULL) { + public function get_value($values, $field = NULL) { return isset($this->entities[$this->view->row_index]) ? $this->entities[$this->view->row_index] : FALSE; } @@ -95,4 +95,5 @@ class entity_views_plugin_row_entity_view extends views_plugin_row { return drupal_render($render); } } + } diff --git a/profiles/dkan/modules/dkan/dkan_data_dashboard/dkan_data_dashboard.info b/profiles/dkan/modules/dkan/dkan_data_dashboard/dkan_data_dashboard.info index 9f3d942865a..094245b1f44 100644 --- a/profiles/dkan/modules/dkan/dkan_data_dashboard/dkan_data_dashboard.info +++ b/profiles/dkan/modules/dkan/dkan_data_dashboard/dkan_data_dashboard.info @@ -30,4 +30,4 @@ features[variable][] = panelizer_node:data_dashboard_default features[views_view][] = data_dashboards features[views_view][] = front_page_dashboards_list features_exclude[dependencies][dkan_topics] = dkan_topics -version = 7.x-1.18.16 +version = 7.x-1.18.17 diff --git a/profiles/dkan/modules/dkan/dkan_data_story/dkan_data_story.info b/profiles/dkan/modules/dkan/dkan_data_story/dkan_data_story.info index c24da2c6ce5..621515ebc79 100644 --- a/profiles/dkan/modules/dkan/dkan_data_story/dkan_data_story.info +++ b/profiles/dkan/modules/dkan/dkan_data_story/dkan_data_story.info @@ -53,4 +53,4 @@ features_exclude[dependencies][image] = image features_exclude[dependencies][strongarm] = strongarm features_exclude[dependencies][taxonomy] = taxonomy no autodetect = 1 -version = 7.x-1.18.16 +version = 7.x-1.18.17 diff --git a/profiles/dkan/modules/dkan/dkan_dataset/dkan_dataset.info b/profiles/dkan/modules/dkan/dkan_dataset/dkan_dataset.info index 5ba6add4f2f..068d2426445 100644 --- a/profiles/dkan/modules/dkan/dkan_dataset/dkan_dataset.info +++ b/profiles/dkan/modules/dkan/dkan_dataset/dkan_dataset.info @@ -33,4 +33,4 @@ features[ctools][] = views:views_default:3.0 features[features_api][] = api:2 features[variable][] = pathauto_node_dataset_pattern features[variable][] = pathauto_node_resource_pattern -version = 7.x-1.18.16 +version = 7.x-1.18.17 diff --git a/profiles/dkan/modules/dkan/dkan_dataset/modules/dkan_dataset_content_types/dkan_dataset_content_types.info b/profiles/dkan/modules/dkan/dkan_dataset/modules/dkan_dataset_content_types/dkan_dataset_content_types.info index 66ab95887f1..78d8886f097 100644 --- a/profiles/dkan/modules/dkan/dkan_dataset/modules/dkan_dataset_content_types/dkan_dataset_content_types.info +++ b/profiles/dkan/modules/dkan/dkan_dataset/modules/dkan_dataset_content_types/dkan_dataset_content_types.info @@ -125,4 +125,4 @@ features_exclude[dependencies][og] = og features_exclude[dependencies][dkan_featured_topics] = dkan_featured_topics features_exclude[field_base][og_group_ref] = og_group_ref features_exclude[field_instance][node-dataset-og_group_ref] = node-dataset-og_group_ref -version = 7.x-1.18.16 +version = 7.x-1.18.17 diff --git a/profiles/dkan/modules/dkan/dkan_dataset/modules/dkan_dataset_groups/dkan_dataset_groups.info b/profiles/dkan/modules/dkan/dkan_dataset/modules/dkan_dataset_groups/dkan_dataset_groups.info index 12262017ba0..bc2df1f4501 100644 --- a/profiles/dkan/modules/dkan/dkan_dataset/modules/dkan_dataset_groups/dkan_dataset_groups.info +++ b/profiles/dkan/modules/dkan/dkan_dataset/modules/dkan_dataset_groups/dkan_dataset_groups.info @@ -74,4 +74,4 @@ features[views_view][] = front_page_group_grid features[views_view][] = front_page_group_list features[views_view][] = group_block features[views_view][] = groups_page -version = 7.x-1.18.16 +version = 7.x-1.18.17 diff --git a/profiles/dkan/modules/dkan/dkan_dataset/modules/dkan_dataset_groups/modules/dkan_dataset_groups_perms/dkan_dataset_groups_perms.info b/profiles/dkan/modules/dkan/dkan_dataset/modules/dkan_dataset_groups/modules/dkan_dataset_groups_perms/dkan_dataset_groups_perms.info index bceeb0e4748..3dcc7e2f08b 100644 --- a/profiles/dkan/modules/dkan/dkan_dataset/modules/dkan_dataset_groups/modules/dkan_dataset_groups_perms/dkan_dataset_groups_perms.info +++ b/profiles/dkan/modules/dkan/dkan_dataset/modules/dkan_dataset_groups/modules/dkan_dataset_groups_perms/dkan_dataset_groups_perms.info @@ -32,4 +32,4 @@ features[og_features_permission][] = node:group:update own dataset content features[og_features_permission][] = node:group:update own resource content features[og_features_permission][] = node:group:view any unpublished dataset content features[og_features_permission][] = node:group:view any unpublished resource content -version = 7.x-1.18.16 +version = 7.x-1.18.17 diff --git a/profiles/dkan/modules/dkan/dkan_dataset/modules/dkan_dataset_rest_api/dkan_dataset_rest_api.info b/profiles/dkan/modules/dkan/dkan_dataset/modules/dkan_dataset_rest_api/dkan_dataset_rest_api.info index 4124c44cff8..833b93c98aa 100644 --- a/profiles/dkan/modules/dkan/dkan_dataset/modules/dkan_dataset_rest_api/dkan_dataset_rest_api.info +++ b/profiles/dkan/modules/dkan/dkan_dataset/modules/dkan_dataset_rest_api/dkan_dataset_rest_api.info @@ -10,4 +10,4 @@ dependencies[] = services features[ctools][] = services:services:3 features[features_api][] = api:2 features[services_endpoint][] = dkan_dataset_api -version = 7.x-1.18.16 +version = 7.x-1.18.17 diff --git a/profiles/dkan/modules/dkan/dkan_dataset/modules/dkan_dataset_voting/dkan_dataset_voting.info b/profiles/dkan/modules/dkan/dkan_dataset/modules/dkan_dataset_voting/dkan_dataset_voting.info index 317833d97c7..3f19797ef8c 100644 --- a/profiles/dkan/modules/dkan/dkan_dataset/modules/dkan_dataset_voting/dkan_dataset_voting.info +++ b/profiles/dkan/modules/dkan/dkan_dataset/modules/dkan_dataset_voting/dkan_dataset_voting.info @@ -17,4 +17,4 @@ features[field_instance][] = comment-comment_node_dataset-field_rating features[field_instance][] = node-dataset-field_rating features[variable][] = ajax_comments_node_types features[variable][] = ajax_comments_notify -version = 7.x-1.18.16 +version = 7.x-1.18.17 diff --git a/profiles/dkan/modules/dkan/dkan_dataset/tests/dkan_dataset_test.info b/profiles/dkan/modules/dkan/dkan_dataset/tests/dkan_dataset_test.info index f2632aa97d5..8fbf63f4c07 100644 --- a/profiles/dkan/modules/dkan/dkan_dataset/tests/dkan_dataset_test.info +++ b/profiles/dkan/modules/dkan/dkan_dataset/tests/dkan_dataset_test.info @@ -4,4 +4,4 @@ core = 7.x dependencies[] = dkan_dataset dependencies[] = dkan_dataset_rest_api hidden = TRUE -version = 7.x-1.18.16 +version = 7.x-1.18.17 diff --git a/profiles/dkan/modules/dkan/dkan_datastore/dkan_datastore.info b/profiles/dkan/modules/dkan/dkan_datastore/dkan_datastore.info index 6f95b2ca8af..c79c9f49059 100644 --- a/profiles/dkan/modules/dkan/dkan_datastore/dkan_datastore.info +++ b/profiles/dkan/modules/dkan/dkan_datastore/dkan_datastore.info @@ -12,4 +12,4 @@ features[features_api][] = api:2 features[field_base][] = field_datastore_status features[field_instance][] = node-resource-field_datastore_status features[views_view][] = datasets -version = 7.x-1.18.16 +version = 7.x-1.18.17 diff --git a/profiles/dkan/modules/dkan/dkan_datastore/modules/dkan_datastore_api/dkan_datastore_api.info b/profiles/dkan/modules/dkan/dkan_datastore/modules/dkan_datastore_api/dkan_datastore_api.info index ee1c52d828f..553df9a6618 100644 --- a/profiles/dkan/modules/dkan/dkan_datastore/modules/dkan_datastore_api/dkan_datastore_api.info +++ b/profiles/dkan/modules/dkan/dkan_datastore/modules/dkan_datastore_api/dkan_datastore_api.info @@ -4,4 +4,4 @@ package = DKAN API core = 7.x dependencies[] = services dependencies[] = dkan_datastore -version = 7.x-1.18.16 +version = 7.x-1.18.17 diff --git a/profiles/dkan/modules/dkan/dkan_datastore/modules/dkan_datastore_fast_import/dkan_datastore_fast_import.info b/profiles/dkan/modules/dkan/dkan_datastore/modules/dkan_datastore_fast_import/dkan_datastore_fast_import.info index c5b43dd72fb..1078f1bd3ae 100644 --- a/profiles/dkan/modules/dkan/dkan_datastore/modules/dkan_datastore_fast_import/dkan_datastore_fast_import.info +++ b/profiles/dkan/modules/dkan/dkan_datastore/modules/dkan_datastore_fast_import/dkan_datastore_fast_import.info @@ -3,4 +3,4 @@ description = Enable fast import for resources core = 7.x package = DKAN dependencies[] = dkan_datastore -version = 7.x-1.18.16 +version = 7.x-1.18.17 diff --git a/profiles/dkan/modules/dkan/dkan_datastore/modules/dkan_datastore_simple_import/dkan_datastore_simple_import.info b/profiles/dkan/modules/dkan/dkan_datastore/modules/dkan_datastore_simple_import/dkan_datastore_simple_import.info index d3531c6c5ee..d45a08910d9 100644 --- a/profiles/dkan/modules/dkan/dkan_datastore/modules/dkan_datastore_simple_import/dkan_datastore_simple_import.info +++ b/profiles/dkan/modules/dkan/dkan_datastore/modules/dkan_datastore_simple_import/dkan_datastore_simple_import.info @@ -3,4 +3,4 @@ description = A datastore importer that uses MySQL insert statements, and a cust core = 7.x package = DKAN dependencies[] = dkan_datastore -version = 7.x-1.18.16 +version = 7.x-1.18.17 diff --git a/profiles/dkan/modules/dkan/dkan_environment/dkan_environment.info b/profiles/dkan/modules/dkan/dkan_environment/dkan_environment.info index f940a1dbd57..7119645b3dd 100755 --- a/profiles/dkan/modules/dkan/dkan_environment/dkan_environment.info +++ b/profiles/dkan/modules/dkan/dkan_environment/dkan_environment.info @@ -3,4 +3,4 @@ description = Basic environments management (Local, Development, Production, etc core = 7.x dependencies[] = environment dependencies[] = environment_indicator -version = 7.x-1.18.16 +version = 7.x-1.18.17 diff --git a/profiles/dkan/modules/dkan/dkan_fixtures/dkan_fixtures.info b/profiles/dkan/modules/dkan/dkan_fixtures/dkan_fixtures.info index 28cc3532996..a299644bca6 100644 --- a/profiles/dkan/modules/dkan/dkan_fixtures/dkan_fixtures.info +++ b/profiles/dkan/modules/dkan/dkan_fixtures/dkan_fixtures.info @@ -14,4 +14,4 @@ files[] = includes/page.inc files[] = includes/panelized_node.inc files[] = includes/resource.inc files[] = includes/visualization_entity.inc -version = 7.x-1.18.16 +version = 7.x-1.18.17 diff --git a/profiles/dkan/modules/dkan/dkan_harvest/dkan_harvest.info b/profiles/dkan/modules/dkan/dkan_harvest/dkan_harvest.info index ea1e414fa1c..337d131312d 100644 --- a/profiles/dkan/modules/dkan/dkan_harvest/dkan_harvest.info +++ b/profiles/dkan/modules/dkan/dkan_harvest/dkan_harvest.info @@ -73,4 +73,4 @@ files[] = includes/HarvestCache.php files[] = includes/HarvestMigrateSQLMap.php files[] = includes/HarvestMigrateSourceList.php files[] = includes/XmlHarvestMigration.php -version = 7.x-1.18.16 +version = 7.x-1.18.17 diff --git a/profiles/dkan/modules/dkan/dkan_harvest/modules/dkan_harvest_dashboard/dkan_harvest_dashboard.info b/profiles/dkan/modules/dkan/dkan_harvest/modules/dkan_harvest_dashboard/dkan_harvest_dashboard.info index ba8ccabbfb0..7e1ec5cd2fd 100644 --- a/profiles/dkan/modules/dkan/dkan_harvest/modules/dkan_harvest_dashboard/dkan_harvest_dashboard.info +++ b/profiles/dkan/modules/dkan/dkan_harvest/modules/dkan_harvest_dashboard/dkan_harvest_dashboard.info @@ -23,4 +23,4 @@ features[views_view][] = dkan_harvest_datasets files[] = views/handlers/views_handler_field_date_harvest_date.inc files[] = views/handlers/views_handler_field_numeric_harvest_count.inc files[] = views/handlers/views_handler_field_harvest_status.inc -version = 7.x-1.18.16 +version = 7.x-1.18.17 diff --git a/profiles/dkan/modules/dkan/dkan_harvest/modules/dkan_harvest_datajson/dkan_harvest_datajson.info b/profiles/dkan/modules/dkan/dkan_harvest/modules/dkan_harvest_datajson/dkan_harvest_datajson.info index fd62da90f31..2c6b3d246d7 100644 --- a/profiles/dkan/modules/dkan/dkan_harvest/modules/dkan_harvest_datajson/dkan_harvest_datajson.info +++ b/profiles/dkan/modules/dkan/dkan_harvest/modules/dkan_harvest_datajson/dkan_harvest_datajson.info @@ -5,4 +5,4 @@ core = 7.x dependencies[] = dkan_harvest files[] = dkan_harvest_datajson.migrate.inc -version = 7.x-1.18.16 +version = 7.x-1.18.17 diff --git a/profiles/dkan/modules/dkan/dkan_harvest/modules/dkan_harvest_test/dkan_harvest_test.info b/profiles/dkan/modules/dkan/dkan_harvest/modules/dkan_harvest_test/dkan_harvest_test.info index 413304a9ad2..68527df934e 100644 --- a/profiles/dkan/modules/dkan/dkan_harvest/modules/dkan_harvest_test/dkan_harvest_test.info +++ b/profiles/dkan/modules/dkan/dkan_harvest/modules/dkan_harvest_test/dkan_harvest_test.info @@ -3,4 +3,4 @@ description = Test module for dkan_harvest core = 7.x dependencies[] = 'dkan_harvest' -version = 7.x-1.18.16 +version = 7.x-1.18.17 diff --git a/profiles/dkan/modules/dkan/dkan_ipe/dkan_ipe.info b/profiles/dkan/modules/dkan/dkan_ipe/dkan_ipe.info index 83f72734ca2..ffa22f762a1 100644 --- a/profiles/dkan/modules/dkan/dkan_ipe/dkan_ipe.info +++ b/profiles/dkan/modules/dkan/dkan_ipe/dkan_ipe.info @@ -8,4 +8,4 @@ dependencies[] = panels dependencies[] = strongarm features[features_api][] = api:2 project path = profiles/dkan/modules/dkan -version = 7.x-1.18.16 +version = 7.x-1.18.17 diff --git a/profiles/dkan/modules/dkan/dkan_linkchecker/dkan_linkchecker.info b/profiles/dkan/modules/dkan/dkan_linkchecker/dkan_linkchecker.info index e0646cb0af6..3c039642812 100644 --- a/profiles/dkan/modules/dkan/dkan_linkchecker/dkan_linkchecker.info +++ b/profiles/dkan/modules/dkan/dkan_linkchecker/dkan_linkchecker.info @@ -22,4 +22,4 @@ features[variable][] = linkchecker_scan_node_resource features[views_view][] = dkan_linkchecker_reports features_exclude[dependencies][ctools] = ctools project path = profiles/dkan/modules/dkan -version = 7.x-1.18.16 +version = 7.x-1.18.17 diff --git a/profiles/dkan/modules/dkan/dkan_migrate_base/dkan_migrate_base.info b/profiles/dkan/modules/dkan/dkan_migrate_base/dkan_migrate_base.info index 04202738527..647a019592c 100644 --- a/profiles/dkan/modules/dkan/dkan_migrate_base/dkan_migrate_base.info +++ b/profiles/dkan/modules/dkan/dkan_migrate_base/dkan_migrate_base.info @@ -11,4 +11,4 @@ files[] = dkan_migrate_base_group.inc files[] = dkan_migrate_base_dataset.inc files[] = dkan_migrate_base_resource.inc files[] = dkan_migrate_base_data_json.inc -version = 7.x-1.18.16 +version = 7.x-1.18.17 diff --git a/profiles/dkan/modules/dkan/dkan_migrate_base/modules/dkan_migrate_base_example/dkan_migrate_base_example.info b/profiles/dkan/modules/dkan/dkan_migrate_base/modules/dkan_migrate_base_example/dkan_migrate_base_example.info index ec2bfd6c26c..da0963f7cb5 100644 --- a/profiles/dkan/modules/dkan/dkan_migrate_base/modules/dkan_migrate_base_example/dkan_migrate_base_example.info +++ b/profiles/dkan/modules/dkan/dkan_migrate_base/modules/dkan_migrate_base_example/dkan_migrate_base_example.info @@ -4,4 +4,4 @@ package = "DKAN" core = 7.x dependencies[] = dkan_migrate_base dependencies[] = open_data_federal_extras -version = 7.x-1.18.16 +version = 7.x-1.18.17 diff --git a/profiles/dkan/modules/dkan/dkan_periodic_updates/dkan_periodic_updates.info b/profiles/dkan/modules/dkan/dkan_periodic_updates/dkan_periodic_updates.info index b138b060daf..81b7a96fc12 100644 --- a/profiles/dkan/modules/dkan/dkan_periodic_updates/dkan_periodic_updates.info +++ b/profiles/dkan/modules/dkan/dkan_periodic_updates/dkan_periodic_updates.info @@ -4,4 +4,4 @@ core = 7.x package = DKAN dependencies[] = dkan_dataset dependencies[] = dkan_datastore -version = 7.x-1.18.16 +version = 7.x-1.18.17 diff --git a/profiles/dkan/modules/dkan/dkan_permissions/dkan_permissions.info b/profiles/dkan/modules/dkan/dkan_permissions/dkan_permissions.info index bd303e2574f..5f3a15e0dcc 100644 --- a/profiles/dkan/modules/dkan/dkan_permissions/dkan_permissions.info +++ b/profiles/dkan/modules/dkan/dkan_permissions/dkan_permissions.info @@ -11,4 +11,4 @@ features[roles_permissions][] = editor features[roles_permissions][] = site manager features_exclude[dependencies][features] = features project path = profiles/dkan/modules/dkan -version = 7.x-1.18.16 +version = 7.x-1.18.17 diff --git a/profiles/dkan/modules/dkan/dkan_plugins/dkan_plugins.info b/profiles/dkan/modules/dkan/dkan_plugins/dkan_plugins.info index 8f255b4d194..323dcc9b28e 100644 --- a/profiles/dkan/modules/dkan/dkan_plugins/dkan_plugins.info +++ b/profiles/dkan/modules/dkan/dkan_plugins/dkan_plugins.info @@ -6,4 +6,4 @@ dependencies[] = ctools dependencies[] = panels project path = profiles/dkan/modules/dkan scripts[] = js/colorPicker.behavior.js -version = 7.x-1.18.16 +version = 7.x-1.18.17 diff --git a/profiles/dkan/modules/dkan/dkan_sitewide/dkan_sitewide.info b/profiles/dkan/modules/dkan/dkan_sitewide/dkan_sitewide.info index 5f353e289e9..9938b2a0dc0 100644 --- a/profiles/dkan/modules/dkan/dkan_sitewide/dkan_sitewide.info +++ b/profiles/dkan/modules/dkan/dkan_sitewide/dkan_sitewide.info @@ -56,4 +56,4 @@ features[views_view][] = dkan_administration_files features[views_view][] = dkan_administration_nodes features[views_view][] = dkan_administration_users features[views_view][] = popular_tags -version = 7.x-1.18.16 +version = 7.x-1.18.17 diff --git a/profiles/dkan/modules/dkan/dkan_sitewide/modules/dkan_sitewide_context/dkan_sitewide_context.info b/profiles/dkan/modules/dkan/dkan_sitewide/modules/dkan_sitewide_context/dkan_sitewide_context.info index 280a019d83d..d78a1b203cc 100644 --- a/profiles/dkan/modules/dkan/dkan_sitewide/modules/dkan_sitewide_context/dkan_sitewide_context.info +++ b/profiles/dkan/modules/dkan/dkan_sitewide/modules/dkan_sitewide_context/dkan_sitewide_context.info @@ -19,4 +19,4 @@ features[context][] = sitewide features[ctools][] = context:context:3 features[ctools][] = strongarm:strongarm:1 features[features_api][] = api:2 -version = 7.x-1.18.16 +version = 7.x-1.18.17 diff --git a/profiles/dkan/modules/dkan/dkan_sitewide/modules/dkan_sitewide_demo_front/dkan_sitewide_demo_front.info b/profiles/dkan/modules/dkan/dkan_sitewide/modules/dkan_sitewide_demo_front/dkan_sitewide_demo_front.info index cde9fe2c79f..de59cb67ff7 100644 --- a/profiles/dkan/modules/dkan/dkan_sitewide/modules/dkan_sitewide_demo_front/dkan_sitewide_demo_front.info +++ b/profiles/dkan/modules/dkan/dkan_sitewide/modules/dkan_sitewide_demo_front/dkan_sitewide_demo_front.info @@ -9,4 +9,4 @@ features[ctools][] = context:context:3 features[ctools][] = page_manager:pages_default:1 features[features_api][] = api:2 fetures[context][] = front -version = 7.x-1.18.16 +version = 7.x-1.18.17 diff --git a/profiles/dkan/modules/dkan/dkan_sitewide/modules/dkan_sitewide_menu/dkan_sitewide_menu.info b/profiles/dkan/modules/dkan/dkan_sitewide/modules/dkan_sitewide_menu/dkan_sitewide_menu.info index 2fd0aa58339..1e34bcca10e 100644 --- a/profiles/dkan/modules/dkan/dkan_sitewide/modules/dkan_sitewide_menu/dkan_sitewide_menu.info +++ b/profiles/dkan/modules/dkan/dkan_sitewide/modules/dkan_sitewide_menu/dkan_sitewide_menu.info @@ -44,4 +44,4 @@ features[menu_links][] = menu-command-center-menu_site-information:admin/config/ features[menu_links][] = menu-command-center-menu_taxonomy:admin/structure/taxonomy features[menu_links][] = menu-command-center-menu_visualization:admin/structure/entity-type/visualization/ve_chart/add features[menu_links][] = menu-command-center-menu_visualizations:admin/structure/entity-type/visualization -version = 7.x-1.18.16 +version = 7.x-1.18.17 diff --git a/profiles/dkan/modules/dkan/dkan_sitewide/modules/dkan_sitewide_panelizer/dkan_sitewide_panelizer.info b/profiles/dkan/modules/dkan/dkan_sitewide/modules/dkan_sitewide_panelizer/dkan_sitewide_panelizer.info index 6057add8bb5..a362edf3f6b 100644 --- a/profiles/dkan/modules/dkan/dkan_sitewide/modules/dkan_sitewide_panelizer/dkan_sitewide_panelizer.info +++ b/profiles/dkan/modules/dkan/dkan_sitewide/modules/dkan_sitewide_panelizer/dkan_sitewide_panelizer.info @@ -17,4 +17,4 @@ features[variable][] = panelizer_node:page_allowed_layouts_default features[variable][] = panelizer_node:page_allowed_types features[variable][] = panelizer_node:page_allowed_types_default features[variable][] = panelizer_node:page_default -version = 7.x-1.18.16 +version = 7.x-1.18.17 diff --git a/profiles/dkan/modules/dkan/dkan_sitewide/modules/dkan_sitewide_panels/dkan_sitewide_panels.info b/profiles/dkan/modules/dkan/dkan_sitewide/modules/dkan_sitewide_panels/dkan_sitewide_panels.info index a3359be490d..d9e7b8378c0 100644 --- a/profiles/dkan/modules/dkan/dkan_sitewide/modules/dkan_sitewide_panels/dkan_sitewide_panels.info +++ b/profiles/dkan/modules/dkan/dkan_sitewide/modules/dkan_sitewide_panels/dkan_sitewide_panels.info @@ -48,4 +48,4 @@ features[views_view][] = dkan_datasets_filtered features[views_view][] = dkan_groups features[views_view][] = entity_reference_groups_list features[views_view][] = list_of_users_groups -version = 7.x-1.18.16 +version = 7.x-1.18.17 diff --git a/profiles/dkan/modules/dkan/dkan_sitewide/modules/dkan_sitewide_search_db/dkan_sitewide_search_db.info b/profiles/dkan/modules/dkan/dkan_sitewide/modules/dkan_sitewide_search_db/dkan_sitewide_search_db.info index b79bf7b3db7..a7bda00c9ce 100644 --- a/profiles/dkan/modules/dkan/dkan_sitewide/modules/dkan_sitewide_search_db/dkan_sitewide_search_db.info +++ b/profiles/dkan/modules/dkan/dkan_sitewide/modules/dkan_sitewide_search_db/dkan_sitewide_search_db.info @@ -18,4 +18,4 @@ features[features_api][] = api:2 features[search_api_server][] = datasets features[variable][] = facetapi_pretty_paths_searcher_search_api@datasets features[variable][] = facetapi_pretty_paths_searcher_search_api@datasets_options -version = 7.x-1.18.16 +version = 7.x-1.18.17 diff --git a/profiles/dkan/modules/dkan/dkan_sitewide/modules/dkan_sitewide_user/dkan_sitewide_user.info b/profiles/dkan/modules/dkan/dkan_sitewide/modules/dkan_sitewide_user/dkan_sitewide_user.info index e147c9287b0..99cfafef215 100644 --- a/profiles/dkan/modules/dkan/dkan_sitewide/modules/dkan_sitewide_user/dkan_sitewide_user.info +++ b/profiles/dkan/modules/dkan/dkan_sitewide/modules/dkan_sitewide_user/dkan_sitewide_user.info @@ -21,4 +21,4 @@ features[field_group][] = group_user_tabs|user|user|default features[field_instance][] = user-user-field_about features[views_view][] = user_profile_fields features[views_view][] = user_profile_search -version = 7.x-1.18.16 +version = 7.x-1.18.17 diff --git a/profiles/dkan/modules/dkan/dkan_sitewide/modules/facet_icons/facet_icons.info b/profiles/dkan/modules/dkan/dkan_sitewide/modules/facet_icons/facet_icons.info index db470a2a0cd..cbf4d6cd8c7 100644 --- a/profiles/dkan/modules/dkan/dkan_sitewide/modules/facet_icons/facet_icons.info +++ b/profiles/dkan/modules/dkan/dkan_sitewide/modules/facet_icons/facet_icons.info @@ -6,4 +6,4 @@ dependencies[] = facetapi dependencies[] = panels_style_collapsible files[] = widget_term_icons.inc files[] = widget_content_type_icons.inc -version = 7.x-1.18.16 +version = 7.x-1.18.17 diff --git a/profiles/dkan/modules/dkan/dkan_topics/dkan_topics.info b/profiles/dkan/modules/dkan/dkan_topics/dkan_topics.info index 2e631af44af..c2e742395a9 100755 --- a/profiles/dkan/modules/dkan/dkan_topics/dkan_topics.info +++ b/profiles/dkan/modules/dkan/dkan_topics/dkan_topics.info @@ -57,4 +57,4 @@ features_exclude[dependencies][dkan_dataset_groups] = dkan_dataset_groups features_exclude[dependencies][dkan_topics] = dkan_topics no autodetect = 1 project path = profiles/dkan/modules/dkan -version = 7.x-1.18.16 +version = 7.x-1.18.17 diff --git a/profiles/dkan/modules/dkan/dkan_topics/modules/dkan_default_topics/dkan_default_topics.info b/profiles/dkan/modules/dkan/dkan_topics/modules/dkan_default_topics/dkan_default_topics.info index 7f8a7dd95c7..a8ebb586b96 100755 --- a/profiles/dkan/modules/dkan/dkan_topics/modules/dkan_default_topics/dkan_default_topics.info +++ b/profiles/dkan/modules/dkan/dkan_topics/modules/dkan_default_topics/dkan_default_topics.info @@ -5,4 +5,4 @@ package = DKAN Features dependencies[] = dkan_topics dependencies[] = taxonomy_fixtures dependencies[] = taxonomy -version = 7.x-1.18.16 +version = 7.x-1.18.17 diff --git a/profiles/dkan/modules/dkan/dkan_workflow/dkan_workflow.info b/profiles/dkan/modules/dkan/dkan_workflow/dkan_workflow.info index c33cb2442b9..299f9b0eaab 100644 --- a/profiles/dkan/modules/dkan/dkan_workflow/dkan_workflow.info +++ b/profiles/dkan/modules/dkan/dkan_workflow/dkan_workflow.info @@ -33,4 +33,4 @@ features[workbench_moderation_transitions][] = needs_review:published features[workbench_moderation_transitions][] = published:needs_review features_exclude[dependencies][ctools] = ctools features_exclude[dependencies][dkan_dataset_content_types] = dkan_dataset_content_types -version = 7.x-1.18.16 +version = 7.x-1.18.17 diff --git a/profiles/dkan/modules/dkan/dkan_workflow/modules/dkan_workflow_permissions/dkan_workflow_permissions.info b/profiles/dkan/modules/dkan/dkan_workflow/modules/dkan_workflow_permissions/dkan_workflow_permissions.info index f8fe5098e80..0e1aff85ff0 100644 --- a/profiles/dkan/modules/dkan/dkan_workflow/modules/dkan_workflow_permissions/dkan_workflow_permissions.info +++ b/profiles/dkan/modules/dkan/dkan_workflow/modules/dkan_workflow_permissions/dkan_workflow_permissions.info @@ -9,4 +9,4 @@ features[roles_permissions][] = Workflow Contributor features[roles_permissions][] = Workflow Moderator features[roles_permissions][] = Workflow Supervisor project path = profiles/dkan/modules/dkan/dkan_workflow/modules -version = 7.x-1.18.16 +version = 7.x-1.18.17 diff --git a/profiles/dkan/modules/dkan/dkan_workflow/modules/views_dkan_workflow_tree/views_dkan_workflow_tree.info b/profiles/dkan/modules/dkan/dkan_workflow/modules/views_dkan_workflow_tree/views_dkan_workflow_tree.info index 5344bbf93bf..267e6780719 100644 --- a/profiles/dkan/modules/dkan/dkan_workflow/modules/views_dkan_workflow_tree/views_dkan_workflow_tree.info +++ b/profiles/dkan/modules/dkan/dkan_workflow/modules/views_dkan_workflow_tree/views_dkan_workflow_tree.info @@ -6,4 +6,4 @@ dependencies[] = views dependencies[] = workbench_moderation files[] = ViewsDkanWorkflowTreePluginStyle.inc stylesheets[all][] = views_dkan_workflow_tree.css -version = 7.x-1.18.16 +version = 7.x-1.18.17 diff --git a/profiles/dkan/modules/dkan/open_data_federal_extras/open_data_federal_extras.info b/profiles/dkan/modules/dkan/open_data_federal_extras/open_data_federal_extras.info index 110ae9f10e3..f1a459a0826 100644 --- a/profiles/dkan/modules/dkan/open_data_federal_extras/open_data_federal_extras.info +++ b/profiles/dkan/modules/dkan/open_data_federal_extras/open_data_federal_extras.info @@ -27,4 +27,4 @@ features[field_instance][] = node-dataset-field_odfe_data_quality features[field_instance][] = node-dataset-field_odfe_investment_uii features[field_instance][] = node-dataset-field_odfe_program_code features[field_instance][] = node-dataset-field_odfe_system_of_records -version = 7.x-1.18.16 +version = 7.x-1.18.17 diff --git a/profiles/dkan/modules/dkan/open_data_schema_map_dkan/open_data_schema_map_dkan.info b/profiles/dkan/modules/dkan/open_data_schema_map_dkan/open_data_schema_map_dkan.info index 9f8c6d6295a..6c9192d314f 100644 --- a/profiles/dkan/modules/dkan/open_data_schema_map_dkan/open_data_schema_map_dkan.info +++ b/profiles/dkan/modules/dkan/open_data_schema_map_dkan/open_data_schema_map_dkan.info @@ -21,4 +21,4 @@ features[open_data_schema_apis][] = data_json_1_1 features[open_data_schema_apis][] = dcat_ap_v1_1_dataset features[open_data_schema_apis][] = dcat_v1_1 features[open_data_schema_apis][] = dcat_v1_1_json -version = 7.x-1.18.16 +version = 7.x-1.18.17 diff --git a/scripts/run-tests.sh b/scripts/run-tests.sh index f5c4a144f9f..b18fd142abb 100755 --- a/scripts/run-tests.sh +++ b/scripts/run-tests.sh @@ -156,6 +156,23 @@ All arguments are long options. --verbose Output detailed assertion messages in addition to summary. + --fail-only When paired with --verbose, do not print the detailed messages + for passing tests. + + --cache (Experimental) Cache result of setUp per installation profile. + This will create one cache entry per profile and is generally safe + to use. + To clear all cache entries use --clean. + + --cache-modules + + (Experimental) Cache result of setUp per installation profile and + installed modules. This will create one copy of the database + tables per module-combination and therefore this option should not + be used when running all tests. This is most useful for local + development of individual test cases. This option implies --cache. + To clear all cache entries use --clean. + [,[, ...]] One or more tests to be run. By default, these are interpreted @@ -199,7 +216,10 @@ function simpletest_script_parse_args() { 'directory' => '', 'color' => FALSE, 'verbose' => FALSE, + 'cache' => FALSE, + 'cache-modules' => FALSE, 'test_names' => array(), + 'fail-only' => FALSE, // Used internally. 'test-id' => 0, 'execute-test' => '', @@ -380,6 +400,8 @@ function simpletest_script_execute_batch($test_id, $test_classes) { * Bootstrap Drupal and run a single test. */ function simpletest_script_run_one_test($test_id, $test_class) { + global $args; + try { // Bootstrap Drupal. drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL); @@ -387,6 +409,8 @@ function simpletest_script_run_one_test($test_id, $test_class) { simpletest_classloader_register(); $test = new $test_class($test_id); + $test->useSetupInstallationCache = !empty($args['cache']); + $test->useSetupModulesCache = !empty($args['cache-modules']); $test->run(); $info = $test->getInfo(); @@ -422,6 +446,13 @@ function simpletest_script_command($test_id, $test_class) { if ($args['color']) { $command .= ' --color'; } + if ($args['cache-modules']) { + $command .= ' --cache --cache-modules'; + } + elseif ($args['cache']) { + $command .= ' --cache'; + } + $command .= " --php " . escapeshellarg($php) . " --test-id $test_id --execute-test " . escapeshellarg($test_class); return $command; } @@ -677,7 +708,7 @@ function simpletest_script_reporter_display_results() { $results = db_query("SELECT * FROM {simpletest} WHERE test_id = :test_id ORDER BY test_class, message_id", array(':test_id' => $test_id)); $test_class = ''; foreach ($results as $result) { - if (isset($results_map[$result->status])) { + if (isset($results_map[$result->status]) && (!$args['fail-only'] || $result->status !== 'pass')) { if ($result->test_class != $test_class) { // Display test class every time results are for new test class. echo "\n\n---- $result->test_class ----\n\n\n"; diff --git a/sites/default/default.settings.php b/sites/default/default.settings.php index 3e88c383430..f8941f94c5b 100755 --- a/sites/default/default.settings.php +++ b/sites/default/default.settings.php @@ -744,4 +744,19 @@ * @see drupal_session_start() * @see https://www.php.net/manual/en/session.configuration.php#ini.session.cookie-samesite */ -#$conf['samesite_cookie_value'] = 'None'; +# $conf['samesite_cookie_value'] = 'None'; + +/** + * Add Permissions-Policy header to disable Google FLoC. + * + * By default, Drupal sends the 'Permissions-Policy: interest-cohort=()' header + * to disable Google's Federated Learning of Cohorts feature, introduced in + * Chrome 89. + * + * See https://en.wikipedia.org/wiki/Federated_Learning_of_Cohorts for more + * information about FLoC. + * + * If you don't wish to disable FLoC in Chrome, you can set this value + * to FALSE. + */ +# $conf['block_interest_cohort'] = TRUE; diff --git a/web.config b/web.config index 1d82aab6399..dcf948dbb9d 100644 --- a/web.config +++ b/web.config @@ -26,6 +26,18 @@ +