class LeafletMarker in Leaflet 8
Same name and namespace in other branches
- 2.1.x modules/leaflet_views/src/Plugin/views/row/LeafletMarker.php \Drupal\leaflet_views\Plugin\views\row\LeafletMarker
 - 2.0.x modules/leaflet_views/src/Plugin/views/row/LeafletMarker.php \Drupal\leaflet_views\Plugin\views\row\LeafletMarker
 
Plugin which formats a row as a leaflet marker.
Plugin annotation
@ViewsRow(
  id = "leaflet_marker",
  title = @Translation("Leaflet Marker"),
  help = @Translation("Display the row as a leaflet marker."),
  display_types = {"leaflet"},
  no_ui = TRUE
)
  Hierarchy
- class \Drupal\Component\Plugin\PluginBase implements DerivativeInspectionInterface, PluginInspectionInterface
- class \Drupal\Core\Plugin\PluginBase uses DependencySerializationTrait, MessengerTrait, StringTranslationTrait
- class \Drupal\views\Plugin\views\PluginBase implements DependentPluginInterface, ContainerFactoryPluginInterface, TrustedCallbackInterface, ViewsPluginInterface
- class \Drupal\views\Plugin\views\row\RowPluginBase
- class \Drupal\leaflet_views\Plugin\views\row\LeafletMarker implements ContainerFactoryPluginInterface uses EntityTranslationRenderTrait
 
 
 - class \Drupal\views\Plugin\views\row\RowPluginBase
 
 - class \Drupal\views\Plugin\views\PluginBase implements DependentPluginInterface, ContainerFactoryPluginInterface, TrustedCallbackInterface, ViewsPluginInterface
 
 - class \Drupal\Core\Plugin\PluginBase uses DependencySerializationTrait, MessengerTrait, StringTranslationTrait
 
