2012-12-07 22:32:14 +01:00
|
|
|
<?php
|
|
|
|
|
2013-06-05 17:41:43 +02:00
|
|
|
final class PHUIListItemView extends AphrontTagView {
|
2012-12-07 22:32:14 +01:00
|
|
|
|
|
|
|
const TYPE_LINK = 'type-link';
|
|
|
|
const TYPE_SPACER = 'type-spacer';
|
|
|
|
const TYPE_LABEL = 'type-label';
|
2013-01-29 19:20:17 +01:00
|
|
|
const TYPE_BUTTON = 'type-button';
|
2013-02-03 19:02:35 +01:00
|
|
|
const TYPE_CUSTOM = 'type-custom';
|
2013-06-05 17:41:43 +02:00
|
|
|
const TYPE_DIVIDER = 'type-divider';
|
|
|
|
const TYPE_ICON = 'type-icon';
|
2015-01-12 19:04:01 +01:00
|
|
|
const TYPE_ICON_NAV = 'type-icon-nav';
|
2012-12-07 22:32:14 +01:00
|
|
|
|
2013-10-08 04:29:05 +02:00
|
|
|
const STATUS_WARN = 'phui-list-item-warn';
|
|
|
|
const STATUS_FAIL = 'phui-list-item-fail';
|
|
|
|
|
2012-12-07 22:32:14 +01:00
|
|
|
private $name;
|
|
|
|
private $href;
|
|
|
|
private $type = self::TYPE_LINK;
|
|
|
|
private $isExternal;
|
|
|
|
private $key;
|
2012-12-07 22:33:03 +01:00
|
|
|
private $icon;
|
2014-02-01 00:19:39 +01:00
|
|
|
private $appIcon;
|
2012-12-07 22:33:03 +01:00
|
|
|
private $selected;
|
2013-06-17 15:12:45 +02:00
|
|
|
private $disabled;
|
2013-07-12 20:28:18 +02:00
|
|
|
private $renderNameAsTooltip;
|
2013-10-08 04:29:05 +02:00
|
|
|
private $statusColor;
|
2014-01-29 05:18:01 +01:00
|
|
|
private $order;
|
Add support for aural-only and visual-only elements
Summary:
Ref T4843. This adds support to `javelin_tag()` for an `aural` attribute. When specified, `true` values mean "this content is aural-only", while `false` values mean "this content is not aural".
- I've attempted to find the best modern approaches for marking this content, but the `aural` attribute should let us change the mechanism later.
- Make the "beta" markers on application navigation visual only (see T4843). This information is of very low importance, the application navigation is accessed frequently, and the information is available on the application list.
- Partially convert the main navigation. This is mostly to test things, since I want to get more concrete feedback about approaches here.
- Add a `?__aural__=1` attribute, which renders the page with aural-only elements visible and visual-only elements colored.
Test Plan: {F146476}
Reviewers: btrahan, scp, chad
Reviewed By: chad
Subscribers: aklapper, qgil, epriestley
Maniphest Tasks: T4843
Differential Revision: https://secure.phabricator.com/D8830
2014-05-01 16:18:18 +02:00
|
|
|
private $aural;
|
2015-01-12 19:04:01 +01:00
|
|
|
private $profileImage;
|
Add support for aural-only and visual-only elements
Summary:
Ref T4843. This adds support to `javelin_tag()` for an `aural` attribute. When specified, `true` values mean "this content is aural-only", while `false` values mean "this content is not aural".
- I've attempted to find the best modern approaches for marking this content, but the `aural` attribute should let us change the mechanism later.
- Make the "beta" markers on application navigation visual only (see T4843). This information is of very low importance, the application navigation is accessed frequently, and the information is available on the application list.
- Partially convert the main navigation. This is mostly to test things, since I want to get more concrete feedback about approaches here.
- Add a `?__aural__=1` attribute, which renders the page with aural-only elements visible and visual-only elements colored.
Test Plan: {F146476}
Reviewers: btrahan, scp, chad
Reviewed By: chad
Subscribers: aklapper, qgil, epriestley
Maniphest Tasks: T4843
Differential Revision: https://secure.phabricator.com/D8830
2014-05-01 16:18:18 +02:00
|
|
|
|
2015-05-27 20:11:11 +02:00
|
|
|
public function setDropdownMenu(PhabricatorActionListView $actions) {
|
|
|
|
Javelin::initBehavior('phui-dropdown-menu');
|
|
|
|
|
|
|
|
$this->addSigil('phui-dropdown-menu');
|
|
|
|
$this->setMetadata(
|
|
|
|
array(
|
|
|
|
'items' => $actions,
|
|
|
|
));
|
|
|
|
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
Add support for aural-only and visual-only elements
Summary:
Ref T4843. This adds support to `javelin_tag()` for an `aural` attribute. When specified, `true` values mean "this content is aural-only", while `false` values mean "this content is not aural".
- I've attempted to find the best modern approaches for marking this content, but the `aural` attribute should let us change the mechanism later.
- Make the "beta" markers on application navigation visual only (see T4843). This information is of very low importance, the application navigation is accessed frequently, and the information is available on the application list.
- Partially convert the main navigation. This is mostly to test things, since I want to get more concrete feedback about approaches here.
- Add a `?__aural__=1` attribute, which renders the page with aural-only elements visible and visual-only elements colored.
Test Plan: {F146476}
Reviewers: btrahan, scp, chad
Reviewed By: chad
Subscribers: aklapper, qgil, epriestley
Maniphest Tasks: T4843
Differential Revision: https://secure.phabricator.com/D8830
2014-05-01 16:18:18 +02:00
|
|
|
public function setAural($aural) {
|
|
|
|
$this->aural = $aural;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getAural() {
|
|
|
|
return $this->aural;
|
|
|
|
}
|
2014-01-29 05:18:01 +01:00
|
|
|
|
|
|
|
public function setOrder($order) {
|
|
|
|
$this->order = $order;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getOrder() {
|
|
|
|
return $this->order;
|
|
|
|
}
|
2013-07-12 20:28:18 +02:00
|
|
|
|
|
|
|
public function setRenderNameAsTooltip($render_name_as_tooltip) {
|
|
|
|
$this->renderNameAsTooltip = $render_name_as_tooltip;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getRenderNameAsTooltip() {
|
|
|
|
return $this->renderNameAsTooltip;
|
|
|
|
}
|
2013-01-16 18:00:11 +01:00
|
|
|
|
2012-12-07 22:33:03 +01:00
|
|
|
public function setSelected($selected) {
|
|
|
|
$this->selected = $selected;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getSelected() {
|
|
|
|
return $this->selected;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function setIcon($icon) {
|
|
|
|
$this->icon = $icon;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
2015-01-12 19:04:01 +01:00
|
|
|
public function setProfileImage($image) {
|
|
|
|
$this->profileImage = $image;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
2012-12-07 22:33:03 +01:00
|
|
|
public function getIcon() {
|
|
|
|
return $this->icon;
|
|
|
|
}
|
2012-12-07 22:32:14 +01:00
|
|
|
|
|
|
|
public function setKey($key) {
|
2012-12-07 22:35:17 +01:00
|
|
|
$this->key = (string)$key;
|
2012-12-07 22:32:14 +01:00
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getKey() {
|
|
|
|
return $this->key;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function setType($type) {
|
|
|
|
$this->type = $type;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getType() {
|
|
|
|
return $this->type;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function setHref($href) {
|
|
|
|
$this->href = $href;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getHref() {
|
|
|
|
return $this->href;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function setName($name) {
|
|
|
|
$this->name = $name;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getName() {
|
|
|
|
return $this->name;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function setIsExternal($is_external) {
|
|
|
|
$this->isExternal = $is_external;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getIsExternal() {
|
|
|
|
return $this->isExternal;
|
|
|
|
}
|
|
|
|
|
2013-10-08 04:29:05 +02:00
|
|
|
public function setStatusColor($color) {
|
|
|
|
$this->statusColor = $color;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
2013-01-16 19:50:41 +01:00
|
|
|
protected function getTagName() {
|
2013-06-06 01:21:55 +02:00
|
|
|
return 'li';
|
2013-01-16 19:50:41 +01:00
|
|
|
}
|
2012-12-07 22:32:14 +01:00
|
|
|
|
2013-06-06 01:21:55 +02:00
|
|
|
protected function getTagAttributes() {
|
|
|
|
$classes = array();
|
|
|
|
$classes[] = 'phui-list-item-view';
|
|
|
|
$classes[] = 'phui-list-item-'.$this->type;
|
2013-06-05 17:41:43 +02:00
|
|
|
|
2014-02-01 00:19:39 +01:00
|
|
|
if ($this->icon || $this->appIcon) {
|
2013-06-06 01:21:55 +02:00
|
|
|
$classes[] = 'phui-list-item-has-icon';
|
|
|
|
}
|
2013-06-05 17:41:43 +02:00
|
|
|
|
2013-06-06 01:21:55 +02:00
|
|
|
if ($this->selected) {
|
|
|
|
$classes[] = 'phui-list-item-selected';
|
|
|
|
}
|
2013-06-05 17:41:43 +02:00
|
|
|
|
2015-03-25 19:48:22 +01:00
|
|
|
if ($this->disabled) {
|
|
|
|
$classes[] = 'phui-list-item-disabled';
|
|
|
|
}
|
|
|
|
|
2013-10-08 04:29:05 +02:00
|
|
|
if ($this->statusColor) {
|
|
|
|
$classes[] = $this->statusColor;
|
|
|
|
}
|
|
|
|
|
2013-01-16 19:50:41 +01:00
|
|
|
return array(
|
2013-06-06 01:21:55 +02:00
|
|
|
'class' => $classes,
|
|
|
|
);
|
2013-01-16 19:50:41 +01:00
|
|
|
}
|
2012-12-07 22:32:14 +01:00
|
|
|
|
2013-06-17 15:12:45 +02:00
|
|
|
public function setDisabled($disabled) {
|
|
|
|
$this->disabled = $disabled;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getDisabled() {
|
|
|
|
return $this->disabled;
|
|
|
|
}
|
|
|
|
|
2013-01-16 19:50:41 +01:00
|
|
|
protected function getTagContent() {
|
2012-12-07 22:33:03 +01:00
|
|
|
$name = null;
|
2013-03-30 22:46:02 +01:00
|
|
|
$icon = null;
|
2013-07-12 20:28:18 +02:00
|
|
|
$meta = null;
|
|
|
|
$sigil = null;
|
2013-03-30 22:46:02 +01:00
|
|
|
|
2012-12-07 22:33:03 +01:00
|
|
|
if ($this->name) {
|
2013-07-12 20:28:18 +02:00
|
|
|
if ($this->getRenderNameAsTooltip()) {
|
2015-01-12 19:04:01 +01:00
|
|
|
Javelin::initBehavior('phabricator-tooltips');
|
2013-07-12 20:28:18 +02:00
|
|
|
$sigil = 'has-tooltip';
|
|
|
|
$meta = array(
|
|
|
|
'tip' => $this->name,
|
2015-01-12 19:04:01 +01:00
|
|
|
'align' => 'E',
|
2013-07-12 20:28:18 +02:00
|
|
|
);
|
|
|
|
} else {
|
|
|
|
$external = null;
|
|
|
|
if ($this->isExternal) {
|
|
|
|
$external = " \xE2\x86\x97";
|
|
|
|
}
|
|
|
|
|
Add support for aural-only and visual-only elements
Summary:
Ref T4843. This adds support to `javelin_tag()` for an `aural` attribute. When specified, `true` values mean "this content is aural-only", while `false` values mean "this content is not aural".
- I've attempted to find the best modern approaches for marking this content, but the `aural` attribute should let us change the mechanism later.
- Make the "beta" markers on application navigation visual only (see T4843). This information is of very low importance, the application navigation is accessed frequently, and the information is available on the application list.
- Partially convert the main navigation. This is mostly to test things, since I want to get more concrete feedback about approaches here.
- Add a `?__aural__=1` attribute, which renders the page with aural-only elements visible and visual-only elements colored.
Test Plan: {F146476}
Reviewers: btrahan, scp, chad
Reviewed By: chad
Subscribers: aklapper, qgil, epriestley
Maniphest Tasks: T4843
Differential Revision: https://secure.phabricator.com/D8830
2014-05-01 16:18:18 +02:00
|
|
|
// If this element has an aural representation, make any name visual
|
|
|
|
// only. This is primarily dealing with the links in the main menu like
|
|
|
|
// "Profile" and "Logout". If we don't hide the name, the mobile
|
|
|
|
// version of these elements will have two redundant names.
|
|
|
|
|
|
|
|
$classes = array();
|
|
|
|
$classes[] = 'phui-list-item-name';
|
|
|
|
if ($this->aural !== null) {
|
|
|
|
$classes[] = 'visual-only';
|
|
|
|
}
|
|
|
|
|
2013-07-12 20:28:18 +02:00
|
|
|
$name = phutil_tag(
|
|
|
|
'span',
|
|
|
|
array(
|
Add support for aural-only and visual-only elements
Summary:
Ref T4843. This adds support to `javelin_tag()` for an `aural` attribute. When specified, `true` values mean "this content is aural-only", while `false` values mean "this content is not aural".
- I've attempted to find the best modern approaches for marking this content, but the `aural` attribute should let us change the mechanism later.
- Make the "beta" markers on application navigation visual only (see T4843). This information is of very low importance, the application navigation is accessed frequently, and the information is available on the application list.
- Partially convert the main navigation. This is mostly to test things, since I want to get more concrete feedback about approaches here.
- Add a `?__aural__=1` attribute, which renders the page with aural-only elements visible and visual-only elements colored.
Test Plan: {F146476}
Reviewers: btrahan, scp, chad
Reviewed By: chad
Subscribers: aklapper, qgil, epriestley
Maniphest Tasks: T4843
Differential Revision: https://secure.phabricator.com/D8830
2014-05-01 16:18:18 +02:00
|
|
|
'class' => implode(' ', $classes),
|
2013-07-12 20:28:18 +02:00
|
|
|
),
|
|
|
|
array(
|
|
|
|
$this->name,
|
|
|
|
$external,
|
|
|
|
));
|
2012-12-07 22:33:03 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Add support for aural-only and visual-only elements
Summary:
Ref T4843. This adds support to `javelin_tag()` for an `aural` attribute. When specified, `true` values mean "this content is aural-only", while `false` values mean "this content is not aural".
- I've attempted to find the best modern approaches for marking this content, but the `aural` attribute should let us change the mechanism later.
- Make the "beta" markers on application navigation visual only (see T4843). This information is of very low importance, the application navigation is accessed frequently, and the information is available on the application list.
- Partially convert the main navigation. This is mostly to test things, since I want to get more concrete feedback about approaches here.
- Add a `?__aural__=1` attribute, which renders the page with aural-only elements visible and visual-only elements colored.
Test Plan: {F146476}
Reviewers: btrahan, scp, chad
Reviewed By: chad
Subscribers: aklapper, qgil, epriestley
Maniphest Tasks: T4843
Differential Revision: https://secure.phabricator.com/D8830
2014-05-01 16:18:18 +02:00
|
|
|
$aural = null;
|
|
|
|
if ($this->aural !== null) {
|
2014-05-01 16:54:29 +02:00
|
|
|
$aural = javelin_tag(
|
Add support for aural-only and visual-only elements
Summary:
Ref T4843. This adds support to `javelin_tag()` for an `aural` attribute. When specified, `true` values mean "this content is aural-only", while `false` values mean "this content is not aural".
- I've attempted to find the best modern approaches for marking this content, but the `aural` attribute should let us change the mechanism later.
- Make the "beta" markers on application navigation visual only (see T4843). This information is of very low importance, the application navigation is accessed frequently, and the information is available on the application list.
- Partially convert the main navigation. This is mostly to test things, since I want to get more concrete feedback about approaches here.
- Add a `?__aural__=1` attribute, which renders the page with aural-only elements visible and visual-only elements colored.
Test Plan: {F146476}
Reviewers: btrahan, scp, chad
Reviewed By: chad
Subscribers: aklapper, qgil, epriestley
Maniphest Tasks: T4843
Differential Revision: https://secure.phabricator.com/D8830
2014-05-01 16:18:18 +02:00
|
|
|
'span',
|
|
|
|
array(
|
2014-05-01 16:54:29 +02:00
|
|
|
'aural' => true,
|
Add support for aural-only and visual-only elements
Summary:
Ref T4843. This adds support to `javelin_tag()` for an `aural` attribute. When specified, `true` values mean "this content is aural-only", while `false` values mean "this content is not aural".
- I've attempted to find the best modern approaches for marking this content, but the `aural` attribute should let us change the mechanism later.
- Make the "beta" markers on application navigation visual only (see T4843). This information is of very low importance, the application navigation is accessed frequently, and the information is available on the application list.
- Partially convert the main navigation. This is mostly to test things, since I want to get more concrete feedback about approaches here.
- Add a `?__aural__=1` attribute, which renders the page with aural-only elements visible and visual-only elements colored.
Test Plan: {F146476}
Reviewers: btrahan, scp, chad
Reviewed By: chad
Subscribers: aklapper, qgil, epriestley
Maniphest Tasks: T4843
Differential Revision: https://secure.phabricator.com/D8830
2014-05-01 16:18:18 +02:00
|
|
|
),
|
|
|
|
$this->aural);
|
|
|
|
}
|
|
|
|
|
Add action icons to object list views
Summary:
We have a few interfaces where add "Edit", "Delete" or some other action to a list. Currently, this happens via icons, but these are cumbersome and weird, are inconsistent, can't be workflow'd, are hard to hit on desktops and virtually impossible to hit on mobile, and generally just feel iffy to me. Prominent examples are Projects and Flags. I'd like to try adding an "edit" action to Maniphest (to provide quick edit from list views, basically). It looks like some of Releeph would benefit here, as well.
Instead, provide first-class actions:
{F42978}
They produce targets which my meaty ham-fists can plausibly hit on mobile, too:
{F42979}
(We could do some kind of swipe-to-expose thing eventually, but I think putting them by default is OK?)
Test Plan: Added UIExamples. Checked desktop/mobile.
Reviewers: chad, btrahan, edward
Reviewed By: btrahan
CC: aran
Differential Revision: https://secure.phabricator.com/D5890
2013-05-10 21:57:01 +02:00
|
|
|
if ($this->icon) {
|
2013-06-17 15:12:45 +02:00
|
|
|
$icon_name = $this->icon;
|
|
|
|
if ($this->getDisabled()) {
|
2014-05-12 19:08:32 +02:00
|
|
|
$icon_name .= ' grey';
|
2013-06-17 15:12:45 +02:00
|
|
|
}
|
|
|
|
|
Add action icons to object list views
Summary:
We have a few interfaces where add "Edit", "Delete" or some other action to a list. Currently, this happens via icons, but these are cumbersome and weird, are inconsistent, can't be workflow'd, are hard to hit on desktops and virtually impossible to hit on mobile, and generally just feel iffy to me. Prominent examples are Projects and Flags. I'd like to try adding an "edit" action to Maniphest (to provide quick edit from list views, basically). It looks like some of Releeph would benefit here, as well.
Instead, provide first-class actions:
{F42978}
They produce targets which my meaty ham-fists can plausibly hit on mobile, too:
{F42979}
(We could do some kind of swipe-to-expose thing eventually, but I think putting them by default is OK?)
Test Plan: Added UIExamples. Checked desktop/mobile.
Reviewers: chad, btrahan, edward
Reviewed By: btrahan
CC: aran
Differential Revision: https://secure.phabricator.com/D5890
2013-05-10 21:57:01 +02:00
|
|
|
$icon = id(new PHUIIconView())
|
2013-06-05 17:41:43 +02:00
|
|
|
->addClass('phui-list-item-icon')
|
2014-05-12 19:08:32 +02:00
|
|
|
->setIconFont($icon_name);
|
Add action icons to object list views
Summary:
We have a few interfaces where add "Edit", "Delete" or some other action to a list. Currently, this happens via icons, but these are cumbersome and weird, are inconsistent, can't be workflow'd, are hard to hit on desktops and virtually impossible to hit on mobile, and generally just feel iffy to me. Prominent examples are Projects and Flags. I'd like to try adding an "edit" action to Maniphest (to provide quick edit from list views, basically). It looks like some of Releeph would benefit here, as well.
Instead, provide first-class actions:
{F42978}
They produce targets which my meaty ham-fists can plausibly hit on mobile, too:
{F42979}
(We could do some kind of swipe-to-expose thing eventually, but I think putting them by default is OK?)
Test Plan: Added UIExamples. Checked desktop/mobile.
Reviewers: chad, btrahan, edward
Reviewed By: btrahan
CC: aran
Differential Revision: https://secure.phabricator.com/D5890
2013-05-10 21:57:01 +02:00
|
|
|
}
|
|
|
|
|
2015-01-12 19:04:01 +01:00
|
|
|
if ($this->profileImage) {
|
|
|
|
$icon = id(new PHUIIconView())
|
|
|
|
->setHeadSize(PHUIIconView::HEAD_SMALL)
|
|
|
|
->setImage($this->profileImage);
|
|
|
|
}
|
|
|
|
|
2014-02-01 00:19:39 +01:00
|
|
|
if ($this->appIcon) {
|
|
|
|
$icon = id(new PHUIIconView())
|
|
|
|
->addClass('phui-list-item-icon')
|
2015-01-25 23:14:41 +01:00
|
|
|
->setIconFont($this->appIcon);
|
2014-02-01 00:19:39 +01:00
|
|
|
}
|
|
|
|
|
2013-07-12 20:28:18 +02:00
|
|
|
return javelin_tag(
|
2013-06-06 01:21:55 +02:00
|
|
|
$this->href ? 'a' : 'div',
|
|
|
|
array(
|
|
|
|
'href' => $this->href,
|
|
|
|
'class' => $this->href ? 'phui-list-item-href' : null,
|
2013-07-12 20:28:18 +02:00
|
|
|
'meta' => $meta,
|
|
|
|
'sigil' => $sigil,
|
2013-06-06 01:21:55 +02:00
|
|
|
),
|
|
|
|
array(
|
Add support for aural-only and visual-only elements
Summary:
Ref T4843. This adds support to `javelin_tag()` for an `aural` attribute. When specified, `true` values mean "this content is aural-only", while `false` values mean "this content is not aural".
- I've attempted to find the best modern approaches for marking this content, but the `aural` attribute should let us change the mechanism later.
- Make the "beta" markers on application navigation visual only (see T4843). This information is of very low importance, the application navigation is accessed frequently, and the information is available on the application list.
- Partially convert the main navigation. This is mostly to test things, since I want to get more concrete feedback about approaches here.
- Add a `?__aural__=1` attribute, which renders the page with aural-only elements visible and visual-only elements colored.
Test Plan: {F146476}
Reviewers: btrahan, scp, chad
Reviewed By: chad
Subscribers: aklapper, qgil, epriestley
Maniphest Tasks: T4843
Differential Revision: https://secure.phabricator.com/D8830
2014-05-01 16:18:18 +02:00
|
|
|
$aural,
|
2013-06-06 01:21:55 +02:00
|
|
|
$icon,
|
|
|
|
$this->renderChildren(),
|
|
|
|
$name,
|
|
|
|
));
|
2012-12-07 22:32:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|