diff --git a/build/scripts/utils.gant b/build/scripts/utils.gant index 06a2d030d39b..bd6d0c16ab72 100644 --- a/build/scripts/utils.gant +++ b/build/scripts/utils.gant @@ -14,15 +14,12 @@ * limitations under the License. */ + import com.intellij.openapi.util.SystemInfo import com.intellij.openapi.util.io.FileUtil import org.jetbrains.jps.gant.JpsGantTool import org.jetbrains.jps.gant.TeamCityBuildInfoPrinter -import org.jetbrains.jps.model.java.JavaResourceRootType -import org.jetbrains.jps.model.java.JavaSourceRootType -import org.jetbrains.jps.model.java.JdkVersionDetector -import org.jetbrains.jps.model.java.JpsJavaExtensionService -import org.jetbrains.jps.model.java.JpsJavaSdkType +import org.jetbrains.jps.model.java.* import org.jetbrains.jps.model.library.JpsOrderRootType import org.jetbrains.jps.model.module.JpsModule import org.jetbrains.jps.model.serialization.JpsModelSerializationDataService @@ -759,6 +756,16 @@ binding.setVariable("zipSourcesOfModules", { String targetFilePath, Collection + result = [] + JpsModule module = findModule(moduleName) + if (module == null) projectBuilder.error("Module $moduleName not found") + module.getSourceRoots(JavaSourceRootType.SOURCE).each { root -> + result << ant.zipfileset(dir: root.file.absolutePath , prefix: root.properties.packagePrefix.replace('.', '/'), erroronmissingdir: false) + } + result +}) + /** * E.g. * diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/BasicStepMethodFilter.java b/java/debugger/impl/src/com/intellij/debugger/engine/BasicStepMethodFilter.java index 49b645b8b5af..ff15205d1e9c 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/BasicStepMethodFilter.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/BasicStepMethodFilter.java @@ -17,7 +17,10 @@ package com.intellij.debugger.engine; import com.intellij.debugger.engine.evaluation.EvaluateException; import com.intellij.debugger.impl.DebuggerUtilsEx; -import com.intellij.psi.PsiMethod; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.Computable; +import com.intellij.psi.*; import com.intellij.util.Range; import com.sun.jdi.Location; import com.sun.jdi.Method; @@ -29,6 +32,8 @@ import org.jetbrains.annotations.Nullable; * Date: 10/26/13 */ public class BasicStepMethodFilter implements NamedMethodFilter { + private static final Logger LOG = Logger.getInstance(BasicStepMethodFilter.class); + @NotNull protected final JVMName myDeclaringClassName; @NotNull @@ -59,17 +64,40 @@ public class BasicStepMethodFilter implements NamedMethodFilter { return myTargetMethodName; } - public boolean locationMatches(DebugProcessImpl process, Location location) throws EvaluateException { + public boolean locationMatches(final DebugProcessImpl process, final Location location) throws EvaluateException { final Method method = location.method(); - if (!myTargetMethodName.equals(method.name())) { - return false; + boolean lambdaMatched = false; + String name = method.name(); + if (!myTargetMethodName.equals(name)) { + if (LambdaMethodFilter.isLambdaName(name)) { + lambdaMatched = ApplicationManager.getApplication().runReadAction(new Computable() { + @Override + public Boolean compute() { + PsiParameterListOwner psiMethod = DebuggerUtilsEx.getContainingMethod(process.getPositionManager().getSourcePosition(location)); + if (psiMethod instanceof PsiLambdaExpression) { + PsiType type = ((PsiLambdaExpression)psiMethod).getFunctionalInterfaceType(); + PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(type); + if (type != null && interfaceMethod != null && myTargetMethodName.equals(interfaceMethod.getName())) { + try { + return type.getCanonicalText().equals(myDeclaringClassName.getName(process).replace('$', '.')); + } + catch (EvaluateException e) { + LOG.info(e); + } + } + } + return false; + } + }); + } + if (!lambdaMatched) return false; } if (myTargetMethodSignature != null) { if (!signatureMatches(method, myTargetMethodSignature.getName(process))) { return false; } } - return DebuggerUtilsEx.isAssignableFrom(myDeclaringClassName.getName(process), location.declaringType()); + return lambdaMatched || DebuggerUtilsEx.isAssignableFrom(myDeclaringClassName.getName(process), location.declaringType()); } private static boolean signatureMatches(Method method, final String expectedSignature) throws EvaluateException { diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/JavaValue.java b/java/debugger/impl/src/com/intellij/debugger/engine/JavaValue.java index c238aaf35792..821311a05063 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/JavaValue.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/JavaValue.java @@ -294,7 +294,7 @@ public class JavaValue extends XNamedValue implements NodeDescriptorProvider, XV String value = myValue; if (myValueDescriptor.isString()) { - renderer.renderStringValue(myValue, "\"\\", XValueNode.MAX_VALUE_LENGTH); + renderer.renderStringValue(myValue, "\"", XValueNode.MAX_VALUE_LENGTH); return; } else if (myValueDescriptor.getLastRenderer() instanceof ToStringRenderer || diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/SuspendManagerImpl.java b/java/debugger/impl/src/com/intellij/debugger/engine/SuspendManagerImpl.java index 2800d5a6f15f..0fe1e45cc5dc 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/SuspendManagerImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/SuspendManagerImpl.java @@ -15,7 +15,7 @@ */ package com.intellij.debugger.engine; -import com.intellij.debugger.engine.events.SuspendContextCommandImpl; +import com.intellij.debugger.engine.events.DebuggerCommandImpl; import com.intellij.debugger.jdi.ThreadReferenceProxyImpl; import com.intellij.openapi.diagnostic.Logger; import com.sun.jdi.InternalException; @@ -309,9 +309,9 @@ public class SuspendManagerImpl implements SuspendManager { if(suspendContext.myVotesToVote == 0) { if(suspendContext.myIsVotedForResume) { // resume in a separate request to allow other requests be processed (e.g. dependent bpts enable) - myDebugProcess.getManagerThread().schedule(new SuspendContextCommandImpl(suspendContext) { + myDebugProcess.getManagerThread().schedule(new DebuggerCommandImpl() { @Override - public void contextAction() throws Exception { + protected void action() throws Exception { resume(suspendContext); } diff --git a/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerUtilsEx.java b/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerUtilsEx.java index fbf830dd422f..b26262196823 100644 --- a/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerUtilsEx.java +++ b/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerUtilsEx.java @@ -872,7 +872,8 @@ public abstract class DebuggerUtilsEx extends DebuggerUtils { } @Nullable - public static PsiParameterListOwner getContainingMethod(@NotNull SourcePosition position) { + public static PsiParameterListOwner getContainingMethod(@Nullable SourcePosition position) { + if (position == null) return null; return getContainingMethod(position.getElementAt()); } diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightNamesUtil.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightNamesUtil.java index 15e75c71e8af..eb085f3649eb 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightNamesUtil.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightNamesUtil.java @@ -191,9 +191,9 @@ public class HighlightNamesUtil { return HighlightInfoType.LOCAL_VARIABLE; } if (var instanceof PsiField) { - return var.hasModifierProperty(PsiModifier.STATIC) ? var.hasModifierProperty(PsiModifier.FINAL) - ? HighlightInfoType.STATIC_FINAL_FIELD - : HighlightInfoType.STATIC_FIELD : HighlightInfoType.INSTANCE_FIELD; + return var.hasModifierProperty(PsiModifier.STATIC) + ? var.hasModifierProperty(PsiModifier.FINAL) ? HighlightInfoType.STATIC_FINAL_FIELD : HighlightInfoType.STATIC_FIELD + : var.hasModifierProperty(PsiModifier.FINAL) ? HighlightInfoType.INSTANCE_FINAL_FIELD : HighlightInfoType.INSTANCE_FIELD; } if (var instanceof PsiParameter) { return HighlightInfoType.PARAMETER; diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/MarkerType.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/MarkerType.java index ed26f09a0aaf..d7ba10395840 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/MarkerType.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/MarkerType.java @@ -57,8 +57,7 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.event.MouseEvent; import java.text.MessageFormat; -import java.util.Arrays; -import java.util.Comparator; +import java.util.*; public class MarkerType { @@ -285,11 +284,12 @@ public class MarkerType { new PsiElementProcessor.CollectElementsWithLimit(2, new THashSet()); final PsiElementProcessor.CollectElementsWithLimit collectExprProcessor = new PsiElementProcessor.CollectElementsWithLimit(2, new THashSet()); + final boolean isAbstract = method.hasModifierProperty(PsiModifier.ABSTRACT); if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable() { @Override public void run() { OverridingMethodsSearch.search(method, true).forEach(new PsiElementProcessorAdapter(collectProcessor)); - if (collectProcessor.getCollection().isEmpty()) { + if (isAbstract && collectProcessor.getCollection().size() < 2) { final PsiClass aClass = ApplicationManager.getApplication().runReadAction(new Computable() { @Override public PsiClass compute() { @@ -306,13 +306,15 @@ public class MarkerType { } final PsiMethod[] methodOverriders = collectProcessor.toArray(PsiMethod.EMPTY_ARRAY); - NavigatablePsiElement[] overridings = ArrayUtil.mergeArrays(methodOverriders, collectExprProcessor.toArray(PsiFunctionalExpression.EMPTY_ARRAY)); - if (overridings.length == 0) return; + final List overridings = new ArrayList(); + overridings.addAll(collectProcessor.getCollection()); + overridings.addAll(collectExprProcessor.getCollection()); + if (overridings.isEmpty()) return; boolean showMethodNames = !PsiUtil.allMethodsHaveSameSignature(methodOverriders); MethodOrFunctionalExpressionCellRenderer renderer = new MethodOrFunctionalExpressionCellRenderer(showMethodNames); - Arrays.sort(overridings, renderer.getComparator()); + Collections.sort(overridings, renderer.getComparator()); final OverridingMethodsUpdater methodsUpdater = new OverridingMethodsUpdater(method, renderer); - PsiElementListNavigator.openTargets(e, overridings, methodsUpdater.getCaption(overridings.length), "Overriding methods of " + method.getName(), renderer, methodsUpdater); + PsiElementListNavigator.openTargets(e, overridings.toArray(new NavigatablePsiElement[overridings.size()]), methodsUpdater.getCaption(overridings.size()), "Overriding methods of " + method.getName(), renderer, methodsUpdater); } private static final String SEARCHING_FOR_OVERRIDDEN_METHODS = "Searching for Overridden Methods"; @@ -380,7 +382,7 @@ public class MarkerType { @Override public void run() { ClassInheritorsSearch.search(aClass, true).forEach(new PsiElementProcessorAdapter(collectProcessor)); - if (collectProcessor.getCollection().isEmpty()) { + if (collectProcessor.getCollection().size() < 2) { FunctionalExpressionSearch.search(aClass).forEach(new PsiElementProcessorAdapter(collectExprProcessor)); } } @@ -388,13 +390,14 @@ public class MarkerType { return; } - NavigatablePsiElement[] inheritors = ArrayUtil.mergeArrays(collectProcessor.toArray(PsiClass.EMPTY_ARRAY), - collectExprProcessor.toArray(PsiFunctionalExpression.EMPTY_ARRAY)); - if (inheritors.length == 0) return; + final List inheritors = new ArrayList(); + inheritors.addAll(collectProcessor.getCollection()); + inheritors.addAll(collectExprProcessor.getCollection()); + if (inheritors.isEmpty()) return; final PsiClassOrFunctionalExpressionListCellRenderer renderer = new PsiClassOrFunctionalExpressionListCellRenderer(); final SubclassUpdater subclassUpdater = new SubclassUpdater(aClass, renderer); - Arrays.sort(inheritors, renderer.getComparator()); - PsiElementListNavigator.openTargets(e, inheritors, subclassUpdater.getCaption(inheritors.length), CodeInsightBundle.message("goto.implementation.findUsages.title", aClass.getName()), renderer, subclassUpdater); + Collections.sort(inheritors, renderer.getComparator()); + PsiElementListNavigator.openTargets(e, inheritors.toArray(new NavigatablePsiElement[inheritors.size()]), subclassUpdater.getCaption(inheritors.size()), CodeInsightBundle.message("goto.implementation.findUsages.title", aClass.getName()), renderer, subclassUpdater); } private static class SubclassUpdater extends ListBackgroundUpdaterTask { diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/JetBrainsAnnotationsExternalLibraryResolver.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/JetBrainsAnnotationsExternalLibraryResolver.java index 5ffede07efd7..f893306df1d8 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/JetBrainsAnnotationsExternalLibraryResolver.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/JetBrainsAnnotationsExternalLibraryResolver.java @@ -37,7 +37,7 @@ import java.util.List; * @author nik */ public class JetBrainsAnnotationsExternalLibraryResolver extends ExternalLibraryResolver { - private static final ExternalLibraryDescriptor JAVA5 = new JetBrainsAnnotationsLibraryDescriptor() { + private static final ExternalLibraryDescriptor JAVA5 = new JetBrainsAnnotationsLibraryDescriptor("annotations-java5") { @NotNull @Override public List getLibraryClassesRoots() { @@ -49,7 +49,7 @@ public class JetBrainsAnnotationsExternalLibraryResolver extends ExternalLibrary } }; - private static final ExternalLibraryDescriptor JAVA8 = new JetBrainsAnnotationsLibraryDescriptor() { + private static final ExternalLibraryDescriptor JAVA8 = new JetBrainsAnnotationsLibraryDescriptor("annotations") { @NotNull @Override public List getLibraryClassesRoots() { @@ -86,8 +86,8 @@ public class JetBrainsAnnotationsExternalLibraryResolver extends ExternalLibrary } private static abstract class JetBrainsAnnotationsLibraryDescriptor extends ExternalLibraryDescriptor { - public JetBrainsAnnotationsLibraryDescriptor() { - super("com.intellij", "annotations"); + public JetBrainsAnnotationsLibraryDescriptor(final String artifactId) { + super("org.jetbrains", artifactId); } } } diff --git a/java/java-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java b/java/java-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java index bd39b5f96f47..51f5789ff5b5 100644 --- a/java/java-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java +++ b/java/java-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java @@ -41,6 +41,7 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; import com.intellij.psi.impl.JavaConstantExpressionEvaluator; import com.intellij.psi.impl.source.tree.JavaDocElementType; +import com.intellij.psi.impl.source.tree.JavaElementType; import com.intellij.psi.javadoc.*; import com.intellij.psi.search.EverythingGlobalScope; import com.intellij.psi.util.PsiFormatUtil; @@ -732,7 +733,7 @@ public class JavaDocInfoGenerator { if (packageInfoFile != null) { final ASTNode node = packageInfoFile.getNode(); if (node != null) { - final ASTNode docCommentNode = node.findChildByType(JavaDocElementType.DOC_COMMENT); + final ASTNode docCommentNode = findRelevantCommentNode(node); if (docCommentNode != null) { final PsiDocComment docComment = (PsiDocComment)docCommentNode.getPsi(); @@ -755,6 +756,19 @@ public class JavaDocInfoGenerator { } } + /** + * Finds doc comment immediately preceding package statement + */ + @Nullable + private static ASTNode findRelevantCommentNode(@NotNull ASTNode fileNode) { + ASTNode node = fileNode.findChildByType(JavaElementType.PACKAGE_STATEMENT); + if (node == null) node = fileNode.getLastChildNode(); + while (node != null && node.getElementType() != JavaDocElementType.DOC_COMMENT) { + node = node.getTreePrev(); + } + return node; + } + public void generateCommonSection(StringBuilder buffer, PsiDocComment docComment) { generateDescription(buffer, docComment); generateApiSection(buffer, docComment); diff --git a/java/java-impl/src/com/intellij/openapi/options/colors/pages/JavaColorSettingsPage.java b/java/java-impl/src/com/intellij/openapi/options/colors/pages/JavaColorSettingsPage.java index b04d68f42a5e..2e9e6b23c9d5 100644 --- a/java/java-impl/src/com/intellij/openapi/options/colors/pages/JavaColorSettingsPage.java +++ b/java/java-impl/src/com/intellij/openapi/options/colors/pages/JavaColorSettingsPage.java @@ -71,6 +71,7 @@ public class JavaColorSettingsPage implements ColorSettingsPage, InspectionColor new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.reassigned.parameter"), CodeInsightColors.REASSIGNED_PARAMETER_ATTRIBUTES), new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.implicit.anonymous.parameter"), CodeInsightColors.IMPLICIT_ANONYMOUS_CLASS_PARAMETER_ATTRIBUTES), new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.instance.field"), CodeInsightColors.INSTANCE_FIELD_ATTRIBUTES), + new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.instance.final.field"), CodeInsightColors.INSTANCE_FINAL_FIELD_ATTRIBUTES), new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.static.field"), CodeInsightColors.STATIC_FIELD_ATTRIBUTES), new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.static.final.field"), CodeInsightColors.STATIC_FINAL_FIELD_ATTRIBUTES), new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.parameter"), CodeInsightColors.PARAMETER_ATTRIBUTES), @@ -120,6 +121,7 @@ public class JavaColorSettingsPage implements ColorSettingsPage, InspectionColor ourTags.put("annotationName", CodeInsightColors.ANNOTATION_NAME_ATTRIBUTES); ourTags.put("annotationAttributeName", CodeInsightColors.ANNOTATION_ATTRIBUTE_NAME_ATTRIBUTES); ourTags.put("javadocTagValue", JavaHighlightingColors.DOC_COMMENT_TAG_VALUE); + ourTags.put("instanceFinalField", CodeInsightColors.INSTANCE_FINAL_FIELD_ATTRIBUTES); } @Override @@ -168,6 +170,7 @@ public class JavaColorSettingsPage implements ColorSettingsPage, InspectionColor " private double unusedField = 12345.67890;\n" + " private UnknownType anotherString = \"Another\\nStrin\\g\";\n" + " public static int staticField = 0;\n" + + " public final int instanceFinalField = 0;\n" + "\n" + " public SomeClass(AnInterface param, int[] reassignedParam) {\n" + " int localVar = \"IntelliJ\"; // Error, incompatible types\n" + diff --git a/java/java-impl/src/com/intellij/refactoring/inlineSuperClass/InlineSuperClassRefactoringDialog.java b/java/java-impl/src/com/intellij/refactoring/inlineSuperClass/InlineSuperClassRefactoringDialog.java index a182e76e1a5b..081ca8ce3750 100644 --- a/java/java-impl/src/com/intellij/refactoring/inlineSuperClass/InlineSuperClassRefactoringDialog.java +++ b/java/java-impl/src/com/intellij/refactoring/inlineSuperClass/InlineSuperClassRefactoringDialog.java @@ -28,7 +28,9 @@ import com.intellij.refactoring.RefactoringBundle; import com.intellij.refactoring.inline.InlineOptionsDialog; import com.intellij.refactoring.ui.DocCommentPanel; import com.intellij.ui.IdeBorderFactory; +import com.intellij.ui.ScrollPaneFactory; import com.intellij.util.Function; +import com.intellij.util.ui.JBDimension; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -83,13 +85,16 @@ public class InlineSuperClassRefactoringDialog extends InlineOptionsDialog { } }, "\',
   \'") + "\'"); - label.setBorder(IdeBorderFactory.createEmptyBorder(5, 5, 5, 5)); final JPanel panel = new JPanel(new GridBagLayout()); final GridBagConstraints gc = new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 1, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0); panel.add(myDocPanel, gc); - panel.add(label, gc); + JScrollPane pane = ScrollPaneFactory.createScrollPane(label); + pane.setBorder(IdeBorderFactory.createEmptyBorder(5, 5, 5, 5)); + pane.setMinimumSize(JBDimension.create(new Dimension(-1, 100))); + pane.setMaximumSize(JBDimension.create(new Dimension(-1, 400))); + panel.add(pane, gc); gc.weighty = 1; gc.fill = GridBagConstraints.BOTH; panel.add(super.createCenterPanel(), gc); diff --git a/java/java-psi-impl/src/com/intellij/codeInsight/ExceptionUtil.java b/java/java-psi-impl/src/com/intellij/codeInsight/ExceptionUtil.java index 92fe13866aac..ec6c6d740217 100644 --- a/java/java-psi-impl/src/com/intellij/codeInsight/ExceptionUtil.java +++ b/java/java-psi-impl/src/com/intellij/codeInsight/ExceptionUtil.java @@ -268,10 +268,10 @@ public class ExceptionUtil { else if (element instanceof PsiMethodReferenceExpression) { PsiExpression qualifierExpression = ((PsiMethodReferenceExpression)element).getQualifierExpression(); return qualifierExpression != null ? collectUnhandledExceptions(qualifierExpression, topElement, null, false) - : Collections.emptySet(); + : null; } else if (element instanceof PsiLambdaExpression) { - return Collections.emptySet(); + return null; } else if (element instanceof PsiThrowStatement) { PsiThrowStatement statement = (PsiThrowStatement)element; diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/TypeCorrector.java b/java/java-psi-impl/src/com/intellij/psi/impl/TypeCorrector.java index fe414c8255dd..a56b50c725fa 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/TypeCorrector.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/TypeCorrector.java @@ -118,7 +118,12 @@ class TypeCorrector extends PsiTypeMapper { private PsiSubstitutor mapSubstitutor(PsiClass originalClass, PsiClass mappedClass, PsiSubstitutor substitutor) { PsiTypeParameter[] typeParameters = mappedClass.getTypeParameters(); PsiTypeParameter[] originalTypeParameters = originalClass.getTypeParameters(); - if (typeParameters.length != originalTypeParameters.length) return substitutor; + if (typeParameters.length != originalTypeParameters.length) { + if (originalTypeParameters.length == 0) { + return JavaPsiFacade.getElementFactory(mappedClass.getProject()).createRawSubstitutor(mappedClass); + } + return substitutor; + } Map substitutionMap = substitutor.getSubstitutionMap(); diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ExceptionCollectionWithLambda.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ExceptionCollectionWithLambda.java new file mode 100644 index 000000000000..1ffb96765917 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/ExceptionCollectionWithLambda.java @@ -0,0 +1,24 @@ + + + +import java.io.File; +import java.io.IOException; +interface I { + void m(String s) throws IOException; +} +class Test { + public void test() throws IOException { + File file = new File("temp"); + try { + for(int t = 0; t < 4; ++t) { + for (int i = 0; i < 10; ++i) { + I appender = out -> File.createTempFile("", "").exists(); + appender.m(""); + } + } + } + finally { + System.out.println(file); + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/javadocIG/packageInfoWithCopyright/package-info.java b/java/java-tests/testData/codeInsight/javadocIG/packageInfoWithCopyright/package-info.java new file mode 100644 index 000000000000..5ee475914eef --- /dev/null +++ b/java/java-tests/testData/codeInsight/javadocIG/packageInfoWithCopyright/package-info.java @@ -0,0 +1,8 @@ +/** + * Copyright + */ + +/** + * This package contains nothing but package-info.java + */ +package packageInfoWithCopyright; \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/javadocIG/packageInfoWithCopyright/packageInfo.html b/java/java-tests/testData/codeInsight/javadocIG/packageInfoWithCopyright/packageInfo.html new file mode 100644 index 000000000000..3c7ff895009c --- /dev/null +++ b/java/java-tests/testData/codeInsight/javadocIG/packageInfoWithCopyright/packageInfo.html @@ -0,0 +1,2 @@ + + This package contains nothing but package-info.java \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/multipleJdks/java3/p/RawAssignmentToGenerics.java b/java/java-tests/testData/codeInsight/multipleJdks/java3/p/RawAssignmentToGenerics.java new file mode 100644 index 000000000000..ac1f647a60c3 --- /dev/null +++ b/java/java-tests/testData/codeInsight/multipleJdks/java3/p/RawAssignmentToGenerics.java @@ -0,0 +1,9 @@ +package p; + +import java.util.Map; + +public class Bar { + public static Map get() { + return null; + } +} diff --git a/java/java-tests/testData/codeInsight/multipleJdks/java7/p/RawAssignmentToGenerics.java b/java/java-tests/testData/codeInsight/multipleJdks/java7/p/RawAssignmentToGenerics.java new file mode 100644 index 000000000000..79fa8888d330 --- /dev/null +++ b/java/java-tests/testData/codeInsight/multipleJdks/java7/p/RawAssignmentToGenerics.java @@ -0,0 +1,7 @@ +package p; +import java.util.Map; +class Foo { + { + Map m = Bar.get(); + } +} diff --git a/java/java-tests/testData/dependencies/search/forwardJdkClasses/A.java b/java/java-tests/testData/dependencies/search/forwardJdkClasses/A.java new file mode 100644 index 000000000000..76994122f096 --- /dev/null +++ b/java/java-tests/testData/dependencies/search/forwardJdkClasses/A.java @@ -0,0 +1,3 @@ +public class A{ + String myName; +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/indent/BinaryOperation.java b/java/java-tests/testData/psi/formatter/indent/BinaryOperation.java new file mode 100644 index 000000000000..100682d90642 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/indent/BinaryOperation.java @@ -0,0 +1,7 @@ + +public class Foo { + public void foo() { + abc = x + +2; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/indent/BinaryOperationSignMoved.java b/java/java-tests/testData/psi/formatter/indent/BinaryOperationSignMoved.java new file mode 100644 index 000000000000..1213742d42ac --- /dev/null +++ b/java/java-tests/testData/psi/formatter/indent/BinaryOperationSignMoved.java @@ -0,0 +1,7 @@ + +public class Foo { + public void foo() { + abc = x + + 2; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/indent/BinaryOperationSignMoved_after.java b/java/java-tests/testData/psi/formatter/indent/BinaryOperationSignMoved_after.java new file mode 100644 index 000000000000..bb4ec689eace --- /dev/null +++ b/java/java-tests/testData/psi/formatter/indent/BinaryOperationSignMoved_after.java @@ -0,0 +1,7 @@ + +public class Foo { + public void foo() { + abc = x + + 2; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/indent/BinaryOperation_after.java b/java/java-tests/testData/psi/formatter/indent/BinaryOperation_after.java new file mode 100644 index 000000000000..3ea3fcf919f8 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/indent/BinaryOperation_after.java @@ -0,0 +1,6 @@ +public class Foo { + public void foo() { + abc = x + + 2; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/indent/DoNotIndentTopLevelClassMembers.java b/java/java-tests/testData/psi/formatter/indent/DoNotIndentTopLevelClassMembers.java new file mode 100644 index 000000000000..8e659ec3cd60 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/indent/DoNotIndentTopLevelClassMembers.java @@ -0,0 +1,12 @@ + +public class Foo { + public void foo() { + x += 2; + } + + public static class Inner { + public void bar() { + y += 2; + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/indent/DoNotIndentTopLevelClassMembers_after.java b/java/java-tests/testData/psi/formatter/indent/DoNotIndentTopLevelClassMembers_after.java new file mode 100644 index 000000000000..de32576f0b74 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/indent/DoNotIndentTopLevelClassMembers_after.java @@ -0,0 +1,12 @@ + +public class Foo { +public void foo() { + x += 2; +} + +public static class Inner { + public void bar() { + y += 2; + } +} +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/indent/ImplementsList.java b/java/java-tests/testData/psi/formatter/indent/ImplementsList.java new file mode 100644 index 000000000000..1f6571eb36d7 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/indent/ImplementsList.java @@ -0,0 +1,6 @@ + +public class Foo implements + Seralizable, + Throwable, +Cloneable { +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/indent/ImplementsList2.java b/java/java-tests/testData/psi/formatter/indent/ImplementsList2.java new file mode 100644 index 000000000000..c4b7d091f1f2 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/indent/ImplementsList2.java @@ -0,0 +1,5 @@ + +public class Foo implements Seralizable, + Throwable, +Cloneable { +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/indent/ImplementsList2_after.java b/java/java-tests/testData/psi/formatter/indent/ImplementsList2_after.java new file mode 100644 index 000000000000..8d033a8043d4 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/indent/ImplementsList2_after.java @@ -0,0 +1,5 @@ + +public class Foo implements Seralizable, + Throwable, + Cloneable { +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/indent/ImplementsList_after.java b/java/java-tests/testData/psi/formatter/indent/ImplementsList_after.java new file mode 100644 index 000000000000..03c04f6b46c2 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/indent/ImplementsList_after.java @@ -0,0 +1,6 @@ + +public class Foo implements + Seralizable, + Throwable, + Cloneable { +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/indent/ParenthesizedBinop.java b/java/java-tests/testData/psi/formatter/indent/ParenthesizedBinop.java new file mode 100644 index 000000000000..a2d9753b45c8 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/indent/ParenthesizedBinop.java @@ -0,0 +1,8 @@ + +public class foo { + { + abc = (a + +b +); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/indent/ParenthesizedBinop_after.java b/java/java-tests/testData/psi/formatter/indent/ParenthesizedBinop_after.java new file mode 100644 index 000000000000..8acfcca5670f --- /dev/null +++ b/java/java-tests/testData/psi/formatter/indent/ParenthesizedBinop_after.java @@ -0,0 +1,8 @@ + +public class foo { + { + abc = (a + + b + ); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/indent/ParenthesizedContinuation.java b/java/java-tests/testData/psi/formatter/indent/ParenthesizedContinuation.java new file mode 100644 index 000000000000..62045971100d --- /dev/null +++ b/java/java-tests/testData/psi/formatter/indent/ParenthesizedContinuation.java @@ -0,0 +1,8 @@ + +public class foo { + { + abc = ( +a + b +); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/indent/ParenthesizedContinuation2.java b/java/java-tests/testData/psi/formatter/indent/ParenthesizedContinuation2.java new file mode 100644 index 000000000000..0dc002325e77 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/indent/ParenthesizedContinuation2.java @@ -0,0 +1,7 @@ + +public class foo { + { + abc = ( +a + b); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/indent/ParenthesizedContinuation2_after.java b/java/java-tests/testData/psi/formatter/indent/ParenthesizedContinuation2_after.java new file mode 100644 index 000000000000..375a1ac7e34c --- /dev/null +++ b/java/java-tests/testData/psi/formatter/indent/ParenthesizedContinuation2_after.java @@ -0,0 +1,7 @@ + +public class foo { + { + abc = ( + a + b); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/indent/ParenthesizedContinuation_after.java b/java/java-tests/testData/psi/formatter/indent/ParenthesizedContinuation_after.java new file mode 100644 index 000000000000..0bfedc395793 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/indent/ParenthesizedContinuation_after.java @@ -0,0 +1,8 @@ + +public class foo { + { + abc = ( + a + b + ); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/indent/SCR3681.java b/java/java-tests/testData/psi/formatter/indent/SCR3681.java new file mode 100644 index 000000000000..47eff20c8242 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/indent/SCR3681.java @@ -0,0 +1,3 @@ +class Foo { // comment here + int a; +} diff --git a/java/java-tests/testData/psi/formatter/indent/SCR3681_after.java b/java/java-tests/testData/psi/formatter/indent/SCR3681_after.java new file mode 100644 index 000000000000..825d5757a725 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/indent/SCR3681_after.java @@ -0,0 +1,4 @@ + +class Foo { // comment here + int a; +} diff --git a/java/java-tests/testData/psi/formatter/indent/TernaryOperation.java b/java/java-tests/testData/psi/formatter/indent/TernaryOperation.java new file mode 100644 index 000000000000..64f459d05788 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/indent/TernaryOperation.java @@ -0,0 +1,8 @@ + +public class Foo { + public void foo() { + abcd = x ? +2 : +3; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/indent/TernaryOperationSignMoved.java b/java/java-tests/testData/psi/formatter/indent/TernaryOperationSignMoved.java new file mode 100644 index 000000000000..173288707aa2 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/indent/TernaryOperationSignMoved.java @@ -0,0 +1,8 @@ + +public class Foo { + public void foo() { + abc = x +? 2 +: 3; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/indent/TernaryOperationSignMoved_after.java b/java/java-tests/testData/psi/formatter/indent/TernaryOperationSignMoved_after.java new file mode 100644 index 000000000000..f5fe139037bc --- /dev/null +++ b/java/java-tests/testData/psi/formatter/indent/TernaryOperationSignMoved_after.java @@ -0,0 +1,8 @@ + +public class Foo { + public void foo() { + abc = x + ? 2 + : 3; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/indent/TernaryOperation_after.java b/java/java-tests/testData/psi/formatter/indent/TernaryOperation_after.java new file mode 100644 index 000000000000..b5b685fe0053 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/indent/TernaryOperation_after.java @@ -0,0 +1,8 @@ + +public class Foo { + public void foo() { + abcd = x ? + 2 : + 3; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/java/paymentManager.java b/java/java-tests/testData/psi/formatter/java/paymentManager.java new file mode 100644 index 000000000000..22910e4df49a --- /dev/null +++ b/java/java-tests/testData/psi/formatter/java/paymentManager.java @@ -0,0 +1,409 @@ +package cms.si.payment; + +import cms.AmountMoreThanBalanceException; + +import cms.db.*; + +import cms.db.payments.px.PayConRequest; + +import cms.db.payments.px.PayConResponse; + +import cms.db.payments.px.PayConStatus; + +import cms.hibernate.HibernateSessionFactory; + +import cms.si.payment.px.PayConPaymentSystem; + +import cms.si.payment.px.PaymentException; + +import org.apache.commons.logging.Log; + +import org.apache.commons.logging.LogFactory; + +import org.hibernate.Query; + +import org.hibernate.Session; + +import javax.servlet.http.HttpServletRequest; + +import java.util.*; + +/** + * @author alf + * @author Alexey Malkovskiy + */ +public class PaymentManager { + + private static final Log log = LogFactory.getLog(PaymentManager.class); + + public static final int TRANSACTION_PENDING = 1; + + public static final int TRANSACTION_PROCESSED = 2; + + public static final int TRANSACTION_DECLINED = 3; + + + + + + + + + + + + + + + public BillingInfo billCreditCard(Player player, Long transactionID, CreditCard card, + + double amount, String ipAddress, String customerRef) throws WrongAmountException, PaymentException { + + player.setUpdateDate(new Date()); + + PayConPaymentSystem px = PayConPaymentSystem.getInstance(); + + String strTransactionID = px.getTrackID(transactionID); + + // here comes authorization code + PayConRequest request = px.createAuthRequest(player.getCurrency().getId(), + + strTransactionID, card, amount, ipAddress, player.getUsername()); + + PayConResponse response = px.sendRequest(request); + + if (response.getReturnCode() != ReturnCode.RETURN_CODE_SUCCESS || + + response.getStatus().getAuthCode() != AuthorizationFailureObject.SUCCESS) + + throw new PaymentException(); + + double paid = response.getStatus().getAmountPaid(); + + if (amount != paid) + + throw new WrongAmountException(amount, paid); + + player.incrementBalance(paid); + + log.info("billCreditCard player " + player.getId() + " TrackID " + strTransactionID + + + " added " + amount + + + " to balance because the credit card was charged for this amount"); + + return new BillingInfo(response.getStatus().getAmountPaid(), + + response.getStatus().getAmountReq(), + + response.getStatus().getTransactionId()); + + } + + + + + + + + + public void performDeposit(double amount, Player player, CreditCardInfo info, + + HttpServletRequest request, String remoteHost) throws PaymentException, WrongAmountException { + + org.hibernate.Transaction tx = HibernateSessionFactory.currentSession().beginTransaction(); + + Transaction t = new Transaction(); + + t.setAmount(amount); + + t.setType(TransactionType.DEPOSIT); + + t.setStatus(TransactionStatus.PENDING); + + t.setCreateDate(new Date()); + + t.setPlayer(player); + + saveNow(t); + + try { + BillingInfo billingInfo = billCreditCard(player, t.getId(), info, amount, remoteHost, + + player.getUsername()); + + t.setStatus(TransactionStatus.COMPLETED); + + t.setExternalId(billingInfo.getTransactionId()); + + t.setProcessDate(new Date()); + + } catch (PaymentException e) { + log.error("Payment problem", e); + + // TODO + } catch ( + WrongAmountException e + ) { + log.error("Wrong amount", e); + // TODO + } + + tx.commit + + (); + } + + + + + + + + + + + + + + + + + private void saveNow(Transaction t) { + Session + session + = + HibernateSessionFactory + .currentSession(); + + session + . + save + ( + t + ); + session. + flush() + ; + } + + @SuppressWarnings + ( + "unchecked" + ) + public + UserCashOut + performCashOut( + double + amount + , + Player + player + ) + throws + AmountMoreThanBalanceException { + Session + ses + = + HibernateSessionFactory + . + currentSession + () + ; + + if (player.getBalanceAmt() < amount) { + throw new AmountMoreThanBalanceException(); + } + + org + . + hibernate + . + Transaction + tx + = + ses + . + beginTransaction + ( + ) + ; + + UserCashOut + userCashOut + = + new + UserCashOut + ( + + ); + userCashOut.setAmount(amount); + userCashOut.setCreateDate(new Date()); + userCashOut.setPlayer(player); + player.getCashOuts().add(userCashOut); + ses.save(userCashOut); + double checkAmount = 0; + double amountForPay = amount; + boolean freeDebitsExist = true; + // + while (amountForPay > 0 && freeDebitsExist) { + List freeDebits = findFreeDebits(player, ses); + if (freeDebits.isEmpty()) { + freeDebitsExist = false; + checkAmount += amountForPay; + } else { + double oldAmount = amountForPay; + amountForPay = createCredits(amountForPay, player, freeDebits, userCashOut, ses); + amountForPay += payCredits(freeDebits, userCashOut, ses); + if (amountForPay == oldAmount) { + //This is strange and hypothetical situation. It can mean + //that PaymentConnexions doesn't work properly. Pay by check. + freeDebitsExist = false; + checkAmount += amountForPay; + } + } + ses.flush(); + } + // + if (checkAmount > 0) { + payCheck(player, ses, userCashOut, checkAmount); + } + player.setBalanceAmt(player.getBalanceAmt() - amount); + tx.commit(); + return userCashOut; + } + private void payCheck(Player player, Session ses, UserCashOut userCashOut, double checkAmount) { + Check check = new Check(); + check.setAmount(checkAmount); + check.setCreateDate(new Date()); + check.setPlayer(player); + player.getChecks().add(check); + check.setUserCashOut(userCashOut); + userCashOut.setCheck(check); + Transaction transaction = new Transaction(); + transaction.setAmount(-checkAmount); + transaction.setCreateDate(new Date()); + transaction.setProcessDate(new Date()); + transaction.setType(TransactionType.CASHOUT); + transaction.setStatus(TransactionStatus.PENDING); + transaction.setPlayer(player); + check.setTransaction(transaction); + transaction.setCheck(check); + ses.save(transaction); + ses.save(check); + } + private double payCredits(List freeDebits, UserCashOut userCashOut, + Session ses) { + double unpaidAmount = 0; + for (CashOutDebitInfo info : freeDebits) { + try { + String trackId = "Tr" + info.credit.getId(); + PayConRequest creditRequest = PayConPaymentSystem.getInstance().createReversalRequest( + userCashOut.getPlayer().getCurrency().getId(), + trackId, -info.credit.getAmount(), + new Long(info.debit.getExternalId())); + PayConResponse response = PayConPaymentSystem.getInstance().sendRequest(creditRequest); + final PayConStatus status = response.getStatus(); + if (response.getReturnCode() == ReturnCode.RETURN_CODE_SUCCESS && + status.getAuthCode() == AuthorizationFailureObject.SUCCESS) { + info.credit.setAmount(-status.getAmountPaid()); + info.credit.setExternalId(status.getTransactionId()); + info.credit.setStatus(TransactionStatus.COMPLETED); + info.credit.setProcessDate(new Date()); + } else { + switch (status.getAuthCode()) { + case TRANSACTION_PENDING: + info.credit.setStatus(TransactionStatus.PENDING); + break; + case TRANSACTION_PROCESSED: + //This is hypothetical situation. We have to delete this credit + //transaction. Original debit transaction still free for + //future credits. + ses.delete(info.credit); + info.credit = null; + break; + case TRANSACTION_DECLINED: + default: + info.debit.getCreditTransactions().remove(info.credit); + info.credit.setOriginalDebitTransaction(null); + info.debit.setCreditStatus("ERROR - " + status.getAuthCode()); + userCashOut.getCredits().remove(info.credit); + info.credit.setUserCashOut(null); + unpaidAmount += -info.credit.getAmount(); + ses.delete(info.credit); + break; + } + } + } catch (PaymentException e) { + // ignore + //log.error(e.getMessage(), e); + } + } + return unpaidAmount; + } + private double createCredits(double amount, Player player, List freeDebits, UserCashOut userCashOut, Session ses) { + double checkAmount = amount; + int i = 0; + for (CashOutDebitInfo debitInfo : freeDebits) { + Transaction credit = new Transaction(); + if (checkAmount > debitInfo.remainder) { + credit.setAmount(-debitInfo.remainder); + checkAmount -= debitInfo.remainder; + } else { + credit.setAmount(-checkAmount); + checkAmount = 0; + } + credit.setCreateDate(new Date()); + credit.setOriginalDebitTransaction(debitInfo.debit); + debitInfo.debit.getCreditTransactions().add(credit); + credit.setPlayer(player); + credit.setType(TransactionType.CASHOUT); + credit.setStatus(TransactionStatus.PENDING); + credit.setUserCashOut(userCashOut); + userCashOut.getCredits().add(credit); + debitInfo.credit = credit; + ses.save(credit); + i++; + if (checkAmount <= 0) { + break; + } + } + int size = freeDebits.size(); + for (int j = i; j < size; j++) { + freeDebits.remove(i); + } + return checkAmount; + } + @SuppressWarnings("unchecked") + private List findFreeDebits(Player player, Session ses) { + Calendar calendar = Calendar.getInstance(); + calendar.add(Calendar.MONTH, -6); + Query query = ses.createQuery("from Transaction as t where " + + "t.player = :player and t.createDate > :date " + + "and t.creditStatus is null and t.type = :type and " + + "(t.amount > (select sum(-t2.amount) from t.creditTransactions as t2) " + + "or t.creditTransactions is empty) " + //+ "where t2.status = :status) or t.creditTransactions is empty) " + + "and t.status = :status " + "and t.externalId is not null " + + "order by t.createDate"); + query.setEntity("player", player); + query.setDate("date", calendar.getTime()); + query.setInteger("type", TransactionType.DEPOSIT.getId()); + query.setInteger("status", TransactionStatus.COMPLETED.getId()); + //query.setInteger("status", TransactionStatus.COMPLETED.getId()); + List transactions = query.list(); + List freeDebits = new ArrayList(); + for (Transaction transaction : transactions) { + Set credits = transaction.getCreditTransactions(); + double sum = 0; + for (Transaction credit : credits) { + sum += credit.getAmount(); + } + CashOutDebitInfo info = new CashOutDebitInfo(); + info.debit = transaction; + info.remainder = transaction.getAmount() - sum; + freeDebits.add(info); + } + return freeDebits; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/java/paymentManager_after.java b/java/java-tests/testData/psi/formatter/java/paymentManager_after.java new file mode 100644 index 000000000000..6cec98878b3a --- /dev/null +++ b/java/java-tests/testData/psi/formatter/java/paymentManager_after.java @@ -0,0 +1,328 @@ +package cms.si.payment; + +import cms.AmountMoreThanBalanceException; + +import cms.db.*; + +import cms.db.payments.px.PayConRequest; + +import cms.db.payments.px.PayConResponse; + +import cms.db.payments.px.PayConStatus; + +import cms.hibernate.HibernateSessionFactory; + +import cms.si.payment.px.PayConPaymentSystem; + +import cms.si.payment.px.PaymentException; + +import org.apache.commons.logging.Log; + +import org.apache.commons.logging.LogFactory; + +import org.hibernate.Query; + +import org.hibernate.Session; + +import javax.servlet.http.HttpServletRequest; + +import java.util.*; + +/** + * @author alf + * @author Alexey Malkovskiy + */ +public class PaymentManager { + + private static final Log log = LogFactory.getLog(PaymentManager.class); + + public static final int TRANSACTION_PENDING = 1; + + public static final int TRANSACTION_PROCESSED = 2; + + public static final int TRANSACTION_DECLINED = 3; + + + public BillingInfo billCreditCard(Player player, Long transactionID, CreditCard card, + + double amount, String ipAddress, String customerRef) throws WrongAmountException, PaymentException { + + player.setUpdateDate(new Date()); + + PayConPaymentSystem px = PayConPaymentSystem.getInstance(); + + String strTransactionID = px.getTrackID(transactionID); + + // here comes authorization code + PayConRequest request = px.createAuthRequest(player.getCurrency().getId(), + + strTransactionID, card, amount, ipAddress, player.getUsername()); + + PayConResponse response = px.sendRequest(request); + + if (response.getReturnCode() != ReturnCode.RETURN_CODE_SUCCESS || + + response.getStatus().getAuthCode() != AuthorizationFailureObject.SUCCESS) + + throw new PaymentException(); + + double paid = response.getStatus().getAmountPaid(); + + if (amount != paid) + + throw new WrongAmountException(amount, paid); + + player.incrementBalance(paid); + + log.info("billCreditCard player " + player.getId() + " TrackID " + strTransactionID + + + " added " + amount + + + " to balance because the credit card was charged for this amount"); + + return new BillingInfo(response.getStatus().getAmountPaid(), + + response.getStatus().getAmountReq(), + + response.getStatus().getTransactionId()); + + } + + + public void performDeposit(double amount, Player player, CreditCardInfo info, + + HttpServletRequest request, String remoteHost) throws PaymentException, WrongAmountException { + + org.hibernate.Transaction tx = HibernateSessionFactory.currentSession().beginTransaction(); + + Transaction t = new Transaction(); + + t.setAmount(amount); + + t.setType(TransactionType.DEPOSIT); + + t.setStatus(TransactionStatus.PENDING); + + t.setCreateDate(new Date()); + + t.setPlayer(player); + + saveNow(t); + + try { + BillingInfo billingInfo = billCreditCard(player, t.getId(), info, amount, remoteHost, + + player.getUsername()); + + t.setStatus(TransactionStatus.COMPLETED); + + t.setExternalId(billingInfo.getTransactionId()); + + t.setProcessDate(new Date()); + + } catch (PaymentException e) { + log.error("Payment problem", e); + + // TODO + } catch (WrongAmountException e) { + log.error("Wrong amount", e); + // TODO + } + + tx.commit + + (); + } + + + private void saveNow(Transaction t) { + Session session = HibernateSessionFactory.currentSession(); + + session. + save(t); + session. + flush(); + } + + @SuppressWarnings( + "unchecked") + public UserCashOut performCashOut(double amount, Player player) throws AmountMoreThanBalanceException { + Session ses = HibernateSessionFactory. + currentSession(); + + if (player.getBalanceAmt() < amount) { + throw new AmountMoreThanBalanceException(); + } + + org. + hibernate. + Transaction tx = ses. + beginTransaction(); + + UserCashOut userCashOut = new UserCashOut( + + ); + userCashOut.setAmount(amount); + userCashOut.setCreateDate(new Date()); + userCashOut.setPlayer(player); + player.getCashOuts().add(userCashOut); + ses.save(userCashOut); + double checkAmount = 0; + double amountForPay = amount; + boolean freeDebitsExist = true; + // + while (amountForPay > 0 && freeDebitsExist) { + List freeDebits = findFreeDebits(player, ses); + if (freeDebits.isEmpty()) { + freeDebitsExist = false; + checkAmount += amountForPay; + } else { + double oldAmount = amountForPay; + amountForPay = createCredits(amountForPay, player, freeDebits, userCashOut, ses); + amountForPay += payCredits(freeDebits, userCashOut, ses); + if (amountForPay == oldAmount) { + //This is strange and hypothetical situation. It can mean + //that PaymentConnexions doesn't work properly. Pay by check. + freeDebitsExist = false; + checkAmount += amountForPay; + } + } + ses.flush(); + } + // + if (checkAmount > 0) { + payCheck(player, ses, userCashOut, checkAmount); + } + player.setBalanceAmt(player.getBalanceAmt() - amount); + tx.commit(); + return userCashOut; + } + + private void payCheck(Player player, Session ses, UserCashOut userCashOut, double checkAmount) { + Check check = new Check(); + check.setAmount(checkAmount); + check.setCreateDate(new Date()); + check.setPlayer(player); + player.getChecks().add(check); + check.setUserCashOut(userCashOut); + userCashOut.setCheck(check); + Transaction transaction = new Transaction(); + transaction.setAmount(-checkAmount); + transaction.setCreateDate(new Date()); + transaction.setProcessDate(new Date()); + transaction.setType(TransactionType.CASHOUT); + transaction.setStatus(TransactionStatus.PENDING); + transaction.setPlayer(player); + check.setTransaction(transaction); + transaction.setCheck(check); + ses.save(transaction); + ses.save(check); + } + + private double payCredits(List freeDebits, UserCashOut userCashOut, Session ses) { + double unpaidAmount = 0; + for (CashOutDebitInfo info : freeDebits) { + try { + String trackId = "Tr" + info.credit.getId(); + PayConRequest creditRequest = PayConPaymentSystem.getInstance().createReversalRequest(userCashOut.getPlayer().getCurrency().getId(), trackId, -info.credit.getAmount(), new Long(info.debit.getExternalId())); + PayConResponse response = PayConPaymentSystem.getInstance().sendRequest(creditRequest); + final PayConStatus status = response.getStatus(); + if (response.getReturnCode() == ReturnCode.RETURN_CODE_SUCCESS && status.getAuthCode() == AuthorizationFailureObject.SUCCESS) { + info.credit.setAmount(-status.getAmountPaid()); + info.credit.setExternalId(status.getTransactionId()); + info.credit.setStatus(TransactionStatus.COMPLETED); + info.credit.setProcessDate(new Date()); + } else { + switch (status.getAuthCode()) { + case TRANSACTION_PENDING: + info.credit.setStatus(TransactionStatus.PENDING); + break; + case TRANSACTION_PROCESSED: + //This is hypothetical situation. We have to delete this credit + //transaction. Original debit transaction still free for + //future credits. + ses.delete(info.credit); + info.credit = null; + break; + case TRANSACTION_DECLINED: + default: + info.debit.getCreditTransactions().remove(info.credit); + info.credit.setOriginalDebitTransaction(null); + info.debit.setCreditStatus("ERROR - " + status.getAuthCode()); + userCashOut.getCredits().remove(info.credit); + info.credit.setUserCashOut(null); + unpaidAmount += -info.credit.getAmount(); + ses.delete(info.credit); + break; + } + } + } catch (PaymentException e) { + // ignore + //log.error(e.getMessage(), e); + } + } + return unpaidAmount; + } + + private double createCredits(double amount, Player player, List freeDebits, UserCashOut userCashOut, Session ses) { + double checkAmount = amount; + int i = 0; + for (CashOutDebitInfo debitInfo : freeDebits) { + Transaction credit = new Transaction(); + if (checkAmount > debitInfo.remainder) { + credit.setAmount(-debitInfo.remainder); + checkAmount -= debitInfo.remainder; + } else { + credit.setAmount(-checkAmount); + checkAmount = 0; + } + credit.setCreateDate(new Date()); + credit.setOriginalDebitTransaction(debitInfo.debit); + debitInfo.debit.getCreditTransactions().add(credit); + credit.setPlayer(player); + credit.setType(TransactionType.CASHOUT); + credit.setStatus(TransactionStatus.PENDING); + credit.setUserCashOut(userCashOut); + userCashOut.getCredits().add(credit); + debitInfo.credit = credit; + ses.save(credit); + i++; + if (checkAmount <= 0) { + break; + } + } + int size = freeDebits.size(); + for (int j = i; j < size; j++) { + freeDebits.remove(i); + } + return checkAmount; + } + + @SuppressWarnings("unchecked") + private List findFreeDebits(Player player, Session ses) { + Calendar calendar = Calendar.getInstance(); + calendar.add(Calendar.MONTH, -6); + Query query = ses.createQuery("from Transaction as t where " + "t.player = :player and t.createDate > :date " + "and t.creditStatus is null and t.type = :type and " + "(t.amount > (select sum(-t2.amount) from t.creditTransactions as t2) " + "or t.creditTransactions is empty) " + //+ "where t2.status = :status) or t.creditTransactions is empty) " + + "and t.status = :status " + "and t.externalId is not null " + "order by t.createDate"); + query.setEntity("player", player); + query.setDate("date", calendar.getTime()); + query.setInteger("type", TransactionType.DEPOSIT.getId()); + query.setInteger("status", TransactionStatus.COMPLETED.getId()); + //query.setInteger("status", TransactionStatus.COMPLETED.getId()); + List transactions = query.list(); + List freeDebits = new ArrayList(); + for (Transaction transaction : transactions) { + Set credits = transaction.getCreditTransactions(); + double sum = 0; + for (Transaction credit : credits) { + sum += credit.getAmount(); + } + CashOutDebitInfo info = new CashOutDebitInfo(); + info.debit = transaction; + info.remainder = transaction.getAmount() - sum; + freeDebits.add(info); + } + return freeDebits; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/java/performance.java b/java/java-tests/testData/psi/formatter/java/performance.java new file mode 100644 index 000000000000..2cacb4d3f53a --- /dev/null +++ b/java/java-tests/testData/psi/formatter/java/performance.java @@ -0,0 +1,3870 @@ +package com.intellij.openapi.editor.impl; + +import com.intellij.Patches; +import com.intellij.codeInsight.hint.HintManager; +import com.intellij.codeInsight.hint.TooltipController; +import com.intellij.codeInsight.hint.TooltipGroup; +import com.intellij.openapi.actionSystem.ActionManager; +import com.intellij.openapi.actionSystem.DataConstants; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.IdeActions; +import com.intellij.openapi.actionSystem.ex.ActionManagerEx; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.actionSystem.EditorAction; +import com.intellij.openapi.editor.actionSystem.EditorActionHandler; +import com.intellij.openapi.editor.actionSystem.EditorActionManager; +import com.intellij.openapi.editor.ex.util.EditorUtil; +import com.intellij.openapi.editor.ex.util.EmptyEditorHighlighter; +import com.intellij.openapi.editor.impl.event.MarkupModelEvent; +import com.intellij.openapi.editor.impl.event.MarkupModelListener; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.ui.JScrollPane2; +import com.intellij.util.Alarm; +import com.intellij.util.IJSwingUtilities; +import com.intellij.util.containers.HashMap; +import gnu.trove.THashMap; +import gnu.trove.TIntArrayList; +import org.jdom.Element; + +import javax.swing.*; +import javax.swing.plaf.ScrollBarUI; +import javax.swing.plaf.basic.BasicScrollBarUI; +import java.awt.*; +import java.awt.datatransfer.*; +import java.awt.dnd.DropTargetAdapter; +import java.awt.dnd.DropTargetDragEvent; +import java.awt.dnd.DropTargetDropEvent; +import java.awt.event.*; +import java.awt.font.TextHitInfo; +import java.awt.im.InputMethodRequests; +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.text.AttributedCharacterIterator; +import java.text.AttributedString; +import java.text.CharacterIterator; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.TooManyListenersException; + +public class EditorImpl implements EditorEx { + private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.editor.impl.EditorImpl"); + private static final Key DND_COMMAND_KEY = Key.create("DndCommand"); + private final DocumentImpl myDocument; + + private JPanel myPanel; + private JScrollPane myScrollPane; + private EditorComponentImpl myEditorComponent; + private EditorGutterComponentImpl myGutterComponent; + + + private CommandProcessor myCommandProcessor; + private MyScrollBar myVerticalScrollBar; + private MyScrollBar myHorizontalScrollBar; + + private ArrayList myMouseListeners = new ArrayList(); + private ArrayList myMouseMotionListeners = new ArrayList(); + + private int myCharHeight = -1; + private int myLineHeight = -1; + private int myDescent = -1; + + private boolean myIsInsertMode = true; + + private final CaretCursor myCaretCursor; + private final ScrollingTimer myScrollingTimer = new ScrollingTimer(); + + private final Object MOUSE_DRAGGED_GROUP = Key.create("MouseDraggedGroup"); + private final THashMap myUserDataMap = new THashMap(); + + private final DocumentListener myEditorDocumentAdapter; + + private SettingsImpl mySettings; + + private boolean isReleased = false; + + private MouseEvent myMousePressedEvent = null; + + private int mySavedSelectionStart = -1; + private int mySavedSelectionEnd = -1; + private int myLastColumnNumber = 0; + + private final PropertyChangeSupport myPropertyChangeSupport = new PropertyChangeSupport(this); + private MyEditable myEditable; + + private EditorColorsScheme myScheme; + private final boolean myIsViewer; + private final SelectionModelImpl mySelectionModel; + private final EditorMarkupModelImpl myMarkupModel; + private final FoldingModelImpl myFoldingModel; + private final ScrollingModelImpl myScrollingModel; + private final CaretModelImpl myCaretModel; + + private static final RepaintCursorThread ourCaretThread; + +// private final BorderEffect myBorderEffect = new BorderEffect(); + + private int myMouseSelectionState = MOUSE_SELECTION_STATE_NONE; + private FoldRegion myMouseSelectedRegion = null; + + private static final int MOUSE_SELECTION_STATE_NONE = 0; + private static final int MOUSE_SELECTION_STATE_WORD_SELECTED = 1; + private static final int MOUSE_SELECTION_STATE_LINE_SELECTED = 2; + + private final MarkupModelListener myMarkupModelListener; + + private EditorHighlighter myHighlighter; + + private int myScrollbarOrientation; + private boolean myMousePressedInsideSelection; + private FontMetrics myPlainFontMetrics; + private FontMetrics myBoldFontMetrics; + private FontMetrics myItalicFontMetrics; + private FontMetrics myBoldItalicFontMetrics; + + private static final int CACHED_CHARS_BUFFER_SIZE = 300; + + private CachedFontContent myPlainCache = new CachedFontContent(Font.PLAIN); + private CachedFontContent myBoldCache = new CachedFontContent(Font.BOLD); + private CachedFontContent myBoldItalicCache = new CachedFontContent(Font.BOLD + Font.ITALIC); + private CachedFontContent myItalicCache = new CachedFontContent(Font.ITALIC); + + private int myCurrentFontType = Font.PLAIN; + + private boolean myIsBlockSelectionMode; + private EditorSizeContainer mySizeContainer = new EditorSizeContainer(); + + private Runnable myCursorUpdater; + private int myCaretUpdateVShift; + Project myProject; + private long myMouseSelectionChangeTimestamp; + private int mySavedCaretOffsetForDNDUndoHack; + private ArrayList myFocusListeners = new ArrayList(); + + private MyInputMethodHandler myInputMethodRequestsHandler; + private InputMethodRequests myInputMethodRequestsSwingWrapper; + private boolean myIsOneLineMode; + private boolean myIsRendererMode; + private VirtualFile myVirtualFile; + private boolean myIsColumnMode = false; + private Color myForcedBackground = null; + private Dimension myPreferredSize; + private Runnable myGutterSizeUpdater = null; + private Alarm myAppleRepaintAlarm; + + static { + ourCaretThread = new RepaintCursorThread(); + ourCaretThread.start(); + } + + + public EditorImpl(Document document, boolean viewer, Project project) { + myProject = project; + myDocument = (DocumentImpl)document; + myScheme = new MyColorSchemeDelegate(); + myIsViewer = viewer; + mySettings = new SettingsImpl(this); + + mySelectionModel = new SelectionModelImpl(this); + myMarkupModel = new EditorMarkupModelImpl(this); + myFoldingModel = new FoldingModelImpl(this); + myCaretModel = new CaretModelImpl(this); + myIsBlockSelectionMode = false; + mySizeContainer.reset(); + + myCommandProcessor = CommandProcessor.getInstance(); + + myEditorDocumentAdapter = new EditorDocumentAdapter(); + + myMarkupModelListener = new MarkupModelListener() { + public void rangeHighlighterChanged(MarkupModelEvent event) { + RangeHighlighterImpl rangeHighlighter = (RangeHighlighterImpl)event.getHighlighter(); + if (rangeHighlighter.isValid()) { + int start = rangeHighlighter.getAffectedAreaStartOffset(); + int end = rangeHighlighter.getAffectedAreaEndOffset(); + int startLine = myDocument.getLineNumber(start); + int endLine = myDocument.getLineNumber(end); + repaintLines(Math.max(0, startLine - 1), Math.min(endLine + 1, getDocument().getLineCount())); + } + else { + repaint(0, getDocument().getTextLength()); + } + ((EditorMarkupModelImpl)getMarkupModel()).repaint(); + ((EditorMarkupModelImpl)getMarkupModel()).markDirtied(); + GutterIconRenderer renderer = rangeHighlighter.getGutterIconRenderer(); + if (renderer != null) { + updateGutterSize(); + } + updateCaretCursor(); + } + }; + + ((MarkupModelImpl)myDocument.getMarkupModel(myProject)).addMarkupModelListener(myMarkupModelListener); + ((MarkupModelImpl)getMarkupModel()).addMarkupModelListener(myMarkupModelListener); + + myDocument.addDocumentListener(myFoldingModel); + myDocument.addDocumentListener(myCaretModel); + myDocument.addDocumentListener(mySelectionModel); + myDocument.addDocumentListener(myEditorDocumentAdapter); + + myCaretCursor = new CaretCursor(); + + myFoldingModel.flushCaretShift(); + myScrollbarOrientation = EditorEx.VERTICAL_SCROLLBAR_RIGHT; + + EditorHighlighter highlighter = new EmptyEditorHighlighter(myScheme.getAttributes(HighlighterColors.TEXT)); + setHighlighter(highlighter); + + initComponent(); + + myScrollingModel = new ScrollingModelImpl(this); + + myGutterComponent.updateSize(); + myEditorComponent.setSize(getContentSize()); + + Dimension preferredSize = getPreferredSize(); + myScrollPane.getViewport().setViewSize(preferredSize); + + if (Patches.APPLE_BUG_ID_3716835) { + myScrollingModel.addVisibleAreaListener(new VisibleAreaListener() { + public void visibleAreaChanged(VisibleAreaEvent e) { + if (myAppleRepaintAlarm == null) { + myAppleRepaintAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD); + } + myAppleRepaintAlarm.cancelAllRequests(); + myAppleRepaintAlarm.addRequest(new Runnable() { + public void run() { + repaint(0, myDocument.getTextLength()); + } + }, 50, ModalityState.stateForComponent(myEditorComponent)); + } + }); + } + + updateCaretCursor(); + } + + public boolean isViewer() { + return myIsViewer || myIsRendererMode; + } + + public boolean isRendererMode() { + return myIsRendererMode; + } + + public void setRendererMode(boolean isRendererMode) { + myIsRendererMode = isRendererMode; + } + + public void setFile(VirtualFile vFile) { + myVirtualFile = vFile; + reinitSettings(); + } + + public VirtualFile getVirtualFile() { + return myVirtualFile; + } + + public SelectionModel getSelectionModel() { + return mySelectionModel; + } + + public MarkupModel getMarkupModel() { + return myMarkupModel; + } + + public FoldingModel getFoldingModel() { + return myFoldingModel; + } + + public CaretModel getCaretModel() { + return myCaretModel; + } + + public ScrollingModel getScrollingModel() { + return myScrollingModel; + } + + public EditorSettings getSettings() { + ApplicationManager.getApplication().assertIsDispatchThread(); + return mySettings; + } + + public void reinitSettings() { + ApplicationManager.getApplication().assertIsDispatchThread(); + myCharHeight = -1; + myLineHeight = -1; + myDescent = -1; + myPlainFontMetrics = null; + + myPlainCache.reinitSettings(); + myBoldCache.reinitSettings(); + myItalicCache.reinitSettings(); + myBoldItalicCache.reinitSettings(); + + myCaretModel.reinitSettings(); + mySelectionModel.reinitSettings(); + mySettings.reinitSettings(); + ourCaretThread.setBlinkCaret(mySettings.isBlinkCaret()); + ourCaretThread.setBlinkPeriod(mySettings.getCaretBlinkPeriod()); + mySizeContainer.reset(); + myFoldingModel.refreshSettings(); + myFoldingModel.rebuild(); + + myHighlighter.setColorScheme(myScheme); + + myGutterComponent.revalidate(); + myEditorComponent.repaint(); + + updateCaretCursor(); + } + + public void release() { + isReleased = true; + myDocument.removeDocumentListener(myHighlighter); + myDocument.removeDocumentListener(myEditorDocumentAdapter); + myDocument.removeDocumentListener(myFoldingModel); + myDocument.removeDocumentListener(myCaretModel); + myDocument.removeDocumentListener(mySelectionModel); + MarkupModelImpl markupModel = (MarkupModelImpl)myDocument.getMarkupModel(myProject, false); + if (markupModel != null) markupModel.removeMarkupModelListener(myMarkupModelListener); + myMarkupModel.dispose(); + myLineHeight = -1; + myCharHeight = -1; + myDescent = -1; + myPlainFontMetrics = null; + myScrollingModel.dispose(); + myGutterComponent.dispose(); + } + + public void putUserData(Key key, T value) { + if (value != null) { + myUserDataMap.put(key, value); + } + else { + myUserDataMap.remove(key); + } + } + + public T getUserData(Key key) { + return (T)myUserDataMap.get(key); + } + + private void initComponent() { + myEditorComponent = new EditorComponentImpl(this); +// myStatusBar = new EditorStatusBarImpl(); + + myScrollPane = new JScrollPane2() { + protected void processMouseWheelEvent(MouseWheelEvent e) { + if (mySettings.isWheelFontChangeEnabled()) { + boolean changeFontSize = SystemInfo.isMac + ? !e.isControlDown() && e.isMetaDown() && !e.isAltDown() && !e.isShiftDown() + : e.isControlDown() && !e.isMetaDown() && !e.isAltDown() && !e.isShiftDown(); + if (changeFontSize) { + setFontSize(myScheme.getEditorFontSize() + e.getWheelRotation()); + return; + } + } + + super.processMouseWheelEvent(e); + } + }; + myPanel = new JPanel() { + public void addNotify() { + super.addNotify(); + if (((JComponent)getParent()).getBorder() != null) myScrollPane.setBorder(null); + } + }; + + //myPanel.setLayout(new BoxLayout(myPanel, BoxLayout.Y_AXIS)); + myPanel.setLayout(new BorderLayout()); + + myVerticalScrollBar = new MyScrollBar(JScrollBar.VERTICAL); + myHorizontalScrollBar = new MyScrollBar(JScrollBar.HORIZONTAL); + + myGutterComponent = new EditorGutterComponentImpl(this); + myGutterComponent.setOpaque(true); + + myScrollPane.setVerticalScrollBar(myVerticalScrollBar); + myScrollPane.setHorizontalScrollBar(myHorizontalScrollBar); + myScrollPane.setViewportView(myEditorComponent); + //myScrollPane.setBorder(null); + myScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); + myScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); + + + myScrollPane.setRowHeaderView(myGutterComponent); + stopOptimizedScrolling(); + + myEditorComponent.setTransferHandler(new MyTransferHandler()); + myEditorComponent.setAutoscrolls(true); + +/* Default mode till 1.4.0 + * myScrollPane.getViewport().setScrollMode(JViewport.BLIT_SCROLL_MODE); + */ + myPanel.add(myScrollPane); + + myEditorComponent.addKeyListener(new KeyAdapter() { + public void keyTyped(KeyEvent event) { + if (Patches.APPLE_BUG_ID_3337563) return; // Everything is going through InputMethods under MacOS X in JDK releases earlier than 1.4.2_03-117.1 + if (event.isConsumed()) { + return; + } + if (processKeyTyped(event)) { + event.consume(); + } + } + }); + + MyMouseAdapter mouseAdapter = new MyMouseAdapter(); + myEditorComponent.addMouseListener(mouseAdapter); + myGutterComponent.addMouseListener(mouseAdapter); + + MyMouseMotionListener mouseMotionListener = new MyMouseMotionListener(); + myEditorComponent.addMouseMotionListener(mouseMotionListener); + myGutterComponent.addMouseMotionListener(mouseMotionListener); + + myEditorComponent.addFocusListener(new FocusAdapter() { + public void focusGained(FocusEvent e) { + myCaretCursor.activate(); + int caretLine = getCaretModel().getLogicalPosition().line; + repaintLines(caretLine, caretLine); + fireFocusGained(); + } + + public void focusLost(FocusEvent e) { + synchronized (ourCaretThread) { + if (ourCaretThread.myEditor == EditorImpl.this) { + ourCaretThread.myEditor = null; + } + } + int caretLine = getCaretModel().getLogicalPosition().line; + repaintLines(caretLine, caretLine); + fireFocusLost(); + } + }); + +// myBorderEffect.reset(); + + try { + myEditorComponent.getDropTarget().addDropTargetListener(new DropTargetAdapter() { + public void drop(DropTargetDropEvent dtde) { + } + + public void dragOver(DropTargetDragEvent dtde) { + Point location = dtde.getLocation(); + + moveCaretToScreenPos(location.x, location.y); + getScrollingModel().scrollToCaret(ScrollType.RELATIVE); + } + }); + } + catch (TooManyListenersException e) { + } + } + + public void setFontSize(final int fontSize) { + int oldFontSize = myScheme.getEditorFontSize(); + myScheme.setEditorFontSize(fontSize); + myPropertyChangeSupport.firePropertyChange(EditorEx.PROP_FONT_SIZE, oldFontSize, fontSize); + } + + private void processKeyTyped(char c) { + // [vova] This is patch for Mac OS X. Under Mac "input methods" + // is handled before our EventQueue consume upcoming KeyEvents. + IdeEventQueue queue = IdeEventQueue.getInstance(); + if (queue.isWaitingForSecondKeyStroke() || ProgressManager.getInstance().hasModalProgressIndicator()) { + return; + } + ActionManagerEx actionManager = ActionManagerEx.getInstanceEx(); + DataContext dataContext = getDataContext(); + actionManager.fireBeforeEditorTyping(c, dataContext); + EditorActionManager.getInstance().getTypedAction().actionPerformed(this, c, dataContext); + } + + private void fireFocusLost() { + FocusChangeListener[] listeners = getFocusListeners(); + for (int i = 0; i < listeners.length; i++) { + FocusChangeListener listener = listeners[i]; + listener.focusLost(this); + } + } + + private FocusChangeListener[] getFocusListeners() { + return myFocusListeners.toArray(new FocusChangeListener[myFocusListeners.size()]); + } + + private void fireFocusGained() { + FocusChangeListener[] listeners = getFocusListeners(); + for (int i = 0; i < listeners.length; i++) { + FocusChangeListener listener = listeners[i]; + listener.focusGained(this); + } + } + + public void setHighlighter(EditorHighlighter highlighter) { + ApplicationManager.getApplication().assertIsDispatchThread(); + if (myHighlighter != null) { + getDocument().removeDocumentListener(myHighlighter); + } + + getDocument().addDocumentListener(highlighter); + highlighter.setText(getDocument().getCharsSequence()); + myHighlighter = highlighter; + myHighlighter.setEditor(this); + if (myPanel != null) { + reinitSettings(); + } + } + + public EditorHighlighter getHighlighter() { + ApplicationManager.getApplication().assertIsDispatchThread(); + return myHighlighter; + } + + public JComponent getContentComponent() { + return myEditorComponent; + } + + public EditorGutterComponentEx getGutterComponentEx() { + return myGutterComponent; + } + + public void addPropertyChangeListener(PropertyChangeListener listener) { + myPropertyChangeSupport.addPropertyChangeListener(listener); + } + + public void removePropertyChangeListener(PropertyChangeListener listener) { + myPropertyChangeSupport.removePropertyChangeListener(listener); + } + + public void setInsertMode(boolean mode) { + ApplicationManager.getApplication().assertIsDispatchThread(); + boolean oldValue = myIsInsertMode; + myIsInsertMode = mode; + myPropertyChangeSupport.firePropertyChange(EditorEx.PROP_INSERT_MODE, oldValue, mode); + //Repaint the caret line by moving caret to the same place + LogicalPosition caretPosition = getCaretModel().getLogicalPosition(); + getCaretModel().moveToLogicalPosition(caretPosition); + } + + public boolean isInsertMode() { + return myIsInsertMode; + } + + public void setColumnMode(boolean mode) { + ApplicationManager.getApplication().assertIsDispatchThread(); + boolean oldValue = myIsColumnMode; + myIsColumnMode = mode; + myPropertyChangeSupport.firePropertyChange(PROP_COLUMN_MODE, oldValue, mode); + } + + public boolean isColumnMode() { + return myIsColumnMode; + } + + public void setBlockSelectionMode(boolean isBlockSelectionMode) { + myIsBlockSelectionMode = isBlockSelectionMode; + } + + public boolean isBlockSelectionMode() { + return myIsBlockSelectionMode; + } + + private int yPositionToVisibleLineNumber(int y) { + return y / getLineHeight(); + } + + public int getSpaceWidth(int fontType) { + int width = charWidth(fontType, ' '); + return width > 0 ? width : 1; + } + + public VisualPosition xyToVisualPosition(Point p) { + int line = yPositionToVisibleLineNumber(p.y); + + int x = 0; + int offset = logicalPositionToOffset(visualToLogicalPosition(new VisualPosition(line, 0))); + int textLength = myDocument.getTextLength(); + + if (offset >= textLength) return new VisualPosition(line, 0); + + int column = 0; + int prevX = 0; + CharSequence text = myDocument.getCharsNoThreadCheck(); + char c = ' '; + IterationState state = new IterationState(this, offset, false); + + int fontType = state.getMergedAttributes().getFontType(); + int spaceSize = getSpaceWidth(fontType); + + outer: + while (true) { + if (offset >= textLength) break; + + if (offset >= state.getEndOffset()) { + state.advance(); + fontType = state.getMergedAttributes().getFontType(); + } + + FoldRegion region = state.getCurrentFold(); + if (region != null) { + char[] placeholder = region.getPlaceholderText().toCharArray(); + for (int j = 0; j < placeholder.length; j++) { + c = placeholder[j]; + x += charWidth(fontType, c); + if (x >= p.x) break outer; + column++; + } + offset = region.getEndOffset(); + } + else { + prevX = x; + c = text.charAt(offset); + if (c == '\n') { + break; + } + if (c == '\t') { + x = nextTabStop(x); + } + else { + x += charWidth(fontType, c); + } + + if (x >= p.x) break; + + if (c == '\t') { + column += (x - prevX) / spaceSize; + } + else { + column++; + } + + offset++; + } + } + + int charWidth = charWidth(fontType, c); + + if (x >= p.x && c == '\t') { + if (mySettings.isCaretInsideTabs()) { + column += (p.x - prevX) / spaceSize; + if ((p.x - prevX) % spaceSize > spaceSize / 2) column++; + } + else { + if ((x - p.x) * 2 < x - prevX) { + column += (x - prevX) / spaceSize; + } + } + } + else { + if (x >= p.x) { + if ((x - p.x) * 2 < charWidth) column++; + } + else { + column += (p.x - x) / getSpaceWidth(fontType); + } + } + + return new VisualPosition(line, column); + } + + public VisualPosition offsetToVisualPosition(int offset) { + return logicalToVisualPosition(offsetToLogicalPosition(offset)); + } + + public LogicalPosition offsetToLogicalPosition(int offset) { + int line = calcLogicalLineNumber(offset); + int column = calcColumnNumber(offset, line); + return new LogicalPosition(line, column); + } + + public LogicalPosition xyToLogicalPosition(Point p) { + final Point pp; + if (p.x >= 0 && p.y >= 0) { + pp = p; + } + else { + pp = new Point(Math.max(p.x, 0), Math.max(p.y, 0)); + } + + return visualToLogicalPosition(xyToVisualPosition(pp)); + } + + public Point logicalPositionToXY(LogicalPosition pos) { + VisualPosition visible = logicalToVisualPosition(pos); + int y = visibleLineNumberToYPosition(visible.line); + + int lineStartOffset; + + if (pos.line == 0) { + lineStartOffset = 0; + } + else { + if (pos.line >= myDocument.getLineCount()) { + lineStartOffset = myDocument.getTextLength(); + } + else { + lineStartOffset = myDocument.getLineStartOffset(pos.line); + } + } + + int x = getTabbedTextWidth(lineStartOffset, visible); + return new Point(x, y); + } + + public Point visualPositionToXY(VisualPosition visible) { + int y = visibleLineNumberToYPosition(visible.line); + int logLine = visualToLogicalPosition(new VisualPosition(visible.line, 0)).line; + + int lineStartOffset; + + if (logLine == 0) { + lineStartOffset = 0; + } + else { + if (logLine >= myDocument.getLineCount()) { + lineStartOffset = myDocument.getTextLength(); + } + else { + lineStartOffset = myDocument.getLineStartOffset(logLine); + } + } + + int x = getTabbedTextWidth(lineStartOffset, visible); + return new Point(x, y); + } + + private int getTabbedTextWidth(int lineStartOffset, VisualPosition pos) { + if (pos.column == 0) return 0; + + int x = 0; + int offset = lineStartOffset; + CharSequence text = myDocument.getCharsNoThreadCheck(); + int textLength = myDocument.getTextLength(); + IterationState state = new IterationState(this, offset, false); + int fontType = state.getMergedAttributes().getFontType(); + int spaceSize = getSpaceWidth(fontType); + + int column = 0; + outer: + while (column < pos.column) { + if (offset >= textLength) break; + + if (offset >= state.getEndOffset()) { + state.advance(); + fontType = state.getMergedAttributes().getFontType(); + } + + FoldRegion region = state.getCurrentFold(); + + if (region != null) { + char[] placeholder = region.getPlaceholderText().toCharArray(); + for (int j = 0; j < placeholder.length; j++) { + x += charWidth(fontType, placeholder[j]); + column++; + if (column >= pos.column) break outer; + } + offset = region.getEndOffset(); + } + else { + char c = text.charAt(offset); + if (c == '\n') { + break; + } + if (c == '\t') { + int prevX = x; + x = nextTabStop(x); + column += (x - prevX) / spaceSize; + } + else { + x += charWidth(fontType, c); + column++; + } + offset++; + } + } + + if (column != pos.column) { + x += getSpaceWidth(fontType) * (pos.column - column); + } + + return x; + } + + public int nextTabStop(int x) { + int tabSize = mySettings.getTabSize(myProject); + if (tabSize <= 0) { + tabSize = 1; + } + + tabSize *= getSpaceWidth(Font.PLAIN); + + int nTabs = x / tabSize; + return (nTabs + 1) * tabSize; + } + + public int visibleLineNumberToYPosition(int lineNum) { + if (lineNum < 0) throw new IndexOutOfBoundsException("Wrong line: " + lineNum); + return lineNum * getLineHeight(); + } + + public void repaint(int startOffset, int endOffset) { + ApplicationManager.getApplication().assertIsDispatchThread(); + if (myScrollPane == null) { + return; + } + if (endOffset > myDocument.getTextLength()) { + endOffset = myDocument.getTextLength(); + } + if (startOffset < endOffset) { + int startLine = myDocument.getLineNumber(startOffset); + int endLine = myDocument.getLineNumber(endOffset); + repaintLines(startLine, endLine); + } + } + + public void repaintLines(int startLine, int endLine) { + Rectangle visibleRect = getScrollingModel().getVisibleArea(); + int yStartLine = logicalPositionToXY(new LogicalPosition(startLine, 0)).y; + int yEndLine = logicalPositionToXY(new LogicalPosition(endLine, 0)).y + getLineHeight() + WAVE_HEIGHT; + + myEditorComponent.repaintEditorComponent(visibleRect.x, + yStartLine, + visibleRect.x + visibleRect.width, + yEndLine - yStartLine); + myGutterComponent.repaint(0, yStartLine, myGutterComponent.getWidth(), yEndLine - yStartLine); + } + + private void beforeChangedUpdate(DocumentEvent e) { + Rectangle viewRect = getScrollingModel().getVisibleArea(); + Point pos = visualPositionToXY(getCaretModel().getVisualPosition()); + myCaretUpdateVShift = pos.y - viewRect.y; + mySizeContainer.beforeChange(e); + } + + private void changedUpdate(DocumentEvent e) { + if (myScrollPane == null) return; + + stopOptimizedScrolling(); + mySelectionModel.removeBlockSelection(); + + mySizeContainer.changedUpdate(e); + int startVisualLine = offsetToVisualPosition(e.getOffset()).line; + int endVisualLine = offsetToVisualPosition(e.getOffset() + e.getNewLength()).line; + + if (myDocument.getTextLength() > 0) { + int startDocLine = myDocument.getLineNumber(e.getOffset()); + int endDocLine = myDocument.getLineNumber(e.getOffset() + e.getNewLength()); + if (e.getOldLength() > e.getNewLength() || startDocLine != endDocLine) { + updateGutterSize(); + } + } + + updateCaretCursor(); + repaintLines(startVisualLine, endVisualLine); + + Point caretLocation = visualPositionToXY(getCaretModel().getVisualPosition()); + int scrollOffset = caretLocation.y - myCaretUpdateVShift; + getScrollingModel().scrollVertically(scrollOffset); + } + + private void updateGutterSize() { + if (myGutterSizeUpdater != null) return; + myGutterSizeUpdater = new Runnable() { + public void run() { + myGutterComponent.updateSize(); + myGutterSizeUpdater = null; + } + }; + } + + void validateSize() { + if (myGutterSizeUpdater != null) { + SwingUtilities.invokeLater(myGutterSizeUpdater); + } + + Dimension dim = getPreferredSize(); + + if (!dim.equals(myPreferredSize)) { + myPreferredSize = dim; + + stopOptimizedScrolling(); + myScrollPane.getViewport().setViewSize(myPreferredSize); + int lineNum = Math.max(1, getDocument().getLineCount()); + + myGutterComponent.setLineNumberAreaWidth(getFontMetrics(Font.PLAIN).stringWidth(Integer.toString((lineNum + 2))) + 6); + final JViewport rowHeader = myScrollPane.getRowHeader(); + if (rowHeader != null) { + rowHeader.setViewSize(myGutterComponent.getPreferredSize()); + } + + getScrollPane().revalidate(); + + myEditorComponent.repaint(); + myScrollPane.repaint(); + myMarkupModel.repaint(); + } + } + + void recalcSizeAndRepaint() { + mySizeContainer.reset(); + + validateSize(); + + Dimension size = getPreferredSize(); + + myScrollPane.getVerticalScrollBar().setMaximum(size.height); + myScrollPane.getHorizontalScrollBar().setMaximum(size.width); + + getScrollPane().revalidate(); + myMarkupModel.repaint(); + + stopOptimizedScrolling(); + myEditorComponent.repaintEditorComponent(); + + myGutterComponent.repaint(); + } + + public Document getDocument() { + return myDocument; + } + + public JComponent getComponent() { + return myPanel; + } + + public void addEditorMouseListener(EditorMouseListener listener) { + myMouseListeners.add(listener); + } + + public void removeEditorMouseListener(EditorMouseListener listener) { + boolean success = myMouseListeners.remove(listener); + LOG.assertTrue(success); + } + + public void addEditorMouseMotionListener(EditorMouseMotionListener listener) { + myMouseMotionListeners.add(listener); + } + + public void removeEditorMouseMotionListener(EditorMouseMotionListener listener) { + boolean success = myMouseMotionListeners.remove(listener); + LOG.assertTrue(success); + } + + public boolean isDisposed() { + return isReleased; + } + + public void paint(Graphics g) { + validateSize(); + startOptimizedScrolling(); + + if (myCursorUpdater != null) { + myCursorUpdater.run(); + myCursorUpdater = null; + } + + Rectangle clip = getClipBounds(g); + + if (clip == null) { + return; + } + + Rectangle viewRect = getScrollingModel().getVisibleArea(); + if (viewRect == null) { + return; + } + + if (isReleased) { + g.setColor(new Color(128, 255, 128)); + g.fillRect(clip.x, clip.y, clip.width, clip.height); + + return; + } + + Color background = getBackroundColor(); + g.setColor(background); + g.fillRect(clip.x, clip.y, clip.width, clip.height); + + paintBackgrounds(g, clip); + paintRectangularSelection(g); + paintRightMargin(g, clip); + final MarkupModel docMarkup = myDocument.getMarkupModel(myProject); + if (docMarkup != null) { + paintLineMarkersSeparators(g, clip, docMarkup); + } + paintLineMarkersSeparators(g, clip, myMarkupModel); + paintText(g, clip); + paintSegmentHighlightersBorderAndAfterEndOfLine(g, clip); + BorderEffect borderEffect = new BorderEffect(this, g); + borderEffect.paintHighlighters(getHighlighter()); + if (docMarkup != null) { + borderEffect.paintHighlighters(docMarkup.getAllHighlighters()); + } + borderEffect.paintHighlighters((getMarkupModel()).getAllHighlighters()); + paintCaretCursor(g); + + paintComposedTextDecoration((Graphics2D)g); + } + + public void setBackgroundColor(Color color) { + myForcedBackground = color; + } + + public void resetBackgourndColor() { + myForcedBackground = null; + } + + public Color getBackroundColor() { + if (myForcedBackground != null) return myForcedBackground; + + Color color = myScheme.getColor(EditorColors.BACKGROUND_COLOR); + if (color == null) color = Color.white; + if (myDocument.isWritable()) { + return color; + } + Color readOnlyColor = myScheme.getColor(EditorColors.READONLY_BACKGROUND_COLOR); + return readOnlyColor != null ? readOnlyColor : color; + } + + private void paintComposedTextDecoration(Graphics2D g) { + if (myInputMethodRequestsHandler != null && myInputMethodRequestsHandler.composedText != null) { + VisualPosition visStart = offsetToVisualPosition( + Math.min(myInputMethodRequestsHandler.composedTextStart, myDocument.getTextLength())); + int y = visibleLineNumberToYPosition(visStart.line) + getLineHeight() - getDescent() + 1; + Point p1 = visualPositionToXY(visStart); + Point p2 = logicalPositionToXY( + offsetToLogicalPosition(Math.min(myInputMethodRequestsHandler.composedTextEnd, myDocument.getTextLength()))); + + Stroke saved = g.getStroke(); + BasicStroke dotted = new BasicStroke(1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND, 0, new float[]{0, 2, 0, 2}, + 0); + g.setStroke(dotted); + g.drawLine(p1.x, y, p2.x, y); + g.setStroke(saved); + } + } + + private static Rectangle getClipBounds(Graphics g) { + return g.getClipBounds(); + } + + private void paintRightMargin(Graphics g, Rectangle clip) { + Color rightMargin = myScheme.getColor(EditorColors.RIGHT_MARGIN_COLOR); + if (!mySettings.isRightMarginShown() || rightMargin == null) { + return; + } + int x = mySettings.getRightMargin(myProject) * getSpaceWidth(Font.PLAIN); + if (x >= clip.x && x < clip.x + clip.width) { + g.setColor(rightMargin); + g.drawLine(x, clip.y, x, clip.y + clip.height); + } + } + + private void paintSegmentHighlightersBorderAndAfterEndOfLine(Graphics g, Rectangle clip) { + if (myDocument.getLineCount() == 0) return; + int startLineNumber = yPositionToVisibleLineNumber(clip.y); + int endLineNumber = yPositionToVisibleLineNumber(clip.y + clip.height) + 1; + + RangeHighlighter[] segmentHighlighters; + final MarkupModel docMarkup = myDocument.getMarkupModel(myProject); + if (docMarkup != null) { + segmentHighlighters = docMarkup.getAllHighlighters(); + for (int i = 0; i < segmentHighlighters.length; i++) { + paintSegmentHighlighterAfterEndOfLine(g, (RangeHighlighterEx)segmentHighlighters[i], startLineNumber, + endLineNumber); + } + } + + segmentHighlighters = getMarkupModel().getAllHighlighters(); + for (int i = 0; i < segmentHighlighters.length; i++) { + RangeHighlighter segmentHighlighter = segmentHighlighters[i]; + paintSegmentHighlighterAfterEndOfLine(g, (RangeHighlighterEx)segmentHighlighter, startLineNumber, endLineNumber); + } + } + + private void paintSegmentHighlighterAfterEndOfLine(Graphics g, RangeHighlighterEx segmentHighlighter, + int startLineNumber, int endLineNumber) { + if (!segmentHighlighter.isValid()) { + return; + } + if (segmentHighlighter.isAfterEndOfLine()) { + int startOffset = segmentHighlighter.getStartOffset(); + int visibleStartLine = offsetToVisualPosition(startOffset).line; + + if (!getFoldingModel().isOffsetCollapsed(startOffset)) { + if (visibleStartLine >= startLineNumber && visibleStartLine <= endLineNumber) { + int logStartLine = offsetToLogicalPosition(startOffset).line; + LogicalPosition logPosition = offsetToLogicalPosition(myDocument.getLineEndOffset(logStartLine)); + Point end = logicalPositionToXY(logPosition); + int charWidth = getSpaceWidth(Font.PLAIN); + int lineHeight = getLineHeight(); + TextAttributes attributes = segmentHighlighter.getTextAttributes(); + if (attributes != null && attributes.getBackgroundColor() != null) { + g.setColor(attributes.getBackgroundColor()); + g.fillRect(end.x, end.y, charWidth, lineHeight); + } + if (attributes != null && attributes.getEffectColor() != null) { + int y = visibleLineNumberToYPosition(visibleStartLine) + getLineHeight() - getDescent() + 1; + g.setColor(attributes.getEffectColor()); + if (attributes.getEffectType() == EffectType.WAVE_UNDERSCORE) { + drawWave(g, end.x, end.x + charWidth - 1, y); + } + else if (attributes.getEffectType() != EffectType.BOXED) { + g.drawLine(end.x, y, end.x + charWidth - 1, y); + } + } + } + } + } + } + + public int getMaxWidthInRange(int startOffset, int endOffset) { + int width = 0; + VisualPosition start = offsetToVisualPosition(startOffset); + VisualPosition end = offsetToVisualPosition(endOffset); + + for (int i = start.line; i <= end.line; i++) { + int lastColumn = EditorUtil.getLastVisualLineColumnNumber(this, i) + 1; + int lineWidth = visualPositionToXY(new VisualPosition(i, lastColumn)).x; + + if (lineWidth > width) { + width = lineWidth; + } + } + + return width; + } + + private void paintBackgrounds(Graphics g, Rectangle clip) { + int lineHeight = getLineHeight(); + + int visibleLineNumber = clip.y / lineHeight; + + int startLineNumber = xyToLogicalPosition(new Point(0, clip.y)).line; + + if (startLineNumber >= myDocument.getLineCount() || startLineNumber < 0) { + return; + } + + int start = myDocument.getLineStartOffset(startLineNumber); + + IterationState iterationState = new IterationState(this, start, true); + + LineIterator lIterator = createLineIterator(); + lIterator.start(start); + if (lIterator.atEnd()) { + return; + } + + TextAttributes attributes = iterationState.getMergedAttributes(); + Color backColor = attributes.getBackgroundColor(); + Point position = new Point(0, visibleLineNumber * lineHeight); + int fontType = attributes.getFontType(); + CharSequence text = myDocument.getCharsNoThreadCheck(); + int lastLineIndex = Math.max(0, myDocument.getLineCount() - 1); + while (!iterationState.atEnd() && !lIterator.atEnd()) { + int hEnd = iterationState.getEndOffset(); + int lEnd = lIterator.getEnd(); + + if (hEnd >= lEnd) { + FoldRegion collapsedFolderAt = myFoldingModel.getCollapsedRegionAtOffset(start); + if (collapsedFolderAt == null) { + position.x = drawBackground(g, backColor, text.subSequence(start, lEnd - lIterator.getSeparatorLength()), + position, fontType); + + if (lIterator.getLineNumber() < lastLineIndex) { + if (backColor != null) { + Color saved = g.getColor(); + g.setColor(backColor); + g.fillRect(position.x, position.y, clip.x + clip.width - position.x, lineHeight); + g.setColor(saved); + } + } + else { + paintAfterFileEndBackground(iterationState, g, position, clip, lineHeight); + break; + } + + position.x = 0; + if (position.y > clip.y + clip.height) break; + position.y += lineHeight; + start = lEnd; + } + + lIterator.advance(); + } + else { + FoldRegion collapsedFolderAt = iterationState.getCurrentFold(); + if (collapsedFolderAt != null) { + position.x = drawBackground(g, backColor, collapsedFolderAt.getPlaceholderText(), + position, fontType); + } + else { + if (hEnd > lEnd - lIterator.getSeparatorLength()) { + position.x = drawBackground(g, backColor, text.subSequence(start, lEnd - lIterator.getSeparatorLength()), + position, fontType); + } + else { + position.x = drawBackground(g, backColor, text.subSequence(start, hEnd), position, fontType); + } + } + + iterationState.advance(); + attributes = iterationState.getMergedAttributes(); + backColor = attributes.getBackgroundColor(); + fontType = attributes.getFontType(); + start = iterationState.getStartOffset(); + } + } + + if (lIterator.getLineNumber() >= lastLineIndex && position.y <= clip.y + clip.height) { + paintAfterFileEndBackground(iterationState, g, position, clip, lineHeight); + } + } + + private void paintRectangularSelection(Graphics g) { + final SelectionModel model = getSelectionModel(); + if (!model.hasBlockSelection()) return; + final Point start = logicalPositionToXY(model.getBlockStart()); + final Point end = logicalPositionToXY(model.getBlockEnd()); + g.setColor(myScheme.getColor(EditorColors.SELECTION_BACKGROUND_COLOR)); + final int y; + final int height; + if (start.y <= end.y) { + y = start.y; + height = end.y - y + getLineHeight(); + } + else { + y = end.y; + height = start.y - end.y + getLineHeight(); + } + final int x = Math.min(start.x, end.x); + final int width = Math.max(2, Math.abs(end.x - start.x)); + g.fillRect(x, y, width, height); + } + + private static void paintAfterFileEndBackground(IterationState iterationState, Graphics g, Point position, + Rectangle clip, int lineHeight) { + Color backColor = iterationState.getPastFileEndBackground(); + if (backColor != null) { + Color saved = g.getColor(); + g.setColor(backColor); + g.fillRect(position.x, position.y, clip.x + clip.width - position.x, lineHeight); + g.setColor(saved); + } + } + + private int drawBackground(Graphics g, + Color backColor, + CharSequence text, + Point position, + int fontType) { + int w = getTextSegmentWidth(text, position.x, fontType); + + if (backColor != null) { + Color savedColor = g.getColor(); + g.setColor(backColor); + g.fillRect(position.x, position.y, w, getLineHeight()); + g.setColor(savedColor); + } + + return position.x + w; + } + + private LineIterator createLineIterator() { + return myDocument.createLineIterator(); + } + + private void paintText(Graphics g, Rectangle clip) { + int lineHeight = getLineHeight(); + + int visibleLineNumber = clip.y / lineHeight; + + int startLineNumber = xyToLogicalPosition(new Point(0, clip.y)).line; + + if (startLineNumber >= myDocument.getLineCount() || startLineNumber < 0) { + return; + } + + int start = myDocument.getLineStartOffset(startLineNumber); + + IterationState iterationState = new IterationState(this, start, true); + + LineIterator lIterator = createLineIterator(); + lIterator.start(start); + if (lIterator.atEnd()) { + return; + } + + TextAttributes attributes = iterationState.getMergedAttributes(); + Color currentColor = attributes.getForegroundColor(); + if (currentColor == null) { + currentColor = Color.black; + } + Color effectColor = attributes.getEffectColor(); + EffectType effectType = attributes.getEffectType(); + int fontType = attributes.getFontType(); + myCurrentFontType = fontType; + Font currentFont = getFont(fontType); + g.setColor(currentColor); + g.setFont(currentFont); + Point position = new Point(0, visibleLineNumber * lineHeight); + while (!iterationState.atEnd() && !lIterator.atEnd()) { + int hEnd = iterationState.getEndOffset(); + int lEnd = lIterator.getEnd(); + if (hEnd >= lEnd) { + FoldRegion collapsedFolderAt = myFoldingModel.getCollapsedRegionAtOffset(start); + if (collapsedFolderAt == null) { + drawString(g, start, lEnd - lIterator.getSeparatorLength(), position, clip, effectColor, effectType, + fontType, currentColor); + position.x = 0; + if (position.y > clip.y + clip.height) break; + position.y += lineHeight; + start = lEnd; + } + +// myBorderEffect.eolReached(g, this); + lIterator.advance(); + } + else { + FoldRegion collapsedFolderAt = iterationState.getCurrentFold(); + if (collapsedFolderAt != null) { + int foldingXStart = position.x; + position.x = drawString(g, collapsedFolderAt.getPlaceholderText(), position, clip, effectColor, effectType, + fontType, currentColor); + BorderEffect.paintFoldedEffect(g, foldingXStart, position.y, position.x, getLineHeight(), effectColor, + effectType); + + } + else { + if (hEnd > lEnd - lIterator.getSeparatorLength()) { + position.x = drawString(g, start, lEnd - lIterator.getSeparatorLength(), position, clip, effectColor, + effectType, fontType, currentColor); + } + else { + position.x = drawString(g, start, hEnd, position, clip, effectColor, effectType, fontType, currentColor); + } + } + + iterationState.advance(); + attributes = iterationState.getMergedAttributes(); + Color color = attributes.getForegroundColor(); + if (color == null) { + color = Color.black; + } + if (color != currentColor) { + g.setColor(color); + currentColor = color; + } + effectColor = attributes.getEffectColor(); + effectType = attributes.getEffectType(); + fontType = attributes.getFontType(); + + start = iterationState.getStartOffset(); + } + } + + FoldRegion collapsedFolderAt = iterationState.getCurrentFold(); + if (collapsedFolderAt != null) { + int foldingXStart = position.x; + int foldingXEnd = drawString(g, collapsedFolderAt.getPlaceholderText(), position, clip, effectColor, effectType, fontType, + currentColor); + BorderEffect.paintFoldedEffect(g, foldingXStart, position.y, foldingXEnd, getLineHeight(), effectColor, + effectType); +// myBorderEffect.collapsedFolderReached(g, this); + } + + flushCachedChars(g); + } + + private class CachedFontContent { + int[] charWidths = null; + final CharSequence[] data = new CharSequence[CACHED_CHARS_BUFFER_SIZE]; + final int[] x = new int[CACHED_CHARS_BUFFER_SIZE]; + final int[] y = new int[CACHED_CHARS_BUFFER_SIZE]; + final Color[] color = new Color[CACHED_CHARS_BUFFER_SIZE]; + + int myCount = 0; + final int myFontType; + private FontMetrics myFontMetrics; + + public CachedFontContent(int fontType) { + myFontType = fontType; + } + + public void reinitSettings() { + myFontMetrics = null; + charWidths = null; + } + + public int charWidth(char c) { + if (c >= 256) return fontMetrics().charWidth(c); + if (charWidths == null) { + charWidths = new int[256]; + FontMetrics fontMetrics = fontMetrics(); + for (int i = 0; i < 256; i++) { + charWidths[i] = fontMetrics.charWidth(i); + } + } + return charWidths[c]; + } + + private FontMetrics fontMetrics() { + if (myFontMetrics == null) { + myFontMetrics = getFontMetrics(myFontType); + } + return myFontMetrics; + } + + public void flushContent(Graphics g) { + if (myCount != 0) { + if (myCurrentFontType != myFontType) { + myCurrentFontType = myFontType; + g.setFont(getFont(myFontType)); + } + + Color currentColor = null; + for (int i = 0; i < myCount; i++) { + if (!color[i].equals(currentColor)) { + currentColor = color[i]; + g.setColor(currentColor); + } + + drawChars(g, data[i], x[i], y[i]); + color[i] = null; + data[i] = null; + } + + myCount = 0; + } + } + + public void addContent(Graphics g, CharSequence data, int x, int y, Color color) { + this.data[myCount] = data; + this.x[myCount] = x; + this.y[myCount] = y; + this.color[myCount] = color; + + myCount++; + if (myCount >= CACHED_CHARS_BUFFER_SIZE) { + flushContent(g); + } + } + } + + private void flushCachedChars(Graphics g) { + myPlainCache.flushContent(g); + myBoldCache.flushContent(g); + myBoldItalicCache.flushContent(g); + myItalicCache.flushContent(g); + } + + private void paintCaretCursor(Graphics g) { + myCaretCursor.paint(g); + } + + private void paintLineMarkersSeparators(Graphics g, Rectangle clip, MarkupModel markupModel) { + if (markupModel == null) return; + RangeHighlighter[] lineMarkers = markupModel.getAllHighlighters(); + for (int i = 0; i < lineMarkers.length; i++) { + RangeHighlighter lineMarker = lineMarkers[i]; + paintLineMarkerSeparator(lineMarker, clip, g); + } + } + + private void paintLineMarkerSeparator(RangeHighlighter marker, Rectangle clip, Graphics g) { + if (!marker.isValid()) { + return; + } + Color separatorColor = marker.getLineSeparatorColor(); + if (separatorColor != null) { + int lineNumber = marker.getLineSeparatorPlacement() == SeparatorPlacement.TOP ? marker.getDocument() + .getLineNumber(marker.getStartOffset()) : marker.getDocument().getLineNumber(marker.getEndOffset()); + if (lineNumber < 0 || lineNumber >= myDocument.getLineCount()) { + return; + } + + int endShift = clip.x + clip.width; + g.setColor(separatorColor); + + if (mySettings.isRightMarginShown() + && myScheme.getColor(EditorColors.RIGHT_MARGIN_COLOR) != null) { + endShift = + Math.min(endShift, mySettings.getRightMargin(myProject) * getSpaceWidth(Font.PLAIN)); + } + + int y = visibleLineNumberToYPosition(logicalToVisualPosition(new LogicalPosition(lineNumber, 0)).line); + + if (marker.getLineSeparatorPlacement() != SeparatorPlacement.TOP) { + y += getLineHeight(); + } + + g.drawLine(0, y - 1, endShift, y - 1); + } + } + + private Font getFont(int type) { + if (type == Font.BOLD) { + return myScheme.getFont(EditorFontType.BOLD); + } + else { + if (type == Font.ITALIC) { + return myScheme.getFont(EditorFontType.ITALIC); + } + else { + if (type == Font.ITALIC + Font.BOLD) { + return myScheme.getFont(EditorFontType.BOLD_ITALIC); + } + else { + return myScheme.getFont(EditorFontType.PLAIN); + } + } + } + } + + private int drawString(Graphics g, int start, int end, Point position, Rectangle clip, Color effectColor, + EffectType effectType, int fontType, Color fontColor) { + if (start >= end) return position.x; + + CharSequence text = myDocument.getCharsNoThreadCheck(); + boolean isInClip = (getLineHeight() + position.y >= clip.y) && (position.y <= clip.y + clip.height); + + if (!isInClip) return position.x; + + int y = getLineHeight() - getDescent() + position.y; + int x = position.x; + return drawTabbedString(g, text.subSequence(start, end), x, y, effectColor, effectType, fontType, fontColor); + } + + private int drawString(Graphics g, String text, Point position, Rectangle clip, Color effectColor, + EffectType effectType, int fontType, Color fontColor) { + boolean isInClip = (getLineHeight() + position.y >= clip.y) && (position.y <= clip.y + clip.height); + + if (!isInClip) return position.x; + + int y = getLineHeight() - getDescent() + position.y; + int x = position.x; + return drawTabbedString(g, text, x, y, effectColor, effectType, fontType, + fontColor); + } + + private int drawTabbedString(Graphics g, CharSequence text, int x, int y, Color effectColor, + EffectType effectType, int fontType, Color fontColor) { + int xStart = x; + + int start = 0; + + for (int i = 0; i < text.length(); i++) { + if (text.charAt(i) != '\t') continue; + + if (i > start) { + drawCharsCached(g, text.subSequence(start, i), x, y, fontType, fontColor); + for (int j = start; j < i; j++) { + char c = text.charAt(j); + x += charWidth(fontType, c); + } + } + + int x1 = nextTabStop(x); + drawTabPlacer(g, y, x, x1); + x = x1; + start = i + 1; + } + + if (start < text.length()) { + drawCharsCached(g, text.subSequence(start, text.length()), x, y, fontType, fontColor); + for (int j = start; j < text.length(); j++) x += charWidth(fontType, text.charAt(j)); + } + + if (effectColor != null) { + Color savedColor = g.getColor(); + + int w = getTextSegmentWidth(text, xStart, fontType); +// myBorderEffect.flushIfCantProlong(g, this, effectType, effectColor); + if (effectType == EffectType.LINE_UNDERSCORE) { + g.setColor(effectColor); + g.drawLine(xStart, y + 1, xStart + w, y + 1); + g.setColor(savedColor); + } + else { + if (effectType == EffectType.STRIKEOUT) { + g.setColor(effectColor); + int y1 = y - getCharHeight() / 2; + g.drawLine(xStart, y1, xStart + w, y1); + g.setColor(savedColor); + } + else { + if (effectType == EffectType.WAVE_UNDERSCORE) { + g.setColor(effectColor); + drawWave(g, xStart, xStart + w, y + 1); + g.setColor(savedColor); + } /*else { + if (effectType == EffectType.BOXED) { + int yStart = y - getLineHeight() + getDescent(); + if (!myBorderEffect.isDetached()) myBorderEffect.start(effectColor, start); + myBorderEffect.setEndOffset(offset + length); + } + }*/ + } + } + } /*else myBorderEffect.flushBorder(g, this);*/ + + return x; + } + + public int charWidth(int fontType, char c) { + switch(fontType) { + case Font.PLAIN: return myPlainCache.charWidth(c); + case Font.BOLD: return myBoldCache.charWidth(c); + case Font.ITALIC: return myItalicCache.charWidth(c); + case Font.BOLD | Font.ITALIC: return myBoldItalicCache.charWidth(c); + } + + return 0; + } + + private void drawTabPlacer(Graphics g, int y, int start, int stop) { + if (mySettings.isWhitespacesShown()) { + stop -= g.getFontMetrics().charWidth(' ') / 2; + Color oldColor = g.getColor(); + g.setColor(myScheme.getColor(EditorColors.WHITESPACES_COLOR)); + final int charHeight = getCharHeight(); + final int halfCharHeight = charHeight / 2; + int mid = y - halfCharHeight; + int top = y - charHeight; + g.drawLine(start, mid, stop, mid); + g.drawLine(stop, y, stop, top); + g.fillPolygon(new int[]{stop - halfCharHeight, stop - halfCharHeight, stop}, + new int[]{y, y - charHeight, y - halfCharHeight}, 3); + g.setColor(oldColor); + } + } + + private void drawCharsCached(Graphics g, + CharSequence data, + int x, + int y, + int fontType, + Color color) { + if (!SystemInfo.isMac) { + if (fontType == myCurrentFontType) { + drawChars(g, data, x, y); + } + else if (fontType == Font.PLAIN) { + myPlainCache.addContent(g, data, x, y, color); + } + else if (fontType == Font.BOLD) { + myBoldCache.addContent(g, data, x, y, color); + } + else if (fontType == Font.ITALIC) { + myItalicCache.addContent(g, data, x, y, color); + } + else { + myBoldItalicCache.addContent(g, data, x, y, color); + } + } + else { + if (fontType != myCurrentFontType) { + myCurrentFontType = fontType; + g.setFont(getFont(fontType)); + } + + drawChars(g, data, x, y); + } + } + + private void drawChars(Graphics g, CharSequence data, int x, int y) { + g.drawString(data.toString(), x, y); + + if (mySettings.isWhitespacesShown()) { + Color oldColor = g.getColor(); + g.setColor(myScheme.getColor(EditorColors.WHITESPACES_COLOR)); + final FontMetrics metrics = g.getFontMetrics(); + int halfSpaceWidth = metrics.charWidth(' ') / 2; + for (int i = 0; i < data.length(); i++) { + if (data.charAt(i) == ' ') { + g.fillRect(x + halfSpaceWidth, y, 1, 1); + } + x += metrics.charWidth(data.charAt(i)); + } + g.setColor(oldColor); + } + } + + private static final int WAVE_HEIGHT = 2; + private static final int WAVE_SEGMENT_LENGTH = 4; + + private static void drawWave(Graphics g, int xStart, int xEnd, int y) { + int startSegment = xStart / WAVE_SEGMENT_LENGTH; + int endSegment = xEnd / WAVE_SEGMENT_LENGTH; + for (int i = startSegment; i < endSegment; i++) { + drawWaveSegment(g, WAVE_SEGMENT_LENGTH * i, y); + } + + int x = WAVE_SEGMENT_LENGTH * endSegment; + g.drawLine(x, y + WAVE_HEIGHT, x + WAVE_SEGMENT_LENGTH / 2, y); + } + + private static void drawWaveSegment(Graphics g, int x, int y) { + g.drawLine(x, y + WAVE_HEIGHT, x + WAVE_SEGMENT_LENGTH / 2, y); + g.drawLine(x + WAVE_SEGMENT_LENGTH / 2, y, x + WAVE_SEGMENT_LENGTH, y + WAVE_HEIGHT); + } + + private int getTextSegmentWidth(CharSequence text, int xStart, int fontType) { + int start = 0; + int x = xStart; + + for (int i = 0; i < text.length(); i++) { + if (text.charAt(i) != '\t') continue; + + if (i > start) { + for (int j = start; j < i; j++) x += charWidth(fontType, text.charAt(j)); + } + x = nextTabStop(x); + start = i + 1; + } + + if (start < text.length()) { + for (int j = start; j < text.length(); j++) x += charWidth(fontType, text.charAt(j)); + } + + return x - xStart; + } + + public int getLineHeight() { + if (myLineHeight != -1) return myLineHeight; + + ApplicationManager.getApplication().assertIsDispatchThread(); + + FontMetrics fontMetrics = myEditorComponent.getFontMetrics(myScheme.getFont(EditorFontType.PLAIN)); + myLineHeight = (int)(fontMetrics.getHeight() * (isOneLineMode() ? 1 : myScheme.getLineSpacing())); + if (myLineHeight == 0) { + myLineHeight = fontMetrics.getHeight(); + if (myLineHeight == 0) { + myLineHeight = 12; + } + } + + return myLineHeight; + } + + int getDescent() { + if (myDescent != -1) { + return myDescent; + } + FontMetrics fontMetrics = myEditorComponent.getFontMetrics(myScheme.getFont(EditorFontType.PLAIN)); + myDescent = fontMetrics.getDescent(); + return myDescent; + } + + public FontMetrics getFontMetrics(int fontType) { + if (myPlainFontMetrics == null) { + ApplicationManager.getApplication().assertIsDispatchThread(); + myPlainFontMetrics = myEditorComponent.getFontMetrics(myScheme.getFont(EditorFontType.PLAIN)); + myBoldFontMetrics = myEditorComponent.getFontMetrics(myScheme.getFont(EditorFontType.BOLD)); + myItalicFontMetrics = myEditorComponent.getFontMetrics(myScheme.getFont(EditorFontType.ITALIC)); + myBoldItalicFontMetrics = myEditorComponent.getFontMetrics(myScheme.getFont(EditorFontType.BOLD_ITALIC)); + } + + if (fontType == Font.PLAIN) return myPlainFontMetrics; + if (fontType == Font.BOLD) return myBoldFontMetrics; + if (fontType == Font.ITALIC) return myItalicFontMetrics; + if (fontType == Font.BOLD + Font.ITALIC) return myBoldItalicFontMetrics; + + LOG.assertTrue(false, "Unknown font type: " + fontType); + + return myPlainFontMetrics; + } + + private int getCharHeight() { + if (myCharHeight == -1) { + ApplicationManager.getApplication().assertIsDispatchThread(); + FontMetrics fontMetrics = myEditorComponent.getFontMetrics(myScheme.getFont(EditorFontType.PLAIN)); + myCharHeight = fontMetrics.charWidth('a'); + } + return myCharHeight; + } + + public Dimension getPreferredSize() { + Dimension draft = getSizeWithoutCaret(); + int caretX = visualPositionToXY(getCaretModel().getVisualPosition()).x; + draft.width = Math.max(caretX, draft.width) + mySettings.getAdditionalColumnsCount() * getSpaceWidth(Font.PLAIN); + return draft; + } + + private Dimension getSizeWithoutCaret() { + Dimension size = mySizeContainer.getContentSize(); + if (isOneLineMode()) return new Dimension(size.width, getLineHeight()); + if (mySettings.isAdditionalPageAtBottom()) { + int lineHeight = getLineHeight(); + return new Dimension(size.width, + size.height + + Math.max(getScrollingModel().getVisibleArea().height - 2 * lineHeight, lineHeight)); + } + + return getContentSize(); + } + + public Dimension getContentSize() { + Dimension size = mySizeContainer.getContentSize(); + return new Dimension(size.width, size.height + mySettings.getAdditionalLinesCount() * getLineHeight()); + } + + public JScrollPane getScrollPane() { + return myScrollPane; + } + + public int logicalPositionToOffset(LogicalPosition pos) { + ApplicationManager.getApplication().assertIsDispatchThread(); + if (myDocument.getLineCount() == 0) return 0; + + if (pos.line < 0) throw new IndexOutOfBoundsException("Wrong line: " + pos.line); + if (pos.column < 0) throw new IndexOutOfBoundsException("Wrong column:" + pos.column); + + if (pos.line >= myDocument.getLineCount()) { + return myDocument.getTextLength(); + } + + int start = myDocument.getLineStartOffset(pos.line); + int end = myDocument.getLineEndOffset(pos.line); + + CharSequence text = myDocument.getCharsNoThreadCheck(); + + if (pos.column == 0) return start; + return EditorUtil.calcOffset(this, text, start, end, pos.column, mySettings.getTabSize(myProject)); + } + + public void setLastColumnNumber(int val) { + ApplicationManager.getApplication().assertIsDispatchThread(); + myLastColumnNumber = val; + } + + public int getLastColumnNumber() { + ApplicationManager.getApplication().assertIsDispatchThread(); + return myLastColumnNumber; + } + + int getVisibleLineCount() { + int line = getDocument().getLineCount(); + line -= myFoldingModel.getFoldedLinesCountBefore(getDocument().getTextLength() + 1); + return line; + } + + public VisualPosition logicalToVisualPosition(LogicalPosition logicalPos) { + ApplicationManager.getApplication().assertIsDispatchThread(); + if (!myFoldingModel.isFoldingEnabled()) return new VisualPosition(logicalPos.line, logicalPos.column); + + int offset = logicalPositionToOffset(logicalPos); + + FoldRegion outermostCollapsed = myFoldingModel.getCollapsedRegionAtOffset(offset); + if (outermostCollapsed != null && offset > outermostCollapsed.getStartOffset()) { + if (offset < getDocument().getTextLength() - 1) { + offset = outermostCollapsed.getStartOffset(); + LogicalPosition foldStart = offsetToLogicalPosition(offset); + return logicalToVisualPosition(foldStart); + } + else { + offset = outermostCollapsed.getEndOffset() + 3; + } + } + + int line = logicalPos.line; + int column = logicalPos.column; + + line -= myFoldingModel.getFoldedLinesCountBefore(offset); + + FoldRegion[] toplevel = myFoldingModel.fetchTopLevel(); + for (int idx = myFoldingModel.getLastTopLevelIndexBefore(offset); idx >= 0; idx--) { + FoldRegion region = toplevel[idx]; + if (region.isValid()) { + if (region.getDocument().getLineNumber(region.getEndOffset()) == logicalPos.line && + region.getEndOffset() <= offset) { + LogicalPosition foldStart = offsetToLogicalPosition(region.getStartOffset()); + LogicalPosition foldEnd = offsetToLogicalPosition(region.getEndOffset()); + column += foldStart.column + region.getPlaceholderText().length() - foldEnd.column; + offset = region.getStartOffset(); + logicalPos = foldStart; + } + else { + break; + } + } + } + + LOG.assertTrue(line >= 0); + + return new VisualPosition(line, Math.max(0, column)); + } + + private FoldRegion getLastCollapsedBeforePosition(VisualPosition visual) { + FoldRegion[] topLevelCollapsed = myFoldingModel.fetchTopLevel(); + + if (topLevelCollapsed == null) return null; + + int start = 0; + int end = topLevelCollapsed.length - 1; + int i = 0; + + while (start <= end) { + i = (start + end) / 2; + FoldRegion region = topLevelCollapsed[i]; + LogicalPosition logFoldEnd = offsetToLogicalPosition(region.getEndOffset() - 1); + VisualPosition visFoldEnd = logicalToVisualPosition(logFoldEnd); + if (visFoldEnd.line < visual.line) { + start = i + 1; + } + else { + if (visFoldEnd.line > visual.line) { + end = i - 1; + } + else { + if (visFoldEnd.column < visual.column) { + start = i + 1; + } + else { + if (visFoldEnd.column > visual.column) { + end = i - 1; + } + else { + i--; + break; + } + } + } + } + } + + while (i >= 0 && i < topLevelCollapsed.length) { + if (topLevelCollapsed[i].isValid()) break; + i--; + } + + if (i >= 0 && i < topLevelCollapsed.length) { + FoldRegion region = topLevelCollapsed[i]; + LogicalPosition logFoldEnd = offsetToLogicalPosition(region.getEndOffset() - 1); + VisualPosition visFoldEnd = logicalToVisualPosition(logFoldEnd); + if (visFoldEnd.line > visual.line || visFoldEnd.line == visual.line && visFoldEnd.column > visual.column) { + i--; + if (i >= 0) { + return topLevelCollapsed[i]; + } + else { + return null; + } + } + return region; + } + + return null; + } + + public LogicalPosition visualToLogicalPosition(VisualPosition visiblePos) { + ApplicationManager.getApplication().assertIsDispatchThread(); + if (!myFoldingModel.isFoldingEnabled()) return new LogicalPosition(visiblePos.line, visiblePos.column); + + int line = visiblePos.line; + int column = visiblePos.column; + + FoldRegion lastCollapsedBefore = getLastCollapsedBeforePosition(visiblePos); + + if (lastCollapsedBefore != null) { + LogicalPosition logFoldEnd = offsetToLogicalPosition(lastCollapsedBefore.getEndOffset()); + VisualPosition visFoldEnd = logicalToVisualPosition(logFoldEnd); + + line = logFoldEnd.line + (visiblePos.line - visFoldEnd.line); + if (visFoldEnd.line == visiblePos.line) { + if (visiblePos.column >= visFoldEnd.column) { + column = logFoldEnd.column + (visiblePos.column - visFoldEnd.column); + } + else { + return offsetToLogicalPosition(lastCollapsedBefore.getStartOffset()); + } + } + } + + if (column < 0) column = 0; + + return new LogicalPosition(line, column); + } + + private int calcLogicalLineNumber(int offset) { + int textLength = myDocument.getTextLength(); + if (textLength == 0) return 0; + + if (offset > textLength || offset < 0) { + throw new IndexOutOfBoundsException("Wrong offset: " + offset + " textLength: " + textLength); + } + + int lineIndex = myDocument.getLineNumber(offset); + + LOG.assertTrue(lineIndex >= 0 && lineIndex < myDocument.getLineCount()); + + return lineIndex; + } + + private int calcColumnNumber(int offset, int lineIndex) { + if (myDocument.getTextLength() == 0) return 0; + + CharSequence text = myDocument.getCharsSequence(); + int start = myDocument.getLineStartOffset(lineIndex); + if (start == offset) return 0; + return EditorUtil.calcColumnNumber(this, text, start, offset, mySettings.getTabSize(myProject)); + } + + private void moveCaretToScreenPos(int x, int y) { + if (x < 0) { + x = 0; + } + + LogicalPosition pos = xyToLogicalPosition(new Point(x, y)); + + int columnNumber = pos.column; + int lineNumber = pos.line; + + if (lineNumber >= myDocument.getLineCount()) { + lineNumber = myDocument.getLineCount() - 1; + } + if (!mySettings.isVirtualSpace()) { + if (lineNumber >= 0) { + int lineEndOffset = myDocument.getLineEndOffset(lineNumber); + int lineEndColumnNumber = calcColumnNumber(lineEndOffset, lineNumber); + if (columnNumber > lineEndColumnNumber) { + columnNumber = lineEndColumnNumber; + } + } + } + if (lineNumber < 0) { + lineNumber = 0; + columnNumber = 0; + } + if (!mySettings.isCaretInsideTabs()) { + int offset = logicalPositionToOffset(new LogicalPosition(lineNumber, columnNumber)); + CharSequence text = myDocument.getCharsSequence(); + if (offset >= 0 && offset < myDocument.getTextLength()) { + if (text.charAt(offset) == '\t') { + columnNumber = calcColumnNumber(offset, lineNumber); + } + } + } + LogicalPosition pos1 = new LogicalPosition(lineNumber, columnNumber); + getCaretModel().moveToLogicalPosition(pos1); + } + + private void runMousePressedCommand(final MouseEvent e) { + myMousePressedEvent = e; + EditorMouseEvent event = new EditorMouseEvent(this, e, getMouseEventArea(e)); + + EditorMouseListener[] mouseListeners = myMouseListeners.toArray(new EditorMouseListener[myMouseListeners.size()]); + for (int i = 0; i < mouseListeners.length; i++) { + mouseListeners[i].mousePressed(event); + } + + // On some systems (for example on Linux) popup trigger is MOUSE_PRESSED event. + // But this trigger is always consumed by popup handler. In that case we have to + // also move caret. + if (event.isConsumed() && + !(event.getMouseEvent().isPopupTrigger() || event.getArea() == EditorMouseEventArea.EDITING_AREA)) { + return; + } + + if (myCommandProcessor != null) { + Runnable runnable = new Runnable() { + public void run() { + processMousePressed(e); + } + }; + myCommandProcessor.executeCommand(myProject, runnable, "", null); + } + else { + processMousePressed(e); + } + } + + private void runMouseClickedCommand(final MouseEvent e) { + EditorMouseEvent event = new EditorMouseEvent(this, e, getMouseEventArea(e)); + EditorMouseListener[] listeners = myMouseListeners.toArray(new EditorMouseListener[myMouseListeners.size()]); + for (int i = 0; i < listeners.length; i++) { + listeners[i].mouseClicked(event); + if (event.isConsumed()) { + e.consume(); + return; + } + } + } + + private void runMouseReleasedCommand(final MouseEvent e) { + myScrollingTimer.stop(); + EditorMouseEvent event = new EditorMouseEvent(this, e, getMouseEventArea(e)); + EditorMouseListener[] listeners = myMouseListeners.toArray(new EditorMouseListener[myMouseListeners.size()]); + for (int i = 0; i < listeners.length; i++) { + listeners[i].mouseReleased(event); + if (event.isConsumed()) { + e.consume(); + return; + } + } + + if (myCommandProcessor != null) { + Runnable runnable = new Runnable() { + public void run() { + processMouseReleased(e); + } + }; + myCommandProcessor.executeCommand(myProject, runnable, "", null); + } + else { + processMouseReleased(e); + } + } + + private void runMouseEnteredCommand(MouseEvent e) { + EditorMouseEvent event = new EditorMouseEvent(this, e, getMouseEventArea(e)); + EditorMouseListener[] listeners = myMouseListeners.toArray(new EditorMouseListener[myMouseListeners.size()]); + for (int i = 0; i < listeners.length; i++) { + listeners[i].mouseEntered(event); + if (event.isConsumed()) { + e.consume(); + return; + } + } + } + + private void runMouseExitedCommand(MouseEvent e) { + EditorMouseEvent event = new EditorMouseEvent(this, e, getMouseEventArea(e)); + EditorMouseListener[] listeners = myMouseListeners.toArray(new EditorMouseListener[myMouseListeners.size()]); + for (int i = 0; i < listeners.length; i++) { + listeners[i].mouseExited(event); + if (event.isConsumed()) { + e.consume(); + return; + } + } + } + + private void processMousePressed(MouseEvent e) { + if (myMouseSelectionState != MOUSE_SELECTION_STATE_NONE && + System.currentTimeMillis() - myMouseSelectionChangeTimestamp > 1000) { + setMouseSelectionState(MOUSE_SELECTION_STATE_NONE); + } + + int x = e.getX(); + int y = e.getY(); + + if (x < 0) x = 0; + if (y < 0) y = 0; + + final EditorMouseEventArea eventArea = getMouseEventArea(e); + if (eventArea == EditorMouseEventArea.FOLDING_OUTLINE_AREA) { + final FoldRegion range = myGutterComponent.findFoldingAnchorAt(x, y); + if (range != null) { + final boolean expansion = !range.isExpanded(); + + int scrollShift = y - getScrollingModel().getVerticalScrollOffset(); + Runnable processor = new Runnable() { + public void run() { + myFoldingModel.flushCaretShift(); + range.setExpanded(expansion); + } + }; + getFoldingModel().runBatchFoldingOperation(processor); + y = myGutterComponent.getHeadCenterY(range); + getScrollingModel().scrollVertically(y - scrollShift); + return; + } + } + + if (e.getSource() == myGutterComponent) { + if (eventArea == EditorMouseEventArea.LINE_MARKERS_AREA || + eventArea == EditorMouseEventArea.ANNOTATIONS_AREA) { + myGutterComponent.mousePressed(e); + if (e.isConsumed()) return; + } + x = 0; + } + + int oldSelectionStart = mySelectionModel.getLeadSelectionOffset(); + moveCaretToScreenPos(x, y); + + if (e.isPopupTrigger()) return; + + requestFocus(); + + int caretOffset = getCaretModel().getOffset(); + + myMouseSelectedRegion = myFoldingModel.getFoldingPlaceholderAt(new Point(x, y)); + myMousePressedInsideSelection = mySelectionModel.hasSelection() && + caretOffset >= mySelectionModel.getSelectionStart() && + caretOffset <= mySelectionModel.getSelectionEnd(); + + if (!myMousePressedInsideSelection && mySelectionModel.hasBlockSelection()) { + int[] starts = mySelectionModel.getBlockSelectionStarts(); + int[] ends = mySelectionModel.getBlockSelectionEnds(); + for (int i = 0; i < starts.length; i++) { + if (caretOffset >= starts[i] && caretOffset < ends[i]) { + myMousePressedInsideSelection = true; + break; + } + } + } + + if (getMouseEventArea(e) == EditorMouseEventArea.LINE_NUMBERS_AREA && e.getClickCount() == 1) { + mySelectionModel.selectLineAtCaret(); + setMouseSelectionState(MOUSE_SELECTION_STATE_LINE_SELECTED); + mySavedSelectionStart = mySelectionModel.getSelectionStart(); + mySavedSelectionEnd = mySelectionModel.getSelectionEnd(); + return; + } + + if (e.isShiftDown() && !e.isControlDown() && !e.isAltDown()) { + if (getMouseSelectionState() != MOUSE_SELECTION_STATE_NONE) { + if (caretOffset < mySavedSelectionStart) { + mySelectionModel.setSelection(mySavedSelectionEnd, caretOffset); + } + else { + mySelectionModel.setSelection(mySavedSelectionStart, caretOffset); + } + } + else { + mySelectionModel.setSelection(oldSelectionStart, caretOffset); + } + } + else { + if (!myMousePressedInsideSelection && getSelectionModel().hasSelection()) { + setMouseSelectionState(MOUSE_SELECTION_STATE_NONE); + mySelectionModel.setSelection(caretOffset, caretOffset); + } + else { + if (!e.isPopupTrigger()) { + switch (e.getClickCount()) { + case 2: + mySelectionModel.selectWordAtCaret(mySettings.isMouseClickSelectionHonorsCamelWords()); + setMouseSelectionState(MOUSE_SELECTION_STATE_WORD_SELECTED); + mySavedSelectionStart = mySelectionModel.getSelectionStart(); + mySavedSelectionEnd = mySelectionModel.getSelectionEnd(); + getCaretModel().moveToOffset(mySavedSelectionEnd); + break; + + case 3: + mySelectionModel.selectLineAtCaret(); + setMouseSelectionState(MOUSE_SELECTION_STATE_LINE_SELECTED); + mySavedSelectionStart = mySelectionModel.getSelectionStart(); + mySavedSelectionEnd = mySelectionModel.getSelectionEnd(); + break; + } + } + } + } + } + + private static boolean isControlKeyDown(MouseEvent mouseEvent) { + return SystemInfo.isMac ? mouseEvent.isMetaDown() : mouseEvent.isControlDown(); + } + + private void processMouseReleased(MouseEvent e) { + if (e.getSource() == myGutterComponent) { + myGutterComponent.mouseReleased(e); + } + + if (getMouseEventArea(e) != EditorMouseEventArea.EDITING_AREA || e.getY() < 0 || e.getX() < 0) { + return; + } + +// if (myMousePressedInsideSelection) getSelectionModel().removeSelection(); + final FoldRegion region = ((FoldingModelEx)getFoldingModel()).getFoldingPlaceholderAt(e.getPoint()); + if (e.getX() >= 0 && e.getY() >= 0 && region != null && region == myMouseSelectedRegion) { + getFoldingModel().runBatchFoldingOperation(new Runnable() { + public void run() { + myFoldingModel.flushCaretShift(); + region.setExpanded(true); + } + }); + } + + if (myMousePressedEvent != null && myMousePressedEvent.getClickCount() == 1 && myMousePressedInsideSelection) { + getSelectionModel().removeSelection(); + } + } + + public DataContext getDataContext() { + return getProjectAwareDataContext(DataManager.getInstance().getDataContext(getContentComponent())); + } + + public DataContext getProjectAwareDataContext(final DataContext original) { + if (original.getData(DataConstants.PROJECT) == myProject) return original; + + return new DataContext() { + public Object getData(String dataId) { + if (DataConstants.PROJECT.equals(dataId)) { + return myProject; + } + return original.getData(dataId); + } + }; + } + + + public EditorMouseEventArea getMouseEventArea(MouseEvent e) { + if (myGutterComponent != e.getSource()) return EditorMouseEventArea.EDITING_AREA; + + int x = myGutterComponent.convertX(e.getX()); + + if (x >= myGutterComponent.getLineNumberAreaOffset() && + x < myGutterComponent.getLineNumberAreaOffset() + myGutterComponent.getLineNumberAreaWidth()) { + return EditorMouseEventArea.LINE_NUMBERS_AREA; + } + + if (x >= myGutterComponent.getAnnotationsAreaOffset() && + x <= myGutterComponent.getAnnotationsAreaOffset() + myGutterComponent.getAnnotationsAreaWidth()) { + return EditorMouseEventArea.ANNOTATIONS_AREA; + } + + if (x >= myGutterComponent.getLineMarkerAreaOffset() && + x < myGutterComponent.getLineMarkerAreaOffset() + myGutterComponent.getLineMarkerAreaWidth()) { + return EditorMouseEventArea.LINE_MARKERS_AREA; + } + + if (x >= myGutterComponent.getFoldingAreaOffset() && + x < myGutterComponent.getFoldingAreaOffset() + myGutterComponent.getFoldingAreaWidth()) { + return EditorMouseEventArea.FOLDING_OUTLINE_AREA; + } + + return null; + } + + private void requestFocus() { + myEditorComponent.requestFocus(); + } + + private void validateMousePointer(MouseEvent e) { + if (e.getSource() == myGutterComponent) { + FoldRegion foldingAtCursor = myGutterComponent.findFoldingAnchorAt(e.getX(), e.getY()); + myGutterComponent.setActiveFoldRegion(foldingAtCursor); + if (foldingAtCursor != null) { + myGutterComponent.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + } + else { + myGutterComponent.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + } + } + else { + myGutterComponent.setActiveFoldRegion(null); + if (getSelectionModel().hasSelection() && + (e.getModifiersEx() & (MouseEvent.BUTTON1_DOWN_MASK | MouseEvent.BUTTON2_DOWN_MASK)) == 0) { + int offset = logicalPositionToOffset(xyToLogicalPosition(e.getPoint())); + if (getSelectionModel().getSelectionStart() <= offset && offset < getSelectionModel().getSelectionEnd()) { + myEditorComponent.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + return; + } + } + myEditorComponent.setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR)); + } + } + + private void runMouseDraggedCommand(final MouseEvent e) { + if (myCommandProcessor == null || myMousePressedEvent != null && myMousePressedEvent.isConsumed()) { + return; + } + myCommandProcessor.executeCommand(myProject, new Runnable() { + public void run() { + processMouseDragged(e); + } + }, "", MOUSE_DRAGGED_GROUP); + } + + private void processMouseDragged(MouseEvent e) { + if (SwingUtilities.isRightMouseButton(e)) { + return; + } + Rectangle rect = getScrollingModel().getVisibleArea(); + + int dx = 0; + int x = e.getX(); + + if (e.getSource() == myGutterComponent) { + x = 0; + } + + if (x < rect.x) { + dx = x - rect.x; + } + else { + if (x > rect.x + rect.width) { + dx = x - rect.x - rect.width; + } + } + + int dy = 0; + int y = e.getY(); + if (y < rect.y) { + dy = y - rect.y; + } + else { + if (y > rect.y + rect.height) { + dy = y - rect.y - rect.height; + } + } + if (dx == 0 && dy == 0) { + myScrollingTimer.stop(); + + SelectionModel selectionModel = getSelectionModel(); + int oldSelectionStart = selectionModel.getLeadSelectionOffset(); + int oldCaretOffset = getCaretModel().getOffset(); + LogicalPosition oldLogicalCaret = getCaretModel().getLogicalPosition(); + moveCaretToScreenPos(x, y); + getScrollingModel().scrollToCaret(ScrollType.RELATIVE); + + int newCaretOffset = getCaretModel().getOffset(); + int caretShift = newCaretOffset - mySavedSelectionStart; + + if (myMousePressedEvent != null && + getMouseEventArea(myMousePressedEvent) != EditorMouseEventArea.EDITING_AREA && + getMouseEventArea(myMousePressedEvent) != EditorMouseEventArea.LINE_NUMBERS_AREA) { + selectionModel.setSelection(oldSelectionStart, newCaretOffset); + } + else { + if (isColumnMode()) { + final LogicalPosition blockStart = selectionModel.hasBlockSelection() + ? selectionModel.getBlockStart() + : oldLogicalCaret; + selectionModel.setBlockSelection(blockStart, getCaretModel().getLogicalPosition()); + } + else { + if (getMouseSelectionState() != MOUSE_SELECTION_STATE_NONE) { + if (caretShift < 0) { + int newSelection = newCaretOffset; + if (getMouseSelectionState() == MOUSE_SELECTION_STATE_WORD_SELECTED) { + newSelection = mySelectionModel.getWordAtCaretStart(); + } + else { + if (getMouseSelectionState() == MOUSE_SELECTION_STATE_LINE_SELECTED) { + newSelection = logicalPositionToOffset( + visualToLogicalPosition(new VisualPosition(getCaretModel().getVisualPosition().line, 0))); + } + } + if (newSelection < 0) newSelection = newCaretOffset; + selectionModel.setSelection(mySavedSelectionEnd, newSelection); + getCaretModel().moveToOffset(newSelection); + } + else { + int newSelection = newCaretOffset; + if (getMouseSelectionState() == MOUSE_SELECTION_STATE_WORD_SELECTED) { + newSelection = mySelectionModel.getWordAtCaretEnd(); + } + else { + if (getMouseSelectionState() == MOUSE_SELECTION_STATE_LINE_SELECTED) { + newSelection = logicalPositionToOffset( + visualToLogicalPosition(new VisualPosition(getCaretModel().getVisualPosition().line + 1, 0))); + } + } + if (newSelection < 0) newSelection = newCaretOffset; + selectionModel.setSelection(mySavedSelectionStart, newSelection); + getCaretModel().moveToOffset(newSelection); + } + return; + } + + if (!myMousePressedInsideSelection) { + selectionModel.setSelection(oldSelectionStart, newCaretOffset); + } + else { + if (caretShift != 0) { + if (myMousePressedEvent != null) { + if (mySettings.isDndEnabled()) { + boolean isCopy = isControlKeyDown(e) || isViewer() || !getDocument().isWritable(); + mySavedCaretOffsetForDNDUndoHack = oldCaretOffset; + getContentComponent().getTransferHandler().exportAsDrag(getContentComponent(), e, + isCopy + ? TransferHandler.COPY + : TransferHandler.MOVE); + } + else { + selectionModel.removeSelection(); + } + myMousePressedEvent = null; + } + } + } + } + } + } + else { + myScrollingTimer.start(dx, dy); + } + } + + private static class RepaintCursorThread extends Thread { + private long mySleepTime = 500; + private boolean myIsBlinkCaret = true; + private EditorImpl myEditor = null; + private boolean isStopped = false; + private MyRepaintRunnable myRepaintRunnable; + + public RepaintCursorThread() { + super("EditorCaretThread"); + myRepaintRunnable = new MyRepaintRunnable(); + } + + private class MyRepaintRunnable implements Runnable { + public void run() { + if (myEditor != null) { + myEditor.myCaretCursor.repaint(); + } + } + } + + public void setBlinkPeriod(int blinkPeriod) { + mySleepTime = blinkPeriod > 10 ? blinkPeriod : 10; + } + + public void setBlinkCaret(boolean value) { + myIsBlinkCaret = value; + } + + public synchronized void stopThread() { + isStopped = true; + } + + public void run() { + while (true) { + try { + Thread.sleep(myIsBlinkCaret ? mySleepTime : 1000); + } + catch (InterruptedException e) { + } + + synchronized (this) { + if (isStopped) { + break; + } + } + + if (myEditor == null) { + continue; + } + CaretCursor activeCursor = myEditor.myCaretCursor; + + long time = System.currentTimeMillis(); + time -= activeCursor.myStartTime; + + if (time > mySleepTime) { + boolean toRepaint = true; + if (myIsBlinkCaret) { + activeCursor.isVisible = !activeCursor.isVisible; + } + else { + + toRepaint = !activeCursor.isVisible; + activeCursor.isVisible = true; + } + + if (toRepaint) { + SwingUtilities.invokeLater(myRepaintRunnable); + } + } + } + } + } + + void updateCaretCursor() { + if (!IJSwingUtilities.hasFocus(getContentComponent())) { + stopOptimizedScrolling(); + } + + if (myCursorUpdater == null) { + myCursorUpdater = new Runnable() { + public void run() { + if (myCursorUpdater == null) return; + myCursorUpdater = null; + + if (getDocument().getMarkupModel(myProject) == null) return; + + VisualPosition caretPosition = getCaretModel().getVisualPosition(); + Point pos1 = visualPositionToXY(caretPosition); + Point pos2 = visualPositionToXY(new VisualPosition(caretPosition.line, caretPosition.column + 1)); + myCaretCursor.setPosition(pos1, pos2.x - pos1.x); + } + }; + } + } + + public void setCaretVisible(boolean b) { + if (b) { + myCaretCursor.activate(); + } + else { + myCaretCursor.passivate(); + } + } + + public void addFocusListener(FocusChangeListener listener) { + myFocusListeners.add(listener); + } + + public Project getProject() { + return myProject; + } + + public boolean isOneLineMode() { + return myIsOneLineMode; + } + + public void setOneLineMode(boolean isOneLineMode) { + myIsOneLineMode = isOneLineMode; + getScrollPane().setInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, null); + reinitSettings(); + } + + public void stopOptimizedScrolling() { + if (SystemInfo.isMac) return; + myEditorComponent.setOpaque(false); + } + + private void startOptimizedScrolling() { + if (SystemInfo.isMac) return; + myEditorComponent.setOpaque(true); + } + + private class CaretCursor { + private Point myLocation; + private int myWidth; + private boolean isVisible = true; + private long myStartTime = 0; + + public CaretCursor() { + myLocation = new Point(0, 0); + } + + public void activate() { + synchronized (ourCaretThread) { + ourCaretThread.myEditor = EditorImpl.this; + ourCaretThread.setBlinkCaret(mySettings.isBlinkCaret()); + ourCaretThread.setBlinkPeriod(mySettings.getCaretBlinkPeriod()); + isVisible = true; + } + } + + public void passivate() { + synchronized (ourCaretThread) { + isVisible = false; + } + } + + public void setPosition(Point location, int width) { + myStartTime = System.currentTimeMillis(); + myLocation = location; + isVisible = true; + myWidth = Math.max(width, 2); + repaint(); + } + + private void repaint() { + myEditorComponent.repaintEditorComponent(myLocation.x, + myLocation.y, + myWidth, + getLineHeight()); + } + + public void paint(Graphics g) { + if (!isVisible || !IJSwingUtilities.hasFocus(getContentComponent()) || isRendererMode()) return; + + int x = myLocation.x; + int lineHeight = getLineHeight(); + int y = myLocation.y; + + Rectangle viewRect = getScrollingModel().getVisibleArea(); + if (x - viewRect.x < 0) { + return; + } + + + g.setColor(myScheme.getColor(EditorColors.CARET_COLOR)); + if (!SystemInfo.isMac) { + Color background = myScheme.getColor(EditorColors.CARET_ROW_COLOR); + if (background == null) background = getBackroundColor(); + g.setXORMode(background != null ? background : Color.white); + } + + if (EditorImpl.this.myIsInsertMode != mySettings.isBlockCursor()) { + for (int i = 0; i < mySettings.getLineCursorWidth(); i++) { + g.drawLine(x + i, y, x + i, y + lineHeight - 1); + } + } + else { + g.fillRect(x, y, myWidth, lineHeight - 1); + } + + g.setPaintMode(); + } + } + + private class ScrollingTimer { + Timer myTimer; + private static final int TIMER_PERIOD = 100; + private static final int CYCLE_SIZE = 20; + private int myXCycles; + private int myYCycles; + private int myDx; + private int myDy; + private int xPassedCycles = 0; + private int yPassedCycles = 0; + + public void start(int dx, int dy) { + myDx = 0; + myDy = 0; + if (dx > 0) { + myXCycles = CYCLE_SIZE / dx + 1; + myDx = 1 + dx / CYCLE_SIZE; + } + else { + if (dx < 0) { + myXCycles = -CYCLE_SIZE / dx + 1; + myDx = -1 + dx / CYCLE_SIZE; + } + } + + if (dy > 0) { + myYCycles = CYCLE_SIZE / dy + 1; + myDy = 1 + dy / CYCLE_SIZE; + } + else { + if (dy < 0) { + myYCycles = -CYCLE_SIZE / dy + 1; + myDy = -1 + dy / CYCLE_SIZE; + } + } + + if (myTimer != null) { + return; + } + myTimer = new Timer(TIMER_PERIOD, + new ActionListener() { + public void actionPerformed(ActionEvent e) { + myCommandProcessor.executeCommand(myProject, new Runnable() { + public void run() { + int oldSelectionStart = mySelectionModel.getLeadSelectionOffset(); + LogicalPosition caretPosition = getCaretModel().getLogicalPosition(); + int columnNumber = caretPosition.column; + xPassedCycles++; + if (xPassedCycles >= myXCycles) { + xPassedCycles = 0; + columnNumber += myDx; + } + + int lineNumber = caretPosition.line; + yPassedCycles++; + if (yPassedCycles >= myYCycles) { + yPassedCycles = 0; + lineNumber += myDy; + } + + LogicalPosition pos = new LogicalPosition(lineNumber, columnNumber); + getCaretModel().moveToLogicalPosition(pos); + getScrollingModel().scrollToCaret(ScrollType.RELATIVE); + + int newCaretOffset = getCaretModel().getOffset(); + int caretShift = newCaretOffset - mySavedSelectionStart; + + if (getMouseSelectionState() != MOUSE_SELECTION_STATE_NONE) { + if (caretShift < 0) { + int newSelection = newCaretOffset; + if (getMouseSelectionState() == MOUSE_SELECTION_STATE_WORD_SELECTED) { + newSelection = mySelectionModel.getWordAtCaretStart(); + } + else { + if (getMouseSelectionState() == MOUSE_SELECTION_STATE_LINE_SELECTED) { + newSelection = logicalPositionToOffset(visualToLogicalPosition( + new VisualPosition(getCaretModel().getVisualPosition().line, 0))); + } + } + if (newSelection < 0) newSelection = newCaretOffset; + mySelectionModel.setSelection(mySavedSelectionEnd, newSelection); + getCaretModel().moveToOffset(newSelection); + } + else { + int newSelection = newCaretOffset; + if (getMouseSelectionState() == MOUSE_SELECTION_STATE_WORD_SELECTED) { + newSelection = mySelectionModel.getWordAtCaretEnd(); + } + else { + if (getMouseSelectionState() == MOUSE_SELECTION_STATE_LINE_SELECTED) { + newSelection = logicalPositionToOffset(visualToLogicalPosition( + new VisualPosition(getCaretModel().getVisualPosition().line + 1, 0))); + } + } + if (newSelection < 0) newSelection = newCaretOffset; + mySelectionModel.setSelection(mySavedSelectionStart, newSelection); + getCaretModel().moveToOffset(newSelection); + } + return; + } + + if (mySelectionModel.hasBlockSelection()) { + mySelectionModel.setBlockSelection(mySelectionModel.getBlockStart(), + getCaretModel().getLogicalPosition()); + } + else { + mySelectionModel.setSelection(oldSelectionStart, getCaretModel().getOffset()); + } + } + }, + "Move Cursor", null); + } + }); + myTimer.start(); + } + + public void stop() { + if (myTimer != null) { + myTimer.stop(); + myTimer = null; + } + } + + } + + class MyScrollBar extends JScrollBar { + + public MyScrollBar(int orientation) { + super(orientation); + } + + /** + * This is helper method. It returns height of the top (descrease) scrollbar + * button. Please note, that it's possible to return real height only if scrollbar + * is instance of BasicScrollBarUI. Otherwise it returns fake (but good enough :) ) + * value. + */ + int getDecScrollButtonHeight() { + ScrollBarUI ui = getUI(); + Insets insets = getInsets(); + if (ui instanceof BasicScrollBarUI) { + try { + Field decrButtonField = BasicScrollBarUI.class.getDeclaredField("decrButton"); + decrButtonField.setAccessible(true); + JButton decrButtonValue = (JButton)decrButtonField.get(ui); + LOG.assertTrue(decrButtonValue != null); + return insets.top + decrButtonValue.getHeight(); + } + catch (Exception exc) { + exc.printStackTrace(); + throw new IllegalStateException(exc.getMessage()); + } + } + else { + return insets.top + 15; + } + } + + /** + * This is helper method. It returns height of the bottom (increase) scrollbar + * button. Please note, that it's possible to return real height only if scrollbar + * is instance of BasicScrollBarUI. Otherwise it returns fake (but good enough :) ) + * value. + */ + int getIncScrollButtonHeight() { + ScrollBarUI ui = getUI(); + Insets insets = getInsets(); + if (ui instanceof BasicScrollBarUI) { + try { + Field incrButtonField = BasicScrollBarUI.class.getDeclaredField("incrButton"); + incrButtonField.setAccessible(true); + JButton incrButtonValue = (JButton)incrButtonField.get(ui); + LOG.assertTrue(incrButtonValue != null); + return insets.bottom + incrButtonValue.getHeight(); + } + catch (Exception exc) { + exc.printStackTrace(); + throw new IllegalStateException(exc.getMessage()); + } + } + else if ("apple.laf.AquaScrollBarUI".equals(ui.getClass().getName())) { + return insets.bottom + 30; + } + else { + return insets.bottom + 15; + } + } + + public int getUnitIncrement(int direction) { + JViewport vp = myScrollPane.getViewport(); + Rectangle vr = vp.getViewRect(); + return myEditorComponent.getScrollableUnitIncrement(vr, SwingConstants.VERTICAL, direction); + } + + public int getBlockIncrement(int direction) { + JViewport vp = myScrollPane.getViewport(); + Rectangle vr = vp.getViewRect(); + return myEditorComponent.getScrollableBlockIncrement(vr, SwingConstants.VERTICAL, direction); + } + } + + private MyEditable getViewer() { + if (myEditable == null) { + myEditable = new MyEditable(); + } + return myEditable; + } + + public CopyProvider getCopyProvider() { + return getViewer(); + } + + public CutProvider getCutProvider() { + return getViewer(); + } + + public PasteProvider getPasteProvider() { + + return getViewer(); + } + + public DeleteProvider getDeleteProvider() { + return getViewer(); + } + + private class MyEditable implements CutProvider, CopyProvider, PasteProvider, DeleteProvider { + public void performCopy(DataContext dataContext) { + executeAction(IdeActions.ACTION_EDITOR_COPY, dataContext); + } + + public boolean isCopyEnabled(DataContext dataContext) { + return true; + } + + public void performCut(DataContext dataContext) { + executeAction(IdeActions.ACTION_EDITOR_CUT, dataContext); + } + + public boolean isCutEnabled(DataContext dataContext) { + return !isViewer() && getDocument().isWritable(); + } + + public void performPaste(DataContext dataContext) { + executeAction(IdeActions.ACTION_EDITOR_PASTE, dataContext); + } + + public boolean isPastePossible(DataContext dataContext) { + // Copy of isPasteEnabled. See interface method javadoc. + return !isViewer() && getDocument().isWritable(); + } + + public boolean isPasteEnabled(DataContext dataContext) { + return !isViewer() && getDocument().isWritable(); + } + + public void deleteElement(DataContext dataContext) { + executeAction(IdeActions.ACTION_EDITOR_DELETE, dataContext); + } + + public boolean canDeleteElement(DataContext dataContext) { + return !isViewer() && getDocument().isWritable(); + } + + private void executeAction(String actionId, DataContext dataContext) { + EditorAction action = (EditorAction)ActionManager.getInstance().getAction(actionId); + if (action != null) { + action.actionPerformed(EditorImpl.this, dataContext); + } + } + } + + public void setColorsScheme(EditorColorsScheme scheme) { + ApplicationManager.getApplication().assertIsDispatchThread(); + myScheme = scheme; + reinitSettings(); + } + + public EditorColorsScheme getColorsScheme() { + ApplicationManager.getApplication().assertIsDispatchThread(); + return myScheme; + } + + public void setVerticalScrollbarOrientation(int type) { + ApplicationManager.getApplication().assertIsDispatchThread(); + int currentHorOffset = myScrollingModel.getHorizontalScrollOffset(); + myScrollbarOrientation = type; + if (type == EditorEx.VERTICAL_SCROLLBAR_LEFT) { + myScrollPane.setLayout(new LeftHandScrollbarLayout()); + } + else { + myScrollPane.setLayout(new ScrollPaneLayout()); + } + myScrollingModel.scrollHorizontally(currentHorOffset); + } + + public void setVerticalScrollbarVisible(boolean b) { + if (b) { + myScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); + } + else { + myScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER); + } + } + + public void setHorizontalScrollbarVisible(boolean b) { + if (b) { + myScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); + } + else { + myScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); + } + } + + public int getVerticalScrollbarOrientation() { + return myScrollbarOrientation; + } + + public MyScrollBar getVerticalScrollBar() { + return myVerticalScrollBar; + } + + public JPanel getPanel() { + return myPanel; + } + + private int getMouseSelectionState() { + return myMouseSelectionState; + } + + private void setMouseSelectionState(int mouseSelectionState) { + myMouseSelectionState = mouseSelectionState; + myMouseSelectionChangeTimestamp = System.currentTimeMillis(); + } + + + public void replaceInputMethodText(InputMethodEvent e) { + getInputMethodRequests(); + myInputMethodRequestsHandler.replaceInputMethodText(e); + } + + public void inputMethodCaretPositionChanged(InputMethodEvent e) { + getInputMethodRequests(); + myInputMethodRequestsHandler.setInputMethodCaretPosition(e); + } + + public InputMethodRequests getInputMethodRequests() { + if (myInputMethodRequestsHandler == null) { + myInputMethodRequestsHandler = new MyInputMethodHandler(); + myInputMethodRequestsSwingWrapper = new MyInputMethodHandleSwingThreadWrapper(myInputMethodRequestsHandler); + } + return myInputMethodRequestsSwingWrapper; + } + + public boolean processKeyTyped(KeyEvent e) { + if (e.getID() != KeyEvent.KEY_TYPED) return false; + char c = e.getKeyChar(); + if (isReallyTypedEvent(e) && c >= 0x20 && c != 0x7F) { // Hack just like in javax.swing.text.DefaultEditorKit.DefaultKeyTypedAction + processKeyTyped(c); + return true; + } + else { + return false; + } + } + + private static boolean isReallyTypedEvent(KeyEvent e) { + int modifiers = e.getModifiers(); + if (SystemInfo.isMac) { + return !e.isMetaDown() && !e.isControlDown(); + } + + return (modifiers & ActionEvent.ALT_MASK) == (modifiers & ActionEvent.CTRL_MASK); + } + + public void beforeModalityStateChanged() { + myScrollingModel.beforeModalityStateChanged(); + } + + private static class MyInputMethodHandleSwingThreadWrapper implements InputMethodRequests { + private InputMethodRequests myDelegate; + + public MyInputMethodHandleSwingThreadWrapper(InputMethodRequests delegate) { + myDelegate = delegate; + } + + public Rectangle getTextLocation(final TextHitInfo offset) { + if (ApplicationManager.getApplication().isDispatchThread()) return myDelegate.getTextLocation(offset); + + final Rectangle[] r = new Rectangle[1]; + try { + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + r[0] = myDelegate.getTextLocation(offset); + } + }); + } + catch (InterruptedException e) { + LOG.error(e); + } + catch (InvocationTargetException e) { + LOG.error(e); + } + return r[0]; + } + + public TextHitInfo getLocationOffset(final int x, final int y) { + if (ApplicationManager.getApplication().isDispatchThread()) return myDelegate.getLocationOffset(x, y); + + final TextHitInfo[] r = new TextHitInfo[1]; + try { + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + r[0] = myDelegate.getLocationOffset(x, y); + } + }); + } + catch (InterruptedException e) { + LOG.error(e); + } + catch (InvocationTargetException e) { + LOG.error(e); + } + return r[0]; + } + + public int getInsertPositionOffset() { + if (ApplicationManager.getApplication().isDispatchThread()) return myDelegate.getInsertPositionOffset(); + + final int[] r = new int[1]; + try { + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + r[0] = myDelegate.getInsertPositionOffset(); + } + }); + } + catch (InterruptedException e) { + LOG.error(e); + } + catch (InvocationTargetException e) { + LOG.error(e); + } + return r[0]; + } + + public AttributedCharacterIterator getCommittedText(final int beginIndex, final int endIndex, + final AttributedCharacterIterator.Attribute[] attributes) { + if (ApplicationManager.getApplication().isDispatchThread()) { + return myDelegate.getCommittedText(beginIndex, + endIndex, + attributes); + } + final AttributedCharacterIterator[] r = new AttributedCharacterIterator[1]; + try { + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + r[0] = myDelegate.getCommittedText(beginIndex, endIndex, attributes); + } + }); + } + catch (InterruptedException e) { + LOG.error(e); + } + catch (InvocationTargetException e) { + LOG.error(e); + } + return r[0]; + } + + public int getCommittedTextLength() { + if (ApplicationManager.getApplication().isDispatchThread()) return myDelegate.getCommittedTextLength(); + final int[] r = new int[1]; + try { + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + r[0] = myDelegate.getCommittedTextLength(); + } + }); + } + catch (InterruptedException e) { + LOG.error(e); + } + catch (InvocationTargetException e) { + LOG.error(e); + } + return r[0]; + } + + public AttributedCharacterIterator cancelLatestCommittedText(AttributedCharacterIterator.Attribute[] attributes) { + return null; + } + + public AttributedCharacterIterator getSelectedText(final AttributedCharacterIterator.Attribute[] attributes) { + if (ApplicationManager.getApplication().isDispatchThread()) return myDelegate.getSelectedText(attributes); + + final AttributedCharacterIterator[] r = new AttributedCharacterIterator[1]; + try { + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + r[0] = myDelegate.getSelectedText(attributes); + } + }); + } + catch (InterruptedException e) { + LOG.error(e); + } + catch (InvocationTargetException e) { + LOG.error(e); + } + return r[0]; + } + } + + private class MyInputMethodHandler implements InputMethodRequests { + private String composedText; + private int composedTextStart; + private int composedTextEnd; + + public Rectangle getTextLocation(TextHitInfo offset) { + Point caret = logicalPositionToXY(getCaretModel().getLogicalPosition()); + Rectangle r = new Rectangle(caret, new Dimension(1, getLineHeight())); + Point p = getContentComponent().getLocationOnScreen(); + r.translate(p.x, p.y); + + return r; + } + + public TextHitInfo getLocationOffset(int x, int y) { + if (composedText != null) { + Point p = getContentComponent().getLocationOnScreen(); + p.x = x - p.x; + p.y = y - p.y; + int pos = logicalPositionToOffset(xyToLogicalPosition(p)); + if (pos >= composedTextStart && pos <= composedTextEnd) { + return TextHitInfo.leading(pos - composedTextStart); + } + } + return null; + } + + public int getInsertPositionOffset() { + int composedStartIndex = 0; + int composedEndIndex = 0; + if (composedText != null) { + composedStartIndex = composedTextStart; + composedEndIndex = composedTextEnd; + } + + int caretIndex = getCaretModel().getOffset(); + + if (caretIndex < composedStartIndex) { + return caretIndex; + } + else { + if (caretIndex < composedEndIndex) { + return composedStartIndex; + } + else { + return caretIndex - (composedEndIndex - composedStartIndex); + } + } + } + + private String getText(int startIdx, int endIdx) { + CharSequence chars = getDocument().getCharsSequence(); + return chars.subSequence(startIdx, endIdx).toString(); + } + + public AttributedCharacterIterator getCommittedText(int beginIndex, int endIndex, + AttributedCharacterIterator.Attribute[] attributes) { + int composedStartIndex = 0; + int composedEndIndex = 0; + if (composedText != null) { + composedStartIndex = composedTextStart; + composedEndIndex = composedTextEnd; + } + + String committed; + if (beginIndex < composedStartIndex) { + if (endIndex <= composedStartIndex) { + committed = getText(beginIndex, endIndex - beginIndex); + } + else { + int firstPartLength = composedStartIndex - beginIndex; + committed = getText(beginIndex, firstPartLength) + + getText(composedEndIndex, endIndex - beginIndex - firstPartLength); + } + } + else { + committed = getText(beginIndex + (composedEndIndex - composedStartIndex), + endIndex - beginIndex); + } + + return new AttributedString(committed).getIterator(); + } + + public int getCommittedTextLength() { + int length = getDocument().getTextLength(); + if (composedText != null) { + length -= composedText.length(); + } + return length; + } + + public AttributedCharacterIterator cancelLatestCommittedText(AttributedCharacterIterator.Attribute[] attributes) { + return null; + } + + public AttributedCharacterIterator getSelectedText(AttributedCharacterIterator.Attribute[] attributes) { + String text = getSelectionModel().getSelectedText(); + return text == null ? null : new AttributedString(text).getIterator(); + } + + private void createComposedString(int composedIndex, AttributedCharacterIterator text) { + StringBuffer strBuf = new StringBuffer(); + + // create attributed string with no attributes + for (char c = text.setIndex(composedIndex); + c != CharacterIterator.DONE; c = text.next()) { + strBuf.append(c); + } + + composedText = new String(strBuf); + } + + private void setInputMethodCaretPosition(InputMethodEvent e) { + if (composedText != null) { + int dot; + dot = composedTextStart; + + TextHitInfo caretPos = e.getCaret(); + if (caretPos != null) { + int index = caretPos.getInsertionIndex(); + dot += index; + } + + getCaretModel().moveToOffset(dot); + getScrollingModel().scrollToCaret(ScrollType.RELATIVE); + } + } + + private void runUndoTransparent(final Runnable runnable) { + CommandProcessor.getInstance().runUndoTransparentAction(new Runnable() { + public void run() { + CommandProcessor.getInstance().executeCommand(myProject, new Runnable() { + public void run() { + ApplicationManager.getApplication().runWriteAction(runnable); + } + }, "", null); + } + }); + } + + private void replaceInputMethodText(InputMethodEvent e) { + int commitCount = e.getCommittedCharacterCount(); + AttributedCharacterIterator text = e.getText(); + int composedTextIndex; + + // old composed text deletion + final Document doc = getDocument(); + + if (composedText != null) { + if (!isViewer() && doc.isWritable()) { + runUndoTransparent(new Runnable() { + public void run() { + doc.deleteString(Math.max(0, composedTextStart), Math.min(composedTextEnd, doc.getTextLength())); + } + }); + } + composedText = null; + } + + if (text != null) { + text.first(); + + // committed text insertion + if (commitCount > 0) { + for (char c = text.current(); commitCount > 0; c = text.next(), commitCount--) { + if (c >= 0x20 && c != 0x7F) { // Hack just like in javax.swing.text.DefaultEditorKit.DefaultKeyTypedAction + processKeyTyped(c); + } + } + } + + // new composed text insertion + if (!isViewer() && doc.isWritable()) { + composedTextIndex = text.getIndex(); + if (composedTextIndex < text.getEndIndex()) { + createComposedString(composedTextIndex, text); + + runUndoTransparent(new Runnable() { + public void run() { + EditorModificationUtil.insertStringAtCaret(EditorImpl.this, composedText, false, false); + } + }); + + composedTextStart = getCaretModel().getOffset(); + composedTextEnd = getCaretModel().getOffset() + composedText.length(); + } + } + } + } + } + + private class MyMouseAdapter extends MouseAdapter { + public void mousePressed(MouseEvent e) { + runMousePressedCommand(e); + } + + public void mouseReleased(MouseEvent e) { + runMouseReleasedCommand(e); + if (!e.isConsumed() && myMousePressedEvent != null && !myMousePressedEvent.isConsumed() && + Math.abs(e.getX() - myMousePressedEvent.getX()) < getSpaceWidth(Font.PLAIN) && + Math.abs(e.getY() - myMousePressedEvent.getY()) < getLineHeight()) { + runMouseClickedCommand(e); + } + myMousePressedEvent = null; + } + + public void mouseEntered(MouseEvent e) { + runMouseEnteredCommand(e); + } + + public void mouseExited(MouseEvent e) { + runMouseExitedCommand(e); + EditorMouseEvent event = new EditorMouseEvent(EditorImpl.this, e, getMouseEventArea(e)); + if (event.getArea() == EditorMouseEventArea.LINE_MARKERS_AREA) { + myGutterComponent.mouseExited(e); + } + + HintManager.getInstance().getTooltipController().cancelTooltip(FOLDING_TOOLTIP_GROUP); + } + } + + private static final TooltipGroup FOLDING_TOOLTIP_GROUP = new TooltipGroup("FOLDING_TOOLTIP_GROUP", 10); + + private class MyMouseMotionListener implements MouseMotionListener { + public void mouseDragged(MouseEvent e) { + validateMousePointer(e); + runMouseDraggedCommand(e); + EditorMouseEvent event = new EditorMouseEvent(EditorImpl.this, e, getMouseEventArea(e)); + if (event.getArea() == EditorMouseEventArea.LINE_MARKERS_AREA) { + myGutterComponent.mouseDragged(e); + } + + EditorMouseMotionListener[] listeners = myMouseMotionListeners.toArray( + new EditorMouseMotionListener[myMouseMotionListeners.size()]); + for (int i = 0; i < listeners.length; i++) { + listeners[i].mouseDragged(event); + } + } + + public void mouseMoved(MouseEvent e) { + validateMousePointer(e); + EditorMouseEvent event = new EditorMouseEvent(EditorImpl.this, e, getMouseEventArea(e)); + if (e.getSource() == myGutterComponent) { + myGutterComponent.mouseMoved(e); + } + + if (event.getArea() == EditorMouseEventArea.EDITING_AREA) { + FoldRegion fold = myFoldingModel.getFoldingPlaceholderAt(e.getPoint()); + TooltipController controller = HintManager.getInstance().getTooltipController(); + if (fold != null) { + DocumentFragment range = new DocumentFragment(myDocument, fold.getStartOffset(), fold.getEndOffset()); + final Point p = SwingUtilities.convertPoint((Component)e.getSource(), + e.getPoint(), + getComponent().getRootPane().getLayeredPane()); + controller.showTooltip(EditorImpl.this, p, range, false, FOLDING_TOOLTIP_GROUP); + } + else { + controller.cancelTooltip(FOLDING_TOOLTIP_GROUP); + } + } + + EditorMouseMotionListener[] listeners = myMouseMotionListeners.toArray( + new EditorMouseMotionListener[myMouseMotionListeners.size()]); + for (int i = 0; i < listeners.length; i++) { + listeners[i].mouseMoved(event); + } + } + } + + private class MyColorSchemeDelegate implements EditorColorsScheme { + private HashMap myOwnAttributes = new HashMap(); + private HashMap myOwnColors = new HashMap(); + private HashMap myFontsMap = null; + private Integer myFontSize = null; + private String myFaceName = null; + + + private EditorColorsScheme getGlobal() { + return EditorColorsManager.getInstance().getGlobalScheme(); + } + + public String getName() { + return getGlobal().getName(); + } + + protected void initFonts() { + String editorFontName = getEditorFontName(); + int editorFontSize = getEditorFontSize(); + + myFontsMap = new HashMap(); + + Font plainFont = new Font(editorFontName, Font.PLAIN, editorFontSize); + Font boldFont = new Font(editorFontName, Font.BOLD, editorFontSize); + Font italicFont = new Font(editorFontName, Font.ITALIC, editorFontSize); + Font boldItalicFont = new Font(editorFontName, Font.BOLD + Font.ITALIC, editorFontSize); + + myFontsMap.put(EditorFontType.PLAIN, plainFont); + myFontsMap.put(EditorFontType.BOLD, boldFont); + myFontsMap.put(EditorFontType.ITALIC, italicFont); + myFontsMap.put(EditorFontType.BOLD_ITALIC, boldItalicFont); + + reinitSettings(); + } + + public void setName(String name) { + getGlobal().setName(name); + } + + public TextAttributes getAttributes(TextAttributesKey key) { + if (myOwnAttributes.containsKey(key)) return myOwnAttributes.get(key); + return getGlobal().getAttributes(key); + } + + public void setAttributes(TextAttributesKey key, TextAttributes attributes) { + myOwnAttributes.put(key, attributes); + } + + public Color getColor(ColorKey key) { + if (myOwnColors.containsKey(key)) return myOwnColors.get(key); + return getGlobal().getColor(key); + } + + public void setColor(ColorKey key, Color color) { + myOwnColors.put(key, color); + + // These two are here because those attributes are cached and I do not whant the clients to call editor's reinit + // settings in this case. + myCaretModel.reinitSettings(); + mySelectionModel.reinitSettings(); + } + + public int getEditorFontSize() { + if (myFontSize != null) return myFontSize.intValue(); + return getGlobal().getEditorFontSize(); + } + + public void setEditorFontSize(int fontSize) { + if (fontSize < 8) fontSize = 8; + if (fontSize > 20) fontSize = 20; + myFontSize = new Integer(fontSize); + initFonts(); + } + + public String getEditorFontName() { + if (myFaceName != null) return myFaceName; + return getGlobal().getEditorFontName(); + } + + public void setEditorFontName(String fontName) { + myFaceName = fontName; + initFonts(); + } + + public Font getFont(EditorFontType key) { + if (myFontsMap != null) { + Font font = myFontsMap.get(key); + if (font != null) return font; + } + return getGlobal().getFont(key); + } + + public void setFont(EditorFontType key, Font font) { + if (myFontsMap == null) { + initFonts(); + } + myFontsMap.put(key, font); + reinitSettings(); + } + + public float getLineSpacing() { + return getGlobal().getLineSpacing(); + } + + public void setLineSpacing(float lineSpacing) { + getGlobal().setLineSpacing(lineSpacing); + } + + public Object clone() { + return null; + } + + public void readExternal(Element element) throws InvalidDataException { + } + + public void writeExternal(Element element) throws WriteExternalException { + } + } + + private static class MyTransferHandler extends TransferHandler { + private RangeMarker myDraggedRange = null; + + private static Editor getEditor(JComponent comp) { + EditorComponentImpl editorComponent = (EditorComponentImpl)comp; + return editorComponent.getEditor(); + } + + public boolean importData(final JComponent comp, final Transferable t) { + final EditorImpl editor = (EditorImpl)getEditor(comp); + + final int caretOffset = editor.getCaretModel().getOffset(); + if (myDraggedRange != null && + myDraggedRange.getStartOffset() <= caretOffset && + caretOffset < myDraggedRange.getEndOffset()) { + return false; + } + + if (myDraggedRange != null) { + editor.getCaretModel().moveToOffset(editor.mySavedCaretOffsetForDNDUndoHack); + } + + CommandProcessor.getInstance().executeCommand(editor.myProject, new Runnable() { + public void run() { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + try { + final int offset; + editor.getSelectionModel().removeSelection(); + if (myDraggedRange != null) { + editor.getCaretModel().moveToOffset(caretOffset); + offset = caretOffset; + } + else { + offset = editor.getCaretModel().getOffset(); + } + if (editor.getDocument().getRangeGuard(offset, offset) != null) return; + + EditorActionHandler pasteHandler = EditorActionManager.getInstance().getActionHandler( + IdeActions.ACTION_EDITOR_PASTE); + Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); + Transferable backup = clipboard.getContents(this); + ClipboardOwner clipboardOwner = new ClipboardOwner() { + public void lostOwnership(Clipboard clipboard, Transferable contents) { + } + }; + clipboard.setContents(t, clipboardOwner); + + editor.putUserData(LAST_PASTED_REGION, null); + pasteHandler.execute(editor, editor.getDataContext()); + clipboard.setContents(backup, clipboardOwner); + + TextRange range = editor.getUserData(LAST_PASTED_REGION); + if (range != null) { + editor.getCaretModel().moveToOffset(range.getStartOffset()); + editor.getSelectionModel().setSelection(range.getStartOffset(), range.getEndOffset()); + } + } + catch (Exception exception) { + LOG.error(exception); + } + } + }); + } + }, "Paste", DND_COMMAND_KEY); + + return true; + } + + public boolean canImport(JComponent comp, DataFlavor[] transferFlavors) { + Editor editor = getEditor(comp); + if (editor.isViewer()) return false; + if (!editor.getDocument().isWritable()) return false; + + int offset = editor.getCaretModel().getOffset(); + if (editor.getDocument().getRangeGuard(offset, offset) != null) return false; + + for (int i = 0; i < transferFlavors.length; i++) { + DataFlavor transferFlavor = transferFlavors[i]; + if (transferFlavor.equals(DataFlavor.stringFlavor)) return true; + } + + return false; + } + + protected Transferable createTransferable(JComponent c) { + Editor editor = getEditor(c); + String s = editor.getSelectionModel().getSelectedText(); + if (s == null) return null; + int selectionStart = editor.getSelectionModel().getSelectionStart(); + int selectionEnd = editor.getSelectionModel().getSelectionEnd(); + myDraggedRange = editor.getDocument().createRangeMarker(selectionStart, selectionEnd); + + return new StringSelection(s); + } + + public int getSourceActions(JComponent c) { + return COPY_OR_MOVE; + } + + protected void exportDone(final JComponent source, Transferable data, int action) { + if (data == null) return; + + if (action == MOVE && !getEditor(source).isViewer() && getEditor(source).getDocument().isWritable()) { + CommandProcessor.getInstance().executeCommand(((EditorImpl)getEditor(source)).myProject, new Runnable() { + public void run() { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + Document doc = getEditor(source).getDocument(); + doc.startGuardedBlockChecking(); + try { + doc.deleteString(myDraggedRange.getStartOffset(), myDraggedRange.getEndOffset()); + } + catch (ReadOnlyFragmentModificationException e) { + EditorActionManager.getInstance().getReadonlyFragmentModificationHandler().handle(e); + } + finally { + doc.stopGuardedBlockChecking(); + } + } + }); + } + }, "Move selection", DND_COMMAND_KEY); + } + + myDraggedRange = null; + } + } + + class EditorDocumentAdapter extends DocumentAdapter { + public void beforeDocumentChange(DocumentEvent e) { + beforeChangedUpdate(e); + } + + public void documentChanged(DocumentEvent e) { + changedUpdate(e); + } + } + + private class EditorSizeContainer { + private TIntArrayList myLineWidths; + private boolean myIsDirty; + private int myOldEndLine; + private Dimension mySize; + + public void reset() { + int visLinesCount = getVisibleLineCount(); + myLineWidths = new TIntArrayList(visLinesCount + 300); + int[] values = new int[visLinesCount]; + Arrays.fill(values, -1); + myLineWidths.add(values); + myIsDirty = true; + } + + public void beforeChange(DocumentEvent e) { + myOldEndLine = offsetToVisualPosition(e.getOffset() + e.getOldLength()).line; + } + + public void changedUpdate(DocumentEvent e) { + int startLine = offsetToVisualPosition(e.getOffset()).line; + int newEndLine = offsetToVisualPosition(e.getOffset() + e.getNewLength()).line; + int oldEndLine = myOldEndLine; + + if (myLineWidths.size() == 0) { + reset(); + } + else { + int min = Math.min(oldEndLine, newEndLine); + for (int i = startLine; i <= min; i++) myLineWidths.set(i, -1); + if (newEndLine > oldEndLine) { + int[] delta = new int[newEndLine - oldEndLine]; + Arrays.fill(delta, -1); + myLineWidths.insert(oldEndLine + 1, delta); + } + else if (oldEndLine > newEndLine) { + myLineWidths.remove(newEndLine + 1, oldEndLine - newEndLine); + } + myIsDirty = true; + } + } + + private void validateSizes() { + if (!myIsDirty) return; + + CharSequence text = myDocument.getCharsNoThreadCheck(); + int lineCount = myLineWidths.size(); + int end = myDocument.getTextLength(); + int x = 0; + for (int line = 0; line < lineCount; line++) { + if (myLineWidths.getQuick(line) != -1) continue; + x = 0; + int offset = logicalPositionToOffset(visualToLogicalPosition(new VisualPosition(line, 0))); + + if (offset >= myDocument.getTextLength()) { + myLineWidths.set(line, 0); + break; + } + + IterationState state = new IterationState(EditorImpl.this, offset, false); + int fontType = state.getMergedAttributes().getFontType(); + + while (offset < end) { + char c = text.charAt(offset); + if (offset >= state.getEndOffset()) { + state.advance(); + fontType = state.getMergedAttributes().getFontType(); + } + + FoldRegion collapsed = state.getCurrentFold(); + if (collapsed != null) { + String placeholder = collapsed.getPlaceholderText(); + for (int i = 0; i < placeholder.length(); i++) { + x += charWidth(fontType, placeholder.charAt(i)); + } + offset = collapsed.getEndOffset(); + } + else { + if (c == '\t') { + x = nextTabStop(x); + offset++; + } + else { + if (c == '\n') { + myLineWidths.set(line, x); + if (line + 1 >= lineCount || myLineWidths.getQuick(line + 1) != -1) break; + offset++; + x = 0; + line++; + } + else { + x += charWidth(fontType, c); + offset++; + } + } + } + } + } + + if (lineCount > 0) { + myLineWidths.set(lineCount - 1, x); // Last line can be non-zero length and won't be caught by in-loop procedure since latter only react on \n's + } + + int maxWidth = 0; + for (int i = 0; i < lineCount; i++) { + maxWidth = Math.max(maxWidth, myLineWidths.getQuick(i)); + } + + mySize = new Dimension(maxWidth, getLineHeight() * lineCount); + + myIsDirty = false; + } + + public Dimension getContentSize() { + validateSizes(); + return mySize; + } + } + + public EditorGutter getGutter() { + return getGutterComponentEx(); + } +} diff --git a/java/java-tests/testData/psi/formatter/java/performance2.java b/java/java-tests/testData/psi/formatter/java/performance2.java new file mode 100644 index 000000000000..dc827646a6fb --- /dev/null +++ b/java/java-tests/testData/psi/formatter/java/performance2.java @@ -0,0 +1,7 @@ +package scrap; + +/** + */ +public interface A1024 { + byte[] a = {123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, }; +} diff --git a/java/java-tests/testData/psi/formatter/java/performance2_after.java b/java/java-tests/testData/psi/formatter/java/performance2_after.java new file mode 100644 index 000000000000..9f416302572e --- /dev/null +++ b/java/java-tests/testData/psi/formatter/java/performance2_after.java @@ -0,0 +1,7 @@ +package scrap; + +/** + */ +public interface A1024 { + byte[] a = {123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,}; +} diff --git a/java/java-tests/testData/psi/formatter/java/performance3.java b/java/java-tests/testData/psi/formatter/java/performance3.java new file mode 100644 index 000000000000..93aa7e61b628 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/java/performance3.java @@ -0,0 +1,130 @@ +package scrap; + +/** + */ +public interface A1024 { + private static final BusinessClass[] pool_DUMMY79 = + { + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + new BusinessClass("Description_1", new MortalityTable.PersonalDetails(MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY(1, 10, 1950), false, 0.85), 2200000, new Bday100Roll(calCalc.getTimeFromMDY(6, 16, 1926))), + + }; +} diff --git a/java/java-tests/testData/psi/formatter/java/performance3_after.java b/java/java-tests/testData/psi/formatter/java/performance3_after.java new file mode 100644 index 000000000000..dddc6c9fb787 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/java/performance3_after.java @@ -0,0 +1,130 @@ +package scrap; + +/** + */ +public interface A1024 { + private static final BusinessClass[] pool_DUMMY79 = + { + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + new BusinessClass ("Description_1", new MortalityTable.PersonalDetails (MortalityTable.Gender.FEMALE, calCalc.getTimeFromMDY (1, 10, 1950), false, 0.85), 2200000, new Bday100Roll (calCalc.getTimeFromMDY (6, 16, 1926))), + + }; +} diff --git a/java/java-tests/testData/psi/formatter/tabIndenting/SCR6197.java b/java/java-tests/testData/psi/formatter/tabIndenting/SCR6197.java new file mode 100644 index 000000000000..1ea4e6cc2a08 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/tabIndenting/SCR6197.java @@ -0,0 +1,4 @@ +class Test{ + /* + */ +} diff --git a/java/java-tests/testData/psi/formatter/tabIndenting/SCR6197_after.java b/java/java-tests/testData/psi/formatter/tabIndenting/SCR6197_after.java new file mode 100644 index 000000000000..3e3145fc4fb8 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/tabIndenting/SCR6197_after.java @@ -0,0 +1,5 @@ + +class Test { + /* + */ +} diff --git a/java/java-tests/testData/psi/formatter/tabIndenting/SmartTab2_after.java b/java/java-tests/testData/psi/formatter/tabIndenting/SmartTab2_after.java new file mode 100644 index 000000000000..6781288e4d1f --- /dev/null +++ b/java/java-tests/testData/psi/formatter/tabIndenting/SmartTab2_after.java @@ -0,0 +1,9 @@ + +class A { + int a; + + void foo(int a, + int b) { + boolean b; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/tabIndenting/SmartTab4_after.java b/java/java-tests/testData/psi/formatter/tabIndenting/SmartTab4_after.java new file mode 100644 index 000000000000..db9e44b919a9 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/tabIndenting/SmartTab4_after.java @@ -0,0 +1,9 @@ + +class A { + int a; + + void foo(int a, + int b) { + boolean b; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/tabIndenting/SmartTab8_after.java b/java/java-tests/testData/psi/formatter/tabIndenting/SmartTab8_after.java new file mode 100644 index 000000000000..6038386b1ee8 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/tabIndenting/SmartTab8_after.java @@ -0,0 +1,9 @@ + +class A { + int a; + + void foo(int a, + int b) { + boolean b; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/tabIndenting/Space_after.java b/java/java-tests/testData/psi/formatter/tabIndenting/Space_after.java new file mode 100644 index 000000000000..e18b7b938b71 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/tabIndenting/Space_after.java @@ -0,0 +1,9 @@ + +class A { + int a; + + void foo(int a, + int b) { + boolean b; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/tabIndenting/Tab2_after.java b/java/java-tests/testData/psi/formatter/tabIndenting/Tab2_after.java new file mode 100644 index 000000000000..00625a78f22f --- /dev/null +++ b/java/java-tests/testData/psi/formatter/tabIndenting/Tab2_after.java @@ -0,0 +1,9 @@ + +class A { + int a; + + void foo(int a, + int b) { + boolean b; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/tabIndenting/Tab4_after.java b/java/java-tests/testData/psi/formatter/tabIndenting/Tab4_after.java new file mode 100644 index 000000000000..4a32cfe1970e --- /dev/null +++ b/java/java-tests/testData/psi/formatter/tabIndenting/Tab4_after.java @@ -0,0 +1,9 @@ + +class A { + int a; + + void foo(int a, + int b) { + boolean b; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/tabIndenting/Tab8_after.java b/java/java-tests/testData/psi/formatter/tabIndenting/Tab8_after.java new file mode 100644 index 000000000000..65886fc9a836 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/tabIndenting/Tab8_after.java @@ -0,0 +1,9 @@ + +class A { + int a; + + void foo(int a, + int b) { + boolean b; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/tabIndenting/Test.java b/java/java-tests/testData/psi/formatter/tabIndenting/Test.java new file mode 100644 index 000000000000..26ab4d4db855 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/tabIndenting/Test.java @@ -0,0 +1,8 @@ +class A{ + int a; + + void foo(int a, + int b){ + boolean b; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/wrapping/BinaryOperation.java b/java/java-tests/testData/psi/formatter/wrapping/BinaryOperation.java new file mode 100644 index 000000000000..147ff9aacf80 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/wrapping/BinaryOperation.java @@ -0,0 +1,6 @@ + +public class Foo { + { + x = a + b + c + d * e; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/wrapping/BinaryOperation_chopped.java b/java/java-tests/testData/psi/formatter/wrapping/BinaryOperation_chopped.java new file mode 100644 index 000000000000..95eeabf5e2b1 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/wrapping/BinaryOperation_chopped.java @@ -0,0 +1,9 @@ + +public class Foo { + { + x = a + + b + + c + + d * e; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/wrapping/BinaryOperation_chopped_signmoved.java b/java/java-tests/testData/psi/formatter/wrapping/BinaryOperation_chopped_signmoved.java new file mode 100644 index 000000000000..52dabf81f39b --- /dev/null +++ b/java/java-tests/testData/psi/formatter/wrapping/BinaryOperation_chopped_signmoved.java @@ -0,0 +1,9 @@ + +public class Foo { + { + x = a + + b + + c + + d * e; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/wrapping/BinaryOperation_normal.java b/java/java-tests/testData/psi/formatter/wrapping/BinaryOperation_normal.java new file mode 100644 index 000000000000..7174275f2e1c --- /dev/null +++ b/java/java-tests/testData/psi/formatter/wrapping/BinaryOperation_normal.java @@ -0,0 +1,7 @@ + +public class Foo { + { + x = a + b + c + + d * e; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/wrapping/CallNoParameteresList.java b/java/java-tests/testData/psi/formatter/wrapping/CallNoParameteresList.java new file mode 100644 index 000000000000..b4b3e51ce3dd --- /dev/null +++ b/java/java-tests/testData/psi/formatter/wrapping/CallNoParameteresList.java @@ -0,0 +1,6 @@ + +public class Test { + public void foo() { + hereIsSomeLongNameMethodCalledWhenNoParams(); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/wrapping/CallNoParameteresList_after.java b/java/java-tests/testData/psi/formatter/wrapping/CallNoParameteresList_after.java new file mode 100644 index 000000000000..b4b3e51ce3dd --- /dev/null +++ b/java/java-tests/testData/psi/formatter/wrapping/CallNoParameteresList_after.java @@ -0,0 +1,6 @@ + +public class Test { + public void foo() { + hereIsSomeLongNameMethodCalledWhenNoParams(); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/wrapping/CallParameterList.java b/java/java-tests/testData/psi/formatter/wrapping/CallParameterList.java new file mode 100644 index 000000000000..f6f1c836a40d --- /dev/null +++ b/java/java-tests/testData/psi/formatter/wrapping/CallParameterList.java @@ -0,0 +1,6 @@ + +public class Foo { + public static void foo() { + bar(bar(1, 2, 3), bar(3, 4, 5), bar(6, 7, 8)); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/wrapping/CallParameterList_chopped.java b/java/java-tests/testData/psi/formatter/wrapping/CallParameterList_chopped.java new file mode 100644 index 000000000000..0a46f85e40cb --- /dev/null +++ b/java/java-tests/testData/psi/formatter/wrapping/CallParameterList_chopped.java @@ -0,0 +1,8 @@ + +public class Foo { + public static void foo() { + bar(bar(1, 2, 3), + bar(3, 4, 5), + bar(6, 7, 8)); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/wrapping/CallParameterList_chopped_bothparenmoved.java b/java/java-tests/testData/psi/formatter/wrapping/CallParameterList_chopped_bothparenmoved.java new file mode 100644 index 000000000000..64659655fd0f --- /dev/null +++ b/java/java-tests/testData/psi/formatter/wrapping/CallParameterList_chopped_bothparenmoved.java @@ -0,0 +1,10 @@ + +public class Foo { + public static void foo() { + bar( + bar(1, 2, 3), + bar(3, 4, 5), + bar(6, 7, 8) + ); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/wrapping/CallParameterList_chopped_parenmoved.java b/java/java-tests/testData/psi/formatter/wrapping/CallParameterList_chopped_parenmoved.java new file mode 100644 index 000000000000..9a6705ecf4c0 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/wrapping/CallParameterList_chopped_parenmoved.java @@ -0,0 +1,9 @@ + +public class Foo { + public static void foo() { + bar(bar(1, 2, 3), + bar(3, 4, 5), + bar(6, 7, 8) + ); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/wrapping/CallParameterList_normal.java b/java/java-tests/testData/psi/formatter/wrapping/CallParameterList_normal.java new file mode 100644 index 000000000000..25b33151ae85 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/wrapping/CallParameterList_normal.java @@ -0,0 +1,7 @@ + +public class Foo { + public static void foo() { + bar(bar(1, 2, 3), bar(3, 4, 5), + bar(6, 7, 8)); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/wrapping/ChainedCallsAndParams.java b/java/java-tests/testData/psi/formatter/wrapping/ChainedCallsAndParams.java new file mode 100644 index 000000000000..383cca45f7e3 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/wrapping/ChainedCallsAndParams.java @@ -0,0 +1,14 @@ + +public class Test_ASPECT { + public static final com.intellij.aspects.rt.pointcut.Pointcut test1_POINTCUT = + new com.intellij.aspects.rt.pointcut.MethodCallPointcut( + new com.intellij.aspects.rt.pattern.BasicMethodPattern( + null, + new com.intellij.aspects.rt.pattern.ExactTypePattern("V"), + new com.intellij.aspects.rt.pattern.ExactTypePattern(new org.apache.bcel.generic.ObjectType(Point.class.getName())), + new com.intellij.aspects.rt.pattern.RegexpIdentifierPattern("setX"), + new com.intellij.aspects.rt.pattern.BasicTypeListPattern( + ) + ) + ); +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/wrapping/ChainedCallsAndParams_normal.java b/java/java-tests/testData/psi/formatter/wrapping/ChainedCallsAndParams_normal.java new file mode 100644 index 000000000000..36b18b7e0308 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/wrapping/ChainedCallsAndParams_normal.java @@ -0,0 +1,14 @@ +public class Test_ASPECT { + public static final com.intellij.aspects.rt.pointcut.Pointcut test1_POINTCUT = + new com.intellij.aspects.rt.pointcut.MethodCallPointcut( + new com.intellij.aspects.rt.pattern.BasicMethodPattern( + null, + new com.intellij.aspects.rt.pattern.ExactTypePattern("V"), + new com.intellij.aspects.rt.pattern.ExactTypePattern(new org.apache.bcel.generic.ObjectType( + Point.class.getName())), + new com.intellij.aspects.rt.pattern.RegexpIdentifierPattern("setX"), + new com.intellij.aspects.rt.pattern.BasicTypeListPattern( + ) + ) + ); +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/wrapping/ChainedMethodCall.java b/java/java-tests/testData/psi/formatter/wrapping/ChainedMethodCall.java new file mode 100644 index 000000000000..ef63d5f4b74d --- /dev/null +++ b/java/java-tests/testData/psi/formatter/wrapping/ChainedMethodCall.java @@ -0,0 +1,6 @@ + +public class Foo { + public static Foo foo(int i1, int i2, int i3) { + Foo.foo(1, 2, 3).foo(4, 5, 6).foo(7, 8, 9).foo(x, y, z); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/wrapping/ChainedMethodCall_chopped.java b/java/java-tests/testData/psi/formatter/wrapping/ChainedMethodCall_chopped.java new file mode 100644 index 000000000000..bdd13bc7332a --- /dev/null +++ b/java/java-tests/testData/psi/formatter/wrapping/ChainedMethodCall_chopped.java @@ -0,0 +1,9 @@ + +public class Foo { + public static Foo foo(int i1, int i2, int i3) { + Foo.foo(1, 2, 3) + .foo(4, 5, 6) + .foo(7, 8, 9) + .foo(x, y, z); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/wrapping/ChainedMethodCall_normal.java b/java/java-tests/testData/psi/formatter/wrapping/ChainedMethodCall_normal.java new file mode 100644 index 000000000000..b950d967485c --- /dev/null +++ b/java/java-tests/testData/psi/formatter/wrapping/ChainedMethodCall_normal.java @@ -0,0 +1,7 @@ + +public class Foo { + public static Foo foo(int i1, int i2, int i3) { + Foo.foo(1, 2, 3).foo(4, 5, 6).foo(7, 8, 9) + .foo(x, y, z); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/wrapping/ExtendsListWrapping.java b/java/java-tests/testData/psi/formatter/wrapping/ExtendsListWrapping.java new file mode 100644 index 000000000000..649f1a1748ea --- /dev/null +++ b/java/java-tests/testData/psi/formatter/wrapping/ExtendsListWrapping.java @@ -0,0 +1,3 @@ + +public interface Foo extends Bar1, Bar2 , Bar3 ,Bar5 { +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/wrapping/ExtendsListWrapping_chopped.java b/java/java-tests/testData/psi/formatter/wrapping/ExtendsListWrapping_chopped.java new file mode 100644 index 000000000000..ab53d2d13f9e --- /dev/null +++ b/java/java-tests/testData/psi/formatter/wrapping/ExtendsListWrapping_chopped.java @@ -0,0 +1,6 @@ + +public interface Foo extends Bar1, + Bar2, + Bar3, + Bar5 { +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/wrapping/ExtendsListWrapping_normal.java b/java/java-tests/testData/psi/formatter/wrapping/ExtendsListWrapping_normal.java new file mode 100644 index 000000000000..ef08dbb5a2fc --- /dev/null +++ b/java/java-tests/testData/psi/formatter/wrapping/ExtendsListWrapping_normal.java @@ -0,0 +1,4 @@ + +public interface Foo extends Bar1, Bar2, + Bar3, Bar5 { +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/wrapping/ExtendsWrappingForced.java b/java/java-tests/testData/psi/formatter/wrapping/ExtendsWrappingForced.java new file mode 100644 index 000000000000..dbe5806a2c9c --- /dev/null +++ b/java/java-tests/testData/psi/formatter/wrapping/ExtendsWrappingForced.java @@ -0,0 +1,3 @@ + +public class Foo extends Bar { +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/wrapping/ExtendsWrappingForced_after.java b/java/java-tests/testData/psi/formatter/wrapping/ExtendsWrappingForced_after.java new file mode 100644 index 000000000000..ca08c3dcce06 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/wrapping/ExtendsWrappingForced_after.java @@ -0,0 +1,4 @@ + +public class Foo + extends Bar { +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/wrapping/ForStatement.java b/java/java-tests/testData/psi/formatter/wrapping/ForStatement.java new file mode 100644 index 000000000000..eff470230f4e --- /dev/null +++ b/java/java-tests/testData/psi/formatter/wrapping/ForStatement.java @@ -0,0 +1,10 @@ + +public class Foo { + public void foo() { + for(int i = 0; i < 10; i++) { + } + + for(int thisShouldBeWrapped = 0; thisShouldBeWrapped < 10; thisShouldBeWrapped++) { + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/wrapping/ForStatement_both.java b/java/java-tests/testData/psi/formatter/wrapping/ForStatement_both.java new file mode 100644 index 000000000000..6c9793e9aae6 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/wrapping/ForStatement_both.java @@ -0,0 +1,14 @@ + +public class Foo { + public void foo() { + for (int i = 0; i < 10; i++) { + } + + for ( + int thisShouldBeWrapped = 0; + thisShouldBeWrapped < 10; + thisShouldBeWrapped++ + ) { + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/wrapping/ForStatement_lparen.java b/java/java-tests/testData/psi/formatter/wrapping/ForStatement_lparen.java new file mode 100644 index 000000000000..5a974b1ba58d --- /dev/null +++ b/java/java-tests/testData/psi/formatter/wrapping/ForStatement_lparen.java @@ -0,0 +1,13 @@ + +public class Foo { + public void foo() { + for (int i = 0; i < 10; i++) { + } + + for ( + int thisShouldBeWrapped = 0; + thisShouldBeWrapped < 10; + thisShouldBeWrapped++) { + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/wrapping/ForStatement_normal.java b/java/java-tests/testData/psi/formatter/wrapping/ForStatement_normal.java new file mode 100644 index 000000000000..9e8006f0e89a --- /dev/null +++ b/java/java-tests/testData/psi/formatter/wrapping/ForStatement_normal.java @@ -0,0 +1,12 @@ + +public class Foo { + public void foo() { + for (int i = 0; i < 10; i++) { + } + + for (int thisShouldBeWrapped = 0; + thisShouldBeWrapped < 10; + thisShouldBeWrapped++) { + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/wrapping/ForStatement_rparen.java b/java/java-tests/testData/psi/formatter/wrapping/ForStatement_rparen.java new file mode 100644 index 000000000000..4d6cbe21dd28 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/wrapping/ForStatement_rparen.java @@ -0,0 +1,13 @@ + +public class Foo { + public void foo() { + for (int i = 0; i < 10; i++) { + } + + for (int thisShouldBeWrapped = 0; + thisShouldBeWrapped < 10; + thisShouldBeWrapped++ + ) { + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/wrapping/IncompleteFor.java b/java/java-tests/testData/psi/formatter/wrapping/IncompleteFor.java new file mode 100644 index 000000000000..92e459e09116 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/wrapping/IncompleteFor.java @@ -0,0 +1,8 @@ + +public class Foo { + { + for (int i = 0; i < 0;) { + System.out.println("something"); + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/wrapping/IncompleteFor_after.java b/java/java-tests/testData/psi/formatter/wrapping/IncompleteFor_after.java new file mode 100644 index 000000000000..d67a755a1314 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/wrapping/IncompleteFor_after.java @@ -0,0 +1,9 @@ + +public class Foo { + { + for (int i = 0; + i < 0; ) { + System.out.println("something"); + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/wrapping/KillSpacesInEmptyLine.java b/java/java-tests/testData/psi/formatter/wrapping/KillSpacesInEmptyLine.java new file mode 100644 index 000000000000..e7ed9303f75c --- /dev/null +++ b/java/java-tests/testData/psi/formatter/wrapping/KillSpacesInEmptyLine.java @@ -0,0 +1,8 @@ + +public class Foo { + public void foo() { + statement1(); + + statement2(); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/wrapping/KillSpacesInEmptyLine_after.java b/java/java-tests/testData/psi/formatter/wrapping/KillSpacesInEmptyLine_after.java new file mode 100644 index 000000000000..00df09860294 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/wrapping/KillSpacesInEmptyLine_after.java @@ -0,0 +1,8 @@ + +public class Foo { + public void foo() { + statement1(); + + statement2(); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/wrapping/MethodParameterList.java b/java/java-tests/testData/psi/formatter/wrapping/MethodParameterList.java new file mode 100644 index 000000000000..d4acae5ecc26 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/wrapping/MethodParameterList.java @@ -0,0 +1,5 @@ + +public class Foo { + public static void foo(int arg1, int arg2, int arg3) { + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/wrapping/MethodParameterList_chopped.java b/java/java-tests/testData/psi/formatter/wrapping/MethodParameterList_chopped.java new file mode 100644 index 000000000000..ee55dc700f36 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/wrapping/MethodParameterList_chopped.java @@ -0,0 +1,7 @@ + +public class Foo { + public static void foo(int arg1, + int arg2, + int arg3) { + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/wrapping/MethodParameterList_chopped_parenmoved.java b/java/java-tests/testData/psi/formatter/wrapping/MethodParameterList_chopped_parenmoved.java new file mode 100644 index 000000000000..089776a7c48d --- /dev/null +++ b/java/java-tests/testData/psi/formatter/wrapping/MethodParameterList_chopped_parenmoved.java @@ -0,0 +1,8 @@ + +public class Foo { + public static void foo(int arg1, + int arg2, + int arg3 + ) { + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/wrapping/MethodParameterList_normal.java b/java/java-tests/testData/psi/formatter/wrapping/MethodParameterList_normal.java new file mode 100644 index 000000000000..86bd1b41b65d --- /dev/null +++ b/java/java-tests/testData/psi/formatter/wrapping/MethodParameterList_normal.java @@ -0,0 +1,6 @@ + +public class Foo { + public static void foo(int arg1, int arg2, + int arg3) { + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/wrapping/ModifierList.java b/java/java-tests/testData/psi/formatter/wrapping/ModifierList.java new file mode 100644 index 000000000000..6060b2f021bf --- /dev/null +++ b/java/java-tests/testData/psi/formatter/wrapping/ModifierList.java @@ -0,0 +1,5 @@ + +public class Foo { + public static void foo(int i1, int i2) { + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/wrapping/ModifierList_after.java b/java/java-tests/testData/psi/formatter/wrapping/ModifierList_after.java new file mode 100644 index 000000000000..43ca32c9ce95 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/wrapping/ModifierList_after.java @@ -0,0 +1,7 @@ + +public +class Foo { + public static + void foo(int i1, int i2) { + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/wrapping/NestedLongCalls.java b/java/java-tests/testData/psi/formatter/wrapping/NestedLongCalls.java new file mode 100644 index 000000000000..c8fafaabe378 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/wrapping/NestedLongCalls.java @@ -0,0 +1,4 @@ + +public class Foo { + public void foo() { super.foo("Parameter here"); } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/wrapping/NestedLongCalls_after.java b/java/java-tests/testData/psi/formatter/wrapping/NestedLongCalls_after.java new file mode 100644 index 000000000000..fd2474a90c9f --- /dev/null +++ b/java/java-tests/testData/psi/formatter/wrapping/NestedLongCalls_after.java @@ -0,0 +1,6 @@ + +public class Foo { + public void foo() { + super.foo("Parameter here"); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/wrapping/ParenthesizedExpressionWrap.java b/java/java-tests/testData/psi/formatter/wrapping/ParenthesizedExpressionWrap.java new file mode 100644 index 000000000000..9ab8d9e2a3ac --- /dev/null +++ b/java/java-tests/testData/psi/formatter/wrapping/ParenthesizedExpressionWrap.java @@ -0,0 +1,6 @@ + +public class Foo { + { + x = (a.foo(1, 2, 3) + variable2); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/wrapping/ParenthesizedExpressionWrap_both.java b/java/java-tests/testData/psi/formatter/wrapping/ParenthesizedExpressionWrap_both.java new file mode 100644 index 000000000000..eb07e6a505d7 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/wrapping/ParenthesizedExpressionWrap_both.java @@ -0,0 +1,10 @@ + +public class Foo { + { + x = ( + a.foo(1, + 2, + 3) + variable2 + ); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/wrapping/ParenthesizedExpressionWrap_left.java b/java/java-tests/testData/psi/formatter/wrapping/ParenthesizedExpressionWrap_left.java new file mode 100644 index 000000000000..992065fe9bec --- /dev/null +++ b/java/java-tests/testData/psi/formatter/wrapping/ParenthesizedExpressionWrap_left.java @@ -0,0 +1,9 @@ + +public class Foo { + { + x = ( + a.foo(1, + 2, + 3) + variable2); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/wrapping/ParenthesizedExpressionWrap_right.java b/java/java-tests/testData/psi/formatter/wrapping/ParenthesizedExpressionWrap_right.java new file mode 100644 index 000000000000..7468c1f62734 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/wrapping/ParenthesizedExpressionWrap_right.java @@ -0,0 +1,9 @@ + +public class Foo { + { + x = (a.foo(1, + 2, + 3) + variable2 + ); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/wrapping/SCR11423.java b/java/java-tests/testData/psi/formatter/wrapping/SCR11423.java new file mode 100644 index 000000000000..f9f6b0f26a34 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/wrapping/SCR11423.java @@ -0,0 +1,6 @@ + +public class Foo { + public UserGestureResponse execute(UserGesture gesture, + ServletRequest request) throws SystemException { + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/wrapping/SCR11423_after.java b/java/java-tests/testData/psi/formatter/wrapping/SCR11423_after.java new file mode 100644 index 000000000000..da01f7e6be8f --- /dev/null +++ b/java/java-tests/testData/psi/formatter/wrapping/SCR11423_after.java @@ -0,0 +1,7 @@ + +public class Foo { + public UserGestureResponse execute(UserGesture gesture, + ServletRequest request) + throws SystemException { + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/wrapping/SCR27373.java b/java/java-tests/testData/psi/formatter/wrapping/SCR27373.java new file mode 100644 index 000000000000..93183a9a3c62 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/wrapping/SCR27373.java @@ -0,0 +1,5 @@ +class Test { + { + String s = methodWithALongNameAndThreeArgs("aaaaaaaaaaaaaaaaaaaaaa", "bbbbbbbbbbbbbbb", "ccccccccc"); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/wrapping/SCR27373_after.java b/java/java-tests/testData/psi/formatter/wrapping/SCR27373_after.java new file mode 100644 index 000000000000..b9e9d8868721 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/wrapping/SCR27373_after.java @@ -0,0 +1,7 @@ + +class Test { + { + String s = methodWithALongNameAndThreeArgs( + "aaaaaaaaaaaaaaaaaaaaaa", "bbbbbbbbbbbbbbb", "ccccccccc"); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/wrapping/SimpleMethods.java b/java/java-tests/testData/psi/formatter/wrapping/SimpleMethods.java new file mode 100644 index 000000000000..f8fe391702df --- /dev/null +++ b/java/java-tests/testData/psi/formatter/wrapping/SimpleMethods.java @@ -0,0 +1,13 @@ + +public class Foo { + public int foo() { return 5; } + + public int longerMethodFooHere() { return thisCodeBlockShouldBeWrapped; } + + int bar() {st = 2; st = 3;} + + int foobar() { //aaaaaaaaaaaaaa + st = 2; st = 3;} + + int barbar() { } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/wrapping/SimpleMethods_after.java b/java/java-tests/testData/psi/formatter/wrapping/SimpleMethods_after.java new file mode 100644 index 000000000000..276d3aaaf27f --- /dev/null +++ b/java/java-tests/testData/psi/formatter/wrapping/SimpleMethods_after.java @@ -0,0 +1,18 @@ + +public class Foo { + public int foo() { return 5; } + + public int longerMethodFooHere() { return thisCodeBlockShouldBeWrapped; } + + int bar() { + st = 2; + st = 3; + } + + int foobar() { //aaaaaaaaaaaaaa + st = 2; + st = 3; + } + + int barbar() { } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/wrapping/TernaryOperation.java b/java/java-tests/testData/psi/formatter/wrapping/TernaryOperation.java new file mode 100644 index 000000000000..08ff7088a8af --- /dev/null +++ b/java/java-tests/testData/psi/formatter/wrapping/TernaryOperation.java @@ -0,0 +1,6 @@ + +public class Foo { + { + x = a + b + c ? b : d; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/wrapping/TernaryOperation_chopped.java b/java/java-tests/testData/psi/formatter/wrapping/TernaryOperation_chopped.java new file mode 100644 index 000000000000..f58583c75371 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/wrapping/TernaryOperation_chopped.java @@ -0,0 +1,8 @@ + +public class Foo { + { + x = a + b + c ? + b : + d; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/wrapping/TernaryOperation_chopped_signmoved.java b/java/java-tests/testData/psi/formatter/wrapping/TernaryOperation_chopped_signmoved.java new file mode 100644 index 000000000000..36341afac00f --- /dev/null +++ b/java/java-tests/testData/psi/formatter/wrapping/TernaryOperation_chopped_signmoved.java @@ -0,0 +1,8 @@ + +public class Foo { + { + x = a + b + c + ? b + : d; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/wrapping/TernaryOperation_normal.java b/java/java-tests/testData/psi/formatter/wrapping/TernaryOperation_normal.java new file mode 100644 index 000000000000..ac2f622ad729 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/wrapping/TernaryOperation_normal.java @@ -0,0 +1,7 @@ + +public class Foo { + { + x = a + b + c ? b : + d; + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/MultipleJdksHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/MultipleJdksHighlightingTest.java index 8dd77a1f47ad..c814d4ce35f7 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/MultipleJdksHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/MultipleJdksHighlightingTest.java @@ -22,7 +22,6 @@ import com.intellij.openapi.roots.ModifiableRootModel; import com.intellij.openapi.roots.ModuleRootModificationUtil; import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.pom.java.LanguageLevel; -import com.intellij.testFramework.IdeaTestCase; import com.intellij.testFramework.IdeaTestUtil; import com.intellij.testFramework.UsefulTestCase; import com.intellij.testFramework.builders.JavaModuleFixtureBuilder; @@ -165,6 +164,14 @@ public class MultipleJdksHighlightingTest extends UsefulTestCase { doTest3Modules(); } + public void testRawAssignmentToGenerics() throws Exception { + ModuleRootModificationUtil.addDependency(myJava7Module, myJava3Module); + final String name = getTestName(false); + myFixture.copyFileToProject("java3/p/" + name + ".java"); + myFixture.configureByFiles("java7/p/" + name + ".java"); + myFixture.checkHighlighting(); + } + public void testCloseableAutoCloseable() { IdeaTestUtil.setModuleLanguageLevel(myJava7Module, LanguageLevel.JDK_1_7); ModuleRootModificationUtil.addDependency(myJava7Module, myJava3Module); diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GenericsHighlighting8Test.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GenericsHighlighting8Test.java index cb844b1b9142..9f10ace0ccce 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GenericsHighlighting8Test.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GenericsHighlighting8Test.java @@ -869,4 +869,8 @@ public class GenericsHighlighting8Test extends LightDaemonAnalyzerTestCase { public void testIDEA107713() throws Exception { doTest(); } + + public void testExceptionCollectionWithLambda() throws Exception { + doTest(); + } } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/javadoc/JavaDocInfoGeneratorTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/javadoc/JavaDocInfoGeneratorTest.java index 3174a67bc707..694108ce80ab 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/javadoc/JavaDocInfoGeneratorTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/javadoc/JavaDocInfoGeneratorTest.java @@ -252,13 +252,21 @@ public class JavaDocInfoGeneratorTest extends CodeInsightTestCase { } public void testPackageInfoFromComment() throws Exception { + doTestPackageInfo("some"); + } + + public void testPackageInfoWithCopyright() throws Exception { + doTestPackageInfo("packageInfoWithCopyright"); + } + + private void doTestPackageInfo(String caretPositionedAt) throws Exception { final String rootPath = getTestDataPath() + "/codeInsight/javadocIG/"; VirtualFile root = PsiTestUtil.createTestProjectStructure(myProject, myModule, rootPath, myFilesToDelete); - VirtualFile piFile = root.findFileByRelativePath("packageInfoFromComment/package-info.java"); + VirtualFile piFile = root.findFileByRelativePath(getTestName(true) + "/package-info.java"); assertNotNull(piFile); PsiFile psiFile = PsiManager.getInstance(myProject).findFile(piFile); assertNotNull(psiFile); - final String info = JavaExternalDocumentationTest.getDocumentationText(psiFile, psiFile.getText().indexOf("some")); + final String info = JavaExternalDocumentationTest.getDocumentationText(psiFile, psiFile.getText().indexOf(caretPositionedAt)); String htmlText = FileUtil.loadFile(new File(rootPath + getTestName(true) + File.separator + "packageInfo.html")); assertEquals(StringUtil.convertLineSeparators(htmlText.trim()), replaceEnvironmentDependentContent(info)); } diff --git a/java/java-tests/testSrc/com/intellij/dependencies/UsagesInAnalyzingDependenciesTest.java b/java/java-tests/testSrc/com/intellij/dependencies/UsagesInAnalyzingDependenciesTest.java index fffb671295f8..5692019147fe 100644 --- a/java/java-tests/testSrc/com/intellij/dependencies/UsagesInAnalyzingDependenciesTest.java +++ b/java/java-tests/testSrc/com/intellij/dependencies/UsagesInAnalyzingDependenciesTest.java @@ -131,6 +131,27 @@ public class UsagesInAnalyzingDependenciesTest extends PsiTestCase{ checkResult(new String []{"(2: 3) B myB = new B();", "(2: 15) B myB = new B();", "(4: 9) myB.bb();"}, psiUsages); } + public void testForwardJdkClasses(){ + final DependenciesBuilder builder = new ForwardDependenciesBuilder(myProject, new AnalysisScope(myProject)); + builder.analyze(); + + final Set searchIn = new HashSet(); + final PsiClass aClass = myJavaFacade.findClass("A", GlobalSearchScope.allScope(myProject)); + searchIn.add(aClass.getContainingFile()); + + final Set searchFor = new HashSet(); + final PsiClass stringClass = myJavaFacade.findClass("java.lang.String", GlobalSearchScope.allScope(myProject)); + searchFor.add((PsiFile)stringClass.getContainingFile().getNavigationElement()); + + final UsageInfo[] usagesInfos = FindDependencyUtil.findDependencies(builder, searchIn, searchFor); + final UsageInfo2UsageAdapter[] usages = UsageInfo2UsageAdapter.convert(usagesInfos); + final String [] psiUsages = new String [usagesInfos.length]; + for (int i = 0; i < usagesInfos.length; i++) { + psiUsages[i] = toString(usages[i]); + } + checkResult(new String []{"(2: 3) String myName;"}, psiUsages); + } + private static void checkResult(final String[] usages, final String [] psiUsages) { assertEquals(usages.length , psiUsages.length); for (int i = 0; i < psiUsages.length; i++) { diff --git a/java/java-tests/testSrc/com/intellij/psi/formatter/java/AnnotationFormatterTest.java b/java/java-tests/testSrc/com/intellij/psi/formatter/java/AnnotationFormatterTest.java new file mode 100644 index 000000000000..10fea8405692 --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/psi/formatter/java/AnnotationFormatterTest.java @@ -0,0 +1,353 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.psi.formatter.java; + +import com.intellij.lang.java.JavaLanguage; +import com.intellij.openapi.roots.LanguageLevelProjectExtension; +import com.intellij.pom.java.LanguageLevel; +import com.intellij.psi.codeStyle.CodeStyleSettings; +import com.intellij.psi.codeStyle.CodeStyleSettingsManager; +import com.intellij.psi.codeStyle.CommonCodeStyleSettings; +import com.intellij.psi.formatter.FormatterTestCase; +import com.intellij.testFramework.LightPlatformTestCase; + +public class AnnotationFormatterTest extends JavaFormatterTestCase { + @Override + protected void setUp() throws Exception { + super.setUp(); + final CodeStyleSettingsManager codeStyleSettingsManager = CodeStyleSettingsManager.getInstance(LightPlatformTestCase.getProject()); + codeStyleSettingsManager.setTemporarySettings(new CodeStyleSettings()); + } + + @Override + protected void tearDown() throws Exception { + CodeStyleSettingsManager.getInstance(LightPlatformTestCase.getProject()).dropTemporarySettings(); + super.tearDown(); + } + + @Override + protected String getBasePath() { + return null; + } + + public void testAnnotationWrapping() throws Exception { + + FormatterTestCase.getSettings(JavaLanguage.INSTANCE).PARAMETER_ANNOTATION_WRAP = CommonCodeStyleSettings.WRAP_ALWAYS; + FormatterTestCase.getSettings(JavaLanguage.INSTANCE).VARIABLE_ANNOTATION_WRAP = CommonCodeStyleSettings.WRAP_ALWAYS; + doTextTest("class Foo {\n" + + " public void foo(@Ann1 @Ann2 int p1, @Ann3 boolean p1){}\n" + + "}", + "class Foo {\n" + + " public void foo(\n" + + " @Ann1\n" + + " @Ann2\n" + + " int p1,\n" + + " @Ann3\n" + + " boolean p1) {\n" + + " }\n" + + "}"); + + doTextTest("public interface PsiClass{\n" + + " @Nullable(documentation = \"return null for anonymous and local classes, and for type parameters\", doc2=\"\")\n" + + " String getQualifiedName();\n" + + "}", + "public interface PsiClass {\n" + + " @Nullable(documentation = \"return null for anonymous and local classes, and for type parameters\", doc2 = \"\")\n" + + " String getQualifiedName();\n" + + "}"); + + FormatterTestCase.getSettings(JavaLanguage.INSTANCE).CLASS_ANNOTATION_WRAP = CommonCodeStyleSettings.WRAP_ALWAYS; + doTextTest("@Ann1 @Ann2 class Foo {}", + "@Ann1\n" + + "@Ann2\n" + + "class Foo {\n" + + "}"); + + doTextTest("@Ann1 @Ann2 interface Foo {}", + "@Ann1\n" + + "@Ann2\n" + + "interface Foo {\n" + + "}"); + + doTextTest("class Foo { @Ann1 @Ann2 public static int myField;}", + "class Foo {\n" + + " @Ann1\n" + + " @Ann2\n" + + " public static int myField;\n" + + "}"); + + doTextTest("class Foo {\n" + + " void foo() {\n" + + " @Ann1 @Ann2 final int i = 0;" + + " }\n" + + "}", + "class Foo {\n" + + " void foo() {\n" + + " @Ann1\n" + + " @Ann2\n" + + " final int i = 0;\n" + + " }\n" + + "}"); + + getCustomJavaSettings().ANNOTATION_PARAMETER_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED; + FormatterTestCase.getSettings(JavaLanguage.INSTANCE).CLASS_ANNOTATION_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED; + FormatterTestCase.getSettings(JavaLanguage.INSTANCE).RIGHT_MARGIN = 40; + + doTextTest("@Annotation1 @Annotation2 @Annotation3(param1=\"value1\", param2=\"value2\") @Annotation4 class Foo {}", + "@Annotation1 @Annotation2\n" + + "@Annotation3(param1 = \"value1\",\n" + + " param2 = \"value2\") @Annotation4\n" + + "class Foo {\n" + + "}"); + + } + + public void testAnnotationParametersWrapping() throws Exception { + FormatterTestCase.getSettings(JavaLanguage.INSTANCE).RIGHT_MARGIN = 50; + getCustomJavaSettings().ANNOTATION_PARAMETER_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED; + getCustomJavaSettings().ALIGN_MULTILINE_ANNOTATION_PARAMETERS = false; + doTextTest("public interface PsiClass{\n" + + " @Nullable(documentation = \"parameter1 value\", doc2=\"parameter2 value\")\n" + + " String getQualifiedName();\n" + + "}", + "public interface PsiClass {\n" + + " @Nullable(documentation = \"parameter1 value\",\n" + + " doc2 = \"parameter2 value\")\n" + + " String getQualifiedName();\n" + + "}"); + getCustomJavaSettings().ALIGN_MULTILINE_ANNOTATION_PARAMETERS = true; + doTextTest("public interface PsiClass{\n" + + " @Nullable(documentation = \"parameter1 value\", doc2=\"parameter2 value\")\n" + + " String getQualifiedName();\n" + + "}", + "public interface PsiClass {\n" + + " @Nullable(documentation = \"parameter1 value\",\n" + + " doc2 = \"parameter2 value\")\n" + + " String getQualifiedName();\n" + + "}"); + + } + + public void testAnnotationParameters_DoNotWrap() { + FormatterTestCase.getSettings(JavaLanguage.INSTANCE).RIGHT_MARGIN = 50; + getCustomJavaSettings().ANNOTATION_PARAMETER_WRAP = CommonCodeStyleSettings.DO_NOT_WRAP; + doTextTest("class Test {\n" + + " @SuperAnnotation(first = \"my first line\", second = \"my second line\", third = \"third line\")\n" + + " public void run() {\n" + + " }\n" + + "}", + "class Test {\n" + + " @SuperAnnotation(first = \"my first line\", second = \"my second line\", third = \"third line\")\n" + + " public void run() {\n" + + " }\n" + + "}"); + } + + public void testAnnotationParameters_ChopDownIfLong() { + FormatterTestCase.getSettings(JavaLanguage.INSTANCE).RIGHT_MARGIN = 50; + getCustomJavaSettings().ANNOTATION_PARAMETER_WRAP = CommonCodeStyleSettings.WRAP_ON_EVERY_ITEM; + + String initial = "class Test {\n" + + " @SuperAnnotation(first = \"my first line\", second = \"my second line\", third = \"third line\")\n" + + " public void run() {\n" + + " }\n" + + "}"; + + getCustomJavaSettings().ALIGN_MULTILINE_ANNOTATION_PARAMETERS = true; + doTextTest(initial, + "class Test {\n" + + " @SuperAnnotation(first = \"my first line\",\n" + + " second = \"my second line\",\n" + + " third = \"third line\")\n" + + " public void run() {\n" + + " }\n" + + "}"); + + getCustomJavaSettings().ALIGN_MULTILINE_ANNOTATION_PARAMETERS = false; + doTextTest(initial, + "class Test {\n" + + " @SuperAnnotation(first = \"my first line\",\n" + + " second = \"my second line\",\n" + + " third = \"third line\")\n" + + " public void run() {\n" + + " }\n" + + "}"); + } + + public void testAnnotationParameters_WrapAlways() { + FormatterTestCase.getSettings(JavaLanguage.INSTANCE).RIGHT_MARGIN = 150; + getCustomJavaSettings().ANNOTATION_PARAMETER_WRAP = CommonCodeStyleSettings.WRAP_ALWAYS; + getCustomJavaSettings().ALIGN_MULTILINE_ANNOTATION_PARAMETERS = true; + + doTextTest("class Test {\n" + + " @SuperAnnotation(first = \"my first line\", second = \"my second line\", third = \"third line\")\n" + + " public void run() {\n" + + " }\n" + + "}", + "class Test {\n" + + " @SuperAnnotation(first = \"my first line\",\n" + + " second = \"my second line\",\n" + + " third = \"third line\")\n" + + " public void run() {\n" + + " }\n" + + "}"); + } + + public void testSpaces1() throws Exception { + defaultSettings(); + doTextTest("public interface PsiClass{\n" + + " @Nullable(documentation = \"parameter1 value\", doc2=\"parameter2 value\")\n" + + " String getQualifiedName();\n" + + "}", + "public interface PsiClass {\n" + + " @Nullable(documentation = \"parameter1 value\", doc2 = \"parameter2 value\")\n" + + " String getQualifiedName();\n" + + "}"); + } + + public void testSpaces2() throws Exception { + defaultSettings(); + FormatterTestCase.getSettings(JavaLanguage.INSTANCE).SPACE_BEFORE_ANOTATION_PARAMETER_LIST = true; + + doTextTest("public interface PsiClass{\n" + + " @Nullable(documentation = \"parameter1 value\", doc2=\"parameter2 value\")\n" + + " String getQualifiedName();\n" + + "}", + "public interface PsiClass {\n" + + " @Nullable (documentation = \"parameter1 value\", doc2 = \"parameter2 value\")\n" + + " String getQualifiedName();\n" + + "}"); + } + + public void testSpaces3() throws Exception { + defaultSettings(); + FormatterTestCase.getSettings(JavaLanguage.INSTANCE).SPACE_AROUND_ASSIGNMENT_OPERATORS = false; + doTextTest("public interface PsiClass{\n" + + " @Nullable(documentation = \"parameter1 value\", doc2=\"parameter2 value\")\n" + + " String getQualifiedName();\n" + + "}", + "public interface PsiClass {\n" + + " @Nullable(documentation=\"parameter1 value\", doc2=\"parameter2 value\")\n" + + " String getQualifiedName();\n" + + "}"); + } + + public void testSpaces4() throws Exception { + defaultSettings(); + FormatterTestCase.getSettings(JavaLanguage.INSTANCE).SPACE_AROUND_ASSIGNMENT_OPERATORS = true; + + doTextTest("public interface PsiClass{\n" + + " @Nullable(documentation = \"parameter1 value\", doc2=\"parameter2 value\")\n" + + " String getQualifiedName();\n" + + "}", + "public interface PsiClass {\n" + + " @Nullable(documentation = \"parameter1 value\", doc2 = \"parameter2 value\")\n" + + " String getQualifiedName();\n" + + "}"); + } + + public void testSpaces6() throws Exception { + defaultSettings(); + FormatterTestCase.getSettings(JavaLanguage.INSTANCE).SPACE_WITHIN_ANNOTATION_PARENTHESES = true; + + doTextTest("public interface PsiClass{\n" + + " @Nullable(documentation = \"parameter1 value\", doc2=\"parameter2 value\")\n" + + " String getQualifiedName();\n" + + "}", + "public interface PsiClass {\n" + + " @Nullable( documentation = \"parameter1 value\", doc2 = \"parameter2 value\" )\n" + + " String getQualifiedName();\n" + + "}"); + } + + public void testSpaces7() throws Exception { + defaultSettings(); + doTextTest("public interface PsiClass{\n" + + " @ Nullable ( documentation = \"parameter1 value\" ,doc2=\"parameter2 value\" ) \n" + + " String getQualifiedName();\n" + + "}", + "public interface PsiClass {\n" + + " @Nullable(documentation = \"parameter1 value\", doc2 = \"parameter2 value\")\n" + + " String getQualifiedName();\n" + + "}"); + } + + public void testAnnotationInterface() throws Exception { + doTextTest(" @ Documented\n" + + " @ Retention(RetentionPolicy.CLASS)\n" + + " @ Target ( { ElementType.METHOD ,ElementType.FIELD , ElementType.PARAMETER,ElementType.LOCAL_VARIABLE})\n" + + "public@interface NotNull{\n" + + "String documentation ( ) default \"\" ;\n" + + "String myField = \"\" ;\n" + + "}", + "@Documented\n" + + "@Retention(RetentionPolicy.CLASS)\n" + + "@Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.LOCAL_VARIABLE})\n" + + "public @interface NotNull {\n" + + " String documentation() default \"\";\n" + + "\n" + + " String myField = \"\";\n" + + "}"); + } + + public void testEnumFormatting() throws Exception{ + defaultSettings(); + FormatterTestCase.getSettings(JavaLanguage.INSTANCE).ENUM_CONSTANTS_WRAP = CommonCodeStyleSettings.WRAP_ALWAYS; + final LanguageLevel effectiveLanguageLevel = LanguageLevelProjectExtension.getInstance(LightPlatformTestCase.ourProject).getLanguageLevel(); + try { + LanguageLevelProjectExtension.getInstance(LightPlatformTestCase.ourProject).setLanguageLevel(LanguageLevel.JDK_1_5); + doTextTest(" enum Breed {\n" + + " Dalmatian ( \"spotted\" ),Labrador ( \"black\" ),Dachshund( \"brown\" );\n" + + "\n" + + " // constructor\n" + + " Breed ( String colour )\n" + + " {\n" + + " this.colour = colour;\n" + + " }\n" + + "\n" + + " private String colour;\n" + + "\n" + + " // additional method of every Breed object\n" + + " public String getColour()\n" + + " {\n" + + " return colour;\n" + + " }\n" + + " }", "enum Breed {\n" + " Dalmatian(\"spotted\"),\n" + " Labrador(\"black\"),\n" + " Dachshund(\"brown\");\n" + + "\n" + " // constructor\n" + " Breed(String colour) {\n" + " this.colour = colour;\n" + " }\n" + + "\n" + + " private String colour;\n" + + "\n" + + " // additional method of every Breed object\n" + + " public String getColour() {\n" + + " return colour;\n" + + " }\n" + + "}"); + doTextTest(" enum Breed {\n" + " Dalmatian ( \"spotted\" ),Labrador ( \"black\" ),Dachshund( \"brown\" )\n" + " }", + "enum Breed {\n" + " Dalmatian(\"spotted\"),\n" + " Labrador(\"black\"),\n" + " Dachshund(\"brown\")\n" + "}"); + doTextTest("enum Command { \n" + " USED \n" + " , \n" + " UNUSED\n" + "; \n" + " }", + "enum Command {\n" + " USED,\n" + " UNUSED;\n" + "}"); + } + finally { + LanguageLevelProjectExtension.getInstance(LightPlatformTestCase.ourProject).setLanguageLevel(effectiveLanguageLevel); + } + } + + + public void testSCR2072() throws Exception{ + } + + +} diff --git a/java/java-tests/testSrc/com/intellij/psi/formatter/java/DefaultProjectFormatterTest.java b/java/java-tests/testSrc/com/intellij/psi/formatter/java/DefaultProjectFormatterTest.java new file mode 100644 index 000000000000..4c066146336b --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/psi/formatter/java/DefaultProjectFormatterTest.java @@ -0,0 +1,62 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.psi.formatter.java; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectManager; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiFileFactory; +import com.intellij.testFramework.LightPlatformTestCase; +import com.intellij.util.IncorrectOperationException; +import junit.framework.TestCase; + +/** + * @author Rustam Vishnyakov + */ +public class DefaultProjectFormatterTest extends JavaFormatterTestCase { + @Override + protected String getBasePath() { + return "/psi/formatter/wrapping"; + } + + public void testFormatting() throws Exception { + Project currProject = LightPlatformTestCase.ourProject; + LightPlatformTestCase.ourProject = ProjectManager.getInstance().getDefaultProject(); + try { + doFileTest( + "class Foo{}", + + "class Foo {\n" + + "}"); + } + finally { + LightPlatformTestCase.ourProject = currProject; + } + } + + protected void doFileTest(final String text, final String textAfter) + throws IncorrectOperationException { + final String fileName = "before." + getFileExtension(); + final PsiFile file = createFileFromText(text, fileName, PsiFileFactory.getInstance(LightPlatformTestCase.getProject())); + CommandProcessor.getInstance().executeCommand(LightPlatformTestCase.getProject(), () -> ApplicationManager.getApplication().runWriteAction(() -> { + performFormatting(file); + }), "", ""); + String fileText = file.getText(); + TestCase.assertEquals(textAfter, fileText); + } +} diff --git a/java/java-tests/testSrc/com/intellij/psi/formatter/java/IndentTest.java b/java/java-tests/testSrc/com/intellij/psi/formatter/java/IndentTest.java new file mode 100644 index 000000000000..beed9ac5521a --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/psi/formatter/java/IndentTest.java @@ -0,0 +1,193 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.psi.formatter.java; + +import com.intellij.lang.java.JavaLanguage; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ex.PathManagerEx; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.PsiFile; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.codeStyle.CodeStyleSettings; +import com.intellij.psi.codeStyle.CodeStyleSettingsManager; +import com.intellij.psi.codeStyle.CommonCodeStyleSettings; +import com.intellij.testFramework.LightIdeaTestCase; +import com.intellij.util.IncorrectOperationException; + +import java.io.File; + +public class IndentTest extends LightIdeaTestCase { + private static final String BASE_PATH = PathManagerEx.getTestDataPath() + "/psi/formatter/indent"; + + private static CommonCodeStyleSettings getJavaSettings() { + return CodeStyleSettingsManager.getSettings(getProject()).getCommonSettings(JavaLanguage.INSTANCE); + } + + public void testSCR3681() throws Exception { + doTest("SCR3681.java", "SCR3681_after.java"); + } + + public void testBinaryOperation() throws Exception { + + defaultSettings(); + CommonCodeStyleSettings settings = getJavaSettings(); + settings.ALIGN_MULTILINE_BINARY_OPERATION = true; + + doTest("BinaryOperation.java", "BinaryOperation_after.java"); + } + + public void testBinaryOperationSignMoved() throws Exception { + + defaultSettings(); + CommonCodeStyleSettings settings = getJavaSettings(); + settings.ALIGN_MULTILINE_BINARY_OPERATION = true; + + doTest("BinaryOperationSignMoved.java", "BinaryOperationSignMoved_after.java"); + } + + public void testTernaryOperation() throws Exception { + defaultSettings(); + CommonCodeStyleSettings settings = getJavaSettings(); + settings.ALIGN_MULTILINE_TERNARY_OPERATION = true; + + doTest("TernaryOperation.java", "TernaryOperation_after.java"); + } + + public void testTernaryOperationSignMoved() throws Exception { + defaultSettings(); + CommonCodeStyleSettings settings = getJavaSettings(); + settings.ALIGN_MULTILINE_TERNARY_OPERATION = true; + + doTest("TernaryOperationSignMoved.java", "TernaryOperationSignMoved_after.java"); + } + + public void testImplementsList() throws Exception { + + defaultSettings(); + CommonCodeStyleSettings settings = getJavaSettings(); + settings.ALIGN_MULTILINE_EXTENDS_LIST = true; + + doTest("ImplementsList.java", "ImplementsList_after.java"); + } + + public void testImplementsList2() throws Exception { + + defaultSettings(); + CommonCodeStyleSettings settings = getJavaSettings(); + settings.ALIGN_MULTILINE_EXTENDS_LIST = true; + + doTest("ImplementsList2.java", "ImplementsList2_after.java"); + } + + public void testParenthesizedBinop() throws Exception { + defaultSettings(); + CommonCodeStyleSettings settings = getJavaSettings(); + settings.ALIGN_MULTILINE_BINARY_OPERATION = true; + settings.ALIGN_MULTILINE_PARENTHESIZED_EXPRESSION = true; + + doTest("ParenthesizedBinop.java", "ParenthesizedBinop_after.java"); + } + + public void testParenthesizedContinuation() throws Exception { + + defaultSettings(); + CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(getProject()); + settings.ALIGN_MULTILINE_PARENTHESIZED_EXPRESSION = true; + + doTest("ParenthesizedContinuation.java", "ParenthesizedContinuation_after.java"); + } + + public void testParenthesizedContinuation2() throws Exception { + + defaultSettings(); + CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(getProject()); + settings.ALIGN_MULTILINE_PARENTHESIZED_EXPRESSION = true; + + doTest("ParenthesizedContinuation2.java", "ParenthesizedContinuation2_after.java"); + } + + public void testDoNotIndentTopLevelClassMembers() throws Exception { + + defaultSettings(); + CommonCodeStyleSettings settings = getJavaSettings(); + settings.DO_NOT_INDENT_TOP_LEVEL_CLASS_MEMBERS = true; + + doTest("DoNotIndentTopLevelClassMembers.java", "DoNotIndentTopLevelClassMembers_after.java"); + } + + private void doTest(String fileNameBefore, String fileNameAfter) throws Exception { + String text = loadFile(fileNameBefore); + final PsiFile file = createFile(fileNameBefore, text); + CommandProcessor.getInstance().executeCommand(getProject(), new Runnable() { + @Override + public void run() { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + @Override + public void run() { + try { + CodeStyleManager.getInstance(getProject()).reformat(file); + } + catch (IncorrectOperationException e) { + assertTrue(false); + } + } + }); + } + }, null, null); + + + String textAfter = loadFile(fileNameAfter); + String fileText = file.getText(); + if (textAfter.startsWith("\n")) { + textAfter = textAfter.substring(1); + } + if (fileText.startsWith("\n")) { + fileText = fileText.substring(1); + } + + assertEquals(textAfter, fileText); + } + + private String loadFile(String name) throws Exception { + String fullName = BASE_PATH + File.separatorChar + name; + String text = FileUtil.loadFile(new File(fullName)); + text = StringUtil.convertLineSeparators(text); + return text; + } + + private void defaultSettings() { + CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(getProject()); + + settings.ALIGN_MULTILINE_PARAMETERS = true; + settings.ALIGN_MULTILINE_PARAMETERS_IN_CALLS = false; + settings.ALIGN_MULTILINE_FOR = true; + + settings.ALIGN_MULTILINE_BINARY_OPERATION = false; + settings.ALIGN_MULTILINE_TERNARY_OPERATION = false; + settings.ALIGN_MULTILINE_THROWS_LIST = false; + settings.ALIGN_MULTILINE_EXTENDS_LIST = false; + settings.ALIGN_MULTILINE_PARENTHESIZED_EXPRESSION = false; + settings.DO_NOT_INDENT_TOP_LEVEL_CLASS_MEMBERS = false; + } + + @Override + protected void tearDown() throws Exception { + defaultSettings(); + super.tearDown(); + } +} diff --git a/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterTestCase.java b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterTestCase.java new file mode 100644 index 000000000000..4d2ebd55a746 --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterTestCase.java @@ -0,0 +1,49 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.psi.formatter.java; + +import com.intellij.openapi.module.ModuleType; +import com.intellij.openapi.module.StdModuleTypes; +import com.intellij.openapi.projectRoots.Sdk; +import com.intellij.psi.codeStyle.JavaCodeStyleSettings; +import com.intellij.psi.formatter.FormatterTestCase; +import com.intellij.testFramework.IdeaTestUtil; +import org.jetbrains.annotations.NotNull; + +/** + * @author yole + */ +public abstract class JavaFormatterTestCase extends FormatterTestCase { + @Override + protected Sdk getProjectJDK() { + return IdeaTestUtil.getMockJdk17(); + } + + @NotNull + @Override + protected ModuleType getModuleType() { + return StdModuleTypes.JAVA; + } + + @Override + protected String getFileExtension() { + return "java"; + } + + protected JavaCodeStyleSettings getCustomJavaSettings() { + return getSettings().getCustomSettings(JavaCodeStyleSettings.class); + } +} diff --git a/java/java-tests/testSrc/com/intellij/psi/formatter/java/TabIndentingTest.java b/java/java-tests/testSrc/com/intellij/psi/formatter/java/TabIndentingTest.java new file mode 100644 index 000000000000..7644c9dcbc2a --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/psi/formatter/java/TabIndentingTest.java @@ -0,0 +1,179 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.psi.formatter.java; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ex.PathManagerEx; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.PsiFile; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.codeStyle.CodeStyleSettings; +import com.intellij.psi.codeStyle.CodeStyleSettingsManager; +import com.intellij.testFramework.LightIdeaTestCase; +import com.intellij.util.IncorrectOperationException; + +import java.io.File; + +public class TabIndentingTest extends LightIdeaTestCase { + private static final String BASE_PATH = PathManagerEx.getTestDataPath() + "/psi/formatter/tabIndenting"; + + public void testSpace() throws Exception { + doTest("Test.java", "Space_after.java"); + } + + public void testSmartTab4() throws Exception { + CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(getProject()); + settings.getIndentOptions(StdFileTypes.JAVA).USE_TAB_CHARACTER = true; + settings.getIndentOptions(StdFileTypes.JAVA).SMART_TABS = true; + + try{ + doTest("Test.java", "SmartTab4_after.java"); + } + finally{ + settings.getIndentOptions(StdFileTypes.JAVA).USE_TAB_CHARACTER = false; + settings.getIndentOptions(StdFileTypes.JAVA).SMART_TABS = false; + } + } + + public void testSmartTab2() throws Exception { + CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(getProject()); + settings.getIndentOptions(StdFileTypes.JAVA).USE_TAB_CHARACTER = true; + settings.getIndentOptions(StdFileTypes.JAVA).SMART_TABS = true; + settings.getIndentOptions(StdFileTypes.JAVA).TAB_SIZE = 2; + + try{ + doTest("Test.java", "SmartTab2_after.java"); + } + finally{ + settings.getIndentOptions(StdFileTypes.JAVA).USE_TAB_CHARACTER = false; + settings.getIndentOptions(StdFileTypes.JAVA).SMART_TABS = false; + settings.getIndentOptions(StdFileTypes.JAVA).TAB_SIZE = 4; + } + } + + //does not work correctly at the moment + /* + public void testSmartTab8() throws Exception { + EditorSettingsExternalizable editorSettings = EditorSettingsExternalizable.getInstance(); + editorSettings.setUseTabCharacter(true); + //editorSettings.setTabSize(8); + + try{ + doTest("Test.java", "SmartTab8_after.java"); + } + finally{ + editorSettings.setUseTabCharacter(false); + //editorSettings.setTabSize(8); + } + } + */ + + public void testTab2() throws Exception { + CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(getProject()); + settings.getIndentOptions(StdFileTypes.JAVA).USE_TAB_CHARACTER = true; + settings.getIndentOptions(StdFileTypes.JAVA).TAB_SIZE = 2; + + try{ + doTest("Test.java", "Tab2_after.java"); + } + finally{ + settings.getIndentOptions(StdFileTypes.JAVA).USE_TAB_CHARACTER = false; + settings.getIndentOptions(StdFileTypes.JAVA).TAB_SIZE = 4; + } + } + + public void testTab4() throws Exception { + CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(getProject()); + settings.getIndentOptions(StdFileTypes.JAVA).USE_TAB_CHARACTER = true; + + try{ + doTest("Test.java", "Tab4_after.java"); + } + finally{ + settings.getIndentOptions(StdFileTypes.JAVA).USE_TAB_CHARACTER = false; + } + } + + public void testTab8() throws Exception { + CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(getProject()); + settings.getIndentOptions(StdFileTypes.JAVA).USE_TAB_CHARACTER = true; + settings.getIndentOptions(StdFileTypes.JAVA).TAB_SIZE = 8; + + try{ + doTest("Test.java", "Tab8_after.java"); + } + finally{ + settings.getIndentOptions(StdFileTypes.JAVA).USE_TAB_CHARACTER = false; + settings.getIndentOptions(StdFileTypes.JAVA).TAB_SIZE = 4; + } + } + + public void testSCR6197() throws Exception { + doTest("SCR6197.java", "SCR6197_after.java"); + } + + private void doTest(String fileNameBefore, String fileNameAfter) throws Exception{ + String text = loadFile(fileNameBefore); + final PsiFile file = createFile(fileNameBefore, text); + CommandProcessor.getInstance().executeCommand(getProject(), new Runnable() { + @Override + public void run() { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + @Override + public void run() { + try { + CodeStyleManager.getInstance(getProject()).reformat(file); + } + catch (IncorrectOperationException e) { + assertTrue(false); + } + } + }); + } + }, null, null); + + + String textAfter = loadFile(fileNameAfter); + String fileText = file.getText(); + + if (textAfter.startsWith("\n")) { + textAfter = textAfter.substring(1); + } + if (fileText.startsWith("\n")) { + fileText = fileText.substring(1); + } + + if (!textAfter.equals(fileText)) { + System.err.println("Expected:"); + System.err.println(textAfter); + System.err.println(); + System.err.println("Was:"); + System.err.println(fileText); + + assertEquals(textAfter, fileText); + } + } + + private String loadFile(String name) throws Exception { + String fullName = BASE_PATH + File.separatorChar + name; + String text = FileUtil.loadFile(new File(fullName)); + text = StringUtil.convertLineSeparators(text); + return text; + } +} diff --git a/java/java-tests/testSrc/com/intellij/psi/formatter/java/WrapperTest.java b/java/java-tests/testSrc/com/intellij/psi/formatter/java/WrapperTest.java new file mode 100644 index 000000000000..5a0508f89447 --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/psi/formatter/java/WrapperTest.java @@ -0,0 +1,542 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.psi.formatter.java; + +import com.intellij.lang.java.JavaLanguage; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.psi.codeStyle.CommonCodeStyleSettings; + +public class WrapperTest extends JavaFormatterTestCase { + @Override + protected String getBasePath() { + return "/psi/formatter/wrapping"; + } + + @Override + protected String prepareText(final String text) { + String result = text; + if (result.startsWith("\n")) { + result = result.substring(1); + } + return result; + } + + + public void testExtendsKeywordWrappingForced() throws Exception { + CommonCodeStyleSettings settings = getSettings(JavaLanguage.INSTANCE); + + defaultCodeStyle(); + settings.EXTENDS_KEYWORD_WRAP = CommonCodeStyleSettings.WRAP_ALWAYS; + + doTest("ExtendsWrappingForced", "ExtendsWrappingForced_after"); + } + + public void testExtendsKeywordWrappingAsNeeded() throws Exception { + CommonCodeStyleSettings settings = getSettings(JavaLanguage.INSTANCE); + + defaultCodeStyle(); + settings.EXTENDS_KEYWORD_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED; + + settings.RIGHT_MARGIN = 20; + + doTest("ExtendsWrappingForced", "ExtendsWrappingForced_after"); + } + + public void testExtendsListWrappingNormal() throws Exception { + CommonCodeStyleSettings settings = getSettings(JavaLanguage.INSTANCE); + + defaultCodeStyle(); + settings.EXTENDS_KEYWORD_WRAP = CommonCodeStyleSettings.DO_NOT_WRAP; + settings.EXTENDS_LIST_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED; + + settings.RIGHT_MARGIN = 45; + doTest("ExtendsListWrapping", "ExtendsListWrapping_normal"); + } + + public void testExtendsListWrappingChopped() throws Exception { + CommonCodeStyleSettings settings = getSettings(JavaLanguage.INSTANCE); + + defaultCodeStyle(); + settings.EXTENDS_KEYWORD_WRAP = CommonCodeStyleSettings.DO_NOT_WRAP; + settings.EXTENDS_LIST_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED | CommonCodeStyleSettings.WRAP_ON_EVERY_ITEM; + + settings.RIGHT_MARGIN = 45; + doTest("ExtendsListWrapping", "ExtendsListWrapping_chopped"); + } + + public void testMethodParametersWrappingNormal() throws Exception { + CommonCodeStyleSettings settings = getSettings(JavaLanguage.INSTANCE); + + defaultCodeStyle(); + settings.METHOD_PARAMETERS_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED; + settings.METHOD_PARAMETERS_RPAREN_ON_NEXT_LINE = false; + settings.METHOD_PARAMETERS_LPAREN_ON_NEXT_LINE = false; + + settings.RIGHT_MARGIN = 50; + doTest("MethodParameterList", "MethodParameterList_normal"); + } + + public void testMethodParametersWrappingChopped() throws Exception { + CommonCodeStyleSettings settings = getSettings(JavaLanguage.INSTANCE); + + defaultCodeStyle(); + settings.METHOD_PARAMETERS_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED | CommonCodeStyleSettings.WRAP_ON_EVERY_ITEM; + settings.METHOD_PARAMETERS_RPAREN_ON_NEXT_LINE = false; + settings.METHOD_PARAMETERS_LPAREN_ON_NEXT_LINE = false; + + settings.RIGHT_MARGIN = 50; + doTest("MethodParameterList", "MethodParameterList_chopped"); + } + + public void testMethodParametersWrappingChoppedParenMoved() throws Exception { + CommonCodeStyleSettings settings = getSettings(JavaLanguage.INSTANCE); + + defaultCodeStyle(); + settings.METHOD_PARAMETERS_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED | CommonCodeStyleSettings.WRAP_ON_EVERY_ITEM; + settings.METHOD_PARAMETERS_RPAREN_ON_NEXT_LINE = true; + settings.METHOD_PARAMETERS_LPAREN_ON_NEXT_LINE = false; + + settings.RIGHT_MARGIN = 50; + doTest("MethodParameterList", "MethodParameterList_chopped_parenmoved"); + } + + public void testCallParametersWrappingNormal() throws Exception { + CommonCodeStyleSettings settings = getSettings(JavaLanguage.INSTANCE); + + defaultCodeStyle(); + settings.CALL_PARAMETERS_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED; + settings.CALL_PARAMETERS_RPAREN_ON_NEXT_LINE = false; + settings.ALIGN_MULTILINE_PARAMETERS_IN_CALLS = true; + settings.CALL_PARAMETERS_LPAREN_ON_NEXT_LINE = false; + + settings.RIGHT_MARGIN = 50; + doTest("CallParameterList", "CallParameterList_normal"); + } + + public void testNotBreakedIfNoParameters() throws Exception { + CommonCodeStyleSettings settings = getSettings(JavaLanguage.INSTANCE); + + defaultCodeStyle(); + settings.CALL_PARAMETERS_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED; + settings.CALL_PARAMETERS_RPAREN_ON_NEXT_LINE = false; + settings.ALIGN_MULTILINE_PARAMETERS_IN_CALLS = true; + settings.CALL_PARAMETERS_LPAREN_ON_NEXT_LINE = false; + + settings.RIGHT_MARGIN = 50; + doTest("CallNoParameteresList", "CallNoParameteresList_after"); + } + + public void testCallParametersWrappingChopped() throws Exception { + CommonCodeStyleSettings settings = getSettings(JavaLanguage.INSTANCE); + + defaultCodeStyle(); + settings.CALL_PARAMETERS_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED | CommonCodeStyleSettings.WRAP_ON_EVERY_ITEM; + settings.CALL_PARAMETERS_RPAREN_ON_NEXT_LINE = false; + settings.ALIGN_MULTILINE_PARAMETERS_IN_CALLS = true; + settings.CALL_PARAMETERS_LPAREN_ON_NEXT_LINE = false; + + settings.RIGHT_MARGIN = 50; + doTest("CallParameterList", "CallParameterList_chopped"); + } + + public void testNestedLongCalls() throws Exception { + CommonCodeStyleSettings settings = getSettings(JavaLanguage.INSTANCE); + + defaultCodeStyle(); + settings.CALL_PARAMETERS_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED | CommonCodeStyleSettings.WRAP_ON_EVERY_ITEM; + settings.CALL_PARAMETERS_RPAREN_ON_NEXT_LINE = false; + settings.ALIGN_MULTILINE_PARAMETERS_IN_CALLS = true; + settings.CALL_PARAMETERS_LPAREN_ON_NEXT_LINE = false; + + settings.RIGHT_MARGIN = 40; + doTest("NestedLongCalls", "NestedLongCalls_after"); + } + + public void testCallParametersWrappingChoppedParenMoved() throws Exception { + CommonCodeStyleSettings settings = getSettings(JavaLanguage.INSTANCE); + + defaultCodeStyle(); + settings.CALL_PARAMETERS_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED | CommonCodeStyleSettings.WRAP_ON_EVERY_ITEM; + settings.CALL_PARAMETERS_RPAREN_ON_NEXT_LINE = true; + settings.ALIGN_MULTILINE_PARAMETERS_IN_CALLS = true; + settings.CALL_PARAMETERS_LPAREN_ON_NEXT_LINE = false; + + settings.RIGHT_MARGIN = 50; + doTest("CallParameterList", "CallParameterList_chopped_parenmoved"); + } + + public void testCallParametersWrappingChoppedBothParenMoved() throws Exception { + CommonCodeStyleSettings settings = getSettings(JavaLanguage.INSTANCE); + + defaultCodeStyle(); + settings.CALL_PARAMETERS_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED | CommonCodeStyleSettings.WRAP_ON_EVERY_ITEM; + settings.CALL_PARAMETERS_RPAREN_ON_NEXT_LINE = true; + settings.ALIGN_MULTILINE_PARAMETERS_IN_CALLS = true; + settings.CALL_PARAMETERS_LPAREN_ON_NEXT_LINE = true; + + settings.RIGHT_MARGIN = 50; + doTest("CallParameterList", "CallParameterList_chopped_bothparenmoved"); + } + + public void testChainedMethodCall() throws Exception { + CommonCodeStyleSettings settings = getSettings(JavaLanguage.INSTANCE); + + defaultCodeStyle(); + settings.CALL_PARAMETERS_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED | CommonCodeStyleSettings.WRAP_ON_EVERY_ITEM; + settings.CALL_PARAMETERS_RPAREN_ON_NEXT_LINE = false; + settings.CALL_PARAMETERS_LPAREN_ON_NEXT_LINE = false; + settings.ALIGN_MULTILINE_PARAMETERS_IN_CALLS = true; + settings.METHOD_CALL_CHAIN_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED; + + settings.RIGHT_MARGIN = 52; + doTest("ChainedMethodCall", "ChainedMethodCall_normal"); + } + + public void testChainedMethodCallChopped() throws Exception { + CommonCodeStyleSettings settings = getSettings(JavaLanguage.INSTANCE); + + defaultCodeStyle(); + settings.CALL_PARAMETERS_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED | CommonCodeStyleSettings.WRAP_ON_EVERY_ITEM; + settings.CALL_PARAMETERS_RPAREN_ON_NEXT_LINE = false; + settings.CALL_PARAMETERS_LPAREN_ON_NEXT_LINE = false; + settings.ALIGN_MULTILINE_PARAMETERS_IN_CALLS = true; + settings.METHOD_CALL_CHAIN_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED | CommonCodeStyleSettings.WRAP_ON_EVERY_ITEM; + + settings.RIGHT_MARGIN = 52; + doTest("ChainedMethodCall", "ChainedMethodCall_chopped"); + } + + public void testChainedCallsAndParams() throws Exception { + CommonCodeStyleSettings settings = getSettings(JavaLanguage.INSTANCE); + + defaultCodeStyle(); + settings.CALL_PARAMETERS_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED | CommonCodeStyleSettings.WRAP_ON_EVERY_ITEM; + settings.CALL_PARAMETERS_RPAREN_ON_NEXT_LINE = true; + settings.CALL_PARAMETERS_LPAREN_ON_NEXT_LINE = false; + settings.ALIGN_MULTILINE_PARAMETERS_IN_CALLS = true; + settings.METHOD_CALL_CHAIN_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED; + + settings.RIGHT_MARGIN = 120; + doTest("ChainedCallsAndParams", "ChainedCallsAndParams_normal"); + } + + public void testParenthesesExpressionLParenWrap() throws Exception { + CommonCodeStyleSettings settings = getSettings(JavaLanguage.INSTANCE); + + defaultCodeStyle(); + settings.PARENTHESES_EXPRESSION_LPAREN_WRAP = true; + settings.PARENTHESES_EXPRESSION_RPAREN_WRAP = false; + settings.ALIGN_MULTILINE_PARAMETERS_IN_CALLS = true; + settings.CALL_PARAMETERS_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED | CommonCodeStyleSettings.WRAP_ON_EVERY_ITEM; + settings.getRootSettings().getIndentOptions(StdFileTypes.JAVA).CONTINUATION_INDENT_SIZE=5; + settings.RIGHT_MARGIN = 25; + doTest("ParenthesizedExpressionWrap", "ParenthesizedExpressionWrap_left"); + } + + public void testParenthesesExpressionRParenWrap() throws Exception { + CommonCodeStyleSettings settings = getSettings(JavaLanguage.INSTANCE); + + defaultCodeStyle(); + settings.PARENTHESES_EXPRESSION_RPAREN_WRAP = true; + settings.PARENTHESES_EXPRESSION_LPAREN_WRAP = false; + settings.ALIGN_MULTILINE_PARAMETERS_IN_CALLS = true; + settings.CALL_PARAMETERS_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED | CommonCodeStyleSettings.WRAP_ON_EVERY_ITEM; + + settings.RIGHT_MARGIN = 25; + doTest("ParenthesizedExpressionWrap", "ParenthesizedExpressionWrap_right"); + } + + public void testParenthesesExpressionBothParenWrap() throws Exception { + CommonCodeStyleSettings settings = getSettings(JavaLanguage.INSTANCE); + + settings.PARENTHESES_EXPRESSION_LPAREN_WRAP = true; + settings.PARENTHESES_EXPRESSION_RPAREN_WRAP = true; + settings.ALIGN_MULTILINE_PARAMETERS_IN_CALLS = true; + settings.CALL_PARAMETERS_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED | CommonCodeStyleSettings.WRAP_ON_EVERY_ITEM; + + settings.RIGHT_MARGIN = 25; + doTest("ParenthesizedExpressionWrap", "ParenthesizedExpressionWrap_both"); + } + + public void testBinaryOperationNormal() throws Exception { + CommonCodeStyleSettings settings = getSettings(JavaLanguage.INSTANCE); + + defaultCodeStyle(); + settings.BINARY_OPERATION_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED; + + settings.RIGHT_MARGIN = 27; + doTest("BinaryOperation", "BinaryOperation_normal"); + } + + public void testBinaryOperationChopped() throws Exception { + CommonCodeStyleSettings settings = getSettings(JavaLanguage.INSTANCE); + + defaultCodeStyle(); + settings.BINARY_OPERATION_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED | CommonCodeStyleSettings.WRAP_ON_EVERY_ITEM; + + settings.RIGHT_MARGIN = 27; + doTest("BinaryOperation", "BinaryOperation_chopped"); + } + + public void testBinaryOperationChoppedSignMove() throws Exception { + CommonCodeStyleSettings settings = getSettings(JavaLanguage.INSTANCE); + + defaultCodeStyle(); + settings.BINARY_OPERATION_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED | CommonCodeStyleSettings.WRAP_ON_EVERY_ITEM; + settings.BINARY_OPERATION_SIGN_ON_NEXT_LINE = true; + + settings.RIGHT_MARGIN = 27; + + doTest("BinaryOperation", "BinaryOperation_chopped_signmoved"); + } + + public void testTernaryOperationNormal() throws Exception { + CommonCodeStyleSettings settings = getSettings(JavaLanguage.INSTANCE); + + defaultCodeStyle(); + settings.TERNARY_OPERATION_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED; + + settings.RIGHT_MARGIN = 27; + doTest("TernaryOperation", "TernaryOperation_normal"); + } + + public void testTernaryOperationChopped() throws Exception { + CommonCodeStyleSettings settings = getSettings(JavaLanguage.INSTANCE); + + defaultCodeStyle(); + settings.TERNARY_OPERATION_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED | CommonCodeStyleSettings.WRAP_ON_EVERY_ITEM; + + settings.RIGHT_MARGIN = 27; + doTest("TernaryOperation", "TernaryOperation_chopped"); + } + + public void testTernaryOperationChoppedSignMoved() throws Exception { + CommonCodeStyleSettings settings = getSettings(JavaLanguage.INSTANCE); + + defaultCodeStyle(); + settings.TERNARY_OPERATION_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED | CommonCodeStyleSettings.WRAP_ON_EVERY_ITEM; + settings.TERNARY_OPERATION_SIGNS_ON_NEXT_LINE = true; + + settings.RIGHT_MARGIN = 27; + doTest("TernaryOperation", "TernaryOperation_chopped_signmoved"); + } + + public void testModifierList() throws Exception { + CommonCodeStyleSettings settings = getSettings(JavaLanguage.INSTANCE); + + defaultCodeStyle(); + settings.MODIFIER_LIST_WRAP = true; + + doTest("ModifierList", "ModifierList_after"); + } + + public void testSimpleMethods() throws Exception { + CommonCodeStyleSettings settings = getSettings(JavaLanguage.INSTANCE); + + defaultCodeStyle(); + settings.KEEP_SIMPLE_METHODS_IN_ONE_LINE = true; + settings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE = true; + + settings.RIGHT_MARGIN = 50; + + doTest("SimpleMethods", "SimpleMethods_after"); + } + + public void testForStatementNormal() throws Exception { + CommonCodeStyleSettings settings = getSettings(JavaLanguage.INSTANCE); + + defaultCodeStyle(); + settings.FOR_STATEMENT_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED | CommonCodeStyleSettings.WRAP_ON_EVERY_ITEM; + + settings.RIGHT_MARGIN = 80; + + doTest("ForStatement", "ForStatement_normal"); + } + + public void testForStatementLParenMoved() throws Exception { + CommonCodeStyleSettings settings = getSettings(JavaLanguage.INSTANCE); + + defaultCodeStyle(); + settings.FOR_STATEMENT_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED | CommonCodeStyleSettings.WRAP_ON_EVERY_ITEM; + settings.FOR_STATEMENT_LPAREN_ON_NEXT_LINE = true; + + settings.RIGHT_MARGIN = 80; + + doTest("ForStatement", "ForStatement_lparen"); + } + + public void testForStatementRParenMoved() throws Exception { + CommonCodeStyleSettings settings = getSettings(JavaLanguage.INSTANCE); + + defaultCodeStyle(); + settings.FOR_STATEMENT_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED | CommonCodeStyleSettings.WRAP_ON_EVERY_ITEM; + settings.FOR_STATEMENT_RPAREN_ON_NEXT_LINE = true; + + settings.RIGHT_MARGIN = 80; + + doTest("ForStatement", "ForStatement_rparen"); + } + + public void testForStatementBothParensMoved() throws Exception { + CommonCodeStyleSettings settings = getSettings(JavaLanguage.INSTANCE); + + defaultCodeStyle(); + settings.FOR_STATEMENT_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED | CommonCodeStyleSettings.WRAP_ON_EVERY_ITEM; + settings.FOR_STATEMENT_LPAREN_ON_NEXT_LINE = true; + settings.FOR_STATEMENT_RPAREN_ON_NEXT_LINE = true; + + settings.RIGHT_MARGIN = 80; + + doTest("ForStatement", "ForStatement_both"); + } + + public void testKillSpacesInEmptyLine() throws Exception { + defaultCodeStyle(); + doTest("KillSpacesInEmptyLine", "KillSpacesInEmptyLine_after"); + } + + public void testSCR11423() throws Exception { + defaultCodeStyle(); + CommonCodeStyleSettings settings = getSettings(JavaLanguage.INSTANCE); + settings.THROWS_KEYWORD_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED; + settings.THROWS_LIST_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED; + + settings.RIGHT_MARGIN = 80; + + doTest("SCR11423", "SCR11423_after"); + } + + public void testIncompleteFor() throws Exception { + defaultCodeStyle(); + + CommonCodeStyleSettings settings = getSettings(JavaLanguage.INSTANCE); + settings.FOR_STATEMENT_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED | CommonCodeStyleSettings.WRAP_ON_EVERY_ITEM; + settings.FOR_STATEMENT_RPAREN_ON_NEXT_LINE = true; + + settings.RIGHT_MARGIN = 20; + + doTest("IncompleteFor", "IncompleteFor_after"); + } + public void testSCR27373() throws Exception { + defaultCodeStyle(); + + CommonCodeStyleSettings settings = getSettings(JavaLanguage.INSTANCE); + settings.CALL_PARAMETERS_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED; + settings.CALL_PARAMETERS_LPAREN_ON_NEXT_LINE = true; + + settings.RIGHT_MARGIN = 100; + + doTest("SCR27373", "SCR27373_after"); + } + + public void testDoNotWrapCallChainIfParametersWrapped() throws Exception{ + getSettings(JavaLanguage.INSTANCE).RIGHT_MARGIN = 140; + getSettings(JavaLanguage.INSTANCE).CALL_PARAMETERS_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED; + getSettings(JavaLanguage.INSTANCE).METHOD_CALL_CHAIN_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED; + getSettings(JavaLanguage.INSTANCE).getRootSettings().getIndentOptions(StdFileTypes.JAVA).INDENT_SIZE = 2; + getSettings(JavaLanguage.INSTANCE).getRootSettings().getIndentOptions(StdFileTypes.JAVA).CONTINUATION_INDENT_SIZE = 2; + getSettings(JavaLanguage.INSTANCE).ALIGN_MULTILINE_PARAMETERS_IN_CALLS = true; + + doTextTest("class Foo {\n" + + " void foo() {\n" + + " for (int i = 0; i < descriptors.length; i++) {\n" + + " descriptors[i] = manager.createProblemDescriptor(results.get(i), \"Usage of the API documented as @since 1.5\", (LocalQuickFix)null,ProblemHighlightType.GENERIC_ERROR_OR_WARNING);\n" + + " }" + + " }\n" + + "}", + "class Foo {\n" + + " void foo() {\n" + + " for (int i = 0; i < descriptors.length; i++) {\n" + + " descriptors[i] = manager.createProblemDescriptor(results.get(i), \"Usage of the API documented as @since 1.5\", (LocalQuickFix) null,\n" + + " ProblemHighlightType.GENERIC_ERROR_OR_WARNING);\n" + + " }\n" + + " }\n" + + "}"); + } + + private void defaultCodeStyle() { + CommonCodeStyleSettings settings = getSettings(JavaLanguage.INSTANCE); + + settings.CALL_PARAMETERS_WRAP = CommonCodeStyleSettings.DO_NOT_WRAP; + settings.CALL_PARAMETERS_LPAREN_ON_NEXT_LINE = false; + settings.CALL_PARAMETERS_RPAREN_ON_NEXT_LINE = false; + settings.METHOD_PARAMETERS_WRAP = CommonCodeStyleSettings.DO_NOT_WRAP; + settings.METHOD_PARAMETERS_LPAREN_ON_NEXT_LINE = false; + settings.METHOD_PARAMETERS_RPAREN_ON_NEXT_LINE = false; + settings.EXTENDS_LIST_WRAP = CommonCodeStyleSettings.DO_NOT_WRAP; + settings.THROWS_LIST_WRAP = CommonCodeStyleSettings.DO_NOT_WRAP; + + settings.EXTENDS_KEYWORD_WRAP = CommonCodeStyleSettings.DO_NOT_WRAP; + settings.THROWS_KEYWORD_WRAP = CommonCodeStyleSettings.DO_NOT_WRAP; + + settings.METHOD_CALL_CHAIN_WRAP = CommonCodeStyleSettings.DO_NOT_WRAP; + + settings.PARENTHESES_EXPRESSION_LPAREN_WRAP = false; + settings.PARENTHESES_EXPRESSION_RPAREN_WRAP = false; + + settings.BINARY_OPERATION_WRAP = CommonCodeStyleSettings.DO_NOT_WRAP; + settings.BINARY_OPERATION_SIGN_ON_NEXT_LINE = false; + settings.MODIFIER_LIST_WRAP = false; + settings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE = false; + + settings.FOR_STATEMENT_WRAP = CommonCodeStyleSettings.DO_NOT_WRAP; + settings.FOR_STATEMENT_LPAREN_ON_NEXT_LINE = false; + settings.FOR_STATEMENT_RPAREN_ON_NEXT_LINE = false; + + settings.ARRAY_INITIALIZER_WRAP = CommonCodeStyleSettings.DO_NOT_WRAP; + settings.ARRAY_INITIALIZER_LBRACE_ON_NEXT_LINE = false; + settings.ARRAY_INITIALIZER_RBRACE_ON_NEXT_LINE = false; + + settings.ASSIGNMENT_WRAP = CommonCodeStyleSettings.DO_NOT_WRAP; + settings.PLACE_ASSIGNMENT_SIGN_ON_NEXT_LINE = false; + + settings.RIGHT_MARGIN = 120; + } + + public void testThrowsListWrapping() throws Exception{ + getSettings(JavaLanguage.INSTANCE).RIGHT_MARGIN = 20; + + getSettings(JavaLanguage.INSTANCE).THROWS_KEYWORD_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED; + getSettings(JavaLanguage.INSTANCE).THROWS_LIST_WRAP = CommonCodeStyleSettings.DO_NOT_WRAP; + getSettings(JavaLanguage.INSTANCE).ALIGN_MULTILINE_THROWS_LIST = false; + + doTextTest("class Foo {\n" + + " void methodFoo() throws IOException, InvalidOperationException {\n" + + " }\n" + + "}", + "class Foo {\n" + + " void methodFoo()\n" + + " throws IOException, InvalidOperationException {\n" + + " }\n" + + "}"); + + getSettings(JavaLanguage.INSTANCE).THROWS_KEYWORD_WRAP = CommonCodeStyleSettings.DO_NOT_WRAP; + getSettings(JavaLanguage.INSTANCE).THROWS_LIST_WRAP = CommonCodeStyleSettings.WRAP_AS_NEEDED; + getSettings(JavaLanguage.INSTANCE).ALIGN_MULTILINE_THROWS_LIST = false; + + doTextTest("class Foo {\n" + + " void methodFoo() throws IOException, InvalidOperationException {\n" + + " }\n" + + "}", + "class Foo {\n" + + " void methodFoo() throws\n" + + " IOException,\n" + + " InvalidOperationException {\n" + + " }\n" + + "}"); + + } +} diff --git a/java/java-tests/testSrc/com/intellij/psi/formatter/performance/JavaFormatterPerformanceTest.java b/java/java-tests/testSrc/com/intellij/psi/formatter/performance/JavaFormatterPerformanceTest.java new file mode 100644 index 000000000000..42180ea69940 --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/psi/formatter/performance/JavaFormatterPerformanceTest.java @@ -0,0 +1,133 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.psi.formatter.performance; + +import com.intellij.formatting.FormatterEx; +import com.intellij.formatting.FormatterImpl; +import com.intellij.formatting.FormattingModel; +import com.intellij.lang.ASTNode; +import com.intellij.lang.LanguageFormatting; +import com.intellij.lang.java.JavaLanguage; +import com.intellij.openapi.application.ex.PathManagerEx; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.PsiFile; +import com.intellij.psi.codeStyle.CodeStyleSettings; +import com.intellij.psi.codeStyle.CommonCodeStyleSettings; +import com.intellij.psi.formatter.FormatterTestCase; +import com.intellij.psi.formatter.java.JavaFormatterTestCase; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.testFramework.LightPlatformTestCase; +import com.intellij.testFramework.PlatformTestUtil; + +import java.io.File; + +/** + * @author Maxim.Mossienko + * @since Jan 26, 2007 + */ +public class JavaFormatterPerformanceTest extends JavaFormatterTestCase { + private static final String BASE_PATH= "psi/formatter/java"; + + @Override + protected String getBasePath() { + return BASE_PATH; + } + + public void testPaymentManager() throws Exception { + final FileEditorManager editorManager = FileEditorManager.getInstance(LightPlatformTestCase.getProject()); + try { + getSettings().getCommonSettings(JavaLanguage.INSTANCE).KEEP_LINE_BREAKS = false; + doTest(); + } finally { + getSettings().getCommonSettings(JavaLanguage.INSTANCE).KEEP_LINE_BREAKS = true; + editorManager.closeFile(editorManager.getSelectedFiles()[0]); + } + } + + public void testPerformance() throws Exception { + final String name = getTestName(true) + ".java"; + final String text = loadFile(name); + final PsiFile file = LightPlatformTestCase.createFile(name, text); + + transformAllChildren(SourceTreeToPsiMap.psiElementToTree(file)); + final CodeStyleSettings settings = new CodeStyleSettings(); + PlatformTestUtil.startPerformanceTest("java formatting",1000, () -> { + final FormattingModel model = LanguageFormatting.INSTANCE.forContext(file).createModel(file, settings); + ((FormatterImpl)FormatterEx.getInstanceEx()).formatWithoutModifications(model.getDocumentModel(), model.getRootBlock(), settings, + settings.getIndentOptions(StdFileTypes.JAVA), + file.getTextRange()); + }).cpuBound().assertTiming(); + } + + public void testPerformance2() throws Exception { + final CodeStyleSettings settings = getSettings(); + settings.setDefaultRightMargin(120); + PlatformTestUtil.startPerformanceTest(getTestName(false), 4000, () -> { + try { + doTest(); + } + catch (Exception e) { + throw new RuntimeException(e); + } + }).cpuBound().assertTiming(); + } + + public void testPerformance3() throws Exception { + PlatformTestUtil.startPerformanceTest(getTestName(false), 3900, () -> { + final CommonCodeStyleSettings settings = FormatterTestCase.getSettings(JavaLanguage.INSTANCE); + settings.RIGHT_MARGIN = 80; + settings.METHOD_PARAMETERS_WRAP = 1; + final CommonCodeStyleSettings.IndentOptions indentOptions = settings.getRootSettings().getIndentOptions(StdFileTypes.JAVA); + indentOptions.USE_TAB_CHARACTER = true; + indentOptions.TAB_SIZE = 4; + settings.SPACE_BEFORE_METHOD_PARENTHESES = true; + settings.SPACE_BEFORE_METHOD_CALL_PARENTHESES = true; + settings.ALIGN_MULTILINE_PARAMETERS = false; + try { + doTest(); + } + catch (Exception e) { + throw new RuntimeException(e); + } + }).cpuBound().assertTiming(); + } + + private static void transformAllChildren(final ASTNode file) { + for (ASTNode child = file.getFirstChildNode(); child != null; child = child.getTreeNext()) { + transformAllChildren(child); + } + } + + private static String loadFile(String name) throws Exception { + String fullName = PathManagerEx.getTestDataPath() + "/" + BASE_PATH + File.separatorChar + name; + String text = FileUtil.loadFile(new File(fullName)); + text = StringUtil.convertLineSeparators(text); + return text; + } + + @Override + protected boolean doCheckDocumentUpdate() { + return true; + } + + @Override + protected String getFileExtension() { + return "java"; + } +} diff --git a/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaSmartReformatPerformanceTest.java b/java/java-tests/testSrc/com/intellij/psi/formatter/performance/JavaSmartReformatPerformanceTest.java similarity index 96% rename from java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaSmartReformatPerformanceTest.java rename to java/java-tests/testSrc/com/intellij/psi/formatter/performance/JavaSmartReformatPerformanceTest.java index c1988677394c..761d69ba46ee 100644 --- a/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaSmartReformatPerformanceTest.java +++ b/java/java-tests/testSrc/com/intellij/psi/formatter/performance/JavaSmartReformatPerformanceTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.psi.formatter.java; +package com.intellij.psi.formatter.performance; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.command.CommandProcessor; @@ -22,6 +22,7 @@ import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiFile; import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.formatter.java.AbstractJavaFormatterTest; import com.intellij.testFramework.PlatformTestUtil; import com.intellij.util.ThrowableRunnable; import com.intellij.util.containers.ContainerUtil; diff --git a/java/typeMigration/src/com/intellij/refactoring/typeMigration/inspections/GuavaInspection.java b/java/typeMigration/src/com/intellij/refactoring/typeMigration/inspections/GuavaInspection.java index cbb6045eac4d..119156b17b79 100644 --- a/java/typeMigration/src/com/intellij/refactoring/typeMigration/inspections/GuavaInspection.java +++ b/java/typeMigration/src/com/intellij/refactoring/typeMigration/inspections/GuavaInspection.java @@ -128,7 +128,8 @@ public class GuavaInspection extends BaseJavaBatchLocalInspectionTool { final PsiElement maybeLocalVariable = chain.getParent(); if (maybeLocalVariable instanceof PsiLocalVariable) { final PsiClass aClass = PsiUtil.resolveClassInType(chain.getType()); - if (aClass != null && GuavaFluentIterableConversionRule.FLUENT_ITERABLE.equals(aClass.getQualifiedName())) { + if (aClass != null && (GuavaFluentIterableConversionRule.FLUENT_ITERABLE.equals(aClass.getQualifiedName()) || + GuavaOptionalConversionRule.GUAVA_OPTIONAL.equals(aClass.getQualifiedName()))) { return; } } diff --git a/java/typeMigration/src/com/intellij/refactoring/typeMigration/rules/guava/GuavaFluentIterableConversionRule.java b/java/typeMigration/src/com/intellij/refactoring/typeMigration/rules/guava/GuavaFluentIterableConversionRule.java index 42b022dbd692..f0ea318356f1 100644 --- a/java/typeMigration/src/com/intellij/refactoring/typeMigration/rules/guava/GuavaFluentIterableConversionRule.java +++ b/java/typeMigration/src/com/intellij/refactoring/typeMigration/rules/guava/GuavaFluentIterableConversionRule.java @@ -185,7 +185,7 @@ public class GuavaFluentIterableConversionRule extends BaseGuavaTypeConversionRu } @Nullable - private static GuavaChainedConversionDescriptor buildCompoundDescriptor(PsiMethodCallExpression expression, + public static GuavaChainedConversionDescriptor buildCompoundDescriptor(PsiMethodCallExpression expression, PsiType to, TypeMigrationLabeler labeler) { List methodDescriptors = new SmartList(); @@ -229,15 +229,12 @@ public class GuavaFluentIterableConversionRule extends BaseGuavaTypeConversionRu if (qualifier instanceof PsiMethodCallExpression) { current = (PsiMethodCallExpression)qualifier; } - else if (qualifier instanceof PsiReferenceExpression) { + else if (method.hasModifierProperty(PsiModifier.STATIC)) { if (!CHAIN_HEAD_METHODS.contains(methodName)) { return null; } - final PsiElement maybeClass = ((PsiReferenceExpression)qualifier).resolve(); - if (!(maybeClass instanceof PsiClass)) { - return null; - } - if (!FLUENT_ITERABLE.equals(((PsiClass)maybeClass).getQualifiedName())) { + final PsiClass aClass = method.getContainingClass(); + if (aClass == null || !FLUENT_ITERABLE.equals(aClass.getQualifiedName())) { return null; } break; diff --git a/java/typeMigration/src/com/intellij/refactoring/typeMigration/rules/guava/GuavaOptionalConversionRule.java b/java/typeMigration/src/com/intellij/refactoring/typeMigration/rules/guava/GuavaOptionalConversionRule.java index 3ab15954e179..1559ae812f78 100644 --- a/java/typeMigration/src/com/intellij/refactoring/typeMigration/rules/guava/GuavaOptionalConversionRule.java +++ b/java/typeMigration/src/com/intellij/refactoring/typeMigration/rules/guava/GuavaOptionalConversionRule.java @@ -78,7 +78,14 @@ public class GuavaOptionalConversionRule extends BaseGuavaTypeConversionRule { } return null; } - return null; + if (!(context instanceof PsiMethodCallExpression)) { + return null; + } + final PsiClass aClass = method.getContainingClass(); + if (aClass == null || !GuavaFluentIterableConversionRule.FLUENT_ITERABLE.equals(aClass.getQualifiedName())) { + return null; + } + return GuavaFluentIterableConversionRule.buildCompoundDescriptor((PsiMethodCallExpression) context, to, labeler); } private PsiClass getParameterClass(PsiMethod method) { diff --git a/java/typeMigration/test/com/intellij/codeInsight/inspections/GuavaInspectionTest.java b/java/typeMigration/test/com/intellij/codeInsight/inspections/GuavaInspectionTest.java index 8fb82bdab029..9d334c1e7f6b 100644 --- a/java/typeMigration/test/com/intellij/codeInsight/inspections/GuavaInspectionTest.java +++ b/java/typeMigration/test/com/intellij/codeInsight/inspections/GuavaInspectionTest.java @@ -57,6 +57,10 @@ public class GuavaInspectionTest extends JavaCodeInsightFixtureTestCase { doTest(); } + public void testOptional3() { + doTest(); + } + public void testSimpleFluentIterable() { doTest(); } diff --git a/java/typeMigration/testData/inspections/guava/optional3.java b/java/typeMigration/testData/inspections/guava/optional3.java new file mode 100644 index 000000000000..2c679a1af7fb --- /dev/null +++ b/java/typeMigration/testData/inspections/guava/optional3.java @@ -0,0 +1,19 @@ +import com.google.common.base.Optional; +import com.google.common.base.Predicate; +import com.google.common.collect.FluentIterable; + +import java.util.ArrayList; + +public class Main7 { + + public static void main(String[] args) { + Optional image = FluentIterable.from(new ArrayList()).firstMatch(getPredicate()); + if (image.isPresent()) { + System.out.println(image.get()); + } + } + + static Predicate getPredicate() { + return null; + } +} \ No newline at end of file diff --git a/java/typeMigration/testData/inspections/guava/optional3_after.java b/java/typeMigration/testData/inspections/guava/optional3_after.java new file mode 100644 index 000000000000..db95e659f5ce --- /dev/null +++ b/java/typeMigration/testData/inspections/guava/optional3_after.java @@ -0,0 +1,18 @@ +import com.google.common.base.Predicate; + +import java.util.ArrayList; +import java.util.Optional; + +public class Main7 { + + public static void main(String[] args) { + Optional image = new ArrayList().stream().filter(getPredicate()::apply).findFirst(); + if (image.isPresent()) { + System.out.println(image.get()); + } + } + + static Predicate getPredicate() { + return null; + } +} \ No newline at end of file diff --git a/lib/coverage-agent.jar b/lib/coverage-agent.jar index c352e58e4a84..bae7d09083a4 100755 Binary files a/lib/coverage-agent.jar and b/lib/coverage-agent.jar differ diff --git a/lib/coverage-instrumenter.jar b/lib/coverage-instrumenter.jar index 6c15e07ff116..b6226f70fa01 100755 Binary files a/lib/coverage-instrumenter.jar and b/lib/coverage-instrumenter.jar differ diff --git a/lib/coverage-util.jar b/lib/coverage-util.jar index 490ec4bf3453..00135249e482 100755 Binary files a/lib/coverage-util.jar and b/lib/coverage-util.jar differ diff --git a/lib/src/coverage-src.zip b/lib/src/coverage-src.zip index 115a3247e168..8c6424c7bd59 100755 Binary files a/lib/src/coverage-src.zip and b/lib/src/coverage-src.zip differ diff --git a/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/HighlightInfo.java b/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/HighlightInfo.java index 0320130f78e6..fb76b4b6b16a 100644 --- a/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/HighlightInfo.java +++ b/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/HighlightInfo.java @@ -741,13 +741,13 @@ public class HighlightInfo implements Segment { this(action, options, displayName, icon, null, null, null); } - private IntentionActionDescriptor(@NotNull IntentionAction action, - @Nullable final List options, - @Nullable final String displayName, - @Nullable Icon icon, - @Nullable HighlightDisplayKey key, - @Nullable ProblemGroup problemGroup, - @Nullable HighlightSeverity severity) { + public IntentionActionDescriptor(@NotNull IntentionAction action, + @Nullable final List options, + @Nullable final String displayName, + @Nullable Icon icon, + @Nullable HighlightDisplayKey key, + @Nullable ProblemGroup problemGroup, + @Nullable HighlightSeverity severity) { myAction = action; myOptions = options; myDisplayName = displayName; diff --git a/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/HighlightInfoType.java b/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/HighlightInfoType.java index 8ea97bd0835c..ade2f5040ba4 100644 --- a/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/HighlightInfoType.java +++ b/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/HighlightInfoType.java @@ -69,6 +69,7 @@ public interface HighlightInfoType { HighlightInfoType LOCAL_VARIABLE = new HighlightInfoTypeImpl(SYMBOL_TYPE_SEVERITY, CodeInsightColors.LOCAL_VARIABLE_ATTRIBUTES); HighlightInfoType INSTANCE_FIELD = new HighlightInfoTypeImpl(SYMBOL_TYPE_SEVERITY, CodeInsightColors.INSTANCE_FIELD_ATTRIBUTES); + HighlightInfoType INSTANCE_FINAL_FIELD = new HighlightInfoTypeImpl(SYMBOL_TYPE_SEVERITY, CodeInsightColors.INSTANCE_FINAL_FIELD_ATTRIBUTES); HighlightInfoType STATIC_FIELD = new HighlightInfoTypeImpl(SYMBOL_TYPE_SEVERITY, CodeInsightColors.STATIC_FIELD_ATTRIBUTES); HighlightInfoType STATIC_FINAL_FIELD = new HighlightInfoTypeImpl(SYMBOL_TYPE_SEVERITY, CodeInsightColors.STATIC_FINAL_FIELD_ATTRIBUTES); HighlightInfoType PARAMETER = new HighlightInfoTypeImpl(SYMBOL_TYPE_SEVERITY, CodeInsightColors.PARAMETER_ATTRIBUTES); diff --git a/platform/analysis-impl/src/com/intellij/codeInspection/ProblemDescriptorUtil.java b/platform/analysis-impl/src/com/intellij/codeInspection/ProblemDescriptorUtil.java index 93f40c41a3d9..47eb271344ea 100644 --- a/platform/analysis-impl/src/com/intellij/codeInspection/ProblemDescriptorUtil.java +++ b/platform/analysis-impl/src/com/intellij/codeInspection/ProblemDescriptorUtil.java @@ -140,6 +140,19 @@ public class ProblemDescriptorUtil { @NotNull HighlightSeverity severity, @NotNull SeverityRegistrar severityRegistrar) { final ProblemHighlightType highlightType = problemDescriptor.getHighlightType(); + final HighlightInfoType highlightInfoType = getHighlightInfoType(highlightType, severity, severityRegistrar); + if (highlightInfoType == HighlightSeverity.INFORMATION) { + final TextAttributesKey attributes = ((ProblemDescriptorBase)problemDescriptor).getEnforcedTextAttributes(); + if (attributes != null) { + return new HighlightInfoType.HighlightInfoTypeImpl(HighlightSeverity.INFORMATION, attributes); + } + } + return highlightInfoType; + } + + public static HighlightInfoType getHighlightInfoType(@NotNull ProblemHighlightType highlightType, + @NotNull HighlightSeverity severity, + @NotNull SeverityRegistrar severityRegistrar) { switch (highlightType) { case GENERIC_ERROR_OR_WARNING: return severityRegistrar.getHighlightInfoTypeBySeverity(severity); @@ -164,10 +177,6 @@ public class ProblemDescriptorUtil { case GENERIC_ERROR: return HighlightInfoType.ERROR; case INFORMATION: - final TextAttributesKey attributes = ((ProblemDescriptorBase)problemDescriptor).getEnforcedTextAttributes(); - if (attributes != null) { - return new HighlightInfoType.HighlightInfoTypeImpl(HighlightSeverity.INFORMATION, attributes); - } return HighlightInfoType.INFORMATION; } throw new RuntimeException("Cannot map " + highlightType); diff --git a/platform/built-in-server/src/org/jetbrains/io/fastCgi/FastCgiService.kt b/platform/built-in-server/src/org/jetbrains/io/fastCgi/FastCgiService.kt index e7d54e0210f7..63989e44549f 100644 --- a/platform/built-in-server/src/org/jetbrains/io/fastCgi/FastCgiService.kt +++ b/platform/built-in-server/src/org/jetbrains/io/fastCgi/FastCgiService.kt @@ -15,7 +15,6 @@ */ package org.jetbrains.io.fastCgi -import com.intellij.execution.process.OSProcessHandler import com.intellij.openapi.diagnostic.Logger import com.intellij.openapi.project.Project import com.intellij.util.Consumer @@ -144,11 +143,7 @@ public abstract class FastCgiService(project: Project) : SingleConnectionNetServ } else { processHandler.get() - .done(object : Consumer { - override fun consume(osProcessHandler: OSProcessHandler) { - fastCgiRequest.writeToServerChannel(notEmptyContent, processChannel!!) - } - }) + .done { fastCgiRequest.writeToServerChannel(notEmptyContent, processChannel!!) } .rejected { Promise.logError(LOG, it) handleError(fastCgiRequest, notEmptyContent) diff --git a/platform/configuration-store-impl/src/DefaultProjectStoreImpl.kt b/platform/configuration-store-impl/src/DefaultProjectStoreImpl.kt index 86134104607c..66dc978daa76 100644 --- a/platform/configuration-store-impl/src/DefaultProjectStoreImpl.kt +++ b/platform/configuration-store-impl/src/DefaultProjectStoreImpl.kt @@ -66,12 +66,9 @@ internal class DefaultProjectStoreImpl(override val project: ProjectImpl, privat override fun getStateStorage(storageSpec: Storage) = storage - override fun startExternalization(): StateStorageManager.ExternalizationSession? { - val externalizationSession = storage.startExternalization() - return if (externalizationSession == null) null else MyExternalizationSession(externalizationSession) - } + override fun startExternalization() = storage.startExternalization()?.let { MyExternalizationSession(it) } - override fun expandMacros(file: String) = throw UnsupportedOperationException("Method expandMacros not implemented in " + javaClass) + override fun expandMacros(file: String) = throw UnsupportedOperationException() override fun getOldStorage(component: Any, componentName: String, operation: StateStorageOperation) = storage } @@ -104,7 +101,7 @@ internal class DefaultProjectStoreImpl(override val project: ProjectImpl, privat // ExportSettingsAction checks only "State" annotation presence, but doesn't require PersistentStateComponent implementation, so, we can just specify annotation @State(name = "ProjectManager", storages = arrayOf(Storage(file = DefaultProjectStoreImpl.FILE_SPEC))) private class DefaultProjectExportableAndSaveTrigger : SettingsSavingComponent { - @Volatile var project: Project? = null; + @Volatile var project: Project? = null override fun save() { // we must trigger save diff --git a/platform/core-api/src/com/intellij/openapi/editor/colors/CodeInsightColors.java b/platform/core-api/src/com/intellij/openapi/editor/colors/CodeInsightColors.java index 26c41d67d105..ef11feb0e627 100644 --- a/platform/core-api/src/com/intellij/openapi/editor/colors/CodeInsightColors.java +++ b/platform/core-api/src/com/intellij/openapi/editor/colors/CodeInsightColors.java @@ -37,6 +37,7 @@ public interface CodeInsightColors { TextAttributesKey REASSIGNED_PARAMETER_ATTRIBUTES = TextAttributesKey.createTextAttributesKey("REASSIGNED_PARAMETER_ATTRIBUTES", PARAMETER_ATTRIBUTES); TextAttributesKey IMPLICIT_ANONYMOUS_CLASS_PARAMETER_ATTRIBUTES = TextAttributesKey.createTextAttributesKey("IMPLICIT_ANONYMOUS_CLASS_PARAMETER_ATTRIBUTES"); TextAttributesKey INSTANCE_FIELD_ATTRIBUTES = TextAttributesKey.createTextAttributesKey("INSTANCE_FIELD_ATTRIBUTES"); + TextAttributesKey INSTANCE_FINAL_FIELD_ATTRIBUTES = TextAttributesKey.createTextAttributesKey("INSTANCE_FINAL_FIELD_ATTRIBUTES", INSTANCE_FIELD_ATTRIBUTES); TextAttributesKey STATIC_FIELD_ATTRIBUTES = TextAttributesKey.createTextAttributesKey("STATIC_FIELD_ATTRIBUTES"); TextAttributesKey STATIC_FINAL_FIELD_ATTRIBUTES = TextAttributesKey.createTextAttributesKey("STATIC_FINAL_FIELD_ATTRIBUTES", STATIC_FIELD_ATTRIBUTES); TextAttributesKey CLASS_NAME_ATTRIBUTES = TextAttributesKey.createTextAttributesKey("CLASS_NAME_ATTRIBUTES"); diff --git a/platform/core-api/src/com/intellij/psi/impl/ElementBase.java b/platform/core-api/src/com/intellij/psi/impl/ElementBase.java index fb982fbadcbf..b2f5a7284eb4 100644 --- a/platform/core-api/src/com/intellij/psi/impl/ElementBase.java +++ b/platform/core-api/src/com/intellij/psi/impl/ElementBase.java @@ -104,15 +104,14 @@ public abstract class ElementBase extends UserDataHolderBase implements Iconable @Nullable private Icon computeIcon(@Iconable.IconFlags int flags) { PsiElement psiElement = (PsiElement)this; - PsiFile psiFile = psiElement.getContainingFile(); - if (psiFile == null || !psiFile.isValid()) return null; + if (!psiElement.isValid()) return null; if (Registry.is("psi.deferIconLoading")) { Icon baseIcon = LastComputedIcon.get(psiElement, flags); if (baseIcon == null) { baseIcon = computeBaseIcon(flags); } - return IconDeferrer.getInstance().defer(baseIcon, new ElementIconRequest(psiElement, psiFile.getProject(), flags), ICON_COMPUTE); + return IconDeferrer.getInstance().defer(baseIcon, new ElementIconRequest(psiElement, psiElement.getProject(), flags), ICON_COMPUTE); } return computeIconNow(psiElement, flags); diff --git a/platform/core-api/src/org/jetbrains/concurrency/Promise.java b/platform/core-api/src/org/jetbrains/concurrency/Promise.java index 2ce7c001d1d1..2d578c354523 100644 --- a/platform/core-api/src/org/jetbrains/concurrency/Promise.java +++ b/platform/core-api/src/org/jetbrains/concurrency/Promise.java @@ -67,7 +67,7 @@ public abstract class Promise { } @NotNull - public static Promise all(@NotNull Collection> promises) { + public static Promise all(@NotNull Collection> promises) { return all(promises, null); } diff --git a/platform/core-impl/src/com/intellij/openapi/editor/impl/ManualRangeMarker.java b/platform/core-impl/src/com/intellij/openapi/editor/impl/ManualRangeMarker.java index ac7777c49cd1..2e4e11c88c46 100644 --- a/platform/core-impl/src/com/intellij/openapi/editor/impl/ManualRangeMarker.java +++ b/platform/core-impl/src/com/intellij/openapi/editor/impl/ManualRangeMarker.java @@ -16,6 +16,7 @@ package com.intellij.openapi.editor.impl; import com.intellij.openapi.editor.event.DocumentEvent; +import com.intellij.openapi.editor.impl.event.DocumentEventImpl; import com.intellij.openapi.editor.impl.event.RetargetRangeMarkers; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.ProperTextRange; @@ -23,47 +24,49 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; /** - * A range marker that has to be manually updated with {@link #getUpdatedRange(DocumentEvent)}. + * A range marker that has to be manually updated with {@link #getUpdatedRange(DocumentEvent, FrozenDocument)}. * Can hold PSI-based range and be updated when the document is committed. */ public class ManualRangeMarker { private final ProperTextRange myRange; private final boolean myGreedyLeft; private final boolean myGreedyRight; + private final boolean mySurviveOnExternalChange; private final PersistentRangeMarker.LinesCols myLinesCols; - public ManualRangeMarker(@NotNull FrozenDocument document, @NotNull ProperTextRange range, boolean greedyLeft, boolean greedyRight, boolean surviveOnExternalChange) { - this(range, greedyLeft, greedyRight, surviveOnExternalChange ? PersistentRangeMarker.storeLinesAndCols(range, document) : null); - } - - private ManualRangeMarker(@NotNull ProperTextRange range, + public ManualRangeMarker(@NotNull ProperTextRange range, boolean greedyLeft, boolean greedyRight, + boolean surviveOnExternalChange, @Nullable PersistentRangeMarker.LinesCols linesCols) { myRange = range; myGreedyLeft = greedyLeft; myGreedyRight = greedyRight; + mySurviveOnExternalChange = surviveOnExternalChange; myLinesCols = linesCols; } @Nullable - public ManualRangeMarker getUpdatedRange(@NotNull DocumentEvent event) { + public ManualRangeMarker getUpdatedRange(@NotNull DocumentEvent event, @NotNull FrozenDocument documentBefore) { if (event instanceof RetargetRangeMarkers) { int start = ((RetargetRangeMarkers)event).getStartOffset(); if (myRange.getStartOffset() >= start && myRange.getEndOffset() <= ((RetargetRangeMarkers)event).getEndOffset()) { ProperTextRange range = myRange.shiftRight(((RetargetRangeMarkers)event).getMoveDestinationOffset() - start); - return new ManualRangeMarker(range, myGreedyLeft, myGreedyRight, myLinesCols == null ? null : PersistentRangeMarker.storeLinesAndCols(range, event.getDocument())); + return new ManualRangeMarker(range, myGreedyLeft, myGreedyRight, mySurviveOnExternalChange, null); } } - if (myLinesCols != null) { - Pair pair = PersistentRangeMarker - .applyChange(event, myRange, myRange.getStartOffset(), myRange.getEndOffset(), myGreedyLeft, myGreedyRight, myLinesCols); - return pair == null ? null : new ManualRangeMarker(pair.first, myGreedyLeft, myGreedyRight, pair.second); + if (mySurviveOnExternalChange && PersistentRangeMarkerUtil.shouldTranslateViaDiff(event, myRange)) { + PersistentRangeMarker.LinesCols linesCols = myLinesCols != null ? myLinesCols + : PersistentRangeMarker.storeLinesAndCols(myRange, documentBefore); + Pair pair = PersistentRangeMarker.translateViaDiff((DocumentEventImpl)event, linesCols); + if (pair != null) { + return new ManualRangeMarker(pair.first, myGreedyLeft, myGreedyRight, true, pair.second); + } } - + ProperTextRange range = RangeMarkerImpl.applyChange(event, myRange.getStartOffset(), myRange.getEndOffset(), myGreedyLeft, myGreedyRight); - return range == null ? null : new ManualRangeMarker(range, myGreedyLeft, myGreedyRight, null); + return range == null ? null : new ManualRangeMarker(range, myGreedyLeft, myGreedyRight, mySurviveOnExternalChange, null); } @NotNull diff --git a/platform/core-impl/src/com/intellij/openapi/editor/impl/PersistentRangeMarker.java b/platform/core-impl/src/com/intellij/openapi/editor/impl/PersistentRangeMarker.java index 62a7e063e58e..c401dbd17e58 100644 --- a/platform/core-impl/src/com/intellij/openapi/editor/impl/PersistentRangeMarker.java +++ b/platform/core-impl/src/com/intellij/openapi/editor/impl/PersistentRangeMarker.java @@ -79,7 +79,7 @@ class PersistentRangeMarker extends RangeMarkerImpl { } @Nullable - private static Pair translateViaDiff(final DocumentEventImpl event, LinesCols linesCols) { + static Pair translateViaDiff(final DocumentEventImpl event, LinesCols linesCols) { try { int myStartLine = event.translateLineViaDiffStrict(linesCols.myStartLine); Document document = event.getDocument(); @@ -98,6 +98,13 @@ class PersistentRangeMarker extends RangeMarkerImpl { int end = document.getLineStartOffset(myEndLine) + linesCols.myEndColumn; if (end > document.getTextLength() || end < start) return null; + if (end > event.getDocument().getTextLength() || + myEndLine < myStartLine || + myStartLine == myEndLine && linesCols.myEndColumn < linesCols.myStartColumn || + event.getDocument().getLineCount() < myEndLine) { + return null; + } + return Pair.create(new ProperTextRange(start, end), new LinesCols(myStartLine, linesCols.myStartColumn, myEndLine, linesCols.myEndColumn)); } catch (FilesTooBigForDiffException e) { @@ -122,7 +129,7 @@ class PersistentRangeMarker extends RangeMarkerImpl { } @Nullable - static Pair applyChange(DocumentEvent event, Segment range, int intervalStart, int intervalEnd, boolean greedyLeft, boolean greedyRight, LinesCols linesCols) { + private static Pair applyChange(DocumentEvent event, Segment range, int intervalStart, int intervalEnd, boolean greedyLeft, boolean greedyRight, LinesCols linesCols) { final boolean shouldTranslateViaDiff = PersistentRangeMarkerUtil.shouldTranslateViaDiff(event, range); Pair translated = null; if (shouldTranslateViaDiff) { @@ -137,13 +144,6 @@ class PersistentRangeMarker extends RangeMarkerImpl { translated = Pair.create(fallback, lc); } - if (translated.first.getEndOffset() > event.getDocument().getTextLength() || - translated.second.myEndLine < translated.second.myStartLine || - translated.second.myStartLine == translated.second.myEndLine && translated.second.myEndColumn < translated.second.myStartColumn || - event.getDocument().getLineCount() < translated.second.myEndLine) { - return null; - } - return translated; } diff --git a/platform/core-impl/src/com/intellij/psi/impl/smartPointers/MarkerCache.java b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/MarkerCache.java index bb2cd46450b4..02678e34f0f4 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/smartPointers/MarkerCache.java +++ b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/MarkerCache.java @@ -71,7 +71,7 @@ class MarkerCache { long key = info.markerCacheKey(); if (range != null && key != 0) { boolean forInjected = info.isForInjected(); - answer.put(key, new ManualRangeMarker(frozen, range, forInjected, forInjected, !forInjected)); + answer.put(key, new ManualRangeMarker(range, forInjected, forInjected, !forInjected, null)); } } frozen = applyEvents(frozen, events, answer); @@ -86,6 +86,7 @@ class MarkerCache { @NotNull List events, final TLongObjectHashMap map) { for (DocumentEvent event : events) { + final FrozenDocument before = frozen; final DocumentEvent corrected; if ((event instanceof RetargetRangeMarkers)) { RetargetRangeMarkers retarget = (RetargetRangeMarkers)event; @@ -101,7 +102,7 @@ class MarkerCache { map.transformValues(new TObjectFunction() { @Override public ManualRangeMarker execute(ManualRangeMarker currentRange) { - return currentRange == null ? null : currentRange.getUpdatedRange(corrected); + return currentRange == null ? null : currentRange.getUpdatedRange(corrected, before); } }); } diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ContentRootDataService.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ContentRootDataService.java index d0e73a2878f8..715b845d2ff4 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ContentRootDataService.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ContentRootDataService.java @@ -126,7 +126,7 @@ public class ContentRootDataService extends AbstractProjectDataService values.each { folder(type: key, path: "$rootPath/$it") } } + } } } } } + + DataNode projectNodeInitial = projectRootBuilder() + + contentRoots[(EXCLUDED)].remove(0) + contentRoots[(EXCLUDED)].add("newExclDir") + + DataNode projectNodeRefreshed = projectRootBuilder() + applyProjectState([projectNodeInitial, projectNodeRefreshed]) + + def modelsProvider = new IdeModelsProviderImpl(project); + def module = modelsProvider.findIdeModule('module') + assertNotNull(module) + def folders = [] + for (OrderEntry entry : modelsProvider.getOrderEntries(module)) { + if (entry instanceof ModuleSourceOrderEntry) { + def contentEntry = (entry as ModuleSourceOrderEntry).getRootModel().getContentEntries().first() + folders = contentEntry.excludeFolders.collect {new File(it.url).name} + } + } + assertEquals(new HashSet<>(folders), new HashSet<>([".gradle", "build", "newExclDir"])); + } } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/IntentionListStep.java b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/IntentionListStep.java index 85bf449092e2..e507c654eca2 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/IntentionListStep.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/IntentionListStep.java @@ -114,65 +114,74 @@ public class IntentionListStep implements ListPopupStep newDescriptors, @NotNull Set cachedActions, boolean callUpdate) { - final int caretOffset = myEditor == null ? 0 : myEditor.getCaretModel().getOffset(); - final int fileOffset = caretOffset > 0 && caretOffset == myFile.getTextLength() ? caretOffset - 1 : caretOffset; - PsiElement element; - final PsiElement hostElement; - if (myFile instanceof PsiCompiledElement) { - hostElement = element = myFile; - - } - else if (myEditor != null && PsiDocumentManager.getInstance(myProject).isUncommited(myEditor.getDocument())) { - //??? - FileViewProvider viewProvider = myFile.getViewProvider(); - hostElement = element = viewProvider.findElementAt(fileOffset, viewProvider.getBaseLanguage()); - } - else { - hostElement = myFile.getViewProvider().findElementAt(fileOffset, myFile.getLanguage()); - element = InjectedLanguageUtil.findElementAtNoCommit(myFile, fileOffset); - } - PsiFile injectedFile; - Editor injectedEditor; - if (element == null || element == hostElement) { - injectedFile = myFile; - injectedEditor = myEditor; - } - else { - injectedFile = element.getContainingFile(); - injectedEditor = myEditor == null ? null : InjectedLanguageUtil.getInjectedEditorForInjectedFile(myEditor, injectedFile); - } - boolean changed = false; - for (Iterator iterator = cachedActions.iterator(); iterator.hasNext();) { - IntentionActionWithTextCaching cachedAction = iterator.next(); - IntentionAction action = cachedAction.getAction(); - if (myEditor != null && !ShowIntentionActionsHandler.availableFor(myFile, myEditor, action) - && (hostElement == element || element != null && !ShowIntentionActionsHandler.availableFor(injectedFile, injectedEditor, action))) { - iterator.remove(); - changed = true; + if (myEditor == null) { + LOG.assertTrue(!callUpdate); + for (HighlightInfo.IntentionActionDescriptor descriptor : newDescriptors) { + changed |= cachedActions.add(wrapAction(descriptor, myFile, myFile, null)); + } + } else { + final int caretOffset = myEditor.getCaretModel().getOffset(); + final int fileOffset = caretOffset > 0 && caretOffset == myFile.getTextLength() ? caretOffset - 1 : caretOffset; + PsiElement element; + final PsiElement hostElement; + if (myFile instanceof PsiCompiledElement) { + hostElement = element = myFile; + } + else if (PsiDocumentManager.getInstance(myProject).isUncommited(myEditor.getDocument())) { + //??? + FileViewProvider viewProvider = myFile.getViewProvider(); + hostElement = element = viewProvider.findElementAt(fileOffset, viewProvider.getBaseLanguage()); + } + else { + hostElement = myFile.getViewProvider().findElementAt(fileOffset, myFile.getLanguage()); + element = InjectedLanguageUtil.findElementAtNoCommit(myFile, fileOffset); + } + PsiFile injectedFile; + Editor injectedEditor; + if (element == null || element == hostElement) { + injectedFile = myFile; + injectedEditor = myEditor; + } + else { + injectedFile = element.getContainingFile(); + injectedEditor = InjectedLanguageUtil.getInjectedEditorForInjectedFile(myEditor, injectedFile); } - } - Set wrappedNew = new THashSet(newDescriptors.size(), ACTION_TEXT_AND_CLASS_EQUALS); - for (HighlightInfo.IntentionActionDescriptor descriptor : newDescriptors) { - final IntentionAction action = descriptor.getAction(); - if (element != null && element != hostElement && (!callUpdate || myEditor == null || ShowIntentionActionsHandler.availableFor(injectedFile, injectedEditor, action))) { - IntentionActionWithTextCaching cachedAction = wrapAction(descriptor, element, injectedFile, injectedEditor); - wrappedNew.add(cachedAction); - changed |= cachedActions.add(cachedAction); + for (Iterator iterator = cachedActions.iterator(); iterator.hasNext(); ) { + IntentionActionWithTextCaching cachedAction = iterator.next(); + IntentionAction action = cachedAction.getAction(); + if (!ShowIntentionActionsHandler.availableFor(myFile, myEditor, action) && + (hostElement == element || element != null && !ShowIntentionActionsHandler.availableFor(injectedFile, injectedEditor, action))) { + iterator.remove(); + changed = true; + } } - else if (hostElement != null && (!callUpdate || myEditor == null || ShowIntentionActionsHandler.availableFor(myFile, myEditor, action))) { - IntentionActionWithTextCaching cachedAction = wrapAction(descriptor, hostElement, myFile, myEditor); - wrappedNew.add(cachedAction); - changed |= cachedActions.add(cachedAction); + + Set wrappedNew = + new THashSet(newDescriptors.size(), ACTION_TEXT_AND_CLASS_EQUALS); + for (HighlightInfo.IntentionActionDescriptor descriptor : newDescriptors) { + final IntentionAction action = descriptor.getAction(); + if (element != null && + element != hostElement && + (!callUpdate || ShowIntentionActionsHandler.availableFor(injectedFile, injectedEditor, action))) { + IntentionActionWithTextCaching cachedAction = wrapAction(descriptor, element, injectedFile, injectedEditor); + wrappedNew.add(cachedAction); + changed |= cachedActions.add(cachedAction); + } + else if (hostElement != null && (!callUpdate || ShowIntentionActionsHandler.availableFor(myFile, myEditor, action))) { + IntentionActionWithTextCaching cachedAction = wrapAction(descriptor, hostElement, myFile, myEditor); + wrappedNew.add(cachedAction); + changed |= cachedActions.add(cachedAction); + } } - } - for (Iterator iterator = cachedActions.iterator(); iterator.hasNext();) { - IntentionActionWithTextCaching cachedAction = iterator.next(); - if (!wrappedNew.contains(cachedAction)) { - // action disappeared - iterator.remove(); - changed = true; + for (Iterator iterator = cachedActions.iterator(); iterator.hasNext(); ) { + IntentionActionWithTextCaching cachedAction = iterator.next(); + if (!wrappedNew.contains(cachedAction)) { + // action disappeared + iterator.remove(); + changed = true; + } } } return changed; @@ -180,10 +189,11 @@ public class IntentionListStep implements ListPopupStep options = descriptor.getOptions(element, containingEditor); if (options == null) return cachedAction; for (IntentionAction option : options) { @@ -253,12 +263,14 @@ public class IntentionListStep implements ListPopupStep pair = hostEditor != null && hostFile != null - ? chooseBetweenHostAndInjected(hostFile, hostEditor, new PairProcessor() { + final Pair pair = hostEditor != null ? chooseBetweenHostAndInjected(hostFile, hostEditor, new PairProcessor() { @Override public boolean process(PsiFile psiFile, Editor editor) { return availableFor(psiFile, editor, action); } - }) : Pair.create(null, null); + }) : Pair.create(hostFile, null); if (pair == null) return false; Runnable runnable = new Runnable() { diff --git a/platform/lang-impl/src/com/intellij/execution/startup/ProjectStartupConfigurable.java b/platform/lang-impl/src/com/intellij/execution/startup/ProjectStartupConfigurable.java index 750030eb1039..a6eefd49bd37 100644 --- a/platform/lang-impl/src/com/intellij/execution/startup/ProjectStartupConfigurable.java +++ b/platform/lang-impl/src/com/intellij/execution/startup/ProjectStartupConfigurable.java @@ -258,9 +258,9 @@ public class ProjectStartupConfigurable implements SearchableConfigurable, Confi } private void addConfiguration(RunnerAndConfigurationSettings configuration) { - if (!ProjectStartupRunner.canRun(DefaultRunExecutor.getRunExecutorInstance(), configuration)) { + if (!ProjectStartupRunner.canBeRun(configuration)) { final String message = "Can not add Run Configuration '" + configuration.getName() + "' to Startup Tasks," + - " since it can not be run with Run executor."; + " since it can not be started with 'Run' action."; final Balloon balloon = JBPopupFactory.getInstance() .createHtmlTextBalloonBuilder(message, MessageType.ERROR, null) .setHideOnClickOutside(true) @@ -290,7 +290,7 @@ public class ProjectStartupConfigurable implements SearchableConfigurable, Confi for (ChooseRunConfigurationPopup.ItemWrapper setting : allSettings) { if (setting.getValue() instanceof RunnerAndConfigurationSettings) { final RunnerAndConfigurationSettings settings = (RunnerAndConfigurationSettings)setting.getValue(); - if (!settings.isTemporary() && ProjectStartupRunner.canRun(executor, settings) && !existing.contains(settings)) { + if (!settings.isTemporary() && ProjectStartupRunner.canBeRun(settings) && !existing.contains(settings)) { wrappers.add(setting); } } diff --git a/platform/lang-impl/src/com/intellij/execution/startup/ProjectStartupRunner.java b/platform/lang-impl/src/com/intellij/execution/startup/ProjectStartupRunner.java index 4cf7083a4598..6222a392017f 100644 --- a/platform/lang-impl/src/com/intellij/execution/startup/ProjectStartupRunner.java +++ b/platform/lang-impl/src/com/intellij/execution/startup/ProjectStartupRunner.java @@ -89,7 +89,7 @@ public class ProjectStartupRunner implements StartupActivity { ApplicationManager.getApplication().invokeLater(new Runnable() { @Override public void run() { - if (! canRun(executor, configuration)) { + if (! canBeRun(configuration)) { ProjectStartupTaskManager.NOTIFICATION_GROUP .createNotification(ProjectStartupTaskManager.PREFIX + " Run Configuration '" + configuration.getName() + "' can not be started with Run executor.", MessageType.ERROR) .notify(project); @@ -104,7 +104,7 @@ public class ProjectStartupRunner implements StartupActivity { } } - public static boolean canRun(Executor executor, RunnerAndConfigurationSettings configuration) { - return RunnerRegistry.getInstance().getRunner(executor.getId(), configuration.getConfiguration()) != null; + public static boolean canBeRun(@NotNull RunnerAndConfigurationSettings configuration) { + return RunnerRegistry.getInstance().getRunner(DefaultRunExecutor.EXECUTOR_ID, configuration.getConfiguration()) != null; } } diff --git a/platform/lang-impl/src/com/intellij/find/actions/CompositeActiveComponent.java b/platform/lang-impl/src/com/intellij/find/actions/CompositeActiveComponent.java index 9c6a27946b94..182efc382e44 100644 --- a/platform/lang-impl/src/com/intellij/find/actions/CompositeActiveComponent.java +++ b/platform/lang-impl/src/com/intellij/find/actions/CompositeActiveComponent.java @@ -16,6 +16,7 @@ package com.intellij.find.actions; import com.intellij.ui.ActiveComponent; +import com.intellij.util.ui.JBUI; import org.jetbrains.annotations.NotNull; import javax.swing.*; @@ -28,7 +29,7 @@ class CompositeActiveComponent implements ActiveComponent { public CompositeActiveComponent(@NotNull ActiveComponent... components) { myComponents = components; - myComponent = new JPanel(new FlowLayout(FlowLayout.CENTER, 2, 4)); + myComponent = new JPanel(new FlowLayout(FlowLayout.CENTER, JBUI.scale(2), JBUI.scale(4))); myComponent.setBorder(null); myComponent.setOpaque(false); for (ActiveComponent component : components) { diff --git a/platform/lang-impl/src/com/intellij/openapi/fileTypes/FileTypeUsagesCollector.java b/platform/lang-impl/src/com/intellij/openapi/fileTypes/FileTypeUsagesCollector.java index 731134a66cba..038bb5f143c8 100644 --- a/platform/lang-impl/src/com/intellij/openapi/fileTypes/FileTypeUsagesCollector.java +++ b/platform/lang-impl/src/com/intellij/openapi/fileTypes/FileTypeUsagesCollector.java @@ -33,7 +33,6 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.File; -import java.io.FilenameFilter; import java.util.HashSet; import java.util.Set; @@ -63,7 +62,7 @@ public class FileTypeUsagesCollector extends AbstractApplicationUsagesCollector if (project.isDisposed()) { throw new CollectUsagesException("Project is disposed"); } - final String ideaDirPath = getIdeaDirPath(project.getBasePath()); + final String ideaDirPath = getIdeaDirPath(project); ApplicationManager.getApplication().runReadAction(new Runnable() { @Override public void run() { @@ -95,17 +94,12 @@ public class FileTypeUsagesCollector extends AbstractApplicationUsagesCollector } @Nullable - private static String getIdeaDirPath(@Nullable String projectPath) { + private static String getIdeaDirPath(@NotNull Project project) { + String projectPath = project.getBasePath(); if (projectPath != null) { - File projectDir = new File(projectPath); - File[] ideaDirs = projectDir.listFiles(new FilenameFilter() { - @Override - public boolean accept(File dir, String name) { - return Project.DIRECTORY_STORE_FOLDER.equals(name); - } - }); - if (ideaDirs.length == 1) { - return ideaDirs[0].getPath(); + String ideaDirPath = projectPath + "/" + Project.DIRECTORY_STORE_FOLDER; + if (new File(ideaDirPath).isDirectory()) { + return ideaDirPath; } } return null; diff --git a/platform/lang-impl/src/com/intellij/packageDependencies/FindDependencyUtil.java b/platform/lang-impl/src/com/intellij/packageDependencies/FindDependencyUtil.java index b4f0234c4bca..888fb38b1b3e 100644 --- a/platform/lang-impl/src/com/intellij/packageDependencies/FindDependencyUtil.java +++ b/platform/lang-impl/src/com/intellij/packageDependencies/FindDependencyUtil.java @@ -59,15 +59,7 @@ public class FindDependencyUtil { precomputedDeps = Collections.unmodifiableSet(searchFor); } - DependenciesBuilder.analyzeFileDependencies(psiFile, new DependenciesBuilder.DependencyProcessor() { - @Override - public void process(PsiElement place, PsiElement dependency) { - PsiFile dependencyFile = dependency.getContainingFile(); - if (precomputedDeps.contains(dependencyFile)) { - usages.add(new UsageInfo(place)); - } - } - }); + analyzeFileDependencies(psiFile, precomputedDeps, usages); } return usages.toArray(new UsageInfo[usages.size()]); @@ -95,26 +87,30 @@ public class FindDependencyUtil { for (final PsiFile psiFile : deps) { count = updateIndicator(indicator, totalCount, count, psiFile); - DependenciesBuilder.analyzeFileDependencies(psiFile, new DependenciesBuilder.DependencyProcessor() { - @Override - public void process(PsiElement place, PsiElement dependency) { - PsiFile dependencyFile = dependency.getContainingFile(); - if (dependencyFile != null) { - final PsiElement navigationElement = dependencyFile.getNavigationElement(); - if (navigationElement instanceof PsiFile) { - dependencyFile = (PsiFile)navigationElement; - } - } - if (searchFor.contains(dependencyFile)) { - usages.add(new UsageInfo(place)); - } - } - }); + analyzeFileDependencies(psiFile, searchFor, usages); } return usages.toArray(new UsageInfo[usages.size()]); } + private static void analyzeFileDependencies(PsiFile psiFile, final Set searchFor, final List result) { + DependenciesBuilder.analyzeFileDependencies(psiFile, new DependenciesBuilder.DependencyProcessor() { + @Override + public void process(PsiElement place, PsiElement dependency) { + PsiFile dependencyFile = dependency.getContainingFile(); + if (dependencyFile != null) { + final PsiElement navigationElement = dependencyFile.getNavigationElement(); + if (navigationElement instanceof PsiFile) { + dependencyFile = (PsiFile)navigationElement; + } + } + if (searchFor.contains(dependencyFile)) { + result.add(new UsageInfo(place)); + } + } + }); + } + private static int updateIndicator(final ProgressIndicator indicator, final int totalCount, int count, final PsiFile psiFile) { if (indicator != null) { if (indicator.isCanceled()) throw new ProcessCanceledException(); diff --git a/platform/platform-impl/src/com/intellij/ide/dnd/FileCopyPasteUtil.java b/platform/platform-impl/src/com/intellij/ide/dnd/FileCopyPasteUtil.java index 4faddff03bab..9edf2bb7a945 100644 --- a/platform/platform-impl/src/com/intellij/ide/dnd/FileCopyPasteUtil.java +++ b/platform/platform-impl/src/com/intellij/ide/dnd/FileCopyPasteUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -100,8 +100,8 @@ public class FileCopyPasteUtil { try { if (transferable.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) { @SuppressWarnings({"unchecked"}) - final List fileList = (List)transferable.getTransferData(DataFlavor.javaFileListFlavor); - return ContainerUtil.filter(fileList, new Condition() { + List fileList = (List)transferable.getTransferData(DataFlavor.javaFileListFlavor); + return fileList == null ? null : ContainerUtil.filter(fileList, new Condition() { @Override public boolean value(File file) { return !StringUtil.isEmptyOrSpaces(file.getPath()); diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerMain.java b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerMain.java index a01f13cbab13..6de4a1e1f242 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerMain.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManagerMain.java @@ -129,7 +129,8 @@ public abstract class PluginManagerMain implements Disposable { return isDevelopedByJetBrains(plugin.getVendor()); } - public static boolean isDevelopedByJetBrains(String vendorString) { + public static boolean isDevelopedByJetBrains(@Nullable String vendorString) { + if (vendorString == null) return false; for (String vendor : StringUtil.split(vendorString, ",")) { if (vendor.trim().equals(JETBRAINS_VENDOR)) { return true; diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java index 73502af88781..f22111b06427 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java @@ -1362,22 +1362,26 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse } void validateMousePointer(@NotNull MouseEvent e) { - Cursor cursor = Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR); + Cursor cursor = getCursor();//Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR); FoldRegion foldingAtCursor = findFoldingAnchorAt(e.getX(), e.getY()); setActiveFoldRegion(foldingAtCursor); + boolean updated = false; if (foldingAtCursor != null) { cursor = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR); + updated = true; } GutterIconRenderer renderer = getGutterRenderer(e); if (renderer != null) { if (renderer.isNavigateAction()) { cursor = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR); + updated = true; } } else { ActiveGutterRenderer lineRenderer = getActiveRendererByMouseEvent(e); if (lineRenderer != null) { cursor = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR); + updated = true; } else { TextAnnotationGutterProvider provider = getProviderAtPoint(e.getPoint()); @@ -1387,11 +1391,15 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse if (action != null) { int line = getLineNumAtPoint(e.getPoint()); cursor = action.getCursor(line); + updated = true; } } } } } + if (!updated && cursor == Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)) { + cursor = Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR); + } setCursor(cursor); } diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/InternalDecorator.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/InternalDecorator.java index 2162782e2132..3c0d740bf5a3 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/InternalDecorator.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/InternalDecorator.java @@ -312,9 +312,7 @@ public final class InternalDecorator extends JPanel implements Queryable, DataPr doPaintBorder(c, g, x, y, width, height); } else { - g.setColor(UIUtil.getPanelBackground()); - doPaintBorder(c, g, x, y, width, height); - g.setColor(Gray._155); + g.setColor(SystemInfo.isMac && UIUtil.isUnderIntelliJLaF() ? Gray.xC9 : Gray._155); doPaintBorder(c, g, x, y, width, height); } } diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/IdeStatusBarImpl.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/IdeStatusBarImpl.java index 7c5c475f8fba..e5cc4d63dcff 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/IdeStatusBarImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/IdeStatusBarImpl.java @@ -36,7 +36,6 @@ import com.intellij.ui.awt.RelativePoint; import com.intellij.ui.popup.NotificationPopup; import com.intellij.util.ArrayUtil; import com.intellij.util.Consumer; -import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.HashMap; import com.intellij.util.ui.JBUI; import com.intellij.util.ui.UIUtil; @@ -633,16 +632,6 @@ public class IdeStatusBarImpl extends JComponent implements StatusBarEx { return (StatusBarUI)ui; } - @Override - public void paint(Graphics g) { - super.paint(g); - if (UIUtil.isUnderDarcula()) { - //IDEA-112093 - g.setColor(UIUtil.getPanelBackground()); - g.drawLine(0, getHeight(), getWidth(), getHeight()); - } - } - @Override public void removeWidget(@NotNull final String id) { assert EventQueue.isDispatchThread() : "Must be EDT"; diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/MemoryUsagePanel.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/MemoryUsagePanel.java index 0f5cbfc6ae66..50fc3c30e69c 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/MemoryUsagePanel.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/MemoryUsagePanel.java @@ -194,7 +194,7 @@ public class MemoryUsagePanel extends JButton implements CustomStatusBarWidget { if (UIUtil.isRetina() && !UIUtil.isUnderDarcula()) { Graphics2D g2 = (Graphics2D)g.create(0, 0, getWidth(), getHeight()); g2.scale(0.5, 0.5); - g2.setColor(Gray.x91); + g2.setColor(UIUtil.isUnderIntelliJLaF() ? Gray.xC9 : Gray.x91); g2.drawLine(0,0,2 * getWidth(), 0); g2.scale(1, 1); g2.dispose(); diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/PositionPanel.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/PositionPanel.java index dcdd5e9912cf..7eb2ff2fc307 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/PositionPanel.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/PositionPanel.java @@ -145,18 +145,19 @@ public class PositionPanel extends EditorBasedWidget implements StatusBarWidget. SelectionModel selectionModel = editor.getSelectionModel(); int caretCount = editor.getCaretModel().getCaretCount(); if (caretCount > 1) { - message.append(caretCount).append(" carets"); + message.append(UIBundle.message("position.panel.caret.count", caretCount)); } else { if (selectionModel.hasSelection()) { int selectionStart = selectionModel.getSelectionStart(); int selectionEnd = selectionModel.getSelectionEnd(); if (selectionEnd > selectionStart) { - message.append(selectionEnd - selectionStart).append(" chars"); + message.append(UIBundle.message("position.panel.selected.chars.count", selectionEnd - selectionStart)); int selectionStartLine = editor.getDocument().getLineNumber(selectionStart); int selectionEndLine = editor.getDocument().getLineNumber(selectionEnd); if (selectionEndLine > selectionStartLine) { - message.append(", ").append(selectionEndLine - selectionStartLine + 1).append(" lines"); + message.append(", "); + message.append(UIBundle.message("position.panel.selected.lines.count", selectionEndLine - selectionStartLine + 1)); } message.append(" "); } diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/StatusBarUI.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/StatusBarUI.java index 9f020e905f35..db2c8eacfec2 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/StatusBarUI.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/StatusBarUI.java @@ -15,6 +15,7 @@ */ package com.intellij.openapi.wm.impl.status; +import com.intellij.openapi.util.SystemInfo; import com.intellij.ui.Gray; import com.intellij.util.ui.UIUtil; @@ -63,11 +64,17 @@ public class StatusBarUI extends ComponentUI { g2d.setColor(background); g2d.fillRect(0, 0, width, height); - g2d.setColor(UIUtil.isUnderDarcula() ? BORDER_TOP_COLOR.darker().darker() : BORDER_TOP_COLOR); + Color topColor = UIUtil.isUnderDarcula() ? BORDER_TOP_COLOR.darker().darker() : BORDER_TOP_COLOR; + if (SystemInfo.isMac && UIUtil.isUnderIntelliJLaF()) { + topColor = Gray.xC9; + } + g2d.setColor(topColor); g2d.drawLine(0, 0, width, 0); - g2d.setColor(UIUtil.isUnderDarcula() ? BORDER_BOTTOM_COLOR.darker().darker() : BORDER_BOTTOM_COLOR); - g2d.drawLine(0, height, width, height); + if (!UIUtil.isUnderDarcula()) { + g2d.setColor(BORDER_BOTTOM_COLOR); + g2d.drawLine(0, height, width, height); + } g2d.dispose(); } diff --git a/platform/platform-impl/src/com/intellij/ui/ColorPicker.java b/platform/platform-impl/src/com/intellij/ui/ColorPicker.java index d59b3745db1d..48e8fc51125a 100644 --- a/platform/platform-impl/src/com/intellij/ui/ColorPicker.java +++ b/platform/platform-impl/src/com/intellij/ui/ColorPicker.java @@ -1138,7 +1138,6 @@ public class ColorPicker extends JPanel implements ColorListener, DocumentListen myGraphics = (Graphics2D)myImage.getGraphics(); myGraphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR); - pickerDialog.setBackground(UIUtil.TRANSPARENT_COLOR); } return pickerDialog; diff --git a/platform/platform-impl/src/org/jetbrains/concurrency/promise.kt b/platform/platform-impl/src/org/jetbrains/concurrency/promise.kt new file mode 100644 index 000000000000..4264de0597b7 --- /dev/null +++ b/platform/platform-impl/src/org/jetbrains/concurrency/promise.kt @@ -0,0 +1,35 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.concurrency + +import com.intellij.util.Function + +inline fun Promise.then(crossinline handler: (T) -> SUB_RESULT) = then(object : Function { + override fun `fun`(param: T) = handler(param) +}) + +inline fun Promise.thenAsync(crossinline handler: (T) -> Promise) = then(object : AsyncFunction { + override fun `fun`(param: T) = handler(param) +}) + +inline fun Promise.thenAsyncVoid(crossinline handler: (T) -> Promise<*>) = then(object : AsyncFunction { + override fun `fun`(param: T): Promise { + @Suppress("UNCHECKED_CAST") + return handler(param) as Promise + } +}) + +fun ResolvedPromise(): Promise<*> = Promise.DONE \ No newline at end of file diff --git a/platform/platform-impl/src/org/jetbrains/util/concurrency/Promise.kt b/platform/platform-impl/src/org/jetbrains/util/concurrency/Promise.kt index d5371c3e0e35..448fd53a347c 100644 --- a/platform/platform-impl/src/org/jetbrains/util/concurrency/Promise.kt +++ b/platform/platform-impl/src/org/jetbrains/util/concurrency/Promise.kt @@ -17,8 +17,8 @@ package org.jetbrains.util.concurrency import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.diagnostic.Logger -import org.jetbrains.concurrency.Promise as OJCPromise import org.jetbrains.concurrency.AsyncPromise as OJCAsyncPromise +import org.jetbrains.concurrency.Promise as OJCPromise interface Promise { enum class State { @@ -33,7 +33,7 @@ interface Promise { fun rejected(rejected: (Throwable) -> Unit): Promise - fun processed(processed: (T?) -> Unit): Promise + fun processed(@Suppress("BASE_WITH_NULLABLE_UPPER_BOUND") processed: (T?) -> Unit): Promise fun then(done: (T) -> SUB_RESULT): Promise @@ -93,8 +93,8 @@ fun ResolvedPromise(result: T): Promise = DonePromise(result) fun OJCPromise.toPromise(): AsyncPromise { val promise = AsyncPromise() val oldPromise = this - done({ promise.setResult(it) }) - .rejected({ promise.setError(it) }) + done { promise.setResult(it) } + .rejected { promise.setError(it) } if (oldPromise is OJCAsyncPromise) { promise diff --git a/platform/platform-impl/src/org/jetbrains/util/concurrency/RejectedPromise.kt b/platform/platform-impl/src/org/jetbrains/util/concurrency/RejectedPromise.kt index 08b523a31adf..6c2c6a85eb2c 100644 --- a/platform/platform-impl/src/org/jetbrains/util/concurrency/RejectedPromise.kt +++ b/platform/platform-impl/src/org/jetbrains/util/concurrency/RejectedPromise.kt @@ -15,7 +15,7 @@ */ package org.jetbrains.util.concurrency -class RejectedPromise(private val error: Throwable) : Promise { +internal class RejectedPromise(private val error: Throwable) : Promise { override public val state: Promise.State get() = Promise.State.REJECTED diff --git a/platform/platform-resources-en/src/messages/OptionsBundle.properties b/platform/platform-resources-en/src/messages/OptionsBundle.properties index 9de95bee9757..a11f9e1b2351 100644 --- a/platform/platform-resources-en/src/messages/OptionsBundle.properties +++ b/platform/platform-resources-en/src/messages/OptionsBundle.properties @@ -80,6 +80,7 @@ options.java.attribute.descriptor.reassigned.local.variable=Variables//Reassigne options.java.attribute.descriptor.reassigned.parameter=Parameters//Reassigned parameter options.java.attribute.descriptor.implicit.anonymous.parameter=Parameters//Implicit anonymous class parameter options.java.attribute.descriptor.instance.field=Class Fields//Instance field +options.java.attribute.descriptor.instance.final.field=Class Fields//Instance final field options.java.attribute.descriptor.static.field=Class Fields//Static field options.java.attribute.descriptor.static.final.field=Class Fields//Constant (static final field) options.java.attribute.descriptor.parameter=Parameters//Parameter diff --git a/platform/platform-resources-en/src/messages/UIBundle.properties b/platform/platform-resources-en/src/messages/UIBundle.properties index 3a2d87ed1a48..6f58d5a60cd3 100644 --- a/platform/platform-resources-en/src/messages/UIBundle.properties +++ b/platform/platform-resources-en/src/messages/UIBundle.properties @@ -72,6 +72,9 @@ memory.usage.panel.statistics.message=Allocated heap size: {0}M Used: {1}M memory.usage.panel.message.text={0,number,####} of {1,number,####}M go.to.line.command.name=Go to Line go.to.line.command.double.click=Click to go to line +position.panel.caret.count={0} carets +position.panel.selected.chars.count={0} chars +position.panel.selected.lines.count={0} lines popup.hints.panel.click.to.configure.highlighting.tooltip.text=Click to configure highlighting for this file popup.hints.panel.click.to.configure.profile.text=Click to configure inspection profiles read.only.attr.panel.double.click.to.toggle.attr.tooltip.text=Click to toggle the read-only attribute diff --git a/platform/platform-resources-en/src/messages/XDebuggerBundle.properties b/platform/platform-resources-en/src/messages/XDebuggerBundle.properties index 63cdb4ba5051..ca129821f44e 100644 --- a/platform/platform-resources-en/src/messages/XDebuggerBundle.properties +++ b/platform/platform-resources-en/src/messages/XDebuggerBundle.properties @@ -120,6 +120,8 @@ scope.catch = Catch scope.class = Class scope.instance = Instance scope.library = Library +scope.block = Block +scope.script = Script scope.unknown = Unknown setting.value.tooltip.delay.label=&Value tooltip delay (ms): diff --git a/platform/platform-resources/src/checkedPlugins.txt b/platform/platform-resources/src/checkedPlugins.txt index 7d80cf054556..1ee842c235d7 100644 --- a/platform/platform-resources/src/checkedPlugins.txt +++ b/platform/platform-resources/src/checkedPlugins.txt @@ -20,4 +20,7 @@ com.jetbrains.plugins.meteor AWSCloudFormation Dart IdeaVIM -IDETalk \ No newline at end of file +IDETalk +Commander +SourceSafe +TFS \ No newline at end of file diff --git a/platform/script-debugger/backend/src/org/jetbrains/debugger/BreakpointManager.kt b/platform/script-debugger/backend/src/org/jetbrains/debugger/BreakpointManager.kt index 089b318558c7..5e411d7155a1 100644 --- a/platform/script-debugger/backend/src/org/jetbrains/debugger/BreakpointManager.kt +++ b/platform/script-debugger/backend/src/org/jetbrains/debugger/BreakpointManager.kt @@ -16,34 +16,33 @@ package org.jetbrains.debugger import org.jetbrains.util.concurrency.Promise +import java.util.* -import java.util.EventListener - -public interface BreakpointManager { - public enum class MUTE_MODE { +interface BreakpointManager { + enum class MUTE_MODE { ALL, ONE, NONE } - public val breakpoints: Iterable + val breakpoints: Iterable - public val regExpBreakpointSupported: Boolean + val regExpBreakpointSupported: Boolean get() = false - public fun setBreakpoint(target: BreakpointTarget, line: Int, column: Int, condition: String?, ignoreCount: Int, enabled: Boolean): Breakpoint + fun setBreakpoint(target: BreakpointTarget, line: Int, column: Int, condition: String?, ignoreCount: Int, enabled: Boolean): Breakpoint - public fun remove(breakpoint: Breakpoint): Promise<*> + fun remove(breakpoint: Breakpoint): Promise<*> - public val functionSupport: FunctionSupport? + val functionSupport: FunctionSupport? get() = null // Could be called multiple times for breakpoint - public fun addBreakpointListener(listener: BreakpointListener) + fun addBreakpointListener(listener: BreakpointListener) - public fun removeAll(): Promise<*> + fun removeAll(): Promise<*> - public fun getMuteMode(): MUTE_MODE = BreakpointManager.MUTE_MODE.ONE + fun getMuteMode(): MUTE_MODE = BreakpointManager.MUTE_MODE.ONE /** * Flushes the breakpoint parameter changes (set* methods) into the browser @@ -51,7 +50,7 @@ public interface BreakpointManager { * be called for the set* method invocations to take effect. */ - public fun flush(breakpoint: Breakpoint): Promise<*> + fun flush(breakpoint: Breakpoint): Promise<*> /** * Asynchronously enables or disables all breakpoints on remote. 'Enabled' means that @@ -59,11 +58,11 @@ public interface BreakpointManager { * It doesn't update individual properties of [Breakpoint]s. Method call * with a null value and not null callback simply returns current value. */ - public fun enableBreakpoints(enabled: Boolean): Promise<*> + fun enableBreakpoints(enabled: Boolean): Promise<*> +} - public interface BreakpointListener : EventListener { - public fun resolved(breakpoint: Breakpoint) +interface BreakpointListener : EventListener { + fun resolved(breakpoint: Breakpoint) - public fun errorOccurred(breakpoint: Breakpoint, errorMessage: String?) - } + fun errorOccurred(breakpoint: Breakpoint, errorMessage: String?) } \ No newline at end of file diff --git a/platform/script-debugger/backend/src/org/jetbrains/debugger/BreakpointManagerBase.kt b/platform/script-debugger/backend/src/org/jetbrains/debugger/BreakpointManagerBase.kt index 7ad766e01da2..81b4466d1f2c 100644 --- a/platform/script-debugger/backend/src/org/jetbrains/debugger/BreakpointManagerBase.kt +++ b/platform/script-debugger/backend/src/org/jetbrains/debugger/BreakpointManagerBase.kt @@ -25,8 +25,8 @@ import org.jetbrains.util.concurrency.RejectedPromise import org.jetbrains.util.concurrency.ResolvedPromise import java.util.concurrent.ConcurrentMap -public abstract class BreakpointManagerBase> : BreakpointManager { - override val breakpoints: MutableSet = ContainerUtil.newConcurrentSet() +abstract class BreakpointManagerBase> : BreakpointManager { + override val breakpoints = ContainerUtil.newConcurrentSet() protected val breakpointDuplicationByTarget: ConcurrentMap = ContainerUtil.newConcurrentMap(object : TObjectHashingStrategy { override fun computeHashCode(b: T): Int { @@ -42,13 +42,13 @@ public abstract class BreakpointManagerBase> : BreakpointM override fun equals(b1: T, b2: T) = b1.target.javaClass == b2.target.javaClass && b1.target == b2.target && b1.line == b2.line && b1.column == b2.column && StringUtil.equals(b1.condition, b2.condition) }) - protected val dispatcher: EventDispatcher = EventDispatcher.create(BreakpointManager.BreakpointListener::class.java) + protected val dispatcher: EventDispatcher = EventDispatcher.create(BreakpointListener::class.java) protected abstract fun createBreakpoint(target: BreakpointTarget, line: Int, column: Int, condition: String?, ignoreCount: Int, enabled: Boolean): T protected abstract fun doSetBreakpoint(target: BreakpointTarget, breakpoint: T): Promise - override fun setBreakpoint(target: BreakpointTarget, line: Int, column: Int, condition: String?, ignoreCount: Int, enabled: Boolean): Breakpoint { + override final fun setBreakpoint(target: BreakpointTarget, line: Int, column: Int, condition: String?, ignoreCount: Int, enabled: Boolean): Breakpoint { val breakpoint = createBreakpoint(target, line, column, condition, ignoreCount, enabled) val existingBreakpoint = breakpointDuplicationByTarget.putIfAbsent(breakpoint, breakpoint) if (existingBreakpoint != null) { @@ -62,7 +62,7 @@ public abstract class BreakpointManagerBase> : BreakpointM return breakpoint } - override fun remove(breakpoint: Breakpoint): Promise<*> { + override final fun remove(breakpoint: Breakpoint): Promise<*> { @Suppress("UNCHECKED_CAST") val b = breakpoint as T val existed = breakpoints.remove(b) @@ -72,7 +72,7 @@ public abstract class BreakpointManagerBase> : BreakpointM return if (!existed || !b.isVmRegistered()) ResolvedPromise() else doClearBreakpoint(b) } - override fun removeAll(): Promise<*> { + override final fun removeAll(): Promise<*> { val list = breakpoints.toList() breakpoints.clear() breakpointDuplicationByTarget.clear() @@ -87,7 +87,7 @@ public abstract class BreakpointManagerBase> : BreakpointM protected abstract fun doClearBreakpoint(breakpoint: T): Promise<*> - override fun addBreakpointListener(listener: BreakpointManager.BreakpointListener) { + override final fun addBreakpointListener(listener: BreakpointListener) { dispatcher.addListener(listener) } @@ -101,4 +101,24 @@ public abstract class BreakpointManagerBase> : BreakpointM override fun flush(breakpoint: Breakpoint) = (breakpoint as T).flush(this) override fun enableBreakpoints(enabled: Boolean): Promise<*> = RejectedPromise("Unsupported") +} + +class DummyBreakpointManager : BreakpointManager { + override val breakpoints: Iterable + get() = emptyList() + + override fun setBreakpoint(target: BreakpointTarget, line: Int, column: Int, condition: String?, ignoreCount: Int, enabled: Boolean): Breakpoint { + throw UnsupportedOperationException() + } + + override fun remove(breakpoint: Breakpoint) = ResolvedPromise() + + override fun addBreakpointListener(listener: BreakpointListener) { + } + + override fun removeAll() = ResolvedPromise() + + override fun flush(breakpoint: Breakpoint) = ResolvedPromise() + + override fun enableBreakpoints(enabled: Boolean) = ResolvedPromise() } \ No newline at end of file diff --git a/platform/script-debugger/backend/src/org/jetbrains/debugger/DeclarativeScope.java b/platform/script-debugger/backend/src/org/jetbrains/debugger/DeclarativeScope.java deleted file mode 100644 index 6316d746464b..000000000000 --- a/platform/script-debugger/backend/src/org/jetbrains/debugger/DeclarativeScope.java +++ /dev/null @@ -1,38 +0,0 @@ -package org.jetbrains.debugger; - -import com.intellij.util.Consumer; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.concurrency.Promise; -import org.jetbrains.debugger.values.ObjectValue; -import org.jetbrains.debugger.values.ValueManager; - -import java.util.List; - -public abstract class DeclarativeScope extends ScopeBase { - protected VariablesHost childrenManager; - - protected DeclarativeScope(@NotNull Type type, @Nullable String description) { - super(type, description); - } - - @NotNull - protected final Promise> loadScopeObjectProperties(@NotNull ObjectValue value) { - if (childrenManager.valueManager.isObsolete()) { - return ValueManager.reject(); - } - - return value.getProperties().done(new Consumer>() { - @Override - public void consume(List variables) { - childrenManager.updateCacheStamp(); - } - }); - } - - @NotNull - @Override - public final VariablesHost getVariablesHost() { - return childrenManager; - } -} \ No newline at end of file diff --git a/platform/script-debugger/backend/src/org/jetbrains/debugger/DeclarativeScope.kt b/platform/script-debugger/backend/src/org/jetbrains/debugger/DeclarativeScope.kt new file mode 100644 index 000000000000..eeadaf7463cb --- /dev/null +++ b/platform/script-debugger/backend/src/org/jetbrains/debugger/DeclarativeScope.kt @@ -0,0 +1,39 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.debugger + +import com.intellij.util.Consumer +import org.jetbrains.concurrency.Promise +import org.jetbrains.debugger.values.ObjectValue +import org.jetbrains.debugger.values.ValueManager + +abstract class DeclarativeScope>(type: Scope.Type, description: String? = null) : ScopeBase(type, description) { + protected abstract val childrenManager: VariablesHost + + protected fun loadScopeObjectProperties(value: ObjectValue): Promise> { + if (childrenManager.valueManager.isObsolete) { + return ValueManager.reject() + } + + return value.properties.done(object : Consumer> { + override fun consume(variables: List) { + childrenManager.updateCacheStamp() + } + }) + } + + override fun getVariablesHost() = childrenManager +} \ No newline at end of file diff --git a/platform/script-debugger/backend/src/org/jetbrains/debugger/Scope.java b/platform/script-debugger/backend/src/org/jetbrains/debugger/Scope.java index e92f1c23d47b..d380b07e5002 100644 --- a/platform/script-debugger/backend/src/org/jetbrains/debugger/Scope.java +++ b/platform/script-debugger/backend/src/org/jetbrains/debugger/Scope.java @@ -1,3 +1,18 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.jetbrains.debugger; import org.jetbrains.annotations.NotNull; @@ -13,6 +28,8 @@ public interface Scope { LIBRARY, CLASS, INSTANCE, + BLOCK, + SCRIPT, UNKNOWN } diff --git a/platform/script-debugger/backend/src/org/jetbrains/debugger/StandaloneVmHelper.kt b/platform/script-debugger/backend/src/org/jetbrains/debugger/StandaloneVmHelper.kt index 67c3045af634..8ca522934fa3 100644 --- a/platform/script-debugger/backend/src/org/jetbrains/debugger/StandaloneVmHelper.kt +++ b/platform/script-debugger/backend/src/org/jetbrains/debugger/StandaloneVmHelper.kt @@ -30,7 +30,7 @@ import org.jetbrains.util.concurrency.catchError import java.util.concurrent.TimeUnit import org.jetbrains.concurrency.Promise as OJCPromise -public open class StandaloneVmHelper(private val vm: Vm, private val messageProcessor: MessageProcessor) : MessageWriter(), AttachStateManager { +open class StandaloneVmHelper(private val vm: Vm, private val messageProcessor: MessageProcessor) : MessageWriter(), AttachStateManager { private @Volatile var channel: Channel? = null override fun write(content: ByteBuf) = write((content as Any)) @@ -40,16 +40,16 @@ public open class StandaloneVmHelper(private val vm: Vm, private val messageProc return if (currentChannel == null || !currentChannel.isActive) null else currentChannel } - public fun write(content: Any): Boolean { + fun write(content: Any): Boolean { val channel = getChannelIfActive() return channel != null && !channel.writeAndFlush(content).isCancelled } - public interface VmEx : Vm { - public fun createDisconnectRequest(): Request? + interface VmEx : Vm { + fun createDisconnectRequest(): Request? } - public fun setChannel(channel: Channel) { + fun setChannel(channel: Channel) { this.channel = channel channel.closeFuture().addListener(MyChannelFutureListener()) } @@ -82,8 +82,7 @@ public open class StandaloneVmHelper(private val vm: Vm, private val messageProc messageProcessor.closed() channel = null - @Suppress("USELESS_CAST") - val p = messageProcessor.send(disconnectRequest) as OJCPromise<*> + val p = messageProcessor.send(disconnectRequest) p.processed { promise.catchError { messageProcessor.cancelWaitingRequests() diff --git a/platform/script-debugger/backend/src/org/jetbrains/debugger/ValueModifier.java b/platform/script-debugger/backend/src/org/jetbrains/debugger/ValueModifier.java deleted file mode 100644 index 4800f8005f8b..000000000000 --- a/platform/script-debugger/backend/src/org/jetbrains/debugger/ValueModifier.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.jetbrains.debugger; - -import org.jetbrains.annotations.NotNull; -import org.jetbrains.concurrency.Promise; -import org.jetbrains.debugger.values.Value; - -public interface ValueModifier { - // expression can contains reference to another variables in current scope, so, we should evaluate it before set - // https://youtrack.jetbrains.com/issue/WEB-2342#comment=27-512122 - - // we don't worry about performance in case of simple primitive values - boolean/string/numbers, - // it works quickly and we don't want to complicate our code and debugger SDK - Promise setValue(@NotNull Variable variable, String newValue, @NotNull EvaluateContext evaluateContext); - - Promise setValue(@NotNull Variable variable, @NotNull Value newValue, @NotNull EvaluateContext evaluateContext); - - @NotNull - Promise evaluateGet(@NotNull Variable variable, @NotNull EvaluateContext evaluateContext); -} \ No newline at end of file diff --git a/platform/script-debugger/backend/src/org/jetbrains/debugger/ValueModifier.kt b/platform/script-debugger/backend/src/org/jetbrains/debugger/ValueModifier.kt new file mode 100644 index 000000000000..7b404382bc99 --- /dev/null +++ b/platform/script-debugger/backend/src/org/jetbrains/debugger/ValueModifier.kt @@ -0,0 +1,17 @@ +package org.jetbrains.debugger + +import org.jetbrains.concurrency.Promise +import org.jetbrains.debugger.values.Value + +interface ValueModifier { + // expression can contains reference to another variables in current scope, so, we should evaluate it before set + // https://youtrack.jetbrains.com/issue/WEB-2342#comment=27-512122 + + // we don't worry about performance in case of simple primitive values - boolean/string/numbers, + // it works quickly and we don't want to complicate our code and debugger SDK + fun setValue(variable: Variable, newValue: String, evaluateContext: EvaluateContext): Promise<*> + + fun setValue(variable: Variable, newValue: Value, evaluateContext: EvaluateContext): Promise<*> + + fun evaluateGet(variable: Variable, evaluateContext: EvaluateContext): Promise +} \ No newline at end of file diff --git a/platform/script-debugger/backend/src/org/jetbrains/debugger/Vm.kt b/platform/script-debugger/backend/src/org/jetbrains/debugger/Vm.kt index 74d370ecd6f1..67e4db646b95 100644 --- a/platform/script-debugger/backend/src/org/jetbrains/debugger/Vm.kt +++ b/platform/script-debugger/backend/src/org/jetbrains/debugger/Vm.kt @@ -15,7 +15,6 @@ */ package org.jetbrains.debugger -import org.jetbrains.util.concurrency.Promise import org.jetbrains.util.concurrency.ResolvedPromise interface AttachStateManager { @@ -35,10 +34,10 @@ interface Vm { val breakpointManager: BreakpointManager - fun getSuspendContextManager(): SuspendContextManager + val suspendContextManager: SuspendContextManager /** * Controls whether VM stops on exceptions */ - fun setBreakOnException(catchMode: ExceptionCatchMode): Promise<*> + fun setBreakOnException(catchMode: ExceptionCatchMode) = ResolvedPromise() } \ No newline at end of file diff --git a/platform/script-debugger/backend/src/org/jetbrains/debugger/values/ArrayValue.java b/platform/script-debugger/backend/src/org/jetbrains/debugger/values/ArrayValue.java deleted file mode 100644 index a0a8b22ccb5b..000000000000 --- a/platform/script-debugger/backend/src/org/jetbrains/debugger/values/ArrayValue.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.jetbrains.debugger.values; - -public interface ArrayValue extends ObjectValue { - /** - * Be aware - it is not equals to java array length. - * In case of sparse array {@code - * var sparseArray = [3, 4]; - * sparseArray[45] = 34; - * sparseArray[40999995] = "foo"; - * } - * length will be equal to 40999995. - */ - int getLength(); -} \ No newline at end of file diff --git a/platform/script-debugger/backend/src/org/jetbrains/debugger/values/ArrayValue.kt b/platform/script-debugger/backend/src/org/jetbrains/debugger/values/ArrayValue.kt new file mode 100644 index 000000000000..f9bd69031e27 --- /dev/null +++ b/platform/script-debugger/backend/src/org/jetbrains/debugger/values/ArrayValue.kt @@ -0,0 +1,13 @@ +package org.jetbrains.debugger.values + +interface ArrayValue : ObjectValue { + /** + * Be aware - it is not equals to java array length. + * In case of sparse array `var sparseArray = [3, 4]; + * sparseArray[45] = 34; + * sparseArray[40999995] = "foo"; + ` * + * length will be equal to 40999995. + */ + val length: Int +} \ No newline at end of file diff --git a/platform/script-debugger/backend/src/org/jetbrains/debugger/values/ObjectValue.java b/platform/script-debugger/backend/src/org/jetbrains/debugger/values/ObjectValue.java deleted file mode 100755 index 3d9bd035ed15..000000000000 --- a/platform/script-debugger/backend/src/org/jetbrains/debugger/values/ObjectValue.java +++ /dev/null @@ -1,49 +0,0 @@ -package org.jetbrains.debugger.values; - -import com.intellij.util.ThreeState; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.concurrency.Obsolescent; -import org.jetbrains.concurrency.Promise; -import org.jetbrains.debugger.EvaluateContext; -import org.jetbrains.debugger.Variable; -import org.jetbrains.debugger.VariablesHost; - -import java.util.List; - -/** - * A compound value that has zero or more properties - */ -public interface ObjectValue extends Value { - @Nullable - String getClassName(); - - @NotNull - Promise> getProperties(); - - @NotNull - Promise> getProperties(@NotNull List names, @NotNull EvaluateContext evaluateContext, @NotNull Obsolescent obsolescent); - - @NotNull - VariablesHost getVariablesHost(); - - /** - * from (inclusive) to (exclusive) ranges of array elements or elements if less than bucketThreshold - * - * "to" could be -1 (sometimes length is unknown, so, you can pass -1 instead of actual elements size) - */ - @NotNull - Promise getIndexedProperties(int from, int to, int bucketThreshold, @NotNull IndexedVariablesConsumer consumer, @Nullable ValueType componentType); - - /** - * It must return quickly. Return {@link com.intellij.util.ThreeState#UNSURE} otherwise. - */ - @NotNull - ThreeState hasProperties(); - - /** - * It must return quickly. Return {@link com.intellij.util.ThreeState#UNSURE} otherwise. - */ - @NotNull - ThreeState hasIndexedProperties(); -} \ No newline at end of file diff --git a/platform/script-debugger/backend/src/org/jetbrains/debugger/values/ObjectValue.kt b/platform/script-debugger/backend/src/org/jetbrains/debugger/values/ObjectValue.kt new file mode 100755 index 000000000000..ed57378999c2 --- /dev/null +++ b/platform/script-debugger/backend/src/org/jetbrains/debugger/values/ObjectValue.kt @@ -0,0 +1,39 @@ +package org.jetbrains.debugger.values + +import com.intellij.util.ThreeState +import org.jetbrains.concurrency.Obsolescent +import org.jetbrains.concurrency.Promise +import org.jetbrains.debugger.EvaluateContext +import org.jetbrains.debugger.Variable +import org.jetbrains.debugger.VariablesHost +import org.jetbrains.debugger.Vm + +/** + * A compound value that has zero or more properties + */ +interface ObjectValue : Value { + val className: String? + + val properties: Promise> + + fun getProperties(names: List, evaluateContext: EvaluateContext, obsolescent: Obsolescent): Promise> + + val variablesHost: VariablesHost> + + /** + * from (inclusive) to (exclusive) ranges of array elements or elements if less than bucketThreshold + + * "to" could be -1 (sometimes length is unknown, so, you can pass -1 instead of actual elements size) + */ + fun getIndexedProperties(from: Int, to: Int, bucketThreshold: Int, consumer: IndexedVariablesConsumer, componentType: ValueType?): Promise<*> + + /** + * It must return quickly. Return [com.intellij.util.ThreeState.UNSURE] otherwise. + */ + fun hasProperties() = ThreeState.UNSURE + + /** + * It must return quickly. Return [com.intellij.util.ThreeState.UNSURE] otherwise. + */ + fun hasIndexedProperties() = ThreeState.NO +} \ No newline at end of file diff --git a/platform/script-debugger/backend/src/org/jetbrains/debugger/values/ObjectValueBase.java b/platform/script-debugger/backend/src/org/jetbrains/debugger/values/ObjectValueBase.java deleted file mode 100644 index 67f375b00ad1..000000000000 --- a/platform/script-debugger/backend/src/org/jetbrains/debugger/values/ObjectValueBase.java +++ /dev/null @@ -1,127 +0,0 @@ -package org.jetbrains.debugger.values; - -import com.intellij.util.SmartList; -import com.intellij.util.ThreeState; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.concurrency.Obsolescent; -import org.jetbrains.concurrency.ObsolescentAsyncFunction; -import org.jetbrains.concurrency.Promise; -import org.jetbrains.debugger.EvaluateContext; -import org.jetbrains.debugger.ValueModifier; -import org.jetbrains.debugger.Variable; -import org.jetbrains.debugger.VariablesHost; - -import java.util.Collections; -import java.util.Comparator; -import java.util.List; - -public abstract class ObjectValueBase extends ValueBase implements ObjectValue { - protected VariablesHost childrenManager; - - public ObjectValueBase(@NotNull ValueType type) { - super(type); - } - - @NotNull - @Override - public final Promise> getProperties() { - return childrenManager.get(); - } - - abstract class MyObsolescentAsyncFunction implements ObsolescentAsyncFunction { - private final Obsolescent obsolescent; - - MyObsolescentAsyncFunction(@NotNull Obsolescent obsolescent) { - this.obsolescent = obsolescent; - } - - @Override - public boolean isObsolete() { - return obsolescent.isObsolete() || childrenManager.valueManager.isObsolete(); - } - } - - @NotNull - @Override - public Promise> getProperties(@NotNull final List names, @NotNull final EvaluateContext evaluateContext, @NotNull final Obsolescent obsolescent) { - return getProperties() - .then(new MyObsolescentAsyncFunction, List>(obsolescent) { - @NotNull - @Override - public Promise> fun(List variables) { - return getSpecifiedProperties(variables, names, evaluateContext); - } - }); - } - - @NotNull - protected static Promise> getSpecifiedProperties(@NotNull List variables, @NotNull final List names, @NotNull EvaluateContext evaluateContext) { - final List properties = new SmartList(); - int getterCount = 0; - for (Variable property : variables) { - if (!property.isReadable() || !names.contains(property.getName())) { - continue; - } - - if (!properties.isEmpty()) { - Collections.sort(properties, new Comparator() { - @Override - public int compare(@NotNull Variable o1, @NotNull Variable o2) { - return names.indexOf(o1.getName()) - names.indexOf(o2.getName()); - } - }); - } - - properties.add(property); - if (property.getValue() == null) { - getterCount++; - } - } - - if (getterCount == 0) { - return Promise.resolve(properties); - } - else { - List> promises = new SmartList>(); - for (Variable variable : properties) { - if (variable.getValue() == null) { - ValueModifier valueModifier = variable.getValueModifier(); - assert valueModifier != null; - promises.add(valueModifier.evaluateGet(variable, evaluateContext)); - } - } - return Promise.all(promises, properties); - } - } - - @Nullable - @Override - public String getValueString() { - return null; - } - - @NotNull - @Override - public ThreeState hasProperties() { - return ThreeState.UNSURE; - } - - @NotNull - @Override - public ThreeState hasIndexedProperties() { - return ThreeState.NO; - } - - @NotNull - @Override - public Promise getIndexedProperties(int from, int to, int bucketThreshold, @NotNull IndexedVariablesConsumer consumer, @Nullable ValueType componentType) { - return Promise.REJECTED; - } - - @NotNull - @Override - public VariablesHost getVariablesHost() { - return childrenManager; - } -} \ No newline at end of file diff --git a/platform/script-debugger/backend/src/org/jetbrains/debugger/values/ObjectValueBase.kt b/platform/script-debugger/backend/src/org/jetbrains/debugger/values/ObjectValueBase.kt new file mode 100644 index 000000000000..12ccce2c9cac --- /dev/null +++ b/platform/script-debugger/backend/src/org/jetbrains/debugger/values/ObjectValueBase.kt @@ -0,0 +1,86 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.debugger.values + +import com.intellij.util.SmartList +import org.jetbrains.concurrency.Obsolescent +import org.jetbrains.concurrency.ObsolescentAsyncFunction +import org.jetbrains.concurrency.Promise +import org.jetbrains.debugger.EvaluateContext +import org.jetbrains.debugger.Variable +import org.jetbrains.debugger.VariablesHost +import org.jetbrains.debugger.Vm +import java.util.* + +abstract class ObjectValueBase>(type: ValueType) : ValueBase(type), ObjectValue { + protected abstract val childrenManager: VariablesHost + + override val properties: Promise> + get() = childrenManager.get() + + internal abstract inner class MyObsolescentAsyncFunction(private val obsolescent: Obsolescent) : ObsolescentAsyncFunction { + override fun isObsolete() = obsolescent.isObsolete || childrenManager.valueManager.isObsolete + } + + override fun getProperties(names: List, evaluateContext: EvaluateContext, obsolescent: Obsolescent) = properties + .then(object : MyObsolescentAsyncFunction, List>(obsolescent) { + override fun `fun`(variables: List) = getSpecifiedProperties(variables, names, evaluateContext) + }) + + override val valueString: String? = null + + override fun getIndexedProperties(from: Int, to: Int, bucketThreshold: Int, consumer: IndexedVariablesConsumer, componentType: ValueType?): Promise<*> = Promise.REJECTED + + @Suppress("CAST_NEVER_SUCCEEDS") + override val variablesHost: VariablesHost> + get() = childrenManager as VariablesHost> +} + +fun getSpecifiedProperties(variables: List, names: List, evaluateContext: EvaluateContext): Promise> { + val properties = SmartList() + var getterCount = 0 + for (property in variables) { + if (!property.isReadable || !names.contains(property.name)) { + continue + } + + if (!properties.isEmpty()) { + Collections.sort(properties, object : Comparator { + override fun compare(o1: Variable, o2: Variable) = names.indexOf(o1.name) - names.indexOf(o2.name) + }) + } + + properties.add(property) + if (property.value == null) { + getterCount++ + } + } + + if (getterCount == 0) { + return Promise.resolve(properties) + } + else { + val promises = SmartList>() + for (variable in properties) { + if (variable.value == null) { + val valueModifier = variable.valueModifier + assert(valueModifier != null) + promises.add(valueModifier!!.evaluateGet(variable, evaluateContext)) + } + } + return Promise.all>(promises, properties) + } +} \ No newline at end of file diff --git a/platform/script-debugger/backend/src/org/jetbrains/debugger/values/Value.java b/platform/script-debugger/backend/src/org/jetbrains/debugger/values/Value.java deleted file mode 100755 index c64d1e090795..000000000000 --- a/platform/script-debugger/backend/src/org/jetbrains/debugger/values/Value.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.jetbrains.debugger.values; - -import org.jetbrains.annotations.NotNull; - -/** - * An object that represents a VM variable value (compound or atomic). - */ -public interface Value { - @NotNull - ValueType getType(); - - /** - * @return a string representation of this value - */ - String getValueString(); -} diff --git a/platform/script-debugger/backend/src/org/jetbrains/debugger/values/Value.kt b/platform/script-debugger/backend/src/org/jetbrains/debugger/values/Value.kt new file mode 100755 index 000000000000..7c8ec35576e5 --- /dev/null +++ b/platform/script-debugger/backend/src/org/jetbrains/debugger/values/Value.kt @@ -0,0 +1,13 @@ +package org.jetbrains.debugger.values + +/** + * An object that represents a VM variable value (compound or atomic). + */ +interface Value { + val type: ValueType + + /** + * @return a string representation of this value + */ + val valueString: String? +} diff --git a/platform/script-debugger/backend/src/org/jetbrains/debugger/values/ValueBase.java b/platform/script-debugger/backend/src/org/jetbrains/debugger/values/ValueBase.java deleted file mode 100644 index fd8cc9c93615..000000000000 --- a/platform/script-debugger/backend/src/org/jetbrains/debugger/values/ValueBase.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.jetbrains.debugger.values; - -import org.jetbrains.annotations.NotNull; - -public abstract class ValueBase implements Value { - protected final ValueType type; - - public ValueBase(@NotNull ValueType type) { - this.type = type; - } - - @NotNull - @Override - public final ValueType getType() { - return type; - } -} \ No newline at end of file diff --git a/platform/script-debugger/backend/src/org/jetbrains/debugger/values/ValueBase.kt b/platform/script-debugger/backend/src/org/jetbrains/debugger/values/ValueBase.kt new file mode 100644 index 000000000000..a97684a3522e --- /dev/null +++ b/platform/script-debugger/backend/src/org/jetbrains/debugger/values/ValueBase.kt @@ -0,0 +1,3 @@ +package org.jetbrains.debugger.values + +abstract class ValueBase(override val type: ValueType) : Value \ No newline at end of file diff --git a/platform/script-debugger/backend/src/org/jetbrains/rpc/CommandProcessor.java b/platform/script-debugger/backend/src/org/jetbrains/rpc/CommandProcessor.java deleted file mode 100644 index ea20491884da..000000000000 --- a/platform/script-debugger/backend/src/org/jetbrains/rpc/CommandProcessor.java +++ /dev/null @@ -1,44 +0,0 @@ -package org.jetbrains.rpc; - -import com.intellij.openapi.diagnostic.Logger; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.jsonProtocol.Request; - -import java.util.concurrent.atomic.AtomicInteger; - -public abstract class CommandProcessor - extends CommandSenderBase - implements MessageManager.Handler, - ResultReader, - MessageProcessor { - public static final Logger LOG = Logger.getInstance(CommandProcessor.class); - - private final AtomicInteger currentSequence = new AtomicInteger(); - protected final MessageManager messageManager; - - protected CommandProcessor() { - messageManager = new MessageManager(this); - } - - @Override - public final void cancelWaitingRequests() { - messageManager.cancelWaitingRequests(); - } - - @Override - public final void closed() { - messageManager.closed(); - } - - @Override - public final int getUpdatedSequence(@NotNull Request message) { - int id = currentSequence.incrementAndGet(); - message.finalize(id); - return id; - } - - @Override - protected void send(@NotNull Request message, @NotNull RequestPromise callback) { - messageManager.send(message, callback); - } -} \ No newline at end of file diff --git a/platform/script-debugger/backend/src/org/jetbrains/rpc/CommandProcessor.kt b/platform/script-debugger/backend/src/org/jetbrains/rpc/CommandProcessor.kt new file mode 100644 index 000000000000..2614dcaf8697 --- /dev/null +++ b/platform/script-debugger/backend/src/org/jetbrains/rpc/CommandProcessor.kt @@ -0,0 +1,30 @@ +package org.jetbrains.rpc + +import com.intellij.openapi.diagnostic.Logger +import org.jetbrains.jsonProtocol.Request +import java.util.concurrent.atomic.AtomicInteger + +val LOG = Logger.getInstance(CommandProcessor::class.java) + +abstract class CommandProcessor() : CommandSenderBase(), MessageManager.Handler, INCOMING, INCOMING_WITH_SEQ, SUCCESS_RESPONSE>, ResultReader, MessageProcessor { + private val currentSequence = AtomicInteger() + protected val messageManager = MessageManager(this) + + override fun cancelWaitingRequests() { + messageManager.cancelWaitingRequests() + } + + override fun closed() { + messageManager.closed() + } + + override fun getUpdatedSequence(message: Request): Int { + val id = currentSequence.incrementAndGet() + message.finalize(id) + return id + } + + override final fun doSend(message: Request, callback: CommandSenderBase.RequestPromise) { + messageManager.send(message, callback) + } +} \ No newline at end of file diff --git a/platform/script-debugger/backend/src/org/jetbrains/rpc/CommandSender.java b/platform/script-debugger/backend/src/org/jetbrains/rpc/CommandSender.java deleted file mode 100644 index 87618be3bb93..000000000000 --- a/platform/script-debugger/backend/src/org/jetbrains/rpc/CommandSender.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.jetbrains.rpc; - -import org.jetbrains.annotations.NotNull; -import org.jetbrains.concurrency.Promise; -import org.jetbrains.jsonProtocol.Request; - -public interface CommandSender { - @NotNull - Promise send(@NotNull Request message); -} \ No newline at end of file diff --git a/platform/script-debugger/backend/src/org/jetbrains/rpc/CommandSenderBase.java b/platform/script-debugger/backend/src/org/jetbrains/rpc/CommandSenderBase.java deleted file mode 100644 index 41ecacf14420..000000000000 --- a/platform/script-debugger/backend/src/org/jetbrains/rpc/CommandSenderBase.java +++ /dev/null @@ -1,49 +0,0 @@ -package org.jetbrains.rpc; - -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.concurrency.AsyncPromise; -import org.jetbrains.concurrency.Promise; -import org.jetbrains.jsonProtocol.Request; - -public abstract class CommandSenderBase implements CommandSender { - protected abstract void send(@NotNull Request message, @NotNull RequestPromise callback); - - @Override - @NotNull - public final Promise send(@NotNull Request request) { - RequestPromise callback = new RequestPromise(request.getMethodName()); - send(request, callback); - return callback; - } - - protected static final class RequestPromise extends AsyncPromise implements RequestCallback { - private final String methodName; - - public RequestPromise(@Nullable String methodName) { - this.methodName = methodName; - } - - @Override - public void onSuccess(@Nullable SUCCESS_RESPONSE response, @Nullable ResultReader resultReader) { - try { - if (resultReader == null || response == null) { - //noinspection unchecked - setResult((RESULT)response); - } - else { - setResult(methodName == null ? null : resultReader.readResult(methodName, response)); - } - } - catch (Throwable e) { - CommandProcessor.LOG.error(e); - setError(e); - } - } - - @Override - public void onError(@NotNull Throwable error) { - setError(error); - } - } -} \ No newline at end of file diff --git a/platform/script-debugger/backend/src/org/jetbrains/rpc/CommandSenderBase.kt b/platform/script-debugger/backend/src/org/jetbrains/rpc/CommandSenderBase.kt new file mode 100644 index 000000000000..c9c799014f4f --- /dev/null +++ b/platform/script-debugger/backend/src/org/jetbrains/rpc/CommandSenderBase.kt @@ -0,0 +1,43 @@ +package org.jetbrains.rpc + +import org.jetbrains.concurrency.AsyncPromise +import org.jetbrains.concurrency.Promise +import org.jetbrains.jsonProtocol.Request + +abstract class CommandSenderBase { + protected abstract fun doSend(message: Request, callback: RequestPromise) + + fun send(message: Request): Promise { + val callback = RequestPromise(message.methodName) + doSend(message, callback) + return callback + } + + protected class RequestPromise(private val methodName: String?) : AsyncPromise(), RequestCallback { + @Suppress("BASE_WITH_NULLABLE_UPPER_BOUND") + override fun onSuccess(response: SUCCESS_RESPONSE?, resultReader: ResultReader?) { + try { + if (resultReader == null || response == null) { + @Suppress("UNCHECKED_CAST") + setResult(response as RESULT) + } + else { + if (methodName == null) { + setResult(null) + } + else { + setResult(resultReader.readResult(methodName, response)) + } + } + } + catch (e: Throwable) { + LOG.error(e) + setError(e) + } + } + + override fun onError(error: Throwable) { + setError(error) + } + } +} \ No newline at end of file diff --git a/platform/script-debugger/backend/src/org/jetbrains/rpc/ErrorConsumer.java b/platform/script-debugger/backend/src/org/jetbrains/rpc/ErrorConsumer.java deleted file mode 100644 index d081df871648..000000000000 --- a/platform/script-debugger/backend/src/org/jetbrains/rpc/ErrorConsumer.java +++ /dev/null @@ -1,8 +0,0 @@ -package org.jetbrains.rpc; - -import com.intellij.openapi.util.ActionCallback; -import org.jetbrains.annotations.Nullable; - -public interface ErrorConsumer { - void consume(String errorMessage, @Nullable ERROR_DETAILS errorDetails, C callback); -} \ No newline at end of file diff --git a/platform/script-debugger/backend/src/org/jetbrains/rpc/MessageManager.java b/platform/script-debugger/backend/src/org/jetbrains/rpc/MessageManager.java deleted file mode 100644 index 4421b199b735..000000000000 --- a/platform/script-debugger/backend/src/org/jetbrains/rpc/MessageManager.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright 2000-2014 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.jetbrains.rpc; - -import com.intellij.util.containers.ConcurrentIntObjectMap; -import com.intellij.util.containers.ContainerUtil; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.concurrency.Promise; - -import java.io.IOException; -import java.util.Arrays; - -/** - * @param type of outgoing message - * @param type of incoming message - * @param type of incoming message that is a command (has sequence number) - */ -public final class MessageManager extends MessageManagerBase { - private final ConcurrentIntObjectMap> callbackMap = ContainerUtil.createConcurrentIntObjectMap(); - private final Handler handler; - - public MessageManager(Handler handler) { - this.handler = handler; - } - - public interface Handler { - int getUpdatedSequence(@NotNull OUTGOING message); - - boolean write(@NotNull OUTGOING message) throws IOException; - - INCOMING_WITH_SEQ readIfHasSequence(INCOMING incoming); - - int getSequence(INCOMING_WITH_SEQ incomingWithSeq); - - void acceptNonSequence(INCOMING incoming); - - void call(INCOMING_WITH_SEQ response, RequestCallback callback); - } - - public void send(@NotNull REQUEST message, @NotNull RequestCallback callback) { - if (rejectIfClosed(callback)) { - return; - } - - int sequence = handler.getUpdatedSequence(message); - callbackMap.put(sequence, callback); - - boolean success; - try { - success = handler.write(message); - } - catch (Throwable e) { - try { - failedToSend(sequence); - } - finally { - CommandProcessor.LOG.error("Failed to send", e); - } - return; - } - - if (!success) { - failedToSend(sequence); - } - } - - private void failedToSend(int sequence) { - RequestCallback callback = callbackMap.remove(sequence); - if (callback != null) { - callback.onError(Promise.createError("Failed to send")); - } - } - - public void processIncoming(INCOMING incomingParsed) { - INCOMING_WITH_SEQ commandResponse = handler.readIfHasSequence(incomingParsed); - if (commandResponse == null) { - if (closed) { - // just ignore - CommandProcessor.LOG.info("Connection closed, ignore incoming"); - } - else { - handler.acceptNonSequence(incomingParsed); - } - return; - } - - RequestCallback callback = getCallbackAndRemove(handler.getSequence(commandResponse)); - if (rejectIfClosed(callback)) { - return; - } - - try { - handler.call(commandResponse, callback); - } - catch (Throwable e) { - callback.onError(e); - CommandProcessor.LOG.error("Failed to dispatch response to callback", e); - } - } - - public RequestCallback getCallbackAndRemove(int id) { - RequestCallback callback = callbackMap.remove(id); - if (callback == null) { - throw new IllegalArgumentException("Cannot find callback with id " + id); - } - return callback; - } - - public void cancelWaitingRequests() { - // we should call them in the order they have been submitted - ConcurrentIntObjectMap> map = callbackMap; - int[] keys = map.keys(); - Arrays.sort(keys); - for (int key : keys) { - RequestCallback callback = map.get(key); - if (callback != null) { - rejectCallback(callback); - } - } - } -} \ No newline at end of file diff --git a/platform/script-debugger/backend/src/org/jetbrains/rpc/MessageManager.kt b/platform/script-debugger/backend/src/org/jetbrains/rpc/MessageManager.kt new file mode 100644 index 000000000000..5f638734bc47 --- /dev/null +++ b/platform/script-debugger/backend/src/org/jetbrains/rpc/MessageManager.kt @@ -0,0 +1,110 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.rpc + +import com.intellij.util.containers.ContainerUtil +import org.jetbrains.concurrency.Promise +import java.io.IOException +import java.util.* + +class MessageManager(private val handler: MessageManager.Handler) : MessageManagerBase() { + private val callbackMap = ContainerUtil.createConcurrentIntObjectMap>() + + interface Handler { + fun getUpdatedSequence(message: OUTGOING): Int + + @Throws(IOException::class) + fun write(message: OUTGOING): Boolean + + fun readIfHasSequence(incoming: INCOMING): INCOMING_WITH_SEQ? + + fun getSequence(incomingWithSeq: INCOMING_WITH_SEQ): Int + + fun acceptNonSequence(incoming: INCOMING) + + fun call(response: INCOMING_WITH_SEQ, callback: RequestCallback) + } + + fun send(message: REQUEST, callback: RequestCallback) { + if (rejectIfClosed(callback)) { + return + } + + val sequence = handler.getUpdatedSequence(message) + callbackMap.put(sequence, callback) + + val success: Boolean + try { + success = handler.write(message) + } + catch (e: Throwable) { + try { + failedToSend(sequence) + } + finally { + LOG.error("Failed to send", e) + } + return + } + + if (!success) { + failedToSend(sequence) + } + } + + private fun failedToSend(sequence: Int) { + callbackMap.remove(sequence)?.onError(Promise.createError("Failed to send")) + } + + fun processIncoming(incomingParsed: INCOMING) { + val commandResponse = handler.readIfHasSequence(incomingParsed) + if (commandResponse == null) { + if (closed) { + // just ignore + LOG.info("Connection closed, ignore incoming") + } + else { + handler.acceptNonSequence(incomingParsed) + } + return + } + + val callback = getCallbackAndRemove(handler.getSequence(commandResponse)) + if (rejectIfClosed(callback)) { + return + } + + try { + handler.call(commandResponse, callback) + } + catch (e: Throwable) { + callback.onError(e) + LOG.error("Failed to dispatch response to callback", e) + } + } + + fun getCallbackAndRemove(id: Int) = callbackMap.remove(id) ?: throw IllegalArgumentException("Cannot find callback with id $id") + + fun cancelWaitingRequests() { + // we should call them in the order they have been submitted + val map = callbackMap + val keys = map.keys() + Arrays.sort(keys) + for (key in keys) { + map.get(key)?.reject() + } + } +} \ No newline at end of file diff --git a/platform/script-debugger/backend/src/org/jetbrains/rpc/MessageManagerBase.java b/platform/script-debugger/backend/src/org/jetbrains/rpc/MessageManagerBase.java deleted file mode 100644 index 079aa83b4684..000000000000 --- a/platform/script-debugger/backend/src/org/jetbrains/rpc/MessageManagerBase.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.jetbrains.rpc; - -import org.jetbrains.annotations.NotNull; -import org.jetbrains.concurrency.Promise; - -public abstract class MessageManagerBase { - protected volatile boolean closed; - - protected final boolean rejectIfClosed(RequestCallback callback) { - if (closed) { - callback.onError(Promise.createError("Connection closed")); - return true; - } - return false; - } - - public final void closed() { - closed = true; - } - - protected static void rejectCallback(@NotNull RequestCallback callback) { - callback.onError(Promise.createError("Connection closed")); - } -} \ No newline at end of file diff --git a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/ValueNodeAsyncFunction.java b/platform/script-debugger/backend/src/org/jetbrains/rpc/MessageManagerBase.kt similarity index 56% rename from platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/ValueNodeAsyncFunction.java rename to platform/script-debugger/backend/src/org/jetbrains/rpc/MessageManagerBase.kt index 15d685b492f9..aa5d08171c7c 100644 --- a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/ValueNodeAsyncFunction.java +++ b/platform/script-debugger/backend/src/org/jetbrains/rpc/MessageManagerBase.kt @@ -13,21 +13,26 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.jetbrains.debugger; +package org.jetbrains.rpc -import org.jetbrains.annotations.NotNull; -import org.jetbrains.concurrency.AsyncFunction; -import org.jetbrains.concurrency.Obsolescent; +import org.jetbrains.concurrency.Promise -public abstract class ValueNodeAsyncFunction implements AsyncFunction, Obsolescent { - private final Obsolescent node; +abstract class MessageManagerBase { + @Volatile protected var closed = false - protected ValueNodeAsyncFunction(@NotNull Obsolescent node) { - this.node = node; + protected fun rejectIfClosed(callback: RequestCallback<*>): Boolean { + if (closed) { + callback.onError(Promise.createError("Connection closed")) + return true + } + return false } - @Override - public final boolean isObsolete() { - return node.isObsolete(); + fun closed() { + closed = true } } + +fun RequestCallback<*>.reject() { + onError(Promise.createError("Connection closed")) +} \ No newline at end of file diff --git a/platform/script-debugger/backend/src/org/jetbrains/rpc/MessageProcessor.java b/platform/script-debugger/backend/src/org/jetbrains/rpc/MessageProcessor.java deleted file mode 100644 index 719d8b033040..000000000000 --- a/platform/script-debugger/backend/src/org/jetbrains/rpc/MessageProcessor.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.jetbrains.rpc; - -import org.jetbrains.annotations.NotNull; -import org.jetbrains.concurrency.Promise; -import org.jetbrains.jsonProtocol.Request; - -public interface MessageProcessor { - void cancelWaitingRequests(); - - void closed(); - - @NotNull - Promise send(@NotNull Request message); -} \ No newline at end of file diff --git a/platform/script-debugger/backend/src/org/jetbrains/rpc/MessageProcessor.kt b/platform/script-debugger/backend/src/org/jetbrains/rpc/MessageProcessor.kt new file mode 100644 index 000000000000..7c5523090ab2 --- /dev/null +++ b/platform/script-debugger/backend/src/org/jetbrains/rpc/MessageProcessor.kt @@ -0,0 +1,12 @@ +package org.jetbrains.rpc + +import org.jetbrains.concurrency.Promise +import org.jetbrains.jsonProtocol.Request + +interface MessageProcessor { + fun cancelWaitingRequests() + + fun closed() + + fun send(message: Request): Promise +} \ No newline at end of file diff --git a/platform/script-debugger/backend/src/org/jetbrains/rpc/MessageWriter.java b/platform/script-debugger/backend/src/org/jetbrains/rpc/MessageWriter.java deleted file mode 100644 index 07dbee19f922..000000000000 --- a/platform/script-debugger/backend/src/org/jetbrains/rpc/MessageWriter.java +++ /dev/null @@ -1,26 +0,0 @@ -package org.jetbrains.rpc; - -import com.intellij.openapi.vfs.CharsetToolkit; -import com.intellij.util.BooleanFunction; -import io.netty.buffer.ByteBuf; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.jsonProtocol.Request; - -import static org.jetbrains.rpc.CommandProcessor.LOG; - -public abstract class MessageWriter implements BooleanFunction { - @Override - public boolean fun(@NotNull Request message) { - ByteBuf content = message.getBuffer(); - if (isDebugLoggingEnabled()) { - LOG.debug("OUT: " + content.toString(CharsetToolkit.UTF8_CHARSET)); - } - return write(content); - } - - protected boolean isDebugLoggingEnabled() { - return LOG.isDebugEnabled(); - } - - protected abstract boolean write(@NotNull ByteBuf content); -} \ No newline at end of file diff --git a/platform/script-debugger/backend/src/org/jetbrains/rpc/MessageWriter.kt b/platform/script-debugger/backend/src/org/jetbrains/rpc/MessageWriter.kt new file mode 100644 index 000000000000..690f8cf9f3c2 --- /dev/null +++ b/platform/script-debugger/backend/src/org/jetbrains/rpc/MessageWriter.kt @@ -0,0 +1,21 @@ +package org.jetbrains.rpc + +import com.intellij.openapi.vfs.CharsetToolkit +import com.intellij.util.BooleanFunction +import io.netty.buffer.ByteBuf +import org.jetbrains.jsonProtocol.Request + +abstract class MessageWriter : BooleanFunction> { + override fun `fun`(message: Request): Boolean { + val content = message.buffer + if (isDebugLoggingEnabled) { + LOG.debug("OUT: ${content.toString(CharsetToolkit.UTF8_CHARSET)}") + } + return write(content) + } + + protected open val isDebugLoggingEnabled: Boolean + get() = LOG.isDebugEnabled + + protected abstract fun write(content: ByteBuf): Boolean +} \ No newline at end of file diff --git a/platform/script-debugger/backend/src/org/jetbrains/rpc/RequestCallback.java b/platform/script-debugger/backend/src/org/jetbrains/rpc/RequestCallback.java deleted file mode 100644 index 409cff797923..000000000000 --- a/platform/script-debugger/backend/src/org/jetbrains/rpc/RequestCallback.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.jetbrains.rpc; - -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -public interface RequestCallback { - void onSuccess(@Nullable SUCCESS_RESPONSE successResponse, @Nullable ResultReader resultReader); - - void onError(@NotNull Throwable error); -} \ No newline at end of file diff --git a/platform/script-debugger/backend/src/org/jetbrains/rpc/RequestCallback.kt b/platform/script-debugger/backend/src/org/jetbrains/rpc/RequestCallback.kt new file mode 100644 index 000000000000..530aa7c586d2 --- /dev/null +++ b/platform/script-debugger/backend/src/org/jetbrains/rpc/RequestCallback.kt @@ -0,0 +1,8 @@ +package org.jetbrains.rpc + +@Suppress("BASE_WITH_NULLABLE_UPPER_BOUND") +interface RequestCallback { + fun onSuccess(response: SUCCESS_RESPONSE?, resultReader: ResultReader?) + + fun onError(error: Throwable) +} \ No newline at end of file diff --git a/platform/script-debugger/backend/src/org/jetbrains/rpc/ResultReader.java b/platform/script-debugger/backend/src/org/jetbrains/rpc/ResultReader.java deleted file mode 100644 index 4bb055c754d2..000000000000 --- a/platform/script-debugger/backend/src/org/jetbrains/rpc/ResultReader.java +++ /dev/null @@ -1,7 +0,0 @@ -package org.jetbrains.rpc; - -import org.jetbrains.annotations.NotNull; - -public interface ResultReader { - RESULT readResult(@NotNull String readMethodName, @NotNull RESPONSE successResponse); -} \ No newline at end of file diff --git a/platform/script-debugger/backend/src/org/jetbrains/rpc/ResultReader.kt b/platform/script-debugger/backend/src/org/jetbrains/rpc/ResultReader.kt new file mode 100644 index 000000000000..5aeb94e0c369 --- /dev/null +++ b/platform/script-debugger/backend/src/org/jetbrains/rpc/ResultReader.kt @@ -0,0 +1,5 @@ +package org.jetbrains.rpc + +interface ResultReader { + fun readResult(readMethodName: String, successResponse: RESPONSE): RESULT +} \ No newline at end of file diff --git a/platform/script-debugger/debugger-ui/src/com/jetbrains/javascript/debugger/NameMapper.kt b/platform/script-debugger/debugger-ui/src/com/jetbrains/javascript/debugger/NameMapper.kt index 6e8a7bbe9b9e..44b90893d502 100644 --- a/platform/script-debugger/debugger-ui/src/com/jetbrains/javascript/debugger/NameMapper.kt +++ b/platform/script-debugger/debugger-ui/src/com/jetbrains/javascript/debugger/NameMapper.kt @@ -24,8 +24,8 @@ import gnu.trove.THashMap import org.jetbrains.debugger.sourcemap.MappingEntry import org.jetbrains.debugger.sourcemap.MappingList import org.jetbrains.debugger.sourcemap.SourceMap +import org.jetbrains.rpc.LOG -import org.jetbrains.rpc.CommandProcessor.LOG private val S1 = ",()[]{}=" // don't trim trailing .&: - could be part of expression @@ -73,7 +73,7 @@ open class NameMapper(private val document: Document, private val generatedDocum protected open fun extractName(rawGeneratedName: CharSequence) = NAME_TRIMMER.trimFrom(rawGeneratedName) companion object { - protected val NAME_TRIMMER = CharMatcher.INVISIBLE.or(CharMatcher.anyOf(S1 + ".&:")) + val NAME_TRIMMER = CharMatcher.INVISIBLE.or(CharMatcher.anyOf(S1 + ".&:")) fun trimName(rawGeneratedName: CharSequence, isLastToken: Boolean) = (if (isLastToken) NAME_TRIMMER else OPERATOR_TRIMMER).trimFrom(rawGeneratedName) } diff --git a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/BasicDebuggerViewSupport.kt b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/BasicDebuggerViewSupport.kt index 4cf4a1993583..49914ea7b238 100644 --- a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/BasicDebuggerViewSupport.kt +++ b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/BasicDebuggerViewSupport.kt @@ -18,7 +18,6 @@ package org.jetbrains.debugger import com.intellij.xdebugger.evaluation.XDebuggerEvaluator -import com.intellij.xdebugger.frame.XNavigatable import com.intellij.xdebugger.frame.XValueNode import org.jetbrains.concurrency.Promise import org.jetbrains.debugger.frame.CallFrameView @@ -41,9 +40,6 @@ open class BasicDebuggerViewSupport : MemberFilter, DebuggerViewSupport { throw UnsupportedOperationException() } - override fun computeSourcePosition(name: String, variable: Variable, context: VariableContext, navigatable: XNavigatable) { - } - override fun getMemberFilter(context: VariableContext): Promise { return defaultMemberFilterPromise } diff --git a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/DebugProcessImpl.kt b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/DebugProcessImpl.kt index ad3c7b908927..a41e84c164dc 100644 --- a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/DebugProcessImpl.kt +++ b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/DebugProcessImpl.kt @@ -37,11 +37,11 @@ import org.jetbrains.debugger.frame.SuspendContextImpl import java.util.concurrent.ConcurrentMap import java.util.concurrent.atomic.AtomicBoolean -public abstract class DebugProcessImpl>(session: XDebugSession, - public val connection: C, - private val editorsProvider: XDebuggerEditorsProvider, - private val smartStepIntoHandler: XSmartStepIntoHandler<*>?, - protected val executionResult: ExecutionResult?) : XDebugProcess(session) { +abstract class DebugProcessImpl>(session: XDebugSession, + val connection: C, + private val editorsProvider: XDebuggerEditorsProvider, + private val smartStepIntoHandler: XSmartStepIntoHandler<*>?, + protected val executionResult: ExecutionResult?) : XDebugProcess(session) { protected val repeatStepInto: AtomicBoolean = AtomicBoolean() @Volatile protected var lastStep: StepAction? = null @Volatile protected var lastCallFrame: CallFrame? = null @@ -50,7 +50,7 @@ public abstract class DebugProcessImpl>(session: XDebugSessi protected val urlToFileCache: ConcurrentMap = ContainerUtil.newConcurrentMap() - public var processBreakpointConditionsAtIdeSide: Boolean = false + var processBreakpointConditionsAtIdeSide: Boolean = false private val _breakpointHandlers: Array> by lazy(LazyThreadSafetyMode.NONE) { createBreakpointHandlers() } @@ -91,13 +91,13 @@ public abstract class DebugProcessImpl>(session: XDebugSessi override final fun getEditorsProvider() = editorsProvider - public val vm: Vm? + val vm: Vm? get() = connection.vm protected abstract fun createBreakpointHandlers(): Array> private fun updateLastCallFrame() { - lastCallFrame = vm?.getSuspendContextManager()?.context?.topFrame + lastCallFrame = vm?.suspendContextManager?.context?.topFrame } override final fun checkCanPerformCommands() = vm != null @@ -130,14 +130,17 @@ public abstract class DebugProcessImpl>(session: XDebugSessi } // some VM (firefox for example) doesn't implement step out correctly, so, we need to fix it - protected open fun isVmStepOutCorrect(): Boolean = true + protected open fun isVmStepOutCorrect() = true override final fun resume() { continueVm(StepAction.CONTINUE) } - protected final fun continueVm(stepAction: StepAction) { - val suspendContextManager = vm!!.getSuspendContextManager() + /** + * You can override this method to avoid SuspendContextManager implementation, but it is not recommended. + */ + protected open fun continueVm(stepAction: StepAction) { + val suspendContextManager = vm!!.suspendContextManager if (stepAction === StepAction.CONTINUE) { if (suspendContextManager.context == null) { // on resumed we ask session to resume, and session then call our "resume", but we have already resumed, so, we don't need to send "continue" message @@ -155,11 +158,11 @@ public abstract class DebugProcessImpl>(session: XDebugSessi suspendContextManager.continueVm(stepAction, 1) } - protected final fun setOverlay() { - vm!!.getSuspendContextManager().setOverlayMessage("Paused in debugger") + protected fun setOverlay() { + vm!!.suspendContextManager.setOverlayMessage("Paused in debugger") } - protected final fun processBreakpoint(suspendContext: SuspendContext, breakpoint: XBreakpoint<*>, xSuspendContext: SuspendContextImpl) { + protected fun processBreakpoint(suspendContext: SuspendContext, breakpoint: XBreakpoint<*>, xSuspendContext: SuspendContextImpl) { val condition = breakpoint.conditionExpression?.expression if (!processBreakpointConditionsAtIdeSide || condition == null) { processBreakpointLogExpressionAndSuspend(breakpoint, xSuspendContext, suspendContext) @@ -214,7 +217,7 @@ public abstract class DebugProcessImpl>(session: XDebugSessi } override final fun startPausing() { - connection.vm.getSuspendContextManager().suspend().rejected(RejectErrorReporter(session, "Cannot pause")) + connection.vm.suspendContextManager.suspend().rejected(RejectErrorReporter(session, "Cannot pause")) } override final fun getCurrentStateMessage() = connection.state.message @@ -223,11 +226,11 @@ public abstract class DebugProcessImpl>(session: XDebugSessi override fun doGetProcessHandler() = executionResult?.processHandler ?: object : DefaultDebugProcessHandler() { override fun isSilentlyDestroyOnClose() = true } - public fun saveResolvedFile(url: Url, file: VirtualFile) { + fun saveResolvedFile(url: Url, file: VirtualFile) { urlToFileCache.putIfAbsent(url, file) } - public abstract fun getLocationsForBreakpoint(breakpoint: XLineBreakpoint<*>, onlySourceMappedBreakpoints: Boolean): List + abstract fun getLocationsForBreakpoint(breakpoint: XLineBreakpoint<*>, onlySourceMappedBreakpoints: Boolean): List } class LineBreakpointHandler(breakpointTypeClass: Class>, diff --git a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/DebuggerViewSupport.kt b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/DebuggerViewSupport.kt index cbaaf1d1d65c..dd363fbe0811 100644 --- a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/DebuggerViewSupport.kt +++ b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/DebuggerViewSupport.kt @@ -51,12 +51,13 @@ interface DebuggerViewSupport { */ fun canNavigateToSource(variable: Variable, context: VariableContext) = false - fun computeSourcePosition(name: String, variable: Variable, context: VariableContext, navigatable: XNavigatable) + fun computeSourcePosition(name: String, value: Value?, variable: Variable, context: VariableContext, navigatable: XNavigatable) { + } fun computeInlineDebuggerData(name: String, variable: Variable, context: VariableContext, callback: XInlineDebuggerDataCallback) = ThreeState.UNSURE // return null if you don't need to add additional properties - fun computeAdditionalObjectProperties(value: ObjectValue, variable: Variable, context: VariableContext, node: XCompositeNode): Promise? = null + fun computeAdditionalObjectProperties(value: ObjectValue, variable: Variable, context: VariableContext, node: XCompositeNode): Promise<*>? = null fun getMemberFilter(context: VariableContext): Promise diff --git a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/FunctionScopesValueGroup.java b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/FunctionScopesValueGroup.java deleted file mode 100644 index 28a7ed00829c..000000000000 --- a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/FunctionScopesValueGroup.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2000-2015 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.jetbrains.debugger; - -import com.intellij.util.Consumer; -import com.intellij.xdebugger.frame.XCompositeNode; -import com.intellij.xdebugger.frame.XValueChildrenList; -import com.intellij.xdebugger.frame.XValueGroup; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.concurrency.Promise; -import org.jetbrains.debugger.values.FunctionValue; -import org.jetbrains.rpc.CommandProcessor; - -import java.util.Arrays; - -class FunctionScopesValueGroup extends XValueGroup { - private final FunctionValue value; - private final VariableContext variableContext; - - public FunctionScopesValueGroup(@NotNull FunctionValue value, @NotNull VariableContext variableContext) { - super("Function scopes"); - - this.value = value; - this.variableContext = variableContext; - } - - @Override - public void computeChildren(@NotNull final XCompositeNode node) { - node.setAlreadySorted(true); - - value.resolve() - .done(new ObsolescentConsumer(node) { - @Override - public void consume(FunctionValue value) { - Scope[] scopes = value.getScopes(); - if (scopes == null || scopes.length == 0) { - node.addChildren(XValueChildrenList.EMPTY, true); - } - else { - ScopeVariablesGroup.createAndAddScopeList(node, Arrays.asList(scopes), variableContext, null); - } - } - }) - .rejected(new Consumer() { - @Override - public void consume(Throwable error) { - Promise.logError(CommandProcessor.LOG, error); - node.setErrorMessage(error.getMessage()); - } - }); - } -} \ No newline at end of file diff --git a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/FunctionScopesValueGroup.kt b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/FunctionScopesValueGroup.kt new file mode 100644 index 000000000000..9a045bc00963 --- /dev/null +++ b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/FunctionScopesValueGroup.kt @@ -0,0 +1,45 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.debugger + +import com.intellij.xdebugger.frame.XCompositeNode +import com.intellij.xdebugger.frame.XValueChildrenList +import com.intellij.xdebugger.frame.XValueGroup +import org.jetbrains.concurrency.Promise +import org.jetbrains.debugger.values.FunctionValue +import org.jetbrains.rpc.LOG +import java.util.* + +internal class FunctionScopesValueGroup(private val functionValue: FunctionValue, private val variableContext: VariableContext) : XValueGroup("Function scopes") { + override fun computeChildren(node: XCompositeNode) { + node.setAlreadySorted(true) + + functionValue.resolve() + .done(node) { + val scopes = it.scopes + if (scopes == null || scopes.size() == 0) { + node.addChildren(XValueChildrenList.EMPTY, true) + } + else { + createAndAddScopeList(node, Arrays.asList(*scopes), variableContext, null) + } + } + .rejected { + Promise.logError(LOG, it) + node.setErrorMessage(it.getMessage()!!) + } + } +} \ No newline at end of file diff --git a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/LineBreakpointManager.kt b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/LineBreakpointManager.kt index 9b94095582a6..0f38d7e56071 100644 --- a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/LineBreakpointManager.kt +++ b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/LineBreakpointManager.kt @@ -133,7 +133,7 @@ abstract class LineBreakpointManager(private val debugProcess: DebugProcessImpl< protected fun doSetBreakpoint(breakpoint: XLineBreakpoint<*>?, location: Location, isTemporary: Boolean): Breakpoint { if (breakpointResolvedListenerAdded.compareAndSet(false, true)) { - breakpointManager.addBreakpointListener(object : BreakpointManager.BreakpointListener { + breakpointManager.addBreakpointListener(object : BreakpointListener { override fun resolved(breakpoint: Breakpoint) { var breakpoints = synchronized (lock) { vmToIdeBreakpoint.get(breakpoint) } for (ideBreakpoint in breakpoints) { diff --git a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/MemberFilterWithNameMappings.kt b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/MemberFilterWithNameMappings.kt index 352ae2775ef2..a3c716ca9ea9 100644 --- a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/MemberFilterWithNameMappings.kt +++ b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/MemberFilterWithNameMappings.kt @@ -13,21 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/* - * Copyright 2000-2015 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ + + package org.jetbrains.debugger open class MemberFilterWithNameMappings(rawNameToSource: Map?) : MemberFilter { diff --git a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/ObsolescentConsumer.java b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/ObsolescentConsumer.java deleted file mode 100644 index e7cf5e1bf422..000000000000 --- a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/ObsolescentConsumer.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.jetbrains.debugger; - -import com.intellij.util.Consumer; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.concurrency.Obsolescent; - -@SuppressWarnings("ClassNameSameAsAncestorName") -public abstract class ObsolescentConsumer implements Obsolescent, Consumer { - private final Obsolescent obsolescent; - - protected ObsolescentConsumer(@NotNull Obsolescent obsolescent) { - this.obsolescent = obsolescent; - } - - @Override - public final boolean isObsolete() { - return obsolescent.isObsolete(); - } -} \ No newline at end of file diff --git a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/ProcessHandlerWrapper.kt b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/ProcessHandlerWrapper.kt index 6050748bbd38..b58bab56102a 100644 --- a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/ProcessHandlerWrapper.kt +++ b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/ProcessHandlerWrapper.kt @@ -19,10 +19,8 @@ import com.intellij.execution.KillableProcess import com.intellij.execution.process.ProcessAdapter import com.intellij.execution.process.ProcessEvent import com.intellij.execution.process.ProcessHandler -import com.intellij.openapi.diagnostic.Logger import com.intellij.xdebugger.XDebugProcess - -private val LOG: Logger = Logger.getInstance(ProcessHandlerWrapper::class.java) +import org.jetbrains.rpc.LOG class ProcessHandlerWrapper(private val debugProcess: XDebugProcess, private val handler: ProcessHandler) : ProcessHandler(), KillableProcess { init { diff --git a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/RejectErrorReporter.java b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/RejectErrorReporter.java index 85da0944f378..337ec586106e 100644 --- a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/RejectErrorReporter.java +++ b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/RejectErrorReporter.java @@ -21,7 +21,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.concurrency.AsyncPromise; import org.jetbrains.concurrency.Promise; -import org.jetbrains.rpc.CommandProcessor; +import org.jetbrains.rpc.CommandProcessorKt; public final class RejectErrorReporter implements Consumer { private final XDebugSession session; @@ -38,7 +38,7 @@ public final class RejectErrorReporter implements Consumer { @Override public void consume(Throwable error) { - Promise.logError(CommandProcessor.LOG, error); + Promise.logError(CommandProcessorKt.getLOG(), error); if (error != AsyncPromise.OBSOLETE_ERROR) { session.reportError((description == null ? "" : description + ": ") + error.getMessage()); } diff --git a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/ScopeVariablesGroup.java b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/ScopeVariablesGroup.java deleted file mode 100644 index 2d1ba1a36754..000000000000 --- a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/ScopeVariablesGroup.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright 2000-2015 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.jetbrains.debugger; - -import com.intellij.xdebugger.XDebuggerBundle; -import com.intellij.xdebugger.frame.XCompositeNode; -import com.intellij.xdebugger.frame.XValueChildrenList; -import com.intellij.xdebugger.frame.XValueGroup; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.annotations.TestOnly; -import org.jetbrains.concurrency.Promise; - -import java.util.List; - -public class ScopeVariablesGroup extends XValueGroup { - private final Scope scope; - private final VariableContext context; - - private final CallFrame callFrame; - - public ScopeVariablesGroup(@NotNull Scope scope, @NotNull VariableContext parentContext, @Nullable CallFrame callFrame) { - super(createScopeNodeName(scope)); - - this.scope = scope; - context = createVariableContext(scope, parentContext, callFrame); - this.callFrame = scope.getType() == Scope.Type.LOCAL ? callFrame : null; - } - - // public only for tests - @NotNull - public static VariableContext createVariableContext(@NotNull Scope scope, @NotNull VariableContext parentContext, @Nullable CallFrame callFrame) { - if (callFrame == null || scope.getType() == Scope.Type.LIBRARY) { - // functions scopes - we can watch variables only from global scope - return new ParentlessVariableContext(parentContext, scope, scope.getType() == Scope.Type.GLOBAL); - } - else { - return new VariableContextWrapper(parentContext, scope); - } - } - - @TestOnly - @NotNull - public Scope getScope() { - return scope; - } - - public static void createAndAddScopeList(@NotNull XCompositeNode node, @NotNull List scopes, @NotNull VariableContext context, @Nullable CallFrame callFrame) { - XValueChildrenList list = new XValueChildrenList(scopes.size()); - for (Scope scope : scopes) { - list.addTopGroup(new ScopeVariablesGroup(scope, context, callFrame)); - } - node.addChildren(list, true); - } - - private static String createScopeNodeName(@NotNull Scope scope) { - switch (scope.getType()) { - case GLOBAL: - return XDebuggerBundle.message("scope.global"); - case LOCAL: - return XDebuggerBundle.message("scope.local"); - case WITH: - return XDebuggerBundle.message("scope.with"); - case CLOSURE: - return XDebuggerBundle.message("scope.closure"); - case CATCH: - return XDebuggerBundle.message("scope.catch"); - case LIBRARY: - return XDebuggerBundle.message("scope.library"); - case INSTANCE: - return XDebuggerBundle.message("scope.instance"); - case CLASS: - return XDebuggerBundle.message("scope.class"); - case UNKNOWN: - return XDebuggerBundle.message("scope.unknown"); - default: - throw new IllegalArgumentException(scope.getType().name()); - } - } - - @Override - public boolean isAutoExpand() { - return scope.getType() == Scope.Type.LOCAL || scope.getType() == Scope.Type.CATCH; - } - - @Nullable - @Override - public String getComment() { - String className = scope.getDescription(); - return "Object".equals(className) ? null : className; - } - - @Override - public void computeChildren(final @NotNull XCompositeNode node) { - Promise promise = VariablesKt.processScopeVariables(scope, node, context, callFrame == null); - if (callFrame != null) { - promise.done(new ObsolescentConsumer(node) { - @Override - public void consume(Void ignored) { - callFrame.getReceiverVariable() - .done(new ObsolescentConsumer(node) { - @Override - public void consume(Variable variable) { - node.addChildren(variable == null ? XValueChildrenList.EMPTY : XValueChildrenList.singleton(VariableViewKt.VariableView(variable, context)), true); - } - }) - .rejected(new ObsolescentConsumer(node) { - @Override - public void consume(@Nullable Throwable error) { - node.addChildren(XValueChildrenList.EMPTY, true); - } - }); - } - }); - } - } - - private static final class ParentlessVariableContext extends VariableContextWrapper { - private final boolean watchableAsEvaluationExpression; - - public ParentlessVariableContext(@NotNull VariableContext parentContext, @NotNull Scope scope, boolean watchableAsEvaluationExpression) { - super(parentContext, scope); - - this.watchableAsEvaluationExpression = watchableAsEvaluationExpression; - } - - @Override - public boolean watchableAsEvaluationExpression() { - return watchableAsEvaluationExpression; - } - - @Nullable - @Override - public VariableContext getParent() { - return null; - } - } -} \ No newline at end of file diff --git a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/ScopeVariablesGroup.kt b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/ScopeVariablesGroup.kt new file mode 100644 index 000000000000..c88fee5ccdfa --- /dev/null +++ b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/ScopeVariablesGroup.kt @@ -0,0 +1,89 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.debugger + +import com.intellij.xdebugger.XDebuggerBundle +import com.intellij.xdebugger.frame.XCompositeNode +import com.intellij.xdebugger.frame.XValueChildrenList +import com.intellij.xdebugger.frame.XValueGroup + +class ScopeVariablesGroup(val scope: Scope, parentContext: VariableContext, callFrame: CallFrame?) : XValueGroup(scope.createScopeNodeName()) { + private val context = createVariableContext(scope, parentContext, callFrame) + + private val callFrame = if (scope.type == Scope.Type.LOCAL) callFrame else null + + override fun isAutoExpand() = scope.type == Scope.Type.LOCAL || scope.type == Scope.Type.CATCH + + override fun getComment(): String? { + val className = scope.description + return if ("Object" == className) null else className + } + + override fun computeChildren(node: XCompositeNode) { + val promise = processScopeVariables(scope, node, context, callFrame == null) + if (callFrame == null) { + return + } + + promise + .done(node) { + callFrame.receiverVariable + .done(node) { node.addChildren(if (it == null) XValueChildrenList.EMPTY else XValueChildrenList.singleton(VariableView(it, context)), true) } + .rejected(node) { node.addChildren(XValueChildrenList.EMPTY, true) } + } + } +} + +fun createAndAddScopeList(node: XCompositeNode, scopes: List, context: VariableContext, callFrame: CallFrame?) { + val list = XValueChildrenList(scopes.size()) + for (scope in scopes) { + list.addTopGroup(ScopeVariablesGroup(scope, context, callFrame)) + } + node.addChildren(list, true) +} + +fun createVariableContext(scope: Scope, parentContext: VariableContext, callFrame: CallFrame?): VariableContext { + if (callFrame == null || scope.type == Scope.Type.LIBRARY) { + // functions scopes - we can watch variables only from global scope + return ParentlessVariableContext(parentContext, scope, scope.type == Scope.Type.GLOBAL) + } + else { + return VariableContextWrapper(parentContext, scope) + } +} + +private class ParentlessVariableContext(parentContext: VariableContext, scope: Scope, private val watchableAsEvaluationExpression: Boolean) : VariableContextWrapper(parentContext, scope) { + override fun watchableAsEvaluationExpression() = watchableAsEvaluationExpression + + override fun getParent() = null +} + +private fun Scope.createScopeNodeName(): String { + when (type) { + Scope.Type.GLOBAL -> return XDebuggerBundle.message("scope.global") + Scope.Type.LOCAL -> return XDebuggerBundle.message("scope.local") + Scope.Type.WITH -> return XDebuggerBundle.message("scope.with") + Scope.Type.CLOSURE -> return XDebuggerBundle.message("scope.closure") + Scope.Type.CATCH -> return XDebuggerBundle.message("scope.catch") + Scope.Type.LIBRARY -> return XDebuggerBundle.message("scope.library") + Scope.Type.INSTANCE -> return XDebuggerBundle.message("scope.instance") + Scope.Type.CLASS -> return XDebuggerBundle.message("scope.class") + Scope.Type.BLOCK -> return XDebuggerBundle.message("scope.block") + Scope.Type.SCRIPT -> return XDebuggerBundle.message("scope.script") + Scope.Type.UNKNOWN -> return XDebuggerBundle.message("scope.unknown") + else -> throw IllegalArgumentException(type.name()) + } +} \ No newline at end of file diff --git a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/ValueNodeAsyncFunction.kt b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/ValueNodeAsyncFunction.kt new file mode 100644 index 000000000000..5fc903e4afb2 --- /dev/null +++ b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/ValueNodeAsyncFunction.kt @@ -0,0 +1,46 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.debugger + +import com.intellij.util.Consumer +import org.jetbrains.concurrency.AsyncFunction +import org.jetbrains.concurrency.Obsolescent +import org.jetbrains.concurrency.Promise + +abstract class ValueNodeAsyncFunction protected constructor(private val node: Obsolescent) : AsyncFunction, Obsolescent { + override fun isObsolete() = node.isObsolete +} + +inline fun Promise.thenAsync(node: Obsolescent, crossinline handler: (T) -> Promise) = then(object : ValueNodeAsyncFunction(node) { + override fun `fun`(param: T) = handler(param) +}) + +@Suppress("UNCHECKED_CAST") +inline fun Promise.thenAsyncVoid(node: Obsolescent, crossinline handler: (T) -> Promise<*>) = then(object : ValueNodeAsyncFunction(node) { + override fun `fun`(param: T) = handler(param) as Promise +}) + +inline fun Promise.done(node: Obsolescent, crossinline handler: (T) -> Unit) = done(object : ObsolescentConsumer(node) { + override fun consume(param: T) = handler(param) +}) + +inline fun Promise.rejected(node: Obsolescent, crossinline handler: (Throwable) -> Unit) = rejected(object : ObsolescentConsumer(node) { + override fun consume(param: Throwable) = handler(param) +}) + +abstract class ObsolescentConsumer(private val obsolescent: Obsolescent) : Obsolescent, Consumer { + override fun isObsolete() = obsolescent.isObsolete +} \ No newline at end of file diff --git a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/VariableView.kt b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/VariableView.kt index 8e2e8d0b38a2..9ec9e0114651 100644 --- a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/VariableView.kt +++ b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/VariableView.kt @@ -31,7 +31,6 @@ import com.intellij.xdebugger.frame.presentation.XKeywordValuePresentation import com.intellij.xdebugger.frame.presentation.XNumericValuePresentation import com.intellij.xdebugger.frame.presentation.XStringValuePresentation import com.intellij.xdebugger.frame.presentation.XValuePresentation -import org.jetbrains.concurrency.ObsolescentAsyncFunction import org.jetbrains.concurrency.Promise import org.jetbrains.debugger.values.* import java.util.* @@ -68,21 +67,17 @@ class VariableView(name: String, private val variable: Variable, private val con if (variable !is ObjectProperty || variable.getter == null) { // it is "used" expression (WEB-6779 Debugger/Variables: Automatically show used variables) - evaluateContext.evaluate(variable.name).done(object : ObsolescentConsumer(node) { - override fun consume(result: EvaluateResult) { - if (result.wasThrown) { + evaluateContext.evaluate(variable.name) + .done(node) { + if (it.wasThrown) { setEvaluatedValue(viewSupport.transformErrorOnGetUsedReferenceValue(value, null), null, node) } else { - value = result.value - computePresentation(result.value, node) + value = it.value + computePresentation(it.value, node) } } - }).rejected(object : ObsolescentConsumer(node) { - override fun consume(error: Throwable) { - setEvaluatedValue(viewSupport.transformErrorOnGetUsedReferenceValue(null, error.getMessage()), error.getMessage(), node) - } - }) + .rejected(node) { setEvaluatedValue(viewSupport.transformErrorOnGetUsedReferenceValue(null, it.getMessage()), it.getMessage(), node) } return } @@ -95,12 +90,11 @@ class VariableView(name: String, private val variable: Variable, private val con override fun startEvaluation(callback: XFullValueEvaluator.XFullValueEvaluationCallback) { val valueModifier = variable.valueModifier assert(valueModifier != null) - valueModifier!!.evaluateGet(variable, evaluateContext).done(object : ObsolescentConsumer(node) { - override fun consume(value: Value) { + valueModifier!!.evaluateGet(variable, evaluateContext) + .done(node) { callback.evaluated("") - setEvaluatedValue(value, null, node) + setEvaluatedValue(it, null, node) } - }) } }.setShowValuePopup(false)) } @@ -116,7 +110,6 @@ class VariableView(name: String, private val variable: Variable, private val con } private fun computePresentation(value: Value, node: XValueNode) { - val valueString = value.valueString when (value.type) { ValueType.OBJECT, ValueType.NODE -> context.viewSupport.computeObjectPresentation((value as ObjectValue), variable, context, node, icon) @@ -124,20 +117,20 @@ class VariableView(name: String, private val variable: Variable, private val con ValueType.ARRAY -> context.viewSupport.computeArrayPresentation(value, variable, context, node, icon) - ValueType.BOOLEAN, ValueType.NULL, ValueType.UNDEFINED -> node.setPresentation(icon, XKeywordValuePresentation(valueString), false) + ValueType.BOOLEAN, ValueType.NULL, ValueType.UNDEFINED -> node.setPresentation(icon, XKeywordValuePresentation(value.valueString!!), false) - ValueType.NUMBER -> node.setPresentation(icon, createNumberPresentation(valueString), false) + ValueType.NUMBER -> node.setPresentation(icon, createNumberPresentation(value.valueString!!), false) ValueType.STRING -> { - node.setPresentation(icon, XStringValuePresentation(valueString), false) + node.setPresentation(icon, XStringValuePresentation(value.valueString!!), false) // isTruncated in terms of debugger backend, not in our terms (i.e. sometimes we cannot control truncation), // so, even in case of StringValue, we check value string length - if ((value is StringValue && value.isTruncated) || valueString.length() > XValueNode.MAX_VALUE_LENGTH) { + if ((value is StringValue && value.isTruncated) || value.valueString!!.length() > XValueNode.MAX_VALUE_LENGTH) { node.setFullValueEvaluator(MyFullValueEvaluator(value)) } } - else -> node.setPresentation(icon, null, valueString, true) + else -> node.setPresentation(icon, null, value.valueString!!, true) } } @@ -181,32 +174,19 @@ class VariableView(name: String, private val variable: Variable, private val con promises.add(computeNamedProperties(objectValue, node, !hasIndexedProperties && additionalProperties == null)) } else { - promises.add(additionalProperties.then(object : ObsolescentAsyncFunction { - override fun isObsolete(): Boolean { - return node.isObsolete - } - - override fun `fun`(o: Void): Promise { - return computeNamedProperties(objectValue, node, true) - } - })) + promises.add(additionalProperties.thenAsync(node) { computeNamedProperties(objectValue, node, true) }) } } if (hasIndexedProperties == hasNamedProperties || additionalProperties != null) { - Promise.all(promises).processed(object : ObsolescentConsumer(node) { - override fun consume(aVoid: Void) { - node.addChildren(XValueChildrenList.EMPTY, true) - } + Promise.all(promises).processed(object : ObsolescentConsumer(node) { + override fun consume(aVoid: Any?) = node.addChildren(XValueChildrenList.EMPTY, true) }) } } - abstract class ObsolescentIndexedVariablesConsumer protected constructor(protected val node: XCompositeNode) : IndexedVariablesConsumer() { - - override fun isObsolete(): Boolean { - return node.isObsolete - } + abstract class ObsolescentIndexedVariablesConsumer(protected val node: XCompositeNode) : IndexedVariablesConsumer() { + override fun isObsolete() = node.isObsolete } private fun computeIndexedProperties(value: ArrayValue, node: XCompositeNode, isLastChildren: Boolean): Promise<*> { @@ -228,29 +208,27 @@ class VariableView(name: String, private val variable: Variable, private val con }, null) } - private fun computeNamedProperties(value: ObjectValue, node: XCompositeNode, isLastChildren: Boolean): Promise { - return processVariables(this, value.properties, node) { memberFilter, variables -> - this@VariableView.memberFilter = memberFilter + private fun computeNamedProperties(value: ObjectValue, node: XCompositeNode, isLastChildren: Boolean) = processVariables(this, value.properties, node) { memberFilter, variables -> + this@VariableView.memberFilter = memberFilter - if (value.type == ValueType.ARRAY && value !is ArrayValue) { - computeArrayRanges(variables, node) - return@processVariables - } + if (value.type == ValueType.ARRAY && value !is ArrayValue) { + computeArrayRanges(variables, node) + return@processVariables + } - var functionValue = value as? FunctionValue - if (functionValue != null && functionValue.hasScopes() == ThreeState.NO) { - functionValue = null - } + var functionValue = value as? FunctionValue + if (functionValue != null && functionValue.hasScopes() == ThreeState.NO) { + functionValue = null + } - remainingChildren = processNamedObjectProperties(variables, node, this@VariableView, memberFilter, XCompositeNode.MAX_CHILDREN_TO_SHOW, isLastChildren && functionValue == null) - if (remainingChildren != null) { - remainingChildrenOffset = XCompositeNode.MAX_CHILDREN_TO_SHOW - } + remainingChildren = processNamedObjectProperties(variables, node, this@VariableView, memberFilter, XCompositeNode.MAX_CHILDREN_TO_SHOW, isLastChildren && functionValue == null) + if (remainingChildren != null) { + remainingChildrenOffset = XCompositeNode.MAX_CHILDREN_TO_SHOW + } - if (functionValue != null) { - // we pass context as variable context instead of this variable value - we cannot watch function scopes variables, so, this variable name doesn't matter - node.addChildren(XValueChildrenList.bottomGroup(FunctionScopesValueGroup(functionValue, context)), isLastChildren) - } + if (functionValue != null) { + // we pass context as variable context instead of this variable value - we cannot watch function scopes variables, so, this variable name doesn't matter + node.addChildren(XValueChildrenList.bottomGroup(FunctionScopesValueGroup(functionValue, context)), isLastChildren) } } @@ -312,7 +290,7 @@ class VariableView(name: String, private val variable: Variable, private val con return object : XValueModifier() { override fun getInitialValueEditorText(): String? { if (value!!.type == ValueType.STRING) { - val string = value!!.valueString + val string = value!!.valueString!! val builder = StringBuilder(string.length()) builder.append('"') StringUtil.escapeStringCharacters(string.length(), string, builder) @@ -325,10 +303,7 @@ class VariableView(name: String, private val variable: Variable, private val con } override fun setValue(expression: String, callback: XValueModifier.XModificationCallback) { - val valueModifier = variable.valueModifier - assert(valueModifier != null) - //noinspection unchecked - valueModifier!!.setValue(variable, expression, evaluateContext) + variable.valueModifier!!.setValue(variable, expression, evaluateContext) .done(Consumer { value = null callback.valueModified() @@ -346,11 +321,11 @@ class VariableView(name: String, private val variable: Variable, private val con override fun computeSourcePosition(navigatable: XNavigatable) { if (value is FunctionValue) { - (value as FunctionValue).resolve().done(object : Consumer { - override fun consume(function: FunctionValue) { - viewSupport.vm!!.scriptManager.getScript(function).done(object : Consumer