Expanded class hierarchy of LeafletMarker
File
- modules/
leaflet_views/ src/ Plugin/ views/ row/ LeafletMarker.php, line 33  
Namespace
Drupal\leaflet_views\Plugin\views\rowView source
class LeafletMarker extends RowPluginBase implements ContainerFactoryPluginInterface {
  use EntityTranslationRenderTrait;
  /**
   * Overrides Drupal\views\Plugin\Plugin::$usesOptions.
   *
   * @var bool
   */
  protected $usesOptions = TRUE;
  /**
   * Does the row plugin support to add fields to it's output.
   *
   * @var bool
   */
  protected $usesFields = TRUE;
  /**
   * The main entity type id for the view base table.
   *
   * @var string
   */
  protected $entityTypeId;
  /**
   * Contains the entity type of this row plugin instance.
   *
   * @var \Drupal\Core\Entity\EntityTypeInterface
   */
  protected $entityType;
  /**
   * The Entity type manager service.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  public $entityManager;
  /**
   * The language manager.
   *
   * @var \Drupal\Core\Language\LanguageManagerInterface
   */
  protected $languageManager;
  /**
   * The Entity Field manager service property.
   *
   * @var \Drupal\Core\Entity\EntityFieldManagerInterface
   */
  protected $entityFieldManager;
  /**
   * The Entity Display Repository service property.
   *
   * @var \Drupal\Core\Entity\EntityDisplayRepositoryInterface
   */
  protected $entityDisplay;
  /**
   * The Renderer service property.
   *
   * @var \Drupal\Core\Render\RendererInterface
   */
  protected $renderer;
  /**
   * The View Data service property.
   *
   * @var \Drupal\views\ViewsData
   */
  protected $viewsData;
  /**
   * Leaflet service.
   *
   * @var \Drupal\Leaflet\LeafletService
   */
  protected $leafletService;
  /**
   * Field type plugin manager.
   *
   * @var \Drupal\Core\Field\FieldTypePluginManagerInterface
   */
  protected $fieldTypeManager;
  /**
   * Constructs a LeafletMap style instance.
   *
   * @param array $configuration
   *   A configuration array containing information about the plugin instance.
   * @param string $plugin_id
   *   The plugin_id for the formatter.
   * @param mixed $plugin_definition
   *   The plugin implementation definition.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_manager
   *   The entity manager.
   * @param LanguageManagerInterface $language_manager
   *   The language manager.
   * @param \Drupal\Core\Entity\EntityFieldManagerInterface $entity_field_manager
   *   The entity field manager.
   * @param \Drupal\Core\Entity\EntityDisplayRepositoryInterface $entity_display
   *   The entity display manager.
   * @param \Drupal\Core\Render\RendererInterface $renderer
   *   The renderer.
   * @param \Drupal\Views\ViewsData $view_data
   *   The view data.
   * @param \Drupal\Leaflet\LeafletService $leaflet_service
   *   The Leaflet service.
   * @param \Drupal\Core\Field\FieldTypePluginManagerInterface $field_type_manager
   *   The field type plugin manager service.
   */
  public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_manager, LanguageManagerInterface $language_manager, EntityFieldManagerInterface $entity_field_manager, EntityDisplayRepositoryInterface $entity_display, RendererInterface $renderer, ViewsData $view_data, LeafletService $leaflet_service, FieldTypePluginManagerInterface $field_type_manager) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);
    $this->entityManager = $entity_manager;
    $this->languageManager = $language_manager;
    $this->entityFieldManager = $entity_field_manager;
    $this->entityDisplay = $entity_display;
    $this->renderer = $renderer;
    $this->viewsData = $view_data;
    $this->leafletService = $leaflet_service;
    $this->fieldTypeManager = $field_type_manager;
  }
  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static($configuration, $plugin_id, $plugin_definition, $container
      ->get('entity_type.manager'), $container
      ->get('language_manager'), $container
      ->get('entity_field.manager'), $container
      ->get('entity_display.repository'), $container
      ->get('renderer'), $container
      ->get('views.views_data'), $container
      ->get('leaflet.service'), $container
      ->get('plugin.manager.field.field_type'));
  }
  /**
   * {@inheritdoc}
   */
  public function init(ViewExecutable $view, DisplayPluginBase $display, array &$options = NULL) {
    parent::init($view, $display, $options);
    // First base table should correspond to main entity type.
    $this->entityTypeId = $view
      ->getBaseEntityType()
      ->id();
    $this->entityType = $this->entityManager
      ->getDefinition($this->entityTypeId);
  }
  /**
   * {@inheritdoc}
   */
  public function buildOptionsForm(&$form, FormStateInterface $form_state) {
    parent::buildOptionsForm($form, $form_state);
    // Get a list of fields and a sublist of geo data fields in this view.
    // @TODO use $fields = $this->displayHandler->getFieldLabels();
    $fields = [];
    $fields_geo_data = [];
    /* @var \Drupal\views\Plugin\views\ViewsHandlerInterface $handler */
    foreach ($this->displayHandler
      ->getHandlers('field') as $field_id => $handler) {
      $label = $handler
        ->adminLabel() ?: $field_id;
      $fields[$field_id] = $label;
      if (is_a($handler, 'Drupal\\views\\Plugin\\views\\field\\EntityField')) {
        /* @var \Drupal\views\Plugin\views\field\EntityField $handler */
        $field_storage_definitions = $this->entityFieldManager
          ->getFieldStorageDefinitions($handler
          ->getEntityType());
        $field_storage_definition = $field_storage_definitions[$handler->definition['field_name']];
        $type = $field_storage_definition
          ->getType();
        $definition = $this->fieldTypeManager
          ->getDefinition($type);
        if (is_a($definition['class'], '\\Drupal\\geofield\\Plugin\\Field\\FieldType\\GeofieldItem', TRUE)) {
          $fields_geo_data[$field_id] = $label;
        }
      }
    }
    // Check whether we have a geo data field we can work with.
    if (!count($fields_geo_data)) {
      $form['error'] = [
        '#markup' => $this
          ->t('Please add at least one geofield to the view.'),
      ];
      return;
    }
    // Map preset.
    $form['data_source'] = [
      '#type' => 'select',
      '#title' => $this
        ->t('Data Source'),
      '#description' => $this
        ->t('Which field contains geodata?'),
      '#options' => $fields_geo_data,
      '#default_value' => $this->options['data_source'],
      '#required' => TRUE,
    ];
    // Name field.
    $form['name_field'] = [
      '#type' => 'select',
      '#title' => $this
        ->t('Title Field'),
      '#description' => $this
        ->t('Choose the field which will appear as a title on tooltips.'),
      '#options' => $fields,
      '#default_value' => $this->options['name_field'],
      '#empty_value' => '',
    ];
    $desc_options = $fields;
    // Add an option to render the entire entity using a view mode.
    if ($this->entityTypeId) {
      $desc_options += [
        '#rendered_entity' => '<' . $this
          ->t('Rendered @entity entity', [
          '@entity' => $this->entityTypeId,
        ]) . '>',
      ];
    }
    $form['description_field'] = [
      '#type' => 'select',
      '#title' => $this
        ->t('Description Field'),
      '#description' => $this
        ->t('Choose the field or rendering method which will appear as a description on tooltips or popups.'),
      '#options' => $desc_options,
      '#default_value' => $this->options['description_field'],
      '#empty_value' => '',
    ];
    if ($this->entityTypeId) {
      // Get the human readable labels for the entity view modes.
      $view_mode_options = [];
      foreach ($this->entityDisplay
        ->getViewModes($this->entityTypeId) as $key => $view_mode) {
        $view_mode_options[$key] = $view_mode['label'];
      }
      // The View Mode drop-down is visible conditional on "#rendered_entity"
      // being selected in the Description drop-down above.
      $form['view_mode'] = [
        '#type' => 'select',
        '#title' => $this
          ->t('View mode'),
        '#description' => $this
          ->t('View modes are ways of displaying entities.'),
        '#options' => $view_mode_options,
        '#default_value' => !empty($this->options['view_mode']) ? $this->options['view_mode'] : 'full',
        '#states' => [
          'visible' => [
            ':input[name="row_options[description_field]"]' => [
              'value' => '#rendered_entity',
            ],
          ],
        ],
      ];
    }
  }
  /**
   * {@inheritdoc}
   */
  public function render($row) {
    /* @var \Drupal\views\ResultRow $row */
    $geofield_value = $this->view
      ->getStyle()
      ->getFieldValue($row->index, $this->options['data_source']);
    if (empty($geofield_value)) {
      return FALSE;
    }
    // @TODO This assumes that the user has selected WKT as the geofield output
    // formatter in the views field settings, and fails otherwise. Very brittle.
    $result = $this->leafletService
      ->leafletProcessGeofield($geofield_value);
    // Convert the list of geo data points into a list of leaflet markers.
    return $this
      ->renderLeafletMarkers($result, $row);
  }
  /**
   * Converts the given list of geo data points into a list of leaflet markers.
   *
   * @param array $points
   *   A list of geofield points from
   *   {@link \Drupal::service('leaflet.service')->leafletProcessGeofield()}.
   * @param \Drupal\views\ResultRow $row
   *   The views result row.
   *
   * @return array
   *   List of leaflet markers.
   */
  protected function renderLeafletMarkers(array $points, ResultRow $row) {
    // Render the entity with the selected view mode.
    $popup_body = '';
    if ($this->options['description_field'] === '#rendered_entity' && is_object($row->_entity)) {
      $entity = $row->_entity;
      $build = $this
        ->getEntityManager()
        ->getViewBuilder($entity
        ->getEntityTypeId())
        ->view($entity, $this->options['view_mode']);
      $popup_body = $this->renderer
        ->renderPlain($build);
    }
    elseif ($this->options['description_field']) {
      $popup_body = $this->view
        ->getStyle()
        ->getField($row->index, $this->options['description_field']);
    }
    $label = $this->view
      ->getStyle()
      ->getField($row->index, $this->options['name_field']);
    foreach ($points as &$point) {
      $point['popup'] = $popup_body;
      $point['label'] = $label;
      // Allow sub-classes to adjust the marker.
      $this
        ->alterLeafletMarker($point, $row);
      // Allow modules to adjust the marker.
      \Drupal::moduleHandler()
        ->alter('leaflet_views_feature', $point, $row, $this);
    }
    return $points;
  }
  /**
   * Chance for sub-classes to adjust the leaflet marker array.
   *
   * For example, this can be used to add in icon configuration.
   *
   * @param array $point
   *   The Marker Point.
   * @param \Drupal\views\ResultRow $row
   *   The Result rows.
   */
  protected function alterLeafletMarker(array &$point, ResultRow $row) {
  }
  /**
   * {@inheritdoc}
   */
  public function getEntityTypeId() {
    return $this->entityType
      ->id();
  }
  /**
   * {@inheritdoc}
   */
  protected function getEntityManager() {
    return $this->entityManager;
  }
  /**
   * {@inheritdoc}
   */
  protected function getLanguageManager() {
    return $this->languageManager;
  }
  /**
   * {@inheritdoc}
   */
  protected function getView() {
    return $this->view;
  }
  /**
   * {@inheritdoc}
   */
  public function query() {
    parent::query();
    $this
      ->getEntityTranslationRenderer()
      ->query($this->view
      ->getQuery());
  }
  /**
   * {@inheritdoc}
   */
  public function preRender($result) {
    parent::preRender($result);
    if ($result) {
      $this
        ->getEntityTranslationRenderer()
        ->preRender($result);
    }
  }
  /**
   * {@inheritdoc}
   */
  public function validate() {
    $errors = parent::validate();
    // @todo raise validation error if we have no geofield.
    if (empty($this->options['data_source'])) {
      $errors[] = $this
        ->t('Row @row requires the data source to be configured.', [
        '@row' => $this->definition['title'],
      ]);
    }
    return $errors;
  }
  /**
   * {@inheritdoc}
   */
  protected function defineOptions() {
    $options = parent::defineOptions();
    $options['data_source'] = [
      'default' => '',
    ];
    $options['name_field'] = [
      'default' => '',
    ];
    $options['description_field'] = [
      'default' => '',
    ];
    $options['view_mode'] = [
      'default' => 'teaser',
    ];
    return $options;
  }
}Members
| 
            Name | 
                  Modifiers | Type | Description | Overrides | 
|---|---|---|---|---|
| 
            DependencySerializationTrait:: | 
                  protected | property | An array of entity type IDs keyed by the property name of their storages. | |
| 
            DependencySerializationTrait:: | 
                  protected | property | An array of service IDs keyed by property name used for serialization. | |
| 
            DependencySerializationTrait:: | 
                  public | function | 1 | |
| 
            DependencySerializationTrait:: | 
                  public | function | 2 | |
| 
            EntityTranslationRenderTrait:: | 
                  protected | property | The renderer to be used to render the entity row. | |
| 
            EntityTranslationRenderTrait:: | 
                  protected | function | Returns the entity repository. | 7 | 
| 
            EntityTranslationRenderTrait:: | 
                  public | function | Returns the entity translation matching the configured row language. | |
| 
            EntityTranslationRenderTrait:: | 
                  protected | function | Returns the current renderer. | |
| 
            EntityTranslationRenderTrait:: | 
                  protected | function | Returns the entity type manager. | 7 | 
| 
            LeafletMarker:: | 
                  protected | property | The Entity Display Repository service property. | |
| 
            LeafletMarker:: | 
                  protected | property | The Entity Field manager service property. | |
| 
            LeafletMarker:: | 
                  public | property | The Entity type manager service. | |
| 
            LeafletMarker:: | 
                  protected | property | Contains the entity type of this row plugin instance. | |
| 
            LeafletMarker:: | 
                  protected | property | The main entity type id for the view base table. | |
| 
            LeafletMarker:: | 
                  protected | property | Field type plugin manager. | |
| 
            LeafletMarker:: | 
                  protected | property | The language manager. | |
| 
            LeafletMarker:: | 
                  protected | property | Leaflet service. | |
| 
            LeafletMarker:: | 
                  protected | property | 
            The Renderer service property. Overrides PluginBase:: | 
                  |
| 
            LeafletMarker:: | 
                  protected | property | 
            Does the row plugin support to add fields to it's output. Overrides RowPluginBase:: | 
                  |
| 
            LeafletMarker:: | 
                  protected | property | 
            Overrides Drupal\views\Plugin\Plugin::$usesOptions. Overrides RowPluginBase:: | 
                  |
| 
            LeafletMarker:: | 
                  protected | property | The View Data service property. | |
| 
            LeafletMarker:: | 
                  protected | function | Chance for sub-classes to adjust the leaflet marker array. | |
| 
            LeafletMarker:: | 
                  public | function | 
            Provide a form for setting options. Overrides RowPluginBase:: | 
                  |
| 
            LeafletMarker:: | 
                  public static | function | 
            Creates an instance of the plugin. Overrides PluginBase:: | 
                  |
| 
            LeafletMarker:: | 
                  protected | function | 
            Information about options for all kinds of purposes will be held here. Overrides RowPluginBase:: | 
                  |
| 
            LeafletMarker:: | 
                  protected | function | ||
| 
            LeafletMarker:: | 
                  public | function | 
            Returns the entity type identifier. Overrides EntityTranslationRenderTrait:: | 
                  |
| 
            LeafletMarker:: | 
                  protected | function | 
            Returns the language manager. Overrides EntityTranslationRenderTrait:: | 
                  |
| 
            LeafletMarker:: | 
                  protected | function | 
            Returns the top object of a view. Overrides EntityTranslationRenderTrait:: | 
                  |
| 
            LeafletMarker:: | 
                  public | function | 
            Initialize the plugin. Overrides PluginBase:: | 
                  |
| 
            LeafletMarker:: | 
                  public | function | 
            Allow the style to do stuff before each row is rendered. Overrides RowPluginBase:: | 
                  |
| 
            LeafletMarker:: | 
                  public | function | 
            Add anything to the query that we might need to. Overrides RowPluginBase:: | 
                  |
| 
            LeafletMarker:: | 
                  public | function | 
            Render a row object. This usually passes through to a theme template
of some form, but not always. Overrides RowPluginBase:: | 
                  |
| 
            LeafletMarker:: | 
                  protected | function | Converts the given list of geo data points into a list of leaflet markers. | |
| 
            LeafletMarker:: | 
                  public | function | 
            Validate that the plugin is correct and can be saved. Overrides PluginBase:: | 
                  |
| 
            LeafletMarker:: | 
                  public | function | 
            Constructs a LeafletMap style instance. Overrides PluginBase:: | 
                  |
| 
            MessengerTrait:: | 
                  protected | property | The messenger. | 29 | 
| 
            MessengerTrait:: | 
                  public | function | Gets the messenger. | 29 | 
| 
            MessengerTrait:: | 
                  public | function | Sets the messenger. | |
| 
            PluginBase:: | 
                  protected | property | Configuration information passed into the plugin. | 1 | 
| 
            PluginBase:: | 
                  public | property | Plugins's definition | |
| 
            PluginBase:: | 
                  public | property | The display object this plugin is for. | |
| 
            PluginBase:: | 
                  public | property | Options for this plugin will be held here. | |
| 
            PluginBase:: | 
                  protected | property | The plugin implementation definition. | 1 | 
| 
            PluginBase:: | 
                  protected | property | The plugin_id. | |
| 
            PluginBase:: | 
                  public | property | The top object of a view. | 1 | 
| 
            PluginBase:: | 
                  public | function | 
            Calculates dependencies for the configured plugin. Overrides DependentPluginInterface:: | 
                  14 | 
| 
            PluginBase:: | 
                  constant | A string which is used to separate base plugin IDs from the derivative ID. | ||
| 
            PluginBase:: | 
                  public | function | 
            Clears a plugin. Overrides ViewsPluginInterface:: | 
                  2 | 
| 
            PluginBase:: | 
                  protected | function | Do the work to filter out stored options depending on the defined options. | |
| 
            PluginBase:: | 
                  public | function | 
            Filter out stored options depending on the defined options. Overrides ViewsPluginInterface:: | 
                  |
| 
            PluginBase:: | 
                  public | function | 
            Returns an array of available token replacements. Overrides ViewsPluginInterface:: | 
                  |
| 
            PluginBase:: | 
                  public | function | 
            Gets the base_plugin_id of the plugin instance. Overrides DerivativeInspectionInterface:: | 
                  |
| 
            PluginBase:: | 
                  public | function | 
            Gets the derivative_id of the plugin instance. Overrides DerivativeInspectionInterface:: | 
                  |
| 
            PluginBase:: | 
                  public | function | 
            Gets the definition of the plugin implementation. Overrides PluginInspectionInterface:: | 
                  3 | 
| 
            PluginBase:: | 
                  public | function | 
            Gets the plugin_id of the plugin instance. Overrides PluginInspectionInterface:: | 
                  |
| 
            PluginBase:: | 
                  public | function | 
            Returns the plugin provider. Overrides ViewsPluginInterface:: | 
                  |
| 
            PluginBase:: | 
                  protected | function | Returns the render API renderer. | 1 | 
| 
            PluginBase:: | 
                  public | function | 
            Adds elements for available core tokens to a form. Overrides ViewsPluginInterface:: | 
                  |
| 
            PluginBase:: | 
                  public | function | 
            Returns a string with any core tokens replaced. Overrides ViewsPluginInterface:: | 
                  |
| 
            PluginBase:: | 
                  constant | Include entity row languages when listing languages. | ||
| 
            PluginBase:: | 
                  constant | Include negotiated languages when listing languages. | ||
| 
            PluginBase:: | 
                  public | function | Determines if the plugin is configurable. | |
| 
            PluginBase:: | 
                  protected | function | Makes an array of languages, optionally including special languages. | |
| 
            PluginBase:: | 
                  public | function | 
            Return the human readable name of the display. Overrides ViewsPluginInterface:: | 
                  |
| 
            PluginBase:: | 
                  public static | function | 
            Moves form elements into fieldsets for presentation purposes. Overrides ViewsPluginInterface:: | 
                  |
| 
            PluginBase:: | 
                  public static | function | 
            Flattens the structure of form elements. Overrides ViewsPluginInterface:: | 
                  |
| 
            PluginBase:: | 
                  public static | function | Returns substitutions for Views queries for languages. | |
| 
            PluginBase:: | 
                  protected | function | Fills up the options of the plugin with defaults. | |
| 
            PluginBase:: | 
                  public | function | 
            Returns the summary of the settings in the display. Overrides ViewsPluginInterface:: | 
                  6 | 
| 
            PluginBase:: | 
                  public | function | 
            Provide a full list of possible theme templates used by this style. Overrides ViewsPluginInterface:: | 
                  1 | 
| 
            PluginBase:: | 
                  public static | function | 
            Lists the trusted callbacks provided by the implementing class. Overrides TrustedCallbackInterface:: | 
                  6 | 
| 
            PluginBase:: | 
                  public | function | 
            Unpack options over our existing defaults, drilling down into arrays
so that defaults don't get totally blown away. Overrides ViewsPluginInterface:: | 
                  |
| 
            PluginBase:: | 
                  public | function | 
            Returns the usesOptions property. Overrides ViewsPluginInterface:: | 
                  8 | 
| 
            PluginBase:: | 
                  protected | function | Replaces Views' tokens in a given string. The resulting string will be sanitized with Xss::filterAdmin. | 1 | 
| 
            PluginBase:: | 
                  constant | Query string to indicate the site default language. | ||
| 
            RowPluginBase:: | 
                  public | function | 
            Perform any necessary changes to the form values prior to storage.
There is no need for this function to actually store the data. Overrides PluginBase:: | 
                  1 | 
| 
            RowPluginBase:: | 
                  public | function | Returns the usesFields property. | 4 | 
| 
            RowPluginBase:: | 
                  public | function | 
            Validate the options form. Overrides PluginBase:: | 
                  1 | 
| 
            StringTranslationTrait:: | 
                  protected | property | The string translation service. | 1 | 
| 
            StringTranslationTrait:: | 
                  protected | function | Formats a string containing a count of items. | |
| 
            StringTranslationTrait:: | 
                  protected | function | Returns the number of plurals supported by a given language. | |
| 
            StringTranslationTrait:: | 
                  protected | function | Gets the string translation service. | |
| 
            StringTranslationTrait:: | 
                  public | function | Sets the string translation service to use. | 2 | 
| 
            StringTranslationTrait:: | 
                  protected | function | Translates a string to the current language or to a given language. | |
| 
            TrustedCallbackInterface:: | 
                  constant | Untrusted callbacks throw exceptions. | ||
| 
            TrustedCallbackInterface:: | 
                  constant | Untrusted callbacks trigger silenced E_USER_DEPRECATION errors. | ||
| 
            TrustedCallbackInterface:: | 
                  constant | Untrusted callbacks trigger E_USER_WARNING errors. |