| Index: Source/core/animation/KeyframeEffectModelTest.cpp
|
| diff --git a/Source/core/animation/KeyframeEffectModelTest.cpp b/Source/core/animation/KeyframeEffectModelTest.cpp
|
| index 1a44659fbb403c3460fdbeb15b0f82a0c19451ef..9f0e2a42907d7b4efe66ea429eab73e83e67576c 100644
|
| --- a/Source/core/animation/KeyframeEffectModelTest.cpp
|
| +++ b/Source/core/animation/KeyframeEffectModelTest.cpp
|
| @@ -62,8 +62,17 @@ KeyframeEffectModel::KeyframeVector keyframesAtZeroAndOne(AnimatableValue* zeroV
|
| return keyframes;
|
| }
|
|
|
| -void expectDoubleValue(double expectedValue, PassRefPtr<AnimatableValue> value)
|
| +void expectProperty(CSSPropertyID property, PassRefPtr<Interpolation> interpolationValue)
|
| {
|
| + LegacyStyleInterpolation *interpolation = static_cast<LegacyStyleInterpolation *>(interpolationValue.get());
|
| + ASSERT_EQ(property, interpolation->id());
|
| +}
|
| +
|
| +void expectDoubleValue(double expectedValue, PassRefPtr<Interpolation> interpolationValue)
|
| +{
|
| + LegacyStyleInterpolation *interpolation = static_cast<LegacyStyleInterpolation *>(interpolationValue.get());
|
| + RefPtr<AnimatableValue> value = interpolation->currentValue();
|
| +
|
| ASSERT_TRUE(value->isLength() || value->isUnknown());
|
|
|
| double actualValue;
|
| @@ -75,12 +84,12 @@ void expectDoubleValue(double expectedValue, PassRefPtr<AnimatableValue> value)
|
| EXPECT_FLOAT_EQ(static_cast<float>(expectedValue), actualValue);
|
| }
|
|
|
| -const AnimationEffect::CompositableValue* findValue(const AnimationEffect::CompositableValueList& values, CSSPropertyID id)
|
| +Interpolation* findValue(Vector<RefPtr<Interpolation> >& values, CSSPropertyID id)
|
| {
|
| for (size_t i = 0; i < values.size(); ++i) {
|
| - const std::pair<CSSPropertyID, RefPtr<AnimationEffect::CompositableValue> >& value = values.at(i);
|
| - if (value.first == id)
|
| - return value.second.get();
|
| + LegacyStyleInterpolation *value = static_cast<LegacyStyleInterpolation *>(values.at(i).get());
|
| + if (value->id() == id)
|
| + return value;
|
| }
|
| return 0;
|
| }
|
| @@ -90,10 +99,10 @@ TEST(AnimationKeyframeEffectModel, BasicOperation)
|
| {
|
| KeyframeEffectModel::KeyframeVector keyframes = keyframesAtZeroAndOne(unknownAnimatableValue(3.0), unknownAnimatableValue(5.0));
|
| RefPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(keyframes);
|
| - OwnPtr<AnimationEffect::CompositableValueList> values = effect->sample(0, 0.6);
|
| + OwnPtr<Vector<RefPtr<Interpolation> > > values = effect->sample(0, 0.6);
|
| ASSERT_EQ(1UL, values->size());
|
| - EXPECT_EQ(CSSPropertyLeft, values->at(0).first);
|
| - expectDoubleValue(5.0, values->at(0).second->compositeOnto(unknownAnimatableValue(7.0)));
|
| + expectProperty(CSSPropertyLeft, values->at(0));
|
| + expectDoubleValue(5.0, values->at(0));
|
| }
|
|
|
| TEST(AnimationKeyframeEffectModel, CompositeReplaceNonInterpolable)
|
| @@ -102,7 +111,7 @@ TEST(AnimationKeyframeEffectModel, CompositeReplaceNonInterpolable)
|
| keyframes[0]->setComposite(AnimationEffect::CompositeReplace);
|
| keyframes[1]->setComposite(AnimationEffect::CompositeReplace);
|
| RefPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(keyframes);
|
| - expectDoubleValue(5.0, effect->sample(0, 0.6)->at(0).second->compositeOnto(unknownAnimatableValue(7.0)));
|
| + expectDoubleValue(5.0, effect->sample(0, 0.6)->at(0));
|
| }
|
|
|
| TEST(AnimationKeyframeEffectModel, CompositeReplace)
|
| @@ -111,7 +120,7 @@ TEST(AnimationKeyframeEffectModel, CompositeReplace)
|
| keyframes[0]->setComposite(AnimationEffect::CompositeReplace);
|
| keyframes[1]->setComposite(AnimationEffect::CompositeReplace);
|
| RefPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(keyframes);
|
| - expectDoubleValue(3.0 * 0.4 + 5.0 * 0.6, effect->sample(0, 0.6)->at(0).second->compositeOnto(unknownAnimatableValue(7.0)));
|
| + expectDoubleValue(3.0 * 0.4 + 5.0 * 0.6, effect->sample(0, 0.6)->at(0));
|
| }
|
|
|
| TEST(AnimationKeyframeEffectModel, CompositeAdd)
|
| @@ -120,7 +129,7 @@ TEST(AnimationKeyframeEffectModel, CompositeAdd)
|
| keyframes[0]->setComposite(AnimationEffect::CompositeAdd);
|
| keyframes[1]->setComposite(AnimationEffect::CompositeAdd);
|
| RefPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(keyframes);
|
| - expectDoubleValue((7.0 + 3.0) * 0.4 + (7.0 + 5.0) * 0.6, effect->sample(0, 0.6)->at(0).second->compositeOnto(pixelAnimatableValue(7.0)));
|
| + expectDoubleValue((7.0 + 3.0) * 0.4 + (7.0 + 5.0) * 0.6, effect->sample(0, 0.6)->at(0));
|
| }
|
|
|
| TEST(AnimationKeyframeEffectModel, ExtrapolateReplaceNonInterpolable)
|
| @@ -129,7 +138,7 @@ TEST(AnimationKeyframeEffectModel, ExtrapolateReplaceNonInterpolable)
|
| RefPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(keyframes);
|
| keyframes[0]->setComposite(AnimationEffect::CompositeReplace);
|
| keyframes[1]->setComposite(AnimationEffect::CompositeReplace);
|
| - expectDoubleValue(5.0, effect->sample(0, 1.6)->at(0).second->compositeOnto(unknownAnimatableValue(7.0)));
|
| + expectDoubleValue(5.0, effect->sample(0, 1.6)->at(0));
|
| }
|
|
|
| TEST(AnimationKeyframeEffectModel, ExtrapolateReplace)
|
| @@ -138,7 +147,7 @@ TEST(AnimationKeyframeEffectModel, ExtrapolateReplace)
|
| RefPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(keyframes);
|
| keyframes[0]->setComposite(AnimationEffect::CompositeReplace);
|
| keyframes[1]->setComposite(AnimationEffect::CompositeReplace);
|
| - expectDoubleValue(3.0 * -0.6 + 5.0 * 1.6, effect->sample(0, 1.6)->at(0).second->compositeOnto(pixelAnimatableValue(7.0)));
|
| + expectDoubleValue(3.0 * -0.6 + 5.0 * 1.6, effect->sample(0, 1.6)->at(0));
|
| }
|
|
|
| TEST(AnimationKeyframeEffectModel, ExtrapolateAdd)
|
| @@ -147,7 +156,7 @@ TEST(AnimationKeyframeEffectModel, ExtrapolateAdd)
|
| keyframes[0]->setComposite(AnimationEffect::CompositeAdd);
|
| keyframes[1]->setComposite(AnimationEffect::CompositeAdd);
|
| RefPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(keyframes);
|
| - expectDoubleValue((7.0 + 3.0) * -0.6 + (7.0 + 5.0) * 1.6, effect->sample(0, 1.6)->at(0).second->compositeOnto(pixelAnimatableValue(7.0)));
|
| + expectDoubleValue((7.0 + 3.0) * -0.6 + (7.0 + 5.0) * 1.6, effect->sample(0, 1.6)->at(0));
|
| }
|
|
|
| TEST(AnimationKeyframeEffectModel, ZeroKeyframes)
|
| @@ -164,7 +173,7 @@ TEST(AnimationKeyframeEffectModel, SingleKeyframeAtOffsetZero)
|
| keyframes[0]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(3.0));
|
|
|
| RefPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(keyframes);
|
| - expectDoubleValue(3.0, effect->sample(0, 0.6)->at(0).second->compositeOnto(unknownAnimatableValue(7.0)));
|
| + expectDoubleValue(3.0, effect->sample(0, 0.6)->at(0));
|
| }
|
|
|
| TEST(AnimationKeyframeEffectModel, SingleKeyframeAtOffsetOne)
|
| @@ -175,7 +184,7 @@ TEST(AnimationKeyframeEffectModel, SingleKeyframeAtOffsetOne)
|
| keyframes[0]->setPropertyValue(CSSPropertyLeft, pixelAnimatableValue(5.0));
|
|
|
| RefPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(keyframes);
|
| - expectDoubleValue(7.0 * 0.4 + 5.0 * 0.6, effect->sample(0, 0.6)->at(0).second->compositeOnto(pixelAnimatableValue(7.0)));
|
| + expectDoubleValue(7.0 * 0.4 + 5.0 * 0.6, effect->sample(0, 0.6)->at(0));
|
| }
|
|
|
| TEST(AnimationKeyframeEffectModel, MoreThanTwoKeyframes)
|
| @@ -192,8 +201,8 @@ TEST(AnimationKeyframeEffectModel, MoreThanTwoKeyframes)
|
| keyframes[2]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(5.0));
|
|
|
| RefPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(keyframes);
|
| - expectDoubleValue(4.0, effect->sample(0, 0.3)->at(0).second->compositeOnto(unknownAnimatableValue(7.0)));
|
| - expectDoubleValue(5.0, effect->sample(0, 0.8)->at(0).second->compositeOnto(unknownAnimatableValue(7.0)));
|
| + expectDoubleValue(4.0, effect->sample(0, 0.3)->at(0));
|
| + expectDoubleValue(5.0, effect->sample(0, 0.8)->at(0));
|
| }
|
|
|
| TEST(AnimationKeyframeEffectModel, EndKeyframeOffsetsUnspecified)
|
| @@ -208,9 +217,9 @@ TEST(AnimationKeyframeEffectModel, EndKeyframeOffsetsUnspecified)
|
| keyframes[2]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(5.0));
|
|
|
| RefPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(keyframes);
|
| - expectDoubleValue(3.0, effect->sample(0, 0.1)->at(0).second->compositeOnto(unknownAnimatableValue(7.0)));
|
| - expectDoubleValue(4.0, effect->sample(0, 0.6)->at(0).second->compositeOnto(unknownAnimatableValue(7.0)));
|
| - expectDoubleValue(5.0, effect->sample(0, 0.9)->at(0).second->compositeOnto(unknownAnimatableValue(7.0)));
|
| + expectDoubleValue(3.0, effect->sample(0, 0.1)->at(0));
|
| + expectDoubleValue(4.0, effect->sample(0, 0.6)->at(0));
|
| + expectDoubleValue(5.0, effect->sample(0, 0.9)->at(0));
|
| }
|
|
|
| TEST(AnimationKeyframeEffectModel, SampleOnKeyframe)
|
| @@ -227,37 +236,9 @@ TEST(AnimationKeyframeEffectModel, SampleOnKeyframe)
|
| keyframes[2]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(5.0));
|
|
|
| RefPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(keyframes);
|
| - expectDoubleValue(3.0, effect->sample(0, 0.0)->at(0).second->compositeOnto(unknownAnimatableValue(7.0)));
|
| - expectDoubleValue(4.0, effect->sample(0, 0.5)->at(0).second->compositeOnto(unknownAnimatableValue(7.0)));
|
| - expectDoubleValue(5.0, effect->sample(0, 1.0)->at(0).second->compositeOnto(unknownAnimatableValue(7.0)));
|
| -}
|
| -
|
| -// Note that this tests an implementation detail, not behaviour defined by the spec.
|
| -TEST(AnimationKeyframeEffectModel, SampleReturnsSameAnimatableValueInstance)
|
| -{
|
| - AnimatableValue* threePixelsValue = unknownAnimatableValue(3.0);
|
| - AnimatableValue* fourPixelsValue = unknownAnimatableValue(4.0);
|
| - AnimatableValue* fivePixelsValue = unknownAnimatableValue(5.0);
|
| -
|
| - KeyframeEffectModel::KeyframeVector keyframes(3);
|
| - keyframes[0] = Keyframe::create();
|
| - keyframes[0]->setOffset(0.0);
|
| - keyframes[0]->setPropertyValue(CSSPropertyLeft, threePixelsValue);
|
| - keyframes[1] = Keyframe::create();
|
| - keyframes[1]->setOffset(0.5);
|
| - keyframes[1]->setPropertyValue(CSSPropertyLeft, fourPixelsValue);
|
| - keyframes[2] = Keyframe::create();
|
| - keyframes[2]->setOffset(1.0);
|
| - keyframes[2]->setPropertyValue(CSSPropertyLeft, fivePixelsValue);
|
| -
|
| - RefPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(keyframes);
|
| - EXPECT_EQ(threePixelsValue, effect->sample(0, 0.0)->at(0).second->compositeOnto(unknownAnimatableValue(7.0)));
|
| - EXPECT_EQ(threePixelsValue, effect->sample(0, 0.1)->at(0).second->compositeOnto(unknownAnimatableValue(7.0)));
|
| - EXPECT_EQ(fourPixelsValue, effect->sample(0, 0.4)->at(0).second->compositeOnto(unknownAnimatableValue(7.0)));
|
| - EXPECT_EQ(fourPixelsValue, effect->sample(0, 0.5)->at(0).second->compositeOnto(unknownAnimatableValue(7.0)));
|
| - EXPECT_EQ(fourPixelsValue, effect->sample(0, 0.6)->at(0).second->compositeOnto(unknownAnimatableValue(7.0)));
|
| - EXPECT_EQ(fivePixelsValue, effect->sample(0, 0.9)->at(0).second->compositeOnto(unknownAnimatableValue(7.0)));
|
| - EXPECT_EQ(fivePixelsValue, effect->sample(0, 1.0)->at(0).second->compositeOnto(unknownAnimatableValue(7.0)));
|
| + expectDoubleValue(3.0, effect->sample(0, 0.0)->at(0));
|
| + expectDoubleValue(4.0, effect->sample(0, 0.5)->at(0));
|
| + expectDoubleValue(5.0, effect->sample(0, 1.0)->at(0));
|
| }
|
|
|
| TEST(AnimationKeyframeEffectModel, MultipleKeyframesWithSameOffset)
|
| @@ -286,13 +267,13 @@ TEST(AnimationKeyframeEffectModel, MultipleKeyframesWithSameOffset)
|
| keyframes[6]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(7.0));
|
|
|
| RefPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(keyframes);
|
| - expectDoubleValue(2.0, effect->sample(0, 0.0)->at(0).second->compositeOnto(unknownAnimatableValue(8.0)));
|
| - expectDoubleValue(2.0, effect->sample(0, 0.2)->at(0).second->compositeOnto(unknownAnimatableValue(8.0)));
|
| - expectDoubleValue(3.0, effect->sample(0, 0.4)->at(0).second->compositeOnto(unknownAnimatableValue(8.0)));
|
| - expectDoubleValue(5.0, effect->sample(0, 0.5)->at(0).second->compositeOnto(unknownAnimatableValue(8.0)));
|
| - expectDoubleValue(5.0, effect->sample(0, 0.6)->at(0).second->compositeOnto(unknownAnimatableValue(8.0)));
|
| - expectDoubleValue(6.0, effect->sample(0, 0.8)->at(0).second->compositeOnto(unknownAnimatableValue(8.0)));
|
| - expectDoubleValue(6.0, effect->sample(0, 1.0)->at(0).second->compositeOnto(unknownAnimatableValue(8.0)));
|
| + expectDoubleValue(2.0, effect->sample(0, 0.0)->at(0));
|
| + expectDoubleValue(2.0, effect->sample(0, 0.2)->at(0));
|
| + expectDoubleValue(3.0, effect->sample(0, 0.4)->at(0));
|
| + expectDoubleValue(5.0, effect->sample(0, 0.5)->at(0));
|
| + expectDoubleValue(5.0, effect->sample(0, 0.6)->at(0));
|
| + expectDoubleValue(6.0, effect->sample(0, 0.8)->at(0));
|
| + expectDoubleValue(6.0, effect->sample(0, 1.0)->at(0));
|
| }
|
|
|
| TEST(AnimationKeyframeEffectModel, PerKeyframeComposite)
|
| @@ -307,7 +288,7 @@ TEST(AnimationKeyframeEffectModel, PerKeyframeComposite)
|
| keyframes[1]->setComposite(AnimationEffect::CompositeAdd);
|
|
|
| RefPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(keyframes);
|
| - expectDoubleValue(3.0 * 0.4 + (7.0 + 5.0) * 0.6, effect->sample(0, 0.6)->at(0).second->compositeOnto(pixelAnimatableValue(7.0)));
|
| + expectDoubleValue(3.0 * 0.4 + (7.0 + 5.0) * 0.6, effect->sample(0, 0.6)->at(0));
|
| }
|
|
|
| TEST(AnimationKeyframeEffectModel, MultipleProperties)
|
| @@ -323,14 +304,14 @@ TEST(AnimationKeyframeEffectModel, MultipleProperties)
|
| keyframes[1]->setPropertyValue(CSSPropertyRight, unknownAnimatableValue(6.0));
|
|
|
| RefPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(keyframes);
|
| - OwnPtr<AnimationEffect::CompositableValueList> values = effect->sample(0, 0.6);
|
| + OwnPtr<Vector<RefPtr<Interpolation> > > values = effect->sample(0, 0.6);
|
| EXPECT_EQ(2UL, values->size());
|
| - const AnimationEffect::CompositableValue* leftValue = findValue(*values.get(), CSSPropertyLeft);
|
| + Interpolation* leftValue = findValue(*values.get(), CSSPropertyLeft);
|
| ASSERT_TRUE(leftValue);
|
| - expectDoubleValue(5.0, leftValue->compositeOnto(unknownAnimatableValue(7.0)));
|
| - const AnimationEffect::CompositableValue* rightValue = findValue(*values.get(), CSSPropertyRight);
|
| + expectDoubleValue(5.0, leftValue);
|
| + Interpolation* rightValue = findValue(*values.get(), CSSPropertyRight);
|
| ASSERT_TRUE(rightValue);
|
| - expectDoubleValue(6.0, rightValue->compositeOnto(unknownAnimatableValue(7.0)));
|
| + expectDoubleValue(6.0, rightValue);
|
| }
|
|
|
| TEST(AnimationKeyframeEffectModel, RecompositeCompositableValue)
|
| @@ -339,18 +320,18 @@ TEST(AnimationKeyframeEffectModel, RecompositeCompositableValue)
|
| keyframes[0]->setComposite(AnimationEffect::CompositeAdd);
|
| keyframes[1]->setComposite(AnimationEffect::CompositeAdd);
|
| RefPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(keyframes);
|
| - OwnPtr<AnimationEffect::CompositableValueList> values = effect->sample(0, 0.6);
|
| - expectDoubleValue((7.0 + 3.0) * 0.4 + (7.0 + 5.0) * 0.6, values->at(0).second->compositeOnto(pixelAnimatableValue(7.0)));
|
| - expectDoubleValue((9.0 + 3.0) * 0.4 + (9.0 + 5.0) * 0.6, values->at(0).second->compositeOnto(pixelAnimatableValue(9.0)));
|
| + OwnPtr<Vector<RefPtr<Interpolation> > > values = effect->sample(0, 0.6);
|
| + expectDoubleValue((7.0 + 3.0) * 0.4 + (7.0 + 5.0) * 0.6, values->at(0));
|
| + expectDoubleValue((9.0 + 3.0) * 0.4 + (9.0 + 5.0) * 0.6, values->at(0));
|
| }
|
|
|
| TEST(AnimationKeyframeEffectModel, MultipleIterations)
|
| {
|
| KeyframeEffectModel::KeyframeVector keyframes = keyframesAtZeroAndOne(pixelAnimatableValue(1.0), pixelAnimatableValue(3.0));
|
| RefPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(keyframes);
|
| - expectDoubleValue(2.0, effect->sample(0, 0.5)->at(0).second->compositeOnto(unknownAnimatableValue(0.0)));
|
| - expectDoubleValue(2.0, effect->sample(1, 0.5)->at(0).second->compositeOnto(unknownAnimatableValue(0.0)));
|
| - expectDoubleValue(2.0, effect->sample(2, 0.5)->at(0).second->compositeOnto(unknownAnimatableValue(0.0)));
|
| + expectDoubleValue(2.0, effect->sample(0, 0.5)->at(0));
|
| + expectDoubleValue(2.0, effect->sample(1, 0.5)->at(0));
|
| + expectDoubleValue(2.0, effect->sample(2, 0.5)->at(0));
|
| }
|
|
|
| TEST(AnimationKeyframeEffectModel, DependsOnUnderlyingValue)
|
| @@ -368,15 +349,15 @@ TEST(AnimationKeyframeEffectModel, DependsOnUnderlyingValue)
|
| keyframes[2]->setPropertyValue(CSSPropertyLeft, pixelAnimatableValue(1.0));
|
|
|
| RefPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(keyframes);
|
| - EXPECT_TRUE(effect->sample(0, 0)->at(0).second->dependsOnUnderlyingValue());
|
| - EXPECT_TRUE(effect->sample(0, 0.1)->at(0).second->dependsOnUnderlyingValue());
|
| - EXPECT_TRUE(effect->sample(0, 0.25)->at(0).second->dependsOnUnderlyingValue());
|
| - EXPECT_TRUE(effect->sample(0, 0.4)->at(0).second->dependsOnUnderlyingValue());
|
| - EXPECT_FALSE(effect->sample(0, 0.5)->at(0).second->dependsOnUnderlyingValue());
|
| - EXPECT_FALSE(effect->sample(0, 0.6)->at(0).second->dependsOnUnderlyingValue());
|
| - EXPECT_FALSE(effect->sample(0, 0.75)->at(0).second->dependsOnUnderlyingValue());
|
| - EXPECT_FALSE(effect->sample(0, 0.8)->at(0).second->dependsOnUnderlyingValue());
|
| - EXPECT_FALSE(effect->sample(0, 1)->at(0).second->dependsOnUnderlyingValue());
|
| + EXPECT_TRUE(effect->sample(0, 0)->at(0));
|
| + EXPECT_TRUE(effect->sample(0, 0.1)->at(0));
|
| + EXPECT_TRUE(effect->sample(0, 0.25)->at(0));
|
| + EXPECT_TRUE(effect->sample(0, 0.4)->at(0));
|
| + EXPECT_FALSE(effect->sample(0, 0.5)->at(0));
|
| + EXPECT_FALSE(effect->sample(0, 0.6)->at(0));
|
| + EXPECT_FALSE(effect->sample(0, 0.75)->at(0));
|
| + EXPECT_FALSE(effect->sample(0, 0.8)->at(0));
|
| + EXPECT_FALSE(effect->sample(0, 1)->at(0));
|
| }
|
|
|
| TEST(AnimationKeyframeEffectModel, ToKeyframeEffectModel)
|
|
|