From cef6c01d788afc8886b402a8c57da881705e8fd1 Mon Sep 17 00:00:00 2001 From: Gabor Aron Takacs Date: Tue, 3 Jun 2025 16:43:38 +0200 Subject: [PATCH 1/8] Add diagnostics for import for side effects Fixes #24689 internal issue. Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICCBQN Change-Id: If1def850d9efd6c049cd896674824766c9c17243 Signed-off-by: Gabor Aron Takacs --- ets2panda/parser/ETSparser.cpp | 14 +++++++++++++ ets2panda/test/ast/parser/ets/export_as.ets | 20 +++++++++++++++++++ .../ets/import_no_empty_binding_list.ets | 20 +++++++++++++++++++ .../ast/parser/ets/import_no_side_effect.ets | 18 +++++++++++++++++ ets2panda/util/diagnostic/syntax.yaml | 9 +++++++++ 5 files changed, 81 insertions(+) create mode 100644 ets2panda/test/ast/parser/ets/export_as.ets create mode 100644 ets2panda/test/ast/parser/ets/import_no_empty_binding_list.ets create mode 100644 ets2panda/test/ast/parser/ets/import_no_side_effect.ets diff --git a/ets2panda/parser/ETSparser.cpp b/ets2panda/parser/ETSparser.cpp index 9e2059c27df..63ccef2b2e8 100644 --- a/ets2panda/parser/ETSparser.cpp +++ b/ets2panda/parser/ETSparser.cpp @@ -1348,6 +1348,10 @@ ir::ExportNamedDeclaration *ETSParser::ParseSingleExport(ir::ModifierFlags modif return ParseSingleExportForAnonymousConst(modifiers); } + if (token.KeywordType() == lexer::TokenType::KEYW_AS) { + LogError(diagnostic::ERROR_ARKTS_NO_UMD, {}, token.Start()); + return nullptr; + } if (token.Type() != lexer::TokenType::LITERAL_IDENT) { LogError(diagnostic::EXPORT_NON_DECLARATION, {}, token.Start()); return nullptr; @@ -1480,6 +1484,12 @@ SpecifiersInfo ETSParser::ParseNamedSpecifiers() ArenaVector resultDefault(Allocator()->Adapter()); ArenaVector resultExportDefault(Allocator()->Adapter()); + auto token = Lexer()->GetToken(); + if (token.Ident() == (lexer::TokenToString(lexer::TokenType::KEYW_IMPORT)) && + token.Type() == lexer::TokenType::PUNCTUATOR_RIGHT_BRACE) { + LogError(diagnostic::ERROR_ARKTS_NO_SIDE_EFFECT_IMPORT); + } + ParseList( lexer::TokenType::PUNCTUATOR_RIGHT_BRACE, lexer::NextTokenFlags::KEYWORD_TO_IDENT, [this, &result, &resultDefault, &resultExportDefault, &fileName]() { @@ -1534,6 +1544,10 @@ void ETSParser::ParseNameSpaceSpecifier(ArenaVector *specifiers, ir::AstNode *ETSParser::ParseImportDefaultSpecifier(ArenaVector *specifiers) { + if (Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_STRING) { + LogError(diagnostic::ERROR_ARKTS_NO_SIDE_EFFECT_IMPORT); + return nullptr; + } if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) { LogExpectedToken(lexer::TokenType::LITERAL_IDENT); } diff --git a/ets2panda/test/ast/parser/ets/export_as.ets b/ets2panda/test/ast/parser/ets/export_as.ets new file mode 100644 index 00000000000..f2c130fbe82 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/export_as.ets @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * 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. + */ + +export /* @@ label1 */as /* @@ label2 */namespace mathLib {} + +/* @@@ label1 Error SyntaxError: Universal module definitions are not supported, please use ordinary import/export syntax instead. */ +/* @@@ label1 Error SyntaxError: Unexpected token 'as'. */ +/* @@@ label2 Error SyntaxError: Unexpected token 'namespace'. */ diff --git a/ets2panda/test/ast/parser/ets/import_no_empty_binding_list.ets b/ets2panda/test/ast/parser/ets/import_no_empty_binding_list.ets new file mode 100644 index 00000000000..dd2ff3124f6 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/import_no_empty_binding_list.ets @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * 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. + */ + +import {/* @@ label1 */} /* @@ label2 */from /* @@ label3 */'module' + +/* @@@ label1 Error SyntaxError: Importing for side-effect only is prohibited! Please provide objects to be imported explicitly or use * to import all objects declared in the module! */ +/* @@@ label2 Error TypeError: Unresolved reference from */ +/* @@@ label3 Error SyntaxError: Unexpected token 'module'. */ diff --git a/ets2panda/test/ast/parser/ets/import_no_side_effect.ets b/ets2panda/test/ast/parser/ets/import_no_side_effect.ets new file mode 100644 index 00000000000..cd4d80cab0b --- /dev/null +++ b/ets2panda/test/ast/parser/ets/import_no_side_effect.ets @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * 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. + */ + +import /* @@ label1 */'module' + +/* @@@ label1 Error SyntaxError: Importing for side-effect only is prohibited! Please provide objects to be imported explicitly or use * to import all objects declared in the module! */ diff --git a/ets2panda/util/diagnostic/syntax.yaml b/ets2panda/util/diagnostic/syntax.yaml index 47d782ae572..0d4a5b3de35 100644 --- a/ets2panda/util/diagnostic/syntax.yaml +++ b/ets2panda/util/diagnostic/syntax.yaml @@ -245,6 +245,15 @@ syntax: id: 312 message: "Importing by 'require' and 'import' assignment is not supported, use 'import * as ... from ...' form instead!" +- name: ERROR_ARKTS_NO_SIDE_EFFECT_IMPORT + id: 73297 + message: "Importing for side-effect only is prohibited! Please provide objects to be imported explicitly or use * to import + all objects declared in the module!" + +- name: ERROR_ARKTS_NO_UMD + id: 114179 + message: "Universal module definitions are not supported, please use ordinary import/export syntax instead." + - name: ERROR_ARKTS_NO_VAR id: 297 message: "'var' keyword is not supported. Use 'let' instead." -- Gitee From d54c0591e8c74f19b0b8e0d0036e2ff0cd5e8a0e Mon Sep 17 00:00:00 2001 From: Peter Pronai Date: Tue, 1 Jul 2025 08:04:08 +0000 Subject: [PATCH 2/8] Error when accessing prototype field This feature is not in the spec and is explicitly listed as not supported by the cookbook. Add an error when code tries to assign or read from it. Fixes #23743 internal issue. Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICJA0M Testing: ast, astchecker, parser Change-Id: I87f4d5466c748c090f827bfd53b9e302b5dc889b Signed-off-by: Peter Pronai --- ets2panda/parser/expressionParser.cpp | 6 ++++ .../test/ast/parser/ets/no_prototype.ets | 36 +++++++++++++++++++ ets2panda/util/diagnostic/syntax.yaml | 4 +++ 3 files changed, 46 insertions(+) create mode 100644 ets2panda/test/ast/parser/ets/no_prototype.ets diff --git a/ets2panda/parser/expressionParser.cpp b/ets2panda/parser/expressionParser.cpp index 596a70e0864..6c329cba1af 100644 --- a/ets2panda/parser/expressionParser.cpp +++ b/ets2panda/parser/expressionParser.cpp @@ -1599,6 +1599,9 @@ ir::MemberExpression *ParserImpl::ParsePrivatePropertyAccess(ir::Expression *pri auto *privateIdent = AllocNode(lexer_->GetToken().Ident(), Allocator()); ES2PANDA_ASSERT(privateIdent != nullptr); + if (program_->Extension() == util::gen::extension::ETS && privateIdent->Name().Is("prototype")) { + LogError(diagnostic::PROTOTYPE_ACCESS); + } privateIdent->SetRange({memberStart, lexer_->GetToken().End()}); privateIdent->SetPrivate(true); lexer_->NextToken(); @@ -1613,6 +1616,9 @@ ir::MemberExpression *ParserImpl::ParsePrivatePropertyAccess(ir::Expression *pri ir::MemberExpression *ParserImpl::ParsePropertyAccess(ir::Expression *primaryExpr, bool isOptional) { ir::Identifier *ident = ExpectIdentifier(true); + if (program_->Extension() == util::gen::extension::ETS && ident->Name().Is("prototype")) { + LogError(diagnostic::PROTOTYPE_ACCESS); + } auto *memberExpr = AllocNode(primaryExpr, ident, ir::MemberExpressionKind::PROPERTY_ACCESS, false, isOptional); ES2PANDA_ASSERT(memberExpr != nullptr); diff --git a/ets2panda/test/ast/parser/ets/no_prototype.ets b/ets2panda/test/ast/parser/ets/no_prototype.ets new file mode 100644 index 00000000000..2f70cb7112e --- /dev/null +++ b/ets2panda/test/ast/parser/ets/no_prototype.ets @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * 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. + */ + +class C {} + +C.prototype = Object.prototype + +C.prototype = { + m() { + console.log("C.m()") + } +} + +/* @@? 18:3 Error TypeError: Property 'prototype' does not exist on type 'C' */ +/* @@? 18:13 Error SyntaxError: Runtime prototype assignment is not supported because of static typing */ +/* @@? 18:22 Error TypeError: Property 'prototype' does not exist on type 'Object' */ +/* @@? 20:1 Error SyntaxError: Runtime prototype assignment is not supported because of static typing */ +/* @@? 20:3 Error TypeError: Property 'prototype' does not exist on type 'C' */ +/* @@? 20:13 Error SyntaxError: Runtime prototype assignment is not supported because of static typing */ +/* @@? 21:4 Error SyntaxError: Unexpected token, expected ':'. */ +/* @@? 21:5 Error SyntaxError: Unexpected token ')'. */ +/* @@? 21:7 Error SyntaxError: Unexpected token. */ +/* @@? 22:12 Error SyntaxError: Unexpected token, expected ':'. */ +/* @@? 24:1 Error SyntaxError: Unexpected token '}'. */ diff --git a/ets2panda/util/diagnostic/syntax.yaml b/ets2panda/util/diagnostic/syntax.yaml index a998b7eacc6..272b7ccc503 100644 --- a/ets2panda/util/diagnostic/syntax.yaml +++ b/ets2panda/util/diagnostic/syntax.yaml @@ -941,6 +941,10 @@ syntax: id: 238 message: "Methods or fields should not be decorated with {} in ambient class." +- name: PROTOTYPE_ACCESS + id: 30818 + message: "Runtime prototype assignment is not supported because of static typing" + - name: QUANTIFIER_OUT_OF_ORDER id: 78 message: "Quantifier range out of order." -- Gitee From 076aa1cafa0c1c8e4d5a0ff58d2553e914d5b81c Mon Sep 17 00:00:00 2001 From: xuxinjie4 Date: Thu, 10 Jul 2025 19:52:10 +0800 Subject: [PATCH 3/8] Fix assert failed Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICLIKK?from=project-issue Signed-off-by: xuxinjie4 --- ets2panda/parser/ETSparserStatements.cpp | 2 +- .../ets/unexpected_switch_statement.ets | 30 +++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 ets2panda/test/ast/compiler/ets/unexpected_switch_statement.ets diff --git a/ets2panda/parser/ETSparserStatements.cpp b/ets2panda/parser/ETSparserStatements.cpp index 0b8fc5d913c..68ffc5fa04d 100644 --- a/ets2panda/parser/ETSparserStatements.cpp +++ b/ets2panda/parser/ETSparserStatements.cpp @@ -363,7 +363,7 @@ ir::Statement *ETSParser::ParseTryStatement() if (catchClauses.empty() && finalizer == nullptr) { LogError(diagnostic::MISSING_CATCH_OR_FINALLY_AFTER_TRY, {}, startLoc); - return nullptr; + return AllocBrokenStatement(startLoc); } lexer::SourcePosition endLoc = finalizer != nullptr ? finalizer->End() : catchClauses.back()->End(); diff --git a/ets2panda/test/ast/compiler/ets/unexpected_switch_statement.ets b/ets2panda/test/ast/compiler/ets/unexpected_switch_statement.ets new file mode 100644 index 00000000000..a3d25937233 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/unexpected_switch_statement.ets @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * 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. + */ + +let a = 1 +switch(a) { + a": + try{ + + } + } + + +/* @@? 18:5 Error SyntaxError: Unexpected token 'identification literal', expected 'case' or 'default'. */ +/* @@? 18:5 Error SyntaxError: Expected ':', got 'identification literal'. */ +/* @@? 18:6 Error SyntaxError: Newline is not allowed in strings */ +/* @@? 18:6 Error SyntaxError: Unexpected token ':'. */ +/* @@? 18:8 Error SyntaxError: Unexpected token 'try'. */ +/* @@? 18:8 Error SyntaxError: A try statement should contain either finally clause or at least one catch clause. */ -- Gitee From 4044b57e01fd507d3d0c905d5d206d751af1a105 Mon Sep 17 00:00:00 2001 From: Gabor Aron Takacs Date: Sun, 22 Jun 2025 20:12:55 +0200 Subject: [PATCH 4/8] Export parser should work on object literal Reason: Default export from specification 13.5.1 Exported Declarations doesn't work correctly on object literals Description: Adding parser implementation for specific cornercase Fixes #26901 internal issue. Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICJTPP Signed-off-by: Gabor Aron Takacs Signed-off-by: Torok Gergo --- ets2panda/ir/module/exportSpecifier.cpp | 8 +++++- ets2panda/parser/ETSparser.cpp | 27 ++++++++++++++++--- ets2panda/parser/ETSparser.h | 1 + .../ets/defaultExportObjectLiteral_exp.ets | 26 ++++++++++++++++++ 4 files changed, 57 insertions(+), 5 deletions(-) create mode 100644 ets2panda/test/runtime/ets/defaultExportObjectLiteral_exp.ets diff --git a/ets2panda/ir/module/exportSpecifier.cpp b/ets2panda/ir/module/exportSpecifier.cpp index 1133414d19f..1c28d57fe53 100644 --- a/ets2panda/ir/module/exportSpecifier.cpp +++ b/ets2panda/ir/module/exportSpecifier.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2021-2024 Huawei Device Co., Ltd. + * Copyright (c) 2021-2025 Huawei Device Co., Ltd. * 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 @@ -48,6 +48,12 @@ void ExportSpecifier::Dump(ir::AstDumper *dumper) const void ExportSpecifier::Dump(ir::SrcDumper *dumper) const { + if (GetConstantExpression() != nullptr) { + GetConstantExpression()->Dump(dumper); + dumper->Add("as default"); + return; + } + exported_->Dump(dumper); if (local_ != nullptr) { diff --git a/ets2panda/parser/ETSparser.cpp b/ets2panda/parser/ETSparser.cpp index 9788c8d7af7..2847966a885 100644 --- a/ets2panda/parser/ETSparser.cpp +++ b/ets2panda/parser/ETSparser.cpp @@ -1121,17 +1121,36 @@ ir::Statement *ETSParser::CreateReExportDeclarationNode(ir::ETSImportDeclaration return reExport; } +ir::Statement *ETSParser::ParseDefaultIfSingleExport(ir::ModifierFlags modifiers) +{ + auto tokenType = Lexer()->GetToken().Type(); + if (tokenType != lexer::TokenType::PUNCTUATOR_LEFT_BRACE) { + return ParseSingleExport(modifiers); + } + auto savePos = Lexer()->Save(); + Lexer()->NextToken(); + auto isSelectiveExport = Lexer()->TryEatTokenType(lexer::TokenType::LITERAL_IDENT) && + (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA || + Lexer()->GetToken().Type() == lexer::TokenType::KEYW_AS || + Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_RIGHT_BRACE); + Lexer()->Rewind(savePos); + return !isSelectiveExport ? ParseSingleExport(modifiers) : nullptr; +} + ir::Statement *ETSParser::ParseExport(lexer::SourcePosition startLoc, ir::ModifierFlags modifiers) { const size_t exportDefaultMaxSize = 1; if (!InAmbientContext() && (GetContext().Status() & ParserStatus::IN_NAMESPACE) != 0) { LogError(diagnostic::EXPORT_IN_NAMESPACE); } - [[maybe_unused]] auto tokenType = Lexer()->GetToken().Type(); // export a constant variable anonymously, as export default new A() - if ((modifiers & ir::ModifierFlags::DEFAULT_EXPORT) != 0U && tokenType != lexer::TokenType::PUNCTUATOR_MULTIPLY && - tokenType != lexer::TokenType::PUNCTUATOR_LEFT_BRACE && tokenType != lexer::TokenType::LITERAL_IDENT) { - return ParseSingleExport(modifiers); + if ((modifiers & ir::ModifierFlags::DEFAULT_EXPORT) != 0U && + Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_MULTIPLY && + Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) { + auto exportedExpression = ParseDefaultIfSingleExport(modifiers); + if (exportedExpression != nullptr) { + return exportedExpression; + } } ArenaVector specifiers(Allocator()->Adapter()); diff --git a/ets2panda/parser/ETSparser.h b/ets2panda/parser/ETSparser.h index 8dddff53b55..c92657f1390 100644 --- a/ets2panda/parser/ETSparser.h +++ b/ets2panda/parser/ETSparser.h @@ -302,6 +302,7 @@ private: ExpressionParseFlags flags = ExpressionParseFlags::NO_OPTS) override; ir::Statement *ParseTryStatement() override; ir::Statement *ParseDebuggerStatement() override; + ir::Statement *ParseDefaultIfSingleExport(ir::ModifierFlags modifiers); ir::Statement *ParseExport(lexer::SourcePosition startLoc, ir::ModifierFlags modifiers); ir::Statement *ParseImportDeclaration(StatementParsingFlags flags) override; ir::Statement *ParseExportDeclaration(StatementParsingFlags flags) override; diff --git a/ets2panda/test/runtime/ets/defaultExportObjectLiteral_exp.ets b/ets2panda/test/runtime/ets/defaultExportObjectLiteral_exp.ets new file mode 100644 index 00000000000..885d31856d2 --- /dev/null +++ b/ets2panda/test/runtime/ets/defaultExportObjectLiteral_exp.ets @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * 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. + */ + +interface User { + name: string; + age: number; + email: string; +}; + +export default { + name: 'John Doe', + age: 30, + email: 'johndoe@example.com' +} as User; -- Gitee From 748278892b3d516e352423eb8c6402fdca0baff2 Mon Sep 17 00:00:00 2001 From: anjiaqi Date: Fri, 11 Jul 2025 17:00:30 +0800 Subject: [PATCH 5/8] 0328-fix-alert include 4 Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICLQHF Signed-off-by: anjiaqi --- ets2panda/checker/ETSchecker.cpp | 1 + ets2panda/checker/types/ets/etsAnyType.cpp | 2 ++ ets2panda/compiler/core/ETSGen.cpp | 5 +++++ 3 files changed, 8 insertions(+) diff --git a/ets2panda/checker/ETSchecker.cpp b/ets2panda/checker/ETSchecker.cpp index c301c826b3f..f556f61e054 100644 --- a/ets2panda/checker/ETSchecker.cpp +++ b/ets2panda/checker/ETSchecker.cpp @@ -433,6 +433,7 @@ bool ETSChecker::IsClassStaticMethod(checker::ETSObjectType *objType, checker::S TypeFlag::ETS_STRING_ENUM | TypeFlag::READONLY | TypeFlag::BIGINT_LITERAL | TypeFlag::ETS_TYPE_ALIAS | TypeFlag::TYPE_ERROR; + CHECK_NOT_NULL(type); auto res = static_cast(type->TypeFlags() & ~(TO_CLEAR)); ES2PANDA_ASSERT_POS(res == TypeFlag::NONE || helpers::math::IsPowerOfTwo(res & ~(TypeFlag::NONE)), ark::es2panda::GetPositionForDiagnostic()); diff --git a/ets2panda/checker/types/ets/etsAnyType.cpp b/ets2panda/checker/types/ets/etsAnyType.cpp index 8f36fb2b212..ea399276063 100644 --- a/ets2panda/checker/types/ets/etsAnyType.cpp +++ b/ets2panda/checker/types/ets/etsAnyType.cpp @@ -14,6 +14,7 @@ */ #include "etsAnyType.h" +#include #include "checker/ETSchecker.h" #include "checker/ets/conversion.h" @@ -62,6 +63,7 @@ void ETSAnyType::Cast(TypeRelation *relation, Type *target) if (relation->ApplyUnboxing()) { auto *const boxedTarget = relation->GetChecker()->AsETSChecker()->MaybeBoxInRelation(target); + ES2PANDA_ASSERT(boxedTarget != nullptr); conversion::Unboxing(relation, boxedTarget->AsETSObjectType()); relation->Result(true); } diff --git a/ets2panda/compiler/core/ETSGen.cpp b/ets2panda/compiler/core/ETSGen.cpp index 64969cbd232..ef53c9883d2 100644 --- a/ets2panda/compiler/core/ETSGen.cpp +++ b/ets2panda/compiler/core/ETSGen.cpp @@ -671,6 +671,7 @@ void ETSGen::BranchIfIsInstance(const ir::AstNode *const node, const VReg srcReg void ETSGen::IsInstance(const ir::AstNode *const node, const VReg srcReg, const checker::Type *target) { target = Checker()->GetApparentType(target); + ES2PANDA_ASSERT(target != nullptr); ES2PANDA_ASSERT(target->IsETSReferenceType() && GetAccumulatorType() != nullptr); if (target->IsETSAnyType()) { // should be IsSupertypeOf(target, source) @@ -720,6 +721,7 @@ void ETSGen::InternalCheckCast(const ir::AstNode *node, const es2panda::checker: // Handle checkcast for interop if it is 1.2 type. void ETSGen::EmitAnyCheckCast(const ir::AstNode *node, const checker::Type *target) { + ES2PANDA_ASSERT(target != nullptr); if (!target->IsETSAnyType() && (target->IsETSObjectType() || target->IsETSArrayType() || target->IsETSTupleType())) { InternalCheckCast(node, target); @@ -774,6 +776,7 @@ void ETSGen::CheckedReferenceNarrowing(const ir::AstNode *node, const checker::T } target = Checker()->GetApparentType(target); + ES2PANDA_ASSERT(target != nullptr); ES2PANDA_ASSERT(target->IsETSReferenceType()); if (target->IsETSAnyType()) { // should be IsSupertypeOf(target, source) @@ -810,6 +813,7 @@ void ETSGen::GuardUncheckedType(const ir::AstNode *node, const checker::Type *un CheckedReferenceNarrowing(node, Checker()->MaybeBoxType(target)); // Because on previous step accumulator type may be set in CheckerReferenceNarrowing to boxed counterpart of // target We need to apply unbox conversion if needed to avoid RTE + ES2PANDA_ASSERT(GetAccumulatorType() != nullptr); if (target->IsETSPrimitiveType() && GetAccumulatorType()->IsETSUnboxableObject()) { ApplyConversion(node, target); } @@ -1276,6 +1280,7 @@ void ETSGen::CastToInt(const ir::AstNode *node) void ETSGen::CastToReftype(const ir::AstNode *const node, const checker::Type *const targetType, const bool unchecked) { + ES2PANDA_ASSERT(GetAccumulatorType() != nullptr); ES2PANDA_ASSERT(GetAccumulatorType()->IsETSReferenceType()); if (!unchecked) { -- Gitee From 0d5d362a0f198b0c8663945dd375b93046d3753b Mon Sep 17 00:00:00 2001 From: yp9522 Date: Thu, 10 Jul 2025 20:46:34 +0800 Subject: [PATCH 6/8] 0328-fix-alert-conflicts Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICLQZT Signed-off-by: anjiaqi --- ets2panda/checker/ETSAnalyzer.cpp | 7 ++++ ets2panda/checker/TSAnalyzer.cpp | 4 ++- ets2panda/checker/ets/aliveAnalyzer.cpp | 4 ++- ets2panda/checker/ets/function.cpp | 1 + ets2panda/checker/ets/helpers.cpp | 1 + ets2panda/checker/ets/utilityTypeHandlers.cpp | 4 ++- ets2panda/checker/ts/destructuringContext.cpp | 1 + ets2panda/checker/types/typeRelation.cpp | 1 + ets2panda/parser/ASparser.cpp | 3 ++ ets2panda/parser/ETSparser.cpp | 7 ++++ ets2panda/parser/ETSparserAnnotations.cpp | 1 + ets2panda/parser/ETSparserClasses.cpp | 32 +++++++++++++------ ets2panda/parser/ETSparserExpressions.cpp | 6 +++- ets2panda/parser/ETSparserNamespaces.cpp | 1 + ets2panda/parser/ETSparserTypes.cpp | 1 + ets2panda/parser/TSparser.cpp | 4 ++- ets2panda/parser/expressionParser.cpp | 5 ++- ets2panda/parser/parserImpl.cpp | 6 +++- ets2panda/parser/statementParser.cpp | 9 ++++++ ets2panda/parser/statementTSParser.cpp | 1 + 20 files changed, 82 insertions(+), 17 deletions(-) diff --git a/ets2panda/checker/ETSAnalyzer.cpp b/ets2panda/checker/ETSAnalyzer.cpp index 4748735b147..fb821fb4234 100644 --- a/ets2panda/checker/ETSAnalyzer.cpp +++ b/ets2panda/checker/ETSAnalyzer.cpp @@ -462,6 +462,7 @@ checker::Type *ETSAnalyzer::Check(ir::ETSFunctionType *node) const checker->CheckFunctionSignatureAnnotations(node->Params(), node->TypeParams(), node->ReturnType()); auto *signatureInfo = checker->ComposeSignatureInfo(node->TypeParams(), node->Params()); + ES2PANDA_ASSERT(signatureInfo != nullptr); auto *returnType = node->IsExtensionFunction() && node->ReturnType()->IsTSThisType() ? signatureInfo->params.front()->TsType() : checker->ComposeReturnType(node->ReturnType(), node->IsAsync()); @@ -1863,6 +1864,7 @@ checker::Type *ETSAnalyzer::Check(ir::Identifier *expr) const } expr->SetTsType(identType); + ES2PANDA_ASSERT(identType != nullptr); if (!identType->IsTypeError()) { checker->Context().CheckIdentifierSmartCastCondition(expr); } @@ -1977,6 +1979,7 @@ checker::Type *ETSAnalyzer::Check(ir::MemberExpression *expr) const auto *baseType = checker->GetNonConstantType(checker->GetApparentType(expr->Object()->Check(checker))); // Note: don't use possible smart cast to null-like types. // Such situation should be correctly resolved in the subsequent lowering. + ES2PANDA_ASSERT(baseType != nullptr); if (baseType->DefinitelyETSNullish() && expr->Object()->IsIdentifier()) { baseType = expr->Object()->AsIdentifier()->Variable()->TsType(); } @@ -2678,6 +2681,7 @@ static checker::Type *ComputeTypeOfType(ETSChecker *checker, checker::Type *argT { checker::Type *ret = nullptr; ArenaVector types(checker->ProgramAllocator()->Adapter()); + ES2PANDA_ASSERT(argType != nullptr); if (argType->IsETSUnionType()) { for (auto *it : argType->AsETSUnionType()->ConstituentTypes()) { checker::Type *elType = ComputeTypeOfType(checker, it); @@ -2719,6 +2723,7 @@ checker::Type *ETSAnalyzer::Check(ir::UnaryExpression *expr) const checker::Type *type = checker->CreateETSBigIntLiteralType(argType->AsETSBigIntType()->GetValue()); // We do not need this const anymore as we are negating the bigint object in runtime + ES2PANDA_ASSERT(type != nullptr); type->RemoveTypeFlag(checker::TypeFlag::CONSTANT); expr->argument_->SetTsType(type); expr->SetTsType(type); @@ -3114,6 +3119,7 @@ checker::Type *ETSAnalyzer::Check(ir::AnnotationUsage *st) const ArenaUnorderedMap fieldMap {checker->ProgramAllocator()->Adapter()}; for (auto *it : annoDecl->Properties()) { auto *field = it->AsClassProperty(); + ES2PANDA_ASSERT(field->Id() != nullptr); fieldMap.insert(std::make_pair(field->Id()->Name(), field)); } @@ -3701,6 +3707,7 @@ checker::Type *ETSAnalyzer::Check(ir::TSAsExpression *expr) const checker->CheckAnnotations(expr->TypeAnnotation()->Annotations()); auto *const targetType = expr->TypeAnnotation()->AsTypeNode()->GetType(checker); + ES2PANDA_ASSERT(targetType != nullptr); if (targetType->IsTypeError()) { return checker->InvalidateType(expr); } diff --git a/ets2panda/checker/TSAnalyzer.cpp b/ets2panda/checker/TSAnalyzer.cpp index 44d5a3d8245..655c154d5f6 100644 --- a/ets2panda/checker/TSAnalyzer.cpp +++ b/ets2panda/checker/TSAnalyzer.cpp @@ -802,7 +802,7 @@ void TSAnalyzer::CheckNonComputed(checker::ObjectDescriptor *desc, ir::Expressio if (prop->Key()->IsNumberLiteral()) { memberVar->AddFlag(varbinder::VariableFlags::NUMERIC_NAME); } - + ES2PANDA_ASSERT(desc != nullptr); varbinder::LocalVariable *foundMember = desc->FindProperty(propName); allPropertiesMap.insert({propName, it->Start()}); @@ -1740,6 +1740,7 @@ static void AddEnumValueDeclaration(checker::TSChecker *checker, double number, enumScope->AddDecl(checker->Allocator(), decl, ScriptExtension::TS); res = enumScope->FindLocal(memberStr, varbinder::ResolveBindingOptions::BINDINGS); ES2PANDA_ASSERT(res && res->IsEnumVariable()); + ES2PANDA_ASSERT(enumVar != nullptr); enumVar = res->AsEnumVariable(); enumVar->AsEnumVariable()->SetBackReference(); enumVar->SetTsType(checker->GlobalStringType()); @@ -1747,6 +1748,7 @@ static void AddEnumValueDeclaration(checker::TSChecker *checker, double number, ES2PANDA_ASSERT(res->IsEnumVariable()); enumVar = res->AsEnumVariable(); auto *decl = checker->Allocator()->New(memberStr); + ES2PANDA_ASSERT(decl != nullptr); decl->BindNode(variable->Declaration()->Node()); enumVar->ResetDecl(decl); } diff --git a/ets2panda/checker/ets/aliveAnalyzer.cpp b/ets2panda/checker/ets/aliveAnalyzer.cpp index 13abe6b9ca7..e4edb04a7a1 100644 --- a/ets2panda/checker/ets/aliveAnalyzer.cpp +++ b/ets2panda/checker/ets/aliveAnalyzer.cpp @@ -243,7 +243,9 @@ void AliveAnalyzer::AnalyzeMethodDef(const ir::MethodDefinition *methodDef) status_ = LivenessStatus::ALIVE; AnalyzeStat(func->Body()); ES2PANDA_ASSERT(methodDef->TsType() && methodDef->TsType()->IsETSFunctionType()); - const auto *returnType = methodDef->TsType()->AsETSFunctionType()->FindSignature(func)->ReturnType(); + const auto *signature = methodDef->TsType()->AsETSFunctionType()->FindSignature(func); + ES2PANDA_ASSERT(signature != nullptr); + const auto *returnType = signature->ReturnType(); const auto isVoid = returnType->IsETSVoidType() || returnType == checker_->GlobalVoidType(); auto isPromiseVoid = false; diff --git a/ets2panda/checker/ets/function.cpp b/ets2panda/checker/ets/function.cpp index 40a06e17af9..727458be1f6 100644 --- a/ets2panda/checker/ets/function.cpp +++ b/ets2panda/checker/ets/function.cpp @@ -1633,6 +1633,7 @@ SignatureInfo *ETSChecker::ComposeSignatureInfo(ir::TSTypeParameterDeclaration * ES2PANDA_ASSERT(IsAnyError()); // #23134 return nullptr; } + ES2PANDA_ASSERT(restParamType != nullptr); if (!restParamType->IsETSTupleType() && !restParamType->IsETSArrayType() && !restParamType->IsETSResizableArrayType()) { LogError(diagnostic::ONLY_ARRAY_OR_TUPLE_FOR_REST, {}, param->Start()); diff --git a/ets2panda/checker/ets/helpers.cpp b/ets2panda/checker/ets/helpers.cpp index 095b9f0503e..306176bcb82 100644 --- a/ets2panda/checker/ets/helpers.cpp +++ b/ets2panda/checker/ets/helpers.cpp @@ -626,6 +626,7 @@ void ETSChecker::InferAliasLambdaType(ir::TypeNode *localTypeAnnotation, ir::Arr checker::Type *ETSChecker::FixOptionalVariableType(varbinder::Variable *const bindingVar, ir::ModifierFlags flags) { if ((flags & ir::ModifierFlags::OPTIONAL) != 0) { + ES2PANDA_ASSERT(bindingVar != nullptr); auto *variableType = bindingVar->TsType() != nullptr ? bindingVar->TsType() : GlobalTypeError(); bindingVar->SetTsType( !variableType->IsTypeError() ? CreateETSUnionType({GlobalETSUndefinedType(), variableType}) : variableType); diff --git a/ets2panda/checker/ets/utilityTypeHandlers.cpp b/ets2panda/checker/ets/utilityTypeHandlers.cpp index 076bdb34bd0..6341a079153 100644 --- a/ets2panda/checker/ets/utilityTypeHandlers.cpp +++ b/ets2panda/checker/ets/utilityTypeHandlers.cpp @@ -249,10 +249,11 @@ ir::ClassProperty *ETSChecker::CreateNullishPropertyFromAccessor(ir::MethodDefin auto *prop = // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) ProgramAllocator()->New(ident, nullptr, nullptr, modifierFlag, ProgramAllocator(), false); - + ES2PANDA_ASSERT(prop != nullptr); prop->SetParent(newClassDefinition); ident->SetParent(prop); + ES2PANDA_ASSERT(accessor->Function() != nullptr); prop->SetTypeAnnotation(accessor->Function()->IsGetter() ? accessor->Function()->ReturnTypeAnnotation() : accessor->Function()->Params()[0]->AsETSParameterExpression()->TypeAnnotation()); @@ -268,6 +269,7 @@ ir::ClassProperty *ETSChecker::CreateNullishPropertyFromAccessor(ir::MethodDefin auto callSign = accessor->TsType()->AsETSFunctionType()->CallSignatures()[0]; + ES2PANDA_ASSERT(accessor->Function() != nullptr); auto tsType = accessor->Function()->IsGetter() ? callSign->ReturnType() : callSign->Params()[0]->TsType(); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) diff --git a/ets2panda/checker/ts/destructuringContext.cpp b/ets2panda/checker/ts/destructuringContext.cpp index 62212a8fcac..b3f516e2b88 100644 --- a/ets2panda/checker/ts/destructuringContext.cpp +++ b/ets2panda/checker/ts/destructuringContext.cpp @@ -332,6 +332,7 @@ Type *ArrayDestructuringContext::CreateTupleTypeForRest(TupleType *tuple) ES2PANDA_ASSERT(memberVar != nullptr); memberVar->SetTsType(tupleElementType); elementFlags.push_back(memberFlag); + ES2PANDA_ASSERT(desc != nullptr); desc->properties.push_back(memberVar); index_++; diff --git a/ets2panda/checker/types/typeRelation.cpp b/ets2panda/checker/types/typeRelation.cpp index d6de7557220..67ba7f0312f 100644 --- a/ets2panda/checker/types/typeRelation.cpp +++ b/ets2panda/checker/types/typeRelation.cpp @@ -161,6 +161,7 @@ bool TypeRelation::IsComparableTo(Type *source, Type *target) result_ = RelationResult::FALSE; target->Compare(this, source); + ES2PANDA_ASSERT(source != nullptr); auto key = RelationHolder::MakeKey(source->Id(), target->Id()); checker_->ComparableResults().Insert(key, {result_, RelationType::COMPARABLE}); } diff --git a/ets2panda/parser/ASparser.cpp b/ets2panda/parser/ASparser.cpp index f2567fef3d3..2e0e102951f 100644 --- a/ets2panda/parser/ASparser.cpp +++ b/ets2panda/parser/ASparser.cpp @@ -1122,6 +1122,7 @@ ArenaVector ASParser::ParseClassImplementClause() const lexer::SourcePosition &implementStart = Lexer()->GetToken().Start(); auto *implementsName = AllocNode(Lexer()->GetToken().Ident(), Allocator()); + ES2PANDA_ASSERT(implementsName != nullptr); implementsName->SetRange(Lexer()->GetToken().Loc()); auto *implementsClause = AllocNode(implementsName, Allocator()); ES2PANDA_ASSERT(implementsClause != nullptr); @@ -1137,6 +1138,7 @@ ArenaVector ASParser::ParseClassImplementClause() } implementsName = AllocNode(Lexer()->GetToken().Ident(), Allocator()); + ES2PANDA_ASSERT(implementsName != nullptr); implementsName->SetRange(Lexer()->GetToken().Loc()); auto *next = AllocNode(implementsName, Allocator()); current->SetRange(Lexer()->GetToken().Loc()); @@ -1740,6 +1742,7 @@ ir::Statement *ASParser::ParseImportDeclaration([[maybe_unused]] StatementParsin source = ParseFromClause(false); } + ES2PANDA_ASSERT(source != nullptr); lexer::SourcePosition endLoc = source->End(); auto *importDeclaration = AllocNode(source, std::move(specifiers)); ES2PANDA_ASSERT(importDeclaration != nullptr); diff --git a/ets2panda/parser/ETSparser.cpp b/ets2panda/parser/ETSparser.cpp index 6a8ef6664e0..c428e887bc5 100644 --- a/ets2panda/parser/ETSparser.cpp +++ b/ets2panda/parser/ETSparser.cpp @@ -1027,6 +1027,7 @@ ir::TypeNode *ETSParser::ParseTypeReference(TypeAnnotationParsingOptions *option } typeRefPart = AllocNode(typeName, typeParams, typeRefPart, Allocator()); + ES2PANDA_ASSERT(typeRefPart != nullptr); typeRefPart->SetRange({partPos, Lexer()->GetToken().End()}); if (!Lexer()->TryEatTokenType(lexer::TokenType::PUNCTUATOR_PERIOD)) { @@ -1119,6 +1120,7 @@ ir::Statement *ETSParser::CreateReExportDeclarationNode(ir::ETSImportDeclaration } auto reExport = AllocNode(reExportDeclaration, std::vector(), GetProgram()->AbsoluteName(), Allocator()); + ES2PANDA_ASSERT(reExport != nullptr); reExport->AddModifier(modifiers); return reExport; } @@ -1223,6 +1225,7 @@ ir::ETSImportDeclaration *ETSParser::ParseImportPathBuildImport(ArenaVector(ERROR_LITERAL); + ES2PANDA_ASSERT(errorLiteral != nullptr); errorLiteral->SetRange(Lexer()->GetToken().Loc()); auto *const importDeclaration = AllocNode( errorLiteral, util::ImportPathManager::ImportMetadata {}, std::move(specifiers), importKind); @@ -1312,6 +1315,7 @@ ArenaVector ETSParser::ParseImportDeclarations() auto pos = Lexer()->Save(); if (!specifiers.empty()) { auto *const importDecl = ParseImportPathBuildImport(std::move(specifiers), true, startLoc, importKind); + ES2PANDA_ASSERT(importDecl != nullptr); statements.push_back(importDecl->AsETSImportDeclaration()); } @@ -1605,6 +1609,7 @@ ir::AnnotatedExpression *ETSParser::GetAnnotatedExpressionFromParam() switch (Lexer()->GetToken().Type()) { case lexer::TokenType::LITERAL_IDENT: { parameter = AllocNode(Lexer()->GetToken().Ident(), Allocator()); + ES2PANDA_ASSERT(parameter != nullptr); if (parameter->AsIdentifier()->Decorators().empty()) { parameter->SetRange(Lexer()->GetToken().Loc()); } else { @@ -1627,6 +1632,7 @@ ir::AnnotatedExpression *ETSParser::GetAnnotatedExpressionFromParam() restIdent->SetRange(Lexer()->GetToken().Loc()); parameter = AllocNode(ir::AstNodeType::REST_ELEMENT, Allocator(), restIdent); + ES2PANDA_ASSERT(parameter != nullptr); parameter->SetRange({startLoc, Lexer()->GetToken().End()}); break; } @@ -2321,6 +2327,7 @@ ir::FunctionDeclaration *ETSParser::ParseFunctionDeclaration(bool canBeAnonymous Lexer()->NextToken(); } + ES2PANDA_ASSERT(funcDecl != nullptr); funcDecl->SetRange(func->Range()); func->AddModifier(modifiers); func->SetStart(startLoc); diff --git a/ets2panda/parser/ETSparserAnnotations.cpp b/ets2panda/parser/ETSparserAnnotations.cpp index 1194431c694..2f904b8f634 100644 --- a/ets2panda/parser/ETSparserAnnotations.cpp +++ b/ets2panda/parser/ETSparserAnnotations.cpp @@ -392,6 +392,7 @@ ir::AnnotationUsage *ETSParser::ParseAnnotationUsage() } else if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS) { // handle single field annotation auto *singleParamName = AllocNode(compiler::Signatures::ANNOTATION_KEY_VALUE, Allocator()); + ES2PANDA_ASSERT(singleParamName != nullptr); singleParamName->SetRange({Lexer()->GetToken().Start(), Lexer()->GetToken().End()}); const auto savePos = Lexer()->GetToken().Start(); diff --git a/ets2panda/parser/ETSparserClasses.cpp b/ets2panda/parser/ETSparserClasses.cpp index d6821902058..0ae2994d4f8 100644 --- a/ets2panda/parser/ETSparserClasses.cpp +++ b/ets2panda/parser/ETSparserClasses.cpp @@ -421,6 +421,7 @@ ir::TypeNode *ETSParser::ConvertToOptionalUnionType(ir::TypeNode *typeAnno) types.push_back(AllocNode(Allocator())); types.back()->SetRange(typeAnno->Range()); auto *newTypeAnno = AllocNode(std::move(types), Allocator()); + ES2PANDA_ASSERT(newTypeAnno != nullptr); newTypeAnno->SetRange(typeAnno->Range()); return newTypeAnno; } @@ -596,6 +597,7 @@ ir::MethodDefinition *ETSParser::ParseClassMethodDefinition(ir::Identifier *meth funcExpr->SetRange(func->Range()); func->AddModifier(modifiers); + ES2PANDA_ASSERT(methodName->Clone(Allocator(), nullptr) != nullptr); auto *method = AllocNode(methodKind, methodName->Clone(Allocator(), nullptr)->AsExpression(), funcExpr, modifiers, Allocator(), false); ES2PANDA_ASSERT(method != nullptr); @@ -634,6 +636,7 @@ ir::MethodDefinition *ETSParser::ParseClassMethod(ClassElementDescriptor *desc, auto *method = AllocNode(desc->methodKind, propName->Clone(Allocator(), nullptr)->AsExpression(), funcExpr, desc->modifiers, Allocator(), desc->isComputed); + ES2PANDA_ASSERT(method != nullptr); method->SetRange(funcExpr->Range()); return method; @@ -841,13 +844,16 @@ ir::MethodDefinition *ETSParser::ParseClassGetterSetterMethod(const ArenaVector< lexer::SourcePosition propEnd = methodName->End(); ir::MethodDefinition *method = ParseClassMethod(&desc, properties, methodName, &propEnd); + ES2PANDA_ASSERT(method != nullptr); method->SetDefaultAccessModifier(isDefault); - method->Function()->AddModifier(desc.modifiers); + auto *func = method->Function(); + ES2PANDA_ASSERT(func != nullptr); + func->AddModifier(desc.modifiers); method->SetRange({desc.propStart, propEnd}); if (desc.methodKind == ir::MethodDefinitionKind::GET) { - method->Function()->AddFlag(ir::ScriptFunctionFlags::GETTER); + func->AddFlag(ir::ScriptFunctionFlags::GETTER); } else { - method->Function()->AddFlag(ir::ScriptFunctionFlags::SETTER); + func->AddFlag(ir::ScriptFunctionFlags::SETTER); } return method; @@ -864,23 +870,25 @@ ir::MethodDefinition *ETSParser::ParseInterfaceGetterSetterMethod(const ir::Modi return nullptr; } method->AddModifier(ir::ModifierFlags::PUBLIC); - auto id = method->Id(); + auto *id = method->Id(); + auto *func = method->Function(); ES2PANDA_ASSERT(id != nullptr); + ES2PANDA_ASSERT(func != nullptr); if (methodKind == ir::MethodDefinitionKind::GET) { id->SetAccessor(); - method->Function()->AddFlag(ir::ScriptFunctionFlags::GETTER); + func->AddFlag(ir::ScriptFunctionFlags::GETTER); } else { id->SetMutator(); - method->Function()->AddFlag(ir::ScriptFunctionFlags::SETTER); + func->AddFlag(ir::ScriptFunctionFlags::SETTER); } method->AddModifier(ir::ModifierFlags::PUBLIC); - method->Function()->SetIdent(id->Clone(Allocator(), nullptr)); - method->Function()->AddModifier(method->Modifiers()); + func->SetIdent(id->Clone(Allocator(), nullptr)); + func->AddModifier(method->Modifiers()); - bool hasReturn = method->Function()->ReturnTypeAnnotation() != nullptr; + bool hasReturn = func->ReturnTypeAnnotation() != nullptr; if (hasReturn && methodKind == ir::MethodDefinitionKind::SET) { - LogError(diagnostic::SETTER_NO_RETURN_TYPE, {}, method->Function()->Range().start); + LogError(diagnostic::SETTER_NO_RETURN_TYPE, {}, func->Range().start); } return method; @@ -1109,6 +1117,7 @@ ir::AstNode *ETSParser::ParseInterfaceField() return AllocBrokenExpression(Lexer()->GetToken().Start()); } + ES2PANDA_ASSERT(name != nullptr); name->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); bool optionalField = false; @@ -1178,6 +1187,7 @@ ir::MethodDefinition *ETSParser::ParseInterfaceMethod(ir::ModifierFlags flags, i name = AllocBrokenExpression(Lexer()->GetToken().Loc()); } else { name = AllocNode(Lexer()->GetToken().Ident(), Allocator()); + ES2PANDA_ASSERT(name != nullptr); name->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); } @@ -1226,8 +1236,10 @@ ir::MethodDefinition *ETSParser::ParseInterfaceMethod(ir::ModifierFlags flags, i func->AddFlag(ir::ScriptFunctionFlags::METHOD); func->SetIdent(name); + ES2PANDA_ASSERT(name->Clone(Allocator(), nullptr) != nullptr); auto *method = AllocNode(methodKind, name->Clone(Allocator(), nullptr)->AsExpression(), funcExpr, flags, Allocator(), false); + ES2PANDA_ASSERT(method != nullptr); method->SetRange(funcExpr->Range()); ConsumeSemicolon(method); diff --git a/ets2panda/parser/ETSparserExpressions.cpp b/ets2panda/parser/ETSparserExpressions.cpp index d07eb072085..707d44ad1b5 100644 --- a/ets2panda/parser/ETSparserExpressions.cpp +++ b/ets2panda/parser/ETSparserExpressions.cpp @@ -41,11 +41,11 @@ static std::string GetArgumentsSourceView(lexer::Lexer *lexer, const util::Strin ir::Expression *ETSParser::ParseFunctionParameterExpression(ir::AnnotatedExpression *const paramIdent, bool isOptional) { ir::ETSParameterExpression *paramExpression; + ES2PANDA_ASSERT(paramIdent != nullptr); if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SUBSTITUTION) { auto const lexerPos = Lexer()->Save().Iterator(); Lexer()->NextToken(); // eat '=' - ES2PANDA_ASSERT(paramIdent != nullptr); if (paramIdent->IsRestElement()) { LogError(diagnostic::NO_DEFAULT_FOR_REST); } @@ -76,9 +76,11 @@ ir::Expression *ETSParser::ParseFunctionParameterExpression(ir::AnnotatedExpress paramExpression->SetRange({paramIdent->Start(), paramExpression->Initializer()->End()}); } else if (paramIdent->IsIdentifier()) { paramExpression = AllocNode(paramIdent->AsIdentifier(), isOptional, Allocator()); + ES2PANDA_ASSERT(paramExpression != nullptr); paramExpression->SetRange({paramIdent->Start(), paramIdent->End()}); } else { paramExpression = AllocNode(paramIdent->AsRestElement(), false, Allocator()); + ES2PANDA_ASSERT(paramExpression != nullptr); paramExpression->SetRange({paramIdent->Start(), paramIdent->End()}); } return paramExpression; @@ -181,6 +183,7 @@ ir::Expression *ETSParser::ParseUnaryOrPrefixUpdateExpression(ExpressionParseFla } ir::Expression *returnExpr = CreateUnaryExpressionFromArgument(argument, operatorType, beginningChar); + ES2PANDA_ASSERT(returnExpr != nullptr); returnExpr->SetRange({start, argument->End()}); return returnExpr; } @@ -218,6 +221,7 @@ ir::Expression *ETSParser::ParsePropertyDefinition(ExpressionParseFlags flags) if (propertyKind == ir::PropertyKind::INIT) { returnProperty = AllocNode(propertyKind, key, value, methodStatus != ParserStatus::NO_OPTS, isComputed); + ES2PANDA_ASSERT(returnProperty != nullptr); returnProperty->SetRange({start, end}); } else { returnProperty = AllocBrokenExpression(key->Start()); diff --git a/ets2panda/parser/ETSparserNamespaces.cpp b/ets2panda/parser/ETSparserNamespaces.cpp index d60297de796..807b70099f0 100644 --- a/ets2panda/parser/ETSparserNamespaces.cpp +++ b/ets2panda/parser/ETSparserNamespaces.cpp @@ -71,6 +71,7 @@ ir::ETSModule *ETSParser::ParseNamespaceImp(ir::ModifierFlags flags) auto *result = AllocNode(Allocator(), ArenaVector(Allocator()->Adapter()), ExpectIdentifier(), ir::ModuleFlag::NAMESPACE, GetContext().GetLanguage(), globalProgram_); + ES2PANDA_ASSERT(result != nullptr); ir::ETSModule *parent = result; ir::ETSModule *child = nullptr; while (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD) { diff --git a/ets2panda/parser/ETSparserTypes.cpp b/ets2panda/parser/ETSparserTypes.cpp index 44e57121936..918223fb9d8 100644 --- a/ets2panda/parser/ETSparserTypes.cpp +++ b/ets2panda/parser/ETSparserTypes.cpp @@ -178,6 +178,7 @@ ir::TypeNode *ETSParser::ParseWildcardType(TypeAnnotationParsingOptions *options ir::ETSTypeReference *typeReference = nullptr; if (!isUnboundOut) { auto reference = ParseTypeReference(options); + ES2PANDA_ASSERT(reference != nullptr); typeReference = reference->AsETSTypeReference(); } diff --git a/ets2panda/parser/TSparser.cpp b/ets2panda/parser/TSparser.cpp index d2545ce4258..4c41a234a3e 100644 --- a/ets2panda/parser/TSparser.cpp +++ b/ets2panda/parser/TSparser.cpp @@ -515,7 +515,7 @@ ir::TypeNode *TSParser::ParseTypeOperatorOrTypeReference() } auto *typeOperator = AllocNode(type, ir::TSOperatorType::READONLY, Allocator()); - + ES2PANDA_ASSERT(typeOperator != nullptr); typeOperator->SetRange({typeOperatorStart, type->End()}); return typeOperator; @@ -1934,6 +1934,7 @@ ir::MethodDefinition *TSParser::ParseClassMethod(ClassElementDescriptor *desc, } auto *funcExpr = AllocNode(func); + ES2PANDA_ASSERT(funcExpr != nullptr); funcExpr->SetRange(func->Range()); if (desc->methodKind == ir::MethodDefinitionKind::SET) { @@ -1946,6 +1947,7 @@ ir::MethodDefinition *TSParser::ParseClassMethod(ClassElementDescriptor *desc, func->AddFlag(ir::ScriptFunctionFlags::METHOD); auto *method = AllocNode(desc->methodKind, propName, funcExpr, desc->modifiers, Allocator(), desc->isComputed); + ES2PANDA_ASSERT(method != nullptr); method->SetRange(funcExpr->Range()); return method; diff --git a/ets2panda/parser/expressionParser.cpp b/ets2panda/parser/expressionParser.cpp index 596a70e0864..ebc744397b8 100644 --- a/ets2panda/parser/expressionParser.cpp +++ b/ets2panda/parser/expressionParser.cpp @@ -348,6 +348,7 @@ ir::ArrowFunctionExpression *ParserImpl::ParseArrowFunctionExpressionBody(ArrowF funcNode->SetRange({desc->startLoc, endLoc}); auto *arrowFuncNode = AllocNode(funcNode, Allocator()); + ES2PANDA_ASSERT(arrowFuncNode != nullptr); arrowFuncNode->SetRange(funcNode->Range()); return arrowFuncNode; @@ -2370,7 +2371,7 @@ ir::Expression *ParserImpl::ParseUnaryOrPrefixUpdateExpression(ExpressionParseFl returnExpr = AllocNode(argument, operatorType); } - ES2PANDA_ASSERT(returnExpr); + ES2PANDA_ASSERT(returnExpr != nullptr); returnExpr->SetRange({start, end}); return returnExpr; @@ -2416,6 +2417,7 @@ ir::Expression *ParserImpl::ParseImportExpression() ExpectToken(lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS); auto *importExpression = AllocNode(source); + ES2PANDA_ASSERT(importExpression != nullptr); importExpression->SetRange({startLoc, endImportLoc}); return importExpression; @@ -2451,6 +2453,7 @@ ir::FunctionExpression *ParserImpl::ParseFunctionExpression(ParserStatus newStat } ir::ScriptFunction *functionNode = ParseFunction(newStatus); + ES2PANDA_ASSERT(functionNode != nullptr); functionNode->SetStart(startLoc); auto *funcExpr = AllocNode(ident, functionNode); diff --git a/ets2panda/parser/parserImpl.cpp b/ets2panda/parser/parserImpl.cpp index 2b6e9ce4816..ae8dd74781d 100644 --- a/ets2panda/parser/parserImpl.cpp +++ b/ets2panda/parser/parserImpl.cpp @@ -480,6 +480,7 @@ ir::MethodDefinition *ParserImpl::ParseClassMethod(ClassElementDescriptor *desc, : propName; auto *method = AllocNode(desc->methodKind, ident, funcExpr, desc->modifiers, Allocator(), desc->isComputed); + ES2PANDA_ASSERT(method != nullptr); method->SetRange(funcExpr->Range()); return method; @@ -495,6 +496,7 @@ ir::ClassElement *ParserImpl::ParseClassProperty(ClassElementDescriptor *desc, if (desc->classMethod) { property = ParseClassMethod(desc, properties, propName, &propEnd); + ES2PANDA_ASSERT(property != nullptr); property->SetRange({desc->propStart, propEnd}); return property; } @@ -514,7 +516,7 @@ ir::ClassElement *ParserImpl::ParseClassProperty(ClassElementDescriptor *desc, property = AllocNode(propName, value, typeAnnotation, desc->modifiers, Allocator(), desc->isComputed); - + ES2PANDA_ASSERT(property != nullptr); property->SetRange({desc->propStart, propEnd}); return property; @@ -685,6 +687,7 @@ ir::MethodDefinition *ParserImpl::BuildImplicitConstructor(ir::ClassDefinitionMo auto *key = AllocNode("constructor", Allocator()); if ((modifiers & ir::ClassDefinitionModifiers::SET_CTOR_ID) != 0U) { + ES2PANDA_ASSERT(key != nullptr); func->SetIdent(key->Clone(Allocator(), nullptr)); } @@ -710,6 +713,7 @@ void ParserImpl::CreateImplicitConstructor(ir::MethodDefinition *&ctor, ctor = BuildImplicitConstructor(modifiers, startLoc); if ((flags & ir::ModifierFlags::DECLARE) != 0) { + ES2PANDA_ASSERT(ctor != nullptr); auto *ctorFunc = ctor->Function(); ES2PANDA_ASSERT(ctorFunc != nullptr); ctorFunc->AddFlag(ir::ScriptFunctionFlags::EXTERNAL); diff --git a/ets2panda/parser/statementParser.cpp b/ets2panda/parser/statementParser.cpp index c311d81ec3c..cb374f95f30 100644 --- a/ets2panda/parser/statementParser.cpp +++ b/ets2panda/parser/statementParser.cpp @@ -525,9 +525,11 @@ ir::Statement *ParserImpl::ParseBreakStatement() } auto *identNode = AllocNode(label, Allocator()); + ES2PANDA_ASSERT(identNode != nullptr); identNode->SetRange(lexer_->GetToken().Loc()); auto *breakStatement = AllocNode(identNode); + ES2PANDA_ASSERT(breakStatement != nullptr); breakStatement->SetRange({startLoc, lexer_->GetToken().End()}); lexer_->NextToken(); @@ -580,6 +582,7 @@ ir::Statement *ParserImpl::ParseContinueStatement() } auto *identNode = AllocNode(label, Allocator()); + ES2PANDA_ASSERT(identNode != nullptr); identNode->SetRange(lexer_->GetToken().Loc()); auto *continueStatement = AllocNode(identNode); @@ -662,9 +665,11 @@ ir::FunctionDeclaration *ParserImpl::ParseFunctionDeclaration(bool canBeAnonymou if (lexer_->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) { if (canBeAnonymous) { ir::ScriptFunction *func = ParseFunction(newStatus | ParserStatus::NEED_RETURN_TYPE); + ES2PANDA_ASSERT(func != nullptr); func->SetStart(startLoc); auto *funcDecl = AllocNode(Allocator(), func, true); + ES2PANDA_ASSERT(funcDecl != nullptr); funcDecl->SetRange(func->Range()); return funcDecl; } @@ -684,6 +689,7 @@ ir::FunctionDeclaration *ParserImpl::ParseFunctionDeclaration(bool canBeAnonymou func->SetIdent(identNode); func->SetStart(startLoc); auto *funcDecl = AllocNode(Allocator(), func); + ES2PANDA_ASSERT(funcDecl != nullptr); funcDecl->SetRange(func->Range()); if (func->IsOverload() && lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SEMI_COLON) { @@ -1383,6 +1389,7 @@ ir::Statement *ParserImpl::ParseTryStatement() while (lexer_->GetToken().Type() == lexer::TokenType::KEYW_CATCH) { catchClause = ParseCatchClause(); + ES2PANDA_ASSERT(catchClause != nullptr); endLoc = catchClause->End(); catchClauses.push_back(catchClause); } @@ -1398,6 +1405,7 @@ ir::Statement *ParserImpl::ParseTryStatement() ArenaVector> finalizerInsertions(Allocator()->Adapter()); auto *tryStatement = AllocNode(body, std::move(catchClauses), finallyClause, finalizerInsertions); + ES2PANDA_ASSERT(tryStatement != nullptr); tryStatement->SetRange({startLoc, endLoc}); return tryStatement; } @@ -2001,6 +2009,7 @@ ir::Statement *ParserImpl::ParseImportDeclaration(StatementParsingFlags flags) source = ParseFromClause(false); } + ES2PANDA_ASSERT(source != nullptr); lexer::SourcePosition endLoc = source->End(); auto *importDeclaration = AllocNode(source, std::move(specifiers)); ES2PANDA_ASSERT(importDeclaration != nullptr); diff --git a/ets2panda/parser/statementTSParser.cpp b/ets2panda/parser/statementTSParser.cpp index 4cd60c24dbd..b0a451bcd38 100644 --- a/ets2panda/parser/statementTSParser.cpp +++ b/ets2panda/parser/statementTSParser.cpp @@ -372,6 +372,7 @@ ir::Statement *TSParser::ParseImportDeclaration([[maybe_unused]] StatementParsin ES2PANDA_ASSERT(source != nullptr); lexer::SourcePosition endLoc = source->End(); auto *importDeclaration = AllocNode(source, std::move(specifiers)); + ES2PANDA_ASSERT(importDeclaration != nullptr); importDeclaration->SetRange({startLoc, endLoc}); ConsumeSemicolon(importDeclaration); -- Gitee From 298fa0d0459aca9f80e3c0d8de03ff667f2d38a2 Mon Sep 17 00:00:00 2001 From: daizihan Date: Wed, 9 Jul 2025 19:06:08 +0800 Subject: [PATCH 7/8] Fix fuzz crash by adapting recursiveguard Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICL7RW?from=project-issue Signed-off-by: daizihan --- ets2panda/parser/ETSparser.h | 3 --- ets2panda/parser/ETSparserExpressions.cpp | 22 +++++++------------ ets2panda/parser/parserImpl.h | 7 ++++++ ets2panda/parser/statementParser.cpp | 9 ++++++++ ets2panda/test/runtime/ets/too_many_async.ets | 22 +++++++++++++++++++ ets2panda/test/runtime/ets/too_many_await.ets | 22 +++++++++++++++++++ .../test/runtime/ets/too_many_left_brace.ets | 22 +++++++++++++++++++ .../ets/too_many_left_square_brackets.ets | 21 ++++++++++++++++++ .../test/runtime/ets/too_many_new_expr.ets | 22 +++++++++++++++++++ .../srcdumper/srcdumper-ets-ignored.txt | 5 +++++ 10 files changed, 138 insertions(+), 17 deletions(-) create mode 100644 ets2panda/test/runtime/ets/too_many_async.ets create mode 100644 ets2panda/test/runtime/ets/too_many_await.ets create mode 100644 ets2panda/test/runtime/ets/too_many_left_brace.ets create mode 100644 ets2panda/test/runtime/ets/too_many_left_square_brackets.ets create mode 100644 ets2panda/test/runtime/ets/too_many_new_expr.ets diff --git a/ets2panda/parser/ETSparser.h b/ets2panda/parser/ETSparser.h index 8dddff53b55..d25709eeda4 100644 --- a/ets2panda/parser/ETSparser.h +++ b/ets2panda/parser/ETSparser.h @@ -18,7 +18,6 @@ #include "util/arktsconfig.h" #include "util/importPathManager.h" -#include "util/recursiveGuard.h" #include "innerSourceParser.h" #include "TypedParser.h" #include "ir/base/classDefinition.h" @@ -458,7 +457,6 @@ private: friend class ExternalSourceParser; friend class InnerSourceParser; - friend ir::Expression *HandleLeftParanthesis(ETSParser *parser, ExpressionParseFlags flags); private: uint32_t namespaceNestedRank_; @@ -468,7 +466,6 @@ private: parser::Program *globalProgram_; std::vector insertingNodes_ {}; std::unique_ptr importPathManager_ {nullptr}; - RecursiveContext recursiveCtx_; }; class ExternalSourceParser { diff --git a/ets2panda/parser/ETSparserExpressions.cpp b/ets2panda/parser/ETSparserExpressions.cpp index d07eb072085..e2c0c26ef2e 100644 --- a/ets2panda/parser/ETSparserExpressions.cpp +++ b/ets2panda/parser/ETSparserExpressions.cpp @@ -317,26 +317,20 @@ ir::Expression *ETSParser::ParsePrimaryExpressionWithLiterals(ExpressionParseFla } } -// This function is used to handle the left parenthesis in the expression parsing. -ir::Expression *HandleLeftParanthesis(ETSParser *parser, ExpressionParseFlags flags) +// NOLINTNEXTLINE(google-default-arguments) +ir::Expression *ETSParser::ParsePrimaryExpression(ExpressionParseFlags flags) { - TrackRecursive trackRecursive(parser->recursiveCtx_); + TrackRecursive trackRecursive(RecursiveCtx()); if (!trackRecursive) { - parser->LogError(diagnostic::DEEP_NESTING); - while (parser->Lexer()->GetToken().Type() != lexer::TokenType::EOS) { - parser->Lexer()->NextToken(); + LogError(diagnostic::DEEP_NESTING); + while (Lexer()->GetToken().Type() != lexer::TokenType::EOS) { + Lexer()->NextToken(); } - return parser->AllocBrokenExpression(parser->Lexer()->GetToken().Loc()); + return AllocBrokenExpression(Lexer()->GetToken().Loc()); } - return parser->ParseCoverParenthesizedExpressionAndArrowParameterList(flags); -} - -// NOLINTNEXTLINE(google-default-arguments) -ir::Expression *ETSParser::ParsePrimaryExpression(ExpressionParseFlags flags) -{ switch (Lexer()->GetToken().Type()) { case lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS: { - return HandleLeftParanthesis(this, flags); + return ParseCoverParenthesizedExpressionAndArrowParameterList(flags); } case lexer::TokenType::KEYW_THIS: { return ParseThisExpression(); diff --git a/ets2panda/parser/parserImpl.h b/ets2panda/parser/parserImpl.h index 3652e719f23..4b5bc12221c 100644 --- a/ets2panda/parser/parserImpl.h +++ b/ets2panda/parser/parserImpl.h @@ -26,6 +26,7 @@ #include "parser/program/program.h" #include "util/diagnosticEngine.h" #include "util/helpers.h" +#include "util/recursiveGuard.h" namespace ark::es2panda::lexer { class RegExpParser; @@ -572,6 +573,11 @@ protected: const std::function &parseElement, lexer::SourcePosition *sourceEnd = nullptr, bool allowTrailingSep = false); + RecursiveContext &RecursiveCtx() + { + return recursiveCtx_; + } + private: bool GetCanBeForInOf(ir::Expression *leftNode, ir::AstNode *initNode); Program *program_; @@ -582,6 +588,7 @@ private: const util::Options *options_; util::DiagnosticEngine &diagnosticEngine_; public_lib::Context *ctx_ {nullptr}; + RecursiveContext recursiveCtx_; }; } // namespace ark::es2panda::parser diff --git a/ets2panda/parser/statementParser.cpp b/ets2panda/parser/statementParser.cpp index c311d81ec3c..2312034d760 100644 --- a/ets2panda/parser/statementParser.cpp +++ b/ets2panda/parser/statementParser.cpp @@ -63,6 +63,7 @@ #include "lexer/lexer.h" #include "lexer/token/letters.h" #include "lexer/token/sourceLocation.h" +#include "util/recursiveGuard.h" #include "util/ustring.h" #include "generated/diagnostic.h" @@ -91,6 +92,14 @@ ir::Statement *ParserImpl::ParseStatementLiteralIdentHelper(StatementParsingFlag // NOLINTNEXTLINE(google-default-arguments) ir::Statement *ParserImpl::ParseStatementPunctuatorsHelper(StatementParsingFlags flags) { + TrackRecursive trackRecursive(RecursiveCtx()); + if (!trackRecursive) { + LogError(diagnostic::DEEP_NESTING); + while (Lexer()->GetToken().Type() != lexer::TokenType::EOS) { + Lexer()->NextToken(); + } + return AllocBrokenStatement(Lexer()->GetToken().Loc()); + } switch (lexer_->GetToken().Type()) { case lexer::TokenType::PUNCTUATOR_LEFT_BRACE: return ParseBlockStatement(); diff --git a/ets2panda/test/runtime/ets/too_many_async.ets b/ets2panda/test/runtime/ets/too_many_async.ets new file mode 100644 index 00000000000..066837c21e9 --- /dev/null +++ b/ets2panda/test/runtime/ets/too_many_async.ets @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * 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. + */ +/*--- + tags: [compile-only, negative] +---*/ + +// This test cannot moved to astchecker, because this will lead python JSON parse error: +// Failed with maximum recursion depth exceeded while decoding a JSON object from a unicode string + +async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async(ync(async(async(async(async(async(async(async(async(async(async(async( diff --git a/ets2panda/test/runtime/ets/too_many_await.ets b/ets2panda/test/runtime/ets/too_many_await.ets new file mode 100644 index 00000000000..94fe7922745 --- /dev/null +++ b/ets2panda/test/runtime/ets/too_many_await.ets @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * 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. + */ +/*--- + tags: [compile-only, negative] +---*/ + +// This test cannot moved to astchecker, because this will lead python JSON parse error: +// Failed with maximum recursion depth exceeded while decoding a JSON object from a unicode string + +await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await await diff --git a/ets2panda/test/runtime/ets/too_many_left_brace.ets b/ets2panda/test/runtime/ets/too_many_left_brace.ets new file mode 100644 index 00000000000..aab155383ec --- /dev/null +++ b/ets2panda/test/runtime/ets/too_many_left_brace.ets @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * 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. + */ +/*--- + tags: [compile-only, negative] +---*/ + +// This test cannot moved to astchecker, because this will lead python JSON parse error: +// Failed with maximum recursion depth exceeded while decoding a JSON object from a unicode string + +{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ diff --git a/ets2panda/test/runtime/ets/too_many_left_square_brackets.ets b/ets2panda/test/runtime/ets/too_many_left_square_brackets.ets new file mode 100644 index 00000000000..07d66a05d57 --- /dev/null +++ b/ets2panda/test/runtime/ets/too_many_left_square_brackets.ets @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * 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. + */ +/*--- + tags: [compile-only, negative] +---*/ + +// This test cannot moved to astchecker, because this will lead python JSON parse error: +// Failed with maximum recursion depth exceeded while decoding a JSON object from a unicode string +[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ diff --git a/ets2panda/test/runtime/ets/too_many_new_expr.ets b/ets2panda/test/runtime/ets/too_many_new_expr.ets new file mode 100644 index 00000000000..772493b196b --- /dev/null +++ b/ets2panda/test/runtime/ets/too_many_new_expr.ets @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * 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. + */ +/*--- + tags: [compile-only, negative] +---*/ + +// This test cannot moved to astchecker, because this will lead python JSON parse error: +// Failed with maximum recursion depth exceeded while decoding a JSON object from a unicode string + +new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new(new( diff --git a/ets2panda/test/test-lists/srcdumper/srcdumper-ets-ignored.txt b/ets2panda/test/test-lists/srcdumper/srcdumper-ets-ignored.txt index 67a4459f5de..1d0a071b78f 100644 --- a/ets2panda/test/test-lists/srcdumper/srcdumper-ets-ignored.txt +++ b/ets2panda/test/test-lists/srcdumper/srcdumper-ets-ignored.txt @@ -39,6 +39,11 @@ runtime/ets/type_param_in_union.ets runtime/ets/StringFasta.ets runtime/ets/struct-identifier.ets runtime/ets/struct-init2.ets +runtime/ets/too_many_async.ets +runtime/ets/too_many_await.ets +runtime/ets/too_many_left_brace.ets +runtime/ets/too_many_left_square_brackets.ets +runtime/ets/too_many_new_expr.ets ast/compiler/ets/DeclareIndexerTest.ets ast/parser/ets/import_tests/import_class_with_static_field/import_class_with_static_field.ets -- Gitee From 4d1736f93d0183c14ed5473b9bdbf7434bc01c72 Mon Sep 17 00:00:00 2001 From: xuxinjie4 Date: Tue, 15 Jul 2025 22:16:17 +0800 Subject: [PATCH 8/8] Fix lambda bug Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICMK8W?from=project-issue Signed-off-by: xuxinjie4 --- ets2panda/checker/ETSAnalyzer.cpp | 4 +--- ets2panda/compiler/core/ETSCompiler.cpp | 2 +- ets2panda/compiler/lowering/ets/lambdaLowering.cpp | 5 +++-- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/ets2panda/checker/ETSAnalyzer.cpp b/ets2panda/checker/ETSAnalyzer.cpp index fb821fb4234..59bd40ad218 100644 --- a/ets2panda/checker/ETSAnalyzer.cpp +++ b/ets2panda/checker/ETSAnalyzer.cpp @@ -1796,9 +1796,7 @@ checker::Type *ETSAnalyzer::Check(ir::ConditionalExpression *expr) const static Type *TransformTypeForMethodReference(ETSChecker *checker, ir::Expression *const use, Type *type) { ES2PANDA_ASSERT(use->IsIdentifier() || use->IsMemberExpression()); - if (!type->IsETSMethodType() || - (use->IsMemberExpression() && use->AsMemberExpression()->PropVar() != nullptr && - use->AsMemberExpression()->PropVar()->HasFlag(varbinder::VariableFlags::DYNAMIC))) { + if (!type->IsETSMethodType()) { return type; } auto const getUseSite = [use]() { diff --git a/ets2panda/compiler/core/ETSCompiler.cpp b/ets2panda/compiler/core/ETSCompiler.cpp index 75fd7d3de50..83fd68fe4d8 100644 --- a/ets2panda/compiler/core/ETSCompiler.cpp +++ b/ets2panda/compiler/core/ETSCompiler.cpp @@ -757,7 +757,7 @@ void ETSCompiler::Compile(const ir::CallExpression *expr) const auto const callee = expr->Callee(); checker::Signature *const signature = expr->Signature(); - ES2PANDA_ASSERT(!callee->TsType()->IsETSArrowType()); // should have been lowered + ES2PANDA_ASSERT(!callee->TsType()->IsETSArrowType() || expr->IsDynamicCall()); // should have been lowered bool const isStatic = signature->HasSignatureFlag(checker::SignatureFlags::STATIC); diff --git a/ets2panda/compiler/lowering/ets/lambdaLowering.cpp b/ets2panda/compiler/lowering/ets/lambdaLowering.cpp index f621292487d..3533aac4ae8 100644 --- a/ets2panda/compiler/lowering/ets/lambdaLowering.cpp +++ b/ets2panda/compiler/lowering/ets/lambdaLowering.cpp @@ -1311,14 +1311,15 @@ static ir::AstNode *BuildLambdaClassWhenNeeded(public_lib::Context *ctx, ir::Ast // so it is correct to pass ETS extension here to isReference() if (id->IsReference(ScriptExtension::ETS) && id->TsType() != nullptr && id->TsType()->IsETSFunctionType() && !IsInCalleePosition(id) && !IsEnumFunctionCall(id) && IsValidFunctionDeclVar(var) && - !id->Variable()->HasFlag(varbinder::VariableFlags::DYNAMIC) && !IsOverloadedName(id)) { + !IsOverloadedName(id)) { return ConvertFunctionReference(ctx, id); } } if (node->IsMemberExpression()) { auto *mexpr = node->AsMemberExpression(); if (mexpr->Kind() == ir::MemberExpressionKind::PROPERTY_ACCESS && mexpr->TsType() != nullptr && - mexpr->TsType()->IsETSFunctionType() && mexpr->Object()->TsType()->IsETSObjectType()) { + mexpr->TsType()->IsETSFunctionType() && mexpr->Object()->TsType()->IsETSObjectType() && + mexpr->PropVar() != nullptr && !mexpr->PropVar()->HasFlag(varbinder::VariableFlags::DYNAMIC)) { ES2PANDA_ASSERT(mexpr->Property()->IsIdentifier()); auto *var = mexpr->Object()->TsType()->AsETSObjectType()->GetProperty( mexpr->Property()->AsIdentifier()->Name(), -- Gitee