WebKit Bugzilla
Attachment 346518 Details for
Bug 186751
: Remove the SVG elements' attributes macros
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Remove SVG macros from SVGFilterElement
186751-68.patch (text/plain), 18.36 KB, created by
Said Abou-Hallawa
on 2018-08-03 12:36:20 PDT
(
hide
)
Description:
Remove SVG macros from SVGFilterElement
Filename:
MIME Type:
Creator:
Said Abou-Hallawa
Created:
2018-08-03 12:36:20 PDT
Size:
18.36 KB
patch
obsolete
>diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index ff06d864c33..0829152ea59 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,31 @@ >+2018-08-02 Said Abou-Hallawa <sabouhallawa@apple.com> >+ >+ [68] Remove the SVG elements' attributes macros >+ https://bugs.webkit.org/show_bug.cgi?id=186751 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Remove SVG macros from SVGFilterElement. >+ >+ -- Add helper functions to check if an attribute is a length attribute. >+ >+ * svg/SVGFilterElement.cpp: >+ (WebCore::SVGFilterElement::SVGFilterElement): >+ (WebCore::SVGFilterElement::registerAttributes): >+ (WebCore::SVGFilterElement::parseAttribute): >+ (WebCore::SVGFilterElement::isSupportedAttribute): Deleted. >+ (WebCore::SVGFilterElement::svgAttributeChanged): Deleted. >+ (WebCore::SVGFilterElement::childrenChanged): Deleted. >+ (WebCore::SVGFilterElement::createElementRenderer): Deleted. >+ (WebCore::SVGFilterElement::childShouldCreateRenderer const): Deleted. >+ * svg/SVGFilterElement.h: >+ * svg/properties/SVGAttributeAccessor.h: >+ (WebCore::SVGAttributeAccessor::isAnimatedLengthAttribute const): >+ * svg/properties/SVGAttributeOwnerProxy.h: >+ (WebCore::SVGAttributeOwnerProxyImpl::isAnimatedLengthAttribute): >+ * svg/properties/SVGAttributeRegistry.h: Added. >+ (WebCore::SVGAttributeRegistry::isAnimatedLengthAttribute const): >+ > 2018-08-01 Said Abou-Hallawa <sabouhallawa@apple.com> > > [67] Remove the SVG elements' attributes macros >diff --git a/Source/WebCore/svg/SVGFELightElement.cpp b/Source/WebCore/svg/SVGFELightElement.cpp >index 24191fbb1b0..891fedd98d5 100644 >--- a/Source/WebCore/svg/SVGFELightElement.cpp >+++ b/Source/WebCore/svg/SVGFELightElement.cpp >@@ -129,7 +129,7 @@ void SVGFELightElement::parseAttribute(const QualifiedName& name, const AtomicSt > > void SVGFELightElement::svgAttributeChanged(const QualifiedName& attrName) > { >- if (isKnownAttribute(attrName)) { >+ if (isKnownAttribute(attrName)) { > auto parent = makeRefPtr(parentElement()); > if (!parent) > return; >diff --git a/Source/WebCore/svg/SVGFilterElement.cpp b/Source/WebCore/svg/SVGFilterElement.cpp >index f648ba96a4f..f1b0abe90f2 100644 >--- a/Source/WebCore/svg/SVGFilterElement.cpp >+++ b/Source/WebCore/svg/SVGFilterElement.cpp >@@ -5,6 +5,7 @@ > * Copyright (C) 2009 Dirk Schulze <krit@webkit.org> > * Copyright (C) Research In Motion Limited 2010. All rights reserved. > * Copyright (C) 2014 Adobe Systems Incorporated. All rights reserved. >+ * Copyright (C) 2018 Apple Inc. All rights reserved. > * > * This library is free software; you can redistribute it and/or > * modify it under the terms of the GNU Library General Public >@@ -38,44 +39,15 @@ namespace WebCore { > > WTF_MAKE_ISO_ALLOCATED_IMPL(SVGFilterElement); > >-// Animated property definitions >-DEFINE_ANIMATED_ENUMERATION(SVGFilterElement, SVGNames::filterUnitsAttr, FilterUnits, filterUnits, SVGUnitTypes::SVGUnitType) >-DEFINE_ANIMATED_ENUMERATION(SVGFilterElement, SVGNames::primitiveUnitsAttr, PrimitiveUnits, primitiveUnits, SVGUnitTypes::SVGUnitType) >-DEFINE_ANIMATED_LENGTH(SVGFilterElement, SVGNames::xAttr, X, x) >-DEFINE_ANIMATED_LENGTH(SVGFilterElement, SVGNames::yAttr, Y, y) >-DEFINE_ANIMATED_LENGTH(SVGFilterElement, SVGNames::widthAttr, Width, width) >-DEFINE_ANIMATED_LENGTH(SVGFilterElement, SVGNames::heightAttr, Height, height) >-DEFINE_ANIMATED_INTEGER_MULTIPLE_WRAPPERS(SVGFilterElement, SVGNames::filterResAttr, filterResXIdentifier(), FilterResX, filterResX) >-DEFINE_ANIMATED_INTEGER_MULTIPLE_WRAPPERS(SVGFilterElement, SVGNames::filterResAttr, filterResYIdentifier(), FilterResY, filterResY) >-DEFINE_ANIMATED_STRING(SVGFilterElement, XLinkNames::hrefAttr, Href, href) >-DEFINE_ANIMATED_BOOLEAN(SVGFilterElement, SVGNames::externalResourcesRequiredAttr, ExternalResourcesRequired, externalResourcesRequired) >- >-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGFilterElement) >- REGISTER_LOCAL_ANIMATED_PROPERTY(filterUnits) >- REGISTER_LOCAL_ANIMATED_PROPERTY(primitiveUnits) >- REGISTER_LOCAL_ANIMATED_PROPERTY(x) >- REGISTER_LOCAL_ANIMATED_PROPERTY(y) >- REGISTER_LOCAL_ANIMATED_PROPERTY(width) >- REGISTER_LOCAL_ANIMATED_PROPERTY(height) >- REGISTER_LOCAL_ANIMATED_PROPERTY(filterResX) >- REGISTER_LOCAL_ANIMATED_PROPERTY(filterResY) >- REGISTER_LOCAL_ANIMATED_PROPERTY(href) >- REGISTER_LOCAL_ANIMATED_PROPERTY(externalResourcesRequired) >-END_REGISTER_ANIMATED_PROPERTIES >- > inline SVGFilterElement::SVGFilterElement(const QualifiedName& tagName, Document& document) > : SVGElement(tagName, document) >- , m_filterUnits(SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) >- , m_primitiveUnits(SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE) >- , m_x(LengthModeWidth, "-10%") >- , m_y(LengthModeHeight, "-10%") >- , m_width(LengthModeWidth, "120%") >- , m_height(LengthModeHeight, "120%") >+ , SVGURIReference(*this) >+ , SVGExternalResourcesRequired(*this) > { > // Spec: If the x/y attribute is not specified, the effect is as if a value of "-10%" were specified. > // Spec: If the width/height attribute is not specified, the effect is as if a value of "120%" were specified. > ASSERT(hasTagName(SVGNames::filterTag)); >- registerAnimatedPropertiesForSVGFilterElement(); >+ registerAttributes(); > } > > Ref<SVGFilterElement> SVGFilterElement::create(const QualifiedName& tagName, Document& document) >@@ -97,32 +69,27 @@ const AtomicString& SVGFilterElement::filterResYIdentifier() > > void SVGFilterElement::setFilterRes(unsigned filterResX, unsigned filterResY) > { >- setFilterResXBaseValue(filterResX); >- setFilterResYBaseValue(filterResY); >+ m_filterResX.setValue(filterResX); >+ m_filterResY.setValue(filterResY); > > if (RenderObject* object = renderer()) > object->setNeedsLayout(); > } > >-bool SVGFilterElement::isSupportedAttribute(const QualifiedName& attrName) >+void SVGFilterElement::registerAttributes() > { >- static const auto supportedAttributes = makeNeverDestroyed([] { >- HashSet<QualifiedName> set; >- SVGURIReference::addSupportedAttributes(set); >- SVGLangSpace::addSupportedAttributes(set); >- SVGExternalResourcesRequired::addSupportedAttributes(set); >- set.add({ >- SVGNames::filterUnitsAttr.get(), >- SVGNames::primitiveUnitsAttr.get(), >- SVGNames::xAttr.get(), >- SVGNames::yAttr.get(), >- SVGNames::widthAttr.get(), >- SVGNames::heightAttr.get(), >- SVGNames::filterResAttr.get(), >- }); >- return set; >- }()); >- return supportedAttributes.get().contains<SVGAttributeHashTranslator>(attrName); >+ auto& registry = attributeRegistry(); >+ if (!registry.isEmpty()) >+ return; >+ registry.registerAttribute<SVGNames::filterUnitsAttr, SVGUnitTypes::SVGUnitType, &SVGFilterElement::m_filterUnits>(); >+ registry.registerAttribute<SVGNames::primitiveUnitsAttr, SVGUnitTypes::SVGUnitType, &SVGFilterElement::m_primitiveUnits>(); >+ registry.registerAttribute<SVGNames::xAttr, &SVGFilterElement::m_x>(); >+ registry.registerAttribute<SVGNames::yAttr, &SVGFilterElement::m_y>(); >+ registry.registerAttribute<SVGNames::widthAttr, &SVGFilterElement::m_width>(); >+ registry.registerAttribute<SVGNames::heightAttr, &SVGFilterElement::m_height>(); >+ registry.registerAttribute<SVGNames::filterResAttr, >+ &SVGFilterElement::filterResXIdentifier, &SVGFilterElement::m_filterResX, >+ &SVGFilterElement::filterResYIdentifier, &SVGFilterElement::m_filterResY>(); > } > > void SVGFilterElement::parseAttribute(const QualifiedName& name, const AtomicString& value) >@@ -132,24 +99,24 @@ void SVGFilterElement::parseAttribute(const QualifiedName& name, const AtomicStr > if (name == SVGNames::filterUnitsAttr) { > SVGUnitTypes::SVGUnitType propertyValue = SVGPropertyTraits<SVGUnitTypes::SVGUnitType>::fromString(value); > if (propertyValue > 0) >- setFilterUnitsBaseValue(propertyValue); >+ m_filterUnits.setValue(propertyValue); > } else if (name == SVGNames::primitiveUnitsAttr) { > SVGUnitTypes::SVGUnitType propertyValue = SVGPropertyTraits<SVGUnitTypes::SVGUnitType>::fromString(value); > if (propertyValue > 0) >- setPrimitiveUnitsBaseValue(propertyValue); >+ m_primitiveUnits.setValue((propertyValue); > } else if (name == SVGNames::xAttr) >- setXBaseValue(SVGLengthValue::construct(LengthModeWidth, value, parseError)); >+ m_x.setValue(SVGLengthValue::construct(LengthModeWidth, value, parseError)); > else if (name == SVGNames::yAttr) >- setYBaseValue(SVGLengthValue::construct(LengthModeHeight, value, parseError)); >+ m_y.setValue(SVGLengthValue::construct(LengthModeHeight, value, parseError)); > else if (name == SVGNames::widthAttr) >- setWidthBaseValue(SVGLengthValue::construct(LengthModeWidth, value, parseError)); >+ m_width.setValue(SVGLengthValue::construct(LengthModeWidth, value, parseError)); > else if (name == SVGNames::heightAttr) >- setHeightBaseValue(SVGLengthValue::construct(LengthModeHeight, value, parseError)); >+ m_height.setValue(SVGLengthValue::construct(LengthModeHeight, value, parseError)); > else if (name == SVGNames::filterResAttr) { > float x, y; > if (parseNumberOptionalNumber(value, x, y)) { >- setFilterResXBaseValue(x); >- setFilterResYBaseValue(y); >+ m_filterResX.setValue(x); >+ m_filterResY.setValue(y); > } > } > >@@ -162,20 +129,19 @@ void SVGFilterElement::parseAttribute(const QualifiedName& name, const AtomicStr > > void SVGFilterElement::svgAttributeChanged(const QualifiedName& attrName) > { >- if (!isSupportedAttribute(attrName)) { >- SVGElement::svgAttributeChanged(attrName); >+ if (isAnimatedLengthAttribute(attrName)) { >+ InstanceInvalidationGuard guard(*this); >+ invalidateSVGPresentationAttributeStyle(); > return; > } > >- InstanceInvalidationGuard guard(*this); >- >- if (attrName == SVGNames::xAttr || attrName == SVGNames::yAttr || attrName == SVGNames::widthAttr || attrName == SVGNames::heightAttr) { >- invalidateSVGPresentationAttributeStyle(); >+ if (isKnownAttribute(attrName) || SVGURIReference::isKnownAttribute(attrName) || SVGExternalResourcesRequired::isKnownAttribute(attrName)) { >+ if (auto* renderer = this->renderer()) >+ renderer->setNeedsLayout(); > return; > } > >- if (auto* renderer = this->renderer()) >- renderer->setNeedsLayout(); >+ SVGElement::svgAttributeChanged(attrName); > } > > void SVGFilterElement::childrenChanged(const ChildChange& change) >diff --git a/Source/WebCore/svg/SVGFilterElement.h b/Source/WebCore/svg/SVGFilterElement.h >index 725fef7decf..48d1f4fd96d 100644 >--- a/Source/WebCore/svg/SVGFilterElement.h >+++ b/Source/WebCore/svg/SVGFilterElement.h >@@ -3,6 +3,7 @@ > * Copyright (C) 2004, 2005, 2006 Rob Buis <buis@kde.org> > * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com> > * Copyright (C) Research In Motion Limited 2010. All rights reserved. >+ * Copyright (C) 2018 Apple Inc. All rights reserved. > * > * This library is free software; you can redistribute it and/or > * modify it under the terms of the GNU Library General Public >@@ -22,7 +23,6 @@ > > #pragma once > >-#include "SVGAnimatedBoolean.h" > #include "SVGAnimatedEnumeration.h" > #include "SVGAnimatedInteger.h" > #include "SVGAnimatedLength.h" >@@ -40,16 +40,40 @@ public: > > void setFilterRes(unsigned filterResX, unsigned filterResY); > >+ SVGUnitTypes::SVGUnitType filterUnits() const { return m_filterUnits.currentValue(); } >+ SVGUnitTypes::SVGUnitType primitiveUnits() const { return m_primitiveUnits.currentValue(); } >+ const SVGLengthValue& x() const { return m_x.currentValue(); } >+ const SVGLengthValue& y() const { return m_y.currentValue(); } >+ const SVGLengthValue& width() const { return m_width.currentValue(); } >+ const SVGLengthValue& height() const { return m_height.currentValue(); } >+ int filterResX() const { return m_filterResX.currentValue(); } >+ int filterResY() const { return m_filterResY.currentValue(); } >+ >+ RefPtr<SVGAnimatedEnumeration> filterUnitsAnimated() { return m_filterUnits.animatedProperty(); } >+ RefPtr<SVGAnimatedEnumeration> primitiveUnitsAnimated() { return m_primitiveUnits.animatedProperty(); } >+ RefPtr<SVGAnimatedLength> xAnimated() { return m_x.animatedProperty(); } >+ RefPtr<SVGAnimatedLength> yAnimated() { return m_y.animatedProperty(); } >+ RefPtr<SVGAnimatedLength> widthAnimated() { return m_width.animatedProperty(); } >+ RefPtr<SVGAnimatedLength> heightAnimated() { return m_height.animatedProperty(); } >+ RefPtr<SVGAnimatedInteger> filterResXAnimated() { return m_filterResX.animatedProperty(); } >+ RefPtr<SVGAnimatedInteger> filterResYAnimated() { return m_filterResY.animatedProperty(); } >+ > private: > SVGFilterElement(const QualifiedName&, Document&); > >- bool needsPendingResourceHandling() const final { return false; } >+ using AttributeOwnerProxy = SVGAttributeOwnerProxyImpl<SVGFilterElement, SVGElement, SVGURIReference, SVGExternalResourcesRequired>; >+ static AttributeOwnerProxy::AttributeRegistry& attributeRegistry() { return AttributeOwnerProxy::attributeRegistry(); } >+ static bool isKnownAttribute(const QualifiedName& attributeName) { return AttributeOwnerProxy::isKnownAttribute(attributeName); } >+ static bool isAnimatedLengthAttribute(const QualifiedName& attributeName) { return AttributeOwnerProxy::isAnimatedLengthAttribute(attributeName); } >+ static void registerAttributes(); > >- static bool isSupportedAttribute(const QualifiedName&); >+ const SVGAttributeOwnerProxy& attributeOwnerProxy() const final { return m_attributeOwnerProxy; } > void parseAttribute(const QualifiedName&, const AtomicString&) final; > void svgAttributeChanged(const QualifiedName&) final; > void childrenChanged(const ChildChange&) final; > >+ bool needsPendingResourceHandling() const final { return false; } >+ > RenderPtr<RenderElement> createElementRenderer(RenderStyle&&, const RenderTreePosition&) final; > bool childShouldCreateRenderer(const Node&) const final; > >@@ -58,18 +82,15 @@ private: > static const AtomicString& filterResXIdentifier(); > static const AtomicString& filterResYIdentifier(); > >- BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGFilterElement) >- DECLARE_ANIMATED_ENUMERATION(FilterUnits, filterUnits, SVGUnitTypes::SVGUnitType) >- DECLARE_ANIMATED_ENUMERATION(PrimitiveUnits, primitiveUnits, SVGUnitTypes::SVGUnitType) >- DECLARE_ANIMATED_LENGTH(X, x) >- DECLARE_ANIMATED_LENGTH(Y, y) >- DECLARE_ANIMATED_LENGTH(Width, width) >- DECLARE_ANIMATED_LENGTH(Height, height) >- DECLARE_ANIMATED_INTEGER(FilterResX, filterResX) >- DECLARE_ANIMATED_INTEGER(FilterResY, filterResY) >- DECLARE_ANIMATED_STRING_OVERRIDE(Href, href) >- DECLARE_ANIMATED_BOOLEAN_OVERRIDE(ExternalResourcesRequired, externalResourcesRequired) >- END_DECLARE_ANIMATED_PROPERTIES >+ AttributeOwnerProxy m_attributeOwnerProxy { *this }; >+ SVGAnimatedEnumerationAttribute<SVGUnitTypes::SVGUnitType> m_filterUnits { m_attributeOwnerProxy, SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX }; >+ SVGAnimatedEnumerationAttribute<SVGUnitTypes::SVGUnitType> m_primitiveUnits { m_attributeOwnerProxy, SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE }; >+ SVGAnimatedLengthAttribute m_x { m_attributeOwnerProxy, LengthModeWidth, "-10%" }; >+ SVGAnimatedLengthAttribute m_y { m_attributeOwnerProxy, LengthModeHeight, "-10%" }; >+ SVGAnimatedLengthAttribute m_width { m_attributeOwnerProxy, LengthModeWidth, "120%" }; >+ SVGAnimatedLengthAttribute m_height { m_attributeOwnerProxy, LengthModeHeight, "120%" }; >+ SVGAnimatedIntegerAttribute m_filterResX { m_attributeOwnerProxy }; >+ SVGAnimatedIntegerAttribute m_filterResY { m_attributeOwnerProxy }; > }; > > } // namespace WebCore >diff --git a/Source/WebCore/svg/properties/SVGAttributeAccessor.h b/Source/WebCore/svg/properties/SVGAttributeAccessor.h >index 6fe63220fd0..832bf2a20fd 100644 >--- a/Source/WebCore/svg/properties/SVGAttributeAccessor.h >+++ b/Source/WebCore/svg/properties/SVGAttributeAccessor.h >@@ -55,6 +55,7 @@ public: > virtual bool isMatched(const OwnerType&, const SVGAttribute&) const = 0; > virtual void synchronizeProperty(OwnerType&, Element&) const = 0; > >+ virtual bool isAnimatedLengthAttribute() const { return false; } > virtual AnimatedPropertyType animatedType() const { return AnimatedUnknown; } > virtual Vector<AnimatedPropertyType> animatedTypes() const { return { animatedType() }; } > >@@ -146,6 +147,7 @@ protected: > return SVGAnimatedProperty::lookupAnimatedProperty(element, identifier); > } > >+ bool isAnimatedLengthAttribute() const override { return std::is_same<PropertyType, SVGLengthValue>::value; } > AnimatedPropertyType animatedType() const override { return type; } > > RefPtr<SVGAnimatedProperty> lookupOrCreateAnimatedProperty(OwnerType& owner, SVGElement& element, const SVGAttribute& attribute, AnimatedPropertyState animatedState) const override >diff --git a/Source/WebCore/svg/properties/SVGAttributeOwnerProxy.h b/Source/WebCore/svg/properties/SVGAttributeOwnerProxy.h >index 8b357e3d695..177bfebaeb4 100644 >--- a/Source/WebCore/svg/properties/SVGAttributeOwnerProxy.h >+++ b/Source/WebCore/svg/properties/SVGAttributeOwnerProxy.h >@@ -81,6 +81,11 @@ public: > return attributeRegistry().isKnownAttribute(attributeName); > } > >+ static bool isAnimatedLengthAttribute(const QualifiedName& attributeName) >+ { >+ return attributeRegistry().isAnimatedLengthAttribute(attributeName); >+ } >+ > private: > void synchronizeAttributes() const override > { >diff --git a/Source/WebCore/svg/properties/SVGAttributeRegistry.h b/Source/WebCore/svg/properties/SVGAttributeRegistry.h >index 9deff3b4210..17fe2a423c9 100644 >--- a/Source/WebCore/svg/properties/SVGAttributeRegistry.h >+++ b/Source/WebCore/svg/properties/SVGAttributeRegistry.h >@@ -166,6 +166,13 @@ public: > return it != m_map.end(); > } > >+ bool isAnimatedLengthAttribute(const QualifiedName& attributeName) const >+ { >+ if (const auto* attributeAccessor = findAttributeAccessor(attributeName)) >+ return attributeAccessor->isAnimatedLengthAttribute(); >+ return false; >+ } >+ > Vector<AnimatedPropertyType> animatedTypes(const QualifiedName& attributeName) const > { > // If this registry has an accessor for attributeName, return animatedTypes() of this accessor.
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 186751
:
342916
|
342917
|
342985
|
343001
|
343114
|
343123
|
343124
|
343127
|
343129
|
343162
|
343167
|
343169
|
343171
|
343174
|
343213
|
343217
|
343327
|
343335
|
343338
|
343339
|
343343
|
343415
|
343979
|
343989
|
344002
|
344513
|
344516
|
344523
|
344534
|
344536
|
344988
|
344990
|
346097
|
346103
|
346124
|
346129
|
346177
|
346179
|
346180
|
346182
|
346185
|
346188
|
346190
|
346192
|
346193
|
346197
|
346199
|
346201
|
346202
|
346203
|
346204
|
346205
|
346206
|
346207
|
346211
|
346212
|
346217
|
346224
|
346230
|
346233
|
346241
|
346244
|
346245
|
346315
|
346316
|
346317
|
346318
|
346319
|
346320
|
346322
|
346323
|
346324
|
346325
|
346326
|
346327
|
346328
|
346329
|
346330
|
346331
|
346332
|
346333
|
346334
|
346335
|
346336
|
346337
|
346338
|
346339
|
346340
|
346341
|
346342
|
346343
|
346344
|
346345
|
346346
|
346347
|
346348
|
346349
|
346350
|
346518
|
346519
|
346520
|
346521
|
346522
|
346524
|
346525
|
346526
|
346527
|
346528
|
346529
|
346530
|
346531
|
346532
|
346533
|
346534
|
346535
|
346536
|
346537
|
346538
|
346539
|
346540
|
346541
|
346545
|
346546
|
346549
|
346551
|
346552
|
346601
|
346602
|
346611
|
346636
|
346642