WebKit Bugzilla
Attachment 361267 Details for
Bug 194297
: Simplify applyConstraints callbacks
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-194297-20190205193322.patch (text/plain), 20.09 KB, created by
youenn fablet
on 2019-02-05 19:33:23 PST
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
youenn fablet
Created:
2019-02-05 19:33:23 PST
Size:
20.09 KB
patch
obsolete
>Subversion Revision: 240959 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index f6fb51c05f13f20c7b913ce85939db4dd1f6f86a..08103c8f393762fb5b4ef927d66922aae506e6dc 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,32 @@ >+2019-02-05 Youenn Fablet <youenn@apple.com> >+ >+ Simplify applyConstraints callbacks >+ https://bugs.webkit.org/show_bug.cgi?id=194297 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Make use of one callback for both success and failure cases. >+ No changed of behavior. >+ >+ * Modules/mediastream/MediaStreamTrack.cpp: >+ (WebCore::MediaStreamTrack::applyConstraints): >+ * platform/mediastream/MediaStreamTrackPrivate.cpp: >+ (WebCore::MediaStreamTrackPrivate::applyConstraints): >+ * platform/mediastream/MediaStreamTrackPrivate.h: >+ * platform/mediastream/RealtimeMediaSource.cpp: >+ (WebCore::RealtimeMediaSource::applyConstraints): >+ * platform/mediastream/RealtimeMediaSource.h: >+ * platform/mediastream/mac/AVVideoCaptureSource.mm: >+ (WebCore::AVVideoCaptureSource::create): >+ * platform/mediastream/mac/CoreAudioCaptureSource.cpp: >+ (WebCore::CoreAudioCaptureSource::create): >+ * platform/mediastream/gstreamer/MockGStreamerAudioCaptureSource.cpp: >+ (WebCore::MockGStreamerAudioCaptureSource::applyConstraints): >+ * platform/mediastream/gstreamer/MockGStreamerAudioCaptureSource.h: >+ * platform/mediastream/gstreamer/MockGStreamerVideoCaptureSource.cpp: >+ (WebCore::MockGStreamerVideoCaptureSource::applyConstraints): >+ * platform/mediastream/gstreamer/MockGStreamerVideoCaptureSource.h: >+ > 2019-02-04 Fujii Hironori <Hironori.Fujii@sony.com> > > [curl] ASSERTION FAILED: !m_didNotifyResponse || m_multipartHandle >diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog >index 4a0bc095ab2ccefeb2f58b4ce21dd8b4cee2839f..e59f79177965c54693f7e0db8a0a70d65f9a5bca 100644 >--- a/Source/WebKit/ChangeLog >+++ b/Source/WebKit/ChangeLog >@@ -1,3 +1,18 @@ >+2019-02-05 Youenn Fablet <youenn@apple.com> >+ >+ Simplify applyConstraints callbacks >+ https://bugs.webkit.org/show_bug.cgi?id=194297 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * UIProcess/Cocoa/UserMediaCaptureManagerProxy.cpp: >+ (WebKit::UserMediaCaptureManagerProxy::applyConstraints): >+ * WebProcess/cocoa/UserMediaCaptureManager.cpp: >+ (WebKit::UserMediaCaptureManager::Source::applyConstraintsSucceeded): >+ (WebKit::UserMediaCaptureManager::Source::applyConstraintsFailed): >+ (WebKit::UserMediaCaptureManager::applyConstraintsFailed): >+ * WebProcess/cocoa/UserMediaCaptureManager.h: >+ > 2019-02-05 Youenn Fablet <youenn@apple.com> > > Filter out Overconstrainederror.constraint when getUserMedia is not granted >diff --git a/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp b/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp >index 506c145963803a2ceeb8af82bc2a175d3bb5429d..9ca77253628ea4b0f6b4b9b0e7ea0203fb44bd45 100644 >--- a/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp >+++ b/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp >@@ -330,19 +330,17 @@ void MediaStreamTrack::applyConstraints(const Optional<MediaTrackConstraints>& c > { > m_promise = WTFMove(promise); > >- auto weakThis = makeWeakPtr(*this); >- auto failureHandler = [weakThis] (const String& failedConstraint, const String& message) { >- if (!weakThis || !weakThis->m_promise) >+ auto completionHandler = [this, weakThis = makeWeakPtr(*this), constraints](auto&& error) mutable { >+ if (!weakThis || !m_promise) > return; >- weakThis->m_promise->rejectType<IDLInterface<OverconstrainedError>>(OverconstrainedError::create(failedConstraint, message).get()); >- }; >- auto successHandler = [weakThis, constraints] () { >- if (!weakThis || !weakThis->m_promise) >+ if (error) { >+ m_promise->rejectType<IDLInterface<OverconstrainedError>>(OverconstrainedError::create(WTFMove(error->badConstraint), WTFMove(error->message))); > return; >- weakThis->m_promise->resolve(); >- weakThis->m_constraints = constraints.valueOr(MediaTrackConstraints { }); >+ } >+ m_promise->resolve(); >+ m_constraints = constraints.valueOr(MediaTrackConstraints { }); > }; >- m_private->applyConstraints(createMediaConstraints(constraints), WTFMove(successHandler), WTFMove(failureHandler)); >+ m_private->applyConstraints(createMediaConstraints(constraints), WTFMove(completionHandler)); > } > > void MediaStreamTrack::addObserver(Observer& observer) >diff --git a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp >index 95fa95ed4f94b84cd09d6f18bbfdf61d53f588f9..cc54364ce7db42f1fa878864b503aef5fc4b14e6 100644 >--- a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp >+++ b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp >@@ -170,9 +170,9 @@ const RealtimeMediaSourceCapabilities& MediaStreamTrackPrivate::capabilities() c > return m_source->capabilities(); > } > >-void MediaStreamTrackPrivate::applyConstraints(const MediaConstraints& constraints, RealtimeMediaSource::SuccessHandler&& successHandler, RealtimeMediaSource::FailureHandler&& failureHandler) >+void MediaStreamTrackPrivate::applyConstraints(const MediaConstraints& constraints, RealtimeMediaSource::ApplyConstraintsHandler&& completionHandler) > { >- m_source->applyConstraints(constraints, WTFMove(successHandler), WTFMove(failureHandler)); >+ m_source->applyConstraints(constraints, WTFMove(completionHandler)); > } > > AudioSourceProvider* MediaStreamTrackPrivate::audioSourceProvider() >diff --git a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h >index d190971badaa8568278b7c6350f45ce8cc83c900..9c7f03fc677ac02a85d1d68453af568f2386278a 100644 >--- a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h >+++ b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h >@@ -97,7 +97,7 @@ public: > const RealtimeMediaSourceSettings& settings() const; > const RealtimeMediaSourceCapabilities& capabilities() const; > >- void applyConstraints(const MediaConstraints&, RealtimeMediaSource::SuccessHandler&&, RealtimeMediaSource::FailureHandler&&); >+ void applyConstraints(const MediaConstraints&, RealtimeMediaSource::ApplyConstraintsHandler&&); > > AudioSourceProvider* audioSourceProvider(); > >diff --git a/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp b/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp >index 96cf5d99c3bb25e29c2f6bb396c8b5b802679196..2961b65312e81d2c0d18e6fd59f4a442c1e0112b 100644 >--- a/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp >+++ b/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp >@@ -41,6 +41,7 @@ > #include "NotImplemented.h" > #include "RealtimeMediaSourceCapabilities.h" > #include "RealtimeMediaSourceCenter.h" >+#include <wtf/CompletionHandler.h> > #include <wtf/MainThread.h> > #include <wtf/UUID.h> > #include <wtf/text/StringHash.h> >@@ -838,26 +839,22 @@ void RealtimeMediaSource::applyConstraints(const FlattenedConstraint& constraint > commitConfiguration(); > } > >-Optional<std::pair<String, String>> RealtimeMediaSource::applyConstraints(const MediaConstraints& constraints) >+Optional<RealtimeMediaSource::ApplyConstraintsError> RealtimeMediaSource::applyConstraints(const MediaConstraints& constraints) > { > ASSERT(constraints.isValid); > > FlattenedConstraint candidates; > String failedConstraint; > if (!selectSettings(constraints, candidates, failedConstraint, SelectType::ForApplyConstraints)) >- return { { failedConstraint, "Constraint not supported"_s } }; >+ return ApplyConstraintsError { failedConstraint, "Constraint not supported"_s }; > > applyConstraints(candidates); >- return WTF::nullopt; >+ return { }; > } > >-void RealtimeMediaSource::applyConstraints(const MediaConstraints& constraints, SuccessHandler&& successHandler, FailureHandler&& failureHandler) >+void RealtimeMediaSource::applyConstraints(const MediaConstraints& constraints, ApplyConstraintsHandler&& completionHandler) > { >- auto result = applyConstraints(constraints); >- if (!result && successHandler) >- successHandler(); >- else if (result && failureHandler) >- failureHandler(result.value().first, result.value().second); >+ completionHandler(applyConstraints(constraints)); > } > > void RealtimeMediaSource::setSize(const IntSize& size) >diff --git a/Source/WebCore/platform/mediastream/RealtimeMediaSource.h b/Source/WebCore/platform/mediastream/RealtimeMediaSource.h >index 8e462c7e8869ed268a90496eb7f5bde078e9b5f4..b4dc547ff72be4766bf600e9661031babc303b95 100644 >--- a/Source/WebCore/platform/mediastream/RealtimeMediaSource.h >+++ b/Source/WebCore/platform/mediastream/RealtimeMediaSource.h >@@ -150,10 +150,13 @@ public: > virtual const RealtimeMediaSourceCapabilities& capabilities() = 0; > virtual const RealtimeMediaSourceSettings& settings() = 0; > >- using SuccessHandler = WTF::Function<void()>; >- using FailureHandler = WTF::Function<void(const String& badConstraint, const String& errorString)>; >- virtual void applyConstraints(const MediaConstraints&, SuccessHandler&&, FailureHandler&&); >- Optional<std::pair<String, String>> applyConstraints(const MediaConstraints&); >+ struct ApplyConstraintsError { >+ String badConstraint; >+ String message; >+ }; >+ using ApplyConstraintsHandler = CompletionHandler<void(Optional<ApplyConstraintsError>&&)>; >+ virtual void applyConstraints(const MediaConstraints&, ApplyConstraintsHandler&&); >+ Optional<ApplyConstraintsError> applyConstraints(const MediaConstraints&); > > bool supportsConstraints(const MediaConstraints&, String&); > bool supportsConstraint(const MediaConstraint&); >diff --git a/Source/WebCore/platform/mediastream/gstreamer/MockGStreamerAudioCaptureSource.cpp b/Source/WebCore/platform/mediastream/gstreamer/MockGStreamerAudioCaptureSource.cpp >index 5338eb3d93f189007ee5019e113f95edad8fad6b..689aff1ccd7a6aa95e248f6b9bbfa44ca29bcdea 100644 >--- a/Source/WebCore/platform/mediastream/gstreamer/MockGStreamerAudioCaptureSource.cpp >+++ b/Source/WebCore/platform/mediastream/gstreamer/MockGStreamerAudioCaptureSource.cpp >@@ -147,9 +147,9 @@ Optional<std::pair<String, String>> MockGStreamerAudioCaptureSource::applyConstr > return GStreamerAudioCaptureSource::applyConstraints(constraints); > } > >-void MockGStreamerAudioCaptureSource::applyConstraints(const MediaConstraints& constraints, SuccessHandler&& successHandler, FailureHandler&& failureHandler) >+void MockGStreamerAudioCaptureSource::applyConstraints(const MediaConstraints& constraints, ApplyConstraintsHandler&& completionHandler) > { >- m_wrappedSource->applyConstraints(constraints, WTFMove(successHandler), WTFMove(failureHandler)); >+ m_wrappedSource->applyConstraints(constraints, WTFMove(completionHandler)); > } > > MockGStreamerAudioCaptureSource::MockGStreamerAudioCaptureSource(String&& deviceID, String&& name, String&& hashSalt) >diff --git a/Source/WebCore/platform/mediastream/gstreamer/MockGStreamerAudioCaptureSource.h b/Source/WebCore/platform/mediastream/gstreamer/MockGStreamerAudioCaptureSource.h >index f332530accb256f62903d69592827c1630626b9c..f999bc25ae4b00585bb9973608554543ec5175d0 100644 >--- a/Source/WebCore/platform/mediastream/gstreamer/MockGStreamerAudioCaptureSource.h >+++ b/Source/WebCore/platform/mediastream/gstreamer/MockGStreamerAudioCaptureSource.h >@@ -32,7 +32,7 @@ public: > MockGStreamerAudioCaptureSource(String&& deviceID, String&& name, String&& hashSalt); > ~MockGStreamerAudioCaptureSource(); > Optional<std::pair<String, String>> applyConstraints(const MediaConstraints&); >- void applyConstraints(const MediaConstraints&, SuccessHandler&&, FailureHandler&&) final; >+ void applyConstraints(const MediaConstraints&, ApplyConstraintsHandler&&) final; > > private: > void stopProducingData() final; >diff --git a/Source/WebCore/platform/mediastream/gstreamer/MockGStreamerVideoCaptureSource.cpp b/Source/WebCore/platform/mediastream/gstreamer/MockGStreamerVideoCaptureSource.cpp >index 0d62e4b91c6f4975966ea2cba62dcb9fa0360ca0..6ed66246d257c4d3c4fb8e654d84eb45d0d8ab37 100644 >--- a/Source/WebCore/platform/mediastream/gstreamer/MockGStreamerVideoCaptureSource.cpp >+++ b/Source/WebCore/platform/mediastream/gstreamer/MockGStreamerVideoCaptureSource.cpp >@@ -113,9 +113,9 @@ Optional<std::pair<String, String>> MockGStreamerVideoCaptureSource::applyConstr > return GStreamerVideoCaptureSource::applyConstraints(constraints); > } > >-void MockGStreamerVideoCaptureSource::applyConstraints(const MediaConstraints& constraints, SuccessHandler&& successHandler, FailureHandler&& failureHandler) >+void MockGStreamerVideoCaptureSource::applyConstraints(const MediaConstraints& constraints, ApplyConstraintsHandler&& completionHandler) > { >- m_wrappedSource->applyConstraints(constraints, WTFMove(successHandler), WTFMove(failureHandler)); >+ m_wrappedSource->applyConstraints(constraints, WTFMove(completionHandler)); > } > > const RealtimeMediaSourceSettings& MockGStreamerVideoCaptureSource::settings() >diff --git a/Source/WebCore/platform/mediastream/gstreamer/MockGStreamerVideoCaptureSource.h b/Source/WebCore/platform/mediastream/gstreamer/MockGStreamerVideoCaptureSource.h >index 481459d511f9a37c9f1f5b75ef45872171cad276..eedee54d088c205b84d880d6c8253356f8f0e7a0 100644 >--- a/Source/WebCore/platform/mediastream/gstreamer/MockGStreamerVideoCaptureSource.h >+++ b/Source/WebCore/platform/mediastream/gstreamer/MockGStreamerVideoCaptureSource.h >@@ -37,7 +37,7 @@ public: > MockGStreamerVideoCaptureSource(String&& deviceID, String&& name, String&& hashSalt); > ~MockGStreamerVideoCaptureSource(); > Optional<std::pair<String, String>> applyConstraints(const MediaConstraints&); >- void applyConstraints(const MediaConstraints&, SuccessHandler&&, FailureHandler&&) final; >+ void applyConstraints(const MediaConstraints&, ApplyConstraintsHandler&&) final; > > private: > void stopProducingData() final; >diff --git a/Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.mm b/Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.mm >index da78d49c6438b3a2e09ab42b8a14e343dc34d4b9..9a661c793e40bb11afde50634a5630264e0554b3 100644 >--- a/Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.mm >+++ b/Source/WebCore/platform/mediastream/mac/AVVideoCaptureSource.mm >@@ -164,7 +164,7 @@ CaptureSourceOrError AVVideoCaptureSource::create(String&& id, String&& hashSalt > if (constraints) { > auto result = source->applyConstraints(*constraints); > if (result) >- return WTFMove(result.value().first); >+ return WTFMove(result.value().badConstraint); > } > > return CaptureSourceOrError(WTFMove(source)); >diff --git a/Source/WebCore/platform/mediastream/mac/CoreAudioCaptureSource.cpp b/Source/WebCore/platform/mediastream/mac/CoreAudioCaptureSource.cpp >index dd13a520e7e6570a7a3fbb1675cd64bc840b152d..e8c646e7fb4062d64e7a574d39a77f5a06afe091 100644 >--- a/Source/WebCore/platform/mediastream/mac/CoreAudioCaptureSource.cpp >+++ b/Source/WebCore/platform/mediastream/mac/CoreAudioCaptureSource.cpp >@@ -742,7 +742,7 @@ CaptureSourceOrError CoreAudioCaptureSource::create(String&& deviceID, String&& > if (constraints) { > auto result = source->applyConstraints(*constraints); > if (result) >- return WTFMove(result.value().first); >+ return WTFMove(result->badConstraint); > } > return CaptureSourceOrError(WTFMove(source)); > } >diff --git a/Source/WebKit/UIProcess/Cocoa/UserMediaCaptureManagerProxy.cpp b/Source/WebKit/UIProcess/Cocoa/UserMediaCaptureManagerProxy.cpp >index 056d5c342dd05b529c6f26a129b7207fe41343f7..c51cfea5dcc82a356c4e0a9bb0c0cacf1dba6ce6 100644 >--- a/Source/WebKit/UIProcess/Cocoa/UserMediaCaptureManagerProxy.cpp >+++ b/Source/WebKit/UIProcess/Cocoa/UserMediaCaptureManagerProxy.cpp >@@ -205,7 +205,7 @@ void UserMediaCaptureManagerProxy::applyConstraints(uint64_t id, const WebCore:: > if (!result) > m_process.send(Messages::UserMediaCaptureManager::ApplyConstraintsSucceeded(id, source.settings()), 0); > else >- m_process.send(Messages::UserMediaCaptureManager::ApplyConstraintsFailed(id, result.value().first, result.value().second), 0); >+ m_process.send(Messages::UserMediaCaptureManager::ApplyConstraintsFailed(id, result->badConstraint, result->message), 0); > } > > } >diff --git a/Source/WebKit/WebProcess/cocoa/UserMediaCaptureManager.cpp b/Source/WebKit/WebProcess/cocoa/UserMediaCaptureManager.cpp >index 45b901e8ac4d908dcafbda016e53adcff8b7eaea..665253c79bd0ef6c4640cac06f8d829c6e8f84bc 100644 >--- a/Source/WebKit/WebProcess/cocoa/UserMediaCaptureManager.cpp >+++ b/Source/WebKit/WebProcess/cocoa/UserMediaCaptureManager.cpp >@@ -165,15 +165,16 @@ public: > > void applyConstraintsSucceeded(const WebCore::RealtimeMediaSourceSettings& settings) > { >- auto callbacks = m_pendingApplyConstraintsCallbacks.takeFirst(); > setSettings(WebCore::RealtimeMediaSourceSettings(settings)); >- callbacks.successHandler(); >+ >+ auto callback = m_pendingApplyConstraintsCallbacks.takeFirst(); >+ callback({ }); > } > >- void applyConstraintsFailed(const String& failedConstraint, const String& errorMessage) >+ void applyConstraintsFailed(String&& failedConstraint, String&& errorMessage) > { >- auto callbacks = m_pendingApplyConstraintsCallbacks.takeFirst(); >- callbacks.failureHandler(failedConstraint, errorMessage); >+ auto callback = m_pendingApplyConstraintsCallbacks.takeFirst(); >+ callback(ApplyConstraintsError { WTFMove(failedConstraint), WTFMove(errorMessage) }); > } > > private: >@@ -186,9 +187,10 @@ private: > void beginConfiguration() final { } > void commitConfiguration() final { } > >- void applyConstraints(const WebCore::MediaConstraints& constraints, SuccessHandler&& successHandler, FailureHandler&& failureHandler) final { >+ void applyConstraints(const WebCore::MediaConstraints& constraints, ApplyConstraintsHandler&& completionHandler) final >+ { > m_manager.applyConstraints(m_id, constraints); >- m_pendingApplyConstraintsCallbacks.append({ WTFMove(successHandler), WTFMove(failureHandler)}); >+ m_pendingApplyConstraintsCallbacks.append(WTFMove(completionHandler)); > } > > uint64_t m_id; >@@ -202,11 +204,7 @@ private: > std::unique_ptr<ImageTransferSessionVT> m_imageTransferSession; > CaptureDevice::DeviceType m_deviceType { CaptureDevice::DeviceType::Unknown }; > >- struct ApplyConstraintsCallback { >- SuccessHandler successHandler; >- FailureHandler failureHandler; >- }; >- Deque<ApplyConstraintsCallback> m_pendingApplyConstraintsCallbacks; >+ Deque<ApplyConstraintsHandler> m_pendingApplyConstraintsCallbacks; > }; > > UserMediaCaptureManager::UserMediaCaptureManager(WebProcess& process) >@@ -352,11 +350,11 @@ void UserMediaCaptureManager::applyConstraintsSucceeded(uint64_t id, const WebCo > source.applyConstraintsSucceeded(settings); > } > >-void UserMediaCaptureManager::applyConstraintsFailed(uint64_t id, const String& failedConstraint, const String& message) >+void UserMediaCaptureManager::applyConstraintsFailed(uint64_t id, String&& failedConstraint, String&& message) > { > ASSERT(m_sources.contains(id)); > auto& source = *m_sources.get(id); >- source.applyConstraintsFailed(failedConstraint, message); >+ source.applyConstraintsFailed(WTFMove(failedConstraint), WTFMove(message)); > } > > } >diff --git a/Source/WebKit/WebProcess/cocoa/UserMediaCaptureManager.h b/Source/WebKit/WebProcess/cocoa/UserMediaCaptureManager.h >index ad1be7ccedd6ae4308fc4fef028c377b4a9e0bd0..fcfca9af62dbdc73c477c71969fa217e045da16d 100644 >--- a/Source/WebKit/WebProcess/cocoa/UserMediaCaptureManager.h >+++ b/Source/WebKit/WebProcess/cocoa/UserMediaCaptureManager.h >@@ -98,7 +98,7 @@ private: > void setMuted(uint64_t, bool); > void applyConstraints(uint64_t, const WebCore::MediaConstraints&); > void applyConstraintsSucceeded(uint64_t, const WebCore::RealtimeMediaSourceSettings&); >- void applyConstraintsFailed(uint64_t, const String&, const String&); >+ void applyConstraintsFailed(uint64_t, String&&, String&&); > > class Source; > friend class Source;
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 194297
:
361206
|
361267
|
361296
|
361297
|
361299