OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2011 Google Inc. All rights reserved. | 2 * Copyright (C) 2011 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
110 // For multiline, the min preferred width is if you put a break between each item. | 110 // For multiline, the min preferred width is if you put a break between each item. |
111 minLogicalWidth = std::max(minLogicalWidth, minPreferredLogicalW idth); | 111 minLogicalWidth = std::max(minLogicalWidth, minPreferredLogicalW idth); |
112 } else { | 112 } else { |
113 minLogicalWidth += minPreferredLogicalWidth; | 113 minLogicalWidth += minPreferredLogicalWidth; |
114 } | 114 } |
115 } else { | 115 } else { |
116 minLogicalWidth = std::max(minPreferredLogicalWidth, minLogicalWidth ); | 116 minLogicalWidth = std::max(minPreferredLogicalWidth, minLogicalWidth ); |
117 maxLogicalWidth = std::max(maxPreferredLogicalWidth, maxLogicalWidth ); | 117 maxLogicalWidth = std::max(maxPreferredLogicalWidth, maxLogicalWidth ); |
118 } | 118 } |
119 } | 119 } |
120 | |
121 maxLogicalWidth = std::max(minLogicalWidth, maxLogicalWidth); | 120 maxLogicalWidth = std::max(minLogicalWidth, maxLogicalWidth); |
122 | 121 |
123 LayoutUnit scrollbarWidth = intrinsicScrollbarLogicalWidth(); | 122 LayoutUnit scrollbarWidth = intrinsicScrollbarLogicalWidth(); |
124 maxLogicalWidth += scrollbarWidth; | 123 maxLogicalWidth += scrollbarWidth; |
125 minLogicalWidth += scrollbarWidth; | 124 minLogicalWidth += scrollbarWidth; |
126 } | 125 } |
127 | 126 |
128 static int synthesizedBaselineFromContentBox(const LayoutBox& box, LineDirection Mode direction) | 127 static int synthesizedBaselineFromContentBox(const LayoutBox& box, LineDirection Mode direction) |
129 { | 128 { |
130 if (direction == HorizontalLine) { | 129 if (direction == HorizontalLine) { |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
332 } | 331 } |
333 | 332 |
334 Length LayoutFlexibleBox::flexBasisForChild(LayoutBox& child) const | 333 Length LayoutFlexibleBox::flexBasisForChild(LayoutBox& child) const |
335 { | 334 { |
336 Length flexLength = child.style()->flexBasis(); | 335 Length flexLength = child.style()->flexBasis(); |
337 if (flexLength.isAuto()) | 336 if (flexLength.isAuto()) |
338 flexLength = isHorizontalFlow() ? child.style()->width() : child.style() ->height(); | 337 flexLength = isHorizontalFlow() ? child.style()->width() : child.style() ->height(); |
339 return flexLength; | 338 return flexLength; |
340 } | 339 } |
341 | 340 |
341 bool LayoutFlexibleBox::percentageMainSizeIsResolvable() | |
342 { | |
343 return isHorizontalFlow() ? hasDefiniteLogicalWidth() : hasDefiniteLogicalHe ight(); | |
344 } | |
345 | |
342 LayoutUnit LayoutFlexibleBox::crossAxisExtentForChild(LayoutBox& child) const | 346 LayoutUnit LayoutFlexibleBox::crossAxisExtentForChild(LayoutBox& child) const |
343 { | 347 { |
344 return isHorizontalFlow() ? child.size().height() : child.size().width(); | 348 return isHorizontalFlow() ? child.size().height() : child.size().width(); |
345 } | 349 } |
346 | 350 |
347 static inline LayoutUnit constrainedChildIntrinsicContentLogicalHeight(LayoutBox & child) | 351 static inline LayoutUnit constrainedChildIntrinsicContentLogicalHeight(LayoutBox & child) |
348 { | 352 { |
349 LayoutUnit childIntrinsicContentLogicalHeight = child.intrinsicContentLogica lHeight(); | 353 LayoutUnit childIntrinsicContentLogicalHeight = child.intrinsicContentLogica lHeight(); |
350 return child.constrainLogicalHeightByMinMax(childIntrinsicContentLogicalHeig ht + child.borderAndPaddingLogicalHeight(), childIntrinsicContentLogicalHeight); | 354 return child.constrainLogicalHeightByMinMax(childIntrinsicContentLogicalHeig ht + child.borderAndPaddingLogicalHeight(), childIntrinsicContentLogicalHeight); |
351 } | 355 } |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
404 } | 408 } |
405 | 409 |
406 LayoutUnit LayoutFlexibleBox::computeMainAxisExtentForChild(LayoutBox& child, Si zeType sizeType, const Length& size) | 410 LayoutUnit LayoutFlexibleBox::computeMainAxisExtentForChild(LayoutBox& child, Si zeType sizeType, const Length& size) |
407 { | 411 { |
408 // FIXME: This is wrong for orthogonal flows. It should use the flexbox's wr iting-mode, not the child's in order | 412 // FIXME: This is wrong for orthogonal flows. It should use the flexbox's wr iting-mode, not the child's in order |
409 // to figure out the logical height/width. | 413 // to figure out the logical height/width. |
410 if (isColumnFlow()) { | 414 if (isColumnFlow()) { |
411 // We don't have to check for "auto" here - computeContentLogicalHeight will just return -1 for that case anyway. | 415 // We don't have to check for "auto" here - computeContentLogicalHeight will just return -1 for that case anyway. |
412 if (size.isIntrinsic()) | 416 if (size.isIntrinsic()) |
413 child.layoutIfNeeded(); | 417 child.layoutIfNeeded(); |
414 return child.computeContentLogicalHeight(size, child.logicalHeight() - c hild.borderAndPaddingLogicalHeight()) + child.scrollbarLogicalHeight(); | 418 return child.computeContentLogicalHeight(sizeType, size, child.logicalHe ight() - child.borderAndPaddingLogicalHeight()) + child.scrollbarLogicalHeight() ; |
415 } | 419 } |
416 return child.computeLogicalWidthUsing(sizeType, size, contentLogicalWidth(), this) - child.borderAndPaddingLogicalWidth(); | 420 return child.computeLogicalWidthUsing(sizeType, size, contentLogicalWidth(), this) - child.borderAndPaddingLogicalWidth(); |
417 } | 421 } |
418 | 422 |
419 WritingMode LayoutFlexibleBox::transformedWritingMode() const | 423 WritingMode LayoutFlexibleBox::transformedWritingMode() const |
420 { | 424 { |
421 WritingMode mode = style()->writingMode(); | 425 WritingMode mode = style()->writingMode(); |
422 if (!isColumnFlow()) | 426 if (!isColumnFlow()) |
423 return mode; | 427 return mode; |
424 | 428 |
(...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
820 if (isHorizontalFlow()) { | 824 if (isHorizontalFlow()) { |
821 child->setMarginLeft(computeChildMarginValue(child->style()->marginL eft())); | 825 child->setMarginLeft(computeChildMarginValue(child->style()->marginL eft())); |
822 child->setMarginRight(computeChildMarginValue(child->style()->margin Right())); | 826 child->setMarginRight(computeChildMarginValue(child->style()->margin Right())); |
823 } else { | 827 } else { |
824 child->setMarginTop(computeChildMarginValue(child->style()->marginTo p())); | 828 child->setMarginTop(computeChildMarginValue(child->style()->marginTo p())); |
825 child->setMarginBottom(computeChildMarginValue(child->style()->margi nBottom())); | 829 child->setMarginBottom(computeChildMarginValue(child->style()->margi nBottom())); |
826 } | 830 } |
827 } | 831 } |
828 } | 832 } |
829 | 833 |
830 LayoutUnit LayoutFlexibleBox::adjustChildSizeForMinAndMax(LayoutBox& child, Layo utUnit childSize) | 834 LayoutUnit LayoutFlexibleBox::adjustChildSizeForMinAndMax(LayoutBox& child, Layo utUnit childSize, bool hasInfiniteLineLength) |
831 { | 835 { |
832 Length max = isHorizontalFlow() ? child.style()->maxWidth() : child.style()- >maxHeight(); | 836 Length max = isHorizontalFlow() ? child.style()->maxWidth() : child.style()- >maxHeight(); |
837 LayoutUnit maxExtent = -1; | |
833 if (max.isSpecifiedOrIntrinsic()) { | 838 if (max.isSpecifiedOrIntrinsic()) { |
834 LayoutUnit maxExtent = computeMainAxisExtentForChild(child, MaxSize, max ); | 839 maxExtent = computeMainAxisExtentForChild(child, MaxSize, max); |
835 if (maxExtent != -1 && childSize > maxExtent) | 840 if (maxExtent != -1 && childSize > maxExtent) |
836 childSize = maxExtent; | 841 childSize = maxExtent; |
837 } | 842 } |
838 | 843 |
839 Length min = isHorizontalFlow() ? child.style()->minWidth() : child.style()- >minHeight(); | 844 Length min = isHorizontalFlow() ? child.style()->minWidth() : child.style()- >minHeight(); |
840 LayoutUnit minExtent = 0; | 845 LayoutUnit minExtent = 0; |
841 if (min.isSpecifiedOrIntrinsic()) | 846 if (min.isSpecifiedOrIntrinsic()) { |
842 minExtent = computeMainAxisExtentForChild(child, MinSize, min); | 847 minExtent = computeMainAxisExtentForChild(child, MinSize, min); |
848 // computeMainAxisExtentForChild can return -1 when the child has a perc entage | |
849 // min size, but we have an indefinite size in that axis. | |
850 minExtent = std::max(LayoutUnit(0), minExtent); | |
851 } else if (min.isAuto() && mainAxisOverflowForChild(child) == OVISIBLE) { | |
852 // css-flexbox section 4.5 | |
853 LayoutUnit contentSize = computeMainAxisExtentForChild(child, MinSize, L ength(MinContent)); | |
854 ASSERT(contentSize >= 0); | |
855 if (maxExtent != -1 && contentSize > maxExtent) | |
856 contentSize = maxExtent; | |
857 | |
858 bool hasClampedSize = !childPreferredMainAxisContentExtentRequiresLayout (child, hasInfiniteLineLength); | |
859 if (hasClampedSize) { | |
860 Length flexBasis = flexBasisForChild(child); | |
861 bool flexBasisIsDefinite = flexBasis.isFixed() || (flexBasis.isPerce nt() && percentageMainSizeIsResolvable()); | |
862 if (flexBasisIsDefinite) { | |
863 LayoutUnit resolvedFlexBasis = computeMainAxisExtentForChild(chi ld, MainOrPreferredSize, flexBasis); | |
864 ASSERT(resolvedFlexBasis >= 0); | |
865 LayoutUnit clampedSize = resolvedFlexBasis; | |
866 if (maxExtent != -1 && clampedSize > maxExtent) | |
867 clampedSize = maxExtent; | |
868 | |
869 minExtent = std::min(clampedSize, contentSize); | |
870 } else { | |
871 minExtent = contentSize; | |
872 } | |
873 } else { | |
874 minExtent = contentSize; | |
875 } | |
876 // TODO(cbiesinger): Implement aspect ratio handling (here, transferred size) | |
leviw_travelin_and_unemployed
2015/04/02 22:14:36
Tracking bug?
cbiesinger
2015/04/03 18:49:17
Done.
| |
877 } | |
878 ASSERT(minExtent >= 0); | |
843 return std::max(childSize, minExtent); | 879 return std::max(childSize, minExtent); |
844 } | 880 } |
845 | 881 |
846 bool LayoutFlexibleBox::computeNextFlexLine(OrderedFlexItemList& orderedChildren , LayoutUnit& sumFlexBaseSize, double& totalFlexGrow, double& totalWeightedFlexS hrink, LayoutUnit& sumHypotheticalMainSize, bool& hasInfiniteLineLength, bool re layoutChildren) | 882 bool LayoutFlexibleBox::computeNextFlexLine(OrderedFlexItemList& orderedChildren , LayoutUnit& sumFlexBaseSize, double& totalFlexGrow, double& totalWeightedFlexS hrink, LayoutUnit& sumHypotheticalMainSize, bool& hasInfiniteLineLength, bool re layoutChildren) |
847 { | 883 { |
848 orderedChildren.clear(); | 884 orderedChildren.clear(); |
849 sumFlexBaseSize = 0; | 885 sumFlexBaseSize = 0; |
850 totalFlexGrow = totalWeightedFlexShrink = 0; | 886 totalFlexGrow = totalWeightedFlexShrink = 0; |
851 sumHypotheticalMainSize = 0; | 887 sumHypotheticalMainSize = 0; |
852 | 888 |
853 if (!m_orderIterator.currentChild()) | 889 if (!m_orderIterator.currentChild()) |
854 return false; | 890 return false; |
855 | 891 |
856 LayoutUnit lineBreakLength = mainAxisContentExtent(LayoutUnit::max()); | 892 LayoutUnit lineBreakLength = mainAxisContentExtent(LayoutUnit::max()); |
857 hasInfiniteLineLength = lineBreakLength == LayoutUnit::max(); | 893 hasInfiniteLineLength = lineBreakLength == LayoutUnit::max(); |
858 | 894 |
859 bool lineHasInFlowItem = false; | 895 bool lineHasInFlowItem = false; |
860 | 896 |
861 for (LayoutBox* child = m_orderIterator.currentChild(); child; child = m_ord erIterator.next()) { | 897 for (LayoutBox* child = m_orderIterator.currentChild(); child; child = m_ord erIterator.next()) { |
862 if (child->isOutOfFlowPositioned()) { | 898 if (child->isOutOfFlowPositioned()) { |
863 orderedChildren.append(child); | 899 orderedChildren.append(child); |
864 continue; | 900 continue; |
865 } | 901 } |
866 | 902 |
867 LayoutUnit childMainAxisExtent = preferredMainAxisContentExtentForChild( *child, hasInfiniteLineLength, relayoutChildren); | 903 LayoutUnit childMainAxisExtent = preferredMainAxisContentExtentForChild( *child, hasInfiniteLineLength, relayoutChildren); |
868 LayoutUnit childMainAxisMarginBorderPadding = mainAxisBorderAndPaddingEx tentForChild(*child) | 904 LayoutUnit childMainAxisMarginBorderPadding = mainAxisBorderAndPaddingEx tentForChild(*child) |
869 + (isHorizontalFlow() ? child->marginWidth() : child->marginHeight() ); | 905 + (isHorizontalFlow() ? child->marginWidth() : child->marginHeight() ); |
870 LayoutUnit childFlexBaseSize = childMainAxisExtent + childMainAxisMargin BorderPadding; | 906 LayoutUnit childFlexBaseSize = childMainAxisExtent + childMainAxisMargin BorderPadding; |
871 | 907 |
872 LayoutUnit childMinMaxAppliedMainAxisExtent = adjustChildSizeForMinAndMa x(*child, childMainAxisExtent); | 908 LayoutUnit childMinMaxAppliedMainAxisExtent = adjustChildSizeForMinAndMa x(*child, childMainAxisExtent, hasInfiniteLineLength); |
873 LayoutUnit childHypotheticalMainSize = childMinMaxAppliedMainAxisExtent + childMainAxisMarginBorderPadding; | 909 LayoutUnit childHypotheticalMainSize = childMinMaxAppliedMainAxisExtent + childMainAxisMarginBorderPadding; |
874 | 910 |
875 if (isMultiline() && sumHypotheticalMainSize + childHypotheticalMainSize > lineBreakLength && lineHasInFlowItem) | 911 if (isMultiline() && sumHypotheticalMainSize + childHypotheticalMainSize > lineBreakLength && lineHasInFlowItem) |
876 break; | 912 break; |
877 orderedChildren.append(child); | 913 orderedChildren.append(child); |
878 lineHasInFlowItem = true; | 914 lineHasInFlowItem = true; |
879 sumFlexBaseSize += childFlexBaseSize; | 915 sumFlexBaseSize += childFlexBaseSize; |
880 totalFlexGrow += child->style()->flexGrow(); | 916 totalFlexGrow += child->style()->flexGrow(); |
881 totalWeightedFlexShrink += child->style()->flexShrink() * childMainAxisE xtent; | 917 totalWeightedFlexShrink += child->style()->flexShrink() * childMainAxisE xtent; |
882 sumHypotheticalMainSize += childHypotheticalMainSize; | 918 sumHypotheticalMainSize += childHypotheticalMainSize; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
918 LayoutUnit preferredChildSize = preferredMainAxisContentExtentForChi ld(*child, hasInfiniteLineLength); | 954 LayoutUnit preferredChildSize = preferredMainAxisContentExtentForChi ld(*child, hasInfiniteLineLength); |
919 LayoutUnit childSize = preferredChildSize; | 955 LayoutUnit childSize = preferredChildSize; |
920 double extraSpace = 0; | 956 double extraSpace = 0; |
921 if (availableFreeSpace > 0 && totalFlexGrow > 0 && flexSign == Posit iveFlexibility && std::isfinite(totalFlexGrow)) | 957 if (availableFreeSpace > 0 && totalFlexGrow > 0 && flexSign == Posit iveFlexibility && std::isfinite(totalFlexGrow)) |
922 extraSpace = availableFreeSpace * child->style()->flexGrow() / t otalFlexGrow; | 958 extraSpace = availableFreeSpace * child->style()->flexGrow() / t otalFlexGrow; |
923 else if (availableFreeSpace < 0 && totalWeightedFlexShrink > 0 && fl exSign == NegativeFlexibility && std::isfinite(totalWeightedFlexShrink)) | 959 else if (availableFreeSpace < 0 && totalWeightedFlexShrink > 0 && fl exSign == NegativeFlexibility && std::isfinite(totalWeightedFlexShrink)) |
924 extraSpace = availableFreeSpace * child->style()->flexShrink() * preferredChildSize / totalWeightedFlexShrink; | 960 extraSpace = availableFreeSpace * child->style()->flexShrink() * preferredChildSize / totalWeightedFlexShrink; |
925 if (std::isfinite(extraSpace)) | 961 if (std::isfinite(extraSpace)) |
926 childSize += LayoutUnit::fromFloatRound(extraSpace); | 962 childSize += LayoutUnit::fromFloatRound(extraSpace); |
927 | 963 |
928 LayoutUnit adjustedChildSize = adjustChildSizeForMinAndMax(*child, c hildSize); | 964 LayoutUnit adjustedChildSize = adjustChildSizeForMinAndMax(*child, c hildSize, hasInfiniteLineLength); |
929 childSizes.append(adjustedChildSize); | 965 childSizes.append(adjustedChildSize); |
930 usedFreeSpace += adjustedChildSize - preferredChildSize; | 966 usedFreeSpace += adjustedChildSize - preferredChildSize; |
931 | 967 |
932 LayoutUnit violation = adjustedChildSize - childSize; | 968 LayoutUnit violation = adjustedChildSize - childSize; |
933 if (violation > 0) | 969 if (violation > 0) |
934 minViolations.append(Violation(child, adjustedChildSize)); | 970 minViolations.append(Violation(child, adjustedChildSize)); |
935 else if (violation < 0) | 971 else if (violation < 0) |
936 maxViolations.append(Violation(child, adjustedChildSize)); | 972 maxViolations.append(Violation(child, adjustedChildSize)); |
937 totalViolation += violation; | 973 totalViolation += violation; |
938 } | 974 } |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1045 } | 1081 } |
1046 | 1082 |
1047 bool LayoutFlexibleBox::needToStretchChildLogicalHeight(LayoutBox& child) const | 1083 bool LayoutFlexibleBox::needToStretchChildLogicalHeight(LayoutBox& child) const |
1048 { | 1084 { |
1049 if (alignmentForChild(child) != ItemPositionStretch) | 1085 if (alignmentForChild(child) != ItemPositionStretch) |
1050 return false; | 1086 return false; |
1051 | 1087 |
1052 return isHorizontalFlow() && child.style()->height().isAuto(); | 1088 return isHorizontalFlow() && child.style()->height().isAuto(); |
1053 } | 1089 } |
1054 | 1090 |
1091 EOverflow LayoutFlexibleBox::mainAxisOverflowForChild(LayoutBox& child) const | |
1092 { | |
1093 if (isHorizontalFlow()) | |
1094 return child.styleRef().overflowX(); | |
1095 return child.styleRef().overflowY(); | |
1096 } | |
1097 | |
1055 void LayoutFlexibleBox::layoutAndPlaceChildren(LayoutUnit& crossAxisOffset, cons t OrderedFlexItemList& children, const Vector<LayoutUnit, 16>& childSizes, Layou tUnit availableFreeSpace, bool relayoutChildren, Vector<LineContext>& lineContex ts, bool hasInfiniteLineLength) | 1098 void LayoutFlexibleBox::layoutAndPlaceChildren(LayoutUnit& crossAxisOffset, cons t OrderedFlexItemList& children, const Vector<LayoutUnit, 16>& childSizes, Layou tUnit availableFreeSpace, bool relayoutChildren, Vector<LineContext>& lineContex ts, bool hasInfiniteLineLength) |
1056 { | 1099 { |
1057 ASSERT(childSizes.size() == children.size()); | 1100 ASSERT(childSizes.size() == children.size()); |
1058 | 1101 |
1059 size_t numberOfChildrenForJustifyContent = numberOfInFlowPositionedChildren( children); | 1102 size_t numberOfChildrenForJustifyContent = numberOfInFlowPositionedChildren( children); |
1060 LayoutUnit autoMarginOffset = autoMarginOffsetInMainAxis(children, available FreeSpace); | 1103 LayoutUnit autoMarginOffset = autoMarginOffsetInMainAxis(children, available FreeSpace); |
1061 LayoutUnit mainAxisOffset = flowAwareBorderStart() + flowAwarePaddingStart() ; | 1104 LayoutUnit mainAxisOffset = flowAwareBorderStart() + flowAwarePaddingStart() ; |
1062 mainAxisOffset += initialJustifyContentOffset(availableFreeSpace, style()->j ustifyContent(), style()->justifyContentDistribution(), numberOfChildrenForJusti fyContent); | 1105 mainAxisOffset += initialJustifyContentOffset(availableFreeSpace, style()->j ustifyContent(), style()->justifyContentDistribution(), numberOfChildrenForJusti fyContent); |
1063 if (style()->flexDirection() == FlowRowReverse) | 1106 if (style()->flexDirection() == FlowRowReverse) |
1064 mainAxisOffset += isHorizontalFlow() ? verticalScrollbarWidth() : horizo ntalScrollbarHeight(); | 1107 mainAxisOffset += isHorizontalFlow() ? verticalScrollbarWidth() : horizo ntalScrollbarHeight(); |
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1395 ASSERT(child); | 1438 ASSERT(child); |
1396 LayoutUnit lineCrossAxisExtent = lineContexts[lineNumber].crossAxisE xtent; | 1439 LayoutUnit lineCrossAxisExtent = lineContexts[lineNumber].crossAxisE xtent; |
1397 LayoutUnit originalOffset = lineContexts[lineNumber].crossAxisOffset - crossAxisStartEdge; | 1440 LayoutUnit originalOffset = lineContexts[lineNumber].crossAxisOffset - crossAxisStartEdge; |
1398 LayoutUnit newOffset = contentExtent - originalOffset - lineCrossAxi sExtent; | 1441 LayoutUnit newOffset = contentExtent - originalOffset - lineCrossAxi sExtent; |
1399 adjustAlignmentForChild(*child, newOffset - originalOffset); | 1442 adjustAlignmentForChild(*child, newOffset - originalOffset); |
1400 } | 1443 } |
1401 } | 1444 } |
1402 } | 1445 } |
1403 | 1446 |
1404 } | 1447 } |
OLD | NEW |