Commit graph

105 commits

Author SHA1 Message Date
Alexander Vorwerk 702ec511dc MediaWikiTestCase -> MediaWikiIntegrationTestCase
MediaWikiTestCase has been renamed to MediaWikiIntegrationTestCase in 1.34.

Bug: T293043
Change-Id: I5b83516ccdf0ac025421844c9516e856060aefba
2021-10-12 00:53:10 +02:00
Jdlrobson 8651df02bb Replace categories button with HTML rendering
Bug: T246049
Change-Id: Id8c7493a525844b43c1628a1f4f09ae716ece2ba
2021-05-14 20:34:59 +00:00
vladshapik 6da72c8099 Avoid using User::isIP
Remove using of User::isIP since this method will be hard-deprecated. Now it is soft-deprecated

Bug: T275602
Change-Id: I01a0c2ef4d750cf0e81a9345ee462787d4ee28da
2021-03-02 14:29:58 +02:00
Umherirrender 09b331ab83 Improve function and property documentation
Change-Id: I16cc3831cd4c917aa679c7f7c535b97e498291a7
2021-01-16 14:35:10 +01:00
jdlrobson c3b93e14b0 Simplify footer and logo generation
The data already provided by SkinMustache makes the existing
Minerva code redundant.

* html-after-content functionality equivalent to dataAfterContent value
* Rename license and last modified to have html-minerva prefixes and promote
to top level data object. This allows us to distingusih Minerva values from core
values.

Note: previously the logo used srcset to ship a 1x logo but these
were dropped during the desktop improvements work.

Bug: T256083
Change-Id: I7b2cd5181eae67b345f6686e3389a76a12e3b1a1
2020-10-16 23:41:34 +00:00
Jdlrobson 74838b2fa2 Revert "ServiceWiring: Avoid usage of deprecated Title::getSubjectPage()"
This reverts commit ae8e3ad58b.

Reason for revert: This led to T260155 as the internal class uses
isSubPage which is not available on LinkTarget

Bug: T260155
Change-Id: I783f41e70cf1cf3b91737bce9cbf9ac729a778df
2020-08-11 15:50:44 +00:00
Derick A ae8e3ad58b ServiceWiring: Avoid usage of deprecated Title::getSubjectPage()
SkinUserPageHelper::__construct() should be able to consume a LinkTarget
too as NamespaceInfo::getSubjectPage() method returns a LinkTarget and
the Title::getSubjectPage() is deprecated.

Change-Id: I08bfc9bb21772b450798b6354bee2ab09d5dba4d
2020-08-08 14:07:48 +01:00
jdlrobson 2e450e104e Donate link should be in a separate group in main menu
Bug: T219793
Change-Id: I7501c87eaa799e4c8a9052f5e3f650a89f376d1b
2020-06-29 14:38:34 -07:00
Reedy 2d7150125c Fix PSR12.Properties.ConstantVisibility.NotFound
Bug: T253169
Change-Id: I35b646522df6f0ec14ca8fee718937cc8cf44ce9
2020-05-19 22:59:27 +00:00
Reedy 01f824f684 Fix namespace of SkinUserPageHelper
Allows autoloading of file

Change-Id: Ife276b5802e3cdcfd5789a7a91684317c81d5bb3
2020-05-01 02:29:54 +01:00
Daimona Eaytoy edaa6715a0 tests: Avoid calls to Title::__construct
Change-Id: Ib41a016c1deb70daf4ccc302631d70ca7e006503
2020-03-13 14:01:04 +00:00
James D. Forrester 0892d190b6 Drop support for $wgMinervaCustomLogos being set
Bug: T232140
Change-Id: I56dc8ac8d394ad7561ea09e67da6c51db2bc90f9
2020-03-10 20:40:32 +00:00
jdlrobson 51a348097d Deprecate wgMinervaCustomLogos in favor of $wgLogos
Testing:
```
// Start with no Minerva config and no wgLogos defined in LocalSettings.php

// Set $wgMinervaCustomLogos
// Should trigger deprecation warning.
$wgMinervaCustomLogos = [
	'copyright' => 'https://en.m.wikipedia.org/static/images/mobile/copyright/wikipedia-wordmark-fr.svg',
	'copyright-height' => 40,
	'copyright-width' => 120,
];

// Set wgLogos without wordmark
// Should trigger deprecation warning as $wgMinervaCustomLogos is still
// defined.
$wgLogos = [
	'1x' => 'https://en.wikipedia.beta.wmflabs.org/static/images/project-logos/enwiki.png'
];


// Set wgLogos['wordmark']
// No deprecation warning. $wgMinervaCustomLogos will now be ignored
// in favor of the new wordmark key.
$wgLogos = [
	'1x' => 'https://en.wikipedia.beta.wmflabs.org/static/images/project-logos/enwiki.png',
	'wordmark' => [
		'src' => 'https://en.m.wikipedia.org/static/images/mobile/copyright/wikipedia-wordmark-fr.svg',
		'height' => 40,
		'width' => 120,
	],
];

// You can now safely drop $wgMinervaCustomLogos.

```
Depends-On: I66a971631c623cc94b58eb0e5e5bad804789bf1c
Bug: T232140
Change-Id: I013bd0904fe8c55efa49d14e84cf06ec1412896f
2020-02-19 23:59:28 +00:00
Umherirrender 5b0a4f30b2 build: Updating mediawiki/mediawiki-codesniffer to 29.0.0
Change-Id: I529c6a67eeb5eb012031b69ef63f4338f3685178
2020-01-26 20:26:31 +01:00
Ammar Abdulhamid 898b048d1c Discontinue back-to-top feature
Bug: T237290
Change-Id: I06a6823bd3d1985a1d76384bb65c9d2ddf334a21
2019-12-11 05:12:43 +00:00
jdlrobson c0d5889da8 Remove unused test class
Not needed since I09c27a084100b223662f84de6cbe01bebe1fe774

Bug: T221007
Change-Id: I909acac40a3fc732b10d0e66f8d430a0148734cf
2019-10-22 19:16:36 +00:00
James D. Forrester e8d227b78e build: Upgrade mediawiki-codesniffer to v28.0.0
Change-Id: I8ce5f16f496f048f6bcf587c545745193dbfe151
2019-10-11 12:04:00 -07:00
jdlrobson ab61dbb173 Echo is removed from Minerva
Managing the transition from old implementation to new:
* A version number is exported from skins.minerva.scripts to
tell dormant code added to Echo in I09c27a084100b223662f84de6cbe01bebe1fe774
to begin running.
* A skinStyle is added for the new `ext.echo.mobile` module.
`mobile.notifications.overlay` will soon cease to exist but is kept registered for
backwards compatibility reasons
- Drop ev.preventDefault call from onSkinClick - it is no longer necessary and will ensure
notifications overlay closes when shield is clicked while it is open.

Integration:
* A server side hook SkinMinervaReplaceNotificationsBadge allows Echo to replace
the current Minerva notification badge
* A to-be-created client side hook is subscribed to to deal with the navigations drawer
like functionality using the mainMenu code
* id and class names are added to the container for the NotificationBadge for compatibility with
ext.echo.init in Minerva's desktop mode (it will work like Vector)

See I09c27a084100b223662f84de6cbe01bebe1fe774 for understanding the bigger
picture.

Depends-On:  I09c27a084100b223662f84de6cbe01bebe1fe774
Bug: T221007
Change-Id: I4c11f1b241d629e1b294ebaec17472fbf944f8c7
2019-10-08 23:21:12 +00:00
jdlrobson 7eb2e3bd07 Notification icon doesn't show to non-JS users
If JS is disabled and you are logged in, no icon shows.
Icon class is incorrect.

I also update the test.

Change-Id: I786ced58171f4ffb4a9d75dcfc6f993647399065
2019-09-30 14:38:59 -07:00
Jan Drewniak 73e87fdc08 Align right-most header icon with content.
uses the CSS :last-child selector to align the last item in the header
with the edge of the container.
This is usually the notification icon in "normal" mode and
the user menu icon in AMC mode.

Bug: T229440
Change-Id: I4430f5659093f76896e2b86e076526a0b51d9630
2019-09-16 11:05:36 +02:00
jdlrobson 109b24e0ee Adjust notification icon to be the same size as the other icons
Bug: T232011
Change-Id: I0300685d38551bc9ee2c2bd32d6348f32d4df4de
2019-09-13 13:55:01 -07:00
jdlrobson 9150aec131 Feature flag overhaul
Two new feature flags:
1) MinervaPersonalMenu
2) MinervaAdvancedMainMenu

Changes:
* AMC defaults to false on desktop - desktop doesn't have AMC mode it just
enables several skin options.
* WHen inserting a link at the bottom of the page check whether the talk at top
of the page (tabs) is enabled.. not AMC
* Update ServiceWiring to construct menu based on MinervaAdvancedMainMenu
and  MinervaPersonalMenu - note when former is enabled but not latter there is
no way to logout. Noted in README.
* Use one entry point for skins.minerva.amc.styles/index.less
* Document files inside skins.minerva.amc.styles to make it clear which features
they are associated with
* Drop history page styles when AMC is disabled - it's not possible to ever get to
these as the history page redirects in non-AMC mode
* Rename the class .minerva--amc-enabled to minerva--history-page-action-enabled
to reflect its real purpose and move styles from skins.minerva.base.styles to skins.minerva.amc.styles
No need to worry about cached HTML as AMC runs without cache...
* Remove isAnyAMCOptionEnabled - it's an antipattern and should be discouraged as it discourages the
art of feature flagging. Nothing is using it after these changes.
* The AMC_MODE flag is disabled. There is no need for this - AMC is not a feature and therefore not a
skin option. It is a mechanism for turning on other skin options. Tests are updated.

Testing:
It should now be possible to enable any feature in `beta` and see it in the beta of the
site.

Bug: T229295
Change-Id: I48959905f5c09721b14a27aa1a5ad82849ac6263
2019-08-23 10:48:14 -07:00
jdlrobson 9aae174a15 AMC features should default to true in desktop
It is expected that in mobile mode, onRequestContextCreateSkinMobile
hook will explicitly set skin options based on the user configuration.

The desktop should however reflect everything with AMC enabled.

Bug: T229295
Change-Id: Ib3bf09c25d9bcf9b31d994b92a1d016cca8a6224
2019-08-01 18:04:00 -07:00
Piotr Miazga 4efd72a879 Hygiene: Remove OPTIONS_ and OPTION_ prefixes from SKinOptions
Additionally, renamed couple options for better readability.

Bug: T221012
Change-Id: Ia347a60d469fba8f35afa7c70aa806a46271dccd
2019-08-01 10:34:03 -07:00
jdlrobson f0503a52d0 Refresh the user, bell and search icon
* New module skins.minerva.icons.wikimedia provides icons
from Wikimedia UI in Minerva
* search selector in skins.minerva.content.styles.images is
retained for cached HTML
* skins.minerva.icons.loggedin now a
ResourceLoaderOOUIIconPackModule and bell removed from repo.
* userAvatar replaced with userAvatarOutline

Bug: T224070
Change-Id: Ibed609371060acc4b69e5cd4cd4f20edc871b3ba
2019-07-25 16:35:01 +00:00
Piotr Miazga 6352190684 Hygiene: Extract isAllowedPageAction into MinervaPagePermissions
The isAllowedPageAction is used in multiple places (SkinMinerva
and in PageActions toolbar builder). This logic should be defined
in separate service, easy accessible for different parts of the
Minerva skin.

Changes:
 - Introduced MinervaPagePermissions as a centralized place to manage
 user permissions
 - Introduced MinervaNoTitlePermissions, an NullObject pattern to
 handle situations when we do not have Title object (like in CLI)
 - removed Minerva.ContentHandler service as it's not required any
 more
 - moved all permission names into constants
 - moved isTalkAllowed() into MinervaPermissions
 - renamed isAllowedPageAction() it `isAllowed()` to not mix it
 with PageActions. Those checks are used in many places, not only
 on PageActions menu
 - made isAllowed( watch ) more robust - now it checks that Title
 is watchable

Bug: T221792
Change-Id: I87d44a9c717b5f752b8d1fd2f146d7f5eef3c53f
2019-06-21 15:30:11 +00:00
Stephen Niedzielski 1e61706e0e Hygiene: rename "secondary button" to "user notifications"
The secondary button is not generic. Rename it to match its specific
purpose.

Bug: T214540
Change-Id: I50b7e7fa7bea91a029a8ca71199b0309dff1c518
2019-06-19 11:31:16 -06:00
Stephen Niedzielski 02726555e0 Hygiene: rename user notification build method
Rename SkinMinerva->prepareUserButton() to
prepareUserNotificationsButton(). The function is responsible for
inflating the button that displays notifications when pressed. This name
would be especially confusing when an actual user button is added in
T214540.

Bug: T214540
Change-Id: I8965ef4c5b29ea692d67e821a06131ad5f287287
2019-06-19 11:16:23 -06:00
Piotr Miazga 047618c24d Hygiene: SkinUserPageHelper should support Title = null
In some edge cases the RequestContext::getTitle() can return null
instead of Title object. Similar situations already happened in the
past (see T179833). The RequestContext::getTitle() documentation
says it can return null, therefore code should be resilient and
support such situations, even if there are not common.

Bug: T221792
Change-Id: I842f8c49f20e511fda3b081e59a06586810bc748
2019-06-04 17:17:58 +02:00
Jan Drewniak 7af32bc309 Treat anonymouse user IP pages as UserPages
Ensure SkinUserPageHelper::isUserPage() returns true for user pages
that are IP addresses.

Also adds the page-action menu to all user pages.

Bug: T220114
Change-Id: I3703899bc9ff0042c74260d36f48a388b78b0b6b
2019-06-04 11:53:07 +02:00
Piotr Miazga b3a7047d65 Hygiene: test method names should be written in cameCase
Change-Id: I12bd086c0ebd42133b6f7171847dbe50f8f7fe30
2019-06-03 18:53:40 +02:00
Piotr Miazga 4ec9b06a77 Watchstar should respect viewmywatchlist|editmywatchlist permissions
If viewmywatchlist|editmywatchlist permisions were set to false for
anonymous user, MinervaSkin would show a watchstar icon that links
to LoginPage, even if user was logged in. Clicking watching action
would cause browser to reload the page without any effect.
Under the hood - system would redirect to login, and then the login
page would redirect user back to the article page because user is
logged in.

MinervaSkin should respect viewmywatchlist|editmywatchlist
permissions. If user do not have access to watchlist, do not show
watch icon.

Bug: T221792
Change-Id: I26a1133a7ccff6a4adcdc72d594d0902bfa8ff79
2019-05-31 17:34:35 +00:00
Piotr Miazga 39a2078472 Minerva shouldn't call Skin::getNewTalks() twice
The Skin::getNewTalks() is already called in SkinTemplate::prepareQuickTemplate.
There is no need to call this function again, as is pretty heavy. Instead of
calling it second time, just re-use the value stored in the QuickTemplate

Change-Id: I0e9491405f4d760278db3a423ee14e8f80720291
2019-05-14 16:09:18 +02:00
Piotr Miazga 258e635ae5 Extract SkinOptions to separate class
SkinOptions array was used to determine which options are available
for current session. Once we started extracting things from
SkinMinerva class, we found out that lots of things depend on
SkinOptions.

For example MainMenu/PageActionsMenu depend on skinsOptions var.
We could pass $skin object as dependency to a menu builder, but
this would cause a circural dependency (Skin depends on menu builder,
menu builder depends on skin) which is an anti-pattern.
In order to avoid such situations lets prepare first, and extract
the SkinOptions to a separate class, register it as a service
so different parts of Skin Minerva can freely use a single instance
of SkinOptions object.

Bug: T216152
Bug: T221012
Change-Id: Icd5da546e1bfaf8d9bfe86dab3b659a88eae19e4
2019-04-15 20:34:12 +00:00
Piotr Miazga 572ffdf25a Use MediaWikiServices to cache commonly used helpers
SkinMinerva cached the ContentHandler object for better performance.
In the future the ContentHandler will be also used in the Menu,
for better readability, store ContentHandler as Service.

MediaWikiServices will initialize service on first access and cache
it for future needs. Same applies to SkinUserPageHelper,

Bug: T216152
Change-Id: Ia98dc860862360a68556272714669f0c3a13eb1e
2019-04-15 20:50:11 +02:00
jdlrobson 0be05950af Desktop should use AMC mode
To help us test special pages prior to moving them on mobile it
would be useful to make AMC the default on desktop
where the special page override does not exist

This is also probably what editors on desktop using the Minerva
skin want out of the skin.

On top of this, add an amc class to the body tag so we can
target styles at AMC and/or non-AMC users

Change-Id: I7f3141bae71181131ae4878fd21fb6ff4322c8ca
2019-04-04 17:43:12 +00:00
jenkins-bot b08643cbab Merge "Fix undefined NS issue with @coversDefaultClass" 2018-11-01 14:22:48 +00:00
Alangi Derick 679a45677e Explicitly use "MediaWiki\Minerva\SkinUserPageHelper;" on-top of file
To make things neat, use "MediaWiki\Minerva\SkinUserPageHelper;" at the top
of the file and then mock class directly (shorter and easily readable).

Change-Id: Ie2ee64e75c38fff77d41af20bdea01015ed39a87
2018-11-01 14:35:57 +01:00
Alangi Derick e2e5cbc3d7 Fix undefined NS issue with @coversDefaultClass
In skin MinervaNeue, correctly cover SkinUserPageHelper
namespace in SkilUserPageHelperTest.php

Change-Id: I8c8bd9986c2b3989f093bfb585d90647e8da60ef
2018-11-01 14:28:20 +01:00
Alangi Derick a2fd0b3c1f Add "Discussion" button to Main page on Mobile View
* Enable discussion button on main page in mobile view so users
  can view discussion topics related to the main page on mobile.
* Update test to make sure only 'talk' and 'switch-language' actions are
  enabled on the main page and 'edit' and 'watch' are disabled on the main
  page.
* Minor typo fix for doc type. Use "array" instead of "Array" and CSS
  alignment fix issue with Discussion button when displayed together with
  Language selector button.
* [Suggested by: @Jdlrobson] Use a generic "a" CSS selector to style the ".talk"
  and ".language-selector" classes on the main page. This also avoids fixing the
  CSS for future buttons if added (future proofing the code), so if any other
  button is added in the future, the same css rule will be applied to it at once.
  Very wise idea from @Jdlrobson, thanks!

Bug: T206406
Change-Id: Iedce84595adc357f3a707f8b94d23b2ffea3476c
2018-10-23 19:59:22 +01:00
jdlrobson cbad0bd363 Merge skin option modules into a single ResourceLoader module and move enabled logic to client
It's presumed that skin options will eventually become the default or be removed from the skin.
While they are not the default, it would be helpful to package them in one single module - as ResourceLoader
modules are costly bloating the dependency graph in the MediaWiki startup module.

In T167713 we talked about grouping our entry points by page rather than feature, which this seems consistent
with. A page with special options enabled is different from a page without.

Change-Id: Id948f913d4743532ba3442d2059a03c122419ff2
2018-10-12 10:18:21 -07:00
RazeSoldier 91f285127e Use . operator instead of + operator
String concatenation should use . operator, not +, otherwise it will
report some Warning

Bug: T195645
Change-Id: Id27c981622e5ed87519324193abd2249aa1df7b6
2018-05-26 16:37:41 +08:00
Kunal Mehta 4da5567bd9 Simplify SkinUserPageHelper constructor
Instead of requiring a full IContextSource object and only using the
Title, only ask for the Title in the first place.

Change-Id: I33034193140ca53919f29f847a03caf26250ce54
2018-04-15 16:38:50 -07:00
Kunal Mehta 1b1c56c862 Fix some file names to match their class names
Change-Id: Ib1a12f8073a2d737c40c0b4d1dd64f9e55738019
2018-04-15 16:12:45 -07:00
Timo Tijhof d5145178b9 Hygiene: Replace QuickTemplate test subclass with mock
Change-Id: I32aa9d5103f4b6790a5118d5cad2cd91d3ddc459
2018-02-03 03:11:14 +00:00
petarpetkovic 413fcc12f6 Fix seen notifications appearing as unseen on mobile
Important note: Make sure to distinguish unseen from unread

One way to reproduce minerva and non-minerva notification inconsistencies:
- Have all your alerts and notices seen. This is displayed with grayed out
number on vector skin or no number at all, if you have (marked as) read.
- Generate new alert or notice (one is enough) in your preferred way.
- You can check minerva and non-minerva at this step. Both should be in sync.
But don't perform any additional action.
- Open the notification popup in some non-minerva skin (I have tried with
vector and monobook), marking it as seen.
- Check the notification icon in minerva. At this point, you should see
notification displayed as unseen.

The reason bug appeared in the first place is that alert/notice timestamps
were mixed up when seen time is obtained. We get seen time from
EchoSeenTime class, where we get smaller of the two timestamps,
using PHP method `min()`. See I27109ee6a248. Then, we get last unread
notification timestamp (which can be either alert or notice), and compare
that to seen time. That leads to the situation when you have only one of
alerts or notices with unread items, smaller timestamp is used for seen,
and most recent for unread, at which point we compare timestamps for
two separate things.

Previous behavior of getting seen timestamps (using max instead of min) would
probably solve the problem, but some other inconsistencies might arrise.
This should prevent any weird and unpredictable behavior to happen.

Bug: T183076
Change-Id: I20bbd6c590086b1c3eccf82983aad59eb3144a7a
2018-01-18 14:18:56 +01:00
Umherirrender bf974861a2 Fix spacing of @covers
Change-Id: I61d2cd2cb4523433bda37f349cf5327bfb4c1b66
2017-12-29 21:26:59 +01:00
jdlrobson d3318a9f85 Remove MobileFrontend's font changing code from Minerva
Fontchanger code now runs on all skins under the `mobile` target.
All the code will now live in MobileFrontend meaning developers
can operate inside one code base.

Depends-On: I857cfe2d9be9fe49c04c860bc234384c787239b2
Change-Id: I2759455cb6d7ddf13798e94452cb74baf502bafe
2017-10-30 19:11:16 +00:00
jdlrobson 12b49a70ad Notification icon should not show NaN for persian Wikipedia
Bug: T172755
Change-Id: I2884c8daed3fe0e0d05c746ec6319956b7426957
2017-10-26 20:27:12 +00:00
jdlrobson 0dd994edda Prepare to break the server side MobileFrontend dependency on Minerva
Changes:
* Minerva now maintains a MinervaUI - a simplified version of
MobileUI that provides iconClass and buttonClass helpers.
* Minerva now maintains its own ResourceLoaderParserMessageModule

Remaining issues:
* Main menu links to '#'
* Unknown dependency errors are thrown due to the missing
JS libraries e.g. mobile.watchstar
thus JS based UI components are unusable e.g. search autocomplete,
and edit button
* Language button navigates to a missing special page without
MobileFrontend (see T104660)

Bug: T169569
Change-Id: I89e2e15faabab73b0cba91afc2f2c5e785edef29
2017-09-27 21:21:59 +00:00
jdlrobson 47546207ad Hygiene: Remove and update references to MobileFrontend
Changes:
* Update docs
* Update browser test artifacts
* Update comments
* Update phpunit test groups
* Update phpunit test namespace
* Update `die` when MobileFrontend not installed
* Remove the migrate script which is no longer needed

Change-Id: I83432b3f7f0bcd07ed08259972b8ff89147104b6
2017-07-19 14:21:50 -07:00
Piotr Miazga 7536ca089a Enable PHPCS and lint checks via composer test
Sniffs that are currently failing are disabled in phpcs.xml.

Additional changes:
* Fix problem in test file

Change-Id: I53642e9d7bc1ef96e359cfe04a8f93dabbc977eb
2017-07-17 22:20:29 +00:00
Piotr Miazga d5461f55a1 Fix failing SkinMinerva unit test
Bug: T170624
Change-Id: I13fff8eba06abad43291e481f32d9eb30c0f031b
2017-07-17 23:39:53 +02:00
Piotr Miazga 9d90df7b0b SkinMinerva testGetContextSpecificModule test might use undefined title
Test scenario for getContextSpecificModules() mocks only Skin->getTitle()
behavior, but while executing isAllowedPageAction() Skin will create a
UserPageHelper with default RequestContext. As RequestContext is not mocked,
$context->getTitle() will return undefined what could lead to tests crash

Changes:
 - instead of mocking SkinMinerva::getTitle() pass test context with injected
title. Other tests will work properly as MediaWikiTestCase::tearDown() always
restes RequestContext to default

Bug: T170624
Change-Id: I872fddf8d9c52a6875bb6c69a12407a8125fba4c
2017-07-17 21:40:34 +02:00
jdlrobson 2cc9516cde Minerva is its own skin
This is programmatic output from python3 scripts/migrate.py

This will result in a Minerva skin dependent on MobileFrontend.

Post merge we will rename message keys to have minerva- prefix

Bug: T166748
Change-Id: Iff1f7e63e796cc5d4a6d2ab0370e0c33248d2fce
2017-07-12 08:12:40 -07:00