commit e2890e1478f088f45deaeb9dc19f416c1656b702 Author: huangwei <983142558@qq.com> Date: Tue Jul 30 18:21:40 2024 +0800 创建第一个版本 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d293cf1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,31 @@ +#git submodule update --init --recursive +*.hprof +build/ +.vscode/ +.gradle +/local.properties +/.idea +.DS_Store +/captures +/build +/app/build +/app/release +/app/mapping.txt +/app/src/main/libs +/app/src/main/obj +/controlapp/mapping.txt +/controlapp/release +/alpha/build +/alpha/release +/alpha/mapping.txt +/alpha/src/main/schemas/zone.a.dimap.db.RecordsDataBase/1.json +*.iml +.idea +*.jks +obj/ +.cxx/ +*.class +#定制版本 +/app/*/release +/alpha/*/release +/pad/*/release diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..a8b9b8d --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "control_common"] + path = control_common + url = http://code.bingce.com/BingCe-Android/control_common.git diff --git a/README.md b/README.md new file mode 100644 index 0000000..d592795 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +解放军信息工程导线助手 diff --git a/aar/base/base-release.aar b/aar/base/base-release.aar new file mode 100644 index 0000000..9983d9a Binary files /dev/null and b/aar/base/base-release.aar differ diff --git a/aar/base/build.gradle b/aar/base/build.gradle new file mode 100644 index 0000000..587b7c2 --- /dev/null +++ b/aar/base/build.gradle @@ -0,0 +1,2 @@ +configurations.maybeCreate("default") +artifacts.add("default", file('base-release.aar')) \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..3f08270 --- /dev/null +++ b/app/.gitignore @@ -0,0 +1,2 @@ +/build +*/release \ No newline at end of file diff --git a/app/README.md b/app/README.md new file mode 100644 index 0000000..8b72265 --- /dev/null +++ b/app/README.md @@ -0,0 +1,5 @@ +打包注意事项: +1.检查 Test.java 中的DEBUG是否为false; +2.检查 打包版本号; +3.检查数据库版本号; +4.检查changelog.xml内容 diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..ae79708 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,150 @@ +import com.bingce.AndroidSdk +import com.bingce.App +import com.bingce.Libs +import com.bingce.ModuleName + +apply plugin: 'com.android.application' +apply plugin: 'org.jetbrains.kotlin.android' +apply plugin: 'kotlin-kapt' +apply plugin: 'kotlin-parcelize' +apply from: "../control_common/config.gradle" + + +android { + useLibrary Libs.httpLegacy + compileSdk AndroidSdk.compileSdkVersion + namespace App.ControlNetwork.applicationId + + defaultConfig { + versionName "1.0.1" + versionCode 1 + minSdkVersion AndroidSdk.minSdkVersion + targetSdkVersion AndroidSdk.targetSdkVersion + ndk {} + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + multiDexEnabled true + + javaCompileOptions { + annotationProcessorOptions { + arguments = [ + //数据库room + "room.schemaLocation": "$projectDir/src/main/schemas".toString() + ] + } + } + } + + buildFeatures { + viewBinding true + buildConfig true + } + + signingConfigs { + debug { + storeFile file('./debug.keystore') + } + } + + buildTypes { + debug { + signingConfig signingConfigs.debug + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + release { + minifyEnabled true + shrinkResources true + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } + + splits { + // Split apks on build target ABI, view all options for the splits here: + // http://tools.android.com/tech-docs/new-build-system/user-guide/apk-splits + abi { + enable true + reset() + include 'arm64-v8a'//,'armeabi-v7a', 'x86'//, 'x86_64', 'mips','armeabi', + } + } + + //为了解决部分第三方库重复打包了META-INF的问题 + packagingOptions { + exclude 'META-INF/DEPENDENCIES' + exclude 'META-INF/LICENSE.txt' + exclude 'META-INF/NOTICE.txt' + exclude 'META-INF/LICENSE' + exclude 'META-INF/NOTICE' + + exclude 'META-INF/*.kotlin_module' + exclude '/META-INF/{AL2.0,LGPL2.1}'//适配compose +// exclude 'schemaorg_apache_xmlbeans/**' +// exclude 'assets/org/apache/**' +// exclude 'org/apache/**' +// exclude 'font_metrics.properties' + } + + lintOptions { + abortOnError false + disable 'GoogleAppIndexingWarning' + } +} + +dependencies { + implementation fileTree(include: ['*.jar', '*.aar'], dir: 'libs') + implementation project(':control_common') + + def moduleName = new ModuleName(project) + implementation project(moduleName.bingceModule("appBase")) + implementation project(moduleName.bingceModule("repository")) + implementation project(moduleName.bingceModule("base")) + implementation project(moduleName.bingceModule("leancloud")) + implementation project(moduleName.bingceModule("base-java")) + implementation project(moduleName.bingceModule("utils")) + implementation project(moduleName.bingceModule("coordlib")) + implementation project(moduleName.bingceModule("device")) + implementation project(moduleName.bingceModule("device-ui")) + implementation project(moduleName.bingceModule("rtk")) + implementation project(moduleName.bingceModule("totalstation")) + implementation project(moduleName.bingceModule("level")) + implementation project(moduleName.bingceModule("bcdialog-style")) + implementation project(moduleName.openSourceModule("utilcode")) + implementation project(moduleName.openSourceModule("colorful"))//选择主题颜色 + implementation project(moduleName.openSourceModule("dragExpandGrid"))//管理里的布局 + implementation project(moduleName.openSourceModule("lsettingitemlibrary"))//用户信息里 + implementation project(moduleName.openSourceModule("spinkit"))//loading控件 导出使用 + implementation project(moduleName.openSourceModule("splashview"))//广告view + implementation project(moduleName.openSourceModule("poishadowjar"))//导入excel + implementation project(moduleName.openSourceModule("safFilePicker"))//选择文件 + implementation project(moduleName.openSourceModule("fastjson")) + implementation project(moduleName.openSourceModule("agentweb")) + implementation project(":opensource:exFilePicker") + implementation project(":sdk:tensorFlowTTS")//语音播报 + implementation Libs.RxImagePicker.core +// implementation Libs.RxImagePicker.support +// implementation Libs.RxImagePicker.supportWechat + + constraints { + implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.9.10") { + because("kotlin-stdlib-jdk7 is now a part of kotlin-stdlib") + } + implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.10") { + because("kotlin-stdlib-jdk8 is now a part of kotlin-stdlib") + } + } + +// implementation "cn.leancloud:storage-android:8.2.5" +// implementation "cn.leancloud:realtime-android:8.2.5" + implementation Libs.LeanCloud.storage + implementation Libs.LeanCloud.realtime + + testImplementation "junit:junit:4.13.2" + androidTestImplementation "androidx.test:runner:1.1.0" + androidTestImplementation "androidx.test:rules:1.1.0" + androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0' + + implementation 'com.google.android.gms:play-services-auth:20.7.0' + + project.ext.dependencies.each { k, v -> implementation v } + project.ext.kapt.each { k, v -> kapt v } +} \ No newline at end of file diff --git a/app/debug.keystore b/app/debug.keystore new file mode 100644 index 0000000..5bb84af Binary files /dev/null and b/app/debug.keystore differ diff --git a/app/doc/Untitled-old.mdj b/app/doc/Untitled-old.mdj new file mode 100644 index 0000000..c83fd9d --- /dev/null +++ b/app/doc/Untitled-old.mdj @@ -0,0 +1,44 @@ +{ + "_type": "Project", + "_id": "AAAAAAFF+h6SjaM2Hec=", + "name": "Untitled", + "ownedElements": [ + { + "_type": "UMLModel", + "_id": "AAAAAAFF+qBWK6M3Z8Y=", + "_parent": { + "$ref": "AAAAAAFF+h6SjaM2Hec=" + }, + "name": "Model", + "ownedElements": [ + { + "_type": "UMLStateMachine", + "_id": "AAAAAAF5RXOA7okfG2A=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "StateMachine1", + "ownedElements": [ + { + "_type": "UMLStatechartDiagram", + "_id": "AAAAAAF5RXOA7okhiTg=", + "_parent": { + "$ref": "AAAAAAF5RXOA7okfG2A=" + }, + "name": "StatechartDiagram1" + } + ], + "regions": [ + { + "_type": "UMLRegion", + "_id": "AAAAAAF5RXOA7okgaKU=", + "_parent": { + "$ref": "AAAAAAF5RXOA7okfG2A=" + } + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/app/doc/states.mdj b/app/doc/states.mdj new file mode 100644 index 0000000..fa3a069 --- /dev/null +++ b/app/doc/states.mdj @@ -0,0 +1,36869 @@ +{ + "_type": "Project", + "_id": "AAAAAAFElm5XMFNoGY0=", + "name": "Untitled", + "ownedElements": [ + { + "_type": "UMLModel", + "_id": "AAAAAAFElm6BOFNpegQ=", + "_parent": { + "$ref": "AAAAAAFElm5XMFNoGY0=" + }, + "name": "Model", + "ownedElements": [ + { + "_type": "UMLUseCaseDiagram", + "_id": "AAAAAAF5P5m6Qk1jVXQ=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "UseCaseDiagram1", + "ownedViews": [ + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5P5nMr01oLTI=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5P5nMrk1mLCw=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5P5nMr01pxLs=", + "_parent": { + "$ref": "AAAAAAF5P5nMr01oLTI=" + }, + "model": { + "$ref": "AAAAAAF5P5nMrk1mLCw=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5P5nMr01qZlQ=", + "_parent": { + "$ref": "AAAAAAF5P5nMr01pxLs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 224, + "top": 352, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5P5nMr01rWkA=", + "_parent": { + "$ref": "AAAAAAF5P5nMr01pxLs=" + }, + "font": "Arial;13;1", + "left": 132, + "top": 187.5, + "width": 62, + "height": 13, + "text": "check2C" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5P5nMr01srVY=", + "_parent": { + "$ref": "AAAAAAF5P5nMr01pxLs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 224, + "top": 352, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5P5nMr01tKAI=", + "_parent": { + "$ref": "AAAAAAF5P5nMr01pxLs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 224, + "top": 352, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 127, + "top": 180.5, + "width": 72, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5P5nMr01qZlQ=" + }, + "nameLabel": { + "$ref": "AAAAAAF5P5nMr01rWkA=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5P5nMr01srVY=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5P5nMr01tKAI=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5P5nMr01u10s=", + "_parent": { + "$ref": "AAAAAAF5P5nMr01oLTI=" + }, + "model": { + "$ref": "AAAAAAF5P5nMrk1mLCw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 112, + "top": 176, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5P5nMr01vn/8=", + "_parent": { + "$ref": "AAAAAAF5P5nMr01oLTI=" + }, + "model": { + "$ref": "AAAAAAF5P5nMrk1mLCw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 112, + "top": 176, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5nMr01wvTc=", + "_parent": { + "$ref": "AAAAAAF5P5nMr01oLTI=" + }, + "model": { + "$ref": "AAAAAAF5P5nMrk1mLCw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 112, + "top": 176, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5P5nMr01xNvU=", + "_parent": { + "$ref": "AAAAAAF5P5nMr01oLTI=" + }, + "model": { + "$ref": "AAAAAAF5P5nMrk1mLCw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 112, + "top": 176, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5P5nMr01yEgM=", + "_parent": { + "$ref": "AAAAAAF5P5nMr01oLTI=" + }, + "model": { + "$ref": "AAAAAAF5P5nMrk1mLCw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 112, + "top": 176, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 112, + "top": 176, + "width": 102, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5P5nMr01pxLs=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5P5nMr01u10s=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5P5nMr01vn/8=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5nMr01wvTc=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5P5nMr01xNvU=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5P5nMr01yEgM=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5P5rmBE2YaOM=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5P5rmBE2WOV0=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5P5rmBE2Z1VU=", + "_parent": { + "$ref": "AAAAAAF5P5rmBE2YaOM=" + }, + "model": { + "$ref": "AAAAAAF5P5rmBE2WOV0=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5P5rmBE2awCc=", + "_parent": { + "$ref": "AAAAAAF5P5rmBE2Z1VU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -112, + "top": -368, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5P5rmBE2bxgA=", + "_parent": { + "$ref": "AAAAAAF5P5rmBE2Z1VU=" + }, + "font": "Arial;13;1", + "left": 367, + "top": 83.5, + "width": 75, + "height": 13, + "text": "recordClean" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5P5rmBU2c6aQ=", + "_parent": { + "$ref": "AAAAAAF5P5rmBE2Z1VU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -112, + "top": -368, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5P5rmBU2dJfU=", + "_parent": { + "$ref": "AAAAAAF5P5rmBE2Z1VU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -112, + "top": -368, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 362, + "top": 76.5, + "width": 85.86083984375, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5P5rmBE2awCc=" + }, + "nameLabel": { + "$ref": "AAAAAAF5P5rmBE2bxgA=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5P5rmBU2c6aQ=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5P5rmBU2dJfU=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5P5rmBU2e6A8=", + "_parent": { + "$ref": "AAAAAAF5P5rmBE2YaOM=" + }, + "model": { + "$ref": "AAAAAAF5P5rmBE2WOV0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -56, + "top": -184, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5P5rmBU2f+Vc=", + "_parent": { + "$ref": "AAAAAAF5P5rmBE2YaOM=" + }, + "model": { + "$ref": "AAAAAAF5P5rmBE2WOV0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -56, + "top": -184, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5rmBU2gXnU=", + "_parent": { + "$ref": "AAAAAAF5P5rmBE2YaOM=" + }, + "model": { + "$ref": "AAAAAAF5P5rmBE2WOV0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -56, + "top": -184, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5P5rmBU2hbLU=", + "_parent": { + "$ref": "AAAAAAF5P5rmBE2YaOM=" + }, + "model": { + "$ref": "AAAAAAF5P5rmBE2WOV0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -56, + "top": -184, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5P5rmBU2iePg=", + "_parent": { + "$ref": "AAAAAAF5P5rmBE2YaOM=" + }, + "model": { + "$ref": "AAAAAAF5P5rmBE2WOV0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -56, + "top": -184, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 344, + "top": 72, + "width": 121, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5P5rmBE2Z1VU=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5P5rmBU2e6A8=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5P5rmBU2f+Vc=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5rmBU2gXnU=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5P5rmBU2hbLU=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5P5rmBU2iePg=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5P5saWE3J2FY=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5P5saV03F9So=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5saWE3K1ts=", + "_parent": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "model": { + "$ref": "AAAAAAF5P5saV03F9So=" + }, + "font": "Arial;13;0", + "left": 248, + "top": 121, + "width": 59.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "edgePosition": 1, + "text": "+通过检测" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5saWE3LIi0=", + "_parent": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "model": { + "$ref": "AAAAAAF5P5saV03F9So=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 271, + "top": 107, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5saWE3M7xA=", + "_parent": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "model": { + "$ref": "AAAAAAF5P5saV03F9So=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 288, + "top": 148, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5saWE3NmNI=", + "_parent": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "model": { + "$ref": "AAAAAAF5P5saV03GReQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 221, + "top": 144, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5saWE3Oy1k=", + "_parent": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "model": { + "$ref": "AAAAAAF5P5saV03GReQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 218, + "top": 131, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5saWE3PZiY=", + "_parent": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "model": { + "$ref": "AAAAAAF5P5saV03GReQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 228, + "top": 171, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5saWE3QKR0=", + "_parent": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "model": { + "$ref": "AAAAAAF5P5saV03HrLQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 332, + "top": 97, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5saWE3RVpc=", + "_parent": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "model": { + "$ref": "AAAAAAF5P5saV03HrLQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 324, + "top": 86, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5saWE3S3i0=", + "_parent": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "model": { + "$ref": "AAAAAAF5P5saV03HrLQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 347, + "top": 121, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5P5saWE3TepE=", + "_parent": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "model": { + "$ref": "AAAAAAF5P5saV03GReQ=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5P5saWE3U3g4=", + "_parent": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "model": { + "$ref": "AAAAAAF5P5saV03HrLQ=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5P5rmBE2YaOM=" + }, + "tail": { + "$ref": "AAAAAAF5P5nMr01oLTI=" + }, + "lineStyle": 1, + "points": "204:175;362:107", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5P5saWE3K1ts=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5P5saWE3LIi0=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5P5saWE3M7xA=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5P5saWE3NmNI=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5P5saWE3Oy1k=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5P5saWE3PZiY=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5P5saWE3QKR0=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5P5saWE3RVpc=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5P5saWE3S3i0=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5P5saWE3TepE=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5P5saWE3U3g4=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5P56LZE6M/G8=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5P56LY06KFIA=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5P56LZE6NeNY=", + "_parent": { + "$ref": "AAAAAAF5P56LZE6M/G8=" + }, + "model": { + "$ref": "AAAAAAF5P56LY06KFIA=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5P56LZE6OE2I=", + "_parent": { + "$ref": "AAAAAAF5P56LZE6NeNY=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": -464, + "top": -224, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5P56LZE6PKW0=", + "_parent": { + "$ref": "AAAAAAF5P56LZE6NeNY=" + }, + "fillColor": "#ff8282", + "font": "Arial;13;1", + "left": 205, + "top": 283.5, + "width": 103, + "height": 13, + "text": "【用户选择操作】" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5P56LZE6QSXM=", + "_parent": { + "$ref": "AAAAAAF5P56LZE6NeNY=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": -464, + "top": -224, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5P56LZE6RMmU=", + "_parent": { + "$ref": "AAAAAAF5P56LZE6NeNY=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": -464, + "top": -224, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 200, + "top": 276.5, + "width": 114, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5P56LZE6OE2I=" + }, + "nameLabel": { + "$ref": "AAAAAAF5P56LZE6PKW0=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5P56LZE6QSXM=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5P56LZE6RMmU=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5P56LZE6SLIg=", + "_parent": { + "$ref": "AAAAAAF5P56LZE6M/G8=" + }, + "model": { + "$ref": "AAAAAAF5P56LY06KFIA=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": -232, + "top": -112, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5P56LZE6TWFg=", + "_parent": { + "$ref": "AAAAAAF5P56LZE6M/G8=" + }, + "model": { + "$ref": "AAAAAAF5P56LY06KFIA=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": -232, + "top": -112, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P56LZE6U8ts=", + "_parent": { + "$ref": "AAAAAAF5P56LZE6M/G8=" + }, + "model": { + "$ref": "AAAAAAF5P56LY06KFIA=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": -232, + "top": -112, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5P56LZE6VNIk=", + "_parent": { + "$ref": "AAAAAAF5P56LZE6M/G8=" + }, + "model": { + "$ref": "AAAAAAF5P56LY06KFIA=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": -232, + "top": -112, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5P56LZE6W1sE=", + "_parent": { + "$ref": "AAAAAAF5P56LZE6M/G8=" + }, + "model": { + "$ref": "AAAAAAF5P56LY06KFIA=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": -232, + "top": -112, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ff8282", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 176, + "top": 272, + "width": 161, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5P56LZE6NeNY=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5P56LZE6SLIg=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5P56LZE6TWFg=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P56LZE6U8ts=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5P56LZE6VNIk=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5P56LZE6W1sE=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5P56tgE7IY7E=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5P56tf07Epig=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P56tgE7JO9U=", + "_parent": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "model": { + "$ref": "AAAAAAF5P56tf07Epig=" + }, + "font": "Arial;13;0", + "left": 183, + "top": 224, + "width": 72.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "edgePosition": 1, + "text": "+未通过检测" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P56tgE7Kkjk=", + "_parent": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "model": { + "$ref": "AAAAAAF5P56tf07Epig=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 230, + "top": 214, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P56tgE7LlPE=", + "_parent": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "model": { + "$ref": "AAAAAAF5P56tf07Epig=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 198, + "top": 245, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P56tgE7MSF4=", + "_parent": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "model": { + "$ref": "AAAAAAF5P56tgE7F7Yk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 208, + "top": 213, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P56tgE7NsLs=", + "_parent": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "model": { + "$ref": "AAAAAAF5P56tgE7F7Yk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 219, + "top": 205, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P56tgE7OBww=", + "_parent": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "model": { + "$ref": "AAAAAAF5P56tgE7F7Yk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 186, + "top": 229, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P56tgE7PoMY=", + "_parent": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "model": { + "$ref": "AAAAAAF5P56tgE7GNNA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 230, + "top": 235, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P56tgE7Q0NM=", + "_parent": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "model": { + "$ref": "AAAAAAF5P56tgE7GNNA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 238, + "top": 225, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P56tgE7RtW8=", + "_parent": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "model": { + "$ref": "AAAAAAF5P56tgE7GNNA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 213, + "top": 258, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5P56tgE7SCeE=", + "_parent": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "model": { + "$ref": "AAAAAAF5P56tgE7F7Yk=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5P56tgE7TSmw=", + "_parent": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "model": { + "$ref": "AAAAAAF5P56tgE7GNNA=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5P56LZE6M/G8=" + }, + "tail": { + "$ref": "AAAAAAF5P5nMr01oLTI=" + }, + "lineStyle": 1, + "points": "180:211;238:271", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5P56tgE7JO9U=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5P56tgE7Kkjk=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5P56tgE7LlPE=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5P56tgE7MSF4=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5P56tgE7NsLs=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5P56tgE7OBww=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5P56tgE7PoMY=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5P56tgE7Q0NM=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5P56tgE7RtW8=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5P56tgE7SCeE=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5P56tgE7TSmw=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5P5/CAk98zZc=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5P5/CAk96MB0=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5P5/CAk99r9g=", + "_parent": { + "$ref": "AAAAAAF5P5/CAk98zZc=" + }, + "model": { + "$ref": "AAAAAAF5P5/CAk96MB0=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5P5/CA09+uJY=", + "_parent": { + "$ref": "AAAAAAF5P5/CAk99r9g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 64, + "top": -64, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5P5/CA09/h4M=", + "_parent": { + "$ref": "AAAAAAF5P5/CAk99r9g=" + }, + "font": "Arial;13;1", + "left": 764, + "top": 467.5, + "width": 62, + "height": 13, + "text": "Idle" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5P5/CA0+AvMQ=", + "_parent": { + "$ref": "AAAAAAF5P5/CAk99r9g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 64, + "top": -64, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5P5/CA0+BODA=", + "_parent": { + "$ref": "AAAAAAF5P5/CAk99r9g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 64, + "top": -64, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 759, + "top": 460.5, + "width": 72, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5P5/CA09+uJY=" + }, + "nameLabel": { + "$ref": "AAAAAAF5P5/CA09/h4M=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5P5/CA0+AvMQ=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5P5/CA0+BODA=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5P5/CA0+CFD4=", + "_parent": { + "$ref": "AAAAAAF5P5/CAk98zZc=" + }, + "model": { + "$ref": "AAAAAAF5P5/CAk96MB0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 32, + "top": -32, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5P5/CA0+DO7Q=", + "_parent": { + "$ref": "AAAAAAF5P5/CAk98zZc=" + }, + "model": { + "$ref": "AAAAAAF5P5/CAk96MB0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 32, + "top": -32, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5/CA0+EZ7w=", + "_parent": { + "$ref": "AAAAAAF5P5/CAk98zZc=" + }, + "model": { + "$ref": "AAAAAAF5P5/CAk96MB0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 32, + "top": -32, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5P5/CA0+FMSM=", + "_parent": { + "$ref": "AAAAAAF5P5/CAk98zZc=" + }, + "model": { + "$ref": "AAAAAAF5P5/CAk96MB0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 32, + "top": -32, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5P5/CA0+GOcA=", + "_parent": { + "$ref": "AAAAAAF5P5/CAk98zZc=" + }, + "model": { + "$ref": "AAAAAAF5P5/CAk96MB0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 32, + "top": -32, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 744, + "top": 456, + "width": 102, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5P5/CAk99r9g=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5P5/CA0+CFD4=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5P5/CA0+DO7Q=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5/CA0+EZ7w=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5P5/CA0+FMSM=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5P5/CA0+GOcA=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5P5/ask/ENuY=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5P5/ask/ASWM=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5/ask/FCi8=", + "_parent": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "model": { + "$ref": "AAAAAAF5P5/ask/ASWM=" + }, + "font": "Arial;13;0", + "left": 300, + "top": 372, + "width": 124.22798156738281, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "edgePosition": 1, + "text": "+选择忽略or重测目标" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5/ask/GmBY=", + "_parent": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "model": { + "$ref": "AAAAAAF5P5/ask/ASWM=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 373, + "top": 362, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5/ask/H9Os=", + "_parent": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "model": { + "$ref": "AAAAAAF5P5/ask/ASWM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 341, + "top": 393, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5/ask/ITgo=", + "_parent": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "model": { + "$ref": "AAAAAAF5P5/ask/BASE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 301, + "top": 309, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5/ask/J3dw=", + "_parent": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "model": { + "$ref": "AAAAAAF5P5/ask/BASE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 312, + "top": 301, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5/ask/KH+Q=", + "_parent": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "model": { + "$ref": "AAAAAAF5P5/ask/BASE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 279, + "top": 325, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5/ask/LwxI=", + "_parent": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "model": { + "$ref": "AAAAAAF5P5/ask/CwwU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 424, + "top": 435, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5/ask/MCSM=", + "_parent": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "model": { + "$ref": "AAAAAAF5P5/ask/CwwU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 432, + "top": 425, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5/ask/N7rw=", + "_parent": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "model": { + "$ref": "AAAAAAF5P5/ask/CwwU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 407, + "top": 458, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5P5/ask/OUQY=", + "_parent": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "model": { + "$ref": "AAAAAAF5P5/ask/BASE=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5P5/ask/P3tM=", + "_parent": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "model": { + "$ref": "AAAAAAF5P5/ask/CwwU=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QJjLZRML/gk=" + }, + "tail": { + "$ref": "AAAAAAF5P56LZE6M/G8=" + }, + "lineStyle": 1, + "points": "273:307;432:471", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5P5/ask/FCi8=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5P5/ask/GmBY=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5P5/ask/H9Os=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5P5/ask/ITgo=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5P5/ask/J3dw=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5P5/ask/KH+Q=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5P5/ask/LwxI=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5P5/ask/MCSM=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5P5/ask/N7rw=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5P5/ask/OUQY=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5P5/ask/P3tM=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5P6Btl1DS04s=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5P6Btl1DQYFs=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5P6Btl1DTuQ4=", + "_parent": { + "$ref": "AAAAAAF5P6Btl1DS04s=" + }, + "model": { + "$ref": "AAAAAAF5P6Btl1DQYFs=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5P6Btl1DUbE8=", + "_parent": { + "$ref": "AAAAAAF5P6Btl1DTuQ4=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -1072, + "top": 160, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5P6BtmFDVnHI=", + "_parent": { + "$ref": "AAAAAAF5P6Btl1DTuQ4=" + }, + "fillColor": "#ffadad", + "font": "Arial;13;1", + "left": 74.5, + "top": 411.5, + "width": 207, + "height": 13, + "text": "【提示用户是否确定删除整个测回】" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5P6BtmFDW1Rc=", + "_parent": { + "$ref": "AAAAAAF5P6Btl1DTuQ4=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -1072, + "top": 160, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5P6BtmFDXJZ4=", + "_parent": { + "$ref": "AAAAAAF5P6Btl1DTuQ4=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -1072, + "top": 160, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 69.5, + "top": 404.5, + "width": 218, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5P6Btl1DUbE8=" + }, + "nameLabel": { + "$ref": "AAAAAAF5P6BtmFDVnHI=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5P6BtmFDW1Rc=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5P6BtmFDXJZ4=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5P6BtmFDYzoo=", + "_parent": { + "$ref": "AAAAAAF5P6Btl1DS04s=" + }, + "model": { + "$ref": "AAAAAAF5P6Btl1DQYFs=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -536, + "top": 80, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5P6BtmFDZfOA=", + "_parent": { + "$ref": "AAAAAAF5P6Btl1DS04s=" + }, + "model": { + "$ref": "AAAAAAF5P6Btl1DQYFs=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -536, + "top": 80, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P6BtmFDabNE=", + "_parent": { + "$ref": "AAAAAAF5P6Btl1DS04s=" + }, + "model": { + "$ref": "AAAAAAF5P6Btl1DQYFs=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -536, + "top": 80, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5P6BtmFDbcVg=", + "_parent": { + "$ref": "AAAAAAF5P6Btl1DS04s=" + }, + "model": { + "$ref": "AAAAAAF5P6Btl1DQYFs=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -536, + "top": 80, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5P6BtmFDcrag=", + "_parent": { + "$ref": "AAAAAAF5P6Btl1DS04s=" + }, + "model": { + "$ref": "AAAAAAF5P6Btl1DQYFs=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -536, + "top": 80, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ffadad", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 24, + "top": 400, + "width": 308, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5P6Btl1DTuQ4=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5P6BtmFDYzoo=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5P6BtmFDZfOA=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P6BtmFDabNE=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5P6BtmFDbcVg=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5P6BtmFDcrag=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5P6ETu1Fw08c=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5P6ETu1Fsgo0=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6ETvFFx1mw=", + "_parent": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "model": { + "$ref": "AAAAAAF5P6ETu1Fsgo0=" + }, + "font": "Arial;13;0", + "left": 199, + "top": 354, + "width": 59.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "edgePosition": 1, + "text": "+重测测回" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6ETvFFyw0s=", + "_parent": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "model": { + "$ref": "AAAAAAF5P6ETu1Fsgo0=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 241, + "top": 362, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6ETvFFzyRs=", + "_parent": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "model": { + "$ref": "AAAAAAF5P6ETu1Fsgo0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 203, + "top": 339, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6ETvFF0+lY=", + "_parent": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "model": { + "$ref": "AAAAAAF5P6ETu1FtUvs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 244, + "top": 330, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6ETvFF1ok8=", + "_parent": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "model": { + "$ref": "AAAAAAF5P6ETu1FtUvs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 254, + "top": 339, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6ETvFF2wKI=", + "_parent": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "model": { + "$ref": "AAAAAAF5P6ETu1FtUvs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 222, + "top": 312, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6ETvFF3tbw=", + "_parent": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "model": { + "$ref": "AAAAAAF5P6ETu1Fuzfc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 214, + "top": 378, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6ETvFF4Oc0=", + "_parent": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "model": { + "$ref": "AAAAAAF5P6ETu1Fuzfc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 226, + "top": 383, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6ETvFF586k=", + "_parent": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "model": { + "$ref": "AAAAAAF5P6ETu1Fuzfc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 188, + "top": 368, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5P6ETvFF6xek=", + "_parent": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "model": { + "$ref": "AAAAAAF5P6ETu1FtUvs=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5P6ETvFF7szs=", + "_parent": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "model": { + "$ref": "AAAAAAF5P6ETu1Fuzfc=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5P6Btl1DS04s=" + }, + "tail": { + "$ref": "AAAAAAF5P56LZE6M/G8=" + }, + "lineStyle": 1, + "points": "245:307;188:399", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5P6ETvFFx1mw=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5P6ETvFFyw0s=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5P6ETvFFzyRs=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5P6ETvFF0+lY=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5P6ETvFF1ok8=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5P6ETvFF2wKI=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5P6ETvFF3tbw=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5P6ETvFF4Oc0=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5P6ETvFF586k=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5P6ETvFF6xek=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5P6ETvFF7szs=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5P6HZl1JC23Y=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5P6HZl1I+eIg=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6HZl1JDZsQ=", + "_parent": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "model": { + "$ref": "AAAAAAF5P6HZl1I+eIg=" + }, + "font": "Arial;13;0", + "left": 267, + "top": 432, + "width": 98.22798156738281, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "edgePosition": 1, + "text": "+选择忽略or取消" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6HZl1JECIw=", + "_parent": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "model": { + "$ref": "AAAAAAF5P6HZl1I+eIg=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 320, + "top": 417, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6HZl1JF8pk=", + "_parent": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "model": { + "$ref": "AAAAAAF5P6HZl1I+eIg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 309, + "top": 461, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6HZl1JG0HA=", + "_parent": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "model": { + "$ref": "AAAAAAF5P6HZl1I/u/s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 273, + "top": 421, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6HZl1JHztQ=", + "_parent": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "model": { + "$ref": "AAAAAAF5P6HZl1I/u/s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 279, + "top": 408, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6HZl1JIPD0=", + "_parent": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "model": { + "$ref": "AAAAAAF5P6HZl1I/u/s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 262, + "top": 446, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6HZl1JJLUs=", + "_parent": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "model": { + "$ref": "AAAAAAF5P6HZl1JAt1Q=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 359, + "top": 443, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6HZl1JKFgU=", + "_parent": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "model": { + "$ref": "AAAAAAF5P6HZl1JAt1Q=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 360, + "top": 430, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6HZl1JLM+Y=", + "_parent": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "model": { + "$ref": "AAAAAAF5P6HZl1JAt1Q=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 356, + "top": 471, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5P6HZl1JMru0=", + "_parent": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "model": { + "$ref": "AAAAAAF5P6HZl1I/u/s=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5P6HZl1JNqZA=", + "_parent": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "model": { + "$ref": "AAAAAAF5P6HZl1JAt1Q=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QJjLZRML/gk=" + }, + "tail": { + "$ref": "AAAAAAF5P6Btl1DS04s=" + }, + "lineStyle": 1, + "points": "245:435;381:471", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5P6HZl1JDZsQ=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5P6HZl1JECIw=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5P6HZl1JF8pk=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5P6HZl1JG0HA=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5P6HZl1JHztQ=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5P6HZl1JIPD0=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5P6HZl1JJLUs=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5P6HZl1JKFgU=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5P6HZl1JLM+Y=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5P6HZl1JMru0=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5P6HZl1JNqZA=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5P6IYDFMMeFQ=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5P6IYDFMK28k=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5P6IYDFMNnzQ=", + "_parent": { + "$ref": "AAAAAAF5P6IYDFMMeFQ=" + }, + "model": { + "$ref": "AAAAAAF5P6IYDFMK28k=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5P6IYDFMOOjk=", + "_parent": { + "$ref": "AAAAAAF5P6IYDFMNnzQ=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": -1536, + "top": 544, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5P6IYDVMPgvc=", + "_parent": { + "$ref": "AAAAAAF5P6IYDFMNnzQ=" + }, + "fillColor": "#ff8282", + "font": "Arial;13;1", + "left": 125, + "top": 531.5, + "width": 103, + "height": 13, + "text": "【执行删除操作】" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5P6IYDVMQezU=", + "_parent": { + "$ref": "AAAAAAF5P6IYDFMNnzQ=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": -1536, + "top": 544, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5P6IYDVMRBdM=", + "_parent": { + "$ref": "AAAAAAF5P6IYDFMNnzQ=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": -1536, + "top": 544, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 120, + "top": 524.5, + "width": 114, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5P6IYDFMOOjk=" + }, + "nameLabel": { + "$ref": "AAAAAAF5P6IYDVMPgvc=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5P6IYDVMQezU=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5P6IYDVMRBdM=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5P6IYDVMSZQE=", + "_parent": { + "$ref": "AAAAAAF5P6IYDFMMeFQ=" + }, + "model": { + "$ref": "AAAAAAF5P6IYDFMK28k=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": -768, + "top": 272, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5P6IYDVMTe6E=", + "_parent": { + "$ref": "AAAAAAF5P6IYDFMMeFQ=" + }, + "model": { + "$ref": "AAAAAAF5P6IYDFMK28k=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": -768, + "top": 272, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P6IYDVMUviY=", + "_parent": { + "$ref": "AAAAAAF5P6IYDFMMeFQ=" + }, + "model": { + "$ref": "AAAAAAF5P6IYDFMK28k=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": -768, + "top": 272, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5P6IYDVMVT7Q=", + "_parent": { + "$ref": "AAAAAAF5P6IYDFMMeFQ=" + }, + "model": { + "$ref": "AAAAAAF5P6IYDFMK28k=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": -768, + "top": 272, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5P6IYDVMWeEE=", + "_parent": { + "$ref": "AAAAAAF5P6IYDFMMeFQ=" + }, + "model": { + "$ref": "AAAAAAF5P6IYDFMK28k=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": -768, + "top": 272, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ff8282", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 96, + "top": 520, + "width": 161, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5P6IYDFMNnzQ=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5P6IYDVMSZQE=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5P6IYDVMTe6E=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P6IYDVMUviY=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5P6IYDVMVT7Q=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5P6IYDVMWeEE=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5P6Jc6FQAXTQ=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5P6Jc6FP89fs=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6Jc6FQBsAA=", + "_parent": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "model": { + "$ref": "AAAAAAF5P6Jc6FP89fs=" + }, + "font": "Arial;13;0", + "left": 161, + "top": 470, + "width": 59.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "edgePosition": 1, + "text": "+确认删除" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6Jc6FQCliU=", + "_parent": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "model": { + "$ref": "AAAAAAF5P6Jc6FP89fs=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 205, + "top": 470, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6Jc6FQDs0Y=", + "_parent": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "model": { + "$ref": "AAAAAAF5P6Jc6FP89fs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 161, + "top": 471, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6Jc6VQErUI=", + "_parent": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "model": { + "$ref": "AAAAAAF5P6Jc6FP9Ay0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 191, + "top": 455, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6Jc6VQFXc4=", + "_parent": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "model": { + "$ref": "AAAAAAF5P6Jc6FP9Ay0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 204, + "top": 457, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6Jc6VQGACw=", + "_parent": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "model": { + "$ref": "AAAAAAF5P6Jc6FP9Ay0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 164, + "top": 450, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6Jc6VQH5rw=", + "_parent": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "model": { + "$ref": "AAAAAAF5P6Jc6FP+W/w=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 191, + "top": 487, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6Jc6VQIDDY=", + "_parent": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "model": { + "$ref": "AAAAAAF5P6Jc6FP+W/w=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 204, + "top": 485, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6Jc6VQJXs0=", + "_parent": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "model": { + "$ref": "AAAAAAF5P6Jc6FP+W/w=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 163, + "top": 491, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5P6Jc6VQKiwE=", + "_parent": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "model": { + "$ref": "AAAAAAF5P6Jc6FP9Ay0=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5P6Jc6VQLymI=", + "_parent": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "model": { + "$ref": "AAAAAAF5P6Jc6FP+W/w=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5P6IYDFMMeFQ=" + }, + "tail": { + "$ref": "AAAAAAF5P6Btl1DS04s=" + }, + "lineStyle": 1, + "points": "177:435;176:519", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5P6Jc6FQBsAA=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5P6Jc6FQCliU=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5P6Jc6FQDs0Y=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5P6Jc6VQErUI=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5P6Jc6VQFXc4=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5P6Jc6VQGACw=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5P6Jc6VQH5rw=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5P6Jc6VQIDDY=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5P6Jc6VQJXs0=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5P6Jc6VQKiwE=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5P6Jc6VQLymI=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5P6KuWFYy590=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5P6KuWFYuLA4=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6KuWFYzBrY=", + "_parent": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "model": { + "$ref": "AAAAAAF5P6KuWFYuLA4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 409, + "top": 536, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6KuWFY07+U=", + "_parent": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "model": { + "$ref": "AAAAAAF5P6KuWFYuLA4=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 410, + "top": 521, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6KuWFY1T2M=", + "_parent": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "model": { + "$ref": "AAAAAAF5P6KuWFYuLA4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 406, + "top": 565, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6KuWFY2uTU=", + "_parent": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "model": { + "$ref": "AAAAAAF5P6KuWFYvXto=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 284, + "top": 525, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6KuWFY3Q0s=", + "_parent": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "model": { + "$ref": "AAAAAAF5P6KuWFYvXto=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 287, + "top": 512, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6KuWFY4NMQ=", + "_parent": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "model": { + "$ref": "AAAAAAF5P6KuWFYvXto=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 277, + "top": 552, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6KuWFY5sZg=", + "_parent": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "model": { + "$ref": "AAAAAAF5P6KuWFYwtmg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 534, + "top": 547, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P6KuWFYy590=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6KuWFY62Oo=", + "_parent": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "model": { + "$ref": "AAAAAAF5P6KuWFYwtmg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 533, + "top": 534, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5P6KuWFYy590=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6KuWFY78L8=", + "_parent": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "model": { + "$ref": "AAAAAAF5P6KuWFYwtmg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 536, + "top": 575, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5P6KuWFYy590=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5P6KuWFY8wFs=", + "_parent": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "model": { + "$ref": "AAAAAAF5P6KuWFYvXto=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 376, + "top": -144, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5P6KuWVY9b40=", + "_parent": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "model": { + "$ref": "AAAAAAF5P6KuWFYwtmg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 376, + "top": -144, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QMaQUG/rlG8=" + }, + "tail": { + "$ref": "AAAAAAF5P6IYDFMMeFQ=" + }, + "lineStyle": 1, + "points": "257:544;559:571", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5P6KuWFYzBrY=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5P6KuWFY07+U=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5P6KuWFY1T2M=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5P6KuWFY2uTU=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5P6KuWFY3Q0s=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5P6KuWFY4NMQ=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5P6KuWFY5sZg=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5P6KuWFY62Oo=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5P6KuWFY78L8=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5P6KuWFY8wFs=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5P6KuWVY9b40=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5QJWvCwgzk0M=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QJWvCggxZrM=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5QJWvCwg0EPw=", + "_parent": { + "$ref": "AAAAAAF5QJWvCwgzk0M=" + }, + "model": { + "$ref": "AAAAAAF5QJWvCggxZrM=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5QJWvCwg1NpM=", + "_parent": { + "$ref": "AAAAAAF5QJWvCwg0EPw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 704, + "top": 2032, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJWvCwg2wKE=", + "_parent": { + "$ref": "AAAAAAF5QJWvCwg0EPw=" + }, + "font": "Arial;13;1", + "left": 1144, + "top": 1419.5, + "width": 119, + "height": 13, + "text": "move2NextValidate" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJWvCwg3lvo=", + "_parent": { + "$ref": "AAAAAAF5QJWvCwg0EPw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 704, + "top": 2032, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJWvCwg4tCw=", + "_parent": { + "$ref": "AAAAAAF5QJWvCwg0EPw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 704, + "top": 2032, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 1139, + "top": 1412.5, + "width": 129, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5QJWvCwg1NpM=" + }, + "nameLabel": { + "$ref": "AAAAAAF5QJWvCwg2wKE=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5QJWvCwg3lvo=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QJWvCwg4tCw=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5QJWvCwg5PfY=", + "_parent": { + "$ref": "AAAAAAF5QJWvCwgzk0M=" + }, + "model": { + "$ref": "AAAAAAF5QJWvCggxZrM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 352, + "top": 1016, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5QJWvDAg6ClE=", + "_parent": { + "$ref": "AAAAAAF5QJWvCwgzk0M=" + }, + "model": { + "$ref": "AAAAAAF5QJWvCggxZrM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 352, + "top": 1016, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5QJWvDAg7Ros=", + "_parent": { + "$ref": "AAAAAAF5QJWvCwgzk0M=" + }, + "model": { + "$ref": "AAAAAAF5QJWvCggxZrM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 352, + "top": 1016, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5QJWvDAg8tC0=", + "_parent": { + "$ref": "AAAAAAF5QJWvCwgzk0M=" + }, + "model": { + "$ref": "AAAAAAF5QJWvCggxZrM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 352, + "top": 1016, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5QJWvDAg9Vl8=", + "_parent": { + "$ref": "AAAAAAF5QJWvCwgzk0M=" + }, + "model": { + "$ref": "AAAAAAF5QJWvCggxZrM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 352, + "top": 1016, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 1112, + "top": 1408, + "width": 183, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5QJWvCwg0EPw=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5QJWvCwg5PfY=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5QJWvDAg6ClE=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5QJWvDAg7Ros=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5QJWvDAg8tC0=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5QJWvDAg9Vl8=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5QJc4CA2oNI0=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QJc4CA2m0sA=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5QJc4CA2p+Dw=", + "_parent": { + "$ref": "AAAAAAF5QJc4CA2oNI0=" + }, + "model": { + "$ref": "AAAAAAF5QJc4CA2m0sA=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5QJc4CA2qdmU=", + "_parent": { + "$ref": "AAAAAAF5QJc4CA2p+Dw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1808, + "top": -848, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJc4CA2r3po=", + "_parent": { + "$ref": "AAAAAAF5QJc4CA2p+Dw=" + }, + "font": "Arial;13;1", + "left": 1081, + "top": 339.5, + "width": 124, + "height": 13, + "text": "checkHalfCycleZero" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJc4CA2s9SY=", + "_parent": { + "$ref": "AAAAAAF5QJc4CA2p+Dw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1808, + "top": -848, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJc4CA2tVXo=", + "_parent": { + "$ref": "AAAAAAF5QJc4CA2p+Dw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1808, + "top": -848, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 1076, + "top": 332.5, + "width": 134.28076171875, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5QJc4CA2qdmU=" + }, + "nameLabel": { + "$ref": "AAAAAAF5QJc4CA2r3po=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5QJc4CA2s9SY=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QJc4CA2tVXo=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5QJc4CA2uA/U=", + "_parent": { + "$ref": "AAAAAAF5QJc4CA2oNI0=" + }, + "model": { + "$ref": "AAAAAAF5QJc4CA2m0sA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 904, + "top": -424, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5QJc4CQ2vtIA=", + "_parent": { + "$ref": "AAAAAAF5QJc4CA2oNI0=" + }, + "model": { + "$ref": "AAAAAAF5QJc4CA2m0sA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 904, + "top": -424, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5QJc4CQ2wvoY=", + "_parent": { + "$ref": "AAAAAAF5QJc4CA2oNI0=" + }, + "model": { + "$ref": "AAAAAAF5QJc4CA2m0sA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 904, + "top": -424, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5QJc4CQ2xB7c=", + "_parent": { + "$ref": "AAAAAAF5QJc4CA2oNI0=" + }, + "model": { + "$ref": "AAAAAAF5QJc4CA2m0sA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 904, + "top": -424, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5QJc4CQ2yPQg=", + "_parent": { + "$ref": "AAAAAAF5QJc4CA2oNI0=" + }, + "model": { + "$ref": "AAAAAAF5QJc4CA2m0sA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 904, + "top": -424, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 1048, + "top": 328, + "width": 190, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5QJc4CA2p+Dw=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5QJc4CA2uA/U=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5QJc4CQ2vtIA=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5QJc4CQ2wvoY=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5QJc4CQ2xB7c=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5QJc4CQ2yPQg=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5QJeXAw9Y7Yc=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QJeXAw9WAQQ=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5QJeXAw9Z7G0=", + "_parent": { + "$ref": "AAAAAAF5QJeXAw9Y7Yc=" + }, + "model": { + "$ref": "AAAAAAF5QJeXAw9WAQQ=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5QJeXAw9azp8=", + "_parent": { + "$ref": "AAAAAAF5QJeXAw9Z7G0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1936, + "top": -752, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJeXAw9b8aE=", + "_parent": { + "$ref": "AAAAAAF5QJeXAw9Z7G0=" + }, + "font": "Arial;13;1", + "left": 1469, + "top": 219.5, + "width": 105, + "height": 13, + "text": "isReady2CCheck" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJeXAw9cphk=", + "_parent": { + "$ref": "AAAAAAF5QJeXAw9Z7G0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1936, + "top": -752, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJeXAw9dhRA=", + "_parent": { + "$ref": "AAAAAAF5QJeXAw9Z7G0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1936, + "top": -752, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 1464, + "top": 212.5, + "width": 115.498046875, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5QJeXAw9azp8=" + }, + "nameLabel": { + "$ref": "AAAAAAF5QJeXAw9b8aE=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5QJeXAw9cphk=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QJeXAw9dhRA=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5QJeXAw9eiUw=", + "_parent": { + "$ref": "AAAAAAF5QJeXAw9Y7Yc=" + }, + "model": { + "$ref": "AAAAAAF5QJeXAw9WAQQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 968, + "top": -376, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5QJeXAw9fQSo=", + "_parent": { + "$ref": "AAAAAAF5QJeXAw9Y7Yc=" + }, + "model": { + "$ref": "AAAAAAF5QJeXAw9WAQQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 968, + "top": -376, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5QJeXAw9gktM=", + "_parent": { + "$ref": "AAAAAAF5QJeXAw9Y7Yc=" + }, + "model": { + "$ref": "AAAAAAF5QJeXAw9WAQQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 968, + "top": -376, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5QJeXAw9hx78=", + "_parent": { + "$ref": "AAAAAAF5QJeXAw9Y7Yc=" + }, + "model": { + "$ref": "AAAAAAF5QJeXAw9WAQQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 968, + "top": -376, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5QJeXAw9iEQ8=", + "_parent": { + "$ref": "AAAAAAF5QJeXAw9Y7Yc=" + }, + "model": { + "$ref": "AAAAAAF5QJeXAw9WAQQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 968, + "top": -376, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 1440, + "top": 208, + "width": 163, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5QJeXAw9Z7G0=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5QJeXAw9eiUw=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5QJeXAw9fQSo=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5QJeXAw9gktM=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5QJeXAw9hx78=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5QJeXAw9iEQ8=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QJesYRAYGmw=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QJesYRAUeZI=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJesYRAZQUY=", + "_parent": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "model": { + "$ref": "AAAAAAF5QJesYRAUeZI=" + }, + "font": "Arial;13;0", + "left": 1232, + "top": 264, + "width": 189.2279815673828, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "edgePosition": 1, + "text": "+测站不闭合or半测回归零差正常" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJesYRAa+X8=", + "_parent": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "model": { + "$ref": "AAAAAAF5QJesYRAUeZI=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1321, + "top": 250, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJesYRAb41g=", + "_parent": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "model": { + "$ref": "AAAAAAF5QJesYRAUeZI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1335, + "top": 293, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJesYhAcFHE=", + "_parent": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "model": { + "$ref": "AAAAAAF5QJesYRAV/Pw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1219, + "top": 298, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJesYhAdnH8=", + "_parent": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "model": { + "$ref": "AAAAAAF5QJesYRAV/Pw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1217, + "top": 285, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJesYhAeLA0=", + "_parent": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "model": { + "$ref": "AAAAAAF5QJesYRAV/Pw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1223, + "top": 326, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJesYhAfocQ=", + "_parent": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "model": { + "$ref": "AAAAAAF5QJesYRAWIno=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1434, + "top": 230, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJesYhAgNDY=", + "_parent": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "model": { + "$ref": "AAAAAAF5QJesYRAWIno=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1428, + "top": 218, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJesYhAh4Q4=", + "_parent": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "model": { + "$ref": "AAAAAAF5QJesYRAWIno=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1447, + "top": 255, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QJesYhAiBdg=", + "_parent": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "model": { + "$ref": "AAAAAAF5QJesYRAV/Pw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 112, + "top": -144, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QJesYhAjzjQ=", + "_parent": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "model": { + "$ref": "AAAAAAF5QJesYRAWIno=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 112, + "top": -144, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QJeXAw9Y7Yc=" + }, + "tail": { + "$ref": "AAAAAAF5QJc4CA2oNI0=" + }, + "lineStyle": 1, + "points": "1199:327;1464:243", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QJesYRAZQUY=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QJesYRAa+X8=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QJesYRAb41g=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QJesYhAcFHE=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QJesYhAdnH8=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QJesYhAeLA0=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QJesYhAfocQ=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QJesYhAgNDY=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QJesYhAh4Q4=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QJesYhAiBdg=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QJesYhAjzjQ=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5QJjLZRML/gk=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5QJjLZRMMO54=", + "_parent": { + "$ref": "AAAAAAF5QJjLZRML/gk=" + }, + "model": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5QJjLZRMN0eQ=", + "_parent": { + "$ref": "AAAAAAF5QJjLZRMMO54=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": -96, + "top": 32, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJjLZRMOGnw=", + "_parent": { + "$ref": "AAAAAAF5QJjLZRMMO54=" + }, + "fillColor": "#8282ff", + "font": "Arial;13;1", + "left": 380, + "top": 483.5, + "width": 139, + "height": 13, + "text": "switchState2StandStill" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJjLZRMPJsQ=", + "_parent": { + "$ref": "AAAAAAF5QJjLZRMMO54=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": -96, + "top": 32, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJjLZRMQZsw=", + "_parent": { + "$ref": "AAAAAAF5QJjLZRMMO54=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": -96, + "top": 32, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 375, + "top": 476.5, + "width": 149.419921875, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5QJjLZRMN0eQ=" + }, + "nameLabel": { + "$ref": "AAAAAAF5QJjLZRMOGnw=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5QJjLZRMPJsQ=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QJjLZRMQZsw=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5QJjLZRMRZxg=", + "_parent": { + "$ref": "AAAAAAF5QJjLZRML/gk=" + }, + "model": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": -48, + "top": 16, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5QJjLZRMSuGM=", + "_parent": { + "$ref": "AAAAAAF5QJjLZRML/gk=" + }, + "model": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": -48, + "top": 16, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5QJjLZRMTa74=", + "_parent": { + "$ref": "AAAAAAF5QJjLZRML/gk=" + }, + "model": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": -48, + "top": 16, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5QJjLZRMUk04=", + "_parent": { + "$ref": "AAAAAAF5QJjLZRML/gk=" + }, + "model": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": -48, + "top": 16, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5QJjLZRMVcTY=", + "_parent": { + "$ref": "AAAAAAF5QJjLZRML/gk=" + }, + "model": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": -48, + "top": 16, + "width": 10, + "height": 10 + } + ], + "fillColor": "#8282ff", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 344, + "top": 472, + "width": 211, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5QJjLZRMMO54=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5QJjLZRMRZxg=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5QJjLZRMSuGM=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5QJjLZRMTa74=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5QJjLZRMUk04=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5QJjLZRMVcTY=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5QJk5ohVYjKI=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QJk5ohVWyGc=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5QJk5ohVZ7LA=", + "_parent": { + "$ref": "AAAAAAF5QJk5ohVYjKI=" + }, + "model": { + "$ref": "AAAAAAF5QJk5ohVWyGc=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5QJk5ohVaBvo=", + "_parent": { + "$ref": "AAAAAAF5QJk5ohVZ7LA=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 528, + "top": -368, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJk5ohVbtSw=", + "_parent": { + "$ref": "AAAAAAF5QJk5ohVZ7LA=" + }, + "fillColor": "#ff8282", + "font": "Arial;13;1", + "left": 669, + "top": 387.5, + "width": 142, + "height": 13, + "text": "提示半测回归零检测失败" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJk5ohVc1ns=", + "_parent": { + "$ref": "AAAAAAF5QJk5ohVZ7LA=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 528, + "top": -368, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJk5ohVdnqY=", + "_parent": { + "$ref": "AAAAAAF5QJk5ohVZ7LA=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 528, + "top": -368, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 664, + "top": 380.5, + "width": 153, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5QJk5ohVaBvo=" + }, + "nameLabel": { + "$ref": "AAAAAAF5QJk5ohVbtSw=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5QJk5ohVc1ns=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QJk5ohVdnqY=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5QJk5ohVeC3M=", + "_parent": { + "$ref": "AAAAAAF5QJk5ohVYjKI=" + }, + "model": { + "$ref": "AAAAAAF5QJk5ohVWyGc=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 264, + "top": -184, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5QJk5ohVfd1M=", + "_parent": { + "$ref": "AAAAAAF5QJk5ohVYjKI=" + }, + "model": { + "$ref": "AAAAAAF5QJk5ohVWyGc=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 264, + "top": -184, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5QJk5ohVg6Qc=", + "_parent": { + "$ref": "AAAAAAF5QJk5ohVYjKI=" + }, + "model": { + "$ref": "AAAAAAF5QJk5ohVWyGc=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 264, + "top": -184, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5QJk5ohVh4ZY=", + "_parent": { + "$ref": "AAAAAAF5QJk5ohVYjKI=" + }, + "model": { + "$ref": "AAAAAAF5QJk5ohVWyGc=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 264, + "top": -184, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5QJk5ohViitY=", + "_parent": { + "$ref": "AAAAAAF5QJk5ohVYjKI=" + }, + "model": { + "$ref": "AAAAAAF5QJk5ohVWyGc=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 264, + "top": -184, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ff8282", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 632, + "top": 376, + "width": 216, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5QJk5ohVZ7LA=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5QJk5ohVeC3M=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5QJk5ohVfd1M=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5QJk5ohVg6Qc=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5QJk5ohVh4ZY=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5QJk5ohViitY=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QJmQwBdwdmk=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QJmQwBdscKg=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJmQwBdxb3k=", + "_parent": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "model": { + "$ref": "AAAAAAF5QJmQwBdscKg=" + }, + "font": "Arial;13;0", + "left": 906, + "top": 376, + "width": 85.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "edgePosition": 1, + "text": "+没有通过检测" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJmQwRdyFDg=", + "_parent": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "model": { + "$ref": "AAAAAAF5QJmQwBdscKg=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 950, + "top": 391, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJmQwRdzOi4=", + "_parent": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "model": { + "$ref": "AAAAAAF5QJmQwBdscKg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 945, + "top": 347, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJmQwRd0cxc=", + "_parent": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "model": { + "$ref": "AAAAAAF5QJmQwBdt/Nk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1023, + "top": 368, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJmQwRd1+jk=", + "_parent": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "model": { + "$ref": "AAAAAAF5QJmQwBdt/Nk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1022, + "top": 381, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJmQwRd2je8=", + "_parent": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "model": { + "$ref": "AAAAAAF5QJmQwBdt/Nk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1024, + "top": 340, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJmQwRd3aOM=", + "_parent": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "model": { + "$ref": "AAAAAAF5QJmQwBdu0wk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 875, + "top": 385, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJmQwRd4cEI=", + "_parent": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "model": { + "$ref": "AAAAAAF5QJmQwBdu0wk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 879, + "top": 398, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJmQwRd5h7I=", + "_parent": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "model": { + "$ref": "AAAAAAF5QJmQwBdu0wk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 867, + "top": 358, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QJmQwRd6XO0=", + "_parent": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "model": { + "$ref": "AAAAAAF5QJmQwBdt/Nk=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QJmQwRd7bPQ=", + "_parent": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "model": { + "$ref": "AAAAAAF5QJmQwBdu0wk=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QJk5ohVYjKI=" + }, + "tail": { + "$ref": "AAAAAAF5QJc4CA2oNI0=" + }, + "lineStyle": 1, + "points": "1047:356;848:380", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QJmQwBdxb3k=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QJmQwRdyFDg=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QJmQwRdzOi4=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QJmQwRd0cxc=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QJmQwRd1+jk=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QJmQwRd2je8=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QJmQwRd3aOM=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QJmQwRd4cEI=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QJmQwRd5h7I=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QJmQwRd6XO0=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QJmQwRd7bPQ=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QJnHsRkO52k=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QJnHsRkKHYc=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnHsRkPXt4=", + "_parent": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "model": { + "$ref": "AAAAAAF5QJnHsRkKHYc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 598, + "top": 449, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnHsRkQg5M=", + "_parent": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "model": { + "$ref": "AAAAAAF5QJnHsRkKHYc=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 603, + "top": 463, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnHsRkRfd8=", + "_parent": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "model": { + "$ref": "AAAAAAF5QJnHsRkKHYc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 589, + "top": 420, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnHsRkS/7E=", + "_parent": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "model": { + "$ref": "AAAAAAF5QJnHsRkLdTo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 665, + "top": 427, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnHsRkTUvo=", + "_parent": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "model": { + "$ref": "AAAAAAF5QJnHsRkLdTo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 666, + "top": 440, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnHsRkU2kA=", + "_parent": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "model": { + "$ref": "AAAAAAF5QJnHsRkLdTo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 660, + "top": 399, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnHsRkVrbg=", + "_parent": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "model": { + "$ref": "AAAAAAF5QJnHsRkM5N4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 532, + "top": 471, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnHsRkWL5A=", + "_parent": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "model": { + "$ref": "AAAAAAF5QJnHsRkM5N4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 538, + "top": 483, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnHsRkXIlE=", + "_parent": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "model": { + "$ref": "AAAAAAF5QJnHsRkM5N4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 519, + "top": 446, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QJnHsRkYjF0=", + "_parent": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "model": { + "$ref": "AAAAAAF5QJnHsRkLdTo=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QJnHsRkZRp4=", + "_parent": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "model": { + "$ref": "AAAAAAF5QJnHsRkM5N4=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QJjLZRML/gk=" + }, + "tail": { + "$ref": "AAAAAAF5QJk5ohVYjKI=" + }, + "lineStyle": 1, + "points": "685:411;503:471", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QJnHsRkPXt4=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QJnHsRkQg5M=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QJnHsRkRfd8=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QJnHsRkS/7E=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QJnHsRkTUvo=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QJnHsRkU2kA=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QJnHsRkVrbg=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QJnHsRkWL5A=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QJnHsRkXIlE=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QJnHsRkYjF0=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QJnHsRkZRp4=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QJnk3hnngQ0=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QJnk3RnjFKU=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnk3hnoFuM=", + "_parent": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "model": { + "$ref": "AAAAAAF5QJnk3RnjFKU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 648, + "top": 458, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnk3hnpzsU=", + "_parent": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "model": { + "$ref": "AAAAAAF5QJnk3RnjFKU=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 647, + "top": 443, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnk3hnqowI=", + "_parent": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "model": { + "$ref": "AAAAAAF5QJnk3RnjFKU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 649, + "top": 487, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnk3hnr2A8=", + "_parent": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "model": { + "$ref": "AAAAAAF5QJnk3Rnk4S8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 580, + "top": 461, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnk3hnsPz4=", + "_parent": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "model": { + "$ref": "AAAAAAF5QJnk3Rnk4S8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 581, + "top": 448, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnk3hnt7X0=", + "_parent": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "model": { + "$ref": "AAAAAAF5QJnk3Rnk4S8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 577, + "top": 489, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnk3hnuPbw=", + "_parent": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "model": { + "$ref": "AAAAAAF5QJnk3Rnlvxc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 716, + "top": 455, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnk3hnvOwA=", + "_parent": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "model": { + "$ref": "AAAAAAF5QJnk3Rnlvxc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 713, + "top": 442, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnk3hnwvuU=", + "_parent": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "model": { + "$ref": "AAAAAAF5QJnk3Rnlvxc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 721, + "top": 482, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QJnk3hnxCbA=", + "_parent": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "model": { + "$ref": "AAAAAAF5QJnk3Rnk4S8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 264, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QJnk3hny8xs=", + "_parent": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "model": { + "$ref": "AAAAAAF5QJnk3Rnlvxc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 264, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5P5/CAk98zZc=" + }, + "tail": { + "$ref": "AAAAAAF5QJjLZRML/gk=" + }, + "lineStyle": 1, + "points": "555:484;743:475", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QJnk3hnoFuM=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QJnk3hnpzsU=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QJnk3hnqowI=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QJnk3hnr2A8=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QJnk3hnsPz4=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QJnk3hnt7X0=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QJnk3hnuPbw=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QJnk3hnvOwA=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QJnk3hnwvuU=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QJnk3hnxCbA=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QJnk3hny8xs=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5QJ6ahiPXyXI=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QJ6ahSPVJNg=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5QJ6ahiPYzM0=", + "_parent": { + "$ref": "AAAAAAF5QJ6ahiPXyXI=" + }, + "model": { + "$ref": "AAAAAAF5QJ6ahSPVJNg=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5QJ6ahiPZdhA=", + "_parent": { + "$ref": "AAAAAAF5QJ6ahiPYzM0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 208, + "top": -896, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJ6ahiPa2BQ=", + "_parent": { + "$ref": "AAAAAAF5QJ6ahiPYzM0=" + }, + "font": "Arial;13;1", + "left": 795.5, + "top": 123.5, + "width": 96, + "height": 13, + "text": "checkReadData" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJ6ahyPb1CY=", + "_parent": { + "$ref": "AAAAAAF5QJ6ahiPYzM0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 208, + "top": -896, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJ6ahyPcSJM=", + "_parent": { + "$ref": "AAAAAAF5QJ6ahiPYzM0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 208, + "top": -896, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 790.5, + "top": 116.5, + "width": 106.8271484375, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5QJ6ahiPZdhA=" + }, + "nameLabel": { + "$ref": "AAAAAAF5QJ6ahiPa2BQ=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5QJ6ahyPb1CY=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QJ6ahyPcSJM=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5QJ6ahyPdwvQ=", + "_parent": { + "$ref": "AAAAAAF5QJ6ahiPXyXI=" + }, + "model": { + "$ref": "AAAAAAF5QJ6ahSPVJNg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 104, + "top": -448, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5QJ6ahyPeius=", + "_parent": { + "$ref": "AAAAAAF5QJ6ahiPXyXI=" + }, + "model": { + "$ref": "AAAAAAF5QJ6ahSPVJNg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 104, + "top": -448, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5QJ6ahyPfDuE=", + "_parent": { + "$ref": "AAAAAAF5QJ6ahiPXyXI=" + }, + "model": { + "$ref": "AAAAAAF5QJ6ahSPVJNg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 104, + "top": -448, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5QJ6ahyPgVJE=", + "_parent": { + "$ref": "AAAAAAF5QJ6ahiPXyXI=" + }, + "model": { + "$ref": "AAAAAAF5QJ6ahSPVJNg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 104, + "top": -448, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5QJ6ahyPhyOw=", + "_parent": { + "$ref": "AAAAAAF5QJ6ahiPXyXI=" + }, + "model": { + "$ref": "AAAAAAF5QJ6ahSPVJNg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 104, + "top": -448, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 768, + "top": 112, + "width": 151, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5QJ6ahiPYzM0=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5QJ6ahyPdwvQ=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5QJ6ahyPeius=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5QJ6ahyPfDuE=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5QJ6ahyPgVJE=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5QJ6ahyPhyOw=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5QJ8m8Sf6ofY=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QJ8m8Sf4R1w=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5QJ8m8Sf7JBU=", + "_parent": { + "$ref": "AAAAAAF5QJ8m8Sf6ofY=" + }, + "model": { + "$ref": "AAAAAAF5QJ8m8Sf4R1w=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5QJ8m8Sf8/hc=", + "_parent": { + "$ref": "AAAAAAF5QJ8m8Sf7JBU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1088, + "top": -1280, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJ8m8Sf9x9A=", + "_parent": { + "$ref": "AAAAAAF5QJ8m8Sf7JBU=" + }, + "font": "Arial;13;1", + "left": 1044, + "top": 107.5, + "width": 175, + "height": 13, + "text": "isHalfCycleZeroCheckReady" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJ8m8Sf+ddw=", + "_parent": { + "$ref": "AAAAAAF5QJ8m8Sf7JBU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1088, + "top": -1280, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJ8m8Sf/cbI=", + "_parent": { + "$ref": "AAAAAAF5QJ8m8Sf7JBU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1088, + "top": -1280, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 1039, + "top": 100.5, + "width": 186.2998046875, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5QJ8m8Sf8/hc=" + }, + "nameLabel": { + "$ref": "AAAAAAF5QJ8m8Sf9x9A=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5QJ8m8Sf+ddw=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QJ8m8Sf/cbI=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5QJ8m8SgAs+Y=", + "_parent": { + "$ref": "AAAAAAF5QJ8m8Sf6ofY=" + }, + "model": { + "$ref": "AAAAAAF5QJ8m8Sf4R1w=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 544, + "top": -640, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5QJ8m8SgBoKU=", + "_parent": { + "$ref": "AAAAAAF5QJ8m8Sf6ofY=" + }, + "model": { + "$ref": "AAAAAAF5QJ8m8Sf4R1w=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 544, + "top": -640, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5QJ8m8SgCMgY=", + "_parent": { + "$ref": "AAAAAAF5QJ8m8Sf6ofY=" + }, + "model": { + "$ref": "AAAAAAF5QJ8m8Sf4R1w=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 544, + "top": -640, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5QJ8m8SgDeic=", + "_parent": { + "$ref": "AAAAAAF5QJ8m8Sf6ofY=" + }, + "model": { + "$ref": "AAAAAAF5QJ8m8Sf4R1w=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 544, + "top": -640, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5QJ8m8SgEIBM=", + "_parent": { + "$ref": "AAAAAAF5QJ8m8Sf6ofY=" + }, + "model": { + "$ref": "AAAAAAF5QJ8m8Sf4R1w=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 544, + "top": -640, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 1000, + "top": 96, + "width": 263, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5QJ8m8Sf7JBU=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5QJ8m8SgAs+Y=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5QJ8m8SgBoKU=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5QJ8m8SgCMgY=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5QJ8m8SgDeic=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5QJ8m8SgEIBM=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QJ87PCkCJ2c=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QJ87Oyj+dCg=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ87PCkD2ew=", + "_parent": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "model": { + "$ref": "AAAAAAF5QJ87Oyj+dCg=" + }, + "font": "Arial;13;0", + "left": 903, + "top": 101, + "width": 111.22798156738281, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "edgePosition": 1, + "text": "+单测量or通过检测" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ87PCkEHYk=", + "_parent": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "model": { + "$ref": "AAAAAAF5QJ87Oyj+dCg=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 957, + "top": 86, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ87PCkFD0M=", + "_parent": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "model": { + "$ref": "AAAAAAF5QJ87Oyj+dCg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 959, + "top": 130, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ87PCkGBOM=", + "_parent": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "model": { + "$ref": "AAAAAAF5QJ87Oyj/TJQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 943, + "top": 102, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ87PCkHciQ=", + "_parent": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "model": { + "$ref": "AAAAAAF5QJ87Oyj/TJQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 945, + "top": 89, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ87PCkI53k=", + "_parent": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "model": { + "$ref": "AAAAAAF5QJ87Oyj/TJQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 941, + "top": 130, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ87PCkJ5DY=", + "_parent": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "model": { + "$ref": "AAAAAAF5QJ87OykA4RY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 972, + "top": 100, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ87PCkKd2s=", + "_parent": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "model": { + "$ref": "AAAAAAF5QJ87OykA4RY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 969, + "top": 87, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ87PCkLnCE=", + "_parent": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "model": { + "$ref": "AAAAAAF5QJ87OykA4RY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 978, + "top": 127, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QJ87PCkMizE=", + "_parent": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "model": { + "$ref": "AAAAAAF5QJ87Oyj/TJQ=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QJ87PCkNuH0=", + "_parent": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "model": { + "$ref": "AAAAAAF5QJ87OykA4RY=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QJ8m8Sf6ofY=" + }, + "tail": { + "$ref": "AAAAAAF5QJ6ahiPXyXI=" + }, + "lineStyle": 1, + "points": "919:125;999:120", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QJ87PCkD2ew=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QJ87PCkEHYk=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QJ87PCkFD0M=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QJ87PCkGBOM=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QJ87PCkHciQ=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QJ87PCkI53k=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QJ87PCkJ5DY=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QJ87PCkKd2s=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QJ87PCkLnCE=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QJ87PCkMizE=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QJ87PCkNuH0=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5QJ+mRitZ0H0=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QJ+mRitXafY=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5QJ+mRitad0o=", + "_parent": { + "$ref": "AAAAAAF5QJ+mRitZ0H0=" + }, + "model": { + "$ref": "AAAAAAF5QJ+mRitXafY=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5QJ+mRitbxtk=", + "_parent": { + "$ref": "AAAAAAF5QJ+mRitad0o=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 544, + "top": -784, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJ+mRytcRUc=", + "_parent": { + "$ref": "AAAAAAF5QJ+mRitad0o=" + }, + "fillColor": "#ff8282", + "font": "Arial;13;1", + "left": 591.5, + "top": 179.5, + "width": 77, + "height": 13, + "text": "提示读数有误" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJ+mRytdKoM=", + "_parent": { + "$ref": "AAAAAAF5QJ+mRitad0o=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 544, + "top": -784, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJ+mRytecXk=", + "_parent": { + "$ref": "AAAAAAF5QJ+mRitad0o=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 544, + "top": -784, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 586.5, + "top": 172.5, + "width": 88, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5QJ+mRitbxtk=" + }, + "nameLabel": { + "$ref": "AAAAAAF5QJ+mRytcRUc=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5QJ+mRytdKoM=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QJ+mRytecXk=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5QJ+mRytf9wc=", + "_parent": { + "$ref": "AAAAAAF5QJ+mRitZ0H0=" + }, + "model": { + "$ref": "AAAAAAF5QJ+mRitXafY=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 272, + "top": -392, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5QJ+mRytgl/8=", + "_parent": { + "$ref": "AAAAAAF5QJ+mRitZ0H0=" + }, + "model": { + "$ref": "AAAAAAF5QJ+mRitXafY=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 272, + "top": -392, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5QJ+mRythGBg=", + "_parent": { + "$ref": "AAAAAAF5QJ+mRitZ0H0=" + }, + "model": { + "$ref": "AAAAAAF5QJ+mRitXafY=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 272, + "top": -392, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5QJ+mRytiPDo=", + "_parent": { + "$ref": "AAAAAAF5QJ+mRitZ0H0=" + }, + "model": { + "$ref": "AAAAAAF5QJ+mRitXafY=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 272, + "top": -392, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5QJ+mRytjdZM=", + "_parent": { + "$ref": "AAAAAAF5QJ+mRitZ0H0=" + }, + "model": { + "$ref": "AAAAAAF5QJ+mRitXafY=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 272, + "top": -392, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ff8282", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 568, + "top": 168, + "width": 124, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5QJ+mRitad0o=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5QJ+mRytf9wc=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5QJ+mRytgl/8=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5QJ+mRythGBg=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5QJ+mRytiPDo=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5QJ+mRytjdZM=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QJ/UgywlH50=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QJ/Ugywh52g=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/Ugywm6Cw=", + "_parent": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "model": { + "$ref": "AAAAAAF5QJ/Ugywh52g=" + }, + "font": "Arial;13;0", + "left": 700, + "top": 166, + "width": 72.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "edgePosition": 1, + "text": "+未通过检测" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/UgywnNpM=", + "_parent": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "model": { + "$ref": "AAAAAAF5QJ/Ugywh52g=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 740, + "top": 180, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/UgywoaZM=", + "_parent": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "model": { + "$ref": "AAAAAAF5QJ/Ugywh52g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 729, + "top": 137, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/UhCwpjOU=", + "_parent": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "model": { + "$ref": "AAAAAAF5QJ/Ugywiha4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 752, + "top": 162, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/UhCwqyBI=", + "_parent": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "model": { + "$ref": "AAAAAAF5QJ/Ugywiha4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 754, + "top": 175, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/UhCwrLDA=", + "_parent": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "model": { + "$ref": "AAAAAAF5QJ/Ugywiha4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 749, + "top": 134, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/UhCws+Vw=", + "_parent": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "model": { + "$ref": "AAAAAAF5QJ/UgywjRPE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 720, + "top": 170, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/UhCwtL5c=", + "_parent": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "model": { + "$ref": "AAAAAAF5QJ/UgywjRPE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 726, + "top": 182, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/UhCwuYNo=", + "_parent": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "model": { + "$ref": "AAAAAAF5QJ/UgywjRPE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 709, + "top": 145, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QJ/UhCwvaPk=", + "_parent": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "model": { + "$ref": "AAAAAAF5QJ/Ugywiha4=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QJ/UhCwwUDY=", + "_parent": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "model": { + "$ref": "AAAAAAF5QJ/UgywjRPE=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QJ+mRitZ0H0=" + }, + "tail": { + "$ref": "AAAAAAF5QJ6ahiPXyXI=" + }, + "lineStyle": 1, + "points": "774:147;692:169", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QJ/Ugywm6Cw=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QJ/UgywnNpM=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QJ/UgywoaZM=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QJ/UhCwpjOU=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QJ/UhCwqyBI=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QJ/UhCwrLDA=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QJ/UhCws+Vw=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QJ/UhCwtL5c=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QJ/UhCwuYNo=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QJ/UhCwvaPk=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QJ/UhCwwUDY=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QJ/0PC0CShY=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QJ/0PCz+xYo=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/0PS0DtlQ=", + "_parent": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "model": { + "$ref": "AAAAAAF5QJ/0PCz+xYo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 551, + "top": 338, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/0PS0ETCk=", + "_parent": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "model": { + "$ref": "AAAAAAF5QJ/0PCz+xYo=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 564, + "top": 346, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/0PS0FS9M=", + "_parent": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "model": { + "$ref": "AAAAAAF5QJ/0PCz+xYo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 526, + "top": 323, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/0PS0G2RA=", + "_parent": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "model": { + "$ref": "AAAAAAF5QJ/0PCz/2CU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 617, + "top": 226, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/0PS0HEgs=", + "_parent": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "model": { + "$ref": "AAAAAAF5QJ/0PCz/2CU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 628, + "top": 235, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/0PS0IKu8=", + "_parent": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "model": { + "$ref": "AAAAAAF5QJ/0PCz/2CU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 596, + "top": 209, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/0PS0JtjU=", + "_parent": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "model": { + "$ref": "AAAAAAF5QJ/0PC0AjHo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 486, + "top": 450, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/0PS0KkBY=", + "_parent": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "model": { + "$ref": "AAAAAAF5QJ/0PC0AjHo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 498, + "top": 454, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/0PS0LEUU=", + "_parent": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "model": { + "$ref": "AAAAAAF5QJ/0PC0AjHo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 460, + "top": 440, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QJ/0PS0MAmo=", + "_parent": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "model": { + "$ref": "AAAAAAF5QJ/0PCz/2CU=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QJ/0PS0Nb0Y=", + "_parent": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "model": { + "$ref": "AAAAAAF5QJ/0PC0AjHo=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QJjLZRML/gk=" + }, + "tail": { + "$ref": "AAAAAAF5QJ+mRitZ0H0=" + }, + "lineStyle": 1, + "points": "618:203;460:471", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QJ/0PS0DtlQ=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QJ/0PS0ETCk=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QJ/0PS0FS9M=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QJ/0PS0G2RA=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QJ/0PS0HEgs=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QJ/0PS0IKu8=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QJ/0PS0JtjU=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QJ/0PS0KkBY=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QJ/0PS0LEUU=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QJ/0PS0MAmo=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QJ/0PS0Nb0Y=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5QKE6Ojfzjv0=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QKE6OTfx/D4=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5QKE6Ojf0W9Y=", + "_parent": { + "$ref": "AAAAAAF5QKE6Ojfzjv0=" + }, + "model": { + "$ref": "AAAAAAF5QKE6OTfx/D4=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5QKE6Ojf12Ns=", + "_parent": { + "$ref": "AAAAAAF5QKE6Ojf0W9Y=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1472, + "top": 352, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKE6Ojf2D5I=", + "_parent": { + "$ref": "AAAAAAF5QKE6Ojf0W9Y=" + }, + "font": "Arial;13;1", + "left": 1342, + "top": 1123.5, + "width": 110, + "height": 13, + "text": "checkSingleCycle" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKE6Ojf3N+g=", + "_parent": { + "$ref": "AAAAAAF5QKE6Ojf0W9Y=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1472, + "top": 352, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKE6Ojf4rrM=", + "_parent": { + "$ref": "AAAAAAF5QKE6Ojf0W9Y=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1472, + "top": 352, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 1337, + "top": 1116.5, + "width": 120.55712890625, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5QKE6Ojf12Ns=" + }, + "nameLabel": { + "$ref": "AAAAAAF5QKE6Ojf2D5I=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5QKE6Ojf3N+g=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QKE6Ojf4rrM=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5QKE6Ojf5X6A=", + "_parent": { + "$ref": "AAAAAAF5QKE6Ojfzjv0=" + }, + "model": { + "$ref": "AAAAAAF5QKE6OTfx/D4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 736, + "top": 176, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5QKE6Ojf6i5o=", + "_parent": { + "$ref": "AAAAAAF5QKE6Ojfzjv0=" + }, + "model": { + "$ref": "AAAAAAF5QKE6OTfx/D4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 736, + "top": 176, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5QKE6Ojf7hDo=", + "_parent": { + "$ref": "AAAAAAF5QKE6Ojfzjv0=" + }, + "model": { + "$ref": "AAAAAAF5QKE6OTfx/D4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 736, + "top": 176, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5QKE6Ojf8oq8=", + "_parent": { + "$ref": "AAAAAAF5QKE6Ojfzjv0=" + }, + "model": { + "$ref": "AAAAAAF5QKE6OTfx/D4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 736, + "top": 176, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5QKE6Ojf9edk=", + "_parent": { + "$ref": "AAAAAAF5QKE6Ojfzjv0=" + }, + "model": { + "$ref": "AAAAAAF5QKE6OTfx/D4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 736, + "top": 176, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 1312, + "top": 1112, + "width": 170, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5QKE6Ojf0W9Y=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5QKE6Ojf5X6A=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5QKE6Ojf6i5o=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5QKE6Ojf7hDo=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5QKE6Ojf8oq8=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5QKE6Ojf9edk=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5QKIG+T9Y4ko=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QKIG+T9Wjdo=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5QKIG+T9Zl2o=", + "_parent": { + "$ref": "AAAAAAF5QKIG+T9Y4ko=" + }, + "model": { + "$ref": "AAAAAAF5QKIG+T9Wjdo=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5QKIG+T9a7vU=", + "_parent": { + "$ref": "AAAAAAF5QKIG+T9Zl2o=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1408, + "top": 544, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKIG+T9bDug=", + "_parent": { + "$ref": "AAAAAAF5QKIG+T9Zl2o=" + }, + "font": "Arial;13;1", + "left": 1386, + "top": 1299.5, + "width": 129, + "height": 13, + "text": "isAllCycleCompleted" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKIG+T9cIfM=", + "_parent": { + "$ref": "AAAAAAF5QKIG+T9Zl2o=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1408, + "top": 544, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKIG+T9dArI=", + "_parent": { + "$ref": "AAAAAAF5QKIG+T9Zl2o=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1408, + "top": 544, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 1381, + "top": 1292.5, + "width": 139.314453125, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5QKIG+T9a7vU=" + }, + "nameLabel": { + "$ref": "AAAAAAF5QKIG+T9bDug=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5QKIG+T9cIfM=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QKIG+T9dArI=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5QKIG+T9e1Wk=", + "_parent": { + "$ref": "AAAAAAF5QKIG+T9Y4ko=" + }, + "model": { + "$ref": "AAAAAAF5QKIG+T9Wjdo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 704, + "top": 272, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5QKIG+T9fRvU=", + "_parent": { + "$ref": "AAAAAAF5QKIG+T9Y4ko=" + }, + "model": { + "$ref": "AAAAAAF5QKIG+T9Wjdo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 704, + "top": 272, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5QKIG+T9gBhM=", + "_parent": { + "$ref": "AAAAAAF5QKIG+T9Y4ko=" + }, + "model": { + "$ref": "AAAAAAF5QKIG+T9Wjdo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 704, + "top": 272, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5QKIG+T9hA48=", + "_parent": { + "$ref": "AAAAAAF5QKIG+T9Y4ko=" + }, + "model": { + "$ref": "AAAAAAF5QKIG+T9Wjdo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 704, + "top": 272, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5QKIG+T9inVI=", + "_parent": { + "$ref": "AAAAAAF5QKIG+T9Y4ko=" + }, + "model": { + "$ref": "AAAAAAF5QKIG+T9Wjdo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 704, + "top": 272, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 1352, + "top": 1288, + "width": 197, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5QKIG+T9Zl2o=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5QKIG+T9e1Wk=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5QKIG+T9fRvU=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5QKIG+T9gBhM=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5QKIG+T9hA48=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5QKIG+T9inVI=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QKI4zEKHpSc=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QKI4y0KDGow=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKI4zEKIQ1c=", + "_parent": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "model": { + "$ref": "AAAAAAF5QKI4y0KDGow=" + }, + "font": "Arial;13;0", + "left": 1408, + "top": 1206, + "width": 59.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "edgePosition": 1, + "text": "+通过检测" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKI4zEKJdn8=", + "_parent": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "model": { + "$ref": "AAAAAAF5QKI4y0KDGow=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1451, + "top": 1202, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKI4zEKKTG0=", + "_parent": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "model": { + "$ref": "AAAAAAF5QKI4y0KDGow=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1408, + "top": 1215, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKI4zEKL0+I=", + "_parent": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "model": { + "$ref": "AAAAAAF5QKI4zEKEuw8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1423, + "top": 1161, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKI4zEKMDrE=", + "_parent": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "model": { + "$ref": "AAAAAAF5QKI4zEKEuw8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1437, + "top": 1159, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKI4zEKNoT0=", + "_parent": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "model": { + "$ref": "AAAAAAF5QKI4zEKEuw8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1396, + "top": 1165, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKI4zEKOx2g=", + "_parent": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "model": { + "$ref": "AAAAAAF5QKI4zEKFtZg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1450, + "top": 1251, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKI4zEKP85E=", + "_parent": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "model": { + "$ref": "AAAAAAF5QKI4zEKFtZg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1462, + "top": 1245, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKI4zEKQLJU=", + "_parent": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "model": { + "$ref": "AAAAAAF5QKI4zEKFtZg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1425, + "top": 1263, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QKI4zEKR1Nc=", + "_parent": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "model": { + "$ref": "AAAAAAF5QKI4zEKEuw8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 264, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QKI4zEKSZgo=", + "_parent": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "model": { + "$ref": "AAAAAAF5QKI4zEKFtZg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 264, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QKIG+T9Y4ko=" + }, + "tail": { + "$ref": "AAAAAAF5QKE6Ojfzjv0=" + }, + "lineStyle": 1, + "points": "1402:1147;1444:1287", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QKI4zEKIQ1c=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QKI4zEKJdn8=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QKI4zEKKTG0=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QKI4zEKL0+I=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QKI4zEKMDrE=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QKI4zEKNoT0=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QKI4zEKOx2g=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QKI4zEKP85E=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QKI4zEKQLJU=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QKI4zEKR1Nc=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QKI4zEKSZgo=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5QKuCwkzY630=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5QKuCwkzZLtk=", + "_parent": { + "$ref": "AAAAAAF5QKuCwkzY630=" + }, + "model": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5QKuCwkzadw4=", + "_parent": { + "$ref": "AAAAAAF5QKuCwkzZLtk=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 1872, + "top": 48, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKuCwkzbRGU=", + "_parent": { + "$ref": "AAAAAAF5QKuCwkzZLtk=" + }, + "fillColor": "#ff8282", + "font": "Arial;13;1", + "left": 1463.5, + "top": 963.5, + "width": 77, + "height": 13, + "text": "提示用户选择" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKuCwkzc5kQ=", + "_parent": { + "$ref": "AAAAAAF5QKuCwkzZLtk=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 1872, + "top": 48, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKuCwkzd3VI=", + "_parent": { + "$ref": "AAAAAAF5QKuCwkzZLtk=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 1872, + "top": 48, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 1458.5, + "top": 956.5, + "width": 88, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5QKuCwkzadw4=" + }, + "nameLabel": { + "$ref": "AAAAAAF5QKuCwkzbRGU=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5QKuCwkzc5kQ=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QKuCwkzd3VI=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5QKuCw0zeMMo=", + "_parent": { + "$ref": "AAAAAAF5QKuCwkzY630=" + }, + "model": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 936, + "top": 24, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5QKuCw0zfhJM=", + "_parent": { + "$ref": "AAAAAAF5QKuCwkzY630=" + }, + "model": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 936, + "top": 24, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5QKuCw0zgO20=", + "_parent": { + "$ref": "AAAAAAF5QKuCwkzY630=" + }, + "model": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 936, + "top": 24, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5QKuCw0zhG3k=", + "_parent": { + "$ref": "AAAAAAF5QKuCwkzY630=" + }, + "model": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 936, + "top": 24, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5QKuCw0ziN7I=", + "_parent": { + "$ref": "AAAAAAF5QKuCwkzY630=" + }, + "model": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 936, + "top": 24, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ff8282", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 1440, + "top": 952, + "width": 124, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5QKuCwkzZLtk=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5QKuCw0zeMMo=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5QKuCw0zfhJM=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5QKuCw0zgO20=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5QKuCw0zhG3k=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5QKuCw0ziN7I=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QKvMIE8ZF/E=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QKvMIE8VEZE=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKvMIU8a1To=", + "_parent": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "model": { + "$ref": "AAAAAAF5QKvMIE8VEZE=" + }, + "font": "Arial;13;0", + "left": 1399, + "top": 1034, + "width": 72.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "edgePosition": 1, + "text": "+未通过检测" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKvMIU8bx7Y=", + "_parent": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "model": { + "$ref": "AAAAAAF5QKvMIE8VEZE=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1422, + "top": 1026, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKvMIU8c/MU=", + "_parent": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "model": { + "$ref": "AAAAAAF5QKvMIE8VEZE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1460, + "top": 1051, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKvMIU8df1Y=", + "_parent": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "model": { + "$ref": "AAAAAAF5QKvMIE8WKCE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1409, + "top": 1075, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKvMIU8e89E=", + "_parent": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "model": { + "$ref": "AAAAAAF5QKvMIE8WKCE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1399, + "top": 1065, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKvMIU8frKE=", + "_parent": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "model": { + "$ref": "AAAAAAF5QKvMIE8WKCE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1430, + "top": 1093, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKvMIU8gpg0=", + "_parent": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "model": { + "$ref": "AAAAAAF5QKvMIE8XsG8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1462, + "top": 994, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKvMIU8hUUs=", + "_parent": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "model": { + "$ref": "AAAAAAF5QKvMIE8XsG8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1449, + "top": 989, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKvMIU8iPfY=", + "_parent": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "model": { + "$ref": "AAAAAAF5QKvMIE8XsG8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1487, + "top": 1005, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QKvMIU8jJRc=", + "_parent": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "model": { + "$ref": "AAAAAAF5QKvMIE8WKCE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 264, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QKvMIU8kteI=", + "_parent": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "model": { + "$ref": "AAAAAAF5QKvMIE8XsG8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 264, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QKuCwkzY630=" + }, + "tail": { + "$ref": "AAAAAAF5QKE6Ojfzjv0=" + }, + "lineStyle": 1, + "points": "1408:1111;1489:987", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QKvMIU8a1To=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QKvMIU8bx7Y=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QKvMIU8c/MU=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QKvMIU8df1Y=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QKvMIU8e89E=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QKvMIU8frKE=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QKvMIU8gpg0=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QKvMIU8hUUs=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QKvMIU8iPfY=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QKvMIU8jJRc=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QKvMIU8kteI=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5QKyR6VB+5F0=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QKyR6VB8Gq8=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5QKyR6VB/sq8=", + "_parent": { + "$ref": "AAAAAAF5QKyR6VB+5F0=" + }, + "model": { + "$ref": "AAAAAAF5QKyR6VB8Gq8=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5QKyR6lCAlIw=", + "_parent": { + "$ref": "AAAAAAF5QKyR6VB/sq8=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 320, + "top": -272, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKyR6lCBFDc=", + "_parent": { + "$ref": "AAAAAAF5QKyR6VB/sq8=" + }, + "fillColor": "#ff8282", + "font": "Arial;13;1", + "left": 956, + "top": 731.5, + "width": 62, + "height": 13, + "text": "重测方向" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKyR6lCC81I=", + "_parent": { + "$ref": "AAAAAAF5QKyR6VB/sq8=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 320, + "top": -272, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKyR6lCDFwk=", + "_parent": { + "$ref": "AAAAAAF5QKyR6VB/sq8=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 320, + "top": -272, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 951, + "top": 724.5, + "width": 72, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5QKyR6lCAlIw=" + }, + "nameLabel": { + "$ref": "AAAAAAF5QKyR6lCBFDc=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5QKyR6lCC81I=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QKyR6lCDFwk=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5QKyR6lCEof0=", + "_parent": { + "$ref": "AAAAAAF5QKyR6VB+5F0=" + }, + "model": { + "$ref": "AAAAAAF5QKyR6VB8Gq8=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 160, + "top": -136, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5QKyR6lCFl5A=", + "_parent": { + "$ref": "AAAAAAF5QKyR6VB+5F0=" + }, + "model": { + "$ref": "AAAAAAF5QKyR6VB8Gq8=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 160, + "top": -136, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5QKyR6lCGLz0=", + "_parent": { + "$ref": "AAAAAAF5QKyR6VB+5F0=" + }, + "model": { + "$ref": "AAAAAAF5QKyR6VB8Gq8=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 160, + "top": -136, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5QKyR6lCHKbg=", + "_parent": { + "$ref": "AAAAAAF5QKyR6VB+5F0=" + }, + "model": { + "$ref": "AAAAAAF5QKyR6VB8Gq8=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 160, + "top": -136, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5QKyR6lCIqJE=", + "_parent": { + "$ref": "AAAAAAF5QKyR6VB+5F0=" + }, + "model": { + "$ref": "AAAAAAF5QKyR6VB8Gq8=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 160, + "top": -136, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ff8282", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 936, + "top": 720, + "width": 102, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5QKyR6VB/sq8=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5QKyR6lCEof0=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5QKyR6lCFl5A=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5QKyR6lCGLz0=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5QKyR6lCHKbg=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5QKyR6lCIqJE=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5QKysH1F4naw=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QKysH1F2Xh8=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5QKysH1F5Vw8=", + "_parent": { + "$ref": "AAAAAAF5QKysH1F4naw=" + }, + "model": { + "$ref": "AAAAAAF5QKysH1F2Xh8=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5QKysH1F6t1U=", + "_parent": { + "$ref": "AAAAAAF5QKysH1F5Vw8=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 672, + "top": -512, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKysH1F7w44=", + "_parent": { + "$ref": "AAAAAAF5QKysH1F5Vw8=" + }, + "fillColor": "#ffadad", + "font": "Arial;13;1", + "left": 1172, + "top": 675.5, + "width": 62, + "height": 13, + "text": "重测测回" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKysH1F8ews=", + "_parent": { + "$ref": "AAAAAAF5QKysH1F5Vw8=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 672, + "top": -512, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKysH1F9CVk=", + "_parent": { + "$ref": "AAAAAAF5QKysH1F5Vw8=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 672, + "top": -512, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 1167, + "top": 668.5, + "width": 72, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5QKysH1F6t1U=" + }, + "nameLabel": { + "$ref": "AAAAAAF5QKysH1F7w44=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5QKysH1F8ews=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QKysH1F9CVk=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5QKysH1F+SbI=", + "_parent": { + "$ref": "AAAAAAF5QKysH1F4naw=" + }, + "model": { + "$ref": "AAAAAAF5QKysH1F2Xh8=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 336, + "top": -256, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5QKysH1F/p8w=", + "_parent": { + "$ref": "AAAAAAF5QKysH1F4naw=" + }, + "model": { + "$ref": "AAAAAAF5QKysH1F2Xh8=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 336, + "top": -256, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5QKysH1GAwRg=", + "_parent": { + "$ref": "AAAAAAF5QKysH1F4naw=" + }, + "model": { + "$ref": "AAAAAAF5QKysH1F2Xh8=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 336, + "top": -256, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5QKysH1GBWy4=", + "_parent": { + "$ref": "AAAAAAF5QKysH1F4naw=" + }, + "model": { + "$ref": "AAAAAAF5QKysH1F2Xh8=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 336, + "top": -256, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5QKysH1GC8OE=", + "_parent": { + "$ref": "AAAAAAF5QKysH1F4naw=" + }, + "model": { + "$ref": "AAAAAAF5QKysH1F2Xh8=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 336, + "top": -256, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ffadad", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 1152, + "top": 664, + "width": 102, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5QKysH1F5Vw8=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5QKysH1F+SbI=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5QKysH1F/p8w=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5QKysH1GAwRg=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5QKysH1GBWy4=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5QKysH1GC8OE=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5QKzDRVJysxE=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QKzDRVJwpI4=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5QKzDRVJztrc=", + "_parent": { + "$ref": "AAAAAAF5QKzDRVJysxE=" + }, + "model": { + "$ref": "AAAAAAF5QKzDRVJwpI4=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5QKzDRVJ0nsk=", + "_parent": { + "$ref": "AAAAAAF5QKzDRVJztrc=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 752, + "top": -1088, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKzDRVJ1z+Q=", + "_parent": { + "$ref": "AAAAAAF5QKzDRVJztrc=" + }, + "fillColor": "#8282ff", + "font": "Arial;13;1", + "left": 1238.5, + "top": 443.5, + "width": 226, + "height": 13, + "text": "resetSurveyorStateAndKeepPosition" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKzDRVJ29Q0=", + "_parent": { + "$ref": "AAAAAAF5QKzDRVJztrc=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 752, + "top": -1088, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKzDRVJ3D90=", + "_parent": { + "$ref": "AAAAAAF5QKzDRVJztrc=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 752, + "top": -1088, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 1233.5, + "top": 436.5, + "width": 237.5634765625, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5QKzDRVJ0nsk=" + }, + "nameLabel": { + "$ref": "AAAAAAF5QKzDRVJ1z+Q=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5QKzDRVJ29Q0=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QKzDRVJ3D90=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5QKzDRVJ4vK0=", + "_parent": { + "$ref": "AAAAAAF5QKzDRVJysxE=" + }, + "model": { + "$ref": "AAAAAAF5QKzDRVJwpI4=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 376, + "top": -544, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5QKzDRVJ5ijM=", + "_parent": { + "$ref": "AAAAAAF5QKzDRVJysxE=" + }, + "model": { + "$ref": "AAAAAAF5QKzDRVJwpI4=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 376, + "top": -544, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5QKzDRVJ6ScY=", + "_parent": { + "$ref": "AAAAAAF5QKzDRVJysxE=" + }, + "model": { + "$ref": "AAAAAAF5QKzDRVJwpI4=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 376, + "top": -544, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5QKzDRVJ71p4=", + "_parent": { + "$ref": "AAAAAAF5QKzDRVJysxE=" + }, + "model": { + "$ref": "AAAAAAF5QKzDRVJwpI4=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 376, + "top": -544, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5QKzDRVJ8l2g=", + "_parent": { + "$ref": "AAAAAAF5QKzDRVJysxE=" + }, + "model": { + "$ref": "AAAAAAF5QKzDRVJwpI4=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 376, + "top": -544, + "width": 10, + "height": 10 + } + ], + "fillColor": "#8282ff", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 1184, + "top": 432, + "width": 335, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5QKzDRVJztrc=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5QKzDRVJ4vK0=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5QKzDRVJ5ijM=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5QKzDRVJ6ScY=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5QKzDRVJ71p4=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5QKzDRVJ8l2g=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QK2QmFlvdS8=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QK2Ql1lrW/0=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK2QmFlwJfE=", + "_parent": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "model": { + "$ref": "AAAAAAF5QK2Ql1lrW/0=" + }, + "font": "Arial;13;0", + "left": 1395, + "top": 707, + "width": 33.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "edgePosition": 1, + "text": "+忽略" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK2QmFlxSkY=", + "_parent": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "model": { + "$ref": "AAAAAAF5QK2Ql1lrW/0=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1397, + "top": 711, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK2QmFly6tM=", + "_parent": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "model": { + "$ref": "AAAAAAF5QK2Ql1lrW/0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1440, + "top": 698, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK2QmFlzr3g=", + "_parent": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "model": { + "$ref": "AAAAAAF5QK2Ql1lsCzU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1474, + "top": 924, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK2QmFl0RxM=", + "_parent": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "model": { + "$ref": "AAAAAAF5QK2Ql1lsCzU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1460, + "top": 925, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK2QmFl1X3o=", + "_parent": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "model": { + "$ref": "AAAAAAF5QK2Ql1lsCzU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1501, + "top": 920, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK2QmFl29pE=", + "_parent": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "model": { + "$ref": "AAAAAAF5QK2Ql1ltUBY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1348, + "top": 490, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK2QmFl39y0=", + "_parent": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "model": { + "$ref": "AAAAAAF5QK2Ql1ltUBY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1336, + "top": 496, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK2QmFl4Ns0=", + "_parent": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "model": { + "$ref": "AAAAAAF5QK2Ql1ltUBY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1374, + "top": 478, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QK2QmFl5muU=", + "_parent": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "model": { + "$ref": "AAAAAAF5QK2Ql1lsCzU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 480, + "top": -8, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QK2QmFl6Y7A=", + "_parent": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "model": { + "$ref": "AAAAAAF5QK2Ql1ltUBY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 480, + "top": -8, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QKzDRVJysxE=" + }, + "tail": { + "$ref": "AAAAAAF5QKuCwkzY630=" + }, + "lineStyle": 1, + "points": "1496:951;1356:467", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QK2QmFlwJfE=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QK2QmFlxSkY=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QK2QmFly6tM=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QK2QmFlzr3g=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QK2QmFl0RxM=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QK2QmFl1X3o=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QK2QmFl29pE=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QK2QmFl39y0=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QK2QmFl4Ns0=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QK2QmFl5muU=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QK2QmFl6Y7A=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QK340l0Fv9Q=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QK340l0BzRk=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK340l0GnqQ=", + "_parent": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "model": { + "$ref": "AAAAAAF5QK340l0BzRk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1014, + "top": 471, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK340l0Habc=", + "_parent": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "model": { + "$ref": "AAAAAAF5QK340l0BzRk=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1015, + "top": 486, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK340l0IZgE=", + "_parent": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "model": { + "$ref": "AAAAAAF5QK340l0BzRk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1013, + "top": 442, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK340l0Jr30=", + "_parent": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "model": { + "$ref": "AAAAAAF5QK340l0ChAw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1157, + "top": 466, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK340l0KziQ=", + "_parent": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "model": { + "$ref": "AAAAAAF5QK340l0ChAw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1156, + "top": 479, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK340l0LSAI=", + "_parent": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "model": { + "$ref": "AAAAAAF5QK340l0ChAw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1160, + "top": 438, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK340l0MEF0=", + "_parent": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "model": { + "$ref": "AAAAAAF5QK340l0D79M=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 872, + "top": 478, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK340l0NAX0=", + "_parent": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "model": { + "$ref": "AAAAAAF5QK340l0D79M=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 875, + "top": 491, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK340l0Obj8=", + "_parent": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "model": { + "$ref": "AAAAAAF5QK340l0D79M=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 867, + "top": 451, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QK340l0PZLk=", + "_parent": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "model": { + "$ref": "AAAAAAF5QK340l0ChAw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 480, + "top": -8, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QK340l0QvTM=", + "_parent": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "model": { + "$ref": "AAAAAAF5QK340l0D79M=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 480, + "top": -8, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5P5/CAk98zZc=" + }, + "tail": { + "$ref": "AAAAAAF5QKzDRVJysxE=" + }, + "lineStyle": 1, + "points": "1183:456;846:471", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QK340l0GnqQ=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QK340l0Habc=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QK340l0IZgE=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QK340l0Jr30=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QK340l0KziQ=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QK340l0LSAI=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QK340l0MEF0=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QK340l0NAX0=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QK340l0Obj8=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QK340l0PZLk=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QK340l0QvTM=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QLdiXGHqtMU=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QLdiW2HmZcI=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLdiXGHrPm0=", + "_parent": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "model": { + "$ref": "AAAAAAF5QLdiW2HmZcI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1236, + "top": 860, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLdiXGHsNrs=", + "_parent": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "model": { + "$ref": "AAAAAAF5QLdiW2HmZcI=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1230, + "top": 874, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLdiXGHtajM=", + "_parent": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "model": { + "$ref": "AAAAAAF5QLdiW2HmZcI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1249, + "top": 833, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLdiXGHu5Ak=", + "_parent": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "model": { + "$ref": "AAAAAAF5QLdiW2HnzLc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1431, + "top": 948, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLdiXGHvESE=", + "_parent": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "model": { + "$ref": "AAAAAAF5QLdiW2HnzLc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1423, + "top": 959, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLdiXGHwu2c=", + "_parent": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "model": { + "$ref": "AAAAAAF5QLdiW2HnzLc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1446, + "top": 924, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLdiXGHxgP0=", + "_parent": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "model": { + "$ref": "AAAAAAF5QLdiW2HodP8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1043, + "top": 773, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLdiXGHyZg0=", + "_parent": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "model": { + "$ref": "AAAAAAF5QLdiW2HodP8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1040, + "top": 786, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLdiXGHzjfw=", + "_parent": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "model": { + "$ref": "AAAAAAF5QLdiW2HodP8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1050, + "top": 746, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QLdiXGH0aoo=", + "_parent": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "model": { + "$ref": "AAAAAAF5QLdiW2HnzLc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 528, + "top": -72, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QLdiXGH1FM8=", + "_parent": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "model": { + "$ref": "AAAAAAF5QLdiW2HodP8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 528, + "top": -72, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QKyR6VB+5F0=" + }, + "tail": { + "$ref": "AAAAAAF5QKuCwkzY630=" + }, + "lineStyle": 1, + "points": "1461:951;1026:755", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QLdiXGHrPm0=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QLdiXGHsNrs=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QLdiXGHtajM=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QLdiXGHu5Ak=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QLdiXGHvESE=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QLdiXGHwu2c=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QLdiXGHxgP0=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QLdiXGHyZg0=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QLdiXGHzjfw=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QLdiXGH0aoo=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QLdiXGH1FM8=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5QLwOJ2bPDnI=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QLwOJ2bN7N0=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5QLwOJ2bQ8Ro=", + "_parent": { + "$ref": "AAAAAAF5QLwOJ2bPDnI=" + }, + "model": { + "$ref": "AAAAAAF5QLwOJ2bN7N0=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5QLwOJ2bRPfA=", + "_parent": { + "$ref": "AAAAAAF5QLwOJ2bQ8Ro=" + }, + "visible": false, + "fillColor": "#5656ff", + "font": "Arial;13;0", + "left": 560, + "top": -528, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QLwOJ2bSTVM=", + "_parent": { + "$ref": "AAAAAAF5QLwOJ2bQ8Ro=" + }, + "fillColor": "#5656ff", + "font": "Arial;13;1", + "left": 1090.5, + "top": 587.5, + "width": 93, + "height": 13, + "text": "resurveyPoints" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QLwOJ2bTKUY=", + "_parent": { + "$ref": "AAAAAAF5QLwOJ2bQ8Ro=" + }, + "visible": false, + "fillColor": "#5656ff", + "font": "Arial;13;0", + "left": 560, + "top": -528, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QLwOJ2bUBI4=", + "_parent": { + "$ref": "AAAAAAF5QLwOJ2bQ8Ro=" + }, + "visible": false, + "fillColor": "#5656ff", + "font": "Arial;13;0", + "left": 560, + "top": -528, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#5656ff", + "font": "Arial;13;0", + "left": 1085.5, + "top": 580.5, + "width": 103.9326171875, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5QLwOJ2bRPfA=" + }, + "nameLabel": { + "$ref": "AAAAAAF5QLwOJ2bSTVM=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5QLwOJ2bTKUY=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QLwOJ2bUBI4=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5QLwOJ2bVEa0=", + "_parent": { + "$ref": "AAAAAAF5QLwOJ2bPDnI=" + }, + "model": { + "$ref": "AAAAAAF5QLwOJ2bN7N0=" + }, + "visible": false, + "fillColor": "#5656ff", + "font": "Arial;13;0", + "left": 280, + "top": -264, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5QLwOJ2bWae0=", + "_parent": { + "$ref": "AAAAAAF5QLwOJ2bPDnI=" + }, + "model": { + "$ref": "AAAAAAF5QLwOJ2bN7N0=" + }, + "visible": false, + "fillColor": "#5656ff", + "font": "Arial;13;0", + "left": 280, + "top": -264, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5QLwOJ2bXEAg=", + "_parent": { + "$ref": "AAAAAAF5QLwOJ2bPDnI=" + }, + "model": { + "$ref": "AAAAAAF5QLwOJ2bN7N0=" + }, + "visible": false, + "fillColor": "#5656ff", + "font": "Arial;13;0", + "left": 280, + "top": -264, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5QLwOKGbYe7A=", + "_parent": { + "$ref": "AAAAAAF5QLwOJ2bPDnI=" + }, + "model": { + "$ref": "AAAAAAF5QLwOJ2bN7N0=" + }, + "visible": false, + "fillColor": "#5656ff", + "font": "Arial;13;0", + "left": 280, + "top": -264, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5QLwOKGbZQqo=", + "_parent": { + "$ref": "AAAAAAF5QLwOJ2bPDnI=" + }, + "model": { + "$ref": "AAAAAAF5QLwOJ2bN7N0=" + }, + "visible": false, + "fillColor": "#5656ff", + "font": "Arial;13;0", + "left": 280, + "top": -264, + "width": 10, + "height": 10 + } + ], + "fillColor": "#5656ff", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 1064, + "top": 576, + "width": 146, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5QLwOJ2bQ8Ro=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5QLwOJ2bVEa0=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5QLwOJ2bWae0=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5QLwOJ2bXEAg=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5QLwOKGbYe7A=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5QLwOKGbZQqo=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QLx6RGoNnGE=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QLx6RGoJ91g=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLx6RGoOcBM=", + "_parent": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "model": { + "$ref": "AAAAAAF5QLx6RGoJ91g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1050, + "top": 648, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLx6RGoPkXM=", + "_parent": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "model": { + "$ref": "AAAAAAF5QLx6RGoJ91g=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1040, + "top": 637, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLx6RGoQUT8=", + "_parent": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "model": { + "$ref": "AAAAAAF5QLx6RGoJ91g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1071, + "top": 669, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLx6RGoRB9A=", + "_parent": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "model": { + "$ref": "AAAAAAF5QLx6RGoKxZI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1013, + "top": 684, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLx6RGoSk+A=", + "_parent": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "model": { + "$ref": "AAAAAAF5QLx6RGoKxZI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1005, + "top": 673, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLx6RGoT8Lo=", + "_parent": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "model": { + "$ref": "AAAAAAF5QLx6RGoKxZI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1029, + "top": 706, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLx6RGoUHro=", + "_parent": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "model": { + "$ref": "AAAAAAF5QLx6RGoLs1U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1087, + "top": 612, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLx6RGoVk68=", + "_parent": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "model": { + "$ref": "AAAAAAF5QLx6RGoLs1U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1077, + "top": 604, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLx6RGoW9No=", + "_parent": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "model": { + "$ref": "AAAAAAF5QLx6RGoLs1U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1110, + "top": 629, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QLx6RGoXj7U=", + "_parent": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "model": { + "$ref": "AAAAAAF5QLx6RGoKxZI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 480, + "top": -8, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QLx6RGoYmUk=", + "_parent": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "model": { + "$ref": "AAAAAAF5QLx6RGoLs1U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 480, + "top": -8, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QLwOJ2bPDnI=" + }, + "tail": { + "$ref": "AAAAAAF5QKyR6VB+5F0=" + }, + "lineStyle": 1, + "points": "1005:719;1117:611", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QLx6RGoOcBM=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QLx6RGoPkXM=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QLx6RGoQUT8=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QLx6RGoRB9A=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QLx6RGoSk+A=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QLx6RGoT8Lo=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QLx6RGoUHro=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QLx6RGoVk68=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QLx6RGoW9No=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QLx6RGoXj7U=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QLx6RGoYmUk=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5QMaQUG/rlG8=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QMaQUG/pf+g=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5QMaQUG/sv3A=", + "_parent": { + "$ref": "AAAAAAF5QMaQUG/rlG8=" + }, + "model": { + "$ref": "AAAAAAF5QMaQUG/pf+g=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5QMaQUG/tkJ4=", + "_parent": { + "$ref": "AAAAAAF5QMaQUG/sv3A=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": -448, + "top": -256, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QMaQUG/umGY=", + "_parent": { + "$ref": "AAAAAAF5QMaQUG/sv3A=" + }, + "fillColor": "#8282ff", + "font": "Arial;13;1", + "left": 612.5, + "top": 579.5, + "width": 216, + "height": 13, + "text": "switchState2RestartInCurrentCycle" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QMaQUW/vdlU=", + "_parent": { + "$ref": "AAAAAAF5QMaQUG/sv3A=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": -448, + "top": -256, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QMaQUW/w0wQ=", + "_parent": { + "$ref": "AAAAAAF5QMaQUG/sv3A=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": -448, + "top": -256, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 607.5, + "top": 572.5, + "width": 227.4580078125, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5QMaQUG/tkJ4=" + }, + "nameLabel": { + "$ref": "AAAAAAF5QMaQUG/umGY=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5QMaQUW/vdlU=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QMaQUW/w0wQ=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5QMaQUW/x48o=", + "_parent": { + "$ref": "AAAAAAF5QMaQUG/rlG8=" + }, + "model": { + "$ref": "AAAAAAF5QMaQUG/pf+g=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": -224, + "top": -128, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5QMaQUW/yJ84=", + "_parent": { + "$ref": "AAAAAAF5QMaQUG/rlG8=" + }, + "model": { + "$ref": "AAAAAAF5QMaQUG/pf+g=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": -224, + "top": -128, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5QMaQUW/z4XE=", + "_parent": { + "$ref": "AAAAAAF5QMaQUG/rlG8=" + }, + "model": { + "$ref": "AAAAAAF5QMaQUG/pf+g=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": -224, + "top": -128, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5QMaQUW/0u+w=", + "_parent": { + "$ref": "AAAAAAF5QMaQUG/rlG8=" + }, + "model": { + "$ref": "AAAAAAF5QMaQUG/pf+g=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": -224, + "top": -128, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5QMaQUW/13YU=", + "_parent": { + "$ref": "AAAAAAF5QMaQUG/rlG8=" + }, + "model": { + "$ref": "AAAAAAF5QMaQUG/pf+g=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": -224, + "top": -128, + "width": 10, + "height": 10 + } + ], + "fillColor": "#8282ff", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 560, + "top": 568, + "width": 321, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5QMaQUG/sv3A=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5QMaQUW/x48o=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5QMaQUW/yJ84=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5QMaQUW/z4XE=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5QMaQUW/0u+w=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5QMaQUW/13YU=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QMbzEXNQ00I=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QMbzEHNMUo0=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMbzEXNR/aw=", + "_parent": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "model": { + "$ref": "AAAAAAF5QMbzEHNMUo0=" + }, + "font": "Arial;13;0", + "left": 942, + "top": 598, + "width": 59.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "edgePosition": 1, + "text": "+开始重测" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMbzEXNSJUg=", + "_parent": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "model": { + "$ref": "AAAAAAF5QMbzEHNMUo0=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 971, + "top": 613, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMbzEXNTTKw=", + "_parent": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "model": { + "$ref": "AAAAAAF5QMbzEHNMUo0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 972, + "top": 569, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMbzEXNUT2s=", + "_parent": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "model": { + "$ref": "AAAAAAF5QMbzEHNNh8o=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1036, + "top": 600, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMbzEXNVmq4=", + "_parent": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "model": { + "$ref": "AAAAAAF5QMbzEHNNh8o=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1034, + "top": 613, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMbzEXNWUrs=", + "_parent": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "model": { + "$ref": "AAAAAAF5QMbzEHNNh8o=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1041, + "top": 573, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMbzEXNX73U=", + "_parent": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "model": { + "$ref": "AAAAAAF5QMbzEHNOm6M=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 906, + "top": 597, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMbzEXNYoLo=", + "_parent": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "model": { + "$ref": "AAAAAAF5QMbzEHNOm6M=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 908, + "top": 610, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMbzEXNZwIQ=", + "_parent": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "model": { + "$ref": "AAAAAAF5QMbzEHNOm6M=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 902, + "top": 569, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QMbzEXNaGMo=", + "_parent": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "model": { + "$ref": "AAAAAAF5QMbzEHNNh8o=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 480, + "top": -8, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QMbzEXNbVPI=", + "_parent": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "model": { + "$ref": "AAAAAAF5QMbzEHNOm6M=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 480, + "top": -8, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QMaQUG/rlG8=" + }, + "tail": { + "$ref": "AAAAAAF5QLwOJ2bPDnI=" + }, + "lineStyle": 1, + "points": "1063:592;881:588", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QMbzEXNR/aw=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QMbzEXNSJUg=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QMbzEXNTTKw=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QMbzEXNUT2s=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QMbzEXNVmq4=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QMbzEXNWUrs=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QMbzEXNX73U=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QMbzEXNYoLo=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QMbzEXNZwIQ=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QMbzEXNaGMo=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QMbzEXNbVPI=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QMjEp4Xxm70=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QMjEpoXtFac=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMjEp4XyXqY=", + "_parent": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "model": { + "$ref": "AAAAAAF5QMjEpoXtFac=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 973, + "top": 991, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMjEp4XzTSE=", + "_parent": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "model": { + "$ref": "AAAAAAF5QMjEpoXtFac=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 986, + "top": 984, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMjEp4X0hBs=", + "_parent": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "model": { + "$ref": "AAAAAAF5QMjEpoXtFac=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 948, + "top": 1006, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMjEp4X1sYc=", + "_parent": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "model": { + "$ref": "AAAAAAF5QMjEpoXuicM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 755, + "top": 612, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMjEp4X2bX4=", + "_parent": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "model": { + "$ref": "AAAAAAF5QMjEpoXuicM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 768, + "top": 607, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMjEp4X3ebc=", + "_parent": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "model": { + "$ref": "AAAAAAF5QMjEpoXuicM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 729, + "top": 621, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMjEp4X4oDY=", + "_parent": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "model": { + "$ref": "AAAAAAF5QMjEpoXvKNs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1193, + "top": 1371, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMjEp4X5UnY=", + "_parent": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "model": { + "$ref": "AAAAAAF5QMjEpoXvKNs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1203, + "top": 1362, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMjEp4X6pQM=", + "_parent": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "model": { + "$ref": "AAAAAAF5QMjEpoXvKNs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1171, + "top": 1388, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QMjEqIX7oU8=", + "_parent": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "model": { + "$ref": "AAAAAAF5QMjEpoXuicM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 480, + "top": -8, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QMjEqIX8oCk=", + "_parent": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "model": { + "$ref": "AAAAAAF5QMjEpoXvKNs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 480, + "top": -8, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QJWvCwgzk0M=" + }, + "tail": { + "$ref": "AAAAAAF5QMaQUG/rlG8=" + }, + "lineStyle": 1, + "points": "730:603;1193:1407", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QMjEp4XyXqY=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QMjEp4XzTSE=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QMjEp4X0hBs=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QMjEp4X1sYc=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QMjEp4X2bX4=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QMjEp4X3ebc=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QMjEp4X4oDY=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QMjEp4X5UnY=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QMjEp4X6pQM=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QMjEqIX7oU8=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QMjEqIX8oCk=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QMnaf4p31wI=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QMnaf4pzXpA=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMnaf4p4YhA=", + "_parent": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "model": { + "$ref": "AAAAAAF5QMnaf4pzXpA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1340, + "top": 829, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMnaf4p5heM=", + "_parent": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "model": { + "$ref": "AAAAAAF5QMnaf4pzXpA=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1330, + "top": 840, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMnaf4p6u/E=", + "_parent": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "model": { + "$ref": "AAAAAAF5QMnaf4pzXpA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1361, + "top": 808, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMnaf4p7HWo=", + "_parent": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "model": { + "$ref": "AAAAAAF5QMnaf4p0R7o=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1452, + "top": 937, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMnaf4p8uO8=", + "_parent": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "model": { + "$ref": "AAAAAAF5QMnaf4p0R7o=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1442, + "top": 945, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMnaf4p9ZYk=", + "_parent": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "model": { + "$ref": "AAAAAAF5QMnaf4p0R7o=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1475, + "top": 920, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMnaf4p+8dA=", + "_parent": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "model": { + "$ref": "AAAAAAF5QMnaf4p1n0A=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1229, + "top": 721, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMnaf4p/pOU=", + "_parent": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "model": { + "$ref": "AAAAAAF5QMnaf4p1n0A=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1221, + "top": 732, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMnaf4qAet8=", + "_parent": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "model": { + "$ref": "AAAAAAF5QMnaf4p1n0A=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1245, + "top": 699, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QMnaf4qBmzo=", + "_parent": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "model": { + "$ref": "AAAAAAF5QMnaf4p0R7o=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 696, + "top": 8, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QMnaf4qCCtY=", + "_parent": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "model": { + "$ref": "AAAAAAF5QMnaf4p1n0A=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 696, + "top": 8, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QKysH1F4naw=" + }, + "tail": { + "$ref": "AAAAAAF5QKuCwkzY630=" + }, + "lineStyle": 1, + "points": "1482:951;1221:699", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QMnaf4p4YhA=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QMnaf4p5heM=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QMnaf4p6u/E=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QMnaf4p7HWo=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QMnaf4p8uO8=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QMnaf4p9ZYk=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QMnaf4p+8dA=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QMnaf4p/pOU=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QMnaf4qAet8=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QMnaf4qBmzo=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QMnaf4qCCtY=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QNAhapFuI7s=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QNAhapFq3kM=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNAhapFvVXY=", + "_parent": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "model": { + "$ref": "AAAAAAF5QNAhapFq3kM=" + }, + "font": "Arial;13;0", + "left": 1312, + "top": 829, + "width": 33.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "edgePosition": 1, + "text": "+取消" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNAhapFwVCE=", + "_parent": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "model": { + "$ref": "AAAAAAF5QNAhapFq3kM=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1336, + "top": 817, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNAhapFxPvQ=", + "_parent": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "model": { + "$ref": "AAAAAAF5QNAhapFq3kM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1311, + "top": 854, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNAhapFyOWw=", + "_parent": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "model": { + "$ref": "AAAAAAF5QNAhapFrudc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1242, + "top": 705, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNAhapFz3Mw=", + "_parent": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "model": { + "$ref": "AAAAAAF5QNAhapFrudc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1254, + "top": 699, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNAhapF0mvQ=", + "_parent": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "model": { + "$ref": "AAAAAAF5QNAhapFrudc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1217, + "top": 717, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNAha5F1FkI=", + "_parent": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "model": { + "$ref": "AAAAAAF5QNAhapFsZZ8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1460, + "top": 918, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNAha5F2OJ8=", + "_parent": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "model": { + "$ref": "AAAAAAF5QNAhapFsZZ8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1466, + "top": 905, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNAha5F3+WU=", + "_parent": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "model": { + "$ref": "AAAAAAF5QNAhapFsZZ8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1449, + "top": 943, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QNAha5F4AZU=", + "_parent": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "model": { + "$ref": "AAAAAAF5QNAhapFrudc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 744, + "top": -56, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QNAha5F5UgE=", + "_parent": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "model": { + "$ref": "AAAAAAF5QNAhapFsZZ8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 744, + "top": -56, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QKuCwkzY630=" + }, + "tail": { + "$ref": "AAAAAAF5QKysH1F4naw=" + }, + "lineStyle": 1, + "points": "1215:699;1320:848;1474:951", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QNAhapFvVXY=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QNAhapFwVCE=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QNAhapFxPvQ=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QNAhapFyOWw=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QNAhapFz3Mw=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QNAhapF0mvQ=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QNAha5F1FkI=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QNAha5F2OJ8=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QNAha5F3+WU=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QNAha5F4AZU=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QNAha5F5UgE=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QNFL66Cbz6k=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QNFL6qCXEtU=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNFL66CcWkE=", + "_parent": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "model": { + "$ref": "AAAAAAF5QNFL6qCXEtU=" + }, + "font": "Arial;13;0", + "left": 1247, + "top": 550, + "width": 33.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "edgePosition": 1, + "text": "+忽略" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNFL66CdTo8=", + "_parent": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "model": { + "$ref": "AAAAAAF5QNFL6qCXEtU=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1250, + "top": 542, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNFL66Ce+u8=", + "_parent": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "model": { + "$ref": "AAAAAAF5QNFL6qCXEtU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1288, + "top": 567, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNFL66CfR+U=", + "_parent": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "model": { + "$ref": "AAAAAAF5QNFL6qCY2AQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1215, + "top": 627, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNFL66Cg04o=", + "_parent": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "model": { + "$ref": "AAAAAAF5QNFL6qCY2AQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1205, + "top": 617, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNFL66ChcXw=", + "_parent": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "model": { + "$ref": "AAAAAAF5QNFL6qCY2AQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1236, + "top": 645, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNFL66CipGA=", + "_parent": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "model": { + "$ref": "AAAAAAF5QNFL6qCZ01s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1312, + "top": 474, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNFL66Cj6oQ=", + "_parent": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "model": { + "$ref": "AAAAAAF5QNFL6qCZ01s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1299, + "top": 469, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNFL66Ck0os=", + "_parent": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "model": { + "$ref": "AAAAAAF5QNFL6qCZ01s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1337, + "top": 485, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QNFL66ClLUo=", + "_parent": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "model": { + "$ref": "AAAAAAF5QNFL6qCY2AQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 696, + "top": 8, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QNFL66Cm8No=", + "_parent": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "model": { + "$ref": "AAAAAAF5QNFL6qCZ01s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 696, + "top": 8, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QKzDRVJysxE=" + }, + "tail": { + "$ref": "AAAAAAF5QKysH1F4naw=" + }, + "lineStyle": 1, + "points": "1214:663;1339:467", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QNFL66CcWkE=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QNFL66CdTo8=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QNFL66Ce+u8=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QNFL66CfR+U=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QNFL66Cg04o=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QNFL66ChcXw=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QNFL66CipGA=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QNFL66Cj6oQ=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QNFL66Ck0os=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QNFL66ClLUo=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QNFL66Cm8No=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RVTun0vZBv0=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RVTunkvVKUs=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVTun0vaxdo=", + "_parent": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "model": { + "$ref": "AAAAAAF5RVTunkvVKUs=" + }, + "font": "Arial;13;0", + "left": 1205, + "top": 502, + "width": 59.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "edgePosition": 1, + "text": "+重测失败" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVTun0vbxuQ=", + "_parent": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "model": { + "$ref": "AAAAAAF5RVTunkvVKUs=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1226, + "top": 490, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVTun0vcmj8=", + "_parent": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "model": { + "$ref": "AAAAAAF5RVTunkvVKUs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1251, + "top": 527, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVTun0vdoCc=", + "_parent": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "model": { + "$ref": "AAAAAAF5RVTun0vWQ0U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1176, + "top": 542, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVTun0ved/I=", + "_parent": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "model": { + "$ref": "AAAAAAF5RVTun0vWQ0U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1170, + "top": 529, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVTun0vfAMs=", + "_parent": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "model": { + "$ref": "AAAAAAF5RVTun0vWQ0U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1187, + "top": 567, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVTun0vg9C0=", + "_parent": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "model": { + "$ref": "AAAAAAF5RVTun0vXr0g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1294, + "top": 463, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVTuoEvhMzo=", + "_parent": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "model": { + "$ref": "AAAAAAF5RVTun0vXr0g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1284, + "top": 453, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVTuoEviZLY=", + "_parent": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "model": { + "$ref": "AAAAAAF5RVTun0vXr0g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1312, + "top": 483, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RVTuoEvjqMY=", + "_parent": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "model": { + "$ref": "AAAAAAF5RVTun0vWQ0U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 216, + "top": -8, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RVTuoEvkZEE=", + "_parent": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "model": { + "$ref": "AAAAAAF5RVTun0vXr0g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 216, + "top": -8, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QKzDRVJysxE=" + }, + "tail": { + "$ref": "AAAAAAF5QLwOJ2bPDnI=" + }, + "lineStyle": 1, + "points": "1163:575;1324:467", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RVTun0vaxdo=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RVTun0vbxuQ=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RVTun0vcmj8=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RVTun0vdoCc=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RVTun0ved/I=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RVTun0vfAMs=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RVTun0vg9C0=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RVTuoEvhMzo=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RVTuoEviZLY=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RVTuoEvjqMY=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RVTuoEvkZEE=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RVWv21Zu6Aw=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RVWv2lZqu2A=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVWv21ZvsKs=", + "_parent": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "model": { + "$ref": "AAAAAAF5RVWv2lZqu2A=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1032, + "top": 1458, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVWv21ZwRzk=", + "_parent": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "model": { + "$ref": "AAAAAAF5RVWv2lZqu2A=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1034, + "top": 1473, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVWv21ZxCSk=", + "_parent": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "model": { + "$ref": "AAAAAAF5RVWv2lZqu2A=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1027, + "top": 1429, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVWv21Zyej0=", + "_parent": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "model": { + "$ref": "AAAAAAF5RVWv2lZro+8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1087, + "top": 1451, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVWv21ZzuYg=", + "_parent": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "model": { + "$ref": "AAAAAAF5RVWv2lZro+8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1086, + "top": 1464, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVWv3FZ0MPo=", + "_parent": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "model": { + "$ref": "AAAAAAF5RVWv2lZro+8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1087, + "top": 1423, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVWv3FZ18no=", + "_parent": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "model": { + "$ref": "AAAAAAF5RVWv2lZs/XI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 977, + "top": 1467, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVWv3FZ21Iw=", + "_parent": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "model": { + "$ref": "AAAAAAF5RVWv2lZs/XI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 981, + "top": 1480, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVWv3FZ3nLg=", + "_parent": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "model": { + "$ref": "AAAAAAF5RVWv2lZs/XI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 969, + "top": 1440, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RVWv3FZ4weo=", + "_parent": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "model": { + "$ref": "AAAAAAF5RVWv2lZro+8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 216, + "top": -8, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RVWv3FZ58yM=", + "_parent": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "model": { + "$ref": "AAAAAAF5RVWv2lZs/XI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 216, + "top": -8, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5RZAQqNi9KXs=" + }, + "tail": { + "$ref": "AAAAAAF5QJWvCwgzk0M=" + }, + "lineStyle": 1, + "points": "1111:1439;950:1462", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RVWv21ZvsKs=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RVWv21ZwRzk=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RVWv21ZxCSk=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RVWv21Zyej0=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RVWv21ZzuYg=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RVWv3FZ0MPo=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RVWv3FZ18no=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RVWv3FZ21Iw=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RVWv3FZ3nLg=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RVWv3FZ4weo=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RVWv3FZ58yM=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5RVbpp1nKVhc=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RVbpp1nIOnU=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5RVbpp1nLusg=", + "_parent": { + "$ref": "AAAAAAF5RVbpp1nKVhc=" + }, + "model": { + "$ref": "AAAAAAF5RVbpp1nIOnU=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5RVbpqFnM530=", + "_parent": { + "$ref": "AAAAAAF5RVbpp1nLusg=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 1680, + "top": -704, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RVbpqFnNEWc=", + "_parent": { + "$ref": "AAAAAAF5RVbpp1nLusg=" + }, + "fillColor": "#ffadad", + "font": "Arial;13;1", + "left": 1095.5, + "top": 819.5, + "width": 77, + "height": 13, + "text": "执行测回删除" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RVbpqFnO5/0=", + "_parent": { + "$ref": "AAAAAAF5RVbpp1nLusg=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 1680, + "top": -704, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RVbpqFnPMMU=", + "_parent": { + "$ref": "AAAAAAF5RVbpp1nLusg=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 1680, + "top": -704, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 1090.5, + "top": 812.5, + "width": 88, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5RVbpqFnM530=" + }, + "nameLabel": { + "$ref": "AAAAAAF5RVbpqFnNEWc=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5RVbpqFnO5/0=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RVbpqFnPMMU=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5RVbpqFnQqa0=", + "_parent": { + "$ref": "AAAAAAF5RVbpp1nKVhc=" + }, + "model": { + "$ref": "AAAAAAF5RVbpp1nIOnU=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 840, + "top": -352, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5RVbpqFnRVaY=", + "_parent": { + "$ref": "AAAAAAF5RVbpp1nKVhc=" + }, + "model": { + "$ref": "AAAAAAF5RVbpp1nIOnU=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 840, + "top": -352, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5RVbpqFnSiyY=", + "_parent": { + "$ref": "AAAAAAF5RVbpp1nKVhc=" + }, + "model": { + "$ref": "AAAAAAF5RVbpp1nIOnU=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 840, + "top": -352, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5RVbpqFnTp/o=", + "_parent": { + "$ref": "AAAAAAF5RVbpp1nKVhc=" + }, + "model": { + "$ref": "AAAAAAF5RVbpp1nIOnU=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 840, + "top": -352, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5RVbpqFnUeVQ=", + "_parent": { + "$ref": "AAAAAAF5RVbpp1nKVhc=" + }, + "model": { + "$ref": "AAAAAAF5RVbpp1nIOnU=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 840, + "top": -352, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ffadad", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 1072, + "top": 808, + "width": 124, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5RVbpp1nLusg=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5RVbpqFnQqa0=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5RVbpqFnRVaY=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5RVbpqFnSiyY=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5RVbpqFnTp/o=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5RVbpqFnUeVQ=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RVcwNF0lj/I=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RVcwNF0hcaI=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVcwNF0m640=", + "_parent": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "model": { + "$ref": "AAAAAAF5RVcwNF0hcaI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1180, + "top": 753, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVcwNF0n9pE=", + "_parent": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "model": { + "$ref": "AAAAAAF5RVcwNF0hcaI=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1194, + "top": 759, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVcwNF0osMg=", + "_parent": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "model": { + "$ref": "AAAAAAF5RVcwNF0hcaI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1153, + "top": 740, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVcwNF0pne0=", + "_parent": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "model": { + "$ref": "AAAAAAF5RVcwNF0iVWE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1195, + "top": 722, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVcwNF0qTm8=", + "_parent": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "model": { + "$ref": "AAAAAAF5RVcwNF0iVWE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1206, + "top": 730, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVcwNF0rLrQ=", + "_parent": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "model": { + "$ref": "AAAAAAF5RVcwNF0iVWE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1172, + "top": 707, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVcwNF0s558=", + "_parent": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "model": { + "$ref": "AAAAAAF5RVcwNF0jQf0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1166, + "top": 783, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVcwNF0tAew=", + "_parent": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "model": { + "$ref": "AAAAAAF5RVcwNF0jQf0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1179, + "top": 787, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVcwNF0uE34=", + "_parent": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "model": { + "$ref": "AAAAAAF5RVcwNF0jQf0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1139, + "top": 776, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RVcwNF0vsAE=", + "_parent": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "model": { + "$ref": "AAAAAAF5RVcwNF0iVWE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 432, + "top": 8, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RVcwNF0w5ls=", + "_parent": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "model": { + "$ref": "AAAAAAF5RVcwNF0jQf0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 432, + "top": 8, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5RVbpp1nKVhc=" + }, + "tail": { + "$ref": "AAAAAAF5QKysH1F4naw=" + }, + "lineStyle": 1, + "points": "1193:699;1142:807", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RVcwNF0m640=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RVcwNF0n9pE=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RVcwNF0osMg=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RVcwNF0pne0=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RVcwNF0qTm8=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RVcwNF0rLrQ=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RVcwNF0s558=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RVcwNF0tAew=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RVcwNF0uE34=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RVcwNF0vsAE=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RVcwNF0w5ls=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RVdEqmBOVoU=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RVdEqWBKDgY=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVdEqmBP7Mw=", + "_parent": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "model": { + "$ref": "AAAAAAF5RVdEqWBKDgY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 918, + "top": 711, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVdEqmBQ+G0=", + "_parent": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "model": { + "$ref": "AAAAAAF5RVdEqWBKDgY=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 910, + "top": 724, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVdEqmBRwAI=", + "_parent": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "model": { + "$ref": "AAAAAAF5RVdEqWBKDgY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 933, + "top": 686, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVdEqmBSb60=", + "_parent": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "model": { + "$ref": "AAAAAAF5RVdEqWBL2Ro=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1072, + "top": 800, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVdEqmBT13s=", + "_parent": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "model": { + "$ref": "AAAAAAF5RVdEqWBL2Ro=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1063, + "top": 811, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVdEqmBU/V0=", + "_parent": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "model": { + "$ref": "AAAAAAF5RVdEqWBL2Ro=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1089, + "top": 779, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVdEqmBVD2o=", + "_parent": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "model": { + "$ref": "AAAAAAF5RVdEqWBMaWs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 765, + "top": 623, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVdEqmBWru8=", + "_parent": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "model": { + "$ref": "AAAAAAF5RVdEqWBMaWs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 761, + "top": 635, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVdEqmBX1jY=", + "_parent": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "model": { + "$ref": "AAAAAAF5RVdEqWBMaWs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 775, + "top": 597, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RVdEqmBYqxc=", + "_parent": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "model": { + "$ref": "AAAAAAF5RVdEqWBL2Ro=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 216, + "top": -8, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RVdEqmBZh5U=", + "_parent": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "model": { + "$ref": "AAAAAAF5RVdEqWBMaWs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 216, + "top": -8, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QMaQUG/rlG8=" + }, + "tail": { + "$ref": "AAAAAAF5RVbpp1nKVhc=" + }, + "lineStyle": 1, + "points": "1102:807;751:603", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RVdEqmBP7Mw=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RVdEqmBQ+G0=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RVdEqmBRwAI=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RVdEqmBSb60=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RVdEqmBT13s=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RVdEqmBU/V0=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RVdEqmBVD2o=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RVdEqmBWru8=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RVdEqmBX1jY=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RVdEqmBYqxc=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RVdEqmBZh5U=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5RWbWiJQ+LqI=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RWbWh5Q82SE=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5RWbWiJQ/pQw=", + "_parent": { + "$ref": "AAAAAAF5RWbWiJQ+LqI=" + }, + "model": { + "$ref": "AAAAAAF5RWbWh5Q82SE=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5RWbWiJRAz/w=", + "_parent": { + "$ref": "AAAAAAF5RWbWiJQ/pQw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1808, + "top": 368, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RWbWiJRBIu8=", + "_parent": { + "$ref": "AAAAAAF5RWbWiJQ/pQw=" + }, + "font": "Arial;13;1", + "left": 594, + "top": 819.5, + "width": 167, + "height": 13, + "text": "doCalScheduleSingleCycle" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RWbWiJRCluw=", + "_parent": { + "$ref": "AAAAAAF5RWbWiJQ/pQw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1808, + "top": 368, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RWbWiJRDVic=", + "_parent": { + "$ref": "AAAAAAF5RWbWiJQ/pQw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1808, + "top": 368, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 589, + "top": 812.5, + "width": 177.603515625, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5RWbWiJRAz/w=" + }, + "nameLabel": { + "$ref": "AAAAAAF5RWbWiJRBIu8=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5RWbWiJRCluw=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RWbWiJRDVic=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5RWbWiJRE0bA=", + "_parent": { + "$ref": "AAAAAAF5RWbWiJQ+LqI=" + }, + "model": { + "$ref": "AAAAAAF5RWbWh5Q82SE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -904, + "top": 184, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5RWbWiJRF/Bs=", + "_parent": { + "$ref": "AAAAAAF5RWbWiJQ+LqI=" + }, + "model": { + "$ref": "AAAAAAF5RWbWh5Q82SE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -904, + "top": 184, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5RWbWiJRG03U=", + "_parent": { + "$ref": "AAAAAAF5RWbWiJQ+LqI=" + }, + "model": { + "$ref": "AAAAAAF5RWbWh5Q82SE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -904, + "top": 184, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5RWbWiJRHoKE=", + "_parent": { + "$ref": "AAAAAAF5RWbWiJQ+LqI=" + }, + "model": { + "$ref": "AAAAAAF5RWbWh5Q82SE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -904, + "top": 184, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5RWbWiZRIksM=", + "_parent": { + "$ref": "AAAAAAF5RWbWiJQ+LqI=" + }, + "model": { + "$ref": "AAAAAAF5RWbWh5Q82SE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -904, + "top": 184, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 552, + "top": 808, + "width": 251, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5RWbWiJQ/pQw=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5RWbWiJRE0bA=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5RWbWiJRF/Bs=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5RWbWiJRG03U=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5RWbWiJRHoKE=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5RWbWiZRIksM=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5RWiYh6tfjKM=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RWiYh6tdXHE=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5RWiYh6tg64I=", + "_parent": { + "$ref": "AAAAAAF5RWiYh6tfjKM=" + }, + "model": { + "$ref": "AAAAAAF5RWiYh6tdXHE=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5RWiYh6th8ec=", + "_parent": { + "$ref": "AAAAAAF5RWiYh6tg64I=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -1424, + "top": 416, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RWiYh6tiGF8=", + "_parent": { + "$ref": "AAAAAAF5RWiYh6tg64I=" + }, + "fillColor": "#ffff91", + "font": "Arial;13;1", + "left": 703.5, + "top": 931.5, + "width": 116, + "height": 13, + "text": "该测回是否完成测量" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RWiYh6tjmMc=", + "_parent": { + "$ref": "AAAAAAF5RWiYh6tg64I=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -1424, + "top": 416, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RWiYh6tktDE=", + "_parent": { + "$ref": "AAAAAAF5RWiYh6tg64I=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -1424, + "top": 416, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 698.5, + "top": 924.5, + "width": 127, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5RWiYh6th8ec=" + }, + "nameLabel": { + "$ref": "AAAAAAF5RWiYh6tiGF8=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5RWiYh6tjmMc=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RWiYh6tktDE=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5RWiYh6tlfk4=", + "_parent": { + "$ref": "AAAAAAF5RWiYh6tfjKM=" + }, + "model": { + "$ref": "AAAAAAF5RWiYh6tdXHE=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -712, + "top": 208, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5RWiYh6tmr4M=", + "_parent": { + "$ref": "AAAAAAF5RWiYh6tfjKM=" + }, + "model": { + "$ref": "AAAAAAF5RWiYh6tdXHE=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -712, + "top": 208, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5RWiYiKtnqn4=", + "_parent": { + "$ref": "AAAAAAF5RWiYh6tfjKM=" + }, + "model": { + "$ref": "AAAAAAF5RWiYh6tdXHE=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -712, + "top": 208, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5RWiYiKtodLM=", + "_parent": { + "$ref": "AAAAAAF5RWiYh6tfjKM=" + }, + "model": { + "$ref": "AAAAAAF5RWiYh6tdXHE=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -712, + "top": 208, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5RWiYiKtpwlU=", + "_parent": { + "$ref": "AAAAAAF5RWiYh6tfjKM=" + }, + "model": { + "$ref": "AAAAAAF5RWiYh6tdXHE=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -712, + "top": 208, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 672, + "top": 920, + "width": 179, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5RWiYh6tg64I=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5RWiYh6tlfk4=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5RWiYh6tmr4M=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5RWiYiKtnqn4=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5RWiYiKtodLM=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5RWiYiKtpwlU=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RWkDsK/8U8w=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RWkDr6/4piw=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWkDsK/9X9k=", + "_parent": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "model": { + "$ref": "AAAAAAF5RWkDr6/4piw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 730, + "top": 865, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWkDsK/+yfw=", + "_parent": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "model": { + "$ref": "AAAAAAF5RWkDr6/4piw=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 742, + "top": 856, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWkDsK//l9E=", + "_parent": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "model": { + "$ref": "AAAAAAF5RWkDr6/4piw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 707, + "top": 884, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWkDsLAAR6U=", + "_parent": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "model": { + "$ref": "AAAAAAF5RWkDr6/5hKI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 718, + "top": 848, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWkDsLAB24o=", + "_parent": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "model": { + "$ref": "AAAAAAF5RWkDr6/5hKI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 730, + "top": 842, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWkDsLACKmw=", + "_parent": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "model": { + "$ref": "AAAAAAF5RWkDr6/5hKI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 693, + "top": 861, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWkDsLADQMw=", + "_parent": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "model": { + "$ref": "AAAAAAF5RWkDr6/6Fyk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 744, + "top": 883, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWkDsLAEjZI=", + "_parent": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "model": { + "$ref": "AAAAAAF5RWkDr6/6Fyk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 753, + "top": 873, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWkDsLAFuWM=", + "_parent": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "model": { + "$ref": "AAAAAAF5RWkDr6/6Fyk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 725, + "top": 903, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RWkDsLAGH8s=", + "_parent": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "model": { + "$ref": "AAAAAAF5RWkDr6/5hKI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1160, + "top": 208, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RWkDsLAHEmo=", + "_parent": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "model": { + "$ref": "AAAAAAF5RWkDr6/6Fyk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1160, + "top": 208, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5RWiYh6tfjKM=" + }, + "tail": { + "$ref": "AAAAAAF5RWbWiJQ+LqI=" + }, + "lineStyle": 1, + "points": "691:843;748:919", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RWkDsK/9X9k=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RWkDsK/+yfw=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RWkDsK//l9E=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RWkDsLAAR6U=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RWkDsLAB24o=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RWkDsLACKmw=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RWkDsLADQMw=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RWkDsLAEjZI=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RWkDsLAFuWM=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RWkDsLAGH8s=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RWkDsLAHEmo=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RWmAObijdJg=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RWmAObifwr4=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWmAObikqE4=", + "_parent": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "model": { + "$ref": "AAAAAAF5RWmAObifwr4=" + }, + "font": "Arial;13;0", + "left": 702, + "top": 756, + "width": 46.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "edgePosition": 1, + "text": "+未完成" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWmAObilnCo=", + "_parent": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "model": { + "$ref": "AAAAAAF5RWmAObifwr4=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 710, + "top": 758, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWmAObima+o=", + "_parent": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "model": { + "$ref": "AAAAAAF5RWmAObifwr4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 754, + "top": 753, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWmAObinxIM=", + "_parent": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "model": { + "$ref": "AAAAAAF5RWmAObigyuY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 741, + "top": 888, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWmAObioxZQ=", + "_parent": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "model": { + "$ref": "AAAAAAF5RWmAObigyuY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 727, + "top": 888, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWmAObip4S4=", + "_parent": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "model": { + "$ref": "AAAAAAF5RWmAObigyuY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 768, + "top": 890, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWmAObiqN8s=", + "_parent": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "model": { + "$ref": "AAAAAAF5RWmAObih5u0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 710, + "top": 624, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RWmAObijdJg=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWmAObir6/Y=", + "_parent": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "model": { + "$ref": "AAAAAAF5RWmAObih5u0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 697, + "top": 628, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RWmAObijdJg=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWmAObisLv4=", + "_parent": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "model": { + "$ref": "AAAAAAF5RWmAObih5u0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 736, + "top": 617, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RWmAObijdJg=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RWmAObitY30=", + "_parent": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "model": { + "$ref": "AAAAAAF5RWmAObigyuY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -888, + "top": 512, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RWmAObiuohI=", + "_parent": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "model": { + "$ref": "AAAAAAF5RWmAObih5u0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -888, + "top": 512, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QMaQUG/rlG8=" + }, + "tail": { + "$ref": "AAAAAAF5RWiYh6tfjKM=" + }, + "lineStyle": 1, + "points": "759:919;722:603", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RWmAObikqE4=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RWmAObilnCo=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RWmAObima+o=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RWmAObinxIM=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RWmAObioxZQ=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RWmAObip4S4=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RWmAObiqN8s=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RWmAObir6/Y=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RWmAObisLv4=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RWmAObitY30=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RWmAObiuohI=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5RWo+Isgcitc=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RWo+Icga7No=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5RWo+Isgdtvs=", + "_parent": { + "$ref": "AAAAAAF5RWo+Isgcitc=" + }, + "model": { + "$ref": "AAAAAAF5RWo+Icga7No=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5RWo+Isge0Bo=", + "_parent": { + "$ref": "AAAAAAF5RWo+Isgdtvs=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 496, + "top": -256, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RWo+Isgf4GU=", + "_parent": { + "$ref": "AAAAAAF5RWo+Isgdtvs=" + }, + "fillColor": "#ffff91", + "font": "Arial;13;1", + "left": 658, + "top": 1051.5, + "width": 90, + "height": 13, + "text": "执行单测回检测" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RWo+Isgg0Do=", + "_parent": { + "$ref": "AAAAAAF5RWo+Isgdtvs=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 496, + "top": -256, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RWo+IsghCRI=", + "_parent": { + "$ref": "AAAAAAF5RWo+Isgdtvs=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 496, + "top": -256, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 653, + "top": 1044.5, + "width": 101, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5RWo+Isge0Bo=" + }, + "nameLabel": { + "$ref": "AAAAAAF5RWo+Isgf4GU=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5RWo+Isgg0Do=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RWo+IsghCRI=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5RWo+IsgimWA=", + "_parent": { + "$ref": "AAAAAAF5RWo+Isgcitc=" + }, + "model": { + "$ref": "AAAAAAF5RWo+Icga7No=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 248, + "top": -128, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5RWo+IsgjYQU=", + "_parent": { + "$ref": "AAAAAAF5RWo+Isgcitc=" + }, + "model": { + "$ref": "AAAAAAF5RWo+Icga7No=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 248, + "top": -128, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5RWo+I8gkz+0=", + "_parent": { + "$ref": "AAAAAAF5RWo+Isgcitc=" + }, + "model": { + "$ref": "AAAAAAF5RWo+Icga7No=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 248, + "top": -128, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5RWo+I8gl0UM=", + "_parent": { + "$ref": "AAAAAAF5RWo+Isgcitc=" + }, + "model": { + "$ref": "AAAAAAF5RWo+Icga7No=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 248, + "top": -128, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5RWo+I8gmRYk=", + "_parent": { + "$ref": "AAAAAAF5RWo+Isgcitc=" + }, + "model": { + "$ref": "AAAAAAF5RWo+Icga7No=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 248, + "top": -128, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 632, + "top": 1040, + "width": 142, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5RWo+Isgdtvs=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5RWo+IsgimWA=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5RWo+IsgjYQU=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5RWo+I8gkz+0=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5RWo+I8gl0UM=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5RWo+I8gmRYk=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RWqc88vvIe4=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RWqc8svr3pE=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWqc88vwQ3o=", + "_parent": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "model": { + "$ref": "AAAAAAF5RWqc8svr3pE=" + }, + "font": "Arial;13;0", + "left": 728, + "top": 997, + "width": 33.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "edgePosition": 1, + "text": "+完成" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWqc88vxT8A=", + "_parent": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "model": { + "$ref": "AAAAAAF5RWqc8svr3pE=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 758, + "top": 1003, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWqc88vy9C4=", + "_parent": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "model": { + "$ref": "AAAAAAF5RWqc8svr3pE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 717, + "top": 984, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWqc88vzWws=", + "_parent": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "model": { + "$ref": "AAAAAAF5RWqc8svs8AE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 754, + "top": 978, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWqc88v0Sh0=", + "_parent": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "model": { + "$ref": "AAAAAAF5RWqc8svs8AE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 765, + "top": 986, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWqc88v168Q=", + "_parent": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "model": { + "$ref": "AAAAAAF5RWqc8svs8AE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 731, + "top": 962, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWqc88v2l68=", + "_parent": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "model": { + "$ref": "AAAAAAF5RWqc8svtE1U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 735, + "top": 1016, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWqc88v3ThA=", + "_parent": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "model": { + "$ref": "AAAAAAF5RWqc8svtE1U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 748, + "top": 1019, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWqc88v4wsI=", + "_parent": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "model": { + "$ref": "AAAAAAF5RWqc8svtE1U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 709, + "top": 1008, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RWqc88v5V34=", + "_parent": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "model": { + "$ref": "AAAAAAF5RWqc8svs8AE=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RWqc88v6Awc=", + "_parent": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "model": { + "$ref": "AAAAAAF5RWqc8svtE1U=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5RWo+Isgcitc=" + }, + "tail": { + "$ref": "AAAAAAF5RWiYh6tfjKM=" + }, + "lineStyle": 1, + "points": "752:955;711:1039", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RWqc88vwQ3o=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RWqc88vxT8A=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RWqc88vy9C4=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RWqc88vzWws=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RWqc88v0Sh0=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RWqc88v168Q=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RWqc88v2l68=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RWqc88v3ThA=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RWqc88v4wsI=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RWqc88v5V34=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RWqc88v6Awc=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RWvJyNWG+ro=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RWvJyNWC314=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWvJyNWHf5E=", + "_parent": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "model": { + "$ref": "AAAAAAF5RWvJyNWC314=" + }, + "font": "Arial;13;0", + "left": 1068, + "top": 991, + "width": 72.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "edgePosition": 1, + "text": "+未通过检测" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWvJydWI+RY=", + "_parent": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "model": { + "$ref": "AAAAAAF5RWvJyNWC314=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1102, + "top": 976, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWvJydWJFaw=", + "_parent": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "model": { + "$ref": "AAAAAAF5RWvJyNWC314=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1107, + "top": 1020, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWvJydWKHVg=", + "_parent": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "model": { + "$ref": "AAAAAAF5RWvJyNWDYLg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 798, + "top": 1025, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWvJydWLzSM=", + "_parent": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "model": { + "$ref": "AAAAAAF5RWvJyNWDYLg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 799, + "top": 1011, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWvJydWM5GE=", + "_parent": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "model": { + "$ref": "AAAAAAF5RWvJyNWDYLg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 796, + "top": 1053, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWvJydWN+wY=", + "_parent": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "model": { + "$ref": "AAAAAAF5RWvJyNWEI/s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1411, + "top": 957, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWvJydWO3W0=", + "_parent": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "model": { + "$ref": "AAAAAAF5RWvJyNWEI/s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1407, + "top": 944, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWvJydWPqsM=", + "_parent": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "model": { + "$ref": "AAAAAAF5RWvJyNWEI/s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1418, + "top": 984, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RWvJydWQnX8=", + "_parent": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "model": { + "$ref": "AAAAAAF5RWvJyNWDYLg=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RWvJydWRolw=", + "_parent": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "model": { + "$ref": "AAAAAAF5RWvJyNWEI/s=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QKuCwkzY630=" + }, + "tail": { + "$ref": "AAAAAAF5RWo+Isgcitc=" + }, + "lineStyle": 1, + "points": "774:1049;1439:976", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RWvJyNWHf5E=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RWvJydWI+RY=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RWvJydWJFaw=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RWvJydWKHVg=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RWvJydWLzSM=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RWvJydWM5GE=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RWvJydWN+wY=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RWvJydWO3W0=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RWvJydWPqsM=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RWvJydWQnX8=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RWvJydWRolw=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5RWzzg+QpJu4=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RWzzg+QnXQo=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5RWzzg+QqF0g=", + "_parent": { + "$ref": "AAAAAAF5RWzzg+QpJu4=" + }, + "model": { + "$ref": "AAAAAAF5RWzzg+QnXQo=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5RWzzg+QruaM=", + "_parent": { + "$ref": "AAAAAAF5RWzzg+QqF0g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1504, + "top": -800, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RWzzg+QscXo=", + "_parent": { + "$ref": "AAAAAAF5RWzzg+QqF0g=" + }, + "font": "Arial;13;1", + "left": 1093.5, + "top": 907.5, + "width": 144, + "height": 13, + "text": "doCalScheduleAllCycle" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RWzzg+QtTVY=", + "_parent": { + "$ref": "AAAAAAF5RWzzg+QqF0g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1504, + "top": -800, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RWzzg+QuN+0=", + "_parent": { + "$ref": "AAAAAAF5RWzzg+QqF0g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1504, + "top": -800, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 1088.5, + "top": 900.5, + "width": 155.208984375, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5RWzzg+QruaM=" + }, + "nameLabel": { + "$ref": "AAAAAAF5RWzzg+QscXo=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5RWzzg+QtTVY=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RWzzg+QuN+0=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5RWzzg+QvVhA=", + "_parent": { + "$ref": "AAAAAAF5RWzzg+QpJu4=" + }, + "model": { + "$ref": "AAAAAAF5RWzzg+QnXQo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 752, + "top": -400, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5RWzzhOQwWI4=", + "_parent": { + "$ref": "AAAAAAF5RWzzg+QpJu4=" + }, + "model": { + "$ref": "AAAAAAF5RWzzg+QnXQo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 752, + "top": -400, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5RWzzhOQxyn0=", + "_parent": { + "$ref": "AAAAAAF5RWzzg+QpJu4=" + }, + "model": { + "$ref": "AAAAAAF5RWzzg+QnXQo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 752, + "top": -400, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5RWzzhOQy5lE=", + "_parent": { + "$ref": "AAAAAAF5RWzzg+QpJu4=" + }, + "model": { + "$ref": "AAAAAAF5RWzzg+QnXQo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 752, + "top": -400, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5RWzzhOQzPbk=", + "_parent": { + "$ref": "AAAAAAF5RWzzg+QpJu4=" + }, + "model": { + "$ref": "AAAAAAF5RWzzg+QnXQo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 752, + "top": -400, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 1056, + "top": 896, + "width": 219, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5RWzzg+QqF0g=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5RWzzg+QvVhA=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5RWzzhOQwWI4=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5RWzzhOQxyn0=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5RWzzhOQy5lE=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5RWzzhOQzPbk=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RXS1EJdHVug=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RXS1D5dDHCY=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXS1EJdIPgY=", + "_parent": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "model": { + "$ref": "AAAAAAF5RXS1D5dDHCY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 953, + "top": 934, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXS1EJdJc8o=", + "_parent": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "model": { + "$ref": "AAAAAAF5RXS1D5dDHCY=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 954, + "top": 949, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXS1EZdKavs=", + "_parent": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "model": { + "$ref": "AAAAAAF5RXS1D5dDHCY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 952, + "top": 905, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXS1EZdLggY=", + "_parent": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "model": { + "$ref": "AAAAAAF5RXS1D5dEJJs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1029, + "top": 930, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXS1EZdMTYk=", + "_parent": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "model": { + "$ref": "AAAAAAF5RXS1D5dEJJs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1028, + "top": 943, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXS1EZdNexM=", + "_parent": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "model": { + "$ref": "AAAAAAF5RXS1D5dEJJs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1032, + "top": 902, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXS1EZdOTNQ=", + "_parent": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "model": { + "$ref": "AAAAAAF5RXS1D5dF2N4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 877, + "top": 939, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXS1EZdPiGs=", + "_parent": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "model": { + "$ref": "AAAAAAF5RXS1D5dF2N4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 880, + "top": 952, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXS1EZdQDNw=", + "_parent": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "model": { + "$ref": "AAAAAAF5RXS1D5dF2N4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 871, + "top": 912, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RXS1EZdR8Jw=", + "_parent": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "model": { + "$ref": "AAAAAAF5RXS1D5dEJJs=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RXS1EZdSgUI=", + "_parent": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "model": { + "$ref": "AAAAAAF5RXS1D5dF2N4=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5RWiYh6tfjKM=" + }, + "tail": { + "$ref": "AAAAAAF5RWzzg+QpJu4=" + }, + "lineStyle": 1, + "points": "1055:920;851:932", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RXS1EJdIPgY=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RXS1EJdJc8o=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RXS1EZdKavs=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RXS1EZdLggY=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RXS1EZdMTYk=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RXS1EZdNexM=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RXS1EZdOTNQ=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RXS1EZdPiGs=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RXS1EZdQDNw=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RXS1EZdR8Jw=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RXS1EZdSgUI=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5RXZT37eTFkI=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RXZT3reRJjE=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5RXZT37eUYGs=", + "_parent": { + "$ref": "AAAAAAF5RXZT37eTFkI=" + }, + "model": { + "$ref": "AAAAAAF5RXZT3reRJjE=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5RXZT37eVlUE=", + "_parent": { + "$ref": "AAAAAAF5RXZT37eUYGs=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -768, + "top": -352, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RXZT37eWL9s=", + "_parent": { + "$ref": "AAAAAAF5RXZT37eUYGs=" + }, + "fillColor": "#ffff91", + "font": "Arial;13;1", + "left": 75, + "top": 683.5, + "width": 209, + "height": 13, + "text": "是否是doCalScheduleAllCycle状态" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RXZT37eXM1A=", + "_parent": { + "$ref": "AAAAAAF5RXZT37eUYGs=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -768, + "top": -352, + "width": 73.67724609375, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RXZT37eYXNc=", + "_parent": { + "$ref": "AAAAAAF5RXZT37eUYGs=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -768, + "top": -352, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 70, + "top": 676.5, + "width": 220.208984375, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5RXZT37eVlUE=" + }, + "nameLabel": { + "$ref": "AAAAAAF5RXZT37eWL9s=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5RXZT37eXM1A=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RXZT37eYXNc=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5RXZT4LeZ09I=", + "_parent": { + "$ref": "AAAAAAF5RXZT37eTFkI=" + }, + "model": { + "$ref": "AAAAAAF5RXZT3reRJjE=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -384, + "top": -176, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5RXZT4LeaFc4=", + "_parent": { + "$ref": "AAAAAAF5RXZT37eTFkI=" + }, + "model": { + "$ref": "AAAAAAF5RXZT3reRJjE=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -384, + "top": -176, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5RXZT4Leb1Fs=", + "_parent": { + "$ref": "AAAAAAF5RXZT37eTFkI=" + }, + "model": { + "$ref": "AAAAAAF5RXZT3reRJjE=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -384, + "top": -176, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5RXZT4Lec37Q=", + "_parent": { + "$ref": "AAAAAAF5RXZT37eTFkI=" + }, + "model": { + "$ref": "AAAAAAF5RXZT3reRJjE=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -384, + "top": -176, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5RXZT4Led934=", + "_parent": { + "$ref": "AAAAAAF5RXZT37eTFkI=" + }, + "model": { + "$ref": "AAAAAAF5RXZT3reRJjE=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -384, + "top": -176, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 24, + "top": 672, + "width": 311, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5RXZT37eUYGs=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5RXZT4LeZ09I=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5RXZT4LeaFc4=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5RXZT4Leb1Fs=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5RXZT4Lec37Q=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5RXZT4Led934=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RXgsFM1PXPQ=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RXgsE81LcLM=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXgsFM1QsVQ=", + "_parent": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "model": { + "$ref": "AAAAAAF5RXgsE81LcLM=" + }, + "font": "Arial;13;0", + "left": 415, + "top": 879, + "width": 33.591796875, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "edgePosition": 1, + "text": "+通过" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXgsFM1Ra4g=", + "_parent": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "model": { + "$ref": "AAAAAAF5RXgsE81LcLM=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 422, + "top": 891, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXgsFM1S7Hk=", + "_parent": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "model": { + "$ref": "AAAAAAF5RXgsE81LcLM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 448, + "top": 854, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXgsFM1TpZY=", + "_parent": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "model": { + "$ref": "AAAAAAF5RXgsE81Ml9Y=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 646, + "top": 1030, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXgsFM1UfIs=", + "_parent": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "model": { + "$ref": "AAAAAAF5RXgsE81Ml9Y=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 636, + "top": 1039, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXgsFM1VQJk=", + "_parent": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "model": { + "$ref": "AAAAAAF5RXgsE81Ml9Y=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 665, + "top": 1010, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXgsFM1WeYo=", + "_parent": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "model": { + "$ref": "AAAAAAF5RXgsE81Ncj4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 217, + "top": 728, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXgsFM1XNlM=", + "_parent": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "model": { + "$ref": "AAAAAAF5RXgsE81Ncj4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 211, + "top": 740, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXgsFM1Y+GY=", + "_parent": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "model": { + "$ref": "AAAAAAF5RXgsE81Ncj4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 229, + "top": 703, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RXgsFc1ZbPg=", + "_parent": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "model": { + "$ref": "AAAAAAF5RXgsE81Ml9Y=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RXgsFc1aqC8=", + "_parent": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "model": { + "$ref": "AAAAAAF5RXgsE81Ncj4=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5RXZT37eTFkI=" + }, + "tail": { + "$ref": "AAAAAAF5RWo+Isgcitc=" + }, + "lineStyle": 1, + "points": "676:1039;205:707", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RXgsFM1QsVQ=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RXgsFM1Ra4g=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RXgsFM1S7Hk=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RXgsFM1TpZY=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RXgsFM1UfIs=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RXgsFM1VQJk=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RXgsFM1WeYo=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RXgsFM1XNlM=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RXgsFM1Y+GY=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RXgsFc1ZbPg=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RXgsFc1aqC8=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RXiiXNaNYZA=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RXiiW9aJDaw=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXiiXNaOCjk=", + "_parent": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "model": { + "$ref": "AAAAAAF5RXiiW9aJDaw=" + }, + "font": "Arial;13;0", + "left": 289, + "top": 570, + "width": 33.591796875, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "edgePosition": 1, + "text": "+不是" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXiiXNaPvOQ=", + "_parent": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "model": { + "$ref": "AAAAAAF5RXiiW9aJDaw=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 296, + "top": 558, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXiiXNaQrNs=", + "_parent": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "model": { + "$ref": "AAAAAAF5RXiiW9aJDaw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 322, + "top": 595, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXiiXNaRjEI=", + "_parent": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "model": { + "$ref": "AAAAAAF5RXiiW9aKkno=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 214, + "top": 637, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXiiXNaS5Dg=", + "_parent": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "model": { + "$ref": "AAAAAAF5RXiiW9aKkno=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 208, + "top": 625, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXiiXNaT/jE=", + "_parent": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "model": { + "$ref": "AAAAAAF5RXiiW9aKkno=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 227, + "top": 662, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXiiXNaUStc=", + "_parent": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "model": { + "$ref": "AAAAAAF5RXiiW9aL3M4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 395, + "top": 504, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXiiXNaVtIQ=", + "_parent": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "model": { + "$ref": "AAAAAAF5RXiiW9aL3M4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 385, + "top": 495, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXiiXNaWcc8=", + "_parent": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "model": { + "$ref": "AAAAAAF5RXiiW9aL3M4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 415, + "top": 523, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RXiiXNaXeGE=", + "_parent": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "model": { + "$ref": "AAAAAAF5RXiiW9aKkno=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RXiiXNaY4kk=", + "_parent": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "model": { + "$ref": "AAAAAAF5RXiiW9aL3M4=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QJjLZRML/gk=" + }, + "tail": { + "$ref": "AAAAAAF5RXZT37eTFkI=" + }, + "lineStyle": 1, + "points": "203:671;425:507", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RXiiXNaOCjk=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RXiiXNaPvOQ=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RXiiXNaQrNs=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RXiiXNaRjEI=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RXiiXNaS5Dg=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RXiiXNaT/jE=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RXiiXNaUStc=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RXiiXNaVtIQ=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RXiiXNaWcc8=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RXiiXNaXeGE=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RXiiXNaY4kk=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5RX4IzuDknh4=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RX4IzeDinbw=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5RX4IzuDlZLU=", + "_parent": { + "$ref": "AAAAAAF5RX4IzuDknh4=" + }, + "model": { + "$ref": "AAAAAAF5RX4IzeDinbw=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5RX4IzuDmg8A=", + "_parent": { + "$ref": "AAAAAAF5RX4IzuDlZLU=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -240, + "top": -240, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RX4IzuDnpIw=", + "_parent": { + "$ref": "AAAAAAF5RX4IzuDlZLU=" + }, + "fillColor": "#ffff91", + "font": "Arial;13;1", + "left": 69, + "top": 1043.5, + "width": 181, + "height": 13, + "text": "检测其他测回是否有待补测数据" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RX4IzuDoCnY=", + "_parent": { + "$ref": "AAAAAAF5RX4IzuDlZLU=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -240, + "top": -240, + "width": 73.67724609375, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RX4IzuDpft0=", + "_parent": { + "$ref": "AAAAAAF5RX4IzuDlZLU=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -240, + "top": -240, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 64, + "top": 1036.5, + "width": 192, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5RX4IzuDmg8A=" + }, + "nameLabel": { + "$ref": "AAAAAAF5RX4IzuDnpIw=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5RX4IzuDoCnY=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RX4IzuDpft0=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5RX4IzuDqBSE=", + "_parent": { + "$ref": "AAAAAAF5RX4IzuDknh4=" + }, + "model": { + "$ref": "AAAAAAF5RX4IzeDinbw=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -120, + "top": -120, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5RX4IzuDrpSs=", + "_parent": { + "$ref": "AAAAAAF5RX4IzuDknh4=" + }, + "model": { + "$ref": "AAAAAAF5RX4IzeDinbw=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -120, + "top": -120, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5RX4IzuDsUmU=", + "_parent": { + "$ref": "AAAAAAF5RX4IzuDknh4=" + }, + "model": { + "$ref": "AAAAAAF5RX4IzeDinbw=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -120, + "top": -120, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5RX4IzuDtPH4=", + "_parent": { + "$ref": "AAAAAAF5RX4IzuDknh4=" + }, + "model": { + "$ref": "AAAAAAF5RX4IzeDinbw=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -120, + "top": -120, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5RX4IzuDu2iA=", + "_parent": { + "$ref": "AAAAAAF5RX4IzuDknh4=" + }, + "model": { + "$ref": "AAAAAAF5RX4IzeDinbw=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -120, + "top": -120, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 24, + "top": 1032, + "width": 271, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5RX4IzuDlZLU=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5RX4IzuDqBSE=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5RX4IzuDrpSs=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5RX4IzuDsUmU=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5RX4IzuDtPH4=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5RX4IzuDu2iA=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RX50xuaSWVY=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RX50xeaOm84=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX50xuaTzmw=", + "_parent": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "model": { + "$ref": "AAAAAAF5RX50xeaOm84=" + }, + "font": "Arial;13;0", + "left": 173, + "top": 863, + "width": 20.591796875, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "edgePosition": 1, + "text": "+是" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX50xuaUoZk=", + "_parent": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "model": { + "$ref": "AAAAAAF5RX50xeaOm84=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 198, + "top": 864, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX50xuaVv9g=", + "_parent": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "model": { + "$ref": "AAAAAAF5RX50xeaOm84=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 154, + "top": 862, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX50xuaWjUs=", + "_parent": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "model": { + "$ref": "AAAAAAF5RX50xeaPW6s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 191, + "top": 727, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX50xuaX0wc=", + "_parent": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "model": { + "$ref": "AAAAAAF5RX50xeaPW6s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 204, + "top": 730, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX50xuaYr8k=", + "_parent": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "model": { + "$ref": "AAAAAAF5RX50xeaPW6s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 164, + "top": 721, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX50xuaZPzE=", + "_parent": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "model": { + "$ref": "AAAAAAF5RX50xeaQJxA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 176, + "top": 999, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX50xuaaRl8=", + "_parent": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "model": { + "$ref": "AAAAAAF5RX50xeaQJxA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 189, + "top": 998, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX50xuabK8k=", + "_parent": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "model": { + "$ref": "AAAAAAF5RX50xeaQJxA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 148, + "top": 1002, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RX50xuac8yw=", + "_parent": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "model": { + "$ref": "AAAAAAF5RX50xeaPW6s=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RX50xuadjR8=", + "_parent": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "model": { + "$ref": "AAAAAAF5RX50xeaQJxA=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5RX4IzuDknh4=" + }, + "tail": { + "$ref": "AAAAAAF5RXZT37eTFkI=" + }, + "lineStyle": 1, + "points": "178:707;160:1031", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RX50xuaTzmw=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RX50xuaUoZk=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RX50xuaVv9g=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RX50xuaWjUs=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RX50xuaX0wc=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RX50xuaYr8k=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RX50xuaZPzE=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RX50xuaaRl8=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RX50xuabK8k=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RX50xuac8yw=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RX50xuadjR8=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5RX8e8+6VSP4=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RX8e8+6Tpi8=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5RX8e9O6W2xM=", + "_parent": { + "$ref": "AAAAAAF5RX8e8+6VSP4=" + }, + "model": { + "$ref": "AAAAAAF5RX8e8+6Tpi8=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5RX8e9O6XR7Q=", + "_parent": { + "$ref": "AAAAAAF5RX8e9O6W2xM=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -400, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RX8e9O6YBmI=", + "_parent": { + "$ref": "AAAAAAF5RX8e9O6W2xM=" + }, + "fillColor": "#ffadad", + "font": "Arial;13;1", + "left": 295.5, + "top": 1211.5, + "width": 77, + "height": 13, + "text": "提示用户选择" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RX8e9O6ZG1Q=", + "_parent": { + "$ref": "AAAAAAF5RX8e9O6W2xM=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -400, + "width": 73.67724609375, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RX8e9O6aHT4=", + "_parent": { + "$ref": "AAAAAAF5RX8e9O6W2xM=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -400, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 290.5, + "top": 1204.5, + "width": 88, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5RX8e9O6XR7Q=" + }, + "nameLabel": { + "$ref": "AAAAAAF5RX8e9O6YBmI=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5RX8e9O6ZG1Q=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RX8e9O6aHT4=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5RX8e9O6brFw=", + "_parent": { + "$ref": "AAAAAAF5RX8e8+6VSP4=" + }, + "model": { + "$ref": "AAAAAAF5RX8e8+6Tpi8=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -200, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5RX8e9O6chUQ=", + "_parent": { + "$ref": "AAAAAAF5RX8e8+6VSP4=" + }, + "model": { + "$ref": "AAAAAAF5RX8e8+6Tpi8=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -200, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5RX8e9O6d2JQ=", + "_parent": { + "$ref": "AAAAAAF5RX8e8+6VSP4=" + }, + "model": { + "$ref": "AAAAAAF5RX8e8+6Tpi8=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -200, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5RX8e9O6ehSE=", + "_parent": { + "$ref": "AAAAAAF5RX8e8+6VSP4=" + }, + "model": { + "$ref": "AAAAAAF5RX8e8+6Tpi8=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -200, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5RX8e9O6fsgA=", + "_parent": { + "$ref": "AAAAAAF5RX8e8+6VSP4=" + }, + "model": { + "$ref": "AAAAAAF5RX8e8+6Tpi8=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -200, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ffadad", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 272, + "top": 1200, + "width": 124, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5RX8e9O6W2xM=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5RX8e9O6brFw=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5RX8e9O6chUQ=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5RX8e9O6d2JQ=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5RX8e9O6ehSE=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5RX8e9O6fsgA=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RX9EYPFfH8Q=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RX9EYPFbm2U=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX9EYPFg5zI=", + "_parent": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "model": { + "$ref": "AAAAAAF5RX9EYPFbm2U=" + }, + "font": "Arial;13;0", + "left": 246, + "top": 1116, + "width": 20.591796875, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "edgePosition": 1, + "text": "+有" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX9EYPFh+Xw=", + "_parent": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "model": { + "$ref": "AAAAAAF5RX9EYPFbm2U=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 266, + "top": 1105, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX9EYPFiQm8=", + "_parent": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "model": { + "$ref": "AAAAAAF5RX9EYPFbm2U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 235, + "top": 1137, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX9EYPFj0XU=", + "_parent": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "model": { + "$ref": "AAAAAAF5RX9EYPFcd3k=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 207, + "top": 1068, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX9EYPFkHH4=", + "_parent": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "model": { + "$ref": "AAAAAAF5RX9EYPFcd3k=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 217, + "top": 1060, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX9EYPFlEI4=", + "_parent": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "model": { + "$ref": "AAAAAAF5RX9EYPFcd3k=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 184, + "top": 1085, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX9EYPFmXkk=", + "_parent": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "model": { + "$ref": "AAAAAAF5RX9EYPFdtmc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 305, + "top": 1164, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX9EYPFnjvk=", + "_parent": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "model": { + "$ref": "AAAAAAF5RX9EYPFdtmc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 313, + "top": 1153, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX9EYPFoLfQ=", + "_parent": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "model": { + "$ref": "AAAAAAF5RX9EYPFdtmc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 289, + "top": 1186, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RX9EYPFp0GM=", + "_parent": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "model": { + "$ref": "AAAAAAF5RX9EYPFcd3k=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RX9EYPFqX8k=", + "_parent": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "model": { + "$ref": "AAAAAAF5RX9EYPFdtmc=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5RX8e8+6VSP4=" + }, + "tail": { + "$ref": "AAAAAAF5RX4IzuDknh4=" + }, + "lineStyle": 1, + "points": "178:1067;314:1199", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RX9EYPFg5zI=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RX9EYPFh+Xw=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RX9EYPFiQm8=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RX9EYPFj0XU=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RX9EYPFkHH4=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RX9EYPFlEI4=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RX9EYPFmXkk=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RX9EYPFnjvk=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RX9EYPFoLfQ=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RX9EYPFp0GM=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RX9EYPFqX8k=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5RX+92/rtdeY=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RX+92vrrsgo=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5RX+92/ru5aU=", + "_parent": { + "$ref": "AAAAAAF5RX+92/rtdeY=" + }, + "model": { + "$ref": "AAAAAAF5RX+92vrrsgo=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5RX+92/rvMVo=", + "_parent": { + "$ref": "AAAAAAF5RX+92/ru5aU=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -608, + "top": -240, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RX+92/rwk7c=", + "_parent": { + "$ref": "AAAAAAF5RX+92/ru5aU=" + }, + "fillColor": "#ffff91", + "font": "Arial;13;1", + "left": 492, + "top": 1107.5, + "width": 62, + "height": 13, + "text": "切换测回" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RX+92/rxBWI=", + "_parent": { + "$ref": "AAAAAAF5RX+92/ru5aU=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -608, + "top": -240, + "width": 73.67724609375, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RX+92/ryOmk=", + "_parent": { + "$ref": "AAAAAAF5RX+92/ru5aU=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -608, + "top": -240, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 487, + "top": 1100.5, + "width": 72, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5RX+92/rvMVo=" + }, + "nameLabel": { + "$ref": "AAAAAAF5RX+92/rwk7c=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5RX+92/rxBWI=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RX+92/ryOmk=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5RX+92/rzeck=", + "_parent": { + "$ref": "AAAAAAF5RX+92/rtdeY=" + }, + "model": { + "$ref": "AAAAAAF5RX+92vrrsgo=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -304, + "top": -120, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5RX+92/r0UGE=", + "_parent": { + "$ref": "AAAAAAF5RX+92/rtdeY=" + }, + "model": { + "$ref": "AAAAAAF5RX+92vrrsgo=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -304, + "top": -120, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5RX+92/r1dEM=", + "_parent": { + "$ref": "AAAAAAF5RX+92/rtdeY=" + }, + "model": { + "$ref": "AAAAAAF5RX+92vrrsgo=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -304, + "top": -120, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5RX+92/r24rI=", + "_parent": { + "$ref": "AAAAAAF5RX+92/rtdeY=" + }, + "model": { + "$ref": "AAAAAAF5RX+92vrrsgo=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -304, + "top": -120, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5RX+92/r3m0Y=", + "_parent": { + "$ref": "AAAAAAF5RX+92/rtdeY=" + }, + "model": { + "$ref": "AAAAAAF5RX+92vrrsgo=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -304, + "top": -120, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 472, + "top": 1096, + "width": 102, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5RX+92/ru5aU=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5RX+92/rzeck=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5RX+92/r0UGE=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5RX+92/r1dEM=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5RX+92/r24rI=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5RX+92/r3m0Y=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RX/wMv3JNxw=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RX/wMv3F6d4=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX/wM/3KAYY=", + "_parent": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "model": { + "$ref": "AAAAAAF5RX/wMv3F6d4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 606, + "top": 837, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX/wM/3L2sA=", + "_parent": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "model": { + "$ref": "AAAAAAF5RX/wMv3F6d4=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 592, + "top": 832, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX/wM/3MDuY=", + "_parent": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "model": { + "$ref": "AAAAAAF5RX/wMv3F6d4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 635, + "top": 848, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX/wM/3NMMM=", + "_parent": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "model": { + "$ref": "AAAAAAF5RX/wMv3GM64=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 524, + "top": 1059, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX/wM/3OaEE=", + "_parent": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "model": { + "$ref": "AAAAAAF5RX/wMv3GM64=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 512, + "top": 1052, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX/wM/3P2uw=", + "_parent": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "model": { + "$ref": "AAAAAAF5RX/wMv3GM64=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 548, + "top": 1073, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX/wM/3QkNM=", + "_parent": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "model": { + "$ref": "AAAAAAF5RX/wMv3HIz8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 689, + "top": 616, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX/wM/3RuyM=", + "_parent": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "model": { + "$ref": "AAAAAAF5RX/wMv3HIz8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 676, + "top": 613, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX/wM/3SQ5M=", + "_parent": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "model": { + "$ref": "AAAAAAF5RX/wMv3HIz8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 717, + "top": 621, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RX/wM/3TMvA=", + "_parent": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "model": { + "$ref": "AAAAAAF5RX/wMv3GM64=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 216, + "top": -8, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RX/wM/3Udik=", + "_parent": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "model": { + "$ref": "AAAAAAF5RX/wMv3HIz8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 216, + "top": -8, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QMaQUG/rlG8=" + }, + "tail": { + "$ref": "AAAAAAF5RX+92/rtdeY=" + }, + "lineStyle": 1, + "points": "529:1095;713:603", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RX/wM/3KAYY=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RX/wM/3L2sA=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RX/wM/3MDuY=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RX/wM/3NMMM=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RX/wM/3OaEE=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RX/wM/3P2uw=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RX/wM/3QkNM=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RX/wM/3RuyM=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RX/wM/3SQ5M=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RX/wM/3TMvA=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RX/wM/3Udik=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RYA6Lgau9u4=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RYA6LQaqG8I=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYA6LgavBvE=", + "_parent": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "model": { + "$ref": "AAAAAAF5RYA6LQaqG8I=" + }, + "font": "Arial;13;0", + "left": 370, + "top": 1145, + "width": 98.591796875, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "edgePosition": 1, + "text": "+跳转到相应测回" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYA6LgawDgk=", + "_parent": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "model": { + "$ref": "AAAAAAF5RYA6LQaqG8I=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 412, + "top": 1132, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYA6Lgaxot4=", + "_parent": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "model": { + "$ref": "AAAAAAF5RYA6LQaqG8I=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 434, + "top": 1172, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYA6LgayEWk=", + "_parent": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "model": { + "$ref": "AAAAAAF5RYA6LQaryvU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 381, + "top": 1167, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYA6Lgazq+M=", + "_parent": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "model": { + "$ref": "AAAAAAF5RYA6LQaryvU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 377, + "top": 1154, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYA6Lga0Sio=", + "_parent": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "model": { + "$ref": "AAAAAAF5RYA6LQaryvU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 390, + "top": 1193, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYA6Lga1FSA=", + "_parent": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "model": { + "$ref": "AAAAAAF5RYA6LQashgM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 459, + "top": 1124, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYA6Lga2vcA=", + "_parent": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "model": { + "$ref": "AAAAAAF5RYA6LQashgM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 450, + "top": 1113, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYA6Lga3b2g=", + "_parent": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "model": { + "$ref": "AAAAAAF5RYA6LQashgM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 476, + "top": 1146, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RYA6Lga4c4g=", + "_parent": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "model": { + "$ref": "AAAAAAF5RYA6LQaryvU=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RYA6Lga51go=", + "_parent": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "model": { + "$ref": "AAAAAAF5RYA6LQashgM=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5RX+92/rtdeY=" + }, + "tail": { + "$ref": "AAAAAAF5RX8e8+6VSP4=" + }, + "lineStyle": 1, + "points": "366:1199;489:1131", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RYA6LgavBvE=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RYA6LgawDgk=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RYA6Lgaxot4=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RYA6LgayEWk=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RYA6Lgazq+M=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RYA6Lga0Sio=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RYA6Lga1FSA=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RYA6Lga2vcA=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RYA6Lga3b2g=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RYA6Lga4c4g=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RYA6Lga51go=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RYRxIyqNVJQ=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RYRxIiqJIUE=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYRxIyqOsk8=", + "_parent": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "model": { + "$ref": "AAAAAAF5RYRxIiqJIUE=" + }, + "font": "Arial;13;0", + "left": 340, + "top": 844, + "width": 72.591796875, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "edgePosition": 1, + "text": "+忽略或取消" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYRxIyqPdMg=", + "_parent": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "model": { + "$ref": "AAAAAAF5RYRxIiqJIUE=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 361, + "top": 842, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYRxIyqQWvY=", + "_parent": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "model": { + "$ref": "AAAAAAF5RYRxIiqJIUE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 405, + "top": 849, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYRxIyqRHT4=", + "_parent": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "model": { + "$ref": "AAAAAAF5RYRxIyqKuUY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 325, + "top": 1164, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYRxJCqS57E=", + "_parent": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "model": { + "$ref": "AAAAAAF5RYRxIyqKuUY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 312, + "top": 1160, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYRxJCqTkAo=", + "_parent": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "model": { + "$ref": "AAAAAAF5RYRxIyqKuUY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 351, + "top": 1173, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYRxJCqUXmw=", + "_parent": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "model": { + "$ref": "AAAAAAF5RYRxIyqLN6Y=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 427, + "top": 524, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYRxJCqVgEY=", + "_parent": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "model": { + "$ref": "AAAAAAF5RYRxIyqLN6Y=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 413, + "top": 524, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYRxJCqWNBU=", + "_parent": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "model": { + "$ref": "AAAAAAF5RYRxIyqLN6Y=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 454, + "top": 524, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RYRxJCqXBjo=", + "_parent": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "model": { + "$ref": "AAAAAAF5RYRxIyqKuUY=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RYRxJCqYdsw=", + "_parent": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "model": { + "$ref": "AAAAAAF5RYRxIyqLN6Y=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QJjLZRML/gk=" + }, + "tail": { + "$ref": "AAAAAAF5RX8e8+6VSP4=" + }, + "lineStyle": 1, + "points": "336:1199;446:507", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RYRxIyqOsk8=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RYRxIyqPdMg=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RYRxIyqQWvY=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RYRxIyqRHT4=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RYRxJCqS57E=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RYRxJCqTkAo=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RYRxJCqUXmw=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RYRxJCqVgEY=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RYRxJCqWNBU=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RYRxJCqXBjo=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RYRxJCqYdsw=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5RYWBNj55r2s=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RYWBNT536bM=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5RYWBNj56ll8=", + "_parent": { + "$ref": "AAAAAAF5RYWBNj55r2s=" + }, + "model": { + "$ref": "AAAAAAF5RYWBNT536bM=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5RYWBNj57vDo=", + "_parent": { + "$ref": "AAAAAAF5RYWBNj56ll8=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RYWBNj582Gg=", + "_parent": { + "$ref": "AAAAAAF5RYWBNj56ll8=" + }, + "fillColor": "#ffff91", + "font": "Arial;13;1", + "left": 167.5, + "top": 1403.5, + "width": 155, + "height": 13, + "text": "检测其他测回是否有空数据" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RYWBNj59CIs=", + "_parent": { + "$ref": "AAAAAAF5RYWBNj56ll8=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "width": 73.67724609375, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RYWBNj5+a6c=", + "_parent": { + "$ref": "AAAAAAF5RYWBNj56ll8=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 162.5, + "top": 1396.5, + "width": 166, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5RYWBNj57vDo=" + }, + "nameLabel": { + "$ref": "AAAAAAF5RYWBNj582Gg=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5RYWBNj59CIs=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RYWBNj5+a6c=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5RYWBNj5/meo=", + "_parent": { + "$ref": "AAAAAAF5RYWBNj55r2s=" + }, + "model": { + "$ref": "AAAAAAF5RYWBNT536bM=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5RYWBNj6ApFY=", + "_parent": { + "$ref": "AAAAAAF5RYWBNj55r2s=" + }, + "model": { + "$ref": "AAAAAAF5RYWBNT536bM=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5RYWBNj6BKos=", + "_parent": { + "$ref": "AAAAAAF5RYWBNj55r2s=" + }, + "model": { + "$ref": "AAAAAAF5RYWBNT536bM=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5RYWBNj6CyfU=", + "_parent": { + "$ref": "AAAAAAF5RYWBNj55r2s=" + }, + "model": { + "$ref": "AAAAAAF5RYWBNT536bM=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5RYWBNj6DzGw=", + "_parent": { + "$ref": "AAAAAAF5RYWBNj55r2s=" + }, + "model": { + "$ref": "AAAAAAF5RYWBNT536bM=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 128, + "top": 1392, + "width": 234, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5RYWBNj56ll8=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5RYWBNj5/meo=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5RYWBNj6ApFY=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5RYWBNj6BKos=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5RYWBNj6CyfU=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5RYWBNj6DzGw=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RYXKoUPzfpc=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RYXKoEPvmVE=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYXKoUP0Xm4=", + "_parent": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "model": { + "$ref": "AAAAAAF5RYXKoEPvmVE=" + }, + "font": "Arial;13;0", + "left": 205, + "top": 1219, + "width": 20.591796875, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "edgePosition": 1, + "text": "+无" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYXKoUP1/8o=", + "_parent": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "model": { + "$ref": "AAAAAAF5RYXKoEPvmVE=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 230, + "top": 1215, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYXKoUP2TmE=", + "_parent": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "model": { + "$ref": "AAAAAAF5RYXKoEPvmVE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 186, + "top": 1226, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYXKoUP3dpE=", + "_parent": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "model": { + "$ref": "AAAAAAF5RYXKoUPwWeY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 183, + "top": 1082, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYXKoUP4Dks=", + "_parent": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "model": { + "$ref": "AAAAAAF5RYXKoUPwWeY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 197, + "top": 1081, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYXKoUP5sn0=", + "_parent": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "model": { + "$ref": "AAAAAAF5RYXKoUPwWeY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 155, + "top": 1084, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYXKoUP6dKk=", + "_parent": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "model": { + "$ref": "AAAAAAF5RYXKoUPxCsE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 248, + "top": 1356, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYXKoUP7hGo=", + "_parent": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "model": { + "$ref": "AAAAAAF5RYXKoUPxCsE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 260, + "top": 1350, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYXKoUP8Pbs=", + "_parent": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "model": { + "$ref": "AAAAAAF5RYXKoUPxCsE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 222, + "top": 1366, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RYXKoUP9qJ8=", + "_parent": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "model": { + "$ref": "AAAAAAF5RYXKoUPwWeY=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RYXKokP+OFo=", + "_parent": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "model": { + "$ref": "AAAAAAF5RYXKoUPxCsE=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5RYWBNj55r2s=" + }, + "tail": { + "$ref": "AAAAAAF5RX4IzuDknh4=" + }, + "lineStyle": 1, + "points": "163:1067;240:1391", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RYXKoUP0Xm4=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RYXKoUP1/8o=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RYXKoUP2TmE=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RYXKoUP3dpE=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RYXKoUP4Dks=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RYXKoUP5sn0=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RYXKoUP6dKk=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RYXKoUP7hGo=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RYXKoUP8Pbs=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RYXKoUP9qJ8=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RYXKokP+OFo=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RYbKCEsNrL8=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RYbKCEsJsiQ=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYbKCEsOHZ0=", + "_parent": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "model": { + "$ref": "AAAAAAF5RYbKCEsJsiQ=" + }, + "font": "Arial;13;0", + "left": 264, + "top": 1300, + "width": 20.591796875, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "edgePosition": 1, + "text": "+有" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYbKCEsP+kM=", + "_parent": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "model": { + "$ref": "AAAAAAF5RYbKCEsJsiQ=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 260, + "top": 1294, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYbKCEsQdPM=", + "_parent": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "model": { + "$ref": "AAAAAAF5RYbKCEsJsiQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 301, + "top": 1313, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYbKCEsRxi0=", + "_parent": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "model": { + "$ref": "AAAAAAF5RYbKCEsKkG0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 249, + "top": 1355, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYbKCEsSIa0=", + "_parent": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "model": { + "$ref": "AAAAAAF5RYbKCEsKkG0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 238, + "top": 1347, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYbKCEsTIOs=", + "_parent": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "model": { + "$ref": "AAAAAAF5RYbKCEsKkG0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 272, + "top": 1370, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYbKCEsUoUc=", + "_parent": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "model": { + "$ref": "AAAAAAF5RYbKCEsLR+0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 300, + "top": 1246, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYbKCUsVQTY=", + "_parent": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "model": { + "$ref": "AAAAAAF5RYbKCEsLR+0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 287, + "top": 1242, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYbKCUsWC+U=", + "_parent": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "model": { + "$ref": "AAAAAAF5RYbKCEsLR+0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 327, + "top": 1253, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RYbKCUsX4lU=", + "_parent": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "model": { + "$ref": "AAAAAAF5RYbKCEsKkG0=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RYbKCUsYcdA=", + "_parent": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "model": { + "$ref": "AAAAAAF5RYbKCEsLR+0=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5RX8e8+6VSP4=" + }, + "tail": { + "$ref": "AAAAAAF5RYWBNj55r2s=" + }, + "lineStyle": 1, + "points": "252:1391;325:1235", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RYbKCEsOHZ0=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RYbKCEsP+kM=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RYbKCEsQdPM=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RYbKCEsRxi0=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RYbKCEsSIa0=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RYbKCEsTIOs=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RYbKCEsUoUc=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RYbKCUsVQTY=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RYbKCUsWC+U=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RYbKCUsX4lU=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RYbKCUsYcdA=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5RYo1sZrzoek=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RYo1sJrxVxU=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5RYo1sZr0KlU=", + "_parent": { + "$ref": "AAAAAAF5RYo1sZrzoek=" + }, + "model": { + "$ref": "AAAAAAF5RYo1sJrxVxU=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5RYo1sZr1HjQ=", + "_parent": { + "$ref": "AAAAAAF5RYo1sZr0KlU=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -32, + "top": -160, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RYo1sZr2W5c=", + "_parent": { + "$ref": "AAAAAAF5RYo1sZr0KlU=" + }, + "fillColor": "#ffff91", + "font": "Arial;13;1", + "left": 623.5, + "top": 1275.5, + "width": 116, + "height": 13, + "text": "检测其他测回合法性" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RYo1sZr3XYs=", + "_parent": { + "$ref": "AAAAAAF5RYo1sZr0KlU=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -32, + "top": -160, + "width": 73.67724609375, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RYo1sZr4E80=", + "_parent": { + "$ref": "AAAAAAF5RYo1sZr0KlU=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -32, + "top": -160, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 618.5, + "top": 1268.5, + "width": 127, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5RYo1sZr1HjQ=" + }, + "nameLabel": { + "$ref": "AAAAAAF5RYo1sZr2W5c=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5RYo1sZr3XYs=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RYo1sZr4E80=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5RYo1sZr5VvI=", + "_parent": { + "$ref": "AAAAAAF5RYo1sZrzoek=" + }, + "model": { + "$ref": "AAAAAAF5RYo1sJrxVxU=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -16, + "top": -80, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5RYo1sZr6Veg=", + "_parent": { + "$ref": "AAAAAAF5RYo1sZrzoek=" + }, + "model": { + "$ref": "AAAAAAF5RYo1sJrxVxU=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -16, + "top": -80, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5RYo1sZr7Dv4=", + "_parent": { + "$ref": "AAAAAAF5RYo1sZrzoek=" + }, + "model": { + "$ref": "AAAAAAF5RYo1sJrxVxU=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -16, + "top": -80, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5RYo1sZr8TjI=", + "_parent": { + "$ref": "AAAAAAF5RYo1sZrzoek=" + }, + "model": { + "$ref": "AAAAAAF5RYo1sJrxVxU=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -16, + "top": -80, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5RYo1sZr9JcM=", + "_parent": { + "$ref": "AAAAAAF5RYo1sZrzoek=" + }, + "model": { + "$ref": "AAAAAAF5RYo1sJrxVxU=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -16, + "top": -80, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 592, + "top": 1264, + "width": 179, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5RYo1sZr0KlU=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5RYo1sZr5VvI=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5RYo1sZr6Veg=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5RYo1sZr7Dv4=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5RYo1sZr8TjI=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5RYo1sZr9JcM=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RYqgkqO2MyI=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RYqgkaOybww=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYqgkqO3BkI=", + "_parent": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "model": { + "$ref": "AAAAAAF5RYqgkaOybww=" + }, + "font": "Arial;13;0", + "left": 428, + "top": 1324, + "width": 59.591796875, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "edgePosition": 1, + "text": "+无空测回" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYqgkqO4B50=", + "_parent": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "model": { + "$ref": "AAAAAAF5RYqgkaOybww=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 453, + "top": 1310, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYqgkqO5Eu4=", + "_parent": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "model": { + "$ref": "AAAAAAF5RYqgkaOybww=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 466, + "top": 1353, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYqgkqO6Q3U=", + "_parent": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "model": { + "$ref": "AAAAAAF5RYqgkaOzOcA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 325, + "top": 1363, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYqgkqO7HyE=", + "_parent": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "model": { + "$ref": "AAAAAAF5RYqgkaOzOcA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 324, + "top": 1349, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYqgkqO8jmg=", + "_parent": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "model": { + "$ref": "AAAAAAF5RYqgkaOzOcA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 329, + "top": 1390, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYqgkqO9LA0=", + "_parent": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "model": { + "$ref": "AAAAAAF5RYqgkaO0Gyw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 590, + "top": 1285, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYqgkqO+vZw=", + "_parent": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "model": { + "$ref": "AAAAAAF5RYqgkaO0Gyw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 584, + "top": 1273, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYqgkqO/OQc=", + "_parent": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "model": { + "$ref": "AAAAAAF5RYqgkaO0Gyw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 602, + "top": 1311, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RYqgkqPAF8U=", + "_parent": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "model": { + "$ref": "AAAAAAF5RYqgkaOzOcA=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RYqgkqPBTIk=", + "_parent": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "model": { + "$ref": "AAAAAAF5RYqgkaO0Gyw=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5RYo1sZrzoek=" + }, + "tail": { + "$ref": "AAAAAAF5RYWBNj55r2s=" + }, + "lineStyle": 1, + "points": "305:1391;620:1299", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RYqgkqO3BkI=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RYqgkqO4B50=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RYqgkqO5Eu4=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RYqgkqO6Q3U=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RYqgkqO7HyE=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RYqgkqO8jmg=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RYqgkqO9LA0=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RYqgkqO+vZw=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RYqgkqO/OQc=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RYqgkqPAF8U=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RYqgkqPBTIk=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RYuGzq0zcW0=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RYuGza0vDqU=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYuGzq00uWc=", + "_parent": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "model": { + "$ref": "AAAAAAF5RYuGza0vDqU=" + }, + "font": "Arial;13;0", + "left": 1017, + "top": 1104, + "width": 137.591796875, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "edgePosition": 1, + "text": "+发现有测回未通过检测" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYuGzq01kJ4=", + "_parent": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "model": { + "$ref": "AAAAAAF5RYuGza0vDqU=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1080, + "top": 1090, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYuGzq02LjQ=", + "_parent": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "model": { + "$ref": "AAAAAAF5RYuGza0vDqU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1096, + "top": 1133, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYuGzq03E1k=", + "_parent": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "model": { + "$ref": "AAAAAAF5RYuGza0wl4I=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 746, + "top": 1233, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYuGzq044hU=", + "_parent": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "model": { + "$ref": "AAAAAAF5RYuGza0wl4I=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 744, + "top": 1220, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYuGzq05NGE=", + "_parent": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "model": { + "$ref": "AAAAAAF5RYuGza0wl4I=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 752, + "top": 1260, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYuGzq06xW4=", + "_parent": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "model": { + "$ref": "AAAAAAF5RYuGza0xzjs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1424, + "top": 976, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYuGzq07gn8=", + "_parent": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "model": { + "$ref": "AAAAAAF5RYuGza0xzjs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1417, + "top": 964, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYuGzq08/Nc=", + "_parent": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "model": { + "$ref": "AAAAAAF5RYuGza0xzjs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1438, + "top": 1000, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RYuGzq09BO0=", + "_parent": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "model": { + "$ref": "AAAAAAF5RYuGza0wl4I=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RYuGzq0+Fys=", + "_parent": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "model": { + "$ref": "AAAAAAF5RYuGza0xzjs=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QKuCwkzY630=" + }, + "tail": { + "$ref": "AAAAAAF5RYo1sZrzoek=" + }, + "lineStyle": 1, + "points": "728:1263;1454:987", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RYuGzq00uWc=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RYuGzq01kJ4=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RYuGzq02LjQ=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RYuGzq03E1k=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RYuGzq044hU=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RYuGzq05NGE=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RYuGzq06xW4=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RYuGzq07gn8=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RYuGzq08/Nc=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RYuGzq09BO0=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RYuGzq0+Fys=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RY5M47VS/5M=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RY5M4rVOVIM=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY5M47VTDWg=", + "_parent": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "model": { + "$ref": "AAAAAAF5RY5M4rVOVIM=" + }, + "font": "Arial;13;0", + "left": 508, + "top": 883, + "width": 85.591796875, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "edgePosition": 1, + "text": "+全部通过检测" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY5M47VUjKA=", + "_parent": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "model": { + "$ref": "AAAAAAF5RY5M4rVOVIM=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 536, + "top": 887, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY5M5LVVTlw=", + "_parent": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "model": { + "$ref": "AAAAAAF5RY5M4rVOVIM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 579, + "top": 874, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY5M5LVWBPw=", + "_parent": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "model": { + "$ref": "AAAAAAF5RY5M4rVPReU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 654, + "top": 1236, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY5M5LVX2xY=", + "_parent": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "model": { + "$ref": "AAAAAAF5RY5M4rVPReU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 640, + "top": 1237, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY5M5LVYskw=", + "_parent": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "model": { + "$ref": "AAAAAAF5RY5M4rVPReU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 681, + "top": 1232, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY5M5LVZo0A=", + "_parent": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "model": { + "$ref": "AAAAAAF5RY5M4rVQGdM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 446, + "top": 530, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY5M5LVaI9U=", + "_parent": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "model": { + "$ref": "AAAAAAF5RY5M4rVQGdM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 434, + "top": 536, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY5M5LVbdjo=", + "_parent": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "model": { + "$ref": "AAAAAAF5RY5M4rVQGdM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 472, + "top": 518, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RY5M5LVcoPg=", + "_parent": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "model": { + "$ref": "AAAAAAF5RY5M4rVPReU=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RY5M5LVdBDo=", + "_parent": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "model": { + "$ref": "AAAAAAF5RY5M4rVQGdM=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QJjLZRML/gk=" + }, + "tail": { + "$ref": "AAAAAAF5RYo1sZrzoek=" + }, + "lineStyle": 1, + "points": "676:1263;454:507", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RY5M47VTDWg=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RY5M47VUjKA=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RY5M5LVVTlw=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RY5M5LVWBPw=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RY5M5LVX2xY=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RY5M5LVYskw=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RY5M5LVZo0A=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RY5M5LVaI9U=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RY5M5LVbdjo=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RY5M5LVcoPg=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RY5M5LVdBDo=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5RY+P3cq78x4=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RY+P3cq56es=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5RY+P3cq8lrU=", + "_parent": { + "$ref": "AAAAAAF5RY+P3cq78x4=" + }, + "model": { + "$ref": "AAAAAAF5RY+P3cq56es=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5RY+P3cq9UVw=", + "_parent": { + "$ref": "AAAAAAF5RY+P3cq8lrU=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": -384, + "top": -48, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RY+P3cq+inU=", + "_parent": { + "$ref": "AAAAAAF5RY+P3cq8lrU=" + }, + "fillColor": "#8282ff", + "font": "Arial;13;1", + "left": 860.5, + "top": 1283.5, + "width": 101, + "height": 13, + "text": "switchState2Idle" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RY+P3cq/1Xo=", + "_parent": { + "$ref": "AAAAAAF5RY+P3cq8lrU=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": -384, + "top": -48, + "width": 73.67724609375, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RY+P3crAIoY=", + "_parent": { + "$ref": "AAAAAAF5RY+P3cq8lrU=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": -384, + "top": -48, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 855.5, + "top": 1276.5, + "width": 111.8671875, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5RY+P3cq9UVw=" + }, + "nameLabel": { + "$ref": "AAAAAAF5RY+P3cq+inU=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5RY+P3cq/1Xo=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RY+P3crAIoY=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5RY+P3srBu6A=", + "_parent": { + "$ref": "AAAAAAF5RY+P3cq78x4=" + }, + "model": { + "$ref": "AAAAAAF5RY+P3cq56es=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": -192, + "top": -24, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5RY+P3srCnMw=", + "_parent": { + "$ref": "AAAAAAF5RY+P3cq78x4=" + }, + "model": { + "$ref": "AAAAAAF5RY+P3cq56es=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": -192, + "top": -24, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5RY+P3srDTrA=", + "_parent": { + "$ref": "AAAAAAF5RY+P3cq78x4=" + }, + "model": { + "$ref": "AAAAAAF5RY+P3cq56es=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": -192, + "top": -24, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5RY+P3srE+P0=", + "_parent": { + "$ref": "AAAAAAF5RY+P3cq78x4=" + }, + "model": { + "$ref": "AAAAAAF5RY+P3cq56es=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": -192, + "top": -24, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5RY+P3srFRq4=", + "_parent": { + "$ref": "AAAAAAF5RY+P3cq78x4=" + }, + "model": { + "$ref": "AAAAAAF5RY+P3cq56es=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": -192, + "top": -24, + "width": 10, + "height": 10 + } + ], + "fillColor": "#8282ff", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 832, + "top": 1272, + "width": 158, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5RY+P3cq8lrU=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5RY+P3srBu6A=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5RY+P3srCnMw=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5RY+P3srDTrA=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5RY+P3srE+P0=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5RY+P3srFRq4=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RY/lW9HunTY=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RY/lWtHqafY=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY/lW9Hvi/A=", + "_parent": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "model": { + "$ref": "AAAAAAF5RY/lWtHqafY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 837, + "top": 877, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY/lW9Hw6yM=", + "_parent": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "model": { + "$ref": "AAAAAAF5RY/lWtHqafY=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 822, + "top": 879, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY/lW9Hx5k8=", + "_parent": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "model": { + "$ref": "AAAAAAF5RY/lWtHqafY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 866, + "top": 872, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY/lW9HyN1A=", + "_parent": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "model": { + "$ref": "AAAAAAF5RY/lW9Hrql4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 888, + "top": 1241, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY/lW9Hz89k=", + "_parent": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "model": { + "$ref": "AAAAAAF5RY/lW9Hrql4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 875, + "top": 1240, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY/lW9H0J0I=", + "_parent": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "model": { + "$ref": "AAAAAAF5RY/lW9Hrql4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 916, + "top": 1241, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY/lW9H1ErY=", + "_parent": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "model": { + "$ref": "AAAAAAF5RY/lW9HsN84=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 785, + "top": 512, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY/lW9H23xw=", + "_parent": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "model": { + "$ref": "AAAAAAF5RY/lW9HsN84=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 772, + "top": 516, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY/lW9H3Onc=", + "_parent": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "model": { + "$ref": "AAAAAAF5RY/lW9HsN84=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 812, + "top": 504, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RY/lW9H46uE=", + "_parent": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "model": { + "$ref": "AAAAAAF5RY/lW9Hrql4=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RY/lW9H5+K0=", + "_parent": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "model": { + "$ref": "AAAAAAF5RY/lW9HsN84=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5P5/CAk98zZc=" + }, + "tail": { + "$ref": "AAAAAAF5RY+P3cq78x4=" + }, + "lineStyle": 1, + "points": "907:1271;797:491", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RY/lW9Hvi/A=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RY/lW9Hw6yM=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RY/lW9Hx5k8=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RY/lW9HyN1A=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RY/lW9Hz89k=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RY/lW9H0J0I=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RY/lW9H1ErY=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RY/lW9H23xw=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RY/lW9H3Onc=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RY/lW9H46uE=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RY/lW9H5+K0=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5RZAQqNi9KXs=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RZAQp9i7BLM=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5RZAQqNi+U5k=", + "_parent": { + "$ref": "AAAAAAF5RZAQqNi9KXs=" + }, + "model": { + "$ref": "AAAAAAF5RZAQp9i7BLM=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5RZAQqNi/3K4=", + "_parent": { + "$ref": "AAAAAAF5RZAQqNi+U5k=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -240, + "top": 160, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RZAQqNjAnDw=", + "_parent": { + "$ref": "AAAAAAF5RZAQqNi+U5k=" + }, + "fillColor": "#ffff91", + "font": "Arial;13;1", + "left": 834, + "top": 1467.5, + "width": 90, + "height": 13, + "text": "查找待补测数据" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RZAQqNjB74E=", + "_parent": { + "$ref": "AAAAAAF5RZAQqNi+U5k=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -240, + "top": 160, + "width": 73.67724609375, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RZAQqNjCvdQ=", + "_parent": { + "$ref": "AAAAAAF5RZAQqNi+U5k=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -240, + "top": 160, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 829, + "top": 1460.5, + "width": 101, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5RZAQqNi/3K4=" + }, + "nameLabel": { + "$ref": "AAAAAAF5RZAQqNjAnDw=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5RZAQqNjB74E=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RZAQqNjCvdQ=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5RZAQqNjDBLs=", + "_parent": { + "$ref": "AAAAAAF5RZAQqNi9KXs=" + }, + "model": { + "$ref": "AAAAAAF5RZAQp9i7BLM=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -120, + "top": 80, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5RZAQqNjEOXs=", + "_parent": { + "$ref": "AAAAAAF5RZAQqNi9KXs=" + }, + "model": { + "$ref": "AAAAAAF5RZAQp9i7BLM=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -120, + "top": 80, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5RZAQqNjF53M=", + "_parent": { + "$ref": "AAAAAAF5RZAQqNi9KXs=" + }, + "model": { + "$ref": "AAAAAAF5RZAQp9i7BLM=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -120, + "top": 80, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5RZAQqNjGCMk=", + "_parent": { + "$ref": "AAAAAAF5RZAQqNi9KXs=" + }, + "model": { + "$ref": "AAAAAAF5RZAQp9i7BLM=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -120, + "top": 80, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5RZAQqNjHp8s=", + "_parent": { + "$ref": "AAAAAAF5RZAQqNi9KXs=" + }, + "model": { + "$ref": "AAAAAAF5RZAQp9i7BLM=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -120, + "top": 80, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 808, + "top": 1456, + "width": 142, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5RZAQqNi+U5k=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5RZAQqNjDBLs=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5RZAQqNjEOXs=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5RZAQqNjF53M=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5RZAQqNjGCMk=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5RZAQqNjHp8s=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RZDsue7ftRY=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RZDsue7baAw=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZDsue7gCik=", + "_parent": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "model": { + "$ref": "AAAAAAF5RZDsue7baAw=" + }, + "font": "Arial;13;0", + "left": 869, + "top": 1372, + "width": 20.591796875, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "edgePosition": 1, + "text": "+有" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZDsue7h1YU=", + "_parent": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "model": { + "$ref": "AAAAAAF5RZDsue7baAw=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 864, + "top": 1369, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZDsue7iQis=", + "_parent": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "model": { + "$ref": "AAAAAAF5RZDsue7baAw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 908, + "top": 1377, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZDsue7jDYo=", + "_parent": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "model": { + "$ref": "AAAAAAF5RZDsue7cAPs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 870, + "top": 1420, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZDsue7kyAA=", + "_parent": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "model": { + "$ref": "AAAAAAF5RZDsue7cAPs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 858, + "top": 1416, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZDsue7ll8Q=", + "_parent": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "model": { + "$ref": "AAAAAAF5RZDsue7cAPs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 897, + "top": 1429, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZDsue7mtW0=", + "_parent": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "model": { + "$ref": "AAAAAAF5RZDsue7dBLs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 887, + "top": 1323, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZDsue7n/oo=", + "_parent": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "model": { + "$ref": "AAAAAAF5RZDsue7dBLs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 874, + "top": 1323, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZDsue7oje8=", + "_parent": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "model": { + "$ref": "AAAAAAF5RZDsue7dBLs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 915, + "top": 1324, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RZDsue7pTkA=", + "_parent": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "model": { + "$ref": "AAAAAAF5RZDsue7cAPs=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RZDsue7qLNI=", + "_parent": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "model": { + "$ref": "AAAAAAF5RZDsue7dBLs=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5RY+P3cq78x4=" + }, + "tail": { + "$ref": "AAAAAAF5RZAQqNi9KXs=" + }, + "lineStyle": 1, + "points": "881:1455;907:1307", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RZDsue7gCik=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RZDsue7h1YU=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RZDsue7iQis=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RZDsue7jDYo=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RZDsue7kyAA=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RZDsue7ll8Q=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RZDsue7mtW0=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RZDsue7n/oo=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RZDsue7oje8=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RZDsue7pTkA=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RZDsue7qLNI=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5RZEXNfhC2ho=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RZEXNfhA9nA=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5RZEXNfhDeUQ=", + "_parent": { + "$ref": "AAAAAAF5RZEXNfhC2ho=" + }, + "model": { + "$ref": "AAAAAAF5RZEXNfhA9nA=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5RZEXNfhE1JY=", + "_parent": { + "$ref": "AAAAAAF5RZEXNfhDeUQ=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -880, + "top": -96, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RZEXNfhF08s=", + "_parent": { + "$ref": "AAAAAAF5RZEXNfhDeUQ=" + }, + "fillColor": "#ffff91", + "font": "Arial;13;1", + "left": 525, + "top": 1419.5, + "width": 64, + "height": 13, + "text": "查找空数据" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RZEXNfhGZmc=", + "_parent": { + "$ref": "AAAAAAF5RZEXNfhDeUQ=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -880, + "top": -96, + "width": 73.67724609375, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RZEXNfhHCVU=", + "_parent": { + "$ref": "AAAAAAF5RZEXNfhDeUQ=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -880, + "top": -96, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 520, + "top": 1412.5, + "width": 75, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5RZEXNfhE1JY=" + }, + "nameLabel": { + "$ref": "AAAAAAF5RZEXNfhF08s=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5RZEXNfhGZmc=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RZEXNfhHCVU=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5RZEXNfhIvoY=", + "_parent": { + "$ref": "AAAAAAF5RZEXNfhC2ho=" + }, + "model": { + "$ref": "AAAAAAF5RZEXNfhA9nA=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -440, + "top": -48, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5RZEXNvhJXeE=", + "_parent": { + "$ref": "AAAAAAF5RZEXNfhC2ho=" + }, + "model": { + "$ref": "AAAAAAF5RZEXNfhA9nA=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -440, + "top": -48, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5RZEXNvhKzwc=", + "_parent": { + "$ref": "AAAAAAF5RZEXNfhC2ho=" + }, + "model": { + "$ref": "AAAAAAF5RZEXNfhA9nA=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -440, + "top": -48, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5RZEXNvhLfS4=", + "_parent": { + "$ref": "AAAAAAF5RZEXNfhC2ho=" + }, + "model": { + "$ref": "AAAAAAF5RZEXNfhA9nA=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -440, + "top": -48, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5RZEXNvhM3lA=", + "_parent": { + "$ref": "AAAAAAF5RZEXNfhC2ho=" + }, + "model": { + "$ref": "AAAAAAF5RZEXNfhA9nA=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -440, + "top": -48, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 504, + "top": 1408, + "width": 106, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5RZEXNfhDeUQ=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5RZEXNfhIvoY=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5RZEXNvhJXeE=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5RZEXNvhKzwc=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5RZEXNvhLfS4=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5RZEXNvhM3lA=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RZE5Jvvk8+0=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RZE5JvvgNmk=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZE5J/vlq9g=", + "_parent": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "model": { + "$ref": "AAAAAAF5RZE5JvvgNmk=" + }, + "font": "Arial;13;0", + "left": 695, + "top": 1455, + "width": 20.591796875, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "edgePosition": 1, + "text": "+无" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZE5J/vm7FE=", + "_parent": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "model": { + "$ref": "AAAAAAF5RZE5JvvgNmk=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 703, + "top": 1470, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZE5J/vn7vY=", + "_parent": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "model": { + "$ref": "AAAAAAF5RZE5JvvgNmk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 710, + "top": 1426, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZE5J/voHLE=", + "_parent": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "model": { + "$ref": "AAAAAAF5RZE5Jvvh7eI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 779, + "top": 1467, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZE5J/vpdnU=", + "_parent": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "model": { + "$ref": "AAAAAAF5RZE5Jvvh7eI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 774, + "top": 1479, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZE5J/vqSPU=", + "_parent": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "model": { + "$ref": "AAAAAAF5RZE5Jvvh7eI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 787, + "top": 1440, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZE5J/vrD3M=", + "_parent": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "model": { + "$ref": "AAAAAAF5RZE5JvviTz0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 633, + "top": 1445, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZE5J/vslRk=", + "_parent": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "model": { + "$ref": "AAAAAAF5RZE5JvviTz0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 633, + "top": 1459, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZE5J/vtins=", + "_parent": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "model": { + "$ref": "AAAAAAF5RZE5JvviTz0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 633, + "top": 1417, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RZE5J/vuuHI=", + "_parent": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "model": { + "$ref": "AAAAAAF5RZE5Jvvh7eI=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RZE5J/vvgB0=", + "_parent": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "model": { + "$ref": "AAAAAAF5RZE5JvviTz0=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5RZEXNfhC2ho=" + }, + "tail": { + "$ref": "AAAAAAF5RZAQqNi9KXs=" + }, + "lineStyle": 1, + "points": "807:1462;610:1433", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RZE5J/vlq9g=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RZE5J/vm7FE=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RZE5J/vn7vY=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RZE5J/voHLE=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RZE5J/vpdnU=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RZE5J/vqSPU=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RZE5J/vrD3M=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RZE5J/vslRk=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RZE5J/vtins=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RZE5J/vuuHI=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RZE5J/vvgB0=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RZGEZgj/XLs=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RZGEZgj773A=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZGEZgkArOw=", + "_parent": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "model": { + "$ref": "AAAAAAF5RZGEZgj773A=" + }, + "font": "Arial;13;0", + "left": 717, + "top": 1336, + "width": 20.591796875, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "edgePosition": 1, + "text": "+有" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZGEZgkB2TY=", + "_parent": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "model": { + "$ref": "AAAAAAF5RZGEZgj773A=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 722, + "top": 1322, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZGEZgkChVo=", + "_parent": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "model": { + "$ref": "AAAAAAF5RZGEZgj773A=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 738, + "top": 1365, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZGEZgkDRjc=", + "_parent": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "model": { + "$ref": "AAAAAAF5RZGEZgj8gpI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 621, + "top": 1377, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZGEZgkERZ0=", + "_parent": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "model": { + "$ref": "AAAAAAF5RZGEZgj8gpI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 619, + "top": 1364, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZGEZgkFONE=", + "_parent": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "model": { + "$ref": "AAAAAAF5RZGEZgj8gpI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 627, + "top": 1404, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZGEZgkGzgA=", + "_parent": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "model": { + "$ref": "AAAAAAF5RZGEZgj9p0E=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 833, + "top": 1296, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZGEZgkHVm4=", + "_parent": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "model": { + "$ref": "AAAAAAF5RZGEZgj9p0E=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 826, + "top": 1284, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZGEZgkIGXU=", + "_parent": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "model": { + "$ref": "AAAAAAF5RZGEZgj9p0E=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 847, + "top": 1320, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RZGEZgkJQgE=", + "_parent": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "model": { + "$ref": "AAAAAAF5RZGEZgj8gpI=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RZGEZgkK2ek=", + "_parent": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "model": { + "$ref": "AAAAAAF5RZGEZgj9p0E=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5RY+P3cq78x4=" + }, + "tail": { + "$ref": "AAAAAAF5RZEXNfhC2ho=" + }, + "lineStyle": 1, + "points": "603:1407;863:1307", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RZGEZgkArOw=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RZGEZgkB2TY=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RZGEZgkChVo=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RZGEZgkDRjc=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RZGEZgkERZ0=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RZGEZgkFONE=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RZGEZgkGzgA=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RZGEZgkHVm4=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RZGEZgkIGXU=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RZGEZgkJQgE=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RZGEZgkK2ek=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RZHb+w38rbY=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RZHb+g34JOw=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZHb+w39z3k=", + "_parent": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "model": { + "$ref": "AAAAAAF5RZHb+g34JOw=" + }, + "font": "Arial;13;0", + "left": 477, + "top": 952, + "width": 20.591796875, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "edgePosition": 1, + "text": "+无" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZHb+w3+E8c=", + "_parent": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "model": { + "$ref": "AAAAAAF5RZHb+g34JOw=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 472, + "top": 954, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZHb+w3/cnc=", + "_parent": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "model": { + "$ref": "AAAAAAF5RZHb+g34JOw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 516, + "top": 949, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZHb+w4A7LA=", + "_parent": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "model": { + "$ref": "AAAAAAF5RZHb+g35LNk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 536, + "top": 1376, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZHb+w4BF6A=", + "_parent": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "model": { + "$ref": "AAAAAAF5RZHb+g35LNk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 522, + "top": 1376, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZHb+w4COx0=", + "_parent": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "model": { + "$ref": "AAAAAAF5RZHb+g35LNk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 563, + "top": 1378, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZHb+w4DS1Q=", + "_parent": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "model": { + "$ref": "AAAAAAF5RZHb+g36Mvo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 439, + "top": 528, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZHb+w4Efb8=", + "_parent": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "model": { + "$ref": "AAAAAAF5RZHb+g36Mvo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 426, + "top": 532, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZHb+w4Fx+M=", + "_parent": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "model": { + "$ref": "AAAAAAF5RZHb+g36Mvo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 465, + "top": 521, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RZHb+w4GxWE=", + "_parent": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "model": { + "$ref": "AAAAAAF5RZHb+g35LNk=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RZHb+w4HFa8=", + "_parent": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "model": { + "$ref": "AAAAAAF5RZHb+g36Mvo=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QJjLZRML/gk=" + }, + "tail": { + "$ref": "AAAAAAF5RZEXNfhC2ho=" + }, + "lineStyle": 1, + "points": "554:1407;451:507", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RZHb+w39z3k=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RZHb+w3+E8c=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RZHb+w3/cnc=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RZHb+w4A7LA=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RZHb+w4BF6A=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RZHb+w4COx0=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RZHb+w4DS1Q=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RZHb+w4Efb8=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RZHb+w4Fx+M=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RZHb+w4GxWE=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RZHb+w4HFa8=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5RZ6XBji6Gjs=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RZ6XBTi4yu4=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5RZ6XBji742g=", + "_parent": { + "$ref": "AAAAAAF5RZ6XBji6Gjs=" + }, + "model": { + "$ref": "AAAAAAF5RZ6XBTi4yu4=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5RZ6XBji84Lo=", + "_parent": { + "$ref": "AAAAAAF5RZ6XBji742g=" + }, + "visible": false, + "font": "Arial;13;0", + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RZ6XBji96yI=", + "_parent": { + "$ref": "AAAAAAF5RZ6XBji742g=" + }, + "font": "Arial;13;1", + "left": 1112, + "top": 1595.5, + "width": 79, + "height": 13, + "text": "doMoveBack" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RZ6XBji+VvE=", + "_parent": { + "$ref": "AAAAAAF5RZ6XBji742g=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 73.67724609375, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RZ6XBji/AjM=", + "_parent": { + "$ref": "AAAAAAF5RZ6XBji742g=" + }, + "visible": false, + "font": "Arial;13;0", + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 1107, + "top": 1588.5, + "width": 90.18994140625, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5RZ6XBji84Lo=" + }, + "nameLabel": { + "$ref": "AAAAAAF5RZ6XBji96yI=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5RZ6XBji+VvE=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RZ6XBji/AjM=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5RZ6XBjjASWk=", + "_parent": { + "$ref": "AAAAAAF5RZ6XBji6Gjs=" + }, + "model": { + "$ref": "AAAAAAF5RZ6XBTi4yu4=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5RZ6XBzjBtGc=", + "_parent": { + "$ref": "AAAAAAF5RZ6XBji6Gjs=" + }, + "model": { + "$ref": "AAAAAAF5RZ6XBTi4yu4=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5RZ6XBzjCvBw=", + "_parent": { + "$ref": "AAAAAAF5RZ6XBji6Gjs=" + }, + "model": { + "$ref": "AAAAAAF5RZ6XBTi4yu4=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5RZ6XBzjD9LY=", + "_parent": { + "$ref": "AAAAAAF5RZ6XBji6Gjs=" + }, + "model": { + "$ref": "AAAAAAF5RZ6XBTi4yu4=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5RZ6XBzjEkZ0=", + "_parent": { + "$ref": "AAAAAAF5RZ6XBji6Gjs=" + }, + "model": { + "$ref": "AAAAAAF5RZ6XBTi4yu4=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 1088, + "top": 1584, + "width": 127, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5RZ6XBji742g=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5RZ6XBjjASWk=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5RZ6XBzjBtGc=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5RZ6XBzjCvBw=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5RZ6XBzjD9LY=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5RZ6XBzjEkZ0=" + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5P5nMrk1mLCw=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "check2C", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5P5saV03F9So=", + "_parent": { + "$ref": "AAAAAAF5P5nMrk1mLCw=" + }, + "name": "通过检测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5P5saV03GReQ=", + "_parent": { + "$ref": "AAAAAAF5P5saV03F9So=" + }, + "reference": { + "$ref": "AAAAAAF5P5nMrk1mLCw=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5P5saV03HrLQ=", + "_parent": { + "$ref": "AAAAAAF5P5saV03F9So=" + }, + "reference": { + "$ref": "AAAAAAF5P5rmBE2WOV0=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5P56tf07Epig=", + "_parent": { + "$ref": "AAAAAAF5P5nMrk1mLCw=" + }, + "name": "未通过检测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5P56tgE7F7Yk=", + "_parent": { + "$ref": "AAAAAAF5P56tf07Epig=" + }, + "reference": { + "$ref": "AAAAAAF5P5nMrk1mLCw=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5P56tgE7GNNA=", + "_parent": { + "$ref": "AAAAAAF5P56tf07Epig=" + }, + "reference": { + "$ref": "AAAAAAF5P56LY06KFIA=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5P5rmBE2WOV0=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "recordClean" + }, + { + "_type": "UMLUseCaseSubject", + "_id": "AAAAAAF5P5vlT04vpIc=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "用户选择操作" + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5P56LY06KFIA=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "【用户选择操作】", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5P5/ask/ASWM=", + "_parent": { + "$ref": "AAAAAAF5P56LY06KFIA=" + }, + "name": "选择忽略or重测目标", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5P5/ask/BASE=", + "_parent": { + "$ref": "AAAAAAF5P5/ask/ASWM=" + }, + "reference": { + "$ref": "AAAAAAF5P56LY06KFIA=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5P5/ask/CwwU=", + "_parent": { + "$ref": "AAAAAAF5P5/ask/ASWM=" + }, + "reference": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5P6ETu1Fsgo0=", + "_parent": { + "$ref": "AAAAAAF5P56LY06KFIA=" + }, + "name": "重测测回", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5P6ETu1FtUvs=", + "_parent": { + "$ref": "AAAAAAF5P6ETu1Fsgo0=" + }, + "reference": { + "$ref": "AAAAAAF5P56LY06KFIA=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5P6ETu1Fuzfc=", + "_parent": { + "$ref": "AAAAAAF5P6ETu1Fsgo0=" + }, + "reference": { + "$ref": "AAAAAAF5P6Btl1DQYFs=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5P5/CAk96MB0=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "Idle" + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5P6Btl1DQYFs=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "【提示用户是否确定删除整个测回】", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5P6HZl1I+eIg=", + "_parent": { + "$ref": "AAAAAAF5P6Btl1DQYFs=" + }, + "name": "选择忽略or取消", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5P6HZl1I/u/s=", + "_parent": { + "$ref": "AAAAAAF5P6HZl1I+eIg=" + }, + "reference": { + "$ref": "AAAAAAF5P6Btl1DQYFs=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5P6HZl1JAt1Q=", + "_parent": { + "$ref": "AAAAAAF5P6HZl1I+eIg=" + }, + "reference": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5P6Jc6FP89fs=", + "_parent": { + "$ref": "AAAAAAF5P6Btl1DQYFs=" + }, + "name": "确认删除", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5P6Jc6FP9Ay0=", + "_parent": { + "$ref": "AAAAAAF5P6Jc6FP89fs=" + }, + "reference": { + "$ref": "AAAAAAF5P6Btl1DQYFs=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5P6Jc6FP+W/w=", + "_parent": { + "$ref": "AAAAAAF5P6Jc6FP89fs=" + }, + "reference": { + "$ref": "AAAAAAF5P6IYDFMK28k=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5P6IYDFMK28k=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "【执行删除操作】", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5P6KuWFYuLA4=", + "_parent": { + "$ref": "AAAAAAF5P6IYDFMK28k=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5P6KuWFYvXto=", + "_parent": { + "$ref": "AAAAAAF5P6KuWFYuLA4=" + }, + "reference": { + "$ref": "AAAAAAF5P6IYDFMK28k=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5P6KuWFYwtmg=", + "_parent": { + "$ref": "AAAAAAF5P6KuWFYuLA4=" + }, + "reference": { + "$ref": "AAAAAAF5QMaQUG/pf+g=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5P6I/oFN00qM=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "重新搜索目标开启新一轮测量", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QJXgiQky2RI=", + "_parent": { + "$ref": "AAAAAAF5P6I/oFN00qM=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QJXgiQkzVQM=", + "_parent": { + "$ref": "AAAAAAF5QJXgiQky2RI=" + }, + "reference": { + "$ref": "AAAAAAF5P6I/oFN00qM=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QJXgiQk0kU4=", + "_parent": { + "$ref": "AAAAAAF5QJXgiQky2RI=" + }, + "reference": { + "$ref": "AAAAAAF5QJWvCggxZrM=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5QJWvCggxZrM=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "move2NextValidate", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RVWv2lZqu2A=", + "_parent": { + "$ref": "AAAAAAF5QJWvCggxZrM=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RVWv2lZro+8=", + "_parent": { + "$ref": "AAAAAAF5RVWv2lZqu2A=" + }, + "reference": { + "$ref": "AAAAAAF5QJWvCggxZrM=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RVWv2lZs/XI=", + "_parent": { + "$ref": "AAAAAAF5RVWv2lZqu2A=" + }, + "reference": { + "$ref": "AAAAAAF5RZAQp9i7BLM=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5QJc4CA2m0sA=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "checkHalfCycleZero", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QJesYRAUeZI=", + "_parent": { + "$ref": "AAAAAAF5QJc4CA2m0sA=" + }, + "name": "测站不闭合or半测回归零差正常", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QJesYRAV/Pw=", + "_parent": { + "$ref": "AAAAAAF5QJesYRAUeZI=" + }, + "reference": { + "$ref": "AAAAAAF5QJc4CA2m0sA=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QJesYRAWIno=", + "_parent": { + "$ref": "AAAAAAF5QJesYRAUeZI=" + }, + "reference": { + "$ref": "AAAAAAF5QJeXAw9WAQQ=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QJmQwBdscKg=", + "_parent": { + "$ref": "AAAAAAF5QJc4CA2m0sA=" + }, + "name": "没有通过检测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QJmQwBdt/Nk=", + "_parent": { + "$ref": "AAAAAAF5QJmQwBdscKg=" + }, + "reference": { + "$ref": "AAAAAAF5QJc4CA2m0sA=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QJmQwBdu0wk=", + "_parent": { + "$ref": "AAAAAAF5QJmQwBdscKg=" + }, + "reference": { + "$ref": "AAAAAAF5QJk5ohVWyGc=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5QJeXAw9WAQQ=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "isReady2CCheck" + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5QJjLZBMJQJ8=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "switchState2StandStill", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QJnk3RnjFKU=", + "_parent": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QJnk3Rnk4S8=", + "_parent": { + "$ref": "AAAAAAF5QJnk3RnjFKU=" + }, + "reference": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QJnk3Rnlvxc=", + "_parent": { + "$ref": "AAAAAAF5QJnk3RnjFKU=" + }, + "reference": { + "$ref": "AAAAAAF5P5/CAk96MB0=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5QJk5ohVWyGc=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "提示半测回归零检测失败", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QJnHsRkKHYc=", + "_parent": { + "$ref": "AAAAAAF5QJk5ohVWyGc=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QJnHsRkLdTo=", + "_parent": { + "$ref": "AAAAAAF5QJnHsRkKHYc=" + }, + "reference": { + "$ref": "AAAAAAF5QJk5ohVWyGc=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QJnHsRkM5N4=", + "_parent": { + "$ref": "AAAAAAF5QJnHsRkKHYc=" + }, + "reference": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5QJ6ahSPVJNg=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "checkReadData", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QJ87Oyj+dCg=", + "_parent": { + "$ref": "AAAAAAF5QJ6ahSPVJNg=" + }, + "name": "单测量or通过检测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QJ87Oyj/TJQ=", + "_parent": { + "$ref": "AAAAAAF5QJ87Oyj+dCg=" + }, + "reference": { + "$ref": "AAAAAAF5QJ6ahSPVJNg=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QJ87OykA4RY=", + "_parent": { + "$ref": "AAAAAAF5QJ87Oyj+dCg=" + }, + "reference": { + "$ref": "AAAAAAF5QJ8m8Sf4R1w=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QJ/Ugywh52g=", + "_parent": { + "$ref": "AAAAAAF5QJ6ahSPVJNg=" + }, + "name": "未通过检测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QJ/Ugywiha4=", + "_parent": { + "$ref": "AAAAAAF5QJ/Ugywh52g=" + }, + "reference": { + "$ref": "AAAAAAF5QJ6ahSPVJNg=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QJ/UgywjRPE=", + "_parent": { + "$ref": "AAAAAAF5QJ/Ugywh52g=" + }, + "reference": { + "$ref": "AAAAAAF5QJ+mRitXafY=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5QJ8m8Sf4R1w=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "isHalfCycleZeroCheckReady" + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5QJ+mRitXafY=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "提示读数有误", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QJ/0PCz+xYo=", + "_parent": { + "$ref": "AAAAAAF5QJ+mRitXafY=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QJ/0PCz/2CU=", + "_parent": { + "$ref": "AAAAAAF5QJ/0PCz+xYo=" + }, + "reference": { + "$ref": "AAAAAAF5QJ+mRitXafY=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QJ/0PC0AjHo=", + "_parent": { + "$ref": "AAAAAAF5QJ/0PCz+xYo=" + }, + "reference": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5QKE6OTfx/D4=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "checkSingleCycle", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QKI4y0KDGow=", + "_parent": { + "$ref": "AAAAAAF5QKE6OTfx/D4=" + }, + "name": "通过检测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QKI4zEKEuw8=", + "_parent": { + "$ref": "AAAAAAF5QKI4y0KDGow=" + }, + "reference": { + "$ref": "AAAAAAF5QKE6OTfx/D4=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QKI4zEKFtZg=", + "_parent": { + "$ref": "AAAAAAF5QKI4y0KDGow=" + }, + "reference": { + "$ref": "AAAAAAF5QKIG+T9Wjdo=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QKvMIE8VEZE=", + "_parent": { + "$ref": "AAAAAAF5QKE6OTfx/D4=" + }, + "name": "未通过检测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QKvMIE8WKCE=", + "_parent": { + "$ref": "AAAAAAF5QKvMIE8VEZE=" + }, + "reference": { + "$ref": "AAAAAAF5QKE6OTfx/D4=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QKvMIE8XsG8=", + "_parent": { + "$ref": "AAAAAAF5QKvMIE8VEZE=" + }, + "reference": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5QKIG+T9Wjdo=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "isAllCycleCompleted" + }, + { + "_type": "UMLUseCaseSubject", + "_id": "AAAAAAF5QKJM6UPX41c=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "UseCaseSubject1" + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5QKuCwkzWMuI=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "提示用户选择", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QK2Ql1lrW/0=", + "_parent": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + }, + "name": "忽略", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QK2Ql1lsCzU=", + "_parent": { + "$ref": "AAAAAAF5QK2Ql1lrW/0=" + }, + "reference": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QK2Ql1ltUBY=", + "_parent": { + "$ref": "AAAAAAF5QK2Ql1lrW/0=" + }, + "reference": { + "$ref": "AAAAAAF5QKzDRVJwpI4=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QLdiW2HmZcI=", + "_parent": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QLdiW2HnzLc=", + "_parent": { + "$ref": "AAAAAAF5QLdiW2HmZcI=" + }, + "reference": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QLdiW2HodP8=", + "_parent": { + "$ref": "AAAAAAF5QLdiW2HmZcI=" + }, + "reference": { + "$ref": "AAAAAAF5QKyR6VB8Gq8=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QMnaf4pzXpA=", + "_parent": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QMnaf4p0R7o=", + "_parent": { + "$ref": "AAAAAAF5QMnaf4pzXpA=" + }, + "reference": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QMnaf4p1n0A=", + "_parent": { + "$ref": "AAAAAAF5QMnaf4pzXpA=" + }, + "reference": { + "$ref": "AAAAAAF5QKysH1F2Xh8=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5QKyR6VB8Gq8=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "重测方向", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QLx6RGoJ91g=", + "_parent": { + "$ref": "AAAAAAF5QKyR6VB8Gq8=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QLx6RGoKxZI=", + "_parent": { + "$ref": "AAAAAAF5QLx6RGoJ91g=" + }, + "reference": { + "$ref": "AAAAAAF5QKyR6VB8Gq8=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QLx6RGoLs1U=", + "_parent": { + "$ref": "AAAAAAF5QLx6RGoJ91g=" + }, + "reference": { + "$ref": "AAAAAAF5QLwOJ2bN7N0=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5QKysH1F2Xh8=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "重测测回", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QNAhapFq3kM=", + "_parent": { + "$ref": "AAAAAAF5QKysH1F2Xh8=" + }, + "name": "取消", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QNAhapFrudc=", + "_parent": { + "$ref": "AAAAAAF5QNAhapFq3kM=" + }, + "reference": { + "$ref": "AAAAAAF5QKysH1F2Xh8=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QNAhapFsZZ8=", + "_parent": { + "$ref": "AAAAAAF5QNAhapFq3kM=" + }, + "reference": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QNFL6qCXEtU=", + "_parent": { + "$ref": "AAAAAAF5QKysH1F2Xh8=" + }, + "name": "忽略", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QNFL6qCY2AQ=", + "_parent": { + "$ref": "AAAAAAF5QNFL6qCXEtU=" + }, + "reference": { + "$ref": "AAAAAAF5QKysH1F2Xh8=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QNFL6qCZ01s=", + "_parent": { + "$ref": "AAAAAAF5QNFL6qCXEtU=" + }, + "reference": { + "$ref": "AAAAAAF5QKzDRVJwpI4=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RVcwNF0hcaI=", + "_parent": { + "$ref": "AAAAAAF5QKysH1F2Xh8=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RVcwNF0iVWE=", + "_parent": { + "$ref": "AAAAAAF5RVcwNF0hcaI=" + }, + "reference": { + "$ref": "AAAAAAF5QKysH1F2Xh8=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RVcwNF0jQf0=", + "_parent": { + "$ref": "AAAAAAF5RVcwNF0hcaI=" + }, + "reference": { + "$ref": "AAAAAAF5RVbpp1nIOnU=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5QKzDRVJwpI4=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "resetSurveyorStateAndKeepPosition", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QK340l0BzRk=", + "_parent": { + "$ref": "AAAAAAF5QKzDRVJwpI4=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QK340l0ChAw=", + "_parent": { + "$ref": "AAAAAAF5QK340l0BzRk=" + }, + "reference": { + "$ref": "AAAAAAF5QKzDRVJwpI4=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QK340l0D79M=", + "_parent": { + "$ref": "AAAAAAF5QK340l0BzRk=" + }, + "reference": { + "$ref": "AAAAAAF5P5/CAk96MB0=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5QLwOJ2bN7N0=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "resurveyPoints", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QMbzEHNMUo0=", + "_parent": { + "$ref": "AAAAAAF5QLwOJ2bN7N0=" + }, + "name": "开始重测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QMbzEHNNh8o=", + "_parent": { + "$ref": "AAAAAAF5QMbzEHNMUo0=" + }, + "reference": { + "$ref": "AAAAAAF5QLwOJ2bN7N0=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QMbzEHNOm6M=", + "_parent": { + "$ref": "AAAAAAF5QMbzEHNMUo0=" + }, + "reference": { + "$ref": "AAAAAAF5QMaQUG/pf+g=" + } + } + }, + { + "_type": "UMLGeneralization", + "_id": "AAAAAAF5QMevPnTKBWs=", + "_parent": { + "$ref": "AAAAAAF5QLwOJ2bN7N0=" + }, + "name": "重测失败", + "source": { + "$ref": "AAAAAAF5QLwOJ2bN7N0=" + }, + "target": { + "$ref": "AAAAAAF5QKzDRVJwpI4=" + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RVTunkvVKUs=", + "_parent": { + "$ref": "AAAAAAF5QLwOJ2bN7N0=" + }, + "name": "重测失败", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RVTun0vWQ0U=", + "_parent": { + "$ref": "AAAAAAF5RVTunkvVKUs=" + }, + "reference": { + "$ref": "AAAAAAF5QLwOJ2bN7N0=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RVTun0vXr0g=", + "_parent": { + "$ref": "AAAAAAF5RVTunkvVKUs=" + }, + "reference": { + "$ref": "AAAAAAF5QKzDRVJwpI4=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5QMaQUG/pf+g=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "switchState2RestartInCurrentCycle", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QMjEpoXtFac=", + "_parent": { + "$ref": "AAAAAAF5QMaQUG/pf+g=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QMjEpoXuicM=", + "_parent": { + "$ref": "AAAAAAF5QMjEpoXtFac=" + }, + "reference": { + "$ref": "AAAAAAF5QMaQUG/pf+g=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QMjEpoXvKNs=", + "_parent": { + "$ref": "AAAAAAF5QMjEpoXtFac=" + }, + "reference": { + "$ref": "AAAAAAF5QJWvCggxZrM=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5RVbpp1nIOnU=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "执行测回删除", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RVdEqWBKDgY=", + "_parent": { + "$ref": "AAAAAAF5RVbpp1nIOnU=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RVdEqWBL2Ro=", + "_parent": { + "$ref": "AAAAAAF5RVdEqWBKDgY=" + }, + "reference": { + "$ref": "AAAAAAF5RVbpp1nIOnU=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RVdEqWBMaWs=", + "_parent": { + "$ref": "AAAAAAF5RVdEqWBKDgY=" + }, + "reference": { + "$ref": "AAAAAAF5QMaQUG/pf+g=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5RWbWh5Q82SE=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "doCalScheduleSingleCycle", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RWkDr6/4piw=", + "_parent": { + "$ref": "AAAAAAF5RWbWh5Q82SE=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RWkDr6/5hKI=", + "_parent": { + "$ref": "AAAAAAF5RWkDr6/4piw=" + }, + "reference": { + "$ref": "AAAAAAF5RWbWh5Q82SE=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RWkDr6/6Fyk=", + "_parent": { + "$ref": "AAAAAAF5RWkDr6/4piw=" + }, + "reference": { + "$ref": "AAAAAAF5RWiYh6tdXHE=" + } + } + } + ] + }, + { + "_type": "UMLUseCaseSubject", + "_id": "AAAAAAF5RWdznZ2YK/Q=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "UseCaseSubject2" + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5RWiYh6tdXHE=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "该测回是否完成测量", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RWmAObifwr4=", + "_parent": { + "$ref": "AAAAAAF5RWiYh6tdXHE=" + }, + "name": "未完成", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RWmAObigyuY=", + "_parent": { + "$ref": "AAAAAAF5RWmAObifwr4=" + }, + "reference": { + "$ref": "AAAAAAF5RWiYh6tdXHE=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RWmAObih5u0=", + "_parent": { + "$ref": "AAAAAAF5RWmAObifwr4=" + }, + "reference": { + "$ref": "AAAAAAF5QMaQUG/pf+g=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RWqc8svr3pE=", + "_parent": { + "$ref": "AAAAAAF5RWiYh6tdXHE=" + }, + "name": "完成", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RWqc8svs8AE=", + "_parent": { + "$ref": "AAAAAAF5RWqc8svr3pE=" + }, + "reference": { + "$ref": "AAAAAAF5RWiYh6tdXHE=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RWqc8svtE1U=", + "_parent": { + "$ref": "AAAAAAF5RWqc8svr3pE=" + }, + "reference": { + "$ref": "AAAAAAF5RWo+Icga7No=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5RWo+Icga7No=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "执行单测回检测", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RWvJyNWC314=", + "_parent": { + "$ref": "AAAAAAF5RWo+Icga7No=" + }, + "name": "未通过检测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RWvJyNWDYLg=", + "_parent": { + "$ref": "AAAAAAF5RWvJyNWC314=" + }, + "reference": { + "$ref": "AAAAAAF5RWo+Icga7No=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RWvJyNWEI/s=", + "_parent": { + "$ref": "AAAAAAF5RWvJyNWC314=" + }, + "reference": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RWxGx9n5fHg=", + "_parent": { + "$ref": "AAAAAAF5RWo+Icga7No=" + }, + "name": "通过检测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RWxGx9n6uSs=", + "_parent": { + "$ref": "AAAAAAF5RWxGx9n5fHg=" + }, + "reference": { + "$ref": "AAAAAAF5RWo+Icga7No=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RWxGx9n7A0k=", + "_parent": { + "$ref": "AAAAAAF5RWxGx9n5fHg=" + }, + "reference": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RXgsE81LcLM=", + "_parent": { + "$ref": "AAAAAAF5RWo+Icga7No=" + }, + "name": "通过", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RXgsE81Ml9Y=", + "_parent": { + "$ref": "AAAAAAF5RXgsE81LcLM=" + }, + "reference": { + "$ref": "AAAAAAF5RWo+Icga7No=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RXgsE81Ncj4=", + "_parent": { + "$ref": "AAAAAAF5RXgsE81LcLM=" + }, + "reference": { + "$ref": "AAAAAAF5RXZT3reRJjE=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5RWzzg+QnXQo=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "doCalScheduleAllCycle", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RXS1D5dDHCY=", + "_parent": { + "$ref": "AAAAAAF5RWzzg+QnXQo=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RXS1D5dEJJs=", + "_parent": { + "$ref": "AAAAAAF5RXS1D5dDHCY=" + }, + "reference": { + "$ref": "AAAAAAF5RWzzg+QnXQo=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RXS1D5dF2N4=", + "_parent": { + "$ref": "AAAAAAF5RXS1D5dDHCY=" + }, + "reference": { + "$ref": "AAAAAAF5RWiYh6tdXHE=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5RXZT3reRJjE=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "是否是doCalScheduleAllCycle状态", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RXiiW9aJDaw=", + "_parent": { + "$ref": "AAAAAAF5RXZT3reRJjE=" + }, + "name": "不是", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RXiiW9aKkno=", + "_parent": { + "$ref": "AAAAAAF5RXiiW9aJDaw=" + }, + "reference": { + "$ref": "AAAAAAF5RXZT3reRJjE=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RXiiW9aL3M4=", + "_parent": { + "$ref": "AAAAAAF5RXiiW9aJDaw=" + }, + "reference": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RX50xeaOm84=", + "_parent": { + "$ref": "AAAAAAF5RXZT3reRJjE=" + }, + "name": "是", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RX50xeaPW6s=", + "_parent": { + "$ref": "AAAAAAF5RX50xeaOm84=" + }, + "reference": { + "$ref": "AAAAAAF5RXZT3reRJjE=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RX50xeaQJxA=", + "_parent": { + "$ref": "AAAAAAF5RX50xeaOm84=" + }, + "reference": { + "$ref": "AAAAAAF5RX4IzeDinbw=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5RX4IzeDinbw=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "检测其他测回是否有待补测数据", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RX9EYPFbm2U=", + "_parent": { + "$ref": "AAAAAAF5RX4IzeDinbw=" + }, + "name": "有", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RX9EYPFcd3k=", + "_parent": { + "$ref": "AAAAAAF5RX9EYPFbm2U=" + }, + "reference": { + "$ref": "AAAAAAF5RX4IzeDinbw=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RX9EYPFdtmc=", + "_parent": { + "$ref": "AAAAAAF5RX9EYPFbm2U=" + }, + "reference": { + "$ref": "AAAAAAF5RX8e8+6Tpi8=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RYXKoEPvmVE=", + "_parent": { + "$ref": "AAAAAAF5RX4IzeDinbw=" + }, + "name": "无", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RYXKoUPwWeY=", + "_parent": { + "$ref": "AAAAAAF5RYXKoEPvmVE=" + }, + "reference": { + "$ref": "AAAAAAF5RX4IzeDinbw=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RYXKoUPxCsE=", + "_parent": { + "$ref": "AAAAAAF5RYXKoEPvmVE=" + }, + "reference": { + "$ref": "AAAAAAF5RYWBNT536bM=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5RX8e8+6Tpi8=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "提示用户选择", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RYA6LQaqG8I=", + "_parent": { + "$ref": "AAAAAAF5RX8e8+6Tpi8=" + }, + "name": "跳转到相应测回", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RYA6LQaryvU=", + "_parent": { + "$ref": "AAAAAAF5RYA6LQaqG8I=" + }, + "reference": { + "$ref": "AAAAAAF5RX8e8+6Tpi8=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RYA6LQashgM=", + "_parent": { + "$ref": "AAAAAAF5RYA6LQaqG8I=" + }, + "reference": { + "$ref": "AAAAAAF5RX+92vrrsgo=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RYRxIiqJIUE=", + "_parent": { + "$ref": "AAAAAAF5RX8e8+6Tpi8=" + }, + "name": "忽略或取消", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RYRxIyqKuUY=", + "_parent": { + "$ref": "AAAAAAF5RYRxIiqJIUE=" + }, + "reference": { + "$ref": "AAAAAAF5RX8e8+6Tpi8=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RYRxIyqLN6Y=", + "_parent": { + "$ref": "AAAAAAF5RYRxIiqJIUE=" + }, + "reference": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5RX+92vrrsgo=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "切换测回", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RX/wMv3F6d4=", + "_parent": { + "$ref": "AAAAAAF5RX+92vrrsgo=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RX/wMv3GM64=", + "_parent": { + "$ref": "AAAAAAF5RX/wMv3F6d4=" + }, + "reference": { + "$ref": "AAAAAAF5RX+92vrrsgo=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RX/wMv3HIz8=", + "_parent": { + "$ref": "AAAAAAF5RX/wMv3F6d4=" + }, + "reference": { + "$ref": "AAAAAAF5QMaQUG/pf+g=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5RYWBNT536bM=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "检测其他测回是否有空数据", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RYbKCEsJsiQ=", + "_parent": { + "$ref": "AAAAAAF5RYWBNT536bM=" + }, + "name": "有", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RYbKCEsKkG0=", + "_parent": { + "$ref": "AAAAAAF5RYbKCEsJsiQ=" + }, + "reference": { + "$ref": "AAAAAAF5RYWBNT536bM=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RYbKCEsLR+0=", + "_parent": { + "$ref": "AAAAAAF5RYbKCEsJsiQ=" + }, + "reference": { + "$ref": "AAAAAAF5RX8e8+6Tpi8=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RYqgkaOybww=", + "_parent": { + "$ref": "AAAAAAF5RYWBNT536bM=" + }, + "name": "无空测回", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RYqgkaOzOcA=", + "_parent": { + "$ref": "AAAAAAF5RYqgkaOybww=" + }, + "reference": { + "$ref": "AAAAAAF5RYWBNT536bM=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RYqgkaO0Gyw=", + "_parent": { + "$ref": "AAAAAAF5RYqgkaOybww=" + }, + "reference": { + "$ref": "AAAAAAF5RYo1sJrxVxU=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5RYo1sJrxVxU=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "检测其他测回合法性", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RYuGza0vDqU=", + "_parent": { + "$ref": "AAAAAAF5RYo1sJrxVxU=" + }, + "name": "发现有测回未通过检测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RYuGza0wl4I=", + "_parent": { + "$ref": "AAAAAAF5RYuGza0vDqU=" + }, + "reference": { + "$ref": "AAAAAAF5RYo1sJrxVxU=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RYuGza0xzjs=", + "_parent": { + "$ref": "AAAAAAF5RYuGza0vDqU=" + }, + "reference": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RY5M4rVOVIM=", + "_parent": { + "$ref": "AAAAAAF5RYo1sJrxVxU=" + }, + "name": "全部通过检测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RY5M4rVPReU=", + "_parent": { + "$ref": "AAAAAAF5RY5M4rVOVIM=" + }, + "reference": { + "$ref": "AAAAAAF5RYo1sJrxVxU=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RY5M4rVQGdM=", + "_parent": { + "$ref": "AAAAAAF5RY5M4rVOVIM=" + }, + "reference": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5RY+P3cq56es=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "switchState2Idle", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RY/lWtHqafY=", + "_parent": { + "$ref": "AAAAAAF5RY+P3cq56es=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RY/lW9Hrql4=", + "_parent": { + "$ref": "AAAAAAF5RY/lWtHqafY=" + }, + "reference": { + "$ref": "AAAAAAF5RY+P3cq56es=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RY/lW9HsN84=", + "_parent": { + "$ref": "AAAAAAF5RY/lWtHqafY=" + }, + "reference": { + "$ref": "AAAAAAF5P5/CAk96MB0=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5RZAQp9i7BLM=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "查找待补测数据", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RZDsue7baAw=", + "_parent": { + "$ref": "AAAAAAF5RZAQp9i7BLM=" + }, + "name": "有", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RZDsue7cAPs=", + "_parent": { + "$ref": "AAAAAAF5RZDsue7baAw=" + }, + "reference": { + "$ref": "AAAAAAF5RZAQp9i7BLM=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RZDsue7dBLs=", + "_parent": { + "$ref": "AAAAAAF5RZDsue7baAw=" + }, + "reference": { + "$ref": "AAAAAAF5RY+P3cq56es=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RZE5JvvgNmk=", + "_parent": { + "$ref": "AAAAAAF5RZAQp9i7BLM=" + }, + "name": "无", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RZE5Jvvh7eI=", + "_parent": { + "$ref": "AAAAAAF5RZE5JvvgNmk=" + }, + "reference": { + "$ref": "AAAAAAF5RZAQp9i7BLM=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RZE5JvviTz0=", + "_parent": { + "$ref": "AAAAAAF5RZE5JvvgNmk=" + }, + "reference": { + "$ref": "AAAAAAF5RZEXNfhA9nA=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5RZEXNfhA9nA=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "查找空数据", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RZGEZgj773A=", + "_parent": { + "$ref": "AAAAAAF5RZEXNfhA9nA=" + }, + "name": "有", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RZGEZgj8gpI=", + "_parent": { + "$ref": "AAAAAAF5RZGEZgj773A=" + }, + "reference": { + "$ref": "AAAAAAF5RZEXNfhA9nA=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RZGEZgj9p0E=", + "_parent": { + "$ref": "AAAAAAF5RZGEZgj773A=" + }, + "reference": { + "$ref": "AAAAAAF5RY+P3cq56es=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RZHb+g34JOw=", + "_parent": { + "$ref": "AAAAAAF5RZEXNfhA9nA=" + }, + "name": "无", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RZHb+g35LNk=", + "_parent": { + "$ref": "AAAAAAF5RZHb+g34JOw=" + }, + "reference": { + "$ref": "AAAAAAF5RZEXNfhA9nA=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RZHb+g36Mvo=", + "_parent": { + "$ref": "AAAAAAF5RZHb+g34JOw=" + }, + "reference": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5RZ6XBTi4yu4=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "doMoveBack" + } + ] + }, + { + "_type": "UMLProfile", + "_id": "AAAAAAFElnEzslS1AuE=", + "_parent": { + "$ref": "AAAAAAFElm5XMFNoGY0=" + }, + "name": "UMLStandardProfile", + "ownedElements": [ + { + "_type": "UMLProfileDiagram", + "_id": "AAAAAAFElnFUQFS4mT4=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "StandardProfileL2", + "ownedViews": [ + { + "_type": "UMLMetaClassView", + "_id": "AAAAAAFElnFrT1S8vVg=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFElnFrT1S7Kic=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFElnFrT1S9WOE=", + "_parent": { + "$ref": "AAAAAAFElnFrT1S8vVg=" + }, + "model": { + "$ref": "AAAAAAFElnFrT1S7Kic=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFElnFrT1S+aHM=", + "_parent": { + "$ref": "AAAAAAFElnFrT1S9WOE=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": -44, + "top": -16, + "width": 1, + "height": 12 + }, + { + "_type": "LabelView", + "_id": "AAAAAAFElnFrT1S/1HM=", + "_parent": { + "$ref": "AAAAAAFElnFrT1S9WOE=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 57, + "top": 59, + "width": 81, + "height": 12, + "text": "«metaClass»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFElnFrT1TAD0M=", + "_parent": { + "$ref": "AAAAAAFElnFrT1S9WOE=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;1", + "containerChangeable": true, + "containerExtending": true, + "left": 57, + "top": 73, + "width": 81, + "height": 12, + "text": "UMLClassifier" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFElnFrT1TBaUI=", + "_parent": { + "$ref": "AAAAAAFElnFrT1S9WOE=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": -44, + "top": -16, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFElnFrT1TCF/Y=", + "_parent": { + "$ref": "AAAAAAFElnFrT1S9WOE=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": -44, + "top": -16, + "width": 1, + "height": 12, + "horizontalAlignment": 1 + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 52, + "top": 52, + "width": 91, + "height": 38, + "stereotypeLabel": { + "$ref": "AAAAAAFElnFrT1S/1HM=" + }, + "nameLabel": { + "$ref": "AAAAAAFElnFrT1TAD0M=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFElnFrT1TBaUI=" + }, + "propertyLabel": { + "$ref": "AAAAAAFElnFrT1TCF/Y=" + } + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 52, + "top": 52, + "width": 91, + "height": 101, + "nameCompartment": { + "$ref": "AAAAAAFElnFrT1S9WOE=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFElnF1nFTadPw=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFElnF1nFTY/Sw=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqCEfLOas=", + "_parent": { + "$ref": "AAAAAAFElnF1nFTadPw=" + }, + "model": { + "$ref": "AAAAAAFElnF1nFTY/Sw=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFElnF1nFTbplQ=", + "_parent": { + "$ref": "AAAAAAFElnF1nFTadPw=" + }, + "model": { + "$ref": "AAAAAAFElnF1nFTY/Sw=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFElnF1nVTcCng=", + "_parent": { + "$ref": "AAAAAAFElnF1nFTbplQ=" + }, + "visible": false, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 60, + "top": -116, + "width": 1, + "height": 12 + }, + { + "_type": "LabelView", + "_id": "AAAAAAFElnF1nVTd3xg=", + "_parent": { + "$ref": "AAAAAAFElnF1nFTbplQ=" + }, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 213, + "top": 55, + "width": 83, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFElnF1nVTewJM=", + "_parent": { + "$ref": "AAAAAAFElnF1nFTbplQ=" + }, + "font": "Arial;12;1", + "containerChangeable": true, + "containerExtending": true, + "left": 213, + "top": 69, + "width": 83, + "height": 12, + "text": "Realization" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFElnF1nVTfQRQ=", + "_parent": { + "$ref": "AAAAAAFElnF1nFTbplQ=" + }, + "visible": false, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 60, + "top": -116, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFElnF1nVTgrV8=", + "_parent": { + "$ref": "AAAAAAFElnF1nFTbplQ=" + }, + "visible": false, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 60, + "top": -116, + "width": 1, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 208, + "top": 48, + "width": 93, + "height": 38, + "stereotypeLabel": { + "$ref": "AAAAAAFElnF1nVTd3xg=" + }, + "nameLabel": { + "$ref": "AAAAAAFElnF1nVTewJM=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFElnF1nVTfQRQ=" + }, + "propertyLabel": { + "$ref": "AAAAAAFElnF1nVTgrV8=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFElnF1nVThfqA=", + "_parent": { + "$ref": "AAAAAAFElnF1nFTadPw=" + }, + "model": { + "$ref": "AAAAAAFElnF1nFTY/Sw=" + }, + "visible": false, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 208, + "top": 86, + "width": 93, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFElnF1nVTiFXA=", + "_parent": { + "$ref": "AAAAAAFElnF1nFTadPw=" + }, + "model": { + "$ref": "AAAAAAFElnF1nFTY/Sw=" + }, + "visible": false, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 208, + "top": 96, + "width": 93, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFElnF1nVTjasU=", + "_parent": { + "$ref": "AAAAAAFElnF1nFTadPw=" + }, + "model": { + "$ref": "AAAAAAFElnF1nFTY/Sw=" + }, + "visible": false, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 60, + "top": -116, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 208, + "top": 48, + "width": 93, + "height": 38, + "nameCompartment": { + "$ref": "AAAAAAFElnF1nFTbplQ=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFElnF1nVThfqA=" + }, + "operationCompartment": { + "$ref": "AAAAAAFElnF1nVTiFXA=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqCEfLOas=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFElnF1nVTjasU=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFElnGGLFUGHnM=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFElnGGLFUFZFA=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFElnGGLFUH+8s=", + "_parent": { + "$ref": "AAAAAAFElnGGLFUGHnM=" + }, + "model": { + "$ref": "AAAAAAFElnGGLFUFZFA=" + }, + "visible": false, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 174, + "top": 73, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFElnGGLFUGHnM=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFElnGGLFUIOR8=", + "_parent": { + "$ref": "AAAAAAFElnGGLFUGHnM=" + }, + "model": { + "$ref": "AAAAAAFElnGGLFUFZFA=" + }, + "visible": null, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 174, + "top": 88, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFElnGGLFUGHnM=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFElnGGLFUJv6k=", + "_parent": { + "$ref": "AAAAAAFElnGGLFUGHnM=" + }, + "model": { + "$ref": "AAAAAAFElnGGLFUFZFA=" + }, + "visible": false, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 175, + "top": 43, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFElnGGLFUGHnM=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "head": { + "$ref": "AAAAAAFElnFrT1S8vVg=" + }, + "tail": { + "$ref": "AAAAAAFElnF1nFTadPw=" + }, + "points": "208:64;142:64", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFElnGGLFUH+8s=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFElnGGLFUIOR8=" + }, + "propertyLabel": { + "$ref": "AAAAAAFElnGGLFUJv6k=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFElnJRglVMyB8=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFElnJRglVKSoc=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqCkfpKls=", + "_parent": { + "$ref": "AAAAAAFElnJRglVMyB8=" + }, + "model": { + "$ref": "AAAAAAFElnJRglVKSoc=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFElnJRglVN/RI=", + "_parent": { + "$ref": "AAAAAAFElnJRglVMyB8=" + }, + "model": { + "$ref": "AAAAAAFElnJRglVKSoc=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFElnJRglVO7ow=", + "_parent": { + "$ref": "AAAAAAFElnJRglVN/RI=" + }, + "visible": false, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 104, + "top": -176, + "width": 1, + "height": 12 + }, + { + "_type": "LabelView", + "_id": "AAAAAAFElnJRglVPiBM=", + "_parent": { + "$ref": "AAAAAAFElnJRglVN/RI=" + }, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 217, + "top": 119, + "width": 74.73593139648438, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFElnJRglVQT1k=", + "_parent": { + "$ref": "AAAAAAFElnJRglVN/RI=" + }, + "font": "Arial;12;1", + "containerChangeable": true, + "containerExtending": true, + "left": 217, + "top": 133, + "width": 74.73593139648438, + "height": 12, + "text": "Specification" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFElnJRglVRdk8=", + "_parent": { + "$ref": "AAAAAAFElnJRglVN/RI=" + }, + "visible": false, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 104, + "top": -176, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFElnJRglVSFic=", + "_parent": { + "$ref": "AAAAAAFElnJRglVN/RI=" + }, + "visible": false, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 104, + "top": -176, + "width": 1, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 212, + "top": 112, + "width": 84.73593139648438, + "height": 38, + "stereotypeLabel": { + "$ref": "AAAAAAFElnJRglVPiBM=" + }, + "nameLabel": { + "$ref": "AAAAAAFElnJRglVQT1k=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFElnJRglVRdk8=" + }, + "propertyLabel": { + "$ref": "AAAAAAFElnJRglVSFic=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFElnJRglVTXPE=", + "_parent": { + "$ref": "AAAAAAFElnJRglVMyB8=" + }, + "model": { + "$ref": "AAAAAAFElnJRglVKSoc=" + }, + "visible": false, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 212, + "top": 150, + "width": 84, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFElnJRglVUe0c=", + "_parent": { + "$ref": "AAAAAAFElnJRglVMyB8=" + }, + "model": { + "$ref": "AAAAAAFElnJRglVKSoc=" + }, + "visible": false, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 212, + "top": 160, + "width": 84, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFElnJRg1VVWNU=", + "_parent": { + "$ref": "AAAAAAFElnJRglVMyB8=" + }, + "model": { + "$ref": "AAAAAAFElnJRglVKSoc=" + }, + "visible": false, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 104, + "top": -176, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 212, + "top": 112, + "width": 84.73593139648438, + "height": 38, + "nameCompartment": { + "$ref": "AAAAAAFElnJRglVN/RI=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFElnJRglVTXPE=" + }, + "operationCompartment": { + "$ref": "AAAAAAFElnJRglVUe0c=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqCkfpKls=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFElnJRg1VVWNU=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFElnKVuVV5hVg=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFElnKVuVV4pBU=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFElnKVuVV6VLo=", + "_parent": { + "$ref": "AAAAAAFElnKVuVV5hVg=" + }, + "model": { + "$ref": "AAAAAAFElnKVuVV4pBU=" + }, + "visible": false, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 176, + "top": 141, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFElnKVuVV5hVg=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFElnKVuVV7m9U=", + "_parent": { + "$ref": "AAAAAAFElnKVuVV5hVg=" + }, + "model": { + "$ref": "AAAAAAFElnKVuVV4pBU=" + }, + "visible": null, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 176, + "top": 156, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFElnKVuVV5hVg=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFElnKVuVV8bvU=", + "_parent": { + "$ref": "AAAAAAFElnKVuVV5hVg=" + }, + "model": { + "$ref": "AAAAAAFElnKVuVV4pBU=" + }, + "visible": false, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 177, + "top": 111, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFElnKVuVV5hVg=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "head": { + "$ref": "AAAAAAFElnFrT1S8vVg=" + }, + "tail": { + "$ref": "AAAAAAFElnJRglVMyB8=" + }, + "points": "212:132;142:132", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFElnKVuVV6VLo=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFElnKVuVV7m9U=" + }, + "propertyLabel": { + "$ref": "AAAAAAFElnKVuVV8bvU=" + } + }, + { + "_type": "UMLMetaClassView", + "_id": "AAAAAAFFJsZbpDNpnkE=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFJsZbpDNobIs=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFJsZbpTNq6XM=", + "_parent": { + "$ref": "AAAAAAFFJsZbpDNpnkE=" + }, + "model": { + "$ref": "AAAAAAFFJsZbpDNobIs=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFJsZbpTNrbHw=", + "_parent": { + "$ref": "AAAAAAFFJsZbpTNq6XM=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 561, + "top": 209, + "width": 87, + "height": 12, + "text": "«metaClass»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFJsZbpTNsdGc=", + "_parent": { + "$ref": "AAAAAAFFJsZbpTNq6XM=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;1", + "containerChangeable": true, + "containerExtending": true, + "left": 561, + "top": 223, + "width": 87, + "height": 12, + "text": "UMLClass" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFJsZbpTNtikk=", + "_parent": { + "$ref": "AAAAAAFFJsZbpTNq6XM=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 1500, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFJsZbpTNuOXU=", + "_parent": { + "$ref": "AAAAAAFFJsZbpTNq6XM=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 1500, + "width": 1, + "height": 12, + "horizontalAlignment": 1 + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 556, + "top": 204, + "width": 97, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFJsZbpTNrbHw=" + }, + "nameLabel": { + "$ref": "AAAAAAFFJsZbpTNsdGc=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFJsZbpTNtikk=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFJsZbpTNuOXU=" + } + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 556, + "top": 204, + "width": 97, + "height": 305, + "nameCompartment": { + "$ref": "AAAAAAFFJsZbpTNq6XM=" + } + }, + { + "_type": "UMLMetaClassView", + "_id": "AAAAAAFFwKqhJFq1z2Y=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwKqhJFq06mA=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwKqhJFq2eQM=", + "_parent": { + "$ref": "AAAAAAFFwKqhJFq1z2Y=" + }, + "model": { + "$ref": "AAAAAAFFwKqhJFq06mA=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwKqhJFq3hUU=", + "_parent": { + "$ref": "AAAAAAFFwKqhJFq2eQM=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 57, + "top": 209, + "width": 79, + "height": 12, + "text": "«metaClass»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKqhJFq4Vb4=", + "_parent": { + "$ref": "AAAAAAFFwKqhJFq2eQM=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;1", + "containerExtending": true, + "left": 57, + "top": 223, + "width": 79, + "height": 12, + "text": "UMLArtifact" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKqhJFq5GlQ=", + "_parent": { + "$ref": "AAAAAAFFwKqhJFq2eQM=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": -12, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKqhJFq6Fls=", + "_parent": { + "$ref": "AAAAAAFFwKqhJFq2eQM=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": -12, + "height": 12, + "horizontalAlignment": 1 + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 52, + "top": 204, + "width": 89, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwKqhJFq3hUU=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwKqhJFq4Vb4=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwKqhJFq5GlQ=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwKqhJFq6Fls=" + } + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 52, + "top": 204, + "width": 89, + "height": 329, + "nameCompartment": { + "$ref": "AAAAAAFFwKqhJFq2eQM=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwKsvdVrTyNI=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwKsvdVrRJUQ=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqDUglDBo=", + "_parent": { + "$ref": "AAAAAAFFwKsvdVrTyNI=" + }, + "model": { + "$ref": "AAAAAAFFwKsvdVrRJUQ=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwKsvdVrUE8w=", + "_parent": { + "$ref": "AAAAAAFFwKsvdVrTyNI=" + }, + "model": { + "$ref": "AAAAAAFFwKsvdVrRJUQ=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwKsvdVrVvYg=", + "_parent": { + "$ref": "AAAAAAFFwKsvdVrUE8w=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 237, + "top": 209, + "width": 119, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKsvdVrW/Dg=", + "_parent": { + "$ref": "AAAAAAFFwKsvdVrUE8w=" + }, + "font": "Arial;12;3", + "containerExtending": true, + "left": 237, + "top": 223, + "width": 119, + "height": 12, + "text": "File" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKsvdVrXXrQ=", + "_parent": { + "$ref": "AAAAAAFFwKsvdVrUE8w=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 48, + "top": -12, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKsvdVrYnv8=", + "_parent": { + "$ref": "AAAAAAFFwKsvdVrUE8w=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 48, + "top": -12, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 232, + "top": 204, + "width": 129, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwKsvdVrVvYg=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwKsvdVrW/Dg=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwKsvdVrXXrQ=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwKsvdVrYnv8=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwKsvdVrZA0U=", + "_parent": { + "$ref": "AAAAAAFFwKsvdVrTyNI=" + }, + "model": { + "$ref": "AAAAAAFFwKsvdVrRJUQ=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 248, + "top": 236, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwKsvdlraVvA=", + "_parent": { + "$ref": "AAAAAAFFwKsvdVrTyNI=" + }, + "model": { + "$ref": "AAAAAAFFwKsvdVrRJUQ=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 248, + "top": 236, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwKsvdlrbd2U=", + "_parent": { + "$ref": "AAAAAAFFwKsvdVrTyNI=" + }, + "model": { + "$ref": "AAAAAAFFwKsvdVrRJUQ=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 32, + "top": -8, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 232, + "top": 204, + "width": 129, + "height": 37, + "nameCompartment": { + "$ref": "AAAAAAFFwKsvdVrUE8w=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwKsvdVrZA0U=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwKsvdlraVvA=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqDUglDBo=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwKsvdlrbd2U=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwKtwS1r8DQQ=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwKtwS1r6wew=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqDUg7My0=", + "_parent": { + "$ref": "AAAAAAFFwKtwS1r8DQQ=" + }, + "model": { + "$ref": "AAAAAAFFwKtwS1r6wew=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwKtwS1r9YJ4=", + "_parent": { + "$ref": "AAAAAAFFwKtwS1r8DQQ=" + }, + "model": { + "$ref": "AAAAAAFFwKtwS1r6wew=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwKtwS1r+fw8=", + "_parent": { + "$ref": "AAAAAAFFwKtwS1r9YJ4=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 189, + "top": 313, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKtwS1r/Lsw=", + "_parent": { + "$ref": "AAAAAAFFwKtwS1r9YJ4=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 189, + "top": 327, + "width": 72.51593017578125, + "height": 12, + "text": "Document" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKtwS1sAGYA=", + "_parent": { + "$ref": "AAAAAAFFwKtwS1r9YJ4=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 24, + "top": 24, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKtwS1sB7y4=", + "_parent": { + "$ref": "AAAAAAFFwKtwS1r9YJ4=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 24, + "top": 24, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 184, + "top": 308, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwKtwS1r+fw8=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwKtwS1r/Lsw=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwKtwS1sAGYA=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwKtwS1sB7y4=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwKtwTFsC02k=", + "_parent": { + "$ref": "AAAAAAFFwKtwS1r8DQQ=" + }, + "model": { + "$ref": "AAAAAAFFwKtwS1r6wew=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 192, + "top": 352, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwKtwTFsD5lc=", + "_parent": { + "$ref": "AAAAAAFFwKtwS1r8DQQ=" + }, + "model": { + "$ref": "AAAAAAFFwKtwS1r6wew=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 192, + "top": 352, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwKtwTFsEQlE=", + "_parent": { + "$ref": "AAAAAAFFwKtwS1r8DQQ=" + }, + "model": { + "$ref": "AAAAAAFFwKtwS1r6wew=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 16, + "top": 16, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 184, + "top": 308, + "width": 82.51593017578125, + "height": 36, + "nameCompartment": { + "$ref": "AAAAAAFFwKtwS1r9YJ4=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwKtwTFsC02k=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwKtwTFsD5lc=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqDUg7My0=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwKtwTFsEQlE=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwKuBulskCVg=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwKuBulsidLQ=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqDkhRFFg=", + "_parent": { + "$ref": "AAAAAAFFwKuBulskCVg=" + }, + "model": { + "$ref": "AAAAAAFFwKuBulsidLQ=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwKuBulsld0g=", + "_parent": { + "$ref": "AAAAAAFFwKuBulskCVg=" + }, + "model": { + "$ref": "AAAAAAFFwKuBulsidLQ=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwKuBulsmb/s=", + "_parent": { + "$ref": "AAAAAAFFwKuBulsld0g=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 257, + "top": 357, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKuBulsnKBI=", + "_parent": { + "$ref": "AAAAAAFFwKuBulsld0g=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 257, + "top": 371, + "width": 72.51593017578125, + "height": 12, + "text": "Executable" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKuBu1soKF0=", + "_parent": { + "$ref": "AAAAAAFFwKuBulsld0g=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 96, + "top": -48, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKuBu1spOXA=", + "_parent": { + "$ref": "AAAAAAFFwKuBulsld0g=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 96, + "top": -48, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 252, + "top": 352, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwKuBulsmb/s=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwKuBulsnKBI=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwKuBu1soKF0=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwKuBu1spOXA=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwKuBu1sqPhk=", + "_parent": { + "$ref": "AAAAAAFFwKuBulskCVg=" + }, + "model": { + "$ref": "AAAAAAFFwKuBulsidLQ=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 284, + "top": 372, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwKuBu1srnoE=", + "_parent": { + "$ref": "AAAAAAFFwKuBulskCVg=" + }, + "model": { + "$ref": "AAAAAAFFwKuBulsidLQ=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 284, + "top": 372, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwKuBu1ssVVg=", + "_parent": { + "$ref": "AAAAAAFFwKuBulskCVg=" + }, + "model": { + "$ref": "AAAAAAFFwKuBulsidLQ=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 64, + "top": -32, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 252, + "top": 352, + "width": 82.51593017578125, + "height": 36, + "nameCompartment": { + "$ref": "AAAAAAFFwKuBulsld0g=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwKuBu1sqPhk=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwKuBu1srnoE=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqDkhRFFg=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwKuBu1ssVVg=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwKuIMltMJw4=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwKuIMltKnQQ=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqD0hnnhc=", + "_parent": { + "$ref": "AAAAAAFFwKuIMltMJw4=" + }, + "model": { + "$ref": "AAAAAAFFwKuIMltKnQQ=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwKuIMltNJK8=", + "_parent": { + "$ref": "AAAAAAFFwKuIMltMJw4=" + }, + "model": { + "$ref": "AAAAAAFFwKuIMltKnQQ=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwKuIM1tO63M=", + "_parent": { + "$ref": "AAAAAAFFwKuIMltNJK8=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 321, + "top": 405, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKuIM1tPj60=", + "_parent": { + "$ref": "AAAAAAFFwKuIMltNJK8=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 321, + "top": 419, + "width": 72.51593017578125, + "height": 12, + "text": "Library" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKuIM1tQD7A=", + "_parent": { + "$ref": "AAAAAAFFwKuIMltNJK8=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 132, + "top": -108, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKuIM1tRSSY=", + "_parent": { + "$ref": "AAAAAAFFwKuIMltNJK8=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 132, + "top": -108, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 316, + "top": 400, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwKuIM1tO63M=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwKuIM1tPj60=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwKuIM1tQD7A=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwKuIM1tRSSY=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwKuIM1tSiN4=", + "_parent": { + "$ref": "AAAAAAFFwKuIMltMJw4=" + }, + "model": { + "$ref": "AAAAAAFFwKuIMltKnQQ=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 360, + "top": 400, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwKuIM1tTPjo=", + "_parent": { + "$ref": "AAAAAAFFwKuIMltMJw4=" + }, + "model": { + "$ref": "AAAAAAFFwKuIMltKnQQ=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 360, + "top": 400, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwKuIM1tUHbM=", + "_parent": { + "$ref": "AAAAAAFFwKuIMltMJw4=" + }, + "model": { + "$ref": "AAAAAAFFwKuIMltKnQQ=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 88, + "top": -72, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 316, + "top": 400, + "width": 82.51593017578125, + "height": 36, + "nameCompartment": { + "$ref": "AAAAAAFFwKuIMltNJK8=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwKuIM1tSiN4=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwKuIM1tTPjo=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqD0hnnhc=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwKuIM1tUHbM=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwKuS0lt0dAE=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwKuS0ltysPk=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqEEh93KM=", + "_parent": { + "$ref": "AAAAAAFFwKuS0lt0dAE=" + }, + "model": { + "$ref": "AAAAAAFFwKuS0ltysPk=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwKuS0lt1+MM=", + "_parent": { + "$ref": "AAAAAAFFwKuS0lt0dAE=" + }, + "model": { + "$ref": "AAAAAAFFwKuS0ltysPk=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwKuS0lt2XgE=", + "_parent": { + "$ref": "AAAAAAFFwKuS0lt1+MM=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 385, + "top": 453, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKuS0lt36r8=", + "_parent": { + "$ref": "AAAAAAFFwKuS0lt1+MM=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 385, + "top": 467, + "width": 72.51593017578125, + "height": 12, + "text": "Script" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKuS0lt4pP4=", + "_parent": { + "$ref": "AAAAAAFFwKuS0lt1+MM=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 180, + "top": -180, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKuS0lt5mi4=", + "_parent": { + "$ref": "AAAAAAFFwKuS0lt1+MM=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 180, + "top": -180, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 380, + "top": 448, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwKuS0lt2XgE=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwKuS0lt36r8=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwKuS0lt4pP4=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwKuS0lt5mi4=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwKuS0lt6gjg=", + "_parent": { + "$ref": "AAAAAAFFwKuS0lt0dAE=" + }, + "model": { + "$ref": "AAAAAAFFwKuS0ltysPk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 440, + "top": 424, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwKuS0lt7fo0=", + "_parent": { + "$ref": "AAAAAAFFwKuS0lt0dAE=" + }, + "model": { + "$ref": "AAAAAAFFwKuS0ltysPk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 440, + "top": 424, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwKuS0lt8w2A=", + "_parent": { + "$ref": "AAAAAAFFwKuS0lt0dAE=" + }, + "model": { + "$ref": "AAAAAAFFwKuS0ltysPk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 120, + "top": -120, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 380, + "top": 448, + "width": 82.51593017578125, + "height": 36, + "nameCompartment": { + "$ref": "AAAAAAFFwKuS0lt1+MM=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwKuS0lt6gjg=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwKuS0lt7fo0=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqEEh93KM=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwKuS0lt8w2A=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwKueMluc5bE=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwKueMVuaLXM=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqEUiTykw=", + "_parent": { + "$ref": "AAAAAAFFwKueMluc5bE=" + }, + "model": { + "$ref": "AAAAAAFFwKueMVuaLXM=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwKueMludFfk=", + "_parent": { + "$ref": "AAAAAAFFwKueMluc5bE=" + }, + "model": { + "$ref": "AAAAAAFFwKueMVuaLXM=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwKueMlueAco=", + "_parent": { + "$ref": "AAAAAAFFwKueMludFfk=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 445, + "top": 501, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKueMluflfo=", + "_parent": { + "$ref": "AAAAAAFFwKueMludFfk=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 445, + "top": 515, + "width": 72.51593017578125, + "height": 12, + "text": "Source" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKueMlughos=", + "_parent": { + "$ref": "AAAAAAFFwKueMludFfk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "top": -108, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKueMluhfws=", + "_parent": { + "$ref": "AAAAAAFFwKueMludFfk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "top": -108, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 440, + "top": 496, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwKueMlueAco=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwKueMluflfo=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwKueMlughos=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwKueMluhfws=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwKueMluihu4=", + "_parent": { + "$ref": "AAAAAAFFwKueMluc5bE=" + }, + "model": { + "$ref": "AAAAAAFFwKueMVuaLXM=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 440, + "top": 500, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwKueMlujEyo=", + "_parent": { + "$ref": "AAAAAAFFwKueMluc5bE=" + }, + "model": { + "$ref": "AAAAAAFFwKueMVuaLXM=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 440, + "top": 500, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwKueMlukJo8=", + "_parent": { + "$ref": "AAAAAAFFwKueMluc5bE=" + }, + "model": { + "$ref": "AAAAAAFFwKueMVuaLXM=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "top": -72, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 440, + "top": 496, + "width": 82.51593017578125, + "height": 36, + "nameCompartment": { + "$ref": "AAAAAAFFwKueMludFfk=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwKueMluihu4=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwKueMlujEyo=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqEUiTykw=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwKueMlukJo8=" + } + }, + { + "_type": "UMLGeneralizationView", + "_id": "AAAAAAFFwKzkslvYVdw=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwKzkslvX4gU=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwKzkslvZbd0=", + "_parent": { + "$ref": "AAAAAAFFwKzkslvYVdw=" + }, + "model": { + "$ref": "AAAAAAFFwKzkslvX4gU=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 258, + "top": 267, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwKzkslvYVdw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwKzks1vasdU=", + "_parent": { + "$ref": "AAAAAAFFwKzkslvYVdw=" + }, + "model": { + "$ref": "AAAAAAFFwKzkslvX4gU=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 258, + "top": 252, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwKzkslvYVdw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwKzks1vby/c=", + "_parent": { + "$ref": "AAAAAAFFwKzkslvYVdw=" + }, + "model": { + "$ref": "AAAAAAFFwKzkslvX4gU=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 258, + "top": 297, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwKzkslvYVdw=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwKsvdVrTyNI=" + }, + "tail": { + "$ref": "AAAAAAFFwKtwS1r8DQQ=" + }, + "points": "216:308;216:288;300:288;300:240", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwKzkslvZbd0=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwKzks1vasdU=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwKzks1vby/c=" + } + }, + { + "_type": "UMLGeneralizationView", + "_id": "AAAAAAFFwKzsCVvpt2A=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwKzsCVvo11g=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwKzsCVvqAUg=", + "_parent": { + "$ref": "AAAAAAFFwKzsCVvpt2A=" + }, + "model": { + "$ref": "AAAAAAFFwKzsCVvo11g=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 285, + "top": 289, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwKzsCVvpt2A=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwKzsCVvrTi8=", + "_parent": { + "$ref": "AAAAAAFFwKzsCVvpt2A=" + }, + "model": { + "$ref": "AAAAAAFFwKzsCVvo11g=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 270, + "top": 289, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwKzsCVvpt2A=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwKzsCVvsewQ=", + "_parent": { + "$ref": "AAAAAAFFwKzsCVvpt2A=" + }, + "model": { + "$ref": "AAAAAAFFwKzsCVvo11g=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 314, + "top": 290, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwKzsCVvpt2A=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwKsvdVrTyNI=" + }, + "tail": { + "$ref": "AAAAAAFFwKuBulskCVg=" + }, + "points": "300:352;300:240", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwKzsCVvqAUg=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwKzsCVvrTi8=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwKzsCVvsewQ=" + } + }, + { + "_type": "UMLGeneralizationView", + "_id": "AAAAAAFFwKzxcVv6A2c=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwKzxcVv56Dg=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwKzxcVv7wpA=", + "_parent": { + "$ref": "AAAAAAFFwKzxcVv6A2c=" + }, + "model": { + "$ref": "AAAAAAFFwKzxcVv56Dg=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 327, + "top": 297, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwKzxcVv6A2c=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwKzxcVv8NxM=", + "_parent": { + "$ref": "AAAAAAFFwKzxcVv6A2c=" + }, + "model": { + "$ref": "AAAAAAFFwKzxcVv56Dg=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 327, + "top": 312, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwKzxcVv6A2c=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwKzxcVv9X58=", + "_parent": { + "$ref": "AAAAAAFFwKzxcVv6A2c=" + }, + "model": { + "$ref": "AAAAAAFFwKzxcVv56Dg=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 328, + "top": 267, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwKzxcVv6A2c=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwKsvdVrTyNI=" + }, + "tail": { + "$ref": "AAAAAAFFwKuIMltMJw4=" + }, + "points": "356:400;356:288;300:288;300:240", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwKzxcVv7wpA=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwKzxcVv8NxM=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwKzxcVv9X58=" + } + }, + { + "_type": "UMLGeneralizationView", + "_id": "AAAAAAFFwKz3OVwLl+8=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwKz3OVwK9hs=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwKz3OVwMNB4=", + "_parent": { + "$ref": "AAAAAAFFwKz3OVwLl+8=" + }, + "model": { + "$ref": "AAAAAAFFwKz3OVwK9hs=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 357, + "top": 297, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwKz3OVwLl+8=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwKz3OVwNd3E=", + "_parent": { + "$ref": "AAAAAAFFwKz3OVwLl+8=" + }, + "model": { + "$ref": "AAAAAAFFwKz3OVwK9hs=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 357, + "top": 312, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwKz3OVwLl+8=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwKz3OVwODiI=", + "_parent": { + "$ref": "AAAAAAFFwKz3OVwLl+8=" + }, + "model": { + "$ref": "AAAAAAFFwKz3OVwK9hs=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 358, + "top": 267, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwKz3OVwLl+8=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwKsvdVrTyNI=" + }, + "tail": { + "$ref": "AAAAAAFFwKuS0lt0dAE=" + }, + "points": "416:448;416:288;300:288;300:240", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwKz3OVwMNB4=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwKz3OVwNd3E=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwKz3OVwODiI=" + } + }, + { + "_type": "UMLGeneralizationView", + "_id": "AAAAAAFFwKz9mVwcos8=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwKz9mFwbfDg=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwKz9mVwdsGc=", + "_parent": { + "$ref": "AAAAAAFFwKz9mVwcos8=" + }, + "model": { + "$ref": "AAAAAAFFwKz9mFwbfDg=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 391, + "top": 297, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwKz9mVwcos8=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwKz9mVweYvs=", + "_parent": { + "$ref": "AAAAAAFFwKz9mVwcos8=" + }, + "model": { + "$ref": "AAAAAAFFwKz9mFwbfDg=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 391, + "top": 312, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwKz9mVwcos8=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwKz9mVwfOSk=", + "_parent": { + "$ref": "AAAAAAFFwKz9mVwcos8=" + }, + "model": { + "$ref": "AAAAAAFFwKz9mFwbfDg=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 392, + "top": 267, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwKz9mVwcos8=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwKsvdVrTyNI=" + }, + "tail": { + "$ref": "AAAAAAFFwKueMluc5bE=" + }, + "points": "484:496;484:288;300:288;300:240", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwKz9mVwdsGc=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwKz9mVweYvs=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwKz9mVwfOSk=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwK4k1VxFxwI=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwK4k1VxEEpM=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK4k1lxGUvg=", + "_parent": { + "$ref": "AAAAAAFFwK4k1VxFxwI=" + }, + "model": { + "$ref": "AAAAAAFFwK4k1VxEEpM=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 161, + "top": 333, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwK4k1VxFxwI=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK4k1lxHABk=", + "_parent": { + "$ref": "AAAAAAFFwK4k1VxFxwI=" + }, + "model": { + "$ref": "AAAAAAFFwK4k1VxEEpM=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 161, + "top": 348, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwK4k1VxFxwI=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK4k1lxIpIg=", + "_parent": { + "$ref": "AAAAAAFFwK4k1VxFxwI=" + }, + "model": { + "$ref": "AAAAAAFFwK4k1VxEEpM=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 162, + "top": 303, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwK4k1VxFxwI=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwKqhJFq1z2Y=" + }, + "tail": { + "$ref": "AAAAAAFFwKtwS1r8DQQ=" + }, + "points": "184:324;140:324", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwK4k1lxGUvg=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwK4k1lxHABk=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwK4k1lxIpIg=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwK4o4VxWQBI=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwK4o4VxVx00=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK4o4VxXVGc=", + "_parent": { + "$ref": "AAAAAAFFwK4o4VxWQBI=" + }, + "model": { + "$ref": "AAAAAAFFwK4o4VxVx00=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 195, + "top": 378, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwK4o4VxWQBI=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK4o4VxYgZc=", + "_parent": { + "$ref": "AAAAAAFFwK4o4VxWQBI=" + }, + "model": { + "$ref": "AAAAAAFFwK4o4VxVx00=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 195, + "top": 393, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwK4o4VxWQBI=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK4o4VxZqsQ=", + "_parent": { + "$ref": "AAAAAAFFwK4o4VxWQBI=" + }, + "model": { + "$ref": "AAAAAAFFwK4o4VxVx00=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 196, + "top": 348, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwK4o4VxWQBI=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwKqhJFq1z2Y=" + }, + "tail": { + "$ref": "AAAAAAFFwKuBulskCVg=" + }, + "points": "252:369;140:369", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwK4o4VxXVGc=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwK4o4VxYgZc=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwK4o4VxZqsQ=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwK4tiVxnpno=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwK4tiVxmVJM=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK4tiVxoTEk=", + "_parent": { + "$ref": "AAAAAAFFwK4tiVxnpno=" + }, + "model": { + "$ref": "AAAAAAFFwK4tiVxmVJM=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 227, + "top": 429, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwK4tiVxnpno=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK4tiVxpG0I=", + "_parent": { + "$ref": "AAAAAAFFwK4tiVxnpno=" + }, + "model": { + "$ref": "AAAAAAFFwK4tiVxmVJM=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 227, + "top": 444, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwK4tiVxnpno=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK4tiVxqKIY=", + "_parent": { + "$ref": "AAAAAAFFwK4tiVxnpno=" + }, + "model": { + "$ref": "AAAAAAFFwK4tiVxmVJM=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 228, + "top": 399, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwK4tiVxnpno=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwKqhJFq1z2Y=" + }, + "tail": { + "$ref": "AAAAAAFFwKuIMltMJw4=" + }, + "points": "316:420;140:420", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwK4tiVxoTEk=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwK4tiVxpG0I=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwK4tiVxqKIY=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwK41YVx4sZw=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwK41YVx3Hr0=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK41YVx5rZ4=", + "_parent": { + "$ref": "AAAAAAFFwK41YVx4sZw=" + }, + "model": { + "$ref": "AAAAAAFFwK41YVx3Hr0=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 259, + "top": 473, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwK41YVx4sZw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK41YVx6mfE=", + "_parent": { + "$ref": "AAAAAAFFwK41YVx4sZw=" + }, + "model": { + "$ref": "AAAAAAFFwK41YVx3Hr0=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 259, + "top": 488, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwK41YVx4sZw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK41YVx7lFo=", + "_parent": { + "$ref": "AAAAAAFFwK41YVx4sZw=" + }, + "model": { + "$ref": "AAAAAAFFwK41YVx3Hr0=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 260, + "top": 443, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwK41YVx4sZw=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwKqhJFq1z2Y=" + }, + "tail": { + "$ref": "AAAAAAFFwKuS0lt0dAE=" + }, + "points": "380:464;140:464", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwK41YVx5rZ4=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwK41YVx6mfE=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwK41YVx7lFo=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwK47MFyJhkk=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwK47MFyIL/c=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK47MFyKeH8=", + "_parent": { + "$ref": "AAAAAAFFwK47MFyJhkk=" + }, + "model": { + "$ref": "AAAAAAFFwK47MFyIL/c=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 289, + "top": 521, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwK47MFyJhkk=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK47MVyL2Gg=", + "_parent": { + "$ref": "AAAAAAFFwK47MFyJhkk=" + }, + "model": { + "$ref": "AAAAAAFFwK47MFyIL/c=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 289, + "top": 536, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwK47MFyJhkk=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK47MVyMJyk=", + "_parent": { + "$ref": "AAAAAAFFwK47MFyJhkk=" + }, + "model": { + "$ref": "AAAAAAFFwK47MFyIL/c=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 290, + "top": 491, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwK47MFyJhkk=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwKqhJFq1z2Y=" + }, + "tail": { + "$ref": "AAAAAAFFwKueMluc5bE=" + }, + "points": "440:512;140:512", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwK47MFyKeH8=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwK47MVyL2Gg=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwK47MVyMJyk=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwK5AeFyarms=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwK5AeFyZpVg=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK5AeFybX8s=", + "_parent": { + "$ref": "AAAAAAFFwK5AeFyarms=" + }, + "model": { + "$ref": "AAAAAAFFwK5AeFyZpVg=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 185, + "top": 229, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwK5AeFyarms=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK5AeFycm2c=", + "_parent": { + "$ref": "AAAAAAFFwK5AeFyarms=" + }, + "model": { + "$ref": "AAAAAAFFwK5AeFyZpVg=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 185, + "top": 244, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwK5AeFyarms=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK5AeVydbSU=", + "_parent": { + "$ref": "AAAAAAFFwK5AeFyarms=" + }, + "model": { + "$ref": "AAAAAAFFwK5AeFyZpVg=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 186, + "top": 199, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwK5AeFyarms=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwKqhJFq1z2Y=" + }, + "tail": { + "$ref": "AAAAAAFFwKsvdVrTyNI=" + }, + "points": "232:220;140:220", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwK5AeFybX8s=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwK5AeFycm2c=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwK5AeVydbSU=" + } + }, + { + "_type": "UMLMetaClassView", + "_id": "AAAAAAFFwK/k1ly1mNU=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwK/k1ly00Ec=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwK/k1ly236Y=", + "_parent": { + "$ref": "AAAAAAFFwK/k1ly1mNU=" + }, + "model": { + "$ref": "AAAAAAFFwK/k1ly00Ec=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwK/k1ly3kes=", + "_parent": { + "$ref": "AAAAAAFFwK/k1ly236Y=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 385, + "top": 585, + "width": 132, + "height": 12, + "text": "«metaClass»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwK/k1ly4Kb0=", + "_parent": { + "$ref": "AAAAAAFFwK/k1ly236Y=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;1", + "containerExtending": true, + "left": 385, + "top": 599, + "width": 132, + "height": 12, + "text": "UMLBehavioralFeature" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwK/k11y5jis=", + "_parent": { + "$ref": "AAAAAAFFwK/k1ly236Y=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 972, + "top": 60, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwK/k11y6pH4=", + "_parent": { + "$ref": "AAAAAAFFwK/k1ly236Y=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 972, + "top": 60, + "height": 12, + "horizontalAlignment": 1 + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 380, + "top": 580, + "width": 142, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwK/k1ly3kes=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwK/k1ly4Kb0=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwK/k11y5jis=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwK/k11y6pH4=" + } + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 380, + "top": 580, + "width": 142, + "height": 101, + "nameCompartment": { + "$ref": "AAAAAAFFwK/k1ly236Y=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwLBdPFzSzQk=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLBdO1zQosE=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqFkkF9pQ=", + "_parent": { + "$ref": "AAAAAAFFwLBdPFzSzQk=" + }, + "model": { + "$ref": "AAAAAAFFwLBdO1zQosE=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwLBdPFzT/sk=", + "_parent": { + "$ref": "AAAAAAFFwLBdPFzSzQk=" + }, + "model": { + "$ref": "AAAAAAFFwLBdO1zQosE=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwLBdPFzUtqg=", + "_parent": { + "$ref": "AAAAAAFFwLBdPFzT/sk=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 241, + "top": 589, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLBdPFzVTVM=", + "_parent": { + "$ref": "AAAAAAFFwLBdPFzT/sk=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 241, + "top": 603, + "width": 72.51593017578125, + "height": 12, + "text": "Destroy" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLBdPFzWXGg=", + "_parent": { + "$ref": "AAAAAAFFwLBdPFzT/sk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 120, + "top": 24, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLBdPFzX7Kw=", + "_parent": { + "$ref": "AAAAAAFFwLBdPFzT/sk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 120, + "top": 24, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 236, + "top": 584, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLBdPFzUtqg=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwLBdPFzVTVM=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwLBdPFzWXGg=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLBdPFzX7Kw=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwLBdPFzYl0A=", + "_parent": { + "$ref": "AAAAAAFFwLBdPFzSzQk=" + }, + "model": { + "$ref": "AAAAAAFFwLBdO1zQosE=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 220, + "top": 632, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwLBdPFzZMKQ=", + "_parent": { + "$ref": "AAAAAAFFwLBdPFzSzQk=" + }, + "model": { + "$ref": "AAAAAAFFwLBdO1zQosE=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 220, + "top": 632, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwLBdPFzaqUA=", + "_parent": { + "$ref": "AAAAAAFFwLBdPFzSzQk=" + }, + "model": { + "$ref": "AAAAAAFFwLBdO1zQosE=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 80, + "top": 16, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 236, + "top": 584, + "width": 82.51593017578125, + "height": 37, + "nameCompartment": { + "$ref": "AAAAAAFFwLBdPFzT/sk=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwLBdPFzYl0A=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwLBdPFzZMKQ=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqFkkF9pQ=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwLBdPFzaqUA=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwLDMaFz6CG0=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLDMaFz5C14=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLDMaFz7zuA=", + "_parent": { + "$ref": "AAAAAAFFwLDMaFz6CG0=" + }, + "model": { + "$ref": "AAAAAAFFwLDMaFz5C14=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 349, + "top": 579, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLDMaFz6CG0=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLDMaFz8JJ4=", + "_parent": { + "$ref": "AAAAAAFFwLDMaFz6CG0=" + }, + "model": { + "$ref": "AAAAAAFFwLDMaFz5C14=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 349, + "top": 564, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwLDMaFz6CG0=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLDMaFz92bU=", + "_parent": { + "$ref": "AAAAAAFFwLDMaFz6CG0=" + }, + "model": { + "$ref": "AAAAAAFFwLDMaFz5C14=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 349, + "top": 609, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLDMaFz6CG0=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwK/k1ly1mNU=" + }, + "tail": { + "$ref": "AAAAAAFFwLBdPFzSzQk=" + }, + "points": "318:600;380:600", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwLDMaFz7zuA=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLDMaFz8JJ4=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLDMaFz92bU=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwLFUbV0ScDI=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLFUbV0QQVA=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqF0kiyCM=", + "_parent": { + "$ref": "AAAAAAFFwLFUbV0ScDI=" + }, + "model": { + "$ref": "AAAAAAFFwLFUbV0QQVA=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwLFUbV0TTdY=", + "_parent": { + "$ref": "AAAAAAFFwLFUbV0ScDI=" + }, + "model": { + "$ref": "AAAAAAFFwLFUbV0QQVA=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwLFUbV0UvYs=", + "_parent": { + "$ref": "AAAAAAFFwLFUbV0TTdY=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 725, + "top": 209, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLFUbV0V4oU=", + "_parent": { + "$ref": "AAAAAAFFwLFUbV0TTdY=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 725, + "top": 223, + "width": 72.51593017578125, + "height": 12, + "text": "Auxiliary" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLFUbV0WLEA=", + "_parent": { + "$ref": "AAAAAAFFwLFUbV0TTdY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -60, + "top": -336, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLFUbV0XEPg=", + "_parent": { + "$ref": "AAAAAAFFwLFUbV0TTdY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -60, + "top": -336, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 204, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLFUbV0UvYs=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwLFUbV0V4oU=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwLFUbV0WLEA=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLFUbV0XEPg=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwLFUbV0YxWc=", + "_parent": { + "$ref": "AAAAAAFFwLFUbV0ScDI=" + }, + "model": { + "$ref": "AAAAAAFFwLFUbV0QQVA=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 700, + "top": 128, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwLFUbV0Z3Xk=", + "_parent": { + "$ref": "AAAAAAFFwLFUbV0ScDI=" + }, + "model": { + "$ref": "AAAAAAFFwLFUbV0QQVA=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 700, + "top": 128, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwLFUbV0aLJo=", + "_parent": { + "$ref": "AAAAAAFFwLFUbV0ScDI=" + }, + "model": { + "$ref": "AAAAAAFFwLFUbV0QQVA=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -40, + "top": -224, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 204, + "width": 82.51593017578125, + "height": 36, + "nameCompartment": { + "$ref": "AAAAAAFFwLFUbV0TTdY=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwLFUbV0YxWc=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwLFUbV0Z3Xk=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqF0kiyCM=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwLFUbV0aLJo=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwLFu9F06sWk=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLFu8104he4=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqGEk49nc=", + "_parent": { + "$ref": "AAAAAAFFwLFu9F06sWk=" + }, + "model": { + "$ref": "AAAAAAFFwLFu8104he4=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwLFu9F07mo0=", + "_parent": { + "$ref": "AAAAAAFFwLFu9F06sWk=" + }, + "model": { + "$ref": "AAAAAAFFwLFu8104he4=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwLFu9F08FIY=", + "_parent": { + "$ref": "AAAAAAFFwLFu9F07mo0=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 725, + "top": 261, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLFu9F09Ig0=", + "_parent": { + "$ref": "AAAAAAFFwLFu9F07mo0=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 725, + "top": 275, + "width": 72.51593017578125, + "height": 12, + "text": "Focus" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLFu9F0+sYU=", + "_parent": { + "$ref": "AAAAAAFFwLFu9F07mo0=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -60, + "top": -420, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLFu9F0/2cA=", + "_parent": { + "$ref": "AAAAAAFFwLFu9F07mo0=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -60, + "top": -420, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 256, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLFu9F08FIY=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwLFu9F09Ig0=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwLFu9F0+sYU=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLFu9F0/2cA=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwLFu9F1A690=", + "_parent": { + "$ref": "AAAAAAFFwLFu9F06sWk=" + }, + "model": { + "$ref": "AAAAAAFFwLFu8104he4=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 700, + "top": 152, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwLFu9F1BAsU=", + "_parent": { + "$ref": "AAAAAAFFwLFu9F06sWk=" + }, + "model": { + "$ref": "AAAAAAFFwLFu8104he4=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 700, + "top": 152, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwLFu9F1CLR8=", + "_parent": { + "$ref": "AAAAAAFFwLFu9F06sWk=" + }, + "model": { + "$ref": "AAAAAAFFwLFu8104he4=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -40, + "top": -280, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 256, + "width": 82.51593017578125, + "height": 36, + "nameCompartment": { + "$ref": "AAAAAAFFwLFu9F07mo0=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwLFu9F1A690=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwLFu9F1BAsU=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqGEk49nc=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwLFu9F1CLR8=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwLF4tF1iftI=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLF4tF1g4No=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqGUlOO9I=", + "_parent": { + "$ref": "AAAAAAFFwLF4tF1iftI=" + }, + "model": { + "$ref": "AAAAAAFFwLF4tF1g4No=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwLF4tF1jr/w=", + "_parent": { + "$ref": "AAAAAAFFwLF4tF1iftI=" + }, + "model": { + "$ref": "AAAAAAFFwLF4tF1g4No=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwLF4tF1kg2Y=", + "_parent": { + "$ref": "AAAAAAFFwLF4tF1jr/w=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 725, + "top": 313, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLF4tF1la4E=", + "_parent": { + "$ref": "AAAAAAFFwLF4tF1jr/w=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 725, + "top": 327, + "width": 72.51593017578125, + "height": 12, + "text": "Metaclass" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLF4tF1mW9o=", + "_parent": { + "$ref": "AAAAAAFFwLF4tF1jr/w=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -60, + "top": -480, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLF4tF1ngPk=", + "_parent": { + "$ref": "AAAAAAFFwLF4tF1jr/w=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -60, + "top": -480, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 308, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLF4tF1kg2Y=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwLF4tF1la4E=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwLF4tF1mW9o=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLF4tF1ngPk=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwLF4tF1oP5U=", + "_parent": { + "$ref": "AAAAAAFFwLF4tF1iftI=" + }, + "model": { + "$ref": "AAAAAAFFwLF4tF1g4No=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 700, + "top": 184, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwLF4tF1pEYI=", + "_parent": { + "$ref": "AAAAAAFFwLF4tF1iftI=" + }, + "model": { + "$ref": "AAAAAAFFwLF4tF1g4No=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 700, + "top": 184, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwLF4tF1qaMM=", + "_parent": { + "$ref": "AAAAAAFFwLF4tF1iftI=" + }, + "model": { + "$ref": "AAAAAAFFwLF4tF1g4No=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -40, + "top": -320, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 308, + "width": 82.51593017578125, + "height": 36, + "nameCompartment": { + "$ref": "AAAAAAFFwLF4tF1jr/w=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwLF4tF1oP5U=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwLF4tF1pEYI=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqGUlOO9I=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwLF4tF1qaMM=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwLF/G12KFPg=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLF/G12IJ54=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqGUlk1Tc=", + "_parent": { + "$ref": "AAAAAAFFwLF/G12KFPg=" + }, + "model": { + "$ref": "AAAAAAFFwLF/G12IJ54=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwLF/G12LESY=", + "_parent": { + "$ref": "AAAAAAFFwLF/G12KFPg=" + }, + "model": { + "$ref": "AAAAAAFFwLF/G12IJ54=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwLF/G12MFWs=", + "_parent": { + "$ref": "AAAAAAFFwLF/G12LESY=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 725, + "top": 365, + "width": 121, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLF/G12Nq6M=", + "_parent": { + "$ref": "AAAAAAFFwLF/G12LESY=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 725, + "top": 379, + "width": 121, + "height": 12, + "text": "ImplementationClass" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLF/G12OWK0=", + "_parent": { + "$ref": "AAAAAAFFwLF/G12LESY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -48, + "top": -564, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLF/G12PipY=", + "_parent": { + "$ref": "AAAAAAFFwLF/G12LESY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -48, + "top": -564, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 360, + "width": 131, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLF/G12MFWs=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwLF/G12Nq6M=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwLF/G12OWK0=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLF/G12PipY=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwLF/G12QJs8=", + "_parent": { + "$ref": "AAAAAAFFwLF/G12KFPg=" + }, + "model": { + "$ref": "AAAAAAFFwLF/G12IJ54=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 704, + "top": 208, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwLF/G12Rf8c=", + "_parent": { + "$ref": "AAAAAAFFwLF/G12KFPg=" + }, + "model": { + "$ref": "AAAAAAFFwLF/G12IJ54=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 704, + "top": 208, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwLF/HF2Sm8E=", + "_parent": { + "$ref": "AAAAAAFFwLF/G12KFPg=" + }, + "model": { + "$ref": "AAAAAAFFwLF/G12IJ54=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -32, + "top": -376, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 360, + "width": 131, + "height": 36, + "nameCompartment": { + "$ref": "AAAAAAFFwLF/G12LESY=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwLF/G12QJs8=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwLF/G12Rf8c=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqGUlk1Tc=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwLF/HF2Sm8E=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwLGEPF2y6SI=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLGEO12wqJ8=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqHEl6Zbo=", + "_parent": { + "$ref": "AAAAAAFFwLGEPF2y6SI=" + }, + "model": { + "$ref": "AAAAAAFFwLGEO12wqJ8=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwLGEPF2zyUI=", + "_parent": { + "$ref": "AAAAAAFFwLGEPF2y6SI=" + }, + "model": { + "$ref": "AAAAAAFFwLGEO12wqJ8=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwLGEPF20OuI=", + "_parent": { + "$ref": "AAAAAAFFwLGEPF2zyUI=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 725, + "top": 421, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLGEPF21TcM=", + "_parent": { + "$ref": "AAAAAAFFwLGEPF2zyUI=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 725, + "top": 435, + "width": 72.51593017578125, + "height": 12, + "text": "Type" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLGEPF22f/8=", + "_parent": { + "$ref": "AAAAAAFFwLGEPF2zyUI=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -48, + "top": -624, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLGEPF23oz0=", + "_parent": { + "$ref": "AAAAAAFFwLGEPF2zyUI=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -48, + "top": -624, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 416, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLGEPF20OuI=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwLGEPF21TcM=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwLGEPF22f/8=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLGEPF23oz0=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwLGEPF24D5Y=", + "_parent": { + "$ref": "AAAAAAFFwLGEPF2y6SI=" + }, + "model": { + "$ref": "AAAAAAFFwLGEO12wqJ8=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 704, + "top": 244, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwLGEPF252Tg=", + "_parent": { + "$ref": "AAAAAAFFwLGEPF2y6SI=" + }, + "model": { + "$ref": "AAAAAAFFwLGEO12wqJ8=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 704, + "top": 244, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwLGEPF26r38=", + "_parent": { + "$ref": "AAAAAAFFwLGEPF2y6SI=" + }, + "model": { + "$ref": "AAAAAAFFwLGEO12wqJ8=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -32, + "top": -416, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 416, + "width": 82.51593017578125, + "height": 36, + "nameCompartment": { + "$ref": "AAAAAAFFwLGEPF2zyUI=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwLGEPF24D5Y=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwLGEPF252Tg=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqHEl6Zbo=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwLGEPF26r38=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwLGI813a/Lo=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLGI813YL3s=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqHEmQAJ4=", + "_parent": { + "$ref": "AAAAAAFFwLGI813a/Lo=" + }, + "model": { + "$ref": "AAAAAAFFwLGI813YL3s=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwLGI813bmDw=", + "_parent": { + "$ref": "AAAAAAFFwLGI813a/Lo=" + }, + "model": { + "$ref": "AAAAAAFFwLGI813YL3s=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwLGI9F3c6dc=", + "_parent": { + "$ref": "AAAAAAFFwLGI813bmDw=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 725, + "top": 477, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLGI9F3dgjo=", + "_parent": { + "$ref": "AAAAAAFFwLGI813bmDw=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 725, + "top": 491, + "width": 72.51593017578125, + "height": 12, + "text": "Utility" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLGI9F3eWQw=", + "_parent": { + "$ref": "AAAAAAFFwLGI813bmDw=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -48, + "top": -672, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLGI9F3fVUI=", + "_parent": { + "$ref": "AAAAAAFFwLGI813bmDw=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -48, + "top": -672, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 472, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLGI9F3c6dc=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwLGI9F3dgjo=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwLGI9F3eWQw=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLGI9F3fVUI=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwLGI9F3g9+w=", + "_parent": { + "$ref": "AAAAAAFFwLGI813a/Lo=" + }, + "model": { + "$ref": "AAAAAAFFwLGI813YL3s=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 704, + "top": 284, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwLGI9F3hmIE=", + "_parent": { + "$ref": "AAAAAAFFwLGI813a/Lo=" + }, + "model": { + "$ref": "AAAAAAFFwLGI813YL3s=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 704, + "top": 284, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwLGI9F3i+8k=", + "_parent": { + "$ref": "AAAAAAFFwLGI813a/Lo=" + }, + "model": { + "$ref": "AAAAAAFFwLGI813YL3s=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -32, + "top": -448, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 472, + "width": 82.51593017578125, + "height": 36, + "nameCompartment": { + "$ref": "AAAAAAFFwLGI813bmDw=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwLGI9F3g9+w=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwLGI9F3hmIE=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqHEmQAJ4=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwLGI9F3i+8k=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwLNej158NLk=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLNej157D6Y=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLNej1590I0=", + "_parent": { + "$ref": "AAAAAAFFwLNej158NLk=" + }, + "model": { + "$ref": "AAAAAAFFwLNej157D6Y=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 685, + "top": 233, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLNej158NLk=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLNej15+8jc=", + "_parent": { + "$ref": "AAAAAAFFwLNej158NLk=" + }, + "model": { + "$ref": "AAAAAAFFwLNej157D6Y=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 685, + "top": 248, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwLNej158NLk=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLNej15/BRY=", + "_parent": { + "$ref": "AAAAAAFFwLNej158NLk=" + }, + "model": { + "$ref": "AAAAAAFFwLNej157D6Y=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 686, + "top": 203, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLNej158NLk=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFJsZbpDNpnkE=" + }, + "tail": { + "$ref": "AAAAAAFFwLFUbV0ScDI=" + }, + "points": "720:224;652:224", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwLNej1590I0=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLNej15+8jc=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLNej15/BRY=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwLNkZ16NQ/Q=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLNkZ16Mp7Y=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLNkZ16OhBQ=", + "_parent": { + "$ref": "AAAAAAFFwLNkZ16NQ/Q=" + }, + "model": { + "$ref": "AAAAAAFFwLNkZ16Mp7Y=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 685, + "top": 281, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLNkZ16NQ/Q=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLNkZ16PBtY=", + "_parent": { + "$ref": "AAAAAAFFwLNkZ16NQ/Q=" + }, + "model": { + "$ref": "AAAAAAFFwLNkZ16Mp7Y=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 685, + "top": 296, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwLNkZ16NQ/Q=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLNkZ16QvLQ=", + "_parent": { + "$ref": "AAAAAAFFwLNkZ16NQ/Q=" + }, + "model": { + "$ref": "AAAAAAFFwLNkZ16Mp7Y=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 686, + "top": 251, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLNkZ16NQ/Q=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFJsZbpDNpnkE=" + }, + "tail": { + "$ref": "AAAAAAFFwLFu9F06sWk=" + }, + "points": "720:272;652:272", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwLNkZ16OhBQ=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLNkZ16PBtY=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLNkZ16QvLQ=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwLNn916eDZQ=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLNn916d4Yc=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLNn916fvYQ=", + "_parent": { + "$ref": "AAAAAAFFwLNn916eDZQ=" + }, + "model": { + "$ref": "AAAAAAFFwLNn916d4Yc=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 685, + "top": 333, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLNn916eDZQ=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLNn916guUU=", + "_parent": { + "$ref": "AAAAAAFFwLNn916eDZQ=" + }, + "model": { + "$ref": "AAAAAAFFwLNn916d4Yc=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 685, + "top": 348, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwLNn916eDZQ=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLNn916hjhM=", + "_parent": { + "$ref": "AAAAAAFFwLNn916eDZQ=" + }, + "model": { + "$ref": "AAAAAAFFwLNn916d4Yc=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 686, + "top": 303, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLNn916eDZQ=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFJsZbpDNpnkE=" + }, + "tail": { + "$ref": "AAAAAAFFwLF4tF1iftI=" + }, + "points": "720:324;652:324", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwLNn916fvYQ=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLNn916guUU=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLNn916hjhM=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwLNr116vKpE=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLNr116u93k=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLNr116weUM=", + "_parent": { + "$ref": "AAAAAAFFwLNr116vKpE=" + }, + "model": { + "$ref": "AAAAAAFFwLNr116u93k=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 685, + "top": 385, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLNr116vKpE=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLNr116xjvo=", + "_parent": { + "$ref": "AAAAAAFFwLNr116vKpE=" + }, + "model": { + "$ref": "AAAAAAFFwLNr116u93k=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 685, + "top": 400, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwLNr116vKpE=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLNr116yGN0=", + "_parent": { + "$ref": "AAAAAAFFwLNr116vKpE=" + }, + "model": { + "$ref": "AAAAAAFFwLNr116u93k=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 686, + "top": 355, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLNr116vKpE=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFJsZbpDNpnkE=" + }, + "tail": { + "$ref": "AAAAAAFFwLF/G12KFPg=" + }, + "points": "720:376;652:376", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwLNr116weUM=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLNr116xjvo=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLNr116yGN0=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwLNvdl7AF7U=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLNvdl6/WJI=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLNvd17Byl0=", + "_parent": { + "$ref": "AAAAAAFFwLNvdl7AF7U=" + }, + "model": { + "$ref": "AAAAAAFFwLNvdl6/WJI=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 685, + "top": 442, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLNvdl7AF7U=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLNvd17Cmyo=", + "_parent": { + "$ref": "AAAAAAFFwLNvdl7AF7U=" + }, + "model": { + "$ref": "AAAAAAFFwLNvdl6/WJI=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 685, + "top": 457, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwLNvdl7AF7U=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLNvd17DduQ=", + "_parent": { + "$ref": "AAAAAAFFwLNvdl7AF7U=" + }, + "model": { + "$ref": "AAAAAAFFwLNvdl6/WJI=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 686, + "top": 412, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLNvdl7AF7U=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFJsZbpDNpnkE=" + }, + "tail": { + "$ref": "AAAAAAFFwLGEPF2y6SI=" + }, + "points": "720:433;652:433", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwLNvd17Byl0=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLNvd17Cmyo=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLNvd17DduQ=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwLN0fl7RscA=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLN0fl7QL9o=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLN0fl7SzeE=", + "_parent": { + "$ref": "AAAAAAFFwLN0fl7RscA=" + }, + "model": { + "$ref": "AAAAAAFFwLN0fl7QL9o=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 685, + "top": 498, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLN0fl7RscA=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLN0fl7Tq3c=", + "_parent": { + "$ref": "AAAAAAFFwLN0fl7RscA=" + }, + "model": { + "$ref": "AAAAAAFFwLN0fl7QL9o=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 685, + "top": 513, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwLN0fl7RscA=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLN0f17UptI=", + "_parent": { + "$ref": "AAAAAAFFwLN0fl7RscA=" + }, + "model": { + "$ref": "AAAAAAFFwLN0fl7QL9o=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 686, + "top": 468, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLN0fl7RscA=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFJsZbpDNpnkE=" + }, + "tail": { + "$ref": "AAAAAAFFwLGI813a/Lo=" + }, + "points": "720:489;652:489", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwLN0fl7SzeE=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLN0fl7Tq3c=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLN0f17UptI=" + } + }, + { + "_type": "UMLMetaClassView", + "_id": "AAAAAAFFwLRECl7stC8=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLRECl7r1R4=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwLRECl7tsQE=", + "_parent": { + "$ref": "AAAAAAFFwLRECl7stC8=" + }, + "model": { + "$ref": "AAAAAAFFwLRECl7r1R4=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwLRECl7u5vE=", + "_parent": { + "$ref": "AAAAAAFFwLRECl7tsQE=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 561, + "top": 545, + "width": 92.85594177246094, + "height": 12, + "text": "«metaClass»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLRECl7vrCk=", + "_parent": { + "$ref": "AAAAAAFFwLRECl7tsQE=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;1", + "containerExtending": true, + "left": 561, + "top": 559, + "width": 92.85594177246094, + "height": 12, + "text": "UMLComponent" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLRECl7wqHs=", + "_parent": { + "$ref": "AAAAAAFFwLRECl7tsQE=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "top": 504, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLRECl7xJrI=", + "_parent": { + "$ref": "AAAAAAFFwLRECl7tsQE=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "top": 504, + "height": 12, + "horizontalAlignment": 1 + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 556, + "top": 540, + "width": 102.85594177246094, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLRECl7u5vE=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwLRECl7vrCk=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwLRECl7wqHs=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLRECl7xJrI=" + } + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 556, + "top": 540, + "width": 102.85594177246094, + "height": 261, + "nameCompartment": { + "$ref": "AAAAAAFFwLRECl7tsQE=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwLR8CV8I99Y=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLR8CF8G68k=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqH0nfZIU=", + "_parent": { + "$ref": "AAAAAAFFwLR8CV8I99Y=" + }, + "model": { + "$ref": "AAAAAAFFwLR8CF8G68k=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwLR8CV8JFWY=", + "_parent": { + "$ref": "AAAAAAFFwLR8CV8I99Y=" + }, + "model": { + "$ref": "AAAAAAFFwLR8CF8G68k=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwLR8CV8Knxc=", + "_parent": { + "$ref": "AAAAAAFFwLR8CV8JFWY=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 725, + "top": 549, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLR8CV8LWIw=", + "_parent": { + "$ref": "AAAAAAFFwLR8CV8JFWY=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 725, + "top": 563, + "width": 72.51593017578125, + "height": 12, + "text": "Entity" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLR8CV8Mvqc=", + "_parent": { + "$ref": "AAAAAAFFwLR8CV8JFWY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "top": 504, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLR8CV8NdIc=", + "_parent": { + "$ref": "AAAAAAFFwLR8CV8JFWY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "top": 504, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 544, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLR8CV8Knxc=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwLR8CV8LWIw=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwLR8CV8Mvqc=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLR8CV8NdIc=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwLR8CV8OpVY=", + "_parent": { + "$ref": "AAAAAAFFwLR8CV8I99Y=" + }, + "model": { + "$ref": "AAAAAAFFwLR8CF8G68k=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 748, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwLR8CV8PW8k=", + "_parent": { + "$ref": "AAAAAAFFwLR8CV8I99Y=" + }, + "model": { + "$ref": "AAAAAAFFwLR8CF8G68k=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 748, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwLR8Cl8QCTM=", + "_parent": { + "$ref": "AAAAAAFFwLR8CV8I99Y=" + }, + "model": { + "$ref": "AAAAAAFFwLR8CF8G68k=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "top": 336, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 544, + "width": 82.51593017578125, + "height": 36, + "nameCompartment": { + "$ref": "AAAAAAFFwLR8CV8JFWY=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwLR8CV8OpVY=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwLR8CV8PW8k=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqH0nfZIU=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwLR8Cl8QCTM=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwLSByF8w+gI=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLSByF8umMo=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqIEn1Irc=", + "_parent": { + "$ref": "AAAAAAFFwLSByF8w+gI=" + }, + "model": { + "$ref": "AAAAAAFFwLSByF8umMo=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwLSByF8x/Yc=", + "_parent": { + "$ref": "AAAAAAFFwLSByF8w+gI=" + }, + "model": { + "$ref": "AAAAAAFFwLSByF8umMo=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwLSByF8yMLo=", + "_parent": { + "$ref": "AAAAAAFFwLSByF8x/Yc=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 725, + "top": 597, + "width": 88.67578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLSByF8zspI=", + "_parent": { + "$ref": "AAAAAAFFwLSByF8x/Yc=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 725, + "top": 611, + "width": 88.67578125, + "height": 12, + "text": "Implementation" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLSByF80AnU=", + "_parent": { + "$ref": "AAAAAAFFwLSByF8x/Yc=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -12, + "top": 420, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLSByF81b24=", + "_parent": { + "$ref": "AAAAAAFFwLSByF8x/Yc=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -12, + "top": 420, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 592, + "width": 98.67578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLSByF8yMLo=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwLSByF8zspI=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwLSByF80AnU=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLSByF81b24=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwLSByF82e10=", + "_parent": { + "$ref": "AAAAAAFFwLSByF8w+gI=" + }, + "model": { + "$ref": "AAAAAAFFwLSByF8umMo=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 716, + "top": 768, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwLSByF83aE4=", + "_parent": { + "$ref": "AAAAAAFFwLSByF8w+gI=" + }, + "model": { + "$ref": "AAAAAAFFwLSByF8umMo=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 716, + "top": 768, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwLSByF84G88=", + "_parent": { + "$ref": "AAAAAAFFwLSByF8w+gI=" + }, + "model": { + "$ref": "AAAAAAFFwLSByF8umMo=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -8, + "top": 280, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 592, + "width": 98.67578125, + "height": 36, + "nameCompartment": { + "$ref": "AAAAAAFFwLSByF8x/Yc=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwLSByF82e10=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwLSByF83aE4=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqIEn1Irc=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwLSByF84G88=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwLSIN19Ytdk=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLSIN19WMnE=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqIUoLdrY=", + "_parent": { + "$ref": "AAAAAAFFwLSIN19Ytdk=" + }, + "model": { + "$ref": "AAAAAAFFwLSIN19WMnE=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwLSIN19ZQ0U=", + "_parent": { + "$ref": "AAAAAAFFwLSIN19Ytdk=" + }, + "model": { + "$ref": "AAAAAAFFwLSIN19WMnE=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwLSIOF9a8kE=", + "_parent": { + "$ref": "AAAAAAFFwLSIN19ZQ0U=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 725, + "top": 653, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLSIOF9bYBg=", + "_parent": { + "$ref": "AAAAAAFFwLSIN19ZQ0U=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 725, + "top": 667, + "width": 72.51593017578125, + "height": 12, + "text": "Process" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLSIOF9cqZQ=", + "_parent": { + "$ref": "AAAAAAFFwLSIN19ZQ0U=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -12, + "top": 348, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLSIOF9dI5U=", + "_parent": { + "$ref": "AAAAAAFFwLSIN19ZQ0U=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -12, + "top": 348, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 648, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLSIOF9a8kE=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwLSIOF9bYBg=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwLSIOF9cqZQ=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLSIOF9dI5U=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwLSIOF9ekq0=", + "_parent": { + "$ref": "AAAAAAFFwLSIN19Ytdk=" + }, + "model": { + "$ref": "AAAAAAFFwLSIN19WMnE=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 716, + "top": 800, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwLSIOF9fibc=", + "_parent": { + "$ref": "AAAAAAFFwLSIN19Ytdk=" + }, + "model": { + "$ref": "AAAAAAFFwLSIN19WMnE=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 716, + "top": 800, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwLSIOF9gUN0=", + "_parent": { + "$ref": "AAAAAAFFwLSIN19Ytdk=" + }, + "model": { + "$ref": "AAAAAAFFwLSIN19WMnE=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -8, + "top": 232, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 648, + "width": 82.51593017578125, + "height": 36, + "nameCompartment": { + "$ref": "AAAAAAFFwLSIN19ZQ0U=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwLSIOF9ekq0=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwLSIOF9fibc=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqIUoLdrY=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwLSIOF9gUN0=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwLSO/1+AoeQ=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLSO/19+cMY=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqIkohl1g=", + "_parent": { + "$ref": "AAAAAAFFwLSO/1+AoeQ=" + }, + "model": { + "$ref": "AAAAAAFFwLSO/19+cMY=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwLSO/1+BWGA=", + "_parent": { + "$ref": "AAAAAAFFwLSO/1+AoeQ=" + }, + "model": { + "$ref": "AAAAAAFFwLSO/19+cMY=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwLSO/1+CG1s=", + "_parent": { + "$ref": "AAAAAAFFwLSO/1+BWGA=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 725, + "top": 709, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLSO/1+DoUc=", + "_parent": { + "$ref": "AAAAAAFFwLSO/1+BWGA=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 725, + "top": 723, + "width": 72.51593017578125, + "height": 12, + "text": "Service" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLSPAF+EVIo=", + "_parent": { + "$ref": "AAAAAAFFwLSO/1+BWGA=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -12, + "top": 312, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLSPAF+FZR8=", + "_parent": { + "$ref": "AAAAAAFFwLSO/1+BWGA=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -12, + "top": 312, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 704, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLSO/1+CG1s=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwLSO/1+DoUc=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwLSPAF+EVIo=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLSPAF+FZR8=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwLSPAF+GnaI=", + "_parent": { + "$ref": "AAAAAAFFwLSO/1+AoeQ=" + }, + "model": { + "$ref": "AAAAAAFFwLSO/19+cMY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 716, + "top": 844, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwLSPAF+Ho/s=", + "_parent": { + "$ref": "AAAAAAFFwLSO/1+AoeQ=" + }, + "model": { + "$ref": "AAAAAAFFwLSO/19+cMY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 716, + "top": 844, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwLSPAF+I3E8=", + "_parent": { + "$ref": "AAAAAAFFwLSO/1+AoeQ=" + }, + "model": { + "$ref": "AAAAAAFFwLSO/19+cMY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -8, + "top": 208, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 704, + "width": 82.51593017578125, + "height": 36, + "nameCompartment": { + "$ref": "AAAAAAFFwLSO/1+BWGA=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwLSPAF+GnaI=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwLSPAF+Ho/s=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqIkohl1g=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwLSPAF+I3E8=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwLSXP1+o0Kw=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLSXP1+mTVk=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqIko3HYE=", + "_parent": { + "$ref": "AAAAAAFFwLSXP1+o0Kw=" + }, + "model": { + "$ref": "AAAAAAFFwLSXP1+mTVk=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwLSXP1+peko=", + "_parent": { + "$ref": "AAAAAAFFwLSXP1+o0Kw=" + }, + "model": { + "$ref": "AAAAAAFFwLSXP1+mTVk=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwLSXP1+qR3g=", + "_parent": { + "$ref": "AAAAAAFFwLSXP1+peko=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 725, + "top": 765, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLSXP1+rnfg=", + "_parent": { + "$ref": "AAAAAAFFwLSXP1+peko=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 725, + "top": 779, + "width": 72.51593017578125, + "height": 12, + "text": "Subsystem" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLSXP1+sqCM=", + "_parent": { + "$ref": "AAAAAAFFwLSXP1+peko=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "top": 252, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLSXP1+t4Mc=", + "_parent": { + "$ref": "AAAAAAFFwLSXP1+peko=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "top": 252, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 760, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLSXP1+qR3g=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwLSXP1+rnfg=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwLSXP1+sqCM=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLSXP1+t4Mc=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwLSXP1+uKrA=", + "_parent": { + "$ref": "AAAAAAFFwLSXP1+o0Kw=" + }, + "model": { + "$ref": "AAAAAAFFwLSXP1+mTVk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 880, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwLSXP1+vdxM=", + "_parent": { + "$ref": "AAAAAAFFwLSXP1+o0Kw=" + }, + "model": { + "$ref": "AAAAAAFFwLSXP1+mTVk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 880, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwLSXP1+woFc=", + "_parent": { + "$ref": "AAAAAAFFwLSXP1+o0Kw=" + }, + "model": { + "$ref": "AAAAAAFFwLSXP1+mTVk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "top": 168, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 760, + "width": 82.51593017578125, + "height": 36, + "nameCompartment": { + "$ref": "AAAAAAFFwLSXP1+peko=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwLSXP1+uKrA=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwLSXP1+vdxM=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqIko3HYE=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwLSXP1+woFc=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwLV9gV/Ybio=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLV9gV/Xhk4=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLV9gV/Z8CU=", + "_parent": { + "$ref": "AAAAAAFFwLV9gV/Ybio=" + }, + "model": { + "$ref": "AAAAAAFFwLV9gV/Xhk4=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 688, + "top": 569, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLV9gV/Ybio=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLV9gl/a23I=", + "_parent": { + "$ref": "AAAAAAFFwLV9gV/Ybio=" + }, + "model": { + "$ref": "AAAAAAFFwLV9gV/Xhk4=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 688, + "top": 584, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwLV9gV/Ybio=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLV9gl/b3BU=", + "_parent": { + "$ref": "AAAAAAFFwLV9gV/Ybio=" + }, + "model": { + "$ref": "AAAAAAFFwLV9gV/Xhk4=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 689, + "top": 539, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLV9gV/Ybio=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwLRECl7stC8=" + }, + "tail": { + "$ref": "AAAAAAFFwLR8CV8I99Y=" + }, + "points": "720:560;658:560", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwLV9gV/Z8CU=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLV9gl/a23I=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLV9gl/b3BU=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwLWA0V/pWEg=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLWA0V/olVk=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLWA0V/q2AI=", + "_parent": { + "$ref": "AAAAAAFFwLWA0V/pWEg=" + }, + "model": { + "$ref": "AAAAAAFFwLWA0V/olVk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 688, + "top": 621, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLWA0V/pWEg=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLWA0V/rrYc=", + "_parent": { + "$ref": "AAAAAAFFwLWA0V/pWEg=" + }, + "model": { + "$ref": "AAAAAAFFwLWA0V/olVk=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 688, + "top": 636, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwLWA0V/pWEg=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLWA0V/spgM=", + "_parent": { + "$ref": "AAAAAAFFwLWA0V/pWEg=" + }, + "model": { + "$ref": "AAAAAAFFwLWA0V/olVk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 689, + "top": 591, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLWA0V/pWEg=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwLRECl7stC8=" + }, + "tail": { + "$ref": "AAAAAAFFwLSByF8w+gI=" + }, + "points": "720:612;658:612", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwLWA0V/q2AI=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLWA0V/rrYc=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLWA0V/spgM=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwLWEUV/6d1E=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLWEUV/5Qq4=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLWEUV/78Ig=", + "_parent": { + "$ref": "AAAAAAFFwLWEUV/6d1E=" + }, + "model": { + "$ref": "AAAAAAFFwLWEUV/5Qq4=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 688, + "top": 677, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLWEUV/6d1E=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLWEUV/8eIM=", + "_parent": { + "$ref": "AAAAAAFFwLWEUV/6d1E=" + }, + "model": { + "$ref": "AAAAAAFFwLWEUV/5Qq4=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 688, + "top": 692, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwLWEUV/6d1E=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLWEUV/9T0A=", + "_parent": { + "$ref": "AAAAAAFFwLWEUV/6d1E=" + }, + "model": { + "$ref": "AAAAAAFFwLWEUV/5Qq4=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 689, + "top": 647, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLWEUV/6d1E=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwLRECl7stC8=" + }, + "tail": { + "$ref": "AAAAAAFFwLSIN19Ytdk=" + }, + "points": "720:668;658:668", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwLWEUV/78Ig=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLWEUV/8eIM=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLWEUV/9T0A=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwLWIQWALE8M=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLWIQWAKKPo=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLWIQWAMDo8=", + "_parent": { + "$ref": "AAAAAAFFwLWIQWALE8M=" + }, + "model": { + "$ref": "AAAAAAFFwLWIQWAKKPo=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 688, + "top": 737, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLWIQWALE8M=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLWIQWANo/A=", + "_parent": { + "$ref": "AAAAAAFFwLWIQWALE8M=" + }, + "model": { + "$ref": "AAAAAAFFwLWIQWAKKPo=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 688, + "top": 752, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwLWIQWALE8M=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLWIQWAO6qA=", + "_parent": { + "$ref": "AAAAAAFFwLWIQWALE8M=" + }, + "model": { + "$ref": "AAAAAAFFwLWIQWAKKPo=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 689, + "top": 707, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLWIQWALE8M=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwLRECl7stC8=" + }, + "tail": { + "$ref": "AAAAAAFFwLSO/1+AoeQ=" + }, + "points": "720:728;658:728", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwLWIQWAMDo8=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLWIQWANo/A=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLWIQWAO6qA=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwLWMgWAcaQw=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLWMgWAb2Sk=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLWMgWAd1rc=", + "_parent": { + "$ref": "AAAAAAFFwLWMgWAcaQw=" + }, + "model": { + "$ref": "AAAAAAFFwLWMgWAb2Sk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 688, + "top": 789, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLWMgWAcaQw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLWMgWAeZ8k=", + "_parent": { + "$ref": "AAAAAAFFwLWMgWAcaQw=" + }, + "model": { + "$ref": "AAAAAAFFwLWMgWAb2Sk=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 688, + "top": 804, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwLWMgWAcaQw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLWMgWAfxqc=", + "_parent": { + "$ref": "AAAAAAFFwLWMgWAcaQw=" + }, + "model": { + "$ref": "AAAAAAFFwLWMgWAb2Sk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 689, + "top": 759, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLWMgWAcaQw=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwLRECl7stC8=" + }, + "tail": { + "$ref": "AAAAAAFFwLSXP1+o0Kw=" + }, + "points": "720:780;658:780", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwLWMgWAd1rc=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLWMgWAeZ8k=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLWMgWAfxqc=" + } + }, + { + "_type": "UMLMetaClassView", + "_id": "AAAAAAFFwL2WeWA5NQI=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwL2WeGA460g=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwL2WeWA62bI=", + "_parent": { + "$ref": "AAAAAAFFwL2WeWA5NQI=" + }, + "model": { + "$ref": "AAAAAAFFwL2WeGA460g=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwL2WeWA7mnk=", + "_parent": { + "$ref": "AAAAAAFFwL2WeWA62bI=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 61, + "top": 649, + "width": 98, + "height": 12, + "text": "«metaClass»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL2WeWA8/Wk=", + "_parent": { + "$ref": "AAAAAAFFwL2WeWA62bI=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;1", + "containerExtending": true, + "left": 61, + "top": 663, + "width": 98, + "height": 12, + "text": "UMLDependency" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL2WeWA9NaM=", + "_parent": { + "$ref": "AAAAAAFFwL2WeWA62bI=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "top": 144, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL2WeWA+CiM=", + "_parent": { + "$ref": "AAAAAAFFwL2WeWA62bI=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "top": 144, + "height": 12, + "horizontalAlignment": 1 + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 56, + "top": 644, + "width": 108, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwL2WeWA7mnk=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwL2WeWA8/Wk=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwL2WeWA9NaM=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwL2WeWA+CiM=" + } + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 56, + "top": 644, + "width": 108, + "height": 277, + "nameCompartment": { + "$ref": "AAAAAAFFwL2WeWA62bI=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwL4D0mBZIkY=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwL4D0mBXwu4=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqJkp/rUc=", + "_parent": { + "$ref": "AAAAAAFFwL4D0mBZIkY=" + }, + "model": { + "$ref": "AAAAAAFFwL4D0mBXwu4=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwL4D0mBaqmw=", + "_parent": { + "$ref": "AAAAAAFFwL4D0mBZIkY=" + }, + "model": { + "$ref": "AAAAAAFFwL4D0mBXwu4=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwL4D0mBbBNE=", + "_parent": { + "$ref": "AAAAAAFFwL4D0mBaqmw=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 241, + "top": 649, + "width": 69.380859375, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL4D0mBc7go=", + "_parent": { + "$ref": "AAAAAAFFwL4D0mBaqmw=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 241, + "top": 663, + "width": 69.380859375, + "height": 12, + "text": "Create" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL4D02Bd3+g=", + "_parent": { + "$ref": "AAAAAAFFwL4D0mBaqmw=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -48, + "top": -48, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL4D02BeWA8=", + "_parent": { + "$ref": "AAAAAAFFwL4D0mBaqmw=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -48, + "top": -48, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 236, + "top": 644, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwL4D0mBbBNE=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwL4D0mBc7go=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwL4D02Bd3+g=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwL4D02BeWA8=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwL4D02Bf0q0=", + "_parent": { + "$ref": "AAAAAAFFwL4D0mBZIkY=" + }, + "model": { + "$ref": "AAAAAAFFwL4D0mBXwu4=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 220, + "top": 664, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwL4D02BgYs8=", + "_parent": { + "$ref": "AAAAAAFFwL4D0mBZIkY=" + }, + "model": { + "$ref": "AAAAAAFFwL4D0mBXwu4=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 220, + "top": 664, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwL4D02BhsHw=", + "_parent": { + "$ref": "AAAAAAFFwL4D0mBZIkY=" + }, + "model": { + "$ref": "AAAAAAFFwL4D0mBXwu4=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -32, + "top": -32, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 236, + "top": 644, + "width": 79.380859375, + "height": 36, + "autoResize": true, + "nameCompartment": { + "$ref": "AAAAAAFFwL4D0mBaqmw=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwL4D02Bf0q0=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwL4D02BgYs8=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqJkp/rUc=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwL4D02BhsHw=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwL4h4WCCAAY=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwL4h4WCAEkg=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqJ0qVBvA=", + "_parent": { + "$ref": "AAAAAAFFwL4h4WCCAAY=" + }, + "model": { + "$ref": "AAAAAAFFwL4h4WCAEkg=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwL4h4WCD82Y=", + "_parent": { + "$ref": "AAAAAAFFwL4h4WCCAAY=" + }, + "model": { + "$ref": "AAAAAAFFwL4h4WCAEkg=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwL4h4mCE1YI=", + "_parent": { + "$ref": "AAAAAAFFwL4h4WCD82Y=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 241, + "top": 713, + "width": 69.380859375, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL4h4mCFbHY=", + "_parent": { + "$ref": "AAAAAAFFwL4h4WCD82Y=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 241, + "top": 727, + "width": 69.380859375, + "height": 12, + "text": "Call" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL4h4mCG+Bo=", + "_parent": { + "$ref": "AAAAAAFFwL4h4WCD82Y=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -48, + "top": -108, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL4h4mCHhD8=", + "_parent": { + "$ref": "AAAAAAFFwL4h4WCD82Y=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -48, + "top": -108, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 236, + "top": 708, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwL4h4mCE1YI=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwL4h4mCFbHY=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwL4h4mCG+Bo=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwL4h4mCHhD8=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwL4h4mCIEqs=", + "_parent": { + "$ref": "AAAAAAFFwL4h4WCCAAY=" + }, + "model": { + "$ref": "AAAAAAFFwL4h4WCAEkg=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 220, + "top": 708, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwL4h4mCJktQ=", + "_parent": { + "$ref": "AAAAAAFFwL4h4WCCAAY=" + }, + "model": { + "$ref": "AAAAAAFFwL4h4WCAEkg=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 220, + "top": 708, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwL4h4mCKdqI=", + "_parent": { + "$ref": "AAAAAAFFwL4h4WCCAAY=" + }, + "model": { + "$ref": "AAAAAAFFwL4h4WCAEkg=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -32, + "top": -72, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 236, + "top": 708, + "width": 79.380859375, + "height": 36, + "autoResize": true, + "nameCompartment": { + "$ref": "AAAAAAFFwL4h4WCD82Y=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwL4h4mCIEqs=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwL4h4mCJktQ=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqJ0qVBvA=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwL4h4mCKdqI=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwL45WWCr3cU=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwL45WWCpJ0o=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqJ0qrDxY=", + "_parent": { + "$ref": "AAAAAAFFwL45WWCr3cU=" + }, + "model": { + "$ref": "AAAAAAFFwL45WWCpJ0o=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwL45WWCsDkc=", + "_parent": { + "$ref": "AAAAAAFFwL45WWCr3cU=" + }, + "model": { + "$ref": "AAAAAAFFwL45WWCpJ0o=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwL45WWCtTBI=", + "_parent": { + "$ref": "AAAAAAFFwL45WWCsDkc=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 241, + "top": 769, + "width": 69.380859375, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL45WWCuTW0=", + "_parent": { + "$ref": "AAAAAAFFwL45WWCsDkc=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 241, + "top": 783, + "width": 69.380859375, + "height": 12, + "text": "Instantiate" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL45WWCv18Q=", + "_parent": { + "$ref": "AAAAAAFFwL45WWCsDkc=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -48, + "top": -192, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL45WWCwZzE=", + "_parent": { + "$ref": "AAAAAAFFwL45WWCsDkc=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -48, + "top": -192, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 236, + "top": 764, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwL45WWCtTBI=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwL45WWCuTW0=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwL45WWCv18Q=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwL45WWCwZzE=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwL45WWCxsuk=", + "_parent": { + "$ref": "AAAAAAFFwL45WWCr3cU=" + }, + "model": { + "$ref": "AAAAAAFFwL45WWCpJ0o=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 220, + "top": 736, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwL45WmCy+mU=", + "_parent": { + "$ref": "AAAAAAFFwL45WWCr3cU=" + }, + "model": { + "$ref": "AAAAAAFFwL45WWCpJ0o=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 220, + "top": 736, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwL45WmCzW1Y=", + "_parent": { + "$ref": "AAAAAAFFwL45WWCr3cU=" + }, + "model": { + "$ref": "AAAAAAFFwL45WWCpJ0o=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -32, + "top": -128, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 236, + "top": 764, + "width": 79.380859375, + "height": 36, + "autoResize": true, + "nameCompartment": { + "$ref": "AAAAAAFFwL45WWCsDkc=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwL45WWCxsuk=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwL45WmCy+mU=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqJ0qrDxY=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwL45WmCzW1Y=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwL5hQGDUxa0=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwL5hP2DSEFk=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqKErBHOc=", + "_parent": { + "$ref": "AAAAAAFFwL5hQGDUxa0=" + }, + "model": { + "$ref": "AAAAAAFFwL5hP2DSEFk=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwL5hQGDVSBg=", + "_parent": { + "$ref": "AAAAAAFFwL5hQGDUxa0=" + }, + "model": { + "$ref": "AAAAAAFFwL5hP2DSEFk=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwL5hQGDWrwI=", + "_parent": { + "$ref": "AAAAAAFFwL5hQGDVSBg=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 241, + "top": 825, + "width": 82.013671875, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL5hQGDXPFU=", + "_parent": { + "$ref": "AAAAAAFFwL5hQGDVSBg=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 241, + "top": 839, + "width": 82.013671875, + "height": 12, + "text": "Responsibility" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL5hQGDYpi0=", + "_parent": { + "$ref": "AAAAAAFFwL5hQGDVSBg=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -48, + "top": -252, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL5hQGDZAt8=", + "_parent": { + "$ref": "AAAAAAFFwL5hQGDVSBg=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -48, + "top": -252, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 236, + "top": 820, + "width": 92.013671875, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwL5hQGDWrwI=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwL5hQGDXPFU=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwL5hQGDYpi0=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwL5hQGDZAt8=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwL5hQGDa1nY=", + "_parent": { + "$ref": "AAAAAAFFwL5hQGDUxa0=" + }, + "model": { + "$ref": "AAAAAAFFwL5hP2DSEFk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 220, + "top": 772, + "width": 91, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwL5hQGDbixI=", + "_parent": { + "$ref": "AAAAAAFFwL5hQGDUxa0=" + }, + "model": { + "$ref": "AAAAAAFFwL5hP2DSEFk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 220, + "top": 772, + "width": 91, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwL5hQGDcuS4=", + "_parent": { + "$ref": "AAAAAAFFwL5hQGDUxa0=" + }, + "model": { + "$ref": "AAAAAAFFwL5hP2DSEFk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -32, + "top": -168, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 236, + "top": 820, + "width": 92.013671875, + "height": 36, + "autoResize": true, + "nameCompartment": { + "$ref": "AAAAAAFFwL5hQGDVSBg=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwL5hQGDa1nY=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwL5hQGDbixI=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqKErBHOc=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwL5hQGDcuS4=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwL7KdWEqew0=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwL7KdWEoDhA=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqKErXxgY=", + "_parent": { + "$ref": "AAAAAAFFwL7KdWEqew0=" + }, + "model": { + "$ref": "AAAAAAFFwL7KdWEoDhA=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwL7KdWEr60A=", + "_parent": { + "$ref": "AAAAAAFFwL7KdWEqew0=" + }, + "model": { + "$ref": "AAAAAAFFwL7KdWEoDhA=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwL7KdWEspPc=", + "_parent": { + "$ref": "AAAAAAFFwL7KdWEr60A=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 241, + "top": 881, + "width": 69.380859375, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL7KdWEt7g0=", + "_parent": { + "$ref": "AAAAAAFFwL7KdWEr60A=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 241, + "top": 895, + "width": 69.380859375, + "height": 12, + "text": "Send" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL7KdWEum1Q=", + "_parent": { + "$ref": "AAAAAAFFwL7KdWEr60A=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -60, + "top": -324, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL7KdWEv3Yk=", + "_parent": { + "$ref": "AAAAAAFFwL7KdWEr60A=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -60, + "top": -324, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 236, + "top": 876, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwL7KdWEspPc=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwL7KdWEt7g0=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwL7KdWEum1Q=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwL7KdWEv3Yk=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwL7KdWEwzHc=", + "_parent": { + "$ref": "AAAAAAFFwL7KdWEqew0=" + }, + "model": { + "$ref": "AAAAAAFFwL7KdWEoDhA=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 216, + "top": 804, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwL7KdWExRWs=", + "_parent": { + "$ref": "AAAAAAFFwL7KdWEqew0=" + }, + "model": { + "$ref": "AAAAAAFFwL7KdWEoDhA=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 216, + "top": 804, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwL7KdWEyL0Q=", + "_parent": { + "$ref": "AAAAAAFFwL7KdWEqew0=" + }, + "model": { + "$ref": "AAAAAAFFwL7KdWEoDhA=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -40, + "top": -216, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 236, + "top": 876, + "width": 79.380859375, + "height": 36, + "autoResize": true, + "nameCompartment": { + "$ref": "AAAAAAFFwL7KdWEr60A=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwL7KdWEwzHc=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwL7KdWExRWs=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqKErXxgY=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwL7KdWEyL0Q=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwL+LCGFgCjw=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwL+LCGFfPQs=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+LCGFhp5w=", + "_parent": { + "$ref": "AAAAAAFFwL+LCGFgCjw=" + }, + "model": { + "$ref": "AAAAAAFFwL+LCGFfPQs=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 347, + "top": 634, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwL+LCGFgCjw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+LCGFihK4=", + "_parent": { + "$ref": "AAAAAAFFwL+LCGFgCjw=" + }, + "model": { + "$ref": "AAAAAAFFwL+LCGFfPQs=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 347, + "top": 619, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwL+LCGFgCjw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+LCGFjcmE=", + "_parent": { + "$ref": "AAAAAAFFwL+LCGFgCjw=" + }, + "model": { + "$ref": "AAAAAAFFwL+LCGFfPQs=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 347, + "top": 664, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwL+LCGFgCjw=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwK/k1ly1mNU=" + }, + "tail": { + "$ref": "AAAAAAFFwL4D0mBZIkY=" + }, + "points": "314:655;380:655", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwL+LCGFhp5w=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwL+LCGFihK4=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwL+LCGFjcmE=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwL+O8GFxUF4=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwL+O8GFwbog=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+O8GFyCzY=", + "_parent": { + "$ref": "AAAAAAFFwL+O8GFxUF4=" + }, + "model": { + "$ref": "AAAAAAFFwL+O8GFwbog=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 198, + "top": 677, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwL+O8GFxUF4=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+O8GFzT+A=", + "_parent": { + "$ref": "AAAAAAFFwL+O8GFxUF4=" + }, + "model": { + "$ref": "AAAAAAFFwL+O8GFwbog=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 198, + "top": 692, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwL+O8GFxUF4=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+O8GF0qhg=", + "_parent": { + "$ref": "AAAAAAFFwL+O8GFxUF4=" + }, + "model": { + "$ref": "AAAAAAFFwL+O8GFwbog=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 199, + "top": 647, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwL+O8GFxUF4=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwL2WeWA5NQI=" + }, + "tail": { + "$ref": "AAAAAAFFwL4D0mBZIkY=" + }, + "points": "236:668;163:668", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwL+O8GFyCzY=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwL+O8GFzT+A=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwL+O8GF0qhg=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwL+SkWGC/a4=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwL+SkWGBCOg=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+SkWGDbeA=", + "_parent": { + "$ref": "AAAAAAFFwL+SkWGC/a4=" + }, + "model": { + "$ref": "AAAAAAFFwL+SkWGBCOg=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 198, + "top": 731, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwL+SkWGC/a4=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+SkWGEkxM=", + "_parent": { + "$ref": "AAAAAAFFwL+SkWGC/a4=" + }, + "model": { + "$ref": "AAAAAAFFwL+SkWGBCOg=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 198, + "top": 746, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwL+SkWGC/a4=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+SkWGFVnU=", + "_parent": { + "$ref": "AAAAAAFFwL+SkWGC/a4=" + }, + "model": { + "$ref": "AAAAAAFFwL+SkWGBCOg=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 199, + "top": 701, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwL+SkWGC/a4=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwL2WeWA5NQI=" + }, + "tail": { + "$ref": "AAAAAAFFwL4h4WCCAAY=" + }, + "points": "236:722;163:722", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwL+SkWGDbeA=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwL+SkWGEkxM=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwL+SkWGFVnU=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwL+WL2GTesQ=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwL+WL2GScgY=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+WL2GUDZ4=", + "_parent": { + "$ref": "AAAAAAFFwL+WL2GTesQ=" + }, + "model": { + "$ref": "AAAAAAFFwL+WL2GScgY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 198, + "top": 797, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwL+WL2GTesQ=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+WL2GVfH8=", + "_parent": { + "$ref": "AAAAAAFFwL+WL2GTesQ=" + }, + "model": { + "$ref": "AAAAAAFFwL+WL2GScgY=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 198, + "top": 812, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwL+WL2GTesQ=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+WL2GW4Ys=", + "_parent": { + "$ref": "AAAAAAFFwL+WL2GTesQ=" + }, + "model": { + "$ref": "AAAAAAFFwL+WL2GScgY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 199, + "top": 767, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwL+WL2GTesQ=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwL2WeWA5NQI=" + }, + "tail": { + "$ref": "AAAAAAFFwL45WWCr3cU=" + }, + "points": "236:788;163:788", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwL+WL2GUDZ4=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwL+WL2GVfH8=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwL+WL2GW4Ys=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwL+Z72GkT5Y=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwL+Z72GjzGw=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+Z72GllyU=", + "_parent": { + "$ref": "AAAAAAFFwL+Z72GkT5Y=" + }, + "model": { + "$ref": "AAAAAAFFwL+Z72GjzGw=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 198, + "top": 854, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwL+Z72GkT5Y=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+Z72Gm6K8=", + "_parent": { + "$ref": "AAAAAAFFwL+Z72GkT5Y=" + }, + "model": { + "$ref": "AAAAAAFFwL+Z72GjzGw=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 198, + "top": 869, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwL+Z72GkT5Y=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+Z72GnawI=", + "_parent": { + "$ref": "AAAAAAFFwL+Z72GkT5Y=" + }, + "model": { + "$ref": "AAAAAAFFwL+Z72GjzGw=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 199, + "top": 824, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwL+Z72GkT5Y=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwL2WeWA5NQI=" + }, + "tail": { + "$ref": "AAAAAAFFwL5hQGDUxa0=" + }, + "points": "236:845;163:845", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwL+Z72GllyU=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwL+Z72Gm6K8=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwL+Z72GnawI=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwL+eh2G1gXM=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwL+eh2G01aU=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+eh2G2oXg=", + "_parent": { + "$ref": "AAAAAAFFwL+eh2G1gXM=" + }, + "model": { + "$ref": "AAAAAAFFwL+eh2G01aU=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 198, + "top": 910, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwL+eh2G1gXM=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+eh2G3GpE=", + "_parent": { + "$ref": "AAAAAAFFwL+eh2G1gXM=" + }, + "model": { + "$ref": "AAAAAAFFwL+eh2G01aU=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 198, + "top": 925, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwL+eh2G1gXM=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+eh2G4woY=", + "_parent": { + "$ref": "AAAAAAFFwL+eh2G1gXM=" + }, + "model": { + "$ref": "AAAAAAFFwL+eh2G01aU=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 199, + "top": 880, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwL+eh2G1gXM=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwL2WeWA5NQI=" + }, + "tail": { + "$ref": "AAAAAAFFwL7KdWEqew0=" + }, + "points": "236:901;163:901", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwL+eh2G2oXg=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwL+eh2G3GpE=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwL+eh2G4woY=" + } + }, + { + "_type": "UMLMetaClassView", + "_id": "AAAAAAFFwMFq1GHZe+E=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwMFq1GHYSKM=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwMFq1GHa5CM=", + "_parent": { + "$ref": "AAAAAAFFwMFq1GHZe+E=" + }, + "model": { + "$ref": "AAAAAAFFwMFq1GHYSKM=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwMFq1GHbxIU=", + "_parent": { + "$ref": "AAAAAAFFwMFq1GHa5CM=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 561, + "top": 33, + "width": 93, + "height": 12, + "text": "«metaClass»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMFq1GHc3zA=", + "_parent": { + "$ref": "AAAAAAFFwMFq1GHa5CM=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;1", + "containerExtending": true, + "left": 561, + "top": 47, + "width": 93, + "height": 12, + "text": "UMLAbstraction" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMFq1GHdTFI=", + "_parent": { + "$ref": "AAAAAAFFwMFq1GHa5CM=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": -12, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMFq1GHeicg=", + "_parent": { + "$ref": "AAAAAAFFwMFq1GHa5CM=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": -12, + "height": 12, + "horizontalAlignment": 1 + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 556, + "top": 28, + "width": 103, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwMFq1GHbxIU=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwMFq1GHc3zA=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwMFq1GHdTFI=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwMFq1GHeicg=" + } + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 556, + "top": 28, + "width": 103, + "height": 153, + "nameCompartment": { + "$ref": "AAAAAAFFwMFq1GHa5CM=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwMGle2H29zI=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwMGlemH0Tq8=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqKksmed8=", + "_parent": { + "$ref": "AAAAAAFFwMGle2H29zI=" + }, + "model": { + "$ref": "AAAAAAFFwMGlemH0Tq8=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwMGle2H3I+8=", + "_parent": { + "$ref": "AAAAAAFFwMGle2H29zI=" + }, + "model": { + "$ref": "AAAAAAFFwMGlemH0Tq8=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwMGle2H4B8s=", + "_parent": { + "$ref": "AAAAAAFFwMGle2H3I+8=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 745, + "top": 29, + "width": 110.396484375, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMGle2H5FWo=", + "_parent": { + "$ref": "AAAAAAFFwMGle2H3I+8=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 745, + "top": 43, + "width": 110.396484375, + "height": 12, + "text": "Derive" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMGle2H6wQw=", + "_parent": { + "$ref": "AAAAAAFFwMGle2H3I+8=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 252, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMGle2H7ifs=", + "_parent": { + "$ref": "AAAAAAFFwMGle2H3I+8=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 252, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 740, + "top": 24, + "width": 120.396484375, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwMGle2H4B8s=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwMGle2H5FWo=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwMGle2H6wQw=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwMGle2H7ifs=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwMGle2H8ZWU=", + "_parent": { + "$ref": "AAAAAAFFwMGle2H29zI=" + }, + "model": { + "$ref": "AAAAAAFFwMGlemH0Tq8=" + }, + "subViews": [ + { + "_type": "UMLAttributeView", + "_id": "AAAAAAFFwMJPAWJ40Vg=", + "_parent": { + "$ref": "AAAAAAFFwMGle2H8ZWU=" + }, + "model": { + "$ref": "AAAAAAFFwMJO92J1Y/s=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 745, + "top": 65, + "width": 110.396484375, + "height": 12, + "text": "+computation: String", + "horizontalAlignment": 0 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 740, + "top": 60, + "width": 127.16787719726562, + "height": 22 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwMGle2H9VL8=", + "_parent": { + "$ref": "AAAAAAFFwMGle2H29zI=" + }, + "model": { + "$ref": "AAAAAAFFwMGlemH0Tq8=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 824, + "top": 60, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwMGle2H+hpQ=", + "_parent": { + "$ref": "AAAAAAFFwMGle2H29zI=" + }, + "model": { + "$ref": "AAAAAAFFwMGlemH0Tq8=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 168, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 740, + "top": 24, + "width": 120.396484375, + "height": 58, + "autoResize": true, + "nameCompartment": { + "$ref": "AAAAAAFFwMGle2H3I+8=" + }, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwMGle2H8ZWU=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwMGle2H9VL8=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqKksmed8=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwMGle2H+hpQ=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwMGo6mIepMc=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwMGo6mIcITc=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqK0s9CwU=", + "_parent": { + "$ref": "AAAAAAFFwMGo6mIepMc=" + }, + "model": { + "$ref": "AAAAAAFFwMGo6mIcITc=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwMGo6mIfS5g=", + "_parent": { + "$ref": "AAAAAAFFwMGo6mIepMc=" + }, + "model": { + "$ref": "AAAAAAFFwMGo6mIcITc=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwMGo6mIgcys=", + "_parent": { + "$ref": "AAAAAAFFwMGo6mIfS5g=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 745, + "top": 101, + "width": 69.380859375, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMGo6mIha40=", + "_parent": { + "$ref": "AAAAAAFFwMGo6mIfS5g=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 745, + "top": 115, + "width": 69.380859375, + "height": 12, + "text": "Refine" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMGo6mIiGvE=", + "_parent": { + "$ref": "AAAAAAFFwMGo6mIfS5g=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 276, + "top": 120, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMGo6mIjVCs=", + "_parent": { + "$ref": "AAAAAAFFwMGo6mIfS5g=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 276, + "top": 120, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 740, + "top": 96, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwMGo6mIgcys=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwMGo6mIha40=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwMGo6mIiGvE=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwMGo6mIjVCs=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwMGo6mIkY0Y=", + "_parent": { + "$ref": "AAAAAAFFwMGo6mIepMc=" + }, + "model": { + "$ref": "AAAAAAFFwMGo6mIcITc=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 832, + "top": 172, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwMGo6mIlYhc=", + "_parent": { + "$ref": "AAAAAAFFwMGo6mIepMc=" + }, + "model": { + "$ref": "AAAAAAFFwMGo6mIcITc=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 832, + "top": 172, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwMGo6mImbZE=", + "_parent": { + "$ref": "AAAAAAFFwMGo6mIepMc=" + }, + "model": { + "$ref": "AAAAAAFFwMGo6mIcITc=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 184, + "top": 80, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 740, + "top": 96, + "width": 79.380859375, + "height": 36, + "autoResize": true, + "nameCompartment": { + "$ref": "AAAAAAFFwMGo6mIfS5g=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwMGo6mIkY0Y=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwMGo6mIlYhc=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqK0s9CwU=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwMGo6mImbZE=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwMGrimJGJ0s=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwMGrimJEvvk=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqK0tTuyw=", + "_parent": { + "$ref": "AAAAAAFFwMGrimJGJ0s=" + }, + "model": { + "$ref": "AAAAAAFFwMGrimJEvvk=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwMGrimJHZ7Y=", + "_parent": { + "$ref": "AAAAAAFFwMGrimJGJ0s=" + }, + "model": { + "$ref": "AAAAAAFFwMGrimJEvvk=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwMGrimJIfxU=", + "_parent": { + "$ref": "AAAAAAFFwMGrimJHZ7Y=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 745, + "top": 153, + "width": 69.380859375, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMGrimJJ7uc=", + "_parent": { + "$ref": "AAAAAAFFwMGrimJHZ7Y=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 745, + "top": 167, + "width": 69.380859375, + "height": 12, + "text": "Trace" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMGrimJKI9M=", + "_parent": { + "$ref": "AAAAAAFFwMGrimJHZ7Y=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 324, + "top": 168, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMGrimJL3ag=", + "_parent": { + "$ref": "AAAAAAFFwMGrimJHZ7Y=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 324, + "top": 168, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 740, + "top": 148, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwMGrimJIfxU=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwMGrimJJ7uc=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwMGrimJKI9M=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwMGrimJL3ag=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwMGrimJMCIQ=", + "_parent": { + "$ref": "AAAAAAFFwMGrimJGJ0s=" + }, + "model": { + "$ref": "AAAAAAFFwMGrimJEvvk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 848, + "top": 240, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwMGrimJNPbE=", + "_parent": { + "$ref": "AAAAAAFFwMGrimJGJ0s=" + }, + "model": { + "$ref": "AAAAAAFFwMGrimJEvvk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 848, + "top": 240, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwMGrimJOkXc=", + "_parent": { + "$ref": "AAAAAAFFwMGrimJGJ0s=" + }, + "model": { + "$ref": "AAAAAAFFwMGrimJEvvk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 216, + "top": 112, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 740, + "top": 148, + "width": 79.380859375, + "height": 36, + "autoResize": true, + "nameCompartment": { + "$ref": "AAAAAAFFwMGrimJHZ7Y=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwMGrimJMCIQ=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwMGrimJNPbE=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqK0tTuyw=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwMGrimJOkXc=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwMLTm2KEAI0=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwMLTmmKDF1M=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwMLTm2KFRRg=", + "_parent": { + "$ref": "AAAAAAFFwMLTm2KEAI0=" + }, + "model": { + "$ref": "AAAAAAFFwMLTmmKDF1M=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 698, + "top": 61, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwMLTm2KEAI0=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwMLTm2KGrkQ=", + "_parent": { + "$ref": "AAAAAAFFwMLTm2KEAI0=" + }, + "model": { + "$ref": "AAAAAAFFwMLTmmKDF1M=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 698, + "top": 76, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwMLTm2KEAI0=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwMLTm2KHZTE=", + "_parent": { + "$ref": "AAAAAAFFwMLTm2KEAI0=" + }, + "model": { + "$ref": "AAAAAAFFwMLTmmKDF1M=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 699, + "top": 31, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwMLTm2KEAI0=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwMFq1GHZe+E=" + }, + "tail": { + "$ref": "AAAAAAFFwMGle2H29zI=" + }, + "points": "740:52;658:52", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwMLTm2KFRRg=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwMLTm2KGrkQ=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwMLTm2KHZTE=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwMLXQmKVDuM=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwMLXQmKUyu0=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwMLXQmKW+3c=", + "_parent": { + "$ref": "AAAAAAFFwMLXQmKVDuM=" + }, + "model": { + "$ref": "AAAAAAFFwMLXQmKUyu0=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 698, + "top": 121, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwMLXQmKVDuM=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwMLXQmKXpUQ=", + "_parent": { + "$ref": "AAAAAAFFwMLXQmKVDuM=" + }, + "model": { + "$ref": "AAAAAAFFwMLXQmKUyu0=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 698, + "top": 136, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwMLXQmKVDuM=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwMLXQmKYWOg=", + "_parent": { + "$ref": "AAAAAAFFwMLXQmKVDuM=" + }, + "model": { + "$ref": "AAAAAAFFwMLXQmKUyu0=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 699, + "top": 91, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwMLXQmKVDuM=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwMFq1GHZe+E=" + }, + "tail": { + "$ref": "AAAAAAFFwMGo6mIepMc=" + }, + "points": "740:112;658:112", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwMLXQmKW+3c=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwMLXQmKXpUQ=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwMLXQmKYWOg=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwMLbmmKmAvI=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwMLbmmKloGE=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwMLbmmKnMuM=", + "_parent": { + "$ref": "AAAAAAFFwMLbmmKmAvI=" + }, + "model": { + "$ref": "AAAAAAFFwMLbmmKloGE=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 698, + "top": 169, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwMLbmmKmAvI=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwMLbmmKonTw=", + "_parent": { + "$ref": "AAAAAAFFwMLbmmKmAvI=" + }, + "model": { + "$ref": "AAAAAAFFwMLbmmKloGE=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 698, + "top": 184, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwMLbmmKmAvI=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwMLbmmKpbLQ=", + "_parent": { + "$ref": "AAAAAAFFwMLbmmKmAvI=" + }, + "model": { + "$ref": "AAAAAAFFwMLbmmKloGE=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 699, + "top": 139, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwMLbmmKmAvI=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwMFq1GHZe+E=" + }, + "tail": { + "$ref": "AAAAAAFFwMGrimJGJ0s=" + }, + "points": "740:160;658:160", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwMLbmmKnMuM=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwMLbmmKonTw=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwMLbmmKpbLQ=" + } + }, + { + "_type": "UMLMetaClassView", + "_id": "AAAAAAFFwMYNEWK8jeA=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwMYNEWK7ItA=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwMYNEWK9Wb8=", + "_parent": { + "$ref": "AAAAAAFFwMYNEWK8jeA=" + }, + "model": { + "$ref": "AAAAAAFFwMYNEWK7ItA=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwMYNEWK++fU=", + "_parent": { + "$ref": "AAAAAAFFwMYNEWK9Wb8=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 561, + "top": 833, + "width": 91, + "height": 12, + "text": "«metaClass»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMYNEWK/PY8=", + "_parent": { + "$ref": "AAAAAAFFwMYNEWK9Wb8=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;1", + "containerExtending": true, + "left": 561, + "top": 847, + "width": 91, + "height": 12, + "text": "UMLPackage" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMYNEWLAHjA=", + "_parent": { + "$ref": "AAAAAAFFwMYNEWK9Wb8=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMYNEWLBm9I=", + "_parent": { + "$ref": "AAAAAAFFwMYNEWK9Wb8=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "height": 12, + "horizontalAlignment": 1 + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 556, + "top": 828, + "width": 101, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwMYNEWK++fU=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwMYNEWK/PY8=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwMYNEWLAHjA=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwMYNEWLBm9I=" + } + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 556, + "top": 828, + "width": 101, + "height": 101, + "nameCompartment": { + "$ref": "AAAAAAFFwMYNEWK9Wb8=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwMdnrWLZAY8=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwMdnrWLXWLA=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqLUuNRhM=", + "_parent": { + "$ref": "AAAAAAFFwMdnrWLZAY8=" + }, + "model": { + "$ref": "AAAAAAFFwMdnrWLXWLA=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwMdnrWLaXkY=", + "_parent": { + "$ref": "AAAAAAFFwMdnrWLZAY8=" + }, + "model": { + "$ref": "AAAAAAFFwMdnrWLXWLA=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwMdnrmLbib0=", + "_parent": { + "$ref": "AAAAAAFFwMdnrWLaXkY=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 729, + "top": 837, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMdnrmLclU4=", + "_parent": { + "$ref": "AAAAAAFFwMdnrWLaXkY=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 729, + "top": 851, + "width": 72.51593017578125, + "height": 12, + "text": "Framework" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMdnrmLdBNU=", + "_parent": { + "$ref": "AAAAAAFFwMdnrWLaXkY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMdnrmLeF4I=", + "_parent": { + "$ref": "AAAAAAFFwMdnrWLaXkY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 724, + "top": 832, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwMdnrmLbib0=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwMdnrmLclU4=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwMdnrmLdBNU=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwMdnrmLeF4I=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwMdnrmLf950=", + "_parent": { + "$ref": "AAAAAAFFwMdnrWLZAY8=" + }, + "model": { + "$ref": "AAAAAAFFwMdnrWLXWLA=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 724, + "top": 868, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwMdnrmLgzek=", + "_parent": { + "$ref": "AAAAAAFFwMdnrWLZAY8=" + }, + "model": { + "$ref": "AAAAAAFFwMdnrWLXWLA=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 724, + "top": 878, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwMdnrmLhmpQ=", + "_parent": { + "$ref": "AAAAAAFFwMdnrWLZAY8=" + }, + "model": { + "$ref": "AAAAAAFFwMdnrWLXWLA=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 724, + "top": 832, + "width": 82.51593017578125, + "height": 37, + "nameCompartment": { + "$ref": "AAAAAAFFwMdnrWLaXkY=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwMdnrmLf950=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwMdnrmLgzek=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqLUuNRhM=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwMdnrmLhmpQ=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwMeIHGMCTCk=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwMeIHGMAPDc=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqLUujT3E=", + "_parent": { + "$ref": "AAAAAAFFwMeIHGMCTCk=" + }, + "model": { + "$ref": "AAAAAAFFwMeIHGMAPDc=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwMeIHGMDiPY=", + "_parent": { + "$ref": "AAAAAAFFwMeIHGMCTCk=" + }, + "model": { + "$ref": "AAAAAAFFwMeIHGMAPDc=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwMeIHGMEN4g=", + "_parent": { + "$ref": "AAAAAAFFwMeIHGMDiPY=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 729, + "top": 893, + "width": 75.345703125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMeIHGMFxQc=", + "_parent": { + "$ref": "AAAAAAFFwMeIHGMDiPY=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 729, + "top": 907, + "width": 75.345703125, + "height": 12, + "text": "ModelLibrary" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMeIHGMG6CQ=", + "_parent": { + "$ref": "AAAAAAFFwMeIHGMDiPY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "top": -60, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMeIHGMH2dQ=", + "_parent": { + "$ref": "AAAAAAFFwMeIHGMDiPY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "top": -60, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 724, + "top": 888, + "width": 85.345703125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwMeIHGMEN4g=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwMeIHGMFxQc=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwMeIHGMG6CQ=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwMeIHGMH2dQ=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwMeIHGMI7hI=", + "_parent": { + "$ref": "AAAAAAFFwMeIHGMCTCk=" + }, + "model": { + "$ref": "AAAAAAFFwMeIHGMAPDc=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 724, + "top": 904, + "width": 85, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwMeIHGMJi90=", + "_parent": { + "$ref": "AAAAAAFFwMeIHGMCTCk=" + }, + "model": { + "$ref": "AAAAAAFFwMeIHGMAPDc=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 724, + "top": 914, + "width": 85, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwMeIHGMK1pc=", + "_parent": { + "$ref": "AAAAAAFFwMeIHGMCTCk=" + }, + "model": { + "$ref": "AAAAAAFFwMeIHGMAPDc=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "top": -40, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 724, + "top": 888, + "width": 85.345703125, + "height": 37, + "nameCompartment": { + "$ref": "AAAAAAFFwMeIHGMDiPY=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwMeIHGMI7hI=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwMeIHGMJi90=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqLUujT3E=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwMeIHGMK1pc=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwMevo2Mq4Ew=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwMevo2MpIU4=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwMevo2Mr7wQ=", + "_parent": { + "$ref": "AAAAAAFFwMevo2Mq4Ew=" + }, + "model": { + "$ref": "AAAAAAFFwMevo2MpIU4=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 689, + "top": 861, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwMevo2Mq4Ew=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwMevo2Msv/w=", + "_parent": { + "$ref": "AAAAAAFFwMevo2Mq4Ew=" + }, + "model": { + "$ref": "AAAAAAFFwMevo2MpIU4=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 689, + "top": 876, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwMevo2Mq4Ew=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwMevo2MtL5c=", + "_parent": { + "$ref": "AAAAAAFFwMevo2Mq4Ew=" + }, + "model": { + "$ref": "AAAAAAFFwMevo2MpIU4=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 690, + "top": 831, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwMevo2Mq4Ew=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwMYNEWK8jeA=" + }, + "tail": { + "$ref": "AAAAAAFFwMdnrWLZAY8=" + }, + "points": "724:852;656:852", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwMevo2Mr7wQ=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwMevo2Msv/w=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwMevo2MtL5c=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwMe0G2M7rmg=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwMe0G2M69PQ=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwMe0G2M8gls=", + "_parent": { + "$ref": "AAAAAAFFwMe0G2M7rmg=" + }, + "model": { + "$ref": "AAAAAAFFwMe0G2M69PQ=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 689, + "top": 917, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwMe0G2M7rmg=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwMe0G2M9WEg=", + "_parent": { + "$ref": "AAAAAAFFwMe0G2M7rmg=" + }, + "model": { + "$ref": "AAAAAAFFwMe0G2M69PQ=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 689, + "top": 932, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwMe0G2M7rmg=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwMe0G2M+CD8=", + "_parent": { + "$ref": "AAAAAAFFwMe0G2M7rmg=" + }, + "model": { + "$ref": "AAAAAAFFwMe0G2M69PQ=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 690, + "top": 887, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwMe0G2M7rmg=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwMYNEWK8jeA=" + }, + "tail": { + "$ref": "AAAAAAFFwMeIHGMCTCk=" + }, + "points": "724:908;656:908", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwMe0G2M8gls=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwMe0G2M9WEg=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwMe0G2M+CD8=" + } + } + ] + }, + { + "_type": "UMLMetaClass", + "_id": "AAAAAAFElnFrT1S7Kic=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "UMLClassifier" + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFElnF1nFTY/Sw=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Realization", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFElnGGLFUFZFA=", + "_parent": { + "$ref": "AAAAAAFElnF1nFTY/Sw=" + }, + "source": { + "$ref": "AAAAAAFElnF1nFTY/Sw=" + }, + "target": { + "$ref": "AAAAAAFElnFrT1S7Kic=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFElnF1nFTZHOU=", + "_parent": { + "$ref": "AAAAAAFElnF1nFTY/Sw=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFElnJRglVKSoc=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Specification", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFElnKVuVV4pBU=", + "_parent": { + "$ref": "AAAAAAFElnJRglVKSoc=" + }, + "source": { + "$ref": "AAAAAAFElnJRglVKSoc=" + }, + "target": { + "$ref": "AAAAAAFElnFrT1S7Kic=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFElnJRglVLifA=", + "_parent": { + "$ref": "AAAAAAFElnJRglVKSoc=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFJsYgDTM+Z6E=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "entity", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFJsZx3DOCac8=", + "_parent": { + "$ref": "AAAAAAFFJsYgDTM+Z6E=" + }, + "source": { + "$ref": "AAAAAAFFJsYgDTM+Z6E=" + }, + "target": { + "$ref": "AAAAAAFFJsZbpDNobIs=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFJsYgDTM/qY8=", + "_parent": { + "$ref": "AAAAAAFFJsYgDTM+Z6E=" + }, + "width": 40, + "height": 40, + "content": "var w = rect.getWidth(),\n m = w / 10;\ncanvas.fillEllipse(rect.x1 + m, rect.y1 + m, rect.x2 - m, rect.y2 - m);\ncanvas.ellipse(rect.x1 + m, rect.y1 + m, rect.x2 - m, rect.y2 - m);\ncanvas.line(rect.x1 + m, rect.y2 - m, rect.x2 - m, rect.y2 - m);\n" + } + }, + { + "_type": "UMLMetaClass", + "_id": "AAAAAAFFJsZbpDNobIs=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "UMLClass" + }, + { + "_type": "UMLMetaClass", + "_id": "AAAAAAFFwKqhJFq06mA=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "UMLArtifact" + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwKsvdVrRJUQ=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "File", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwK5AeFyZpVg=", + "_parent": { + "$ref": "AAAAAAFFwKsvdVrRJUQ=" + }, + "source": { + "$ref": "AAAAAAFFwKsvdVrRJUQ=" + }, + "target": { + "$ref": "AAAAAAFFwKqhJFq06mA=" + } + } + ], + "isAbstract": true, + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwKsvdVrSLo0=", + "_parent": { + "$ref": "AAAAAAFFwKsvdVrRJUQ=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwKtwS1r6wew=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Document", + "ownedElements": [ + { + "_type": "UMLGeneralization", + "_id": "AAAAAAFFwKzkslvX4gU=", + "_parent": { + "$ref": "AAAAAAFFwKtwS1r6wew=" + }, + "source": { + "$ref": "AAAAAAFFwKtwS1r6wew=" + }, + "target": { + "$ref": "AAAAAAFFwKsvdVrRJUQ=" + } + }, + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwK4k1VxEEpM=", + "_parent": { + "$ref": "AAAAAAFFwKtwS1r6wew=" + }, + "source": { + "$ref": "AAAAAAFFwKtwS1r6wew=" + }, + "target": { + "$ref": "AAAAAAFFwKqhJFq06mA=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwKtwS1r7XqE=", + "_parent": { + "$ref": "AAAAAAFFwKtwS1r6wew=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwKuBulsidLQ=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Executable", + "ownedElements": [ + { + "_type": "UMLGeneralization", + "_id": "AAAAAAFFwKzsCVvo11g=", + "_parent": { + "$ref": "AAAAAAFFwKuBulsidLQ=" + }, + "source": { + "$ref": "AAAAAAFFwKuBulsidLQ=" + }, + "target": { + "$ref": "AAAAAAFFwKsvdVrRJUQ=" + } + }, + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwK4o4VxVx00=", + "_parent": { + "$ref": "AAAAAAFFwKuBulsidLQ=" + }, + "source": { + "$ref": "AAAAAAFFwKuBulsidLQ=" + }, + "target": { + "$ref": "AAAAAAFFwKqhJFq06mA=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwKuBulsjhp0=", + "_parent": { + "$ref": "AAAAAAFFwKuBulsidLQ=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwKuIMltKnQQ=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Library", + "ownedElements": [ + { + "_type": "UMLGeneralization", + "_id": "AAAAAAFFwKzxcVv56Dg=", + "_parent": { + "$ref": "AAAAAAFFwKuIMltKnQQ=" + }, + "source": { + "$ref": "AAAAAAFFwKuIMltKnQQ=" + }, + "target": { + "$ref": "AAAAAAFFwKsvdVrRJUQ=" + } + }, + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwK4tiVxmVJM=", + "_parent": { + "$ref": "AAAAAAFFwKuIMltKnQQ=" + }, + "source": { + "$ref": "AAAAAAFFwKuIMltKnQQ=" + }, + "target": { + "$ref": "AAAAAAFFwKqhJFq06mA=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwKuIMltLkmg=", + "_parent": { + "$ref": "AAAAAAFFwKuIMltKnQQ=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwKuS0ltysPk=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Script", + "ownedElements": [ + { + "_type": "UMLGeneralization", + "_id": "AAAAAAFFwKz3OVwK9hs=", + "_parent": { + "$ref": "AAAAAAFFwKuS0ltysPk=" + }, + "source": { + "$ref": "AAAAAAFFwKuS0ltysPk=" + }, + "target": { + "$ref": "AAAAAAFFwKsvdVrRJUQ=" + } + }, + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwK41YVx3Hr0=", + "_parent": { + "$ref": "AAAAAAFFwKuS0ltysPk=" + }, + "source": { + "$ref": "AAAAAAFFwKuS0ltysPk=" + }, + "target": { + "$ref": "AAAAAAFFwKqhJFq06mA=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwKuS0ltz9pw=", + "_parent": { + "$ref": "AAAAAAFFwKuS0ltysPk=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwKueMVuaLXM=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Source", + "ownedElements": [ + { + "_type": "UMLGeneralization", + "_id": "AAAAAAFFwKz9mFwbfDg=", + "_parent": { + "$ref": "AAAAAAFFwKueMVuaLXM=" + }, + "source": { + "$ref": "AAAAAAFFwKueMVuaLXM=" + }, + "target": { + "$ref": "AAAAAAFFwKsvdVrRJUQ=" + } + }, + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwK47MFyIL/c=", + "_parent": { + "$ref": "AAAAAAFFwKueMVuaLXM=" + }, + "source": { + "$ref": "AAAAAAFFwKueMVuaLXM=" + }, + "target": { + "$ref": "AAAAAAFFwKqhJFq06mA=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwKueMlubedY=", + "_parent": { + "$ref": "AAAAAAFFwKueMVuaLXM=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLMetaClass", + "_id": "AAAAAAFFwK/k1ly00Ec=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "UMLBehavioralFeature" + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwLBdO1zQosE=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Destroy", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwLDMaFz5C14=", + "_parent": { + "$ref": "AAAAAAFFwLBdO1zQosE=" + }, + "source": { + "$ref": "AAAAAAFFwLBdO1zQosE=" + }, + "target": { + "$ref": "AAAAAAFFwK/k1ly00Ec=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwLBdO1zR7Ak=", + "_parent": { + "$ref": "AAAAAAFFwLBdO1zQosE=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwLFUbV0QQVA=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Auxiliary", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwLNej157D6Y=", + "_parent": { + "$ref": "AAAAAAFFwLFUbV0QQVA=" + }, + "source": { + "$ref": "AAAAAAFFwLFUbV0QQVA=" + }, + "target": { + "$ref": "AAAAAAFFJsZbpDNobIs=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwLFUbV0RoPU=", + "_parent": { + "$ref": "AAAAAAFFwLFUbV0QQVA=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwLFu8104he4=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Focus", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwLNkZ16Mp7Y=", + "_parent": { + "$ref": "AAAAAAFFwLFu8104he4=" + }, + "source": { + "$ref": "AAAAAAFFwLFu8104he4=" + }, + "target": { + "$ref": "AAAAAAFFJsZbpDNobIs=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwLFu9F05JGE=", + "_parent": { + "$ref": "AAAAAAFFwLFu8104he4=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwLF4tF1g4No=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Metaclass", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwLNn916d4Yc=", + "_parent": { + "$ref": "AAAAAAFFwLF4tF1g4No=" + }, + "source": { + "$ref": "AAAAAAFFwLF4tF1g4No=" + }, + "target": { + "$ref": "AAAAAAFFJsZbpDNobIs=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwLF4tF1h94I=", + "_parent": { + "$ref": "AAAAAAFFwLF4tF1g4No=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwLF/G12IJ54=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "ImplementationClass", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwLNr116u93k=", + "_parent": { + "$ref": "AAAAAAFFwLF/G12IJ54=" + }, + "source": { + "$ref": "AAAAAAFFwLF/G12IJ54=" + }, + "target": { + "$ref": "AAAAAAFFJsZbpDNobIs=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwLF/G12JIns=", + "_parent": { + "$ref": "AAAAAAFFwLF/G12IJ54=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwLGEO12wqJ8=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Type", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwLNvdl6/WJI=", + "_parent": { + "$ref": "AAAAAAFFwLGEO12wqJ8=" + }, + "source": { + "$ref": "AAAAAAFFwLGEO12wqJ8=" + }, + "target": { + "$ref": "AAAAAAFFJsZbpDNobIs=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwLGEPF2x7bg=", + "_parent": { + "$ref": "AAAAAAFFwLGEO12wqJ8=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwLGI813YL3s=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Utility", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwLN0fl7QL9o=", + "_parent": { + "$ref": "AAAAAAFFwLGI813YL3s=" + }, + "source": { + "$ref": "AAAAAAFFwLGI813YL3s=" + }, + "target": { + "$ref": "AAAAAAFFJsZbpDNobIs=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwLGI813ZPxY=", + "_parent": { + "$ref": "AAAAAAFFwLGI813YL3s=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLProfileDiagram", + "_id": "AAAAAAFFwLKxU14QPaE=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Robustness Stereotypes", + "ownedViews": [ + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwLL0NF4VWXk=", + "_parent": { + "$ref": "AAAAAAFFwLKxU14QPaE=" + }, + "model": { + "$ref": "AAAAAAFFJsYgDTM+Z6E=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqMEwRREE=", + "_parent": { + "$ref": "AAAAAAFFwLL0NF4VWXk=" + }, + "model": { + "$ref": "AAAAAAFFJsYgDTM+Z6E=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwLL0NF4WzoE=", + "_parent": { + "$ref": "AAAAAAFFwLL0NF4VWXk=" + }, + "model": { + "$ref": "AAAAAAFFJsYgDTM+Z6E=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwLL0NF4X88I=", + "_parent": { + "$ref": "AAAAAAFFwLL0NF4WzoE=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 217, + "top": 89, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLL0NF4YSt8=", + "_parent": { + "$ref": "AAAAAAFFwLL0NF4WzoE=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 217, + "top": 103, + "width": 72.51593017578125, + "height": 12, + "text": "entity" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLL0NF4ZQaQ=", + "_parent": { + "$ref": "AAAAAAFFwLL0NF4WzoE=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -1065, + "top": -270, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLL0NF4asxs=", + "_parent": { + "$ref": "AAAAAAFFwLL0NF4WzoE=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -1065, + "top": -270, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 212, + "top": 84, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLL0NF4X88I=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwLL0NF4YSt8=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwLL0NF4ZQaQ=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLL0NF4asxs=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwLL0NF4bgXg=", + "_parent": { + "$ref": "AAAAAAFFwLL0NF4VWXk=" + }, + "model": { + "$ref": "AAAAAAFFJsYgDTM+Z6E=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 92, + "top": -28, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwLL0NF4cZ88=", + "_parent": { + "$ref": "AAAAAAFFwLL0NF4VWXk=" + }, + "model": { + "$ref": "AAAAAAFFJsYgDTM+Z6E=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 92, + "top": -18, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwLL0NF4dJaE=", + "_parent": { + "$ref": "AAAAAAFFwLL0NF4VWXk=" + }, + "model": { + "$ref": "AAAAAAFFJsYgDTM+Z6E=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -710, + "top": -180, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 212, + "top": 84, + "width": 82.51593017578125, + "height": 37, + "nameCompartment": { + "$ref": "AAAAAAFFwLL0NF4WzoE=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwLL0NF4bgXg=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwLL0NF4cZ88=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqMEwRREE=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwLL0NF4dJaE=" + } + }, + { + "_type": "UMLMetaClassView", + "_id": "AAAAAAFFwLMO8l44tWU=", + "_parent": { + "$ref": "AAAAAAFFwLKxU14QPaE=" + }, + "model": { + "$ref": "AAAAAAFFJsZbpDNobIs=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwLMO8l45ook=", + "_parent": { + "$ref": "AAAAAAFFwLMO8l44tWU=" + }, + "model": { + "$ref": "AAAAAAFFJsZbpDNobIs=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwLMO8l46Nac=", + "_parent": { + "$ref": "AAAAAAFFwLMO8l45ook=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 33, + "top": 33, + "width": 79, + "height": 12, + "text": "«metaClass»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLMO8l47xu4=", + "_parent": { + "$ref": "AAAAAAFFwLMO8l45ook=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;1", + "containerExtending": true, + "left": 33, + "top": 47, + "width": 79, + "height": 12, + "text": "UMLClass" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLMO8l48V+s=", + "_parent": { + "$ref": "AAAAAAFFwLMO8l45ook=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": -489, + "top": -414, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLMO8l490+g=", + "_parent": { + "$ref": "AAAAAAFFwLMO8l45ook=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": -489, + "top": -414, + "height": 12, + "horizontalAlignment": 1 + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 28, + "top": 28, + "width": 89, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLMO8l46Nac=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwLMO8l47xu4=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwLMO8l48V+s=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLMO8l490+g=" + } + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 28, + "top": 28, + "width": 89, + "height": 149, + "nameCompartment": { + "$ref": "AAAAAAFFwLMO8l45ook=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwLMO814+17w=", + "_parent": { + "$ref": "AAAAAAFFwLKxU14QPaE=" + }, + "model": { + "$ref": "AAAAAAFFJsZx3DOCac8=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLMO814/vLk=", + "_parent": { + "$ref": "AAAAAAFFwLMO814+17w=" + }, + "model": { + "$ref": "AAAAAAFFJsZx3DOCac8=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 163, + "top": 109, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLMO814+17w=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLMO815A2sw=", + "_parent": { + "$ref": "AAAAAAFFwLMO814+17w=" + }, + "model": { + "$ref": "AAAAAAFFJsZx3DOCac8=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 163, + "top": 124, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwLMO814+17w=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLMO815BAcU=", + "_parent": { + "$ref": "AAAAAAFFwLMO814+17w=" + }, + "model": { + "$ref": "AAAAAAFFJsZx3DOCac8=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 164, + "top": 79, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLMO814+17w=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwLMO8l44tWU=" + }, + "tail": { + "$ref": "AAAAAAFFwLL0NF4VWXk=" + }, + "points": "212:100;116:100", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwLMO814/vLk=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLMO815A2sw=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLMO815BAcU=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwx8Q/35wG9A=", + "_parent": { + "$ref": "AAAAAAFFwLKxU14QPaE=" + }, + "model": { + "$ref": "AAAAAAFFwx8Q/35u/80=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqMUw9MBk=", + "_parent": { + "$ref": "AAAAAAFFwx8Q/35wG9A=" + }, + "model": { + "$ref": "AAAAAAFFwx8Q/35u/80=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwx8Q/35xpyY=", + "_parent": { + "$ref": "AAAAAAFFwx8Q/35wG9A=" + }, + "model": { + "$ref": "AAAAAAFFwx8Q/35u/80=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwx8Q/35yVU8=", + "_parent": { + "$ref": "AAAAAAFFwx8Q/35xpyY=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 217, + "top": 37, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwx8Q/35z0VE=", + "_parent": { + "$ref": "AAAAAAFFwx8Q/35xpyY=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 217, + "top": 51, + "width": 72.51593017578125, + "height": 12, + "text": "control" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwx8Q/3506PU=", + "_parent": { + "$ref": "AAAAAAFFwx8Q/35xpyY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -336, + "top": -312, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwx8Q/351cP0=", + "_parent": { + "$ref": "AAAAAAFFwx8Q/35xpyY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -336, + "top": -312, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 212, + "top": 32, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwx8Q/35yVU8=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwx8Q/35z0VE=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwx8Q/3506PU=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwx8Q/351cP0=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwx8RAH52xko=", + "_parent": { + "$ref": "AAAAAAFFwx8Q/35wG9A=" + }, + "model": { + "$ref": "AAAAAAFFwx8Q/35u/80=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 76, + "top": -4, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwx8RAH53MWs=", + "_parent": { + "$ref": "AAAAAAFFwx8Q/35wG9A=" + }, + "model": { + "$ref": "AAAAAAFFwx8Q/35u/80=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 76, + "top": 6, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwx8RAH54kik=", + "_parent": { + "$ref": "AAAAAAFFwx8Q/35wG9A=" + }, + "model": { + "$ref": "AAAAAAFFwx8Q/35u/80=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -224, + "top": -208, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 212, + "top": 32, + "width": 82.51593017578125, + "height": 37, + "nameCompartment": { + "$ref": "AAAAAAFFwx8Q/35xpyY=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwx8RAH52xko=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwx8RAH53MWs=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqMUw9MBk=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwx8RAH54kik=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwyAHeH6a9yk=", + "_parent": { + "$ref": "AAAAAAFFwLKxU14QPaE=" + }, + "model": { + "$ref": "AAAAAAFFwyAHeH6Znas=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwyAHeX6b9JY=", + "_parent": { + "$ref": "AAAAAAFFwyAHeH6a9yk=" + }, + "model": { + "$ref": "AAAAAAFFwyAHeH6Znas=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 163, + "top": 61, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwyAHeH6a9yk=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwyAHeX6cKyY=", + "_parent": { + "$ref": "AAAAAAFFwyAHeH6a9yk=" + }, + "model": { + "$ref": "AAAAAAFFwyAHeH6Znas=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 163, + "top": 76, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwyAHeH6a9yk=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwyAHeX6dvIk=", + "_parent": { + "$ref": "AAAAAAFFwyAHeH6a9yk=" + }, + "model": { + "$ref": "AAAAAAFFwyAHeH6Znas=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 164, + "top": 31, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwyAHeH6a9yk=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwLMO8l44tWU=" + }, + "tail": { + "$ref": "AAAAAAFFwx8Q/35wG9A=" + }, + "points": "212:52;116:52", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwyAHeX6b9JY=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwyAHeX6cKyY=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwyAHeX6dvIk=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFw0h1/QXNqo4=", + "_parent": { + "$ref": "AAAAAAFFwLKxU14QPaE=" + }, + "model": { + "$ref": "AAAAAAFFw0h1/QXL978=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqMkxa+TA=", + "_parent": { + "$ref": "AAAAAAFFw0h1/QXNqo4=" + }, + "model": { + "$ref": "AAAAAAFFw0h1/QXL978=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFw0h1/gXOBI4=", + "_parent": { + "$ref": "AAAAAAFFw0h1/QXNqo4=" + }, + "model": { + "$ref": "AAAAAAFFw0h1/QXL978=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFw0h1/gXPA/w=", + "_parent": { + "$ref": "AAAAAAFFw0h1/gXOBI4=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 217, + "top": 141, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFw0h1/gXQ/LI=", + "_parent": { + "$ref": "AAAAAAFFw0h1/gXOBI4=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 217, + "top": 155, + "width": 72.51593017578125, + "height": 12, + "text": "boundary" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFw0h1/gXRrB4=", + "_parent": { + "$ref": "AAAAAAFFw0h1/gXOBI4=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 96, + "top": -360, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFw0h1/gXSVgA=", + "_parent": { + "$ref": "AAAAAAFFw0h1/gXOBI4=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 96, + "top": -360, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 212, + "top": 136, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFw0h1/gXPA/w=" + }, + "nameLabel": { + "$ref": "AAAAAAFFw0h1/gXQ/LI=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFw0h1/gXRrB4=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFw0h1/gXSVgA=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFw0h1/gXTCRY=", + "_parent": { + "$ref": "AAAAAAFFw0h1/QXNqo4=" + }, + "model": { + "$ref": "AAAAAAFFw0h1/QXL978=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 72, + "top": -20, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFw0h1/gXUu1g=", + "_parent": { + "$ref": "AAAAAAFFw0h1/QXNqo4=" + }, + "model": { + "$ref": "AAAAAAFFw0h1/QXL978=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 72, + "top": -10, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFw0h1/gXVEL8=", + "_parent": { + "$ref": "AAAAAAFFw0h1/QXNqo4=" + }, + "model": { + "$ref": "AAAAAAFFw0h1/QXL978=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 64, + "top": -240, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 212, + "top": 136, + "width": 82.51593017578125, + "height": 37, + "nameCompartment": { + "$ref": "AAAAAAFFw0h1/gXOBI4=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFw0h1/gXTCRY=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFw0h1/gXUu1g=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqMkxa+TA=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFw0h1/gXVEL8=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFw0o5p5IVMGM=", + "_parent": { + "$ref": "AAAAAAFFwLKxU14QPaE=" + }, + "model": { + "$ref": "AAAAAAFFw0o5ppIUB2s=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFw0o5p5IW5Js=", + "_parent": { + "$ref": "AAAAAAFFw0o5p5IVMGM=" + }, + "model": { + "$ref": "AAAAAAFFw0o5ppIUB2s=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 163, + "top": 165, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFw0o5p5IVMGM=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFw0o5p5IXSKA=", + "_parent": { + "$ref": "AAAAAAFFw0o5p5IVMGM=" + }, + "model": { + "$ref": "AAAAAAFFw0o5ppIUB2s=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 163, + "top": 180, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFw0o5p5IVMGM=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFw0o5p5IY/GE=", + "_parent": { + "$ref": "AAAAAAFFw0o5p5IVMGM=" + }, + "model": { + "$ref": "AAAAAAFFw0o5ppIUB2s=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 164, + "top": 135, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFw0o5p5IVMGM=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwLMO8l44tWU=" + }, + "tail": { + "$ref": "AAAAAAFFw0h1/QXNqo4=" + }, + "points": "212:156;116:156", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFw0o5p5IW5Js=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFw0o5p5IXSKA=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFw0o5p5IY/GE=" + } + } + ] + }, + { + "_type": "UMLMetaClass", + "_id": "AAAAAAFFwLRECl7r1R4=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "UMLComponent" + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwLR8CF8G68k=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Entity", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwLV9gV/Xhk4=", + "_parent": { + "$ref": "AAAAAAFFwLR8CF8G68k=" + }, + "source": { + "$ref": "AAAAAAFFwLR8CF8G68k=" + }, + "target": { + "$ref": "AAAAAAFFwLRECl7r1R4=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwLR8CF8HOik=", + "_parent": { + "$ref": "AAAAAAFFwLR8CF8G68k=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwLSByF8umMo=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Implementation", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwLWA0V/olVk=", + "_parent": { + "$ref": "AAAAAAFFwLSByF8umMo=" + }, + "source": { + "$ref": "AAAAAAFFwLSByF8umMo=" + }, + "target": { + "$ref": "AAAAAAFFwLRECl7r1R4=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwLSByF8vzKA=", + "_parent": { + "$ref": "AAAAAAFFwLSByF8umMo=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwLSIN19WMnE=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Process", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwLWEUV/5Qq4=", + "_parent": { + "$ref": "AAAAAAFFwLSIN19WMnE=" + }, + "source": { + "$ref": "AAAAAAFFwLSIN19WMnE=" + }, + "target": { + "$ref": "AAAAAAFFwLRECl7r1R4=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwLSIN19XVng=", + "_parent": { + "$ref": "AAAAAAFFwLSIN19WMnE=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwLSO/19+cMY=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Service", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwLWIQWAKKPo=", + "_parent": { + "$ref": "AAAAAAFFwLSO/19+cMY=" + }, + "source": { + "$ref": "AAAAAAFFwLSO/19+cMY=" + }, + "target": { + "$ref": "AAAAAAFFwLRECl7r1R4=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwLSO/19/YUk=", + "_parent": { + "$ref": "AAAAAAFFwLSO/19+cMY=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwLSXP1+mTVk=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Subsystem", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwLWMgWAb2Sk=", + "_parent": { + "$ref": "AAAAAAFFwLSXP1+mTVk=" + }, + "source": { + "$ref": "AAAAAAFFwLSXP1+mTVk=" + }, + "target": { + "$ref": "AAAAAAFFwLRECl7r1R4=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwLSXP1+njeI=", + "_parent": { + "$ref": "AAAAAAFFwLSXP1+mTVk=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLMetaClass", + "_id": "AAAAAAFFwL2WeGA460g=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "UMLDependency" + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwL4D0mBXwu4=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Create", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwL+LCGFfPQs=", + "_parent": { + "$ref": "AAAAAAFFwL4D0mBXwu4=" + }, + "source": { + "$ref": "AAAAAAFFwL4D0mBXwu4=" + }, + "target": { + "$ref": "AAAAAAFFwK/k1ly00Ec=" + } + }, + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwL+O8GFwbog=", + "_parent": { + "$ref": "AAAAAAFFwL4D0mBXwu4=" + }, + "source": { + "$ref": "AAAAAAFFwL4D0mBXwu4=" + }, + "target": { + "$ref": "AAAAAAFFwL2WeGA460g=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwL4D0mBYXVU=", + "_parent": { + "$ref": "AAAAAAFFwL4D0mBXwu4=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwL4h4WCAEkg=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Call", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwL+SkWGBCOg=", + "_parent": { + "$ref": "AAAAAAFFwL4h4WCAEkg=" + }, + "source": { + "$ref": "AAAAAAFFwL4h4WCAEkg=" + }, + "target": { + "$ref": "AAAAAAFFwL2WeGA460g=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwL4h4WCBKPU=", + "_parent": { + "$ref": "AAAAAAFFwL4h4WCAEkg=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwL45WWCpJ0o=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Instantiate", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwL+WL2GScgY=", + "_parent": { + "$ref": "AAAAAAFFwL45WWCpJ0o=" + }, + "source": { + "$ref": "AAAAAAFFwL45WWCpJ0o=" + }, + "target": { + "$ref": "AAAAAAFFwL2WeGA460g=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwL45WWCq/8I=", + "_parent": { + "$ref": "AAAAAAFFwL45WWCpJ0o=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwL5hP2DSEFk=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Responsibility", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwL+Z72GjzGw=", + "_parent": { + "$ref": "AAAAAAFFwL5hP2DSEFk=" + }, + "source": { + "$ref": "AAAAAAFFwL5hP2DSEFk=" + }, + "target": { + "$ref": "AAAAAAFFwL2WeGA460g=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwL5hQGDTCjI=", + "_parent": { + "$ref": "AAAAAAFFwL5hP2DSEFk=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwL7KdWEoDhA=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Send", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwL+eh2G01aU=", + "_parent": { + "$ref": "AAAAAAFFwL7KdWEoDhA=" + }, + "source": { + "$ref": "AAAAAAFFwL7KdWEoDhA=" + }, + "target": { + "$ref": "AAAAAAFFwL2WeGA460g=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwL7KdWEpx8M=", + "_parent": { + "$ref": "AAAAAAFFwL7KdWEoDhA=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLMetaClass", + "_id": "AAAAAAFFwMFq1GHYSKM=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "UMLAbstraction" + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwMGlemH0Tq8=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Derive", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwMLTmmKDF1M=", + "_parent": { + "$ref": "AAAAAAFFwMGlemH0Tq8=" + }, + "source": { + "$ref": "AAAAAAFFwMGlemH0Tq8=" + }, + "target": { + "$ref": "AAAAAAFFwMFq1GHYSKM=" + } + } + ], + "attributes": [ + { + "_type": "UMLAttribute", + "_id": "AAAAAAFFwMJO92J1Y/s=", + "_parent": { + "$ref": "AAAAAAFFwMGlemH0Tq8=" + }, + "name": "computation", + "type": "String" + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwMGlemH1M8k=", + "_parent": { + "$ref": "AAAAAAFFwMGlemH0Tq8=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwMGo6mIcITc=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Refine", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwMLXQmKUyu0=", + "_parent": { + "$ref": "AAAAAAFFwMGo6mIcITc=" + }, + "source": { + "$ref": "AAAAAAFFwMGo6mIcITc=" + }, + "target": { + "$ref": "AAAAAAFFwMFq1GHYSKM=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwMGo6mIdBMU=", + "_parent": { + "$ref": "AAAAAAFFwMGo6mIcITc=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwMGrimJEvvk=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Trace", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwMLbmmKloGE=", + "_parent": { + "$ref": "AAAAAAFFwMGrimJEvvk=" + }, + "source": { + "$ref": "AAAAAAFFwMGrimJEvvk=" + }, + "target": { + "$ref": "AAAAAAFFwMFq1GHYSKM=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwMGrimJF+z8=", + "_parent": { + "$ref": "AAAAAAFFwMGrimJEvvk=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLMetaClass", + "_id": "AAAAAAFFwMYNEWK7ItA=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "UMLPackage" + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwMdnrWLXWLA=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Framework", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwMevo2MpIU4=", + "_parent": { + "$ref": "AAAAAAFFwMdnrWLXWLA=" + }, + "source": { + "$ref": "AAAAAAFFwMdnrWLXWLA=" + }, + "target": { + "$ref": "AAAAAAFFwMYNEWK7ItA=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwMdnrWLYFcM=", + "_parent": { + "$ref": "AAAAAAFFwMdnrWLXWLA=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwMeIHGMAPDc=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "ModelLibrary", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwMe0G2M69PQ=", + "_parent": { + "$ref": "AAAAAAFFwMeIHGMAPDc=" + }, + "source": { + "$ref": "AAAAAAFFwMeIHGMAPDc=" + }, + "target": { + "$ref": "AAAAAAFFwMYNEWK7ItA=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwMeIHGMBKKk=", + "_parent": { + "$ref": "AAAAAAFFwMeIHGMAPDc=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLProfileDiagram", + "_id": "AAAAAAFFwQCuI7bLjDk=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "StandardProfileL3", + "ownedViews": [ + { + "_type": "UMLMetaClassView", + "_id": "AAAAAAFFwQHC9rbwK6A=", + "_parent": { + "$ref": "AAAAAAFFwQCuI7bLjDk=" + }, + "model": { + "$ref": "AAAAAAFFwQHC9rbvUkk=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwQHC9rbx7Lo=", + "_parent": { + "$ref": "AAAAAAFFwQHC9rbwK6A=" + }, + "model": { + "$ref": "AAAAAAFFwQHC9rbvUkk=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwQHC9rbyTUQ=", + "_parent": { + "$ref": "AAAAAAFFwQHC9rbx7Lo=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 45, + "top": 121, + "width": 107, + "height": 12, + "text": "«metaClass»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwQHC9rbzlgQ=", + "_parent": { + "$ref": "AAAAAAFFwQHC9rbx7Lo=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;1", + "containerExtending": true, + "left": 45, + "top": 135, + "width": 107, + "height": 12, + "text": "UMLModel" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwQHC9rb0L9g=", + "_parent": { + "$ref": "AAAAAAFFwQHC9rbx7Lo=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": -48, + "top": -168, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwQHC9rb1XIk=", + "_parent": { + "$ref": "AAAAAAFFwQHC9rbx7Lo=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": -48, + "top": -168, + "height": 12, + "horizontalAlignment": 1 + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 40, + "top": 116, + "width": 117, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwQHC9rbyTUQ=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwQHC9rbzlgQ=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwQHC9rb0L9g=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwQHC9rb1XIk=" + } + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 40, + "top": 116, + "width": 117, + "height": 97, + "nameCompartment": { + "$ref": "AAAAAAFFwQHC9rbx7Lo=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwQHjjbcLQPM=", + "_parent": { + "$ref": "AAAAAAFFwQCuI7bLjDk=" + }, + "model": { + "$ref": "AAAAAAFFwQHjjbcJ4Ks=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqN0zJrS0=", + "_parent": { + "$ref": "AAAAAAFFwQHjjbcLQPM=" + }, + "model": { + "$ref": "AAAAAAFFwQHjjbcJ4Ks=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwQHjjbcMlRY=", + "_parent": { + "$ref": "AAAAAAFFwQHjjbcLQPM=" + }, + "model": { + "$ref": "AAAAAAFFwQHjjbcJ4Ks=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwQHjjbcNrIk=", + "_parent": { + "$ref": "AAAAAAFFwQHjjbcMlRY=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 229, + "top": 41, + "width": 115, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwQHjjbcOnWs=", + "_parent": { + "$ref": "AAAAAAFFwQHjjbcMlRY=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 229, + "top": 55, + "width": 115, + "height": 12, + "text": "BuildComponent" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwQHjjbcPLIM=", + "_parent": { + "$ref": "AAAAAAFFwQHjjbcMlRY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 108, + "top": -48, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwQHjjbcQOtc=", + "_parent": { + "$ref": "AAAAAAFFwQHjjbcMlRY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 108, + "top": -48, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 224, + "top": 36, + "width": 125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwQHjjbcNrIk=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwQHjjbcOnWs=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwQHjjbcPLIM=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwQHjjbcQOtc=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwQHjjrcRsYI=", + "_parent": { + "$ref": "AAAAAAFFwQHjjbcLQPM=" + }, + "model": { + "$ref": "AAAAAAFFwQHjjbcJ4Ks=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 260, + "top": 56, + "width": 105, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwQHjjrcSCoc=", + "_parent": { + "$ref": "AAAAAAFFwQHjjbcLQPM=" + }, + "model": { + "$ref": "AAAAAAFFwQHjjbcJ4Ks=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 260, + "top": 66, + "width": 105, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwQHjjrcTWEY=", + "_parent": { + "$ref": "AAAAAAFFwQHjjbcLQPM=" + }, + "model": { + "$ref": "AAAAAAFFwQHjjbcJ4Ks=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 72, + "top": -32, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 224, + "top": 36, + "width": 125, + "height": 37, + "nameCompartment": { + "$ref": "AAAAAAFFwQHjjbcMlRY=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwQHjjrcRsYI=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwQHjjrcSCoc=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqN0zJrS0=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwQHjjrcTWEY=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwQIPLLc0Q7M=", + "_parent": { + "$ref": "AAAAAAFFwQCuI7bLjDk=" + }, + "model": { + "$ref": "AAAAAAFFwQIPLLcykEY=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqOEzfvr8=", + "_parent": { + "$ref": "AAAAAAFFwQIPLLc0Q7M=" + }, + "model": { + "$ref": "AAAAAAFFwQIPLLcykEY=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwQIPLLc1jrg=", + "_parent": { + "$ref": "AAAAAAFFwQIPLLc0Q7M=" + }, + "model": { + "$ref": "AAAAAAFFwQIPLLcykEY=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwQIPLLc2rps=", + "_parent": { + "$ref": "AAAAAAFFwQIPLLc1jrg=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 229, + "top": 121, + "width": 83, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwQIPLLc3wdo=", + "_parent": { + "$ref": "AAAAAAFFwQIPLLc1jrg=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 229, + "top": 135, + "width": 83, + "height": 12, + "text": "Metamodel" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwQIPLLc4SHA=", + "_parent": { + "$ref": "AAAAAAFFwQIPLLc1jrg=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 108, + "top": -84, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwQIPLLc5Qvc=", + "_parent": { + "$ref": "AAAAAAFFwQIPLLc1jrg=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 108, + "top": -84, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 224, + "top": 116, + "width": 93, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwQIPLLc2rps=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwQIPLLc3wdo=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwQIPLLc4SHA=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwQIPLLc5Qvc=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwQIPLLc63qc=", + "_parent": { + "$ref": "AAAAAAFFwQIPLLc0Q7M=" + }, + "model": { + "$ref": "AAAAAAFFwQIPLLcykEY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 260, + "top": 124, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwQIPLbc7y2w=", + "_parent": { + "$ref": "AAAAAAFFwQIPLLc0Q7M=" + }, + "model": { + "$ref": "AAAAAAFFwQIPLLcykEY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 260, + "top": 134, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwQIPLbc8jC8=", + "_parent": { + "$ref": "AAAAAAFFwQIPLLc0Q7M=" + }, + "model": { + "$ref": "AAAAAAFFwQIPLLcykEY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 72, + "top": -56, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 224, + "top": 116, + "width": 93, + "height": 37, + "nameCompartment": { + "$ref": "AAAAAAFFwQIPLLc1jrg=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwQIPLLc63qc=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwQIPLbc7y2w=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqOEzfvr8=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwQIPLbc8jC8=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwQIrDLddK/I=", + "_parent": { + "$ref": "AAAAAAFFwQCuI7bLjDk=" + }, + "model": { + "$ref": "AAAAAAFFwQIrDLdbTko=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqOEz1SWk=", + "_parent": { + "$ref": "AAAAAAFFwQIrDLddK/I=" + }, + "model": { + "$ref": "AAAAAAFFwQIrDLdbTko=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwQIrDLdevJE=", + "_parent": { + "$ref": "AAAAAAFFwQIrDLddK/I=" + }, + "model": { + "$ref": "AAAAAAFFwQIrDLdbTko=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwQIrDLdfcec=", + "_parent": { + "$ref": "AAAAAAFFwQIrDLdevJE=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 229, + "top": 181, + "width": 83, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwQIrDLdgsTM=", + "_parent": { + "$ref": "AAAAAAFFwQIrDLdevJE=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 229, + "top": 195, + "width": 83, + "height": 12, + "text": "SystemModel" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwQIrDLdhAR0=", + "_parent": { + "$ref": "AAAAAAFFwQIrDLdevJE=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 120, + "top": -168, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwQIrDLdiiuQ=", + "_parent": { + "$ref": "AAAAAAFFwQIrDLdevJE=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 120, + "top": -168, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 224, + "top": 176, + "width": 93, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwQIrDLdfcec=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwQIrDLdgsTM=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwQIrDLdhAR0=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwQIrDLdiiuQ=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwQIrDLdjYt8=", + "_parent": { + "$ref": "AAAAAAFFwQIrDLddK/I=" + }, + "model": { + "$ref": "AAAAAAFFwQIrDLdbTko=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 264, + "top": 156, + "width": 88, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwQIrDLdkEoo=", + "_parent": { + "$ref": "AAAAAAFFwQIrDLddK/I=" + }, + "model": { + "$ref": "AAAAAAFFwQIrDLdbTko=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 264, + "top": 166, + "width": 88, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwQIrDLdlkbo=", + "_parent": { + "$ref": "AAAAAAFFwQIrDLddK/I=" + }, + "model": { + "$ref": "AAAAAAFFwQIrDLdbTko=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 80, + "top": -112, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 224, + "top": 176, + "width": 93, + "height": 37, + "nameCompartment": { + "$ref": "AAAAAAFFwQIrDLdevJE=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwQIrDLdjYt8=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwQIrDLdkEoo=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqOEz1SWk=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwQIrDLdlkbo=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwQLOH7eRZzI=", + "_parent": { + "$ref": "AAAAAAFFwQCuI7bLjDk=" + }, + "model": { + "$ref": "AAAAAAFFwQLOH7eQuvE=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwQLOH7eSzo8=", + "_parent": { + "$ref": "AAAAAAFFwQLOH7eRZzI=" + }, + "model": { + "$ref": "AAAAAAFFwQLOH7eQuvE=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 189, + "top": 145, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwQLOH7eRZzI=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwQLOILeTl4U=", + "_parent": { + "$ref": "AAAAAAFFwQLOH7eRZzI=" + }, + "model": { + "$ref": "AAAAAAFFwQLOH7eQuvE=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 189, + "top": 160, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwQLOH7eRZzI=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwQLOILeU1qE=", + "_parent": { + "$ref": "AAAAAAFFwQLOH7eRZzI=" + }, + "model": { + "$ref": "AAAAAAFFwQLOH7eQuvE=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 190, + "top": 115, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwQLOH7eRZzI=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwQHC9rbwK6A=" + }, + "tail": { + "$ref": "AAAAAAFFwQIPLLc0Q7M=" + }, + "points": "224:136;156:136", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwQLOH7eSzo8=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwQLOILeTl4U=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwQLOILeU1qE=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwQLSp7eim6s=", + "_parent": { + "$ref": "AAAAAAFFwQCuI7bLjDk=" + }, + "model": { + "$ref": "AAAAAAFFwQLSp7eh5o0=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwQLSp7ejdqM=", + "_parent": { + "$ref": "AAAAAAFFwQLSp7eim6s=" + }, + "model": { + "$ref": "AAAAAAFFwQLSp7eh5o0=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 189, + "top": 205, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwQLSp7eim6s=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwQLSp7ekT+I=", + "_parent": { + "$ref": "AAAAAAFFwQLSp7eim6s=" + }, + "model": { + "$ref": "AAAAAAFFwQLSp7eh5o0=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 189, + "top": 220, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwQLSp7eim6s=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwQLSp7el67w=", + "_parent": { + "$ref": "AAAAAAFFwQLSp7eim6s=" + }, + "model": { + "$ref": "AAAAAAFFwQLSp7eh5o0=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 190, + "top": 175, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwQLSp7eim6s=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwQHC9rbwK6A=" + }, + "tail": { + "$ref": "AAAAAAFFwQIrDLddK/I=" + }, + "points": "224:196;156:196", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwQLSp7ejdqM=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwQLSp7ekT+I=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwQLSp7el67w=" + } + }, + { + "_type": "UMLMetaClassView", + "_id": "AAAAAAFFwQdYRLfPnZs=", + "_parent": { + "$ref": "AAAAAAFFwQCuI7bLjDk=" + }, + "model": { + "$ref": "AAAAAAFFwLRECl7r1R4=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwQdYRLfQc8o=", + "_parent": { + "$ref": "AAAAAAFFwQdYRLfPnZs=" + }, + "model": { + "$ref": "AAAAAAFFwLRECl7r1R4=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwQdYRLfRm/U=", + "_parent": { + "$ref": "AAAAAAFFwQdYRLfQc8o=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 45, + "top": 41, + "width": 107, + "height": 12, + "text": "«metaClass»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwQdYRLfSwyU=", + "_parent": { + "$ref": "AAAAAAFFwQdYRLfQc8o=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;1", + "containerExtending": true, + "left": 45, + "top": 55, + "width": 107, + "height": 12, + "text": "UMLComponent" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwQdYRLfTyV4=", + "_parent": { + "$ref": "AAAAAAFFwQdYRLfQc8o=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": -702, + "top": -954, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwQdYRLfUafY=", + "_parent": { + "$ref": "AAAAAAFFwQdYRLfQc8o=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": -702, + "top": -954, + "height": 12, + "horizontalAlignment": 1 + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 40, + "top": 36, + "width": 117, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwQdYRLfRm/U=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwQdYRLfSwyU=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwQdYRLfTyV4=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwQdYRLfUafY=" + } + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 40, + "top": 36, + "width": 117, + "height": 41, + "nameCompartment": { + "$ref": "AAAAAAFFwQdYRLfQc8o=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwQgwnLf7u0w=", + "_parent": { + "$ref": "AAAAAAFFwQCuI7bLjDk=" + }, + "model": { + "$ref": "AAAAAAFFwQgwnLf6Q+0=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwQgwnLf82nE=", + "_parent": { + "$ref": "AAAAAAFFwQgwnLf7u0w=" + }, + "model": { + "$ref": "AAAAAAFFwQgwnLf6Q+0=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 189, + "top": 64, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwQgwnLf7u0w=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwQgwnbf9bFo=", + "_parent": { + "$ref": "AAAAAAFFwQgwnLf7u0w=" + }, + "model": { + "$ref": "AAAAAAFFwQgwnLf6Q+0=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 189, + "top": 79, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwQgwnLf7u0w=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwQgwnbf+ckE=", + "_parent": { + "$ref": "AAAAAAFFwQgwnLf7u0w=" + }, + "model": { + "$ref": "AAAAAAFFwQgwnLf6Q+0=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 190, + "top": 34, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwQgwnLf7u0w=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwQdYRLfPnZs=" + }, + "tail": { + "$ref": "AAAAAAFFwQHjjbcLQPM=" + }, + "lineStyle": 1, + "points": "223:55;157:55", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwQgwnLf82nE=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwQgwnbf9bFo=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwQgwnbf+ckE=" + } + } + ] + }, + { + "_type": "UMLMetaClass", + "_id": "AAAAAAFFwQHC9rbvUkk=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "UMLModel" + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwQHjjbcJ4Ks=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "BuildComponent", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwQgwnLf6Q+0=", + "_parent": { + "$ref": "AAAAAAFFwQHjjbcJ4Ks=" + }, + "source": { + "$ref": "AAAAAAFFwQHjjbcJ4Ks=" + }, + "target": { + "$ref": "AAAAAAFFwLRECl7r1R4=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwQHjjbcKYjk=", + "_parent": { + "$ref": "AAAAAAFFwQHjjbcJ4Ks=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwQIPLLcykEY=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Metamodel", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwQLOH7eQuvE=", + "_parent": { + "$ref": "AAAAAAFFwQIPLLcykEY=" + }, + "source": { + "$ref": "AAAAAAFFwQIPLLcykEY=" + }, + "target": { + "$ref": "AAAAAAFFwQHC9rbvUkk=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwQIPLLcz/1A=", + "_parent": { + "$ref": "AAAAAAFFwQIPLLcykEY=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwQIrDLdbTko=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "SystemModel", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwQLSp7eh5o0=", + "_parent": { + "$ref": "AAAAAAFFwQIrDLdbTko=" + }, + "source": { + "$ref": "AAAAAAFFwQIrDLdbTko=" + }, + "target": { + "$ref": "AAAAAAFFwQHC9rbvUkk=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwQIrDLdcjKw=", + "_parent": { + "$ref": "AAAAAAFFwQIrDLdbTko=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwx8Q/35u/80=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "control", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwyAHeH6Znas=", + "_parent": { + "$ref": "AAAAAAFFwx8Q/35u/80=" + }, + "source": { + "$ref": "AAAAAAFFwx8Q/35u/80=" + }, + "target": { + "$ref": "AAAAAAFFJsZbpDNobIs=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwx8Q/35vMf0=", + "_parent": { + "$ref": "AAAAAAFFwx8Q/35u/80=" + }, + "width": 40, + "height": 40, + "content": "var w = rect.getWidth(),\n h = w / 2,\n m = w / 8;\ncanvas.fillEllipse(rect.x1 + m, rect.y1 + m, rect.x2 - m, rect.y2 - m);\ncanvas.ellipse(rect.x1 + m, rect.y1 + m, rect.x2 - m, rect.y2 - m);\ncanvas.line(rect.x1 + h, rect.y1 + m, rect.x1 + h + m, rect.y1);\ncanvas.line(rect.x1 + h, rect.y1 + m, rect.x1 + h + m, rect.y1 + 2 * m);\n" + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFw0h1/QXL978=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "boundary", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFw0o5ppIUB2s=", + "_parent": { + "$ref": "AAAAAAFFw0h1/QXL978=" + }, + "source": { + "$ref": "AAAAAAFFw0h1/QXL978=" + }, + "target": { + "$ref": "AAAAAAFFJsZbpDNobIs=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFw0h1/QXM/ss=", + "_parent": { + "$ref": "AAAAAAFFw0h1/QXL978=" + }, + "width": "50", + "height": 40, + "content": "var w = rect.getWidth(),\n h = rect.getHeight(),\n m = w / 5;\ncanvas.fillEllipse(rect.x1 + m, rect.y1, rect.x2, rect.y2);\ncanvas.ellipse(rect.x1 + m, rect.y1, rect.x2, rect.y2);\ncanvas.line(rect.x1, rect.y1, rect.x1, rect.y2);\ncanvas.line(rect.x1, rect.y1 + h/2, rect.x1 + m, rect.y1 + h/2);\n" + } + } + ] + } + ] +} \ No newline at end of file diff --git a/app/doc/状态机.mdj b/app/doc/状态机.mdj new file mode 100644 index 0000000..5f1212f --- /dev/null +++ b/app/doc/状态机.mdj @@ -0,0 +1,45155 @@ +{ + "_type": "Project", + "_id": "AAAAAAFElm5XMFNoGY0=", + "name": "Untitled", + "ownedElements": [ + { + "_type": "UMLModel", + "_id": "AAAAAAFElm6BOFNpegQ=", + "_parent": { + "$ref": "AAAAAAFElm5XMFNoGY0=" + }, + "name": "Model", + "ownedElements": [ + { + "_type": "UMLUseCaseDiagram", + "_id": "AAAAAAF5P5m6Qk1jVXQ=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "UseCaseDiagram1", + "ownedViews": [ + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5P5nMr01oLTI=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5P5nMrk1mLCw=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5P5nMr01pxLs=", + "_parent": { + "$ref": "AAAAAAF5P5nMr01oLTI=" + }, + "model": { + "$ref": "AAAAAAF5P5nMrk1mLCw=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5P5nMr01qZlQ=", + "_parent": { + "$ref": "AAAAAAF5P5nMr01pxLs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 4528, + "top": 672, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5P5nMr01rWkA=", + "_parent": { + "$ref": "AAAAAAF5P5nMr01pxLs=" + }, + "font": "Arial;13;1", + "left": 2284, + "top": 347.5, + "width": 62, + "height": 13, + "text": "check2C" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5P5nMr01srVY=", + "_parent": { + "$ref": "AAAAAAF5P5nMr01pxLs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 4528, + "top": 672, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5P5nMr01tKAI=", + "_parent": { + "$ref": "AAAAAAF5P5nMr01pxLs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 4528, + "top": 672, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 2279, + "top": 340.5, + "width": 72, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5P5nMr01qZlQ=" + }, + "nameLabel": { + "$ref": "AAAAAAF5P5nMr01rWkA=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5P5nMr01srVY=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5P5nMr01tKAI=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5P5nMr01u10s=", + "_parent": { + "$ref": "AAAAAAF5P5nMr01oLTI=" + }, + "model": { + "$ref": "AAAAAAF5P5nMrk1mLCw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2264, + "top": 336, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5P5nMr01vn/8=", + "_parent": { + "$ref": "AAAAAAF5P5nMr01oLTI=" + }, + "model": { + "$ref": "AAAAAAF5P5nMrk1mLCw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2264, + "top": 336, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5nMr01wvTc=", + "_parent": { + "$ref": "AAAAAAF5P5nMr01oLTI=" + }, + "model": { + "$ref": "AAAAAAF5P5nMrk1mLCw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2264, + "top": 336, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5P5nMr01xNvU=", + "_parent": { + "$ref": "AAAAAAF5P5nMr01oLTI=" + }, + "model": { + "$ref": "AAAAAAF5P5nMrk1mLCw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2264, + "top": 336, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5P5nMr01yEgM=", + "_parent": { + "$ref": "AAAAAAF5P5nMr01oLTI=" + }, + "model": { + "$ref": "AAAAAAF5P5nMrk1mLCw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2264, + "top": 336, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 2264, + "top": 336, + "width": 102, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5P5nMr01pxLs=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5P5nMr01u10s=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5P5nMr01vn/8=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5nMr01wvTc=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5P5nMr01xNvU=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5P5nMr01yEgM=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5P5saWE3J2FY=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5P5saV03F9So=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5saWE3K1ts=", + "_parent": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "model": { + "$ref": "AAAAAAF5P5saV03F9So=" + }, + "font": "Arial;13;0", + "left": 2186, + "top": 446, + "width": 59.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "edgePosition": 1, + "text": "+通过检测" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5saWE3LIi0=", + "_parent": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "model": { + "$ref": "AAAAAAF5P5saV03F9So=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 2224, + "top": 458, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5saWE3M7xA=", + "_parent": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "model": { + "$ref": "AAAAAAF5P5saV03F9So=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2196, + "top": 423, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5saWE3NmNI=", + "_parent": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "model": { + "$ref": "AAAAAAF5P5saV03GReQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2281, + "top": 393, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5saWE3Oy1k=", + "_parent": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "model": { + "$ref": "AAAAAAF5P5saV03GReQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2287, + "top": 404, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5saWE3PZiY=", + "_parent": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "model": { + "$ref": "AAAAAAF5P5saV03GReQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2267, + "top": 368, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5saWE3QKR0=", + "_parent": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "model": { + "$ref": "AAAAAAF5P5saV03HrLQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2149, + "top": 500, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5saWE3RVpc=", + "_parent": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "model": { + "$ref": "AAAAAAF5P5saV03HrLQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2159, + "top": 509, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5saWE3S3i0=", + "_parent": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "model": { + "$ref": "AAAAAAF5P5saV03HrLQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2128, + "top": 481, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5P5saWE3TepE=", + "_parent": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "model": { + "$ref": "AAAAAAF5P5saV03GReQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2152, + "top": 160, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5P5saWE3U3g4=", + "_parent": { + "$ref": "AAAAAAF5P5saWE3J2FY=" + }, + "model": { + "$ref": "AAAAAAF5P5saV03HrLQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2152, + "top": 160, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5StIJ55ESsdQ=" + }, + "tail": { + "$ref": "AAAAAAF5P5nMr01oLTI=" + }, + "lineStyle": 1, + "points": "2292:371;2120:511", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5P5saWE3K1ts=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5P5saWE3LIi0=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5P5saWE3M7xA=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5P5saWE3NmNI=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5P5saWE3Oy1k=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5P5saWE3PZiY=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5P5saWE3QKR0=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5P5saWE3RVpc=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5P5saWE3S3i0=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5P5saWE3TepE=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5P5saWE3U3g4=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5P56LZE6M/G8=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5P56LY06KFIA=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5P56LZE6NeNY=", + "_parent": { + "$ref": "AAAAAAF5P56LZE6M/G8=" + }, + "model": { + "$ref": "AAAAAAF5P56LY06KFIA=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5P56LZE6OE2I=", + "_parent": { + "$ref": "AAAAAAF5P56LZE6NeNY=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": -464, + "top": -224, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5P56LZE6PKW0=", + "_parent": { + "$ref": "AAAAAAF5P56LZE6NeNY=" + }, + "fillColor": "#ff8282", + "font": "Arial;13;1", + "left": 205, + "top": 283.5, + "width": 103, + "height": 13, + "text": "【用户选择操作】" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5P56LZE6QSXM=", + "_parent": { + "$ref": "AAAAAAF5P56LZE6NeNY=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": -464, + "top": -224, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5P56LZE6RMmU=", + "_parent": { + "$ref": "AAAAAAF5P56LZE6NeNY=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": -464, + "top": -224, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 200, + "top": 276.5, + "width": 114, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5P56LZE6OE2I=" + }, + "nameLabel": { + "$ref": "AAAAAAF5P56LZE6PKW0=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5P56LZE6QSXM=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5P56LZE6RMmU=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5P56LZE6SLIg=", + "_parent": { + "$ref": "AAAAAAF5P56LZE6M/G8=" + }, + "model": { + "$ref": "AAAAAAF5P56LY06KFIA=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": -232, + "top": -112, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5P56LZE6TWFg=", + "_parent": { + "$ref": "AAAAAAF5P56LZE6M/G8=" + }, + "model": { + "$ref": "AAAAAAF5P56LY06KFIA=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": -232, + "top": -112, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P56LZE6U8ts=", + "_parent": { + "$ref": "AAAAAAF5P56LZE6M/G8=" + }, + "model": { + "$ref": "AAAAAAF5P56LY06KFIA=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": -232, + "top": -112, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5P56LZE6VNIk=", + "_parent": { + "$ref": "AAAAAAF5P56LZE6M/G8=" + }, + "model": { + "$ref": "AAAAAAF5P56LY06KFIA=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": -232, + "top": -112, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5P56LZE6W1sE=", + "_parent": { + "$ref": "AAAAAAF5P56LZE6M/G8=" + }, + "model": { + "$ref": "AAAAAAF5P56LY06KFIA=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": -232, + "top": -112, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ff8282", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 176, + "top": 272, + "width": 161, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5P56LZE6NeNY=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5P56LZE6SLIg=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5P56LZE6TWFg=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P56LZE6U8ts=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5P56LZE6VNIk=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5P56LZE6W1sE=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5P56tgE7IY7E=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5P56tf07Epig=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P56tgE7JO9U=", + "_parent": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "model": { + "$ref": "AAAAAAF5P56tf07Epig=" + }, + "font": "Arial;13;0", + "left": 1216, + "top": 36, + "width": 72.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "edgePosition": 1, + "text": "+未通过检测" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P56tgE7Kkjk=", + "_parent": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "model": { + "$ref": "AAAAAAF5P56tf07Epig=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1252, + "top": 51, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P56tgE7LlPE=", + "_parent": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "model": { + "$ref": "AAAAAAF5P56tf07Epig=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1251, + "top": 7, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P56tgE7MSF4=", + "_parent": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "model": { + "$ref": "AAAAAAF5P56tgE7F7Yk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2273, + "top": 317, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P56tgE7NsLs=", + "_parent": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "model": { + "$ref": "AAAAAAF5P56tgE7F7Yk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2261, + "top": 323, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P56tgE7OBww=", + "_parent": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "model": { + "$ref": "AAAAAAF5P56tgE7F7Yk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2298, + "top": 304, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P56tgE7PoMY=", + "_parent": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "model": { + "$ref": "AAAAAAF5P56tgE7GNNA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 296, + "top": 253, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P56tgE7Q0NM=", + "_parent": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "model": { + "$ref": "AAAAAAF5P56tgE7GNNA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 308, + "top": 259, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P56tgE7RtW8=", + "_parent": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "model": { + "$ref": "AAAAAAF5P56tgE7GNNA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 271, + "top": 240, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5P56tgE7SCeE=", + "_parent": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "model": { + "$ref": "AAAAAAF5P56tgE7F7Yk=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5P56tgE7TSmw=", + "_parent": { + "$ref": "AAAAAAF5P56tgE7IY7E=" + }, + "model": { + "$ref": "AAAAAAF5P56tgE7GNNA=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5P56LZE6M/G8=" + }, + "tail": { + "$ref": "AAAAAAF5P5nMr01oLTI=" + }, + "lineStyle": 1, + "points": "2301:335;2064:16;440:40;269:271", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5P56tgE7JO9U=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5P56tgE7Kkjk=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5P56tgE7LlPE=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5P56tgE7MSF4=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5P56tgE7NsLs=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5P56tgE7OBww=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5P56tgE7PoMY=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5P56tgE7Q0NM=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5P56tgE7RtW8=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5P56tgE7SCeE=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5P56tgE7TSmw=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5P5/CAk98zZc=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5P5/CAk96MB0=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5P5/CAk99r9g=", + "_parent": { + "$ref": "AAAAAAF5P5/CAk98zZc=" + }, + "model": { + "$ref": "AAAAAAF5P5/CAk96MB0=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5P5/CA09+uJY=", + "_parent": { + "$ref": "AAAAAAF5P5/CAk99r9g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1056, + "top": -208, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5P5/CA09/h4M=", + "_parent": { + "$ref": "AAAAAAF5P5/CAk99r9g=" + }, + "font": "Arial;13;1", + "left": 1260, + "top": 395.5, + "width": 62, + "height": 13, + "text": "Idle" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5P5/CA0+AvMQ=", + "_parent": { + "$ref": "AAAAAAF5P5/CAk99r9g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1056, + "top": -208, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5P5/CA0+BODA=", + "_parent": { + "$ref": "AAAAAAF5P5/CAk99r9g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1056, + "top": -208, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 1255, + "top": 388.5, + "width": 72, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5P5/CA09+uJY=" + }, + "nameLabel": { + "$ref": "AAAAAAF5P5/CA09/h4M=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5P5/CA0+AvMQ=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5P5/CA0+BODA=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5P5/CA0+CFD4=", + "_parent": { + "$ref": "AAAAAAF5P5/CAk98zZc=" + }, + "model": { + "$ref": "AAAAAAF5P5/CAk96MB0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 528, + "top": -104, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5P5/CA0+DO7Q=", + "_parent": { + "$ref": "AAAAAAF5P5/CAk98zZc=" + }, + "model": { + "$ref": "AAAAAAF5P5/CAk96MB0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 528, + "top": -104, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5/CA0+EZ7w=", + "_parent": { + "$ref": "AAAAAAF5P5/CAk98zZc=" + }, + "model": { + "$ref": "AAAAAAF5P5/CAk96MB0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 528, + "top": -104, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5P5/CA0+FMSM=", + "_parent": { + "$ref": "AAAAAAF5P5/CAk98zZc=" + }, + "model": { + "$ref": "AAAAAAF5P5/CAk96MB0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 528, + "top": -104, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5P5/CA0+GOcA=", + "_parent": { + "$ref": "AAAAAAF5P5/CAk98zZc=" + }, + "model": { + "$ref": "AAAAAAF5P5/CAk96MB0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 528, + "top": -104, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 1240, + "top": 384, + "width": 102, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5P5/CAk99r9g=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5P5/CA0+CFD4=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5P5/CA0+DO7Q=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5/CA0+EZ7w=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5P5/CA0+FMSM=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5P5/CA0+GOcA=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5P5/ask/ENuY=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5P5/ask/ASWM=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5/ask/FCi8=", + "_parent": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "model": { + "$ref": "AAAAAAF5P5/ask/ASWM=" + }, + "font": "Arial;13;0", + "left": 514, + "top": 360, + "width": 124.22798156738281, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "edgePosition": 1, + "text": "+选择忽略or重测目标" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5/ask/GmBY=", + "_parent": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "model": { + "$ref": "AAAAAAF5P5/ask/ASWM=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 580, + "top": 346, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5/ask/H9Os=", + "_parent": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "model": { + "$ref": "AAAAAAF5P5/ask/ASWM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 567, + "top": 389, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5/ask/ITgo=", + "_parent": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "model": { + "$ref": "AAAAAAF5P5/ask/BASE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 347, + "top": 293, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5/ask/J3dw=", + "_parent": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "model": { + "$ref": "AAAAAAF5P5/ask/BASE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 353, + "top": 281, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5/ask/KH+Q=", + "_parent": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "model": { + "$ref": "AAAAAAF5P5/ask/BASE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 335, + "top": 319, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5/ask/LwxI=", + "_parent": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "model": { + "$ref": "AAAAAAF5P5/ask/CwwU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 806, + "top": 427, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5/ask/MCSM=", + "_parent": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "model": { + "$ref": "AAAAAAF5P5/ask/CwwU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 807, + "top": 413, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P5/ask/N7rw=", + "_parent": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "model": { + "$ref": "AAAAAAF5P5/ask/CwwU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 802, + "top": 454, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5P5/ask/OUQY=", + "_parent": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "model": { + "$ref": "AAAAAAF5P5/ask/BASE=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5P5/ask/P3tM=", + "_parent": { + "$ref": "AAAAAAF5P5/ask/ENuY=" + }, + "model": { + "$ref": "AAAAAAF5P5/ask/CwwU=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QJjLZRML/gk=" + }, + "tail": { + "$ref": "AAAAAAF5P56LZE6M/G8=" + }, + "lineStyle": 1, + "points": "318:307;827:455", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5P5/ask/FCi8=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5P5/ask/GmBY=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5P5/ask/H9Os=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5P5/ask/ITgo=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5P5/ask/J3dw=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5P5/ask/KH+Q=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5P5/ask/LwxI=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5P5/ask/MCSM=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5P5/ask/N7rw=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5P5/ask/OUQY=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5P5/ask/P3tM=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5P6Btl1DS04s=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5P6Btl1DQYFs=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5P6Btl1DTuQ4=", + "_parent": { + "$ref": "AAAAAAF5P6Btl1DS04s=" + }, + "model": { + "$ref": "AAAAAAF5P6Btl1DQYFs=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5P6Btl1DUbE8=", + "_parent": { + "$ref": "AAAAAAF5P6Btl1DTuQ4=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -1072, + "top": 160, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5P6BtmFDVnHI=", + "_parent": { + "$ref": "AAAAAAF5P6Btl1DTuQ4=" + }, + "fillColor": "#ffadad", + "font": "Arial;13;1", + "left": 74.5, + "top": 411.5, + "width": 207, + "height": 13, + "text": "【提示用户是否确定删除整个测回】" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5P6BtmFDW1Rc=", + "_parent": { + "$ref": "AAAAAAF5P6Btl1DTuQ4=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -1072, + "top": 160, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5P6BtmFDXJZ4=", + "_parent": { + "$ref": "AAAAAAF5P6Btl1DTuQ4=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -1072, + "top": 160, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 69.5, + "top": 404.5, + "width": 218, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5P6Btl1DUbE8=" + }, + "nameLabel": { + "$ref": "AAAAAAF5P6BtmFDVnHI=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5P6BtmFDW1Rc=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5P6BtmFDXJZ4=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5P6BtmFDYzoo=", + "_parent": { + "$ref": "AAAAAAF5P6Btl1DS04s=" + }, + "model": { + "$ref": "AAAAAAF5P6Btl1DQYFs=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -536, + "top": 80, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5P6BtmFDZfOA=", + "_parent": { + "$ref": "AAAAAAF5P6Btl1DS04s=" + }, + "model": { + "$ref": "AAAAAAF5P6Btl1DQYFs=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -536, + "top": 80, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P6BtmFDabNE=", + "_parent": { + "$ref": "AAAAAAF5P6Btl1DS04s=" + }, + "model": { + "$ref": "AAAAAAF5P6Btl1DQYFs=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -536, + "top": 80, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5P6BtmFDbcVg=", + "_parent": { + "$ref": "AAAAAAF5P6Btl1DS04s=" + }, + "model": { + "$ref": "AAAAAAF5P6Btl1DQYFs=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -536, + "top": 80, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5P6BtmFDcrag=", + "_parent": { + "$ref": "AAAAAAF5P6Btl1DS04s=" + }, + "model": { + "$ref": "AAAAAAF5P6Btl1DQYFs=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -536, + "top": 80, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ffadad", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 24, + "top": 400, + "width": 308, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5P6Btl1DTuQ4=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5P6BtmFDYzoo=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5P6BtmFDZfOA=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P6BtmFDabNE=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5P6BtmFDbcVg=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5P6BtmFDcrag=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5P6ETu1Fw08c=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5P6ETu1Fsgo0=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6ETvFFx1mw=", + "_parent": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "model": { + "$ref": "AAAAAAF5P6ETu1Fsgo0=" + }, + "font": "Arial;13;0", + "left": 199, + "top": 354, + "width": 59.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "edgePosition": 1, + "text": "+重测测回" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6ETvFFyw0s=", + "_parent": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "model": { + "$ref": "AAAAAAF5P6ETu1Fsgo0=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 241, + "top": 362, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6ETvFFzyRs=", + "_parent": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "model": { + "$ref": "AAAAAAF5P6ETu1Fsgo0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 203, + "top": 339, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6ETvFF0+lY=", + "_parent": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "model": { + "$ref": "AAAAAAF5P6ETu1FtUvs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 244, + "top": 330, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6ETvFF1ok8=", + "_parent": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "model": { + "$ref": "AAAAAAF5P6ETu1FtUvs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 254, + "top": 339, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6ETvFF2wKI=", + "_parent": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "model": { + "$ref": "AAAAAAF5P6ETu1FtUvs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 222, + "top": 312, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6ETvFF3tbw=", + "_parent": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "model": { + "$ref": "AAAAAAF5P6ETu1Fuzfc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 214, + "top": 378, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6ETvFF4Oc0=", + "_parent": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "model": { + "$ref": "AAAAAAF5P6ETu1Fuzfc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 226, + "top": 383, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6ETvFF586k=", + "_parent": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "model": { + "$ref": "AAAAAAF5P6ETu1Fuzfc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 188, + "top": 368, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5P6ETvFF6xek=", + "_parent": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "model": { + "$ref": "AAAAAAF5P6ETu1FtUvs=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5P6ETvFF7szs=", + "_parent": { + "$ref": "AAAAAAF5P6ETu1Fw08c=" + }, + "model": { + "$ref": "AAAAAAF5P6ETu1Fuzfc=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5P6Btl1DS04s=" + }, + "tail": { + "$ref": "AAAAAAF5P56LZE6M/G8=" + }, + "lineStyle": 1, + "points": "245:307;188:399", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5P6ETvFFx1mw=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5P6ETvFFyw0s=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5P6ETvFFzyRs=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5P6ETvFF0+lY=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5P6ETvFF1ok8=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5P6ETvFF2wKI=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5P6ETvFF3tbw=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5P6ETvFF4Oc0=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5P6ETvFF586k=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5P6ETvFF6xek=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5P6ETvFF7szs=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5P6HZl1JC23Y=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5P6HZl1I+eIg=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6HZl1JDZsQ=", + "_parent": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "model": { + "$ref": "AAAAAAF5P6HZl1I+eIg=" + }, + "font": "Arial;13;0", + "left": 509, + "top": 426, + "width": 98.22798156738281, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "edgePosition": 1, + "text": "+选择忽略or取消" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6HZl1JECIw=", + "_parent": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "model": { + "$ref": "AAAAAAF5P6HZl1I+eIg=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 559, + "top": 411, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6HZl1JF8pk=", + "_parent": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "model": { + "$ref": "AAAAAAF5P6HZl1I+eIg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 555, + "top": 455, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6HZl1JG0HA=", + "_parent": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "model": { + "$ref": "AAAAAAF5P6HZl1I/u/s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 359, + "top": 410, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6HZl1JHztQ=", + "_parent": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "model": { + "$ref": "AAAAAAF5P6HZl1I/u/s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 362, + "top": 397, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6HZl1JIPD0=", + "_parent": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "model": { + "$ref": "AAAAAAF5P6HZl1I/u/s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 352, + "top": 437, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6HZl1JJLUs=", + "_parent": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "model": { + "$ref": "AAAAAAF5P6HZl1JAt1Q=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 758, + "top": 441, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6HZl1JKFgU=", + "_parent": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "model": { + "$ref": "AAAAAAF5P6HZl1JAt1Q=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 757, + "top": 428, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6HZl1JLM+Y=", + "_parent": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "model": { + "$ref": "AAAAAAF5P6HZl1JAt1Q=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 760, + "top": 469, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5P6HZl1JMru0=", + "_parent": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "model": { + "$ref": "AAAAAAF5P6HZl1I/u/s=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5P6HZl1JNqZA=", + "_parent": { + "$ref": "AAAAAAF5P6HZl1JC23Y=" + }, + "model": { + "$ref": "AAAAAAF5P6HZl1JAt1Q=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QJjLZRML/gk=" + }, + "tail": { + "$ref": "AAAAAAF5P6Btl1DS04s=" + }, + "lineStyle": 1, + "points": "332:429;783:465", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5P6HZl1JDZsQ=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5P6HZl1JECIw=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5P6HZl1JF8pk=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5P6HZl1JG0HA=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5P6HZl1JHztQ=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5P6HZl1JIPD0=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5P6HZl1JJLUs=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5P6HZl1JKFgU=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5P6HZl1JLM+Y=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5P6HZl1JMru0=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5P6HZl1JNqZA=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5P6IYDFMMeFQ=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5P6IYDFMK28k=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5P6IYDFMNnzQ=", + "_parent": { + "$ref": "AAAAAAF5P6IYDFMMeFQ=" + }, + "model": { + "$ref": "AAAAAAF5P6IYDFMK28k=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5P6IYDFMOOjk=", + "_parent": { + "$ref": "AAAAAAF5P6IYDFMNnzQ=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": -1536, + "top": 544, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5P6IYDVMPgvc=", + "_parent": { + "$ref": "AAAAAAF5P6IYDFMNnzQ=" + }, + "fillColor": "#ff8282", + "font": "Arial;13;1", + "left": 125, + "top": 531.5, + "width": 103, + "height": 13, + "text": "【执行删除操作】" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5P6IYDVMQezU=", + "_parent": { + "$ref": "AAAAAAF5P6IYDFMNnzQ=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": -1536, + "top": 544, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5P6IYDVMRBdM=", + "_parent": { + "$ref": "AAAAAAF5P6IYDFMNnzQ=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": -1536, + "top": 544, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 120, + "top": 524.5, + "width": 114, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5P6IYDFMOOjk=" + }, + "nameLabel": { + "$ref": "AAAAAAF5P6IYDVMPgvc=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5P6IYDVMQezU=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5P6IYDVMRBdM=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5P6IYDVMSZQE=", + "_parent": { + "$ref": "AAAAAAF5P6IYDFMMeFQ=" + }, + "model": { + "$ref": "AAAAAAF5P6IYDFMK28k=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": -768, + "top": 272, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5P6IYDVMTe6E=", + "_parent": { + "$ref": "AAAAAAF5P6IYDFMMeFQ=" + }, + "model": { + "$ref": "AAAAAAF5P6IYDFMK28k=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": -768, + "top": 272, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P6IYDVMUviY=", + "_parent": { + "$ref": "AAAAAAF5P6IYDFMMeFQ=" + }, + "model": { + "$ref": "AAAAAAF5P6IYDFMK28k=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": -768, + "top": 272, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5P6IYDVMVT7Q=", + "_parent": { + "$ref": "AAAAAAF5P6IYDFMMeFQ=" + }, + "model": { + "$ref": "AAAAAAF5P6IYDFMK28k=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": -768, + "top": 272, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5P6IYDVMWeEE=", + "_parent": { + "$ref": "AAAAAAF5P6IYDFMMeFQ=" + }, + "model": { + "$ref": "AAAAAAF5P6IYDFMK28k=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": -768, + "top": 272, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ff8282", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 96, + "top": 520, + "width": 161, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5P6IYDFMNnzQ=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5P6IYDVMSZQE=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5P6IYDVMTe6E=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P6IYDVMUviY=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5P6IYDVMVT7Q=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5P6IYDVMWeEE=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5P6Jc6FQAXTQ=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5P6Jc6FP89fs=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6Jc6FQBsAA=", + "_parent": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "model": { + "$ref": "AAAAAAF5P6Jc6FP89fs=" + }, + "font": "Arial;13;0", + "left": 161, + "top": 470, + "width": 59.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "edgePosition": 1, + "text": "+确认删除" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6Jc6FQCliU=", + "_parent": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "model": { + "$ref": "AAAAAAF5P6Jc6FP89fs=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 205, + "top": 470, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6Jc6FQDs0Y=", + "_parent": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "model": { + "$ref": "AAAAAAF5P6Jc6FP89fs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 161, + "top": 471, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6Jc6VQErUI=", + "_parent": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "model": { + "$ref": "AAAAAAF5P6Jc6FP9Ay0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 191, + "top": 455, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6Jc6VQFXc4=", + "_parent": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "model": { + "$ref": "AAAAAAF5P6Jc6FP9Ay0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 204, + "top": 457, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6Jc6VQGACw=", + "_parent": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "model": { + "$ref": "AAAAAAF5P6Jc6FP9Ay0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 164, + "top": 450, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6Jc6VQH5rw=", + "_parent": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "model": { + "$ref": "AAAAAAF5P6Jc6FP+W/w=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 191, + "top": 487, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6Jc6VQIDDY=", + "_parent": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "model": { + "$ref": "AAAAAAF5P6Jc6FP+W/w=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 204, + "top": 485, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6Jc6VQJXs0=", + "_parent": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "model": { + "$ref": "AAAAAAF5P6Jc6FP+W/w=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 163, + "top": 491, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5P6Jc6VQKiwE=", + "_parent": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "model": { + "$ref": "AAAAAAF5P6Jc6FP9Ay0=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5P6Jc6VQLymI=", + "_parent": { + "$ref": "AAAAAAF5P6Jc6FQAXTQ=" + }, + "model": { + "$ref": "AAAAAAF5P6Jc6FP+W/w=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5P6IYDFMMeFQ=" + }, + "tail": { + "$ref": "AAAAAAF5P6Btl1DS04s=" + }, + "lineStyle": 1, + "points": "177:435;176:519", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5P6Jc6FQBsAA=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5P6Jc6FQCliU=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5P6Jc6FQDs0Y=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5P6Jc6VQErUI=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5P6Jc6VQFXc4=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5P6Jc6VQGACw=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5P6Jc6VQH5rw=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5P6Jc6VQIDDY=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5P6Jc6VQJXs0=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5P6Jc6VQKiwE=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5P6Jc6VQLymI=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5P6KuWFYy590=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5P6KuWFYuLA4=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6KuWFYzBrY=", + "_parent": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "model": { + "$ref": "AAAAAAF5P6KuWFYuLA4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 995, + "top": 977, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6KuWFY07+U=", + "_parent": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "model": { + "$ref": "AAAAAAF5P6KuWFYuLA4=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1002, + "top": 964, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6KuWFY1T2M=", + "_parent": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "model": { + "$ref": "AAAAAAF5P6KuWFYuLA4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 980, + "top": 1004, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6KuWFY2uTU=", + "_parent": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "model": { + "$ref": "AAAAAAF5P6KuWFYvXto=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 237, + "top": 548, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6KuWFY3Q0s=", + "_parent": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "model": { + "$ref": "AAAAAAF5P6KuWFYvXto=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 246, + "top": 538, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6KuWFY4NMQ=", + "_parent": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "model": { + "$ref": "AAAAAAF5P6KuWFYvXto=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 220, + "top": 570, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6KuWFY5sZg=", + "_parent": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "model": { + "$ref": "AAAAAAF5P6KuWFYwtmg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1752, + "top": 1407, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5P6KuWFYy590=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6KuWFY62Oo=", + "_parent": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "model": { + "$ref": "AAAAAAF5P6KuWFYwtmg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1757, + "top": 1394, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5P6KuWFYy590=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5P6KuWFY78L8=", + "_parent": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "model": { + "$ref": "AAAAAAF5P6KuWFYwtmg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1743, + "top": 1433, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5P6KuWFYy590=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5P6KuWFY8wFs=", + "_parent": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "model": { + "$ref": "AAAAAAF5P6KuWFYvXto=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 376, + "top": -144, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5P6KuWVY9b40=", + "_parent": { + "$ref": "AAAAAAF5P6KuWFYy590=" + }, + "model": { + "$ref": "AAAAAAF5P6KuWFYwtmg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 376, + "top": -144, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QMaQUG/rlG8=" + }, + "tail": { + "$ref": "AAAAAAF5P6IYDFMMeFQ=" + }, + "lineStyle": 1, + "points": "208:555;1768:1439", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5P6KuWFYzBrY=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5P6KuWFY07+U=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5P6KuWFY1T2M=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5P6KuWFY2uTU=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5P6KuWFY3Q0s=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5P6KuWFY4NMQ=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5P6KuWFY5sZg=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5P6KuWFY62Oo=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5P6KuWFY78L8=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5P6KuWFY8wFs=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5P6KuWVY9b40=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5QJWvCwgzk0M=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QJWvCggxZrM=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5QJWvCwg0EPw=", + "_parent": { + "$ref": "AAAAAAF5QJWvCwgzk0M=" + }, + "model": { + "$ref": "AAAAAAF5QJWvCggxZrM=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5QJWvCwg1NpM=", + "_parent": { + "$ref": "AAAAAAF5QJWvCwg0EPw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1920, + "top": 2944, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJWvCwg2wKE=", + "_parent": { + "$ref": "AAAAAAF5QJWvCwg0EPw=" + }, + "font": "Arial;13;1", + "left": 1752, + "top": 1875.5, + "width": 119, + "height": 13, + "text": "move2NextValidate" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJWvCwg3lvo=", + "_parent": { + "$ref": "AAAAAAF5QJWvCwg0EPw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1920, + "top": 2944, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJWvCwg4tCw=", + "_parent": { + "$ref": "AAAAAAF5QJWvCwg0EPw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1920, + "top": 2944, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 1747, + "top": 1868.5, + "width": 129, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5QJWvCwg1NpM=" + }, + "nameLabel": { + "$ref": "AAAAAAF5QJWvCwg2wKE=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5QJWvCwg3lvo=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QJWvCwg4tCw=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5QJWvCwg5PfY=", + "_parent": { + "$ref": "AAAAAAF5QJWvCwgzk0M=" + }, + "model": { + "$ref": "AAAAAAF5QJWvCggxZrM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 960, + "top": 1472, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5QJWvDAg6ClE=", + "_parent": { + "$ref": "AAAAAAF5QJWvCwgzk0M=" + }, + "model": { + "$ref": "AAAAAAF5QJWvCggxZrM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 960, + "top": 1472, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5QJWvDAg7Ros=", + "_parent": { + "$ref": "AAAAAAF5QJWvCwgzk0M=" + }, + "model": { + "$ref": "AAAAAAF5QJWvCggxZrM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 960, + "top": 1472, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5QJWvDAg8tC0=", + "_parent": { + "$ref": "AAAAAAF5QJWvCwgzk0M=" + }, + "model": { + "$ref": "AAAAAAF5QJWvCggxZrM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 960, + "top": 1472, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5QJWvDAg9Vl8=", + "_parent": { + "$ref": "AAAAAAF5QJWvCwgzk0M=" + }, + "model": { + "$ref": "AAAAAAF5QJWvCggxZrM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 960, + "top": 1472, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 1720, + "top": 1864, + "width": 183, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5QJWvCwg0EPw=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5QJWvCwg5PfY=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5QJWvDAg6ClE=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5QJWvDAg7Ros=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5QJWvDAg8tC0=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5QJWvDAg9Vl8=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QJesYRAYGmw=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QJesYRAUeZI=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJesYRAZQUY=", + "_parent": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "model": { + "$ref": "AAAAAAF5QJesYRAUeZI=" + }, + "font": "Arial;13;0", + "left": 1492, + "top": 300, + "width": 189.2279815673828, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "edgePosition": 1, + "text": "+测站不闭合or半测回归零差正常" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJesYRAa+X8=", + "_parent": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "model": { + "$ref": "AAAAAAF5QJesYRAUeZI=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1589, + "top": 285, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJesYRAb41g=", + "_parent": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "model": { + "$ref": "AAAAAAF5QJesYRAUeZI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1579, + "top": 329, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJesYhAcFHE=", + "_parent": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "model": { + "$ref": "AAAAAAF5QJesYRAV/Pw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1415, + "top": 260, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJesYhAdnH8=", + "_parent": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "model": { + "$ref": "AAAAAAF5QJesYRAV/Pw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1420, + "top": 247, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJesYhAeLA0=", + "_parent": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "model": { + "$ref": "AAAAAAF5QJesYRAV/Pw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1405, + "top": 286, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJesYhAfocQ=", + "_parent": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "model": { + "$ref": "AAAAAAF5QJesYRAWIno=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1758, + "top": 340, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJesYhAgNDY=", + "_parent": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "model": { + "$ref": "AAAAAAF5QJesYRAWIno=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1758, + "top": 327, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJesYhAh4Q4=", + "_parent": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "model": { + "$ref": "AAAAAAF5QJesYRAWIno=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1756, + "top": 368, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QJesYhAiBdg=", + "_parent": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "model": { + "$ref": "AAAAAAF5QJesYRAV/Pw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 112, + "top": -144, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QJesYhAjzjQ=", + "_parent": { + "$ref": "AAAAAAF5QJesYRAYGmw=" + }, + "model": { + "$ref": "AAAAAAF5QJesYRAWIno=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 112, + "top": -144, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5Ss1QmDKthXI=" + }, + "tail": { + "$ref": "AAAAAAF5Ssw/NBbRxlk=" + }, + "lineStyle": 1, + "points": "1387:275;1780:367", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QJesYRAZQUY=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QJesYRAa+X8=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QJesYRAb41g=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QJesYhAcFHE=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QJesYhAdnH8=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QJesYhAeLA0=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QJesYhAfocQ=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QJesYhAgNDY=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QJesYhAh4Q4=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QJesYhAiBdg=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QJesYhAjzjQ=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5QJjLZRML/gk=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5QJjLZRMMO54=", + "_parent": { + "$ref": "AAAAAAF5QJjLZRML/gk=" + }, + "model": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5QJjLZRMN0eQ=", + "_parent": { + "$ref": "AAAAAAF5QJjLZRMMO54=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 784, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJjLZRMOGnw=", + "_parent": { + "$ref": "AAAAAAF5QJjLZRMMO54=" + }, + "fillColor": "#8282ff", + "font": "Arial;13;1", + "left": 820, + "top": 467.5, + "width": 139, + "height": 13, + "text": "switchState2StandStill" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJjLZRMPJsQ=", + "_parent": { + "$ref": "AAAAAAF5QJjLZRMMO54=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 784, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJjLZRMQZsw=", + "_parent": { + "$ref": "AAAAAAF5QJjLZRMMO54=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 784, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 815, + "top": 460.5, + "width": 149.419921875, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5QJjLZRMN0eQ=" + }, + "nameLabel": { + "$ref": "AAAAAAF5QJjLZRMOGnw=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5QJjLZRMPJsQ=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QJjLZRMQZsw=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5QJjLZRMRZxg=", + "_parent": { + "$ref": "AAAAAAF5QJjLZRML/gk=" + }, + "model": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 392, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5QJjLZRMSuGM=", + "_parent": { + "$ref": "AAAAAAF5QJjLZRML/gk=" + }, + "model": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 392, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5QJjLZRMTa74=", + "_parent": { + "$ref": "AAAAAAF5QJjLZRML/gk=" + }, + "model": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 392, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5QJjLZRMUk04=", + "_parent": { + "$ref": "AAAAAAF5QJjLZRML/gk=" + }, + "model": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 392, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5QJjLZRMVcTY=", + "_parent": { + "$ref": "AAAAAAF5QJjLZRML/gk=" + }, + "model": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 392, + "width": 10, + "height": 10 + } + ], + "fillColor": "#8282ff", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 784, + "top": 456, + "width": 211, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5QJjLZRMMO54=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5QJjLZRMRZxg=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5QJjLZRMSuGM=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5QJjLZRMTa74=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5QJjLZRMUk04=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5QJjLZRMVcTY=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5QJk5ohVYjKI=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QJk5ohVWyGc=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5QJk5ohVZ7LA=", + "_parent": { + "$ref": "AAAAAAF5QJk5ohVYjKI=" + }, + "model": { + "$ref": "AAAAAAF5QJk5ohVWyGc=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5QJk5ohVaBvo=", + "_parent": { + "$ref": "AAAAAAF5QJk5ohVZ7LA=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 1040, + "top": -608, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJk5ohVbtSw=", + "_parent": { + "$ref": "AAAAAAF5QJk5ohVZ7LA=" + }, + "fillColor": "#ff8282", + "font": "Arial;13;1", + "left": 925, + "top": 267.5, + "width": 142, + "height": 13, + "text": "提示半测回归零检测失败" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJk5ohVc1ns=", + "_parent": { + "$ref": "AAAAAAF5QJk5ohVZ7LA=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 1040, + "top": -608, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJk5ohVdnqY=", + "_parent": { + "$ref": "AAAAAAF5QJk5ohVZ7LA=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 1040, + "top": -608, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 920, + "top": 260.5, + "width": 153, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5QJk5ohVaBvo=" + }, + "nameLabel": { + "$ref": "AAAAAAF5QJk5ohVbtSw=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5QJk5ohVc1ns=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QJk5ohVdnqY=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5QJk5ohVeC3M=", + "_parent": { + "$ref": "AAAAAAF5QJk5ohVYjKI=" + }, + "model": { + "$ref": "AAAAAAF5QJk5ohVWyGc=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 520, + "top": -304, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5QJk5ohVfd1M=", + "_parent": { + "$ref": "AAAAAAF5QJk5ohVYjKI=" + }, + "model": { + "$ref": "AAAAAAF5QJk5ohVWyGc=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 520, + "top": -304, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5QJk5ohVg6Qc=", + "_parent": { + "$ref": "AAAAAAF5QJk5ohVYjKI=" + }, + "model": { + "$ref": "AAAAAAF5QJk5ohVWyGc=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 520, + "top": -304, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5QJk5ohVh4ZY=", + "_parent": { + "$ref": "AAAAAAF5QJk5ohVYjKI=" + }, + "model": { + "$ref": "AAAAAAF5QJk5ohVWyGc=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 520, + "top": -304, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5QJk5ohViitY=", + "_parent": { + "$ref": "AAAAAAF5QJk5ohVYjKI=" + }, + "model": { + "$ref": "AAAAAAF5QJk5ohVWyGc=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 520, + "top": -304, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ff8282", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 888, + "top": 256, + "width": 216, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5QJk5ohVZ7LA=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5QJk5ohVeC3M=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5QJk5ohVfd1M=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5QJk5ohVg6Qc=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5QJk5ohVh4ZY=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5QJk5ohViitY=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QJmQwBdwdmk=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QJmQwBdscKg=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJmQwBdxb3k=", + "_parent": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "model": { + "$ref": "AAAAAAF5QJmQwBdscKg=" + }, + "font": "Arial;13;0", + "left": 1117, + "top": 272, + "width": 85.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "edgePosition": 1, + "text": "+没有通过检测" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJmQwRdyFDg=", + "_parent": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "model": { + "$ref": "AAAAAAF5QJmQwBdscKg=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1160, + "top": 287, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJmQwRdzOi4=", + "_parent": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "model": { + "$ref": "AAAAAAF5QJmQwBdscKg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1158, + "top": 243, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJmQwRd0cxc=", + "_parent": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "model": { + "$ref": "AAAAAAF5QJmQwBdt/Nk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1189, + "top": 272, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJmQwRd1+jk=", + "_parent": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "model": { + "$ref": "AAAAAAF5QJmQwBdt/Nk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1188, + "top": 285, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJmQwRd2je8=", + "_parent": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "model": { + "$ref": "AAAAAAF5QJmQwBdt/Nk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1192, + "top": 244, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJmQwRd3aOM=", + "_parent": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "model": { + "$ref": "AAAAAAF5QJmQwBdu0wk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1130, + "top": 274, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJmQwRd4cEI=", + "_parent": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "model": { + "$ref": "AAAAAAF5QJmQwBdu0wk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1133, + "top": 287, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJmQwRd5h7I=", + "_parent": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "model": { + "$ref": "AAAAAAF5QJmQwBdu0wk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1125, + "top": 247, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QJmQwRd6XO0=", + "_parent": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "model": { + "$ref": "AAAAAAF5QJmQwBdt/Nk=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QJmQwRd7bPQ=", + "_parent": { + "$ref": "AAAAAAF5QJmQwBdwdmk=" + }, + "model": { + "$ref": "AAAAAAF5QJmQwBdu0wk=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QJk5ohVYjKI=" + }, + "tail": { + "$ref": "AAAAAAF5Ssw/NBbRxlk=" + }, + "lineStyle": 1, + "points": "1215:262;1104:267", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QJmQwBdxb3k=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QJmQwRdyFDg=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QJmQwRdzOi4=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QJmQwRd0cxc=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QJmQwRd1+jk=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QJmQwRd2je8=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QJmQwRd3aOM=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QJmQwRd4cEI=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QJmQwRd5h7I=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QJmQwRd6XO0=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QJmQwRd7bPQ=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QJnHsRkO52k=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QJnHsRkKHYc=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnHsRkPXt4=", + "_parent": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "model": { + "$ref": "AAAAAAF5QJnHsRkKHYc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 955, + "top": 373, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnHsRkQg5M=", + "_parent": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "model": { + "$ref": "AAAAAAF5QJnHsRkKHYc=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 968, + "top": 380, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnHsRkRfd8=", + "_parent": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "model": { + "$ref": "AAAAAAF5QJnHsRkKHYc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 928, + "top": 360, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnHsRkS/7E=", + "_parent": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "model": { + "$ref": "AAAAAAF5QJnHsRkLdTo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 986, + "top": 314, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnHsRkTUvo=", + "_parent": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "model": { + "$ref": "AAAAAAF5QJnHsRkLdTo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 996, + "top": 323, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnHsRkU2kA=", + "_parent": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "model": { + "$ref": "AAAAAAF5QJnHsRkLdTo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 963, + "top": 298, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnHsRkVrbg=", + "_parent": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "model": { + "$ref": "AAAAAAF5QJnHsRkM5N4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 924, + "top": 432, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnHsRkWL5A=", + "_parent": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "model": { + "$ref": "AAAAAAF5QJnHsRkM5N4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 937, + "top": 437, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnHsRkXIlE=", + "_parent": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "model": { + "$ref": "AAAAAAF5QJnHsRkM5N4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 897, + "top": 424, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QJnHsRkYjF0=", + "_parent": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "model": { + "$ref": "AAAAAAF5QJnHsRkLdTo=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QJnHsRkZRp4=", + "_parent": { + "$ref": "AAAAAAF5QJnHsRkO52k=" + }, + "model": { + "$ref": "AAAAAAF5QJnHsRkM5N4=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QJjLZRML/gk=" + }, + "tail": { + "$ref": "AAAAAAF5QJk5ohVYjKI=" + }, + "lineStyle": 1, + "points": "985:291;899:455", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QJnHsRkPXt4=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QJnHsRkQg5M=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QJnHsRkRfd8=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QJnHsRkS/7E=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QJnHsRkTUvo=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QJnHsRkU2kA=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QJnHsRkVrbg=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QJnHsRkWL5A=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QJnHsRkXIlE=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QJnHsRkYjF0=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QJnHsRkZRp4=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QJnk3hnngQ0=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QJnk3RnjFKU=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnk3hnoFuM=", + "_parent": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "model": { + "$ref": "AAAAAAF5QJnk3RnjFKU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1111, + "top": 411, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnk3hnpzsU=", + "_parent": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "model": { + "$ref": "AAAAAAF5QJnk3RnjFKU=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1108, + "top": 396, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnk3hnqowI=", + "_parent": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "model": { + "$ref": "AAAAAAF5QJnk3RnjFKU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1116, + "top": 440, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnk3hnr2A8=", + "_parent": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "model": { + "$ref": "AAAAAAF5QJnk3Rnk4S8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1011, + "top": 429, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnk3hnsPz4=", + "_parent": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "model": { + "$ref": "AAAAAAF5QJnk3Rnk4S8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1011, + "top": 416, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnk3hnt7X0=", + "_parent": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "model": { + "$ref": "AAAAAAF5QJnk3Rnk4S8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1012, + "top": 457, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnk3hnuPbw=", + "_parent": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "model": { + "$ref": "AAAAAAF5QJnk3Rnlvxc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1210, + "top": 393, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnk3hnvOwA=", + "_parent": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "model": { + "$ref": "AAAAAAF5QJnk3Rnlvxc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1206, + "top": 381, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJnk3hnwvuU=", + "_parent": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "model": { + "$ref": "AAAAAAF5QJnk3Rnlvxc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1219, + "top": 420, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QJnk3hnxCbA=", + "_parent": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "model": { + "$ref": "AAAAAAF5QJnk3Rnk4S8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 264, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QJnk3hny8xs=", + "_parent": { + "$ref": "AAAAAAF5QJnk3hnngQ0=" + }, + "model": { + "$ref": "AAAAAAF5QJnk3Rnlvxc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 264, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5P5/CAk98zZc=" + }, + "tail": { + "$ref": "AAAAAAF5QJjLZRML/gk=" + }, + "lineStyle": 1, + "points": "989:455;1239:410", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QJnk3hnoFuM=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QJnk3hnpzsU=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QJnk3hnqowI=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QJnk3hnr2A8=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QJnk3hnsPz4=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QJnk3hnt7X0=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QJnk3hnuPbw=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QJnk3hnvOwA=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QJnk3hnwvuU=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QJnk3hnxCbA=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QJnk3hny8xs=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5QJ6ahiPXyXI=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QJ6ahSPVJNg=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5QJ6ahiPYzM0=", + "_parent": { + "$ref": "AAAAAAF5QJ6ahiPXyXI=" + }, + "model": { + "$ref": "AAAAAAF5QJ6ahSPVJNg=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5QJ6ahiPZdhA=", + "_parent": { + "$ref": "AAAAAAF5QJ6ahiPYzM0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -544, + "top": -656, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJ6ahiPa2BQ=", + "_parent": { + "$ref": "AAAAAAF5QJ6ahiPYzM0=" + }, + "font": "Arial;13;1", + "left": 419.5, + "top": 243.5, + "width": 96, + "height": 13, + "text": "checkReadData" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJ6ahyPb1CY=", + "_parent": { + "$ref": "AAAAAAF5QJ6ahiPYzM0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -544, + "top": -656, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJ6ahyPcSJM=", + "_parent": { + "$ref": "AAAAAAF5QJ6ahiPYzM0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -544, + "top": -656, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 414.5, + "top": 236.5, + "width": 106.8271484375, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5QJ6ahiPZdhA=" + }, + "nameLabel": { + "$ref": "AAAAAAF5QJ6ahiPa2BQ=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5QJ6ahyPb1CY=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QJ6ahyPcSJM=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5QJ6ahyPdwvQ=", + "_parent": { + "$ref": "AAAAAAF5QJ6ahiPXyXI=" + }, + "model": { + "$ref": "AAAAAAF5QJ6ahSPVJNg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -272, + "top": -328, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5QJ6ahyPeius=", + "_parent": { + "$ref": "AAAAAAF5QJ6ahiPXyXI=" + }, + "model": { + "$ref": "AAAAAAF5QJ6ahSPVJNg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -272, + "top": -328, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5QJ6ahyPfDuE=", + "_parent": { + "$ref": "AAAAAAF5QJ6ahiPXyXI=" + }, + "model": { + "$ref": "AAAAAAF5QJ6ahSPVJNg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -272, + "top": -328, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5QJ6ahyPgVJE=", + "_parent": { + "$ref": "AAAAAAF5QJ6ahiPXyXI=" + }, + "model": { + "$ref": "AAAAAAF5QJ6ahSPVJNg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -272, + "top": -328, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5QJ6ahyPhyOw=", + "_parent": { + "$ref": "AAAAAAF5QJ6ahiPXyXI=" + }, + "model": { + "$ref": "AAAAAAF5QJ6ahSPVJNg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -272, + "top": -328, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 392, + "top": 232, + "width": 151, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5QJ6ahiPYzM0=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5QJ6ahyPdwvQ=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5QJ6ahyPeius=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5QJ6ahyPfDuE=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5QJ6ahyPgVJE=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5QJ6ahyPhyOw=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5QJ8m8Sf6ofY=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QJ8m8Sf4R1w=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5QJ8m8Sf7JBU=", + "_parent": { + "$ref": "AAAAAAF5QJ8m8Sf6ofY=" + }, + "model": { + "$ref": "AAAAAAF5QJ8m8Sf4R1w=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5QJ8m8Sf8/hc=", + "_parent": { + "$ref": "AAAAAAF5QJ8m8Sf7JBU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1504, + "top": -1248, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJ8m8Sf9x9A=", + "_parent": { + "$ref": "AAAAAAF5QJ8m8Sf7JBU=" + }, + "font": "Arial;13;1", + "left": 1252, + "top": 123.5, + "width": 175, + "height": 13, + "text": "isHalfCycleZeroCheckReady" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJ8m8Sf+ddw=", + "_parent": { + "$ref": "AAAAAAF5QJ8m8Sf7JBU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1504, + "top": -1248, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJ8m8Sf/cbI=", + "_parent": { + "$ref": "AAAAAAF5QJ8m8Sf7JBU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1504, + "top": -1248, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 1247, + "top": 116.5, + "width": 186.2998046875, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5QJ8m8Sf8/hc=" + }, + "nameLabel": { + "$ref": "AAAAAAF5QJ8m8Sf9x9A=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5QJ8m8Sf+ddw=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QJ8m8Sf/cbI=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5QJ8m8SgAs+Y=", + "_parent": { + "$ref": "AAAAAAF5QJ8m8Sf6ofY=" + }, + "model": { + "$ref": "AAAAAAF5QJ8m8Sf4R1w=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 752, + "top": -624, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5QJ8m8SgBoKU=", + "_parent": { + "$ref": "AAAAAAF5QJ8m8Sf6ofY=" + }, + "model": { + "$ref": "AAAAAAF5QJ8m8Sf4R1w=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 752, + "top": -624, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5QJ8m8SgCMgY=", + "_parent": { + "$ref": "AAAAAAF5QJ8m8Sf6ofY=" + }, + "model": { + "$ref": "AAAAAAF5QJ8m8Sf4R1w=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 752, + "top": -624, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5QJ8m8SgDeic=", + "_parent": { + "$ref": "AAAAAAF5QJ8m8Sf6ofY=" + }, + "model": { + "$ref": "AAAAAAF5QJ8m8Sf4R1w=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 752, + "top": -624, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5QJ8m8SgEIBM=", + "_parent": { + "$ref": "AAAAAAF5QJ8m8Sf6ofY=" + }, + "model": { + "$ref": "AAAAAAF5QJ8m8Sf4R1w=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 752, + "top": -624, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 1208, + "top": 112, + "width": 263, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5QJ8m8Sf7JBU=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5QJ8m8SgAs+Y=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5QJ8m8SgBoKU=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5QJ8m8SgCMgY=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5QJ8m8SgDeic=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5QJ8m8SgEIBM=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QJ87PCkCJ2c=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QJ87Oyj+dCg=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ87PCkD2ew=", + "_parent": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "model": { + "$ref": "AAAAAAF5QJ87Oyj+dCg=" + }, + "font": "Arial;13;0", + "left": 817, + "top": 172, + "width": 111.22798156738281, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "edgePosition": 1, + "text": "+单测量or通过检测" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ87PCkEHYk=", + "_parent": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "model": { + "$ref": "AAAAAAF5QJ87Oyj+dCg=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 870, + "top": 157, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ87PCkFD0M=", + "_parent": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "model": { + "$ref": "AAAAAAF5QJ87Oyj+dCg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 877, + "top": 201, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ87PCkGBOM=", + "_parent": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "model": { + "$ref": "AAAAAAF5QJ87Oyj/TJQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 566, + "top": 214, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ87PCkHciQ=", + "_parent": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "model": { + "$ref": "AAAAAAF5QJ87Oyj/TJQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 567, + "top": 201, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ87PCkI53k=", + "_parent": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "model": { + "$ref": "AAAAAAF5QJ87Oyj/TJQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 566, + "top": 242, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ87PCkJ5DY=", + "_parent": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "model": { + "$ref": "AAAAAAF5QJ87OykA4RY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1180, + "top": 129, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ87PCkKd2s=", + "_parent": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "model": { + "$ref": "AAAAAAF5QJ87OykA4RY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1176, + "top": 116, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ87PCkLnCE=", + "_parent": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "model": { + "$ref": "AAAAAAF5QJ87OykA4RY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1188, + "top": 156, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QJ87PCkMizE=", + "_parent": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "model": { + "$ref": "AAAAAAF5QJ87Oyj/TJQ=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QJ87PCkNuH0=", + "_parent": { + "$ref": "AAAAAAF5QJ87PCkCJ2c=" + }, + "model": { + "$ref": "AAAAAAF5QJ87OykA4RY=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QJ8m8Sf6ofY=" + }, + "tail": { + "$ref": "AAAAAAF5QJ6ahiPXyXI=" + }, + "lineStyle": 1, + "points": "543:239;1208:147", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QJ87PCkD2ew=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QJ87PCkEHYk=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QJ87PCkFD0M=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QJ87PCkGBOM=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QJ87PCkHciQ=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QJ87PCkI53k=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QJ87PCkJ5DY=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QJ87PCkKd2s=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QJ87PCkLnCE=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QJ87PCkMizE=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QJ87PCkNuH0=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5QJ+mRitZ0H0=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QJ+mRitXafY=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5QJ+mRitad0o=", + "_parent": { + "$ref": "AAAAAAF5QJ+mRitZ0H0=" + }, + "model": { + "$ref": "AAAAAAF5QJ+mRitXafY=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5QJ+mRitbxtk=", + "_parent": { + "$ref": "AAAAAAF5QJ+mRitad0o=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 736, + "top": -560, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJ+mRytcRUc=", + "_parent": { + "$ref": "AAAAAAF5QJ+mRitad0o=" + }, + "fillColor": "#ff8282", + "font": "Arial;13;1", + "left": 687.5, + "top": 291.5, + "width": 77, + "height": 13, + "text": "提示读数有误" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJ+mRytdKoM=", + "_parent": { + "$ref": "AAAAAAF5QJ+mRitad0o=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 736, + "top": -560, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QJ+mRytecXk=", + "_parent": { + "$ref": "AAAAAAF5QJ+mRitad0o=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 736, + "top": -560, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 682.5, + "top": 284.5, + "width": 88, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5QJ+mRitbxtk=" + }, + "nameLabel": { + "$ref": "AAAAAAF5QJ+mRytcRUc=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5QJ+mRytdKoM=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QJ+mRytecXk=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5QJ+mRytf9wc=", + "_parent": { + "$ref": "AAAAAAF5QJ+mRitZ0H0=" + }, + "model": { + "$ref": "AAAAAAF5QJ+mRitXafY=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 368, + "top": -280, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5QJ+mRytgl/8=", + "_parent": { + "$ref": "AAAAAAF5QJ+mRitZ0H0=" + }, + "model": { + "$ref": "AAAAAAF5QJ+mRitXafY=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 368, + "top": -280, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5QJ+mRythGBg=", + "_parent": { + "$ref": "AAAAAAF5QJ+mRitZ0H0=" + }, + "model": { + "$ref": "AAAAAAF5QJ+mRitXafY=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 368, + "top": -280, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5QJ+mRytiPDo=", + "_parent": { + "$ref": "AAAAAAF5QJ+mRitZ0H0=" + }, + "model": { + "$ref": "AAAAAAF5QJ+mRitXafY=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 368, + "top": -280, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5QJ+mRytjdZM=", + "_parent": { + "$ref": "AAAAAAF5QJ+mRitZ0H0=" + }, + "model": { + "$ref": "AAAAAAF5QJ+mRitXafY=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 368, + "top": -280, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ff8282", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 664, + "top": 280, + "width": 124, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5QJ+mRitad0o=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5QJ+mRytf9wc=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5QJ+mRytgl/8=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5QJ+mRythGBg=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5QJ+mRytiPDo=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5QJ+mRytjdZM=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QJ/UgywlH50=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QJ/Ugywh52g=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/Ugywm6Cw=", + "_parent": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "model": { + "$ref": "AAAAAAF5QJ/Ugywh52g=" + }, + "font": "Arial;13;0", + "left": 569, + "top": 253, + "width": 72.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "edgePosition": 1, + "text": "+未通过检测" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/UgywnNpM=", + "_parent": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "model": { + "$ref": "AAAAAAF5QJ/Ugywh52g=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 608, + "top": 238, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/UgywoaZM=", + "_parent": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "model": { + "$ref": "AAAAAAF5QJ/Ugywh52g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 600, + "top": 282, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/UhCwpjOU=", + "_parent": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "model": { + "$ref": "AAAAAAF5QJ/Ugywiha4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 571, + "top": 246, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/UhCwqyBI=", + "_parent": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "model": { + "$ref": "AAAAAAF5QJ/Ugywiha4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 575, + "top": 234, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/UhCwrLDA=", + "_parent": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "model": { + "$ref": "AAAAAAF5QJ/Ugywiha4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 562, + "top": 273, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/UhCws+Vw=", + "_parent": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "model": { + "$ref": "AAAAAAF5QJ/UgywjRPE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 640, + "top": 259, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/UhCwtL5c=", + "_parent": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "model": { + "$ref": "AAAAAAF5QJ/UgywjRPE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 640, + "top": 246, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/UhCwuYNo=", + "_parent": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "model": { + "$ref": "AAAAAAF5QJ/UgywjRPE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 639, + "top": 287, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QJ/UhCwvaPk=", + "_parent": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "model": { + "$ref": "AAAAAAF5QJ/Ugywiha4=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QJ/UhCwwUDY=", + "_parent": { + "$ref": "AAAAAAF5QJ/UgywlH50=" + }, + "model": { + "$ref": "AAAAAAF5QJ/UgywjRPE=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QJ+mRitZ0H0=" + }, + "tail": { + "$ref": "AAAAAAF5QJ6ahiPXyXI=" + }, + "lineStyle": 1, + "points": "543:263;663:285", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QJ/Ugywm6Cw=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QJ/UgywnNpM=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QJ/UgywoaZM=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QJ/UhCwpjOU=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QJ/UhCwqyBI=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QJ/UhCwrLDA=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QJ/UhCws+Vw=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QJ/UhCwtL5c=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QJ/UhCwuYNo=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QJ/UhCwvaPk=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QJ/UhCwwUDY=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QJ/0PC0CShY=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QJ/0PCz+xYo=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/0PS0DtlQ=", + "_parent": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "model": { + "$ref": "AAAAAAF5QJ/0PCz+xYo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 817, + "top": 368, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/0PS0ETCk=", + "_parent": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "model": { + "$ref": "AAAAAAF5QJ/0PCz+xYo=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 828, + "top": 358, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/0PS0FS9M=", + "_parent": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "model": { + "$ref": "AAAAAAF5QJ/0PCz+xYo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 796, + "top": 389, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/0PS0G2RA=", + "_parent": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "model": { + "$ref": "AAAAAAF5QJ/0PCz/2CU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 770, + "top": 317, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/0PS0HEgs=", + "_parent": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "model": { + "$ref": "AAAAAAF5QJ/0PCz/2CU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 781, + "top": 310, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/0PS0IKu8=", + "_parent": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "model": { + "$ref": "AAAAAAF5QJ/0PCz/2CU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 747, + "top": 333, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/0PS0JtjU=", + "_parent": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "model": { + "$ref": "AAAAAAF5QJ/0PC0AjHo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 865, + "top": 419, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/0PS0KkBY=", + "_parent": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "model": { + "$ref": "AAAAAAF5QJ/0PC0AjHo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 873, + "top": 409, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QJ/0PS0LEUU=", + "_parent": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "model": { + "$ref": "AAAAAAF5QJ/0PC0AjHo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 848, + "top": 441, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QJ/0PS0MAmo=", + "_parent": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "model": { + "$ref": "AAAAAAF5QJ/0PCz/2CU=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QJ/0PS0Nb0Y=", + "_parent": { + "$ref": "AAAAAAF5QJ/0PC0CShY=" + }, + "model": { + "$ref": "AAAAAAF5QJ/0PC0AjHo=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QJjLZRML/gk=" + }, + "tail": { + "$ref": "AAAAAAF5QJ+mRitZ0H0=" + }, + "lineStyle": 1, + "points": "742:315;872:455", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QJ/0PS0DtlQ=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QJ/0PS0ETCk=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QJ/0PS0FS9M=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QJ/0PS0G2RA=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QJ/0PS0HEgs=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QJ/0PS0IKu8=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QJ/0PS0JtjU=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QJ/0PS0KkBY=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QJ/0PS0LEUU=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QJ/0PS0MAmo=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QJ/0PS0Nb0Y=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5QKE6Ojfzjv0=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QKE6OTfx/D4=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5QKE6Ojf0W9Y=", + "_parent": { + "$ref": "AAAAAAF5QKE6Ojfzjv0=" + }, + "model": { + "$ref": "AAAAAAF5QKE6OTfx/D4=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5QKE6Ojf12Ns=", + "_parent": { + "$ref": "AAAAAAF5QKE6Ojf0W9Y=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 3008, + "top": -336, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKE6Ojf2D5I=", + "_parent": { + "$ref": "AAAAAAF5QKE6Ojf0W9Y=" + }, + "font": "Arial;13;1", + "left": 2110, + "top": 779.5, + "width": 110, + "height": 13, + "text": "checkSingleCycle" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKE6Ojf3N+g=", + "_parent": { + "$ref": "AAAAAAF5QKE6Ojf0W9Y=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 3008, + "top": -336, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKE6Ojf4rrM=", + "_parent": { + "$ref": "AAAAAAF5QKE6Ojf0W9Y=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 3008, + "top": -336, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 2105, + "top": 772.5, + "width": 120.55712890625, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5QKE6Ojf12Ns=" + }, + "nameLabel": { + "$ref": "AAAAAAF5QKE6Ojf2D5I=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5QKE6Ojf3N+g=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QKE6Ojf4rrM=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5QKE6Ojf5X6A=", + "_parent": { + "$ref": "AAAAAAF5QKE6Ojfzjv0=" + }, + "model": { + "$ref": "AAAAAAF5QKE6OTfx/D4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1504, + "top": -168, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5QKE6Ojf6i5o=", + "_parent": { + "$ref": "AAAAAAF5QKE6Ojfzjv0=" + }, + "model": { + "$ref": "AAAAAAF5QKE6OTfx/D4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1504, + "top": -168, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5QKE6Ojf7hDo=", + "_parent": { + "$ref": "AAAAAAF5QKE6Ojfzjv0=" + }, + "model": { + "$ref": "AAAAAAF5QKE6OTfx/D4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1504, + "top": -168, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5QKE6Ojf8oq8=", + "_parent": { + "$ref": "AAAAAAF5QKE6Ojfzjv0=" + }, + "model": { + "$ref": "AAAAAAF5QKE6OTfx/D4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1504, + "top": -168, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5QKE6Ojf9edk=", + "_parent": { + "$ref": "AAAAAAF5QKE6Ojfzjv0=" + }, + "model": { + "$ref": "AAAAAAF5QKE6OTfx/D4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1504, + "top": -168, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 2080, + "top": 768, + "width": 170, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5QKE6Ojf0W9Y=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5QKE6Ojf5X6A=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5QKE6Ojf6i5o=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5QKE6Ojf7hDo=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5QKE6Ojf8oq8=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5QKE6Ojf9edk=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5QKIG+T9Y4ko=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QKIG+T9Wjdo=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5QKIG+T9Zl2o=", + "_parent": { + "$ref": "AAAAAAF5QKIG+T9Y4ko=" + }, + "model": { + "$ref": "AAAAAAF5QKIG+T9Wjdo=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5QKIG+T9a7vU=", + "_parent": { + "$ref": "AAAAAAF5QKIG+T9Zl2o=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2160, + "top": -1008, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKIG+T9bDug=", + "_parent": { + "$ref": "AAAAAAF5QKIG+T9Zl2o=" + }, + "font": "Arial;13;1", + "left": 1762, + "top": 523.5, + "width": 129, + "height": 13, + "text": "isAllCycleCompleted" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKIG+T9cIfM=", + "_parent": { + "$ref": "AAAAAAF5QKIG+T9Zl2o=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2160, + "top": -1008, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKIG+T9dArI=", + "_parent": { + "$ref": "AAAAAAF5QKIG+T9Zl2o=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2160, + "top": -1008, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 1757, + "top": 516.5, + "width": 139.314453125, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5QKIG+T9a7vU=" + }, + "nameLabel": { + "$ref": "AAAAAAF5QKIG+T9bDug=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5QKIG+T9cIfM=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QKIG+T9dArI=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5QKIG+T9e1Wk=", + "_parent": { + "$ref": "AAAAAAF5QKIG+T9Y4ko=" + }, + "model": { + "$ref": "AAAAAAF5QKIG+T9Wjdo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1080, + "top": -504, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5QKIG+T9fRvU=", + "_parent": { + "$ref": "AAAAAAF5QKIG+T9Y4ko=" + }, + "model": { + "$ref": "AAAAAAF5QKIG+T9Wjdo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1080, + "top": -504, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5QKIG+T9gBhM=", + "_parent": { + "$ref": "AAAAAAF5QKIG+T9Y4ko=" + }, + "model": { + "$ref": "AAAAAAF5QKIG+T9Wjdo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1080, + "top": -504, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5QKIG+T9hA48=", + "_parent": { + "$ref": "AAAAAAF5QKIG+T9Y4ko=" + }, + "model": { + "$ref": "AAAAAAF5QKIG+T9Wjdo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1080, + "top": -504, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5QKIG+T9inVI=", + "_parent": { + "$ref": "AAAAAAF5QKIG+T9Y4ko=" + }, + "model": { + "$ref": "AAAAAAF5QKIG+T9Wjdo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1080, + "top": -504, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 1728, + "top": 512, + "width": 197, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5QKIG+T9Zl2o=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5QKIG+T9e1Wk=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5QKIG+T9fRvU=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5QKIG+T9gBhM=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5QKIG+T9hA48=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5QKIG+T9inVI=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QKI4zEKHpSc=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QKI4y0KDGow=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKI4zEKIQ1c=", + "_parent": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "model": { + "$ref": "AAAAAAF5QKI4y0KDGow=" + }, + "font": "Arial;13;0", + "left": 1956, + "top": 662, + "width": 59.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "edgePosition": 1, + "text": "+通过检测" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKI4zEKJdn8=", + "_parent": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "model": { + "$ref": "AAAAAAF5QKI4y0KDGow=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1976, + "top": 674, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKI4zEKKTG0=", + "_parent": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "model": { + "$ref": "AAAAAAF5QKI4y0KDGow=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2004, + "top": 639, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKI4zEKL0+I=", + "_parent": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "model": { + "$ref": "AAAAAAF5QKI4zEKEuw8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2110, + "top": 757, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKI4zEKMDrE=", + "_parent": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "model": { + "$ref": "AAAAAAF5QKI4zEKEuw8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2100, + "top": 766, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKI4zEKNoT0=", + "_parent": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "model": { + "$ref": "AAAAAAF5QKI4zEKEuw8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2130, + "top": 737, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKI4zEKOx2g=", + "_parent": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "model": { + "$ref": "AAAAAAF5QKI4zEKFtZg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1861, + "top": 568, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKI4zEKP85E=", + "_parent": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "model": { + "$ref": "AAAAAAF5QKI4zEKFtZg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1855, + "top": 580, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKI4zEKQLJU=", + "_parent": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "model": { + "$ref": "AAAAAAF5QKI4zEKFtZg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1874, + "top": 544, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QKI4zEKR1Nc=", + "_parent": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "model": { + "$ref": "AAAAAAF5QKI4zEKEuw8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 264, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QKI4zEKSZgo=", + "_parent": { + "$ref": "AAAAAAF5QKI4zEKHpSc=" + }, + "model": { + "$ref": "AAAAAAF5QKI4zEKFtZg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 264, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QKIG+T9Y4ko=" + }, + "tail": { + "$ref": "AAAAAAF5QKE6Ojfzjv0=" + }, + "lineStyle": 1, + "points": "2140:767;1850:547", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QKI4zEKIQ1c=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QKI4zEKJdn8=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QKI4zEKKTG0=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QKI4zEKL0+I=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QKI4zEKMDrE=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QKI4zEKNoT0=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QKI4zEKOx2g=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QKI4zEKP85E=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QKI4zEKQLJU=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QKI4zEKR1Nc=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QKI4zEKSZgo=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5QKuCwkzY630=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5QKuCwkzZLtk=", + "_parent": { + "$ref": "AAAAAAF5QKuCwkzY630=" + }, + "model": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5QKuCwkzadw4=", + "_parent": { + "$ref": "AAAAAAF5QKuCwkzZLtk=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 2704, + "top": 112, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKuCwkzbRGU=", + "_parent": { + "$ref": "AAAAAAF5QKuCwkzZLtk=" + }, + "fillColor": "#ff8282", + "font": "Arial;13;1", + "left": 1879.5, + "top": 995.5, + "width": 77, + "height": 13, + "text": "提示用户选择" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKuCwkzc5kQ=", + "_parent": { + "$ref": "AAAAAAF5QKuCwkzZLtk=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 2704, + "top": 112, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKuCwkzd3VI=", + "_parent": { + "$ref": "AAAAAAF5QKuCwkzZLtk=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 2704, + "top": 112, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 1874.5, + "top": 988.5, + "width": 88, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5QKuCwkzadw4=" + }, + "nameLabel": { + "$ref": "AAAAAAF5QKuCwkzbRGU=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5QKuCwkzc5kQ=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QKuCwkzd3VI=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5QKuCw0zeMMo=", + "_parent": { + "$ref": "AAAAAAF5QKuCwkzY630=" + }, + "model": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 1352, + "top": 56, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5QKuCw0zfhJM=", + "_parent": { + "$ref": "AAAAAAF5QKuCwkzY630=" + }, + "model": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 1352, + "top": 56, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5QKuCw0zgO20=", + "_parent": { + "$ref": "AAAAAAF5QKuCwkzY630=" + }, + "model": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 1352, + "top": 56, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5QKuCw0zhG3k=", + "_parent": { + "$ref": "AAAAAAF5QKuCwkzY630=" + }, + "model": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 1352, + "top": 56, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5QKuCw0ziN7I=", + "_parent": { + "$ref": "AAAAAAF5QKuCwkzY630=" + }, + "model": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 1352, + "top": 56, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ff8282", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 1856, + "top": 984, + "width": 124, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5QKuCwkzZLtk=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5QKuCw0zeMMo=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5QKuCw0zfhJM=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5QKuCw0zgO20=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5QKuCw0zhG3k=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5QKuCw0ziN7I=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QKvMIE8ZF/E=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QKvMIE8VEZE=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKvMIU8a1To=", + "_parent": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "model": { + "$ref": "AAAAAAF5QKvMIE8VEZE=" + }, + "font": "Arial;13;0", + "left": 2013, + "top": 898, + "width": 72.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "edgePosition": 1, + "text": "+未通过检测" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKvMIU8bx7Y=", + "_parent": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "model": { + "$ref": "AAAAAAF5QKvMIE8VEZE=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 2059, + "top": 909, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKvMIU8c/MU=", + "_parent": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "model": { + "$ref": "AAAAAAF5QKvMIE8VEZE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2030, + "top": 875, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKvMIU8df1Y=", + "_parent": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "model": { + "$ref": "AAAAAAF5QKvMIE8WKCE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2133, + "top": 825, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKvMIU8e89E=", + "_parent": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "model": { + "$ref": "AAAAAAF5QKvMIE8WKCE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2140, + "top": 836, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKvMIU8frKE=", + "_parent": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "model": { + "$ref": "AAAAAAF5QKvMIE8WKCE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2118, + "top": 801, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKvMIU8gpg0=", + "_parent": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "model": { + "$ref": "AAAAAAF5QKvMIE8XsG8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1967, + "top": 971, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKvMIU8hUUs=", + "_parent": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "model": { + "$ref": "AAAAAAF5QKvMIE8XsG8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1977, + "top": 979, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QKvMIU8iPfY=", + "_parent": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "model": { + "$ref": "AAAAAAF5QKvMIE8XsG8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1946, + "top": 953, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QKvMIU8jJRc=", + "_parent": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "model": { + "$ref": "AAAAAAF5QKvMIE8WKCE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 264, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QKvMIU8kteI=", + "_parent": { + "$ref": "AAAAAAF5QKvMIE8ZF/E=" + }, + "model": { + "$ref": "AAAAAAF5QKvMIE8XsG8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 264, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QKuCwkzY630=" + }, + "tail": { + "$ref": "AAAAAAF5QKE6Ojfzjv0=" + }, + "lineStyle": 1, + "points": "2143:803;1938:983", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QKvMIU8a1To=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QKvMIU8bx7Y=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QKvMIU8c/MU=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QKvMIU8df1Y=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QKvMIU8e89E=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QKvMIU8frKE=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QKvMIU8gpg0=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QKvMIU8hUUs=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QKvMIU8iPfY=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QKvMIU8jJRc=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QKvMIU8kteI=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5QKyR6VB+5F0=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QKyR6VB8Gq8=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5QKyR6VB/sq8=", + "_parent": { + "$ref": "AAAAAAF5QKyR6VB+5F0=" + }, + "model": { + "$ref": "AAAAAAF5QKyR6VB8Gq8=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5QKyR6lCAlIw=", + "_parent": { + "$ref": "AAAAAAF5QKyR6VB/sq8=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 320, + "top": -240, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKyR6lCBFDc=", + "_parent": { + "$ref": "AAAAAAF5QKyR6VB/sq8=" + }, + "fillColor": "#ff8282", + "font": "Arial;13;1", + "left": 956, + "top": 747.5, + "width": 62, + "height": 13, + "text": "重测方向" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKyR6lCC81I=", + "_parent": { + "$ref": "AAAAAAF5QKyR6VB/sq8=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 320, + "top": -240, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKyR6lCDFwk=", + "_parent": { + "$ref": "AAAAAAF5QKyR6VB/sq8=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 320, + "top": -240, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 951, + "top": 740.5, + "width": 72, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5QKyR6lCAlIw=" + }, + "nameLabel": { + "$ref": "AAAAAAF5QKyR6lCBFDc=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5QKyR6lCC81I=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QKyR6lCDFwk=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5QKyR6lCEof0=", + "_parent": { + "$ref": "AAAAAAF5QKyR6VB+5F0=" + }, + "model": { + "$ref": "AAAAAAF5QKyR6VB8Gq8=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 160, + "top": -120, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5QKyR6lCFl5A=", + "_parent": { + "$ref": "AAAAAAF5QKyR6VB+5F0=" + }, + "model": { + "$ref": "AAAAAAF5QKyR6VB8Gq8=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 160, + "top": -120, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5QKyR6lCGLz0=", + "_parent": { + "$ref": "AAAAAAF5QKyR6VB+5F0=" + }, + "model": { + "$ref": "AAAAAAF5QKyR6VB8Gq8=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 160, + "top": -120, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5QKyR6lCHKbg=", + "_parent": { + "$ref": "AAAAAAF5QKyR6VB+5F0=" + }, + "model": { + "$ref": "AAAAAAF5QKyR6VB8Gq8=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 160, + "top": -120, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5QKyR6lCIqJE=", + "_parent": { + "$ref": "AAAAAAF5QKyR6VB+5F0=" + }, + "model": { + "$ref": "AAAAAAF5QKyR6VB8Gq8=" + }, + "visible": false, + "fillColor": "#ff8282", + "font": "Arial;13;0", + "left": 160, + "top": -120, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ff8282", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 936, + "top": 736, + "width": 102, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5QKyR6VB/sq8=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5QKyR6lCEof0=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5QKyR6lCFl5A=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5QKyR6lCGLz0=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5QKyR6lCHKbg=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5QKyR6lCIqJE=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5QKysH1F4naw=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QKysH1F2Xh8=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5QKysH1F5Vw8=", + "_parent": { + "$ref": "AAAAAAF5QKysH1F4naw=" + }, + "model": { + "$ref": "AAAAAAF5QKysH1F2Xh8=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5QKysH1F6t1U=", + "_parent": { + "$ref": "AAAAAAF5QKysH1F5Vw8=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 928, + "top": -464, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKysH1F7w44=", + "_parent": { + "$ref": "AAAAAAF5QKysH1F5Vw8=" + }, + "fillColor": "#ffadad", + "font": "Arial;13;1", + "left": 1300, + "top": 699.5, + "width": 62, + "height": 13, + "text": "重测测回" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKysH1F8ews=", + "_parent": { + "$ref": "AAAAAAF5QKysH1F5Vw8=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 928, + "top": -464, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKysH1F9CVk=", + "_parent": { + "$ref": "AAAAAAF5QKysH1F5Vw8=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 928, + "top": -464, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 1295, + "top": 692.5, + "width": 72, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5QKysH1F6t1U=" + }, + "nameLabel": { + "$ref": "AAAAAAF5QKysH1F7w44=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5QKysH1F8ews=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QKysH1F9CVk=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5QKysH1F+SbI=", + "_parent": { + "$ref": "AAAAAAF5QKysH1F4naw=" + }, + "model": { + "$ref": "AAAAAAF5QKysH1F2Xh8=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 464, + "top": -232, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5QKysH1F/p8w=", + "_parent": { + "$ref": "AAAAAAF5QKysH1F4naw=" + }, + "model": { + "$ref": "AAAAAAF5QKysH1F2Xh8=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 464, + "top": -232, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5QKysH1GAwRg=", + "_parent": { + "$ref": "AAAAAAF5QKysH1F4naw=" + }, + "model": { + "$ref": "AAAAAAF5QKysH1F2Xh8=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 464, + "top": -232, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5QKysH1GBWy4=", + "_parent": { + "$ref": "AAAAAAF5QKysH1F4naw=" + }, + "model": { + "$ref": "AAAAAAF5QKysH1F2Xh8=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 464, + "top": -232, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5QKysH1GC8OE=", + "_parent": { + "$ref": "AAAAAAF5QKysH1F4naw=" + }, + "model": { + "$ref": "AAAAAAF5QKysH1F2Xh8=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 464, + "top": -232, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ffadad", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 1280, + "top": 688, + "width": 102, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5QKysH1F5Vw8=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5QKysH1F+SbI=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5QKysH1F/p8w=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5QKysH1GAwRg=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5QKysH1GBWy4=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5QKysH1GC8OE=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5QKzDRVJysxE=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QKzDRVJwpI4=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5QKzDRVJztrc=", + "_parent": { + "$ref": "AAAAAAF5QKzDRVJysxE=" + }, + "model": { + "$ref": "AAAAAAF5QKzDRVJwpI4=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5QKzDRVJ0nsk=", + "_parent": { + "$ref": "AAAAAAF5QKzDRVJztrc=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 1072, + "top": -928, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKzDRVJ1z+Q=", + "_parent": { + "$ref": "AAAAAAF5QKzDRVJztrc=" + }, + "fillColor": "#8282ff", + "font": "Arial;13;1", + "left": 1398.5, + "top": 523.5, + "width": 226, + "height": 13, + "text": "resetSurveyorStateAndKeepPosition" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKzDRVJ29Q0=", + "_parent": { + "$ref": "AAAAAAF5QKzDRVJztrc=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 1072, + "top": -928, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QKzDRVJ3D90=", + "_parent": { + "$ref": "AAAAAAF5QKzDRVJztrc=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 1072, + "top": -928, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 1393.5, + "top": 516.5, + "width": 237.5634765625, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5QKzDRVJ0nsk=" + }, + "nameLabel": { + "$ref": "AAAAAAF5QKzDRVJ1z+Q=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5QKzDRVJ29Q0=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QKzDRVJ3D90=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5QKzDRVJ4vK0=", + "_parent": { + "$ref": "AAAAAAF5QKzDRVJysxE=" + }, + "model": { + "$ref": "AAAAAAF5QKzDRVJwpI4=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 536, + "top": -464, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5QKzDRVJ5ijM=", + "_parent": { + "$ref": "AAAAAAF5QKzDRVJysxE=" + }, + "model": { + "$ref": "AAAAAAF5QKzDRVJwpI4=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 536, + "top": -464, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5QKzDRVJ6ScY=", + "_parent": { + "$ref": "AAAAAAF5QKzDRVJysxE=" + }, + "model": { + "$ref": "AAAAAAF5QKzDRVJwpI4=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 536, + "top": -464, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5QKzDRVJ71p4=", + "_parent": { + "$ref": "AAAAAAF5QKzDRVJysxE=" + }, + "model": { + "$ref": "AAAAAAF5QKzDRVJwpI4=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 536, + "top": -464, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5QKzDRVJ8l2g=", + "_parent": { + "$ref": "AAAAAAF5QKzDRVJysxE=" + }, + "model": { + "$ref": "AAAAAAF5QKzDRVJwpI4=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 536, + "top": -464, + "width": 10, + "height": 10 + } + ], + "fillColor": "#8282ff", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 1344, + "top": 512, + "width": 335, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5QKzDRVJztrc=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5QKzDRVJ4vK0=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5QKzDRVJ5ijM=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5QKzDRVJ6ScY=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5QKzDRVJ71p4=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5QKzDRVJ8l2g=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QK2QmFlvdS8=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QK2Ql1lrW/0=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK2QmFlwJfE=", + "_parent": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "model": { + "$ref": "AAAAAAF5QK2Ql1lrW/0=" + }, + "font": "Arial;13;0", + "left": 1686, + "top": 768, + "width": 33.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "edgePosition": 1, + "text": "+忽略" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK2QmFlxSkY=", + "_parent": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "model": { + "$ref": "AAAAAAF5QK2Ql1lrW/0=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1691, + "top": 778, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK2QmFly6tM=", + "_parent": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "model": { + "$ref": "AAAAAAF5QK2Ql1lrW/0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1725, + "top": 749, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK2QmFlzr3g=", + "_parent": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "model": { + "$ref": "AAAAAAF5QK2Ql1lsCzU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1873, + "top": 967, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK2QmFl0RxM=", + "_parent": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "model": { + "$ref": "AAAAAAF5QK2Ql1lsCzU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1862, + "top": 974, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK2QmFl1X3o=", + "_parent": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "model": { + "$ref": "AAAAAAF5QK2Ql1lsCzU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1897, + "top": 952, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK2QmFl29pE=", + "_parent": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "model": { + "$ref": "AAAAAAF5QK2Ql1ltUBY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1531, + "top": 570, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK2QmFl39y0=", + "_parent": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "model": { + "$ref": "AAAAAAF5QK2Ql1ltUBY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1523, + "top": 580, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK2QmFl4Ns0=", + "_parent": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "model": { + "$ref": "AAAAAAF5QK2Ql1ltUBY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1549, + "top": 549, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QK2QmFl5muU=", + "_parent": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "model": { + "$ref": "AAAAAAF5QK2Ql1lsCzU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 480, + "top": -8, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QK2QmFl6Y7A=", + "_parent": { + "$ref": "AAAAAAF5QK2QmFlvdS8=" + }, + "model": { + "$ref": "AAAAAAF5QK2Ql1ltUBY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 480, + "top": -8, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QKzDRVJysxE=" + }, + "tail": { + "$ref": "AAAAAAF5QKuCwkzY630=" + }, + "lineStyle": 1, + "points": "1902:983;1526:547", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QK2QmFlwJfE=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QK2QmFlxSkY=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QK2QmFly6tM=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QK2QmFlzr3g=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QK2QmFl0RxM=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QK2QmFl1X3o=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QK2QmFl29pE=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QK2QmFl39y0=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QK2QmFl4Ns0=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QK2QmFl5muU=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QK2QmFl6Y7A=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QK340l0Fv9Q=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QK340l0BzRk=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK340l0GnqQ=", + "_parent": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "model": { + "$ref": "AAAAAAF5QK340l0BzRk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1392, + "top": 471, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK340l0Habc=", + "_parent": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "model": { + "$ref": "AAAAAAF5QK340l0BzRk=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1384, + "top": 484, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK340l0IZgE=", + "_parent": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "model": { + "$ref": "AAAAAAF5QK340l0BzRk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1407, + "top": 446, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK340l0Jr30=", + "_parent": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "model": { + "$ref": "AAAAAAF5QK340l0ChAw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1450, + "top": 504, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK340l0KziQ=", + "_parent": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "model": { + "$ref": "AAAAAAF5QK340l0ChAw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1441, + "top": 515, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK340l0LSAI=", + "_parent": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "model": { + "$ref": "AAAAAAF5QK340l0ChAw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1467, + "top": 483, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK340l0MEF0=", + "_parent": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "model": { + "$ref": "AAAAAAF5QK340l0D79M=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1335, + "top": 438, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK340l0NAX0=", + "_parent": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "model": { + "$ref": "AAAAAAF5QK340l0D79M=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1331, + "top": 451, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QK340l0Obj8=", + "_parent": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "model": { + "$ref": "AAAAAAF5QK340l0D79M=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1345, + "top": 413, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QK340l0PZLk=", + "_parent": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "model": { + "$ref": "AAAAAAF5QK340l0ChAw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 480, + "top": -8, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QK340l0QvTM=", + "_parent": { + "$ref": "AAAAAAF5QK340l0Fv9Q=" + }, + "model": { + "$ref": "AAAAAAF5QK340l0D79M=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 480, + "top": -8, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5P5/CAk98zZc=" + }, + "tail": { + "$ref": "AAAAAAF5QKzDRVJysxE=" + }, + "lineStyle": 1, + "points": "1480:511;1321:419", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QK340l0GnqQ=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QK340l0Habc=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QK340l0IZgE=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QK340l0Jr30=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QK340l0KziQ=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QK340l0LSAI=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QK340l0MEF0=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QK340l0NAX0=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QK340l0Obj8=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QK340l0PZLk=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QK340l0QvTM=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QLdiXGHqtMU=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QLdiW2HmZcI=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLdiXGHrPm0=", + "_parent": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "model": { + "$ref": "AAAAAAF5QLdiW2HmZcI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1442, + "top": 883, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLdiXGHsNrs=", + "_parent": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "model": { + "$ref": "AAAAAAF5QLdiW2HmZcI=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1438, + "top": 898, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLdiXGHtajM=", + "_parent": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "model": { + "$ref": "AAAAAAF5QLdiW2HmZcI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1449, + "top": 854, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLdiXGHu5Ak=", + "_parent": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "model": { + "$ref": "AAAAAAF5QLdiW2HnzLc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1826, + "top": 985, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLdiXGHvESE=", + "_parent": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "model": { + "$ref": "AAAAAAF5QLdiW2HnzLc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1820, + "top": 998, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLdiXGHwu2c=", + "_parent": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "model": { + "$ref": "AAAAAAF5QLdiW2HnzLc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1837, + "top": 960, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLdiXGHxgP0=", + "_parent": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "model": { + "$ref": "AAAAAAF5QLdiW2HodP8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1059, + "top": 782, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLdiXGHyZg0=", + "_parent": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "model": { + "$ref": "AAAAAAF5QLdiW2HodP8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1058, + "top": 795, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLdiXGHzjfw=", + "_parent": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "model": { + "$ref": "AAAAAAF5QLdiW2HodP8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1062, + "top": 754, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QLdiXGH0aoo=", + "_parent": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "model": { + "$ref": "AAAAAAF5QLdiW2HnzLc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 528, + "top": -72, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QLdiXGH1FM8=", + "_parent": { + "$ref": "AAAAAAF5QLdiXGHqtMU=" + }, + "model": { + "$ref": "AAAAAAF5QLdiW2HodP8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 528, + "top": -72, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QKyR6VB+5F0=" + }, + "tail": { + "$ref": "AAAAAAF5QKuCwkzY630=" + }, + "lineStyle": 1, + "points": "1855:984;1038:767", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QLdiXGHrPm0=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QLdiXGHsNrs=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QLdiXGHtajM=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QLdiXGHu5Ak=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QLdiXGHvESE=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QLdiXGHwu2c=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QLdiXGHxgP0=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QLdiXGHyZg0=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QLdiXGHzjfw=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QLdiXGH0aoo=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QLdiXGH1FM8=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5QLwOJ2bPDnI=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QLwOJ2bN7N0=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5QLwOJ2bQ8Ro=", + "_parent": { + "$ref": "AAAAAAF5QLwOJ2bPDnI=" + }, + "model": { + "$ref": "AAAAAAF5QLwOJ2bN7N0=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5QLwOJ2bRPfA=", + "_parent": { + "$ref": "AAAAAAF5QLwOJ2bQ8Ro=" + }, + "visible": false, + "fillColor": "#5656ff", + "font": "Arial;13;0", + "left": 560, + "top": -528, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QLwOJ2bSTVM=", + "_parent": { + "$ref": "AAAAAAF5QLwOJ2bQ8Ro=" + }, + "fillColor": "#5656ff", + "font": "Arial;13;1", + "left": 1090.5, + "top": 587.5, + "width": 93, + "height": 13, + "text": "resurveyPoints" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QLwOJ2bTKUY=", + "_parent": { + "$ref": "AAAAAAF5QLwOJ2bQ8Ro=" + }, + "visible": false, + "fillColor": "#5656ff", + "font": "Arial;13;0", + "left": 560, + "top": -528, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QLwOJ2bUBI4=", + "_parent": { + "$ref": "AAAAAAF5QLwOJ2bQ8Ro=" + }, + "visible": false, + "fillColor": "#5656ff", + "font": "Arial;13;0", + "left": 560, + "top": -528, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#5656ff", + "font": "Arial;13;0", + "left": 1085.5, + "top": 580.5, + "width": 103.9326171875, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5QLwOJ2bRPfA=" + }, + "nameLabel": { + "$ref": "AAAAAAF5QLwOJ2bSTVM=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5QLwOJ2bTKUY=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QLwOJ2bUBI4=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5QLwOJ2bVEa0=", + "_parent": { + "$ref": "AAAAAAF5QLwOJ2bPDnI=" + }, + "model": { + "$ref": "AAAAAAF5QLwOJ2bN7N0=" + }, + "visible": false, + "fillColor": "#5656ff", + "font": "Arial;13;0", + "left": 280, + "top": -264, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5QLwOJ2bWae0=", + "_parent": { + "$ref": "AAAAAAF5QLwOJ2bPDnI=" + }, + "model": { + "$ref": "AAAAAAF5QLwOJ2bN7N0=" + }, + "visible": false, + "fillColor": "#5656ff", + "font": "Arial;13;0", + "left": 280, + "top": -264, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5QLwOJ2bXEAg=", + "_parent": { + "$ref": "AAAAAAF5QLwOJ2bPDnI=" + }, + "model": { + "$ref": "AAAAAAF5QLwOJ2bN7N0=" + }, + "visible": false, + "fillColor": "#5656ff", + "font": "Arial;13;0", + "left": 280, + "top": -264, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5QLwOKGbYe7A=", + "_parent": { + "$ref": "AAAAAAF5QLwOJ2bPDnI=" + }, + "model": { + "$ref": "AAAAAAF5QLwOJ2bN7N0=" + }, + "visible": false, + "fillColor": "#5656ff", + "font": "Arial;13;0", + "left": 280, + "top": -264, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5QLwOKGbZQqo=", + "_parent": { + "$ref": "AAAAAAF5QLwOJ2bPDnI=" + }, + "model": { + "$ref": "AAAAAAF5QLwOJ2bN7N0=" + }, + "visible": false, + "fillColor": "#5656ff", + "font": "Arial;13;0", + "left": 280, + "top": -264, + "width": 10, + "height": 10 + } + ], + "fillColor": "#5656ff", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 1064, + "top": 576, + "width": 146, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5QLwOJ2bQ8Ro=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5QLwOJ2bVEa0=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5QLwOJ2bWae0=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5QLwOJ2bXEAg=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5QLwOKGbYe7A=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5QLwOKGbZQqo=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QLx6RGoNnGE=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QLx6RGoJ91g=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLx6RGoOcBM=", + "_parent": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "model": { + "$ref": "AAAAAAF5QLx6RGoJ91g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1050, + "top": 656, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLx6RGoPkXM=", + "_parent": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "model": { + "$ref": "AAAAAAF5QLx6RGoJ91g=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1039, + "top": 646, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLx6RGoQUT8=", + "_parent": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "model": { + "$ref": "AAAAAAF5QLx6RGoJ91g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1071, + "top": 677, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLx6RGoRB9A=", + "_parent": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "model": { + "$ref": "AAAAAAF5QLx6RGoKxZI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1009, + "top": 699, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLx6RGoSk+A=", + "_parent": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "model": { + "$ref": "AAAAAAF5QLx6RGoKxZI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1001, + "top": 689, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLx6RGoT8Lo=", + "_parent": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "model": { + "$ref": "AAAAAAF5QLx6RGoKxZI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1026, + "top": 721, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLx6RGoUHro=", + "_parent": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "model": { + "$ref": "AAAAAAF5QLx6RGoLs1U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1090, + "top": 613, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLx6RGoVk68=", + "_parent": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "model": { + "$ref": "AAAAAAF5QLx6RGoLs1U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1079, + "top": 606, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QLx6RGoW9No=", + "_parent": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "model": { + "$ref": "AAAAAAF5QLx6RGoLs1U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1113, + "top": 629, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QLx6RGoXj7U=", + "_parent": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "model": { + "$ref": "AAAAAAF5QLx6RGoKxZI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 480, + "top": -8, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QLx6RGoYmUk=", + "_parent": { + "$ref": "AAAAAAF5QLx6RGoNnGE=" + }, + "model": { + "$ref": "AAAAAAF5QLx6RGoLs1U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 480, + "top": -8, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QLwOJ2bPDnI=" + }, + "tail": { + "$ref": "AAAAAAF5QKyR6VB+5F0=" + }, + "lineStyle": 1, + "points": "1003:735;1119:611", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QLx6RGoOcBM=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QLx6RGoPkXM=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QLx6RGoQUT8=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QLx6RGoRB9A=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QLx6RGoSk+A=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QLx6RGoT8Lo=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QLx6RGoUHro=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QLx6RGoVk68=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QLx6RGoW9No=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QLx6RGoXj7U=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QLx6RGoYmUk=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5QMaQUG/rlG8=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QMaQUG/pf+g=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5QMaQUG/sv3A=", + "_parent": { + "$ref": "AAAAAAF5QMaQUG/rlG8=" + }, + "model": { + "$ref": "AAAAAAF5QMaQUG/pf+g=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5QMaQUG/tkJ4=", + "_parent": { + "$ref": "AAAAAAF5QMaQUG/sv3A=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 1712, + "top": 1488, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QMaQUG/umGY=", + "_parent": { + "$ref": "AAAAAAF5QMaQUG/sv3A=" + }, + "fillColor": "#8282ff", + "font": "Arial;13;1", + "left": 1692.5, + "top": 1451.5, + "width": 216, + "height": 13, + "text": "switchState2RestartInCurrentCycle" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QMaQUW/vdlU=", + "_parent": { + "$ref": "AAAAAAF5QMaQUG/sv3A=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 1712, + "top": 1488, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5QMaQUW/w0wQ=", + "_parent": { + "$ref": "AAAAAAF5QMaQUG/sv3A=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 1712, + "top": 1488, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 1687.5, + "top": 1444.5, + "width": 227.4580078125, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5QMaQUG/tkJ4=" + }, + "nameLabel": { + "$ref": "AAAAAAF5QMaQUG/umGY=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5QMaQUW/vdlU=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QMaQUW/w0wQ=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5QMaQUW/x48o=", + "_parent": { + "$ref": "AAAAAAF5QMaQUG/rlG8=" + }, + "model": { + "$ref": "AAAAAAF5QMaQUG/pf+g=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 856, + "top": 744, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5QMaQUW/yJ84=", + "_parent": { + "$ref": "AAAAAAF5QMaQUG/rlG8=" + }, + "model": { + "$ref": "AAAAAAF5QMaQUG/pf+g=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 856, + "top": 744, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5QMaQUW/z4XE=", + "_parent": { + "$ref": "AAAAAAF5QMaQUG/rlG8=" + }, + "model": { + "$ref": "AAAAAAF5QMaQUG/pf+g=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 856, + "top": 744, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5QMaQUW/0u+w=", + "_parent": { + "$ref": "AAAAAAF5QMaQUG/rlG8=" + }, + "model": { + "$ref": "AAAAAAF5QMaQUG/pf+g=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 856, + "top": 744, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5QMaQUW/13YU=", + "_parent": { + "$ref": "AAAAAAF5QMaQUG/rlG8=" + }, + "model": { + "$ref": "AAAAAAF5QMaQUG/pf+g=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 856, + "top": 744, + "width": 10, + "height": 10 + } + ], + "fillColor": "#8282ff", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 1640, + "top": 1440, + "width": 321, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5QMaQUG/sv3A=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5QMaQUW/x48o=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5QMaQUW/yJ84=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5QMaQUW/z4XE=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5QMaQUW/0u+w=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5QMaQUW/13YU=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QMbzEXNQ00I=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QMbzEHNMUo0=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMbzEXNR/aw=", + "_parent": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "model": { + "$ref": "AAAAAAF5QMbzEHNMUo0=" + }, + "font": "Arial;13;0", + "left": 1450, + "top": 1009, + "width": 59.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "edgePosition": 1, + "text": "+开始重测" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMbzEXNSJUg=", + "_parent": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "model": { + "$ref": "AAAAAAF5QMbzEHNMUo0=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1491, + "top": 1000, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMbzEXNTTKw=", + "_parent": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "model": { + "$ref": "AAAAAAF5QMbzEHNMUo0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1456, + "top": 1028, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMbzEXNUT2s=", + "_parent": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "model": { + "$ref": "AAAAAAF5QMbzEHNNh8o=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1177, + "top": 616, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMbzEXNVmq4=", + "_parent": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "model": { + "$ref": "AAAAAAF5QMbzEHNNh8o=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1189, + "top": 610, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMbzEXNWUrs=", + "_parent": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "model": { + "$ref": "AAAAAAF5QMbzEHNNh8o=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1153, + "top": 629, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMbzEXNX73U=", + "_parent": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "model": { + "$ref": "AAAAAAF5QMbzEHNOm6M=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1782, + "top": 1403, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMbzEXNYoLo=", + "_parent": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "model": { + "$ref": "AAAAAAF5QMbzEHNOm6M=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1791, + "top": 1393, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMbzEXNZwIQ=", + "_parent": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "model": { + "$ref": "AAAAAAF5QMbzEHNOm6M=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1762, + "top": 1423, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QMbzEXNaGMo=", + "_parent": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "model": { + "$ref": "AAAAAAF5QMbzEHNNh8o=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 480, + "top": -8, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QMbzEXNbVPI=", + "_parent": { + "$ref": "AAAAAAF5QMbzEXNQ00I=" + }, + "model": { + "$ref": "AAAAAAF5QMbzEHNOm6M=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 480, + "top": -8, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QMaQUG/rlG8=" + }, + "tail": { + "$ref": "AAAAAAF5QLwOJ2bPDnI=" + }, + "lineStyle": 1, + "points": "1150:611;1786:1439", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QMbzEXNR/aw=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QMbzEXNSJUg=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QMbzEXNTTKw=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QMbzEXNUT2s=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QMbzEXNVmq4=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QMbzEXNWUrs=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QMbzEXNX73U=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QMbzEXNYoLo=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QMbzEXNZwIQ=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QMbzEXNaGMo=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QMbzEXNbVPI=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QMjEp4Xxm70=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QMjEpoXtFac=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMjEp4XyXqY=", + "_parent": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "model": { + "$ref": "AAAAAAF5QMjEpoXtFac=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1819, + "top": 1662, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMjEp4XzTSE=", + "_parent": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "model": { + "$ref": "AAAAAAF5QMjEpoXtFac=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1834, + "top": 1662, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMjEp4X0hBs=", + "_parent": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "model": { + "$ref": "AAAAAAF5QMjEpoXtFac=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1790, + "top": 1663, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMjEp4X1sYc=", + "_parent": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "model": { + "$ref": "AAAAAAF5QMjEpoXuicM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1815, + "top": 1494, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMjEp4X2bX4=", + "_parent": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "model": { + "$ref": "AAAAAAF5QMjEpoXuicM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1829, + "top": 1496, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMjEp4X3ebc=", + "_parent": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "model": { + "$ref": "AAAAAAF5QMjEpoXuicM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1788, + "top": 1490, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMjEp4X4oDY=", + "_parent": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "model": { + "$ref": "AAAAAAF5QMjEpoXvKNs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1825, + "top": 1830, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMjEp4X5UnY=", + "_parent": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "model": { + "$ref": "AAAAAAF5QMjEpoXvKNs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1838, + "top": 1827, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMjEp4X6pQM=", + "_parent": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "model": { + "$ref": "AAAAAAF5QMjEpoXvKNs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1797, + "top": 1835, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QMjEqIX7oU8=", + "_parent": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "model": { + "$ref": "AAAAAAF5QMjEpoXuicM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 480, + "top": -8, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QMjEqIX8oCk=", + "_parent": { + "$ref": "AAAAAAF5QMjEp4Xxm70=" + }, + "model": { + "$ref": "AAAAAAF5QMjEpoXvKNs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 480, + "top": -8, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QJWvCwgzk0M=" + }, + "tail": { + "$ref": "AAAAAAF5QMaQUG/rlG8=" + }, + "lineStyle": 1, + "points": "1800:1475;1811:1863", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QMjEp4XyXqY=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QMjEp4XzTSE=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QMjEp4X0hBs=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QMjEp4X1sYc=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QMjEp4X2bX4=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QMjEp4X3ebc=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QMjEp4X4oDY=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QMjEp4X5UnY=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QMjEp4X6pQM=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QMjEqIX7oU8=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QMjEqIX8oCk=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QMnaf4p31wI=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QMnaf4pzXpA=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMnaf4p4YhA=", + "_parent": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "model": { + "$ref": "AAAAAAF5QMnaf4pzXpA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1532, + "top": 768, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMnaf4p5heM=", + "_parent": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "model": { + "$ref": "AAAAAAF5QMnaf4pzXpA=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1528, + "top": 782, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMnaf4p6u/E=", + "_parent": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "model": { + "$ref": "AAAAAAF5QMnaf4pzXpA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1539, + "top": 739, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMnaf4p7HWo=", + "_parent": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "model": { + "$ref": "AAAAAAF5QMnaf4p0R7o=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1859, + "top": 975, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMnaf4p8uO8=", + "_parent": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "model": { + "$ref": "AAAAAAF5QMnaf4p0R7o=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1849, + "top": 985, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMnaf4p9ZYk=", + "_parent": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "model": { + "$ref": "AAAAAAF5QMnaf4p0R7o=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1877, + "top": 954, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMnaf4p+8dA=", + "_parent": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "model": { + "$ref": "AAAAAAF5QMnaf4p1n0A=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1403, + "top": 734, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMnaf4p/pOU=", + "_parent": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "model": { + "$ref": "AAAAAAF5QMnaf4p1n0A=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1402, + "top": 747, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QMnaf4qAet8=", + "_parent": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "model": { + "$ref": "AAAAAAF5QMnaf4p1n0A=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1406, + "top": 706, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QMnaf4qBmzo=", + "_parent": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "model": { + "$ref": "AAAAAAF5QMnaf4p0R7o=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 696, + "top": 8, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QMnaf4qCCtY=", + "_parent": { + "$ref": "AAAAAAF5QMnaf4p31wI=" + }, + "model": { + "$ref": "AAAAAAF5QMnaf4p1n0A=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 696, + "top": 8, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QKysH1F4naw=" + }, + "tail": { + "$ref": "AAAAAAF5QKuCwkzY630=" + }, + "lineStyle": 1, + "points": "1889:983;1536:760;1382:719", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QMnaf4p4YhA=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QMnaf4p5heM=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QMnaf4p6u/E=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QMnaf4p7HWo=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QMnaf4p8uO8=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QMnaf4p9ZYk=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QMnaf4p+8dA=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QMnaf4p/pOU=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QMnaf4qAet8=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QMnaf4qBmzo=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QMnaf4qCCtY=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QNAhapFuI7s=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QNAhapFq3kM=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNAhapFvVXY=", + "_parent": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "model": { + "$ref": "AAAAAAF5QNAhapFq3kM=" + }, + "font": "Arial;13;0", + "left": 1437, + "top": 796, + "width": 33.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "edgePosition": 1, + "text": "+取消" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNAhapFwVCE=", + "_parent": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "model": { + "$ref": "AAAAAAF5QNAhapFq3kM=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1459, + "top": 782, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNAhapFxPvQ=", + "_parent": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "model": { + "$ref": "AAAAAAF5QNAhapFq3kM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1442, + "top": 823, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNAhapFyOWw=", + "_parent": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "model": { + "$ref": "AAAAAAF5QNAhapFrudc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1378, + "top": 723, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNAhapFz3Mw=", + "_parent": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "model": { + "$ref": "AAAAAAF5QNAhapFrudc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1388, + "top": 715, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNAhapF0mvQ=", + "_parent": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "model": { + "$ref": "AAAAAAF5QNAhapFrudc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1356, + "top": 740, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNAha5F1FkI=", + "_parent": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "model": { + "$ref": "AAAAAAF5QNAhapFsZZ8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1852, + "top": 953, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNAha5F2OJ8=", + "_parent": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "model": { + "$ref": "AAAAAAF5QNAhapFsZZ8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1855, + "top": 940, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNAha5F3+WU=", + "_parent": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "model": { + "$ref": "AAAAAAF5QNAhapFsZZ8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1846, + "top": 980, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QNAha5F4AZU=", + "_parent": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "model": { + "$ref": "AAAAAAF5QNAhapFrudc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 744, + "top": -56, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QNAha5F5UgE=", + "_parent": { + "$ref": "AAAAAAF5QNAhapFuI7s=" + }, + "model": { + "$ref": "AAAAAAF5QNAhapFsZZ8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 744, + "top": -56, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QKuCwkzY630=" + }, + "tail": { + "$ref": "AAAAAAF5QKysH1F4naw=" + }, + "lineStyle": 1, + "points": "1349:723;1448:816;1871:983", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QNAhapFvVXY=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QNAhapFwVCE=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QNAhapFxPvQ=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QNAhapFyOWw=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QNAhapFz3Mw=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QNAhapF0mvQ=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QNAha5F1FkI=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QNAha5F2OJ8=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QNAha5F3+WU=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QNAha5F4AZU=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QNAha5F5UgE=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5QNFL66Cbz6k=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5QNFL6qCXEtU=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNFL66CcWkE=", + "_parent": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "model": { + "$ref": "AAAAAAF5QNFL6qCXEtU=" + }, + "font": "Arial;13;0", + "left": 1393, + "top": 600, + "width": 33.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "edgePosition": 1, + "text": "+忽略" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNFL66CdTo8=", + "_parent": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "model": { + "$ref": "AAAAAAF5QNFL6qCXEtU=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1399, + "top": 589, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNFL66Ce+u8=", + "_parent": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "model": { + "$ref": "AAAAAAF5QNFL6qCXEtU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1430, + "top": 621, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNFL66CfR+U=", + "_parent": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "model": { + "$ref": "AAAAAAF5QNFL6qCY2AQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1357, + "top": 652, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNFL66Cg04o=", + "_parent": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "model": { + "$ref": "AAAAAAF5QNFL6qCY2AQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1349, + "top": 641, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNFL66ChcXw=", + "_parent": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "model": { + "$ref": "AAAAAAF5QNFL6qCY2AQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1373, + "top": 674, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNFL66CipGA=", + "_parent": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "model": { + "$ref": "AAAAAAF5QNFL6qCZ01s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1462, + "top": 548, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNFL66Cj6oQ=", + "_parent": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "model": { + "$ref": "AAAAAAF5QNFL6qCZ01s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1452, + "top": 540, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5QNFL66Ck0os=", + "_parent": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "model": { + "$ref": "AAAAAAF5QNFL6qCZ01s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1485, + "top": 565, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QNFL66ClLUo=", + "_parent": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "model": { + "$ref": "AAAAAAF5QNFL6qCY2AQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 696, + "top": 8, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5QNFL66Cm8No=", + "_parent": { + "$ref": "AAAAAAF5QNFL66Cbz6k=" + }, + "model": { + "$ref": "AAAAAAF5QNFL6qCZ01s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 696, + "top": 8, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QKzDRVJysxE=" + }, + "tail": { + "$ref": "AAAAAAF5QKysH1F4naw=" + }, + "lineStyle": 1, + "points": "1349:687;1492:547", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5QNFL66CcWkE=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5QNFL66CdTo8=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5QNFL66Ce+u8=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5QNFL66CfR+U=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5QNFL66Cg04o=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5QNFL66ChcXw=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5QNFL66CipGA=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5QNFL66Cj6oQ=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5QNFL66Ck0os=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5QNFL66ClLUo=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5QNFL66Cm8No=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RVTun0vZBv0=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RVTunkvVKUs=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVTun0vaxdo=", + "_parent": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "model": { + "$ref": "AAAAAAF5RVTunkvVKUs=" + }, + "font": "Arial;13;0", + "left": 1276, + "top": 542, + "width": 59.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "edgePosition": 1, + "text": "+重测失败" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVTun0vbxuQ=", + "_parent": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "model": { + "$ref": "AAAAAAF5RVTunkvVKUs=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1303, + "top": 527, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVTun0vcmj8=", + "_parent": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "model": { + "$ref": "AAAAAAF5RVTunkvVKUs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1310, + "top": 571, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVTun0vdoCc=", + "_parent": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "model": { + "$ref": "AAAAAAF5RVTun0vWQ0U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1233, + "top": 554, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVTun0ved/I=", + "_parent": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "model": { + "$ref": "AAAAAAF5RVTun0vWQ0U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1233, + "top": 541, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVTun0vfAMs=", + "_parent": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "model": { + "$ref": "AAAAAAF5RVTun0vWQ0U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1233, + "top": 582, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVTun0vg9C0=", + "_parent": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "model": { + "$ref": "AAAAAAF5RVTun0vXr0g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1377, + "top": 530, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVTuoEvhMzo=", + "_parent": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "model": { + "$ref": "AAAAAAF5RVTun0vXr0g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1373, + "top": 517, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVTuoEviZLY=", + "_parent": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "model": { + "$ref": "AAAAAAF5RVTun0vXr0g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1386, + "top": 556, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RVTuoEvjqMY=", + "_parent": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "model": { + "$ref": "AAAAAAF5RVTun0vWQ0U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 216, + "top": -8, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RVTuoEvkZEE=", + "_parent": { + "$ref": "AAAAAAF5RVTun0vZBv0=" + }, + "model": { + "$ref": "AAAAAAF5RVTun0vXr0g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 216, + "top": -8, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QKzDRVJysxE=" + }, + "tail": { + "$ref": "AAAAAAF5QLwOJ2bPDnI=" + }, + "lineStyle": 1, + "points": "1210:580;1406:547", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RVTun0vaxdo=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RVTun0vbxuQ=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RVTun0vcmj8=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RVTun0vdoCc=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RVTun0ved/I=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RVTun0vfAMs=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RVTun0vg9C0=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RVTuoEvhMzo=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RVTuoEviZLY=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RVTuoEvjqMY=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RVTuoEvkZEE=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RVWv21Zu6Aw=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RVWv2lZqu2A=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVWv21ZvsKs=", + "_parent": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "model": { + "$ref": "AAAAAAF5RVWv2lZqu2A=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1302, + "top": 1897, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVWv21ZwRzk=", + "_parent": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "model": { + "$ref": "AAAAAAF5RVWv2lZqu2A=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1302, + "top": 1912, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVWv21ZxCSk=", + "_parent": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "model": { + "$ref": "AAAAAAF5RVWv2lZqu2A=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1301, + "top": 1868, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVWv21Zyej0=", + "_parent": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "model": { + "$ref": "AAAAAAF5RVWv2lZro+8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1693, + "top": 1891, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVWv21ZzuYg=", + "_parent": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "model": { + "$ref": "AAAAAAF5RVWv2lZro+8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1691, + "top": 1904, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVWv3FZ0MPo=", + "_parent": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "model": { + "$ref": "AAAAAAF5RVWv2lZro+8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1697, + "top": 1863, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVWv3FZ18no=", + "_parent": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "model": { + "$ref": "AAAAAAF5RVWv2lZs/XI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 912, + "top": 1904, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVWv3FZ21Iw=", + "_parent": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "model": { + "$ref": "AAAAAAF5RVWv2lZs/XI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 914, + "top": 1917, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVWv3FZ3nLg=", + "_parent": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "model": { + "$ref": "AAAAAAF5RVWv2lZs/XI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 907, + "top": 1877, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RVWv3FZ4weo=", + "_parent": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "model": { + "$ref": "AAAAAAF5RVWv2lZro+8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 216, + "top": -8, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RVWv3FZ58yM=", + "_parent": { + "$ref": "AAAAAAF5RVWv21Zu6Aw=" + }, + "model": { + "$ref": "AAAAAAF5RVWv2lZs/XI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 216, + "top": -8, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5RZAQqNi9KXs=" + }, + "tail": { + "$ref": "AAAAAAF5QJWvCwgzk0M=" + }, + "lineStyle": 1, + "points": "1719:1882;886:1896", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RVWv21ZvsKs=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RVWv21ZwRzk=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RVWv21ZxCSk=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RVWv21Zyej0=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RVWv21ZzuYg=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RVWv3FZ0MPo=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RVWv3FZ18no=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RVWv3FZ21Iw=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RVWv3FZ3nLg=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RVWv3FZ4weo=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RVWv3FZ58yM=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5RVbpp1nKVhc=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RVbpp1nIOnU=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5RVbpp1nLusg=", + "_parent": { + "$ref": "AAAAAAF5RVbpp1nKVhc=" + }, + "model": { + "$ref": "AAAAAAF5RVbpp1nIOnU=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5RVbpqFnM530=", + "_parent": { + "$ref": "AAAAAAF5RVbpp1nLusg=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 1504, + "top": -656, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RVbpqFnNEWc=", + "_parent": { + "$ref": "AAAAAAF5RVbpp1nLusg=" + }, + "fillColor": "#ffadad", + "font": "Arial;13;1", + "left": 1007.5, + "top": 843.5, + "width": 77, + "height": 13, + "text": "执行测回删除" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RVbpqFnO5/0=", + "_parent": { + "$ref": "AAAAAAF5RVbpp1nLusg=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 1504, + "top": -656, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RVbpqFnPMMU=", + "_parent": { + "$ref": "AAAAAAF5RVbpp1nLusg=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 1504, + "top": -656, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 1002.5, + "top": 836.5, + "width": 88, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5RVbpqFnM530=" + }, + "nameLabel": { + "$ref": "AAAAAAF5RVbpqFnNEWc=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5RVbpqFnO5/0=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RVbpqFnPMMU=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5RVbpqFnQqa0=", + "_parent": { + "$ref": "AAAAAAF5RVbpp1nKVhc=" + }, + "model": { + "$ref": "AAAAAAF5RVbpp1nIOnU=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 752, + "top": -328, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5RVbpqFnRVaY=", + "_parent": { + "$ref": "AAAAAAF5RVbpp1nKVhc=" + }, + "model": { + "$ref": "AAAAAAF5RVbpp1nIOnU=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 752, + "top": -328, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5RVbpqFnSiyY=", + "_parent": { + "$ref": "AAAAAAF5RVbpp1nKVhc=" + }, + "model": { + "$ref": "AAAAAAF5RVbpp1nIOnU=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 752, + "top": -328, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5RVbpqFnTp/o=", + "_parent": { + "$ref": "AAAAAAF5RVbpp1nKVhc=" + }, + "model": { + "$ref": "AAAAAAF5RVbpp1nIOnU=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 752, + "top": -328, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5RVbpqFnUeVQ=", + "_parent": { + "$ref": "AAAAAAF5RVbpp1nKVhc=" + }, + "model": { + "$ref": "AAAAAAF5RVbpp1nIOnU=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 752, + "top": -328, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ffadad", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 984, + "top": 832, + "width": 124, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5RVbpp1nLusg=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5RVbpqFnQqa0=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5RVbpqFnRVaY=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5RVbpqFnSiyY=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5RVbpqFnTp/o=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5RVbpqFnUeVQ=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RVcwNF0lj/I=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RVcwNF0hcaI=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVcwNF0m640=", + "_parent": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "model": { + "$ref": "AAAAAAF5RVcwNF0hcaI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1193, + "top": 784, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVcwNF0n9pE=", + "_parent": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "model": { + "$ref": "AAAAAAF5RVcwNF0hcaI=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1200, + "top": 797, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVcwNF0osMg=", + "_parent": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "model": { + "$ref": "AAAAAAF5RVcwNF0hcaI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1180, + "top": 757, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVcwNF0pne0=", + "_parent": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "model": { + "$ref": "AAAAAAF5RVcwNF0iVWE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1277, + "top": 742, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVcwNF0qTm8=", + "_parent": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "model": { + "$ref": "AAAAAAF5RVcwNF0iVWE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1281, + "top": 755, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVcwNF0rLrQ=", + "_parent": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "model": { + "$ref": "AAAAAAF5RVcwNF0iVWE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1269, + "top": 715, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVcwNF0s558=", + "_parent": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "model": { + "$ref": "AAAAAAF5RVcwNF0jQf0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1110, + "top": 826, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVcwNF0tAew=", + "_parent": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "model": { + "$ref": "AAAAAAF5RVcwNF0jQf0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1119, + "top": 837, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVcwNF0uE34=", + "_parent": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "model": { + "$ref": "AAAAAAF5RVcwNF0jQf0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1094, + "top": 804, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RVcwNF0vsAE=", + "_parent": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "model": { + "$ref": "AAAAAAF5RVcwNF0iVWE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 432, + "top": 8, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RVcwNF0w5ls=", + "_parent": { + "$ref": "AAAAAAF5RVcwNF0lj/I=" + }, + "model": { + "$ref": "AAAAAAF5RVcwNF0jQf0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 432, + "top": 8, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5RVbpp1nKVhc=" + }, + "tail": { + "$ref": "AAAAAAF5QKysH1F4naw=" + }, + "lineStyle": 1, + "points": "1294:723;1081:831", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RVcwNF0m640=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RVcwNF0n9pE=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RVcwNF0osMg=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RVcwNF0pne0=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RVcwNF0qTm8=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RVcwNF0rLrQ=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RVcwNF0s558=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RVcwNF0tAew=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RVcwNF0uE34=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RVcwNF0vsAE=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RVcwNF0w5ls=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RVdEqmBOVoU=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RVdEqWBKDgY=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVdEqmBP7Mw=", + "_parent": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "model": { + "$ref": "AAAAAAF5RVdEqWBKDgY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1431, + "top": 1135, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVdEqmBQ+G0=", + "_parent": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "model": { + "$ref": "AAAAAAF5RVdEqWBKDgY=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1440, + "top": 1123, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVdEqmBRwAI=", + "_parent": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "model": { + "$ref": "AAAAAAF5RVdEqWBKDgY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1412, + "top": 1158, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVdEqmBSb60=", + "_parent": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "model": { + "$ref": "AAAAAAF5RVdEqWBL2Ro=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1096, + "top": 865, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVdEqmBT13s=", + "_parent": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "model": { + "$ref": "AAAAAAF5RVdEqWBL2Ro=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1106, + "top": 856, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVdEqmBU/V0=", + "_parent": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "model": { + "$ref": "AAAAAAF5RVdEqWBL2Ro=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1076, + "top": 884, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVdEqmBVD2o=", + "_parent": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "model": { + "$ref": "AAAAAAF5RVdEqWBMaWs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1767, + "top": 1405, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVdEqmBWru8=", + "_parent": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "model": { + "$ref": "AAAAAAF5RVdEqWBMaWs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1773, + "top": 1393, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RVdEqmBX1jY=", + "_parent": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "model": { + "$ref": "AAAAAAF5RVdEqWBMaWs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1753, + "top": 1429, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RVdEqmBYqxc=", + "_parent": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "model": { + "$ref": "AAAAAAF5RVdEqWBL2Ro=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 216, + "top": -8, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RVdEqmBZh5U=", + "_parent": { + "$ref": "AAAAAAF5RVdEqmBOVoU=" + }, + "model": { + "$ref": "AAAAAAF5RVdEqWBMaWs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 216, + "top": -8, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QMaQUG/rlG8=" + }, + "tail": { + "$ref": "AAAAAAF5RVbpp1nKVhc=" + }, + "lineStyle": 1, + "points": "1067:867;1778:1439", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RVdEqmBP7Mw=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RVdEqmBQ+G0=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RVdEqmBRwAI=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RVdEqmBSb60=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RVdEqmBT13s=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RVdEqmBU/V0=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RVdEqmBVD2o=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RVdEqmBWru8=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RVdEqmBX1jY=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RVdEqmBYqxc=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RVdEqmBZh5U=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5RWbWiJQ+LqI=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RWbWh5Q82SE=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5RWbWiJQ/pQw=", + "_parent": { + "$ref": "AAAAAAF5RWbWiJQ+LqI=" + }, + "model": { + "$ref": "AAAAAAF5RWbWh5Q82SE=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5RWbWiJRAz/w=", + "_parent": { + "$ref": "AAAAAAF5RWbWiJQ/pQw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -32, + "top": 2160, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RWbWiJRBIu8=", + "_parent": { + "$ref": "AAAAAAF5RWbWiJQ/pQw=" + }, + "font": "Arial;13;1", + "left": 1482, + "top": 1715.5, + "width": 167, + "height": 13, + "text": "doCalScheduleSingleCycle" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RWbWiJRCluw=", + "_parent": { + "$ref": "AAAAAAF5RWbWiJQ/pQw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -32, + "top": 2160, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RWbWiJRDVic=", + "_parent": { + "$ref": "AAAAAAF5RWbWiJQ/pQw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -32, + "top": 2160, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 1477, + "top": 1708.5, + "width": 177.603515625, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5RWbWiJRAz/w=" + }, + "nameLabel": { + "$ref": "AAAAAAF5RWbWiJRBIu8=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5RWbWiJRCluw=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RWbWiJRDVic=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5RWbWiJRE0bA=", + "_parent": { + "$ref": "AAAAAAF5RWbWiJQ+LqI=" + }, + "model": { + "$ref": "AAAAAAF5RWbWh5Q82SE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -16, + "top": 1080, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5RWbWiJRF/Bs=", + "_parent": { + "$ref": "AAAAAAF5RWbWiJQ+LqI=" + }, + "model": { + "$ref": "AAAAAAF5RWbWh5Q82SE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -16, + "top": 1080, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5RWbWiJRG03U=", + "_parent": { + "$ref": "AAAAAAF5RWbWiJQ+LqI=" + }, + "model": { + "$ref": "AAAAAAF5RWbWh5Q82SE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -16, + "top": 1080, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5RWbWiJRHoKE=", + "_parent": { + "$ref": "AAAAAAF5RWbWiJQ+LqI=" + }, + "model": { + "$ref": "AAAAAAF5RWbWh5Q82SE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -16, + "top": 1080, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5RWbWiZRIksM=", + "_parent": { + "$ref": "AAAAAAF5RWbWiJQ+LqI=" + }, + "model": { + "$ref": "AAAAAAF5RWbWh5Q82SE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -16, + "top": 1080, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 1440, + "top": 1704, + "width": 251, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5RWbWiJQ/pQw=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5RWbWiJRE0bA=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5RWbWiJRF/Bs=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5RWbWiJRG03U=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5RWbWiJRHoKE=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5RWbWiZRIksM=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5RWiYh6tfjKM=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RWiYh6tdXHE=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5RWiYh6tg64I=", + "_parent": { + "$ref": "AAAAAAF5RWiYh6tfjKM=" + }, + "model": { + "$ref": "AAAAAAF5RWiYh6tdXHE=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5RWiYh6th8ec=", + "_parent": { + "$ref": "AAAAAAF5RWiYh6tg64I=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -352, + "top": 1872, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RWiYh6tiGF8=", + "_parent": { + "$ref": "AAAAAAF5RWiYh6tg64I=" + }, + "fillColor": "#ffff91", + "font": "Arial;13;1", + "left": 1239.5, + "top": 1659.5, + "width": 116, + "height": 13, + "text": "该测回是否完成测量" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RWiYh6tjmMc=", + "_parent": { + "$ref": "AAAAAAF5RWiYh6tg64I=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -352, + "top": 1872, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RWiYh6tktDE=", + "_parent": { + "$ref": "AAAAAAF5RWiYh6tg64I=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -352, + "top": 1872, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 1234.5, + "top": 1652.5, + "width": 127, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5RWiYh6th8ec=" + }, + "nameLabel": { + "$ref": "AAAAAAF5RWiYh6tiGF8=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5RWiYh6tjmMc=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RWiYh6tktDE=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5RWiYh6tlfk4=", + "_parent": { + "$ref": "AAAAAAF5RWiYh6tfjKM=" + }, + "model": { + "$ref": "AAAAAAF5RWiYh6tdXHE=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -176, + "top": 936, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5RWiYh6tmr4M=", + "_parent": { + "$ref": "AAAAAAF5RWiYh6tfjKM=" + }, + "model": { + "$ref": "AAAAAAF5RWiYh6tdXHE=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -176, + "top": 936, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5RWiYiKtnqn4=", + "_parent": { + "$ref": "AAAAAAF5RWiYh6tfjKM=" + }, + "model": { + "$ref": "AAAAAAF5RWiYh6tdXHE=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -176, + "top": 936, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5RWiYiKtodLM=", + "_parent": { + "$ref": "AAAAAAF5RWiYh6tfjKM=" + }, + "model": { + "$ref": "AAAAAAF5RWiYh6tdXHE=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -176, + "top": 936, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5RWiYiKtpwlU=", + "_parent": { + "$ref": "AAAAAAF5RWiYh6tfjKM=" + }, + "model": { + "$ref": "AAAAAAF5RWiYh6tdXHE=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -176, + "top": 936, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 1208, + "top": 1648, + "width": 179, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5RWiYh6tg64I=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5RWiYh6tlfk4=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5RWiYh6tmr4M=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5RWiYiKtnqn4=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5RWiYiKtodLM=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5RWiYiKtpwlU=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RWkDsK/8U8w=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RWkDr6/4piw=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWkDsK/9X9k=", + "_parent": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "model": { + "$ref": "AAAAAAF5RWkDr6/4piw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1427, + "top": 1701, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWkDsK/+yfw=", + "_parent": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "model": { + "$ref": "AAAAAAF5RWkDr6/4piw=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1424, + "top": 1716, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWkDsK//l9E=", + "_parent": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "model": { + "$ref": "AAAAAAF5RWkDr6/4piw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1434, + "top": 1672, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWkDsLAAR6U=", + "_parent": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "model": { + "$ref": "AAAAAAF5RWkDr6/5hKI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1450, + "top": 1706, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWkDsLAB24o=", + "_parent": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "model": { + "$ref": "AAAAAAF5RWkDr6/5hKI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1445, + "top": 1718, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWkDsLACKmw=", + "_parent": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "model": { + "$ref": "AAAAAAF5RWkDr6/5hKI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1460, + "top": 1680, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWkDsLADQMw=", + "_parent": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "model": { + "$ref": "AAAAAAF5RWkDr6/6Fyk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1405, + "top": 1696, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWkDsLAEjZI=", + "_parent": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "model": { + "$ref": "AAAAAAF5RWkDr6/6Fyk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1404, + "top": 1710, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWkDsLAFuWM=", + "_parent": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "model": { + "$ref": "AAAAAAF5RWkDr6/6Fyk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1406, + "top": 1669, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RWkDsLAGH8s=", + "_parent": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "model": { + "$ref": "AAAAAAF5RWkDr6/5hKI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1160, + "top": 208, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RWkDsLAHEmo=", + "_parent": { + "$ref": "AAAAAAF5RWkDsK/8U8w=" + }, + "model": { + "$ref": "AAAAAAF5RWkDr6/6Fyk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1160, + "top": 208, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5RWiYh6tfjKM=" + }, + "tail": { + "$ref": "AAAAAAF5RWbWiJQ+LqI=" + }, + "lineStyle": 1, + "points": "1479:1703;1383:1683", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RWkDsK/9X9k=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RWkDsK/+yfw=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RWkDsK//l9E=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RWkDsLAAR6U=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RWkDsLAB24o=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RWkDsLACKmw=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RWkDsLADQMw=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RWkDsLAEjZI=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RWkDsLAFuWM=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RWkDsLAGH8s=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RWkDsLAHEmo=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RWmAObijdJg=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RWmAObifwr4=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWmAObikqE4=", + "_parent": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "model": { + "$ref": "AAAAAAF5RWmAObifwr4=" + }, + "font": "Arial;13;0", + "left": 1519, + "top": 1541, + "width": 46.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "edgePosition": 1, + "text": "+未完成" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWmAObilnCo=", + "_parent": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "model": { + "$ref": "AAAAAAF5RWmAObifwr4=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1536, + "top": 1527, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWmAObima+o=", + "_parent": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "model": { + "$ref": "AAAAAAF5RWmAObifwr4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1553, + "top": 1568, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWmAObinxIM=", + "_parent": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "model": { + "$ref": "AAAAAAF5RWmAObigyuY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1359, + "top": 1617, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWmAObioxZQ=", + "_parent": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "model": { + "$ref": "AAAAAAF5RWmAObigyuY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1356, + "top": 1604, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWmAObip4S4=", + "_parent": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "model": { + "$ref": "AAAAAAF5RWmAObigyuY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1365, + "top": 1644, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWmAObiqN8s=", + "_parent": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "model": { + "$ref": "AAAAAAF5RWmAObih5u0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1726, + "top": 1465, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RWmAObijdJg=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWmAObir6/Y=", + "_parent": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "model": { + "$ref": "AAAAAAF5RWmAObih5u0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1719, + "top": 1453, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RWmAObijdJg=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWmAObisLv4=", + "_parent": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "model": { + "$ref": "AAAAAAF5RWmAObih5u0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1740, + "top": 1488, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RWmAObijdJg=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RWmAObitY30=", + "_parent": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "model": { + "$ref": "AAAAAAF5RWmAObigyuY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -888, + "top": 512, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RWmAObiuohI=", + "_parent": { + "$ref": "AAAAAAF5RWmAObijdJg=" + }, + "model": { + "$ref": "AAAAAAF5RWmAObih5u0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -888, + "top": 512, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QMaQUG/rlG8=" + }, + "tail": { + "$ref": "AAAAAAF5RWiYh6tfjKM=" + }, + "lineStyle": 1, + "points": "1341:1647;1756:1475", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RWmAObikqE4=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RWmAObilnCo=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RWmAObima+o=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RWmAObinxIM=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RWmAObioxZQ=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RWmAObip4S4=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RWmAObiqN8s=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RWmAObir6/Y=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RWmAObisLv4=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RWmAObitY30=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RWmAObiuohI=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5RWo+Isgcitc=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RWo+Icga7No=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5RWo+Isgdtvs=", + "_parent": { + "$ref": "AAAAAAF5RWo+Isgcitc=" + }, + "model": { + "$ref": "AAAAAAF5RWo+Icga7No=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5RWo+Isge0Bo=", + "_parent": { + "$ref": "AAAAAAF5RWo+Isgdtvs=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 1072, + "top": -480, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RWo+Isgf4GU=", + "_parent": { + "$ref": "AAAAAAF5RWo+Isgdtvs=" + }, + "fillColor": "#ffff91", + "font": "Arial;13;1", + "left": 946, + "top": 939.5, + "width": 90, + "height": 13, + "text": "执行单测回检测" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RWo+Isgg0Do=", + "_parent": { + "$ref": "AAAAAAF5RWo+Isgdtvs=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 1072, + "top": -480, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RWo+IsghCRI=", + "_parent": { + "$ref": "AAAAAAF5RWo+Isgdtvs=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 1072, + "top": -480, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 941, + "top": 932.5, + "width": 101, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5RWo+Isge0Bo=" + }, + "nameLabel": { + "$ref": "AAAAAAF5RWo+Isgf4GU=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5RWo+Isgg0Do=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RWo+IsghCRI=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5RWo+IsgimWA=", + "_parent": { + "$ref": "AAAAAAF5RWo+Isgcitc=" + }, + "model": { + "$ref": "AAAAAAF5RWo+Icga7No=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 536, + "top": -240, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5RWo+IsgjYQU=", + "_parent": { + "$ref": "AAAAAAF5RWo+Isgcitc=" + }, + "model": { + "$ref": "AAAAAAF5RWo+Icga7No=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 536, + "top": -240, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5RWo+I8gkz+0=", + "_parent": { + "$ref": "AAAAAAF5RWo+Isgcitc=" + }, + "model": { + "$ref": "AAAAAAF5RWo+Icga7No=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 536, + "top": -240, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5RWo+I8gl0UM=", + "_parent": { + "$ref": "AAAAAAF5RWo+Isgcitc=" + }, + "model": { + "$ref": "AAAAAAF5RWo+Icga7No=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 536, + "top": -240, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5RWo+I8gmRYk=", + "_parent": { + "$ref": "AAAAAAF5RWo+Isgcitc=" + }, + "model": { + "$ref": "AAAAAAF5RWo+Icga7No=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 536, + "top": -240, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 920, + "top": 928, + "width": 142, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5RWo+Isgdtvs=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5RWo+IsgimWA=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5RWo+IsgjYQU=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5RWo+I8gkz+0=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5RWo+I8gl0UM=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5RWo+I8gmRYk=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RWqc88vvIe4=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RWqc8svr3pE=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWqc88vwQ3o=", + "_parent": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "model": { + "$ref": "AAAAAAF5RWqc8svr3pE=" + }, + "font": "Arial;13;0", + "left": 1113, + "top": 1304, + "width": 33.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "edgePosition": 1, + "text": "+完成" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWqc88vxT8A=", + "_parent": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "model": { + "$ref": "AAAAAAF5RWqc8svr3pE=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1115, + "top": 1310, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWqc88vy9C4=", + "_parent": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "model": { + "$ref": "AAAAAAF5RWqc8svr3pE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1156, + "top": 1293, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWqc88vzWws=", + "_parent": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "model": { + "$ref": "AAAAAAF5RWqc8svs8AE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1265, + "top": 1622, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWqc88v0Sh0=", + "_parent": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "model": { + "$ref": "AAAAAAF5RWqc8svs8AE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1251, + "top": 1626, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWqc88v168Q=", + "_parent": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "model": { + "$ref": "AAAAAAF5RWqc8svs8AE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1292, + "top": 1616, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWqc88v2l68=", + "_parent": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "model": { + "$ref": "AAAAAAF5RWqc8svtE1U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 994, + "top": 986, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWqc88v3ThA=", + "_parent": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "model": { + "$ref": "AAAAAAF5RWqc8svtE1U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 983, + "top": 994, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWqc88v4wsI=", + "_parent": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "model": { + "$ref": "AAAAAAF5RWqc8svtE1U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1017, + "top": 972, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RWqc88v5V34=", + "_parent": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "model": { + "$ref": "AAAAAAF5RWqc8svs8AE=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RWqc88v6Awc=", + "_parent": { + "$ref": "AAAAAAF5RWqc88vvIe4=" + }, + "model": { + "$ref": "AAAAAAF5RWqc8svtE1U=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5RWo+Isgcitc=" + }, + "tail": { + "$ref": "AAAAAAF5RWiYh6tfjKM=" + }, + "lineStyle": 1, + "points": "1289:1647;998:963", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RWqc88vwQ3o=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RWqc88vxT8A=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RWqc88vy9C4=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RWqc88vzWws=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RWqc88v0Sh0=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RWqc88v168Q=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RWqc88v2l68=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RWqc88v3ThA=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RWqc88v4wsI=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RWqc88v5V34=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RWqc88v6Awc=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RWvJyNWG+ro=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RWvJyNWC314=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWvJyNWHf5E=", + "_parent": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "model": { + "$ref": "AAAAAAF5RWvJyNWC314=" + }, + "font": "Arial;13;0", + "left": 1422, + "top": 952, + "width": 72.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "edgePosition": 1, + "text": "+未通过检测" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWvJydWI+RY=", + "_parent": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "model": { + "$ref": "AAAAAAF5RWvJyNWC314=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1459, + "top": 937, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWvJydWJFaw=", + "_parent": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "model": { + "$ref": "AAAAAAF5RWvJyNWC314=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1457, + "top": 981, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWvJydWKHVg=", + "_parent": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "model": { + "$ref": "AAAAAAF5RWvJyNWDYLg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1088, + "top": 929, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWvJydWLzSM=", + "_parent": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "model": { + "$ref": "AAAAAAF5RWvJyNWDYLg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1091, + "top": 916, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWvJydWM5GE=", + "_parent": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "model": { + "$ref": "AAAAAAF5RWvJyNWDYLg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1082, + "top": 956, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWvJydWN+wY=", + "_parent": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "model": { + "$ref": "AAAAAAF5RWvJyNWEI/s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1829, + "top": 974, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWvJydWO3W0=", + "_parent": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "model": { + "$ref": "AAAAAAF5RWvJyNWEI/s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1828, + "top": 961, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RWvJydWPqsM=", + "_parent": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "model": { + "$ref": "AAAAAAF5RWvJyNWEI/s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1832, + "top": 1002, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RWvJydWQnX8=", + "_parent": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "model": { + "$ref": "AAAAAAF5RWvJyNWDYLg=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RWvJydWRolw=", + "_parent": { + "$ref": "AAAAAAF5RWvJyNWG+ro=" + }, + "model": { + "$ref": "AAAAAAF5RWvJyNWEI/s=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QKuCwkzY630=" + }, + "tail": { + "$ref": "AAAAAAF5RWo+Isgcitc=" + }, + "lineStyle": 1, + "points": "1062:949;1855:997", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RWvJyNWHf5E=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RWvJydWI+RY=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RWvJydWJFaw=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RWvJydWKHVg=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RWvJydWLzSM=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RWvJydWM5GE=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RWvJydWN+wY=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RWvJydWO3W0=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RWvJydWPqsM=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RWvJydWQnX8=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RWvJydWRolw=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5RWzzg+QpJu4=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RWzzg+QnXQo=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5RWzzg+QqF0g=", + "_parent": { + "$ref": "AAAAAAF5RWzzg+QpJu4=" + }, + "model": { + "$ref": "AAAAAAF5RWzzg+QnXQo=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5RWzzg+QruaM=", + "_parent": { + "$ref": "AAAAAAF5RWzzg+QqF0g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1360, + "top": 880, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RWzzg+QscXo=", + "_parent": { + "$ref": "AAAAAAF5RWzzg+QqF0g=" + }, + "font": "Arial;13;1", + "left": 1021.5, + "top": 1747.5, + "width": 144, + "height": 13, + "text": "doCalScheduleAllCycle" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RWzzg+QtTVY=", + "_parent": { + "$ref": "AAAAAAF5RWzzg+QqF0g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1360, + "top": 880, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RWzzg+QuN+0=", + "_parent": { + "$ref": "AAAAAAF5RWzzg+QqF0g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1360, + "top": 880, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 1016.5, + "top": 1740.5, + "width": 155.208984375, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5RWzzg+QruaM=" + }, + "nameLabel": { + "$ref": "AAAAAAF5RWzzg+QscXo=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5RWzzg+QtTVY=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RWzzg+QuN+0=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5RWzzg+QvVhA=", + "_parent": { + "$ref": "AAAAAAF5RWzzg+QpJu4=" + }, + "model": { + "$ref": "AAAAAAF5RWzzg+QnXQo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 680, + "top": 440, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5RWzzhOQwWI4=", + "_parent": { + "$ref": "AAAAAAF5RWzzg+QpJu4=" + }, + "model": { + "$ref": "AAAAAAF5RWzzg+QnXQo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 680, + "top": 440, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5RWzzhOQxyn0=", + "_parent": { + "$ref": "AAAAAAF5RWzzg+QpJu4=" + }, + "model": { + "$ref": "AAAAAAF5RWzzg+QnXQo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 680, + "top": 440, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5RWzzhOQy5lE=", + "_parent": { + "$ref": "AAAAAAF5RWzzg+QpJu4=" + }, + "model": { + "$ref": "AAAAAAF5RWzzg+QnXQo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 680, + "top": 440, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5RWzzhOQzPbk=", + "_parent": { + "$ref": "AAAAAAF5RWzzg+QpJu4=" + }, + "model": { + "$ref": "AAAAAAF5RWzzg+QnXQo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 680, + "top": 440, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 984, + "top": 1736, + "width": 219, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5RWzzg+QqF0g=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5RWzzg+QvVhA=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5RWzzhOQwWI4=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5RWzzhOQxyn0=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5RWzzhOQy5lE=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5RWzzhOQzPbk=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RXS1EJdHVug=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RXS1D5dDHCY=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXS1EJdIPgY=", + "_parent": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "model": { + "$ref": "AAAAAAF5RXS1D5dDHCY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1189, + "top": 1689, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXS1EJdJc8o=", + "_parent": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "model": { + "$ref": "AAAAAAF5RXS1D5dDHCY=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1183, + "top": 1675, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXS1EZdKavs=", + "_parent": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "model": { + "$ref": "AAAAAAF5RXS1D5dDHCY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1200, + "top": 1716, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXS1EZdLggY=", + "_parent": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "model": { + "$ref": "AAAAAAF5RXS1D5dEJJs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1152, + "top": 1704, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXS1EZdMTYk=", + "_parent": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "model": { + "$ref": "AAAAAAF5RXS1D5dEJJs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1149, + "top": 1691, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXS1EZdNexM=", + "_parent": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "model": { + "$ref": "AAAAAAF5RXS1D5dEJJs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1159, + "top": 1731, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXS1EZdOTNQ=", + "_parent": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "model": { + "$ref": "AAAAAAF5RXS1D5dF2N4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1225, + "top": 1673, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXS1EZdPiGs=", + "_parent": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "model": { + "$ref": "AAAAAAF5RXS1D5dF2N4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1217, + "top": 1662, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXS1EZdQDNw=", + "_parent": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "model": { + "$ref": "AAAAAAF5RXS1D5dF2N4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1240, + "top": 1697, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RXS1EZdR8Jw=", + "_parent": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "model": { + "$ref": "AAAAAAF5RXS1D5dEJJs=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RXS1EZdSgUI=", + "_parent": { + "$ref": "AAAAAAF5RXS1EJdHVug=" + }, + "model": { + "$ref": "AAAAAAF5RXS1D5dF2N4=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5RWiYh6tfjKM=" + }, + "tail": { + "$ref": "AAAAAAF5RWzzg+QpJu4=" + }, + "lineStyle": 1, + "points": "1135:1735;1255:1683", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RXS1EJdIPgY=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RXS1EJdJc8o=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RXS1EZdKavs=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RXS1EZdLggY=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RXS1EZdMTYk=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RXS1EZdNexM=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RXS1EZdOTNQ=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RXS1EZdPiGs=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RXS1EZdQDNw=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RXS1EZdR8Jw=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RXS1EZdSgUI=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5RXZT37eTFkI=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RXZT3reRJjE=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5RXZT37eUYGs=", + "_parent": { + "$ref": "AAAAAAF5RXZT37eTFkI=" + }, + "model": { + "$ref": "AAAAAAF5RXZT3reRJjE=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5RXZT37eVlUE=", + "_parent": { + "$ref": "AAAAAAF5RXZT37eUYGs=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -64, + "top": -608, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RXZT37eWL9s=", + "_parent": { + "$ref": "AAAAAAF5RXZT37eUYGs=" + }, + "fillColor": "#ffff91", + "font": "Arial;13;1", + "left": 427, + "top": 555.5, + "width": 209, + "height": 13, + "text": "是否是doCalScheduleAllCycle状态" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RXZT37eXM1A=", + "_parent": { + "$ref": "AAAAAAF5RXZT37eUYGs=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -64, + "top": -608, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RXZT37eYXNc=", + "_parent": { + "$ref": "AAAAAAF5RXZT37eUYGs=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -64, + "top": -608, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 422, + "top": 548.5, + "width": 220.208984375, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5RXZT37eVlUE=" + }, + "nameLabel": { + "$ref": "AAAAAAF5RXZT37eWL9s=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5RXZT37eXM1A=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RXZT37eYXNc=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5RXZT4LeZ09I=", + "_parent": { + "$ref": "AAAAAAF5RXZT37eTFkI=" + }, + "model": { + "$ref": "AAAAAAF5RXZT3reRJjE=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -32, + "top": -304, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5RXZT4LeaFc4=", + "_parent": { + "$ref": "AAAAAAF5RXZT37eTFkI=" + }, + "model": { + "$ref": "AAAAAAF5RXZT3reRJjE=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -32, + "top": -304, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5RXZT4Leb1Fs=", + "_parent": { + "$ref": "AAAAAAF5RXZT37eTFkI=" + }, + "model": { + "$ref": "AAAAAAF5RXZT3reRJjE=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -32, + "top": -304, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5RXZT4Lec37Q=", + "_parent": { + "$ref": "AAAAAAF5RXZT37eTFkI=" + }, + "model": { + "$ref": "AAAAAAF5RXZT3reRJjE=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -32, + "top": -304, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5RXZT4Led934=", + "_parent": { + "$ref": "AAAAAAF5RXZT37eTFkI=" + }, + "model": { + "$ref": "AAAAAAF5RXZT3reRJjE=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -32, + "top": -304, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 376, + "top": 544, + "width": 311, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5RXZT37eUYGs=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5RXZT4LeZ09I=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5RXZT4LeaFc4=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5RXZT4Leb1Fs=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5RXZT4Lec37Q=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5RXZT4Led934=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RXgsFM1PXPQ=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RXgsE81LcLM=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXgsFM1QsVQ=", + "_parent": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "model": { + "$ref": "AAAAAAF5RXgsE81LcLM=" + }, + "font": "Arial;13;0", + "left": 734, + "top": 758, + "width": 33.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "edgePosition": 1, + "text": "+通过" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXgsFM1Ra4g=", + "_parent": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "model": { + "$ref": "AAAAAAF5RXgsE81LcLM=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 740, + "top": 769, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXgsFM1S7Hk=", + "_parent": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "model": { + "$ref": "AAAAAAF5RXgsE81LcLM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 769, + "top": 735, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXgsFM1TpZY=", + "_parent": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "model": { + "$ref": "AAAAAAF5RXgsE81Ml9Y=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 938, + "top": 915, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXgsFM1UfIs=", + "_parent": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "model": { + "$ref": "AAAAAAF5RXgsE81Ml9Y=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 928, + "top": 924, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXgsFM1VQJk=", + "_parent": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "model": { + "$ref": "AAAAAAF5RXgsE81Ml9Y=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 959, + "top": 897, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXgsFM1WeYo=", + "_parent": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "model": { + "$ref": "AAAAAAF5RXgsE81Ncj4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 563, + "top": 601, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXgsFM1XNlM=", + "_parent": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "model": { + "$ref": "AAAAAAF5RXgsE81Ncj4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 556, + "top": 612, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXgsFM1Y+GY=", + "_parent": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "model": { + "$ref": "AAAAAAF5RXgsE81Ncj4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 577, + "top": 577, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RXgsFc1ZbPg=", + "_parent": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "model": { + "$ref": "AAAAAAF5RXgsE81Ml9Y=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RXgsFc1aqC8=", + "_parent": { + "$ref": "AAAAAAF5RXgsFM1PXPQ=" + }, + "model": { + "$ref": "AAAAAAF5RXgsE81Ncj4=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5RXZT37eTFkI=" + }, + "tail": { + "$ref": "AAAAAAF5RWo+Isgcitc=" + }, + "lineStyle": 1, + "points": "968:927;553:579", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RXgsFM1QsVQ=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RXgsFM1Ra4g=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RXgsFM1S7Hk=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RXgsFM1TpZY=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RXgsFM1UfIs=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RXgsFM1VQJk=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RXgsFM1WeYo=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RXgsFM1XNlM=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RXgsFM1Y+GY=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RXgsFc1ZbPg=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RXgsFc1aqC8=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RXiiXNaNYZA=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RXiiW9aJDaw=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXiiXNaOCjk=", + "_parent": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "model": { + "$ref": "AAAAAAF5RXiiW9aJDaw=" + }, + "font": "Arial;13;0", + "left": 690, + "top": 496, + "width": 33.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "edgePosition": 1, + "text": "+不是" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXiiXNaPvOQ=", + "_parent": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "model": { + "$ref": "AAAAAAF5RXiiW9aJDaw=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 702, + "top": 481, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXiiXNaQrNs=", + "_parent": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "model": { + "$ref": "AAAAAAF5RXiiW9aJDaw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 713, + "top": 525, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXiiXNaRjEI=", + "_parent": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "model": { + "$ref": "AAAAAAF5RXiiW9aKkno=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 625, + "top": 516, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXiiXNaS5Dg=", + "_parent": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "model": { + "$ref": "AAAAAAF5RXiiW9aKkno=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 624, + "top": 502, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXiiXNaT/jE=", + "_parent": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "model": { + "$ref": "AAAAAAF5RXiiW9aKkno=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 628, + "top": 543, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXiiXNaUStc=", + "_parent": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "model": { + "$ref": "AAAAAAF5RXiiW9aL3M4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 787, + "top": 476, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXiiXNaVtIQ=", + "_parent": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "model": { + "$ref": "AAAAAAF5RXiiW9aL3M4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 781, + "top": 464, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RXiiXNaWcc8=", + "_parent": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "model": { + "$ref": "AAAAAAF5RXiiW9aL3M4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 797, + "top": 502, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RXiiXNaXeGE=", + "_parent": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "model": { + "$ref": "AAAAAAF5RXiiW9aKkno=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RXiiXNaY4kk=", + "_parent": { + "$ref": "AAAAAAF5RXiiXNaNYZA=" + }, + "model": { + "$ref": "AAAAAAF5RXiiW9aL3M4=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QJjLZRML/gk=" + }, + "tail": { + "$ref": "AAAAAAF5RXZT37eTFkI=" + }, + "lineStyle": 1, + "points": "604:543;816:491", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RXiiXNaOCjk=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RXiiXNaPvOQ=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RXiiXNaQrNs=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RXiiXNaRjEI=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RXiiXNaS5Dg=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RXiiXNaT/jE=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RXiiXNaUStc=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RXiiXNaVtIQ=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RXiiXNaWcc8=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RXiiXNaXeGE=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RXiiXNaY4kk=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5RX4IzuDknh4=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RX4IzeDinbw=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5RX4IzuDlZLU=", + "_parent": { + "$ref": "AAAAAAF5RX4IzuDknh4=" + }, + "model": { + "$ref": "AAAAAAF5RX4IzeDinbw=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5RX4IzuDmg8A=", + "_parent": { + "$ref": "AAAAAAF5RX4IzuDlZLU=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -240, + "top": -240, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RX4IzuDnpIw=", + "_parent": { + "$ref": "AAAAAAF5RX4IzuDlZLU=" + }, + "fillColor": "#ffff91", + "font": "Arial;13;1", + "left": 69, + "top": 1043.5, + "width": 181, + "height": 13, + "text": "检测其他测回是否有待补测数据" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RX4IzuDoCnY=", + "_parent": { + "$ref": "AAAAAAF5RX4IzuDlZLU=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -240, + "top": -240, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RX4IzuDpft0=", + "_parent": { + "$ref": "AAAAAAF5RX4IzuDlZLU=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -240, + "top": -240, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 64, + "top": 1036.5, + "width": 192, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5RX4IzuDmg8A=" + }, + "nameLabel": { + "$ref": "AAAAAAF5RX4IzuDnpIw=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5RX4IzuDoCnY=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RX4IzuDpft0=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5RX4IzuDqBSE=", + "_parent": { + "$ref": "AAAAAAF5RX4IzuDknh4=" + }, + "model": { + "$ref": "AAAAAAF5RX4IzeDinbw=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -120, + "top": -120, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5RX4IzuDrpSs=", + "_parent": { + "$ref": "AAAAAAF5RX4IzuDknh4=" + }, + "model": { + "$ref": "AAAAAAF5RX4IzeDinbw=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -120, + "top": -120, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5RX4IzuDsUmU=", + "_parent": { + "$ref": "AAAAAAF5RX4IzuDknh4=" + }, + "model": { + "$ref": "AAAAAAF5RX4IzeDinbw=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -120, + "top": -120, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5RX4IzuDtPH4=", + "_parent": { + "$ref": "AAAAAAF5RX4IzuDknh4=" + }, + "model": { + "$ref": "AAAAAAF5RX4IzeDinbw=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -120, + "top": -120, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5RX4IzuDu2iA=", + "_parent": { + "$ref": "AAAAAAF5RX4IzuDknh4=" + }, + "model": { + "$ref": "AAAAAAF5RX4IzeDinbw=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -120, + "top": -120, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 24, + "top": 1032, + "width": 271, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5RX4IzuDlZLU=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5RX4IzuDqBSE=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5RX4IzuDrpSs=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5RX4IzuDsUmU=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5RX4IzuDtPH4=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5RX4IzuDu2iA=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RX50xuaSWVY=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RX50xeaOm84=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX50xuaTzmw=", + "_parent": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "model": { + "$ref": "AAAAAAF5RX50xeaOm84=" + }, + "font": "Arial;13;0", + "left": 346, + "top": 808, + "width": 20.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "edgePosition": 1, + "text": "+是" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX50xuaUoZk=", + "_parent": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "model": { + "$ref": "AAAAAAF5RX50xeaOm84=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 368, + "top": 817, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX50xuaVv9g=", + "_parent": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "model": { + "$ref": "AAAAAAF5RX50xeaOm84=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 333, + "top": 789, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX50xuaWjUs=", + "_parent": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "model": { + "$ref": "AAAAAAF5RX50xeaPW6s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 513, + "top": 602, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX50xuaX0wc=", + "_parent": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "model": { + "$ref": "AAAAAAF5RX50xeaPW6s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 522, + "top": 612, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX50xuaYr8k=", + "_parent": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "model": { + "$ref": "AAAAAAF5RX50xeaPW6s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 493, + "top": 582, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX50xuaZPzE=", + "_parent": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "model": { + "$ref": "AAAAAAF5RX50xeaQJxA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 200, + "top": 1013, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX50xuaaRl8=", + "_parent": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "model": { + "$ref": "AAAAAAF5RX50xeaQJxA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 212, + "top": 1019, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX50xuabK8k=", + "_parent": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "model": { + "$ref": "AAAAAAF5RX50xeaQJxA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 176, + "top": 1000, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RX50xuac8yw=", + "_parent": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "model": { + "$ref": "AAAAAAF5RX50xeaPW6s=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RX50xuadjR8=", + "_parent": { + "$ref": "AAAAAAF5RX50xuaSWVY=" + }, + "model": { + "$ref": "AAAAAAF5RX50xeaQJxA=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5RX4IzuDknh4=" + }, + "tail": { + "$ref": "AAAAAAF5RXZT37eTFkI=" + }, + "lineStyle": 1, + "points": "517:579;173:1031", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RX50xuaTzmw=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RX50xuaUoZk=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RX50xuaVv9g=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RX50xuaWjUs=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RX50xuaX0wc=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RX50xuaYr8k=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RX50xuaZPzE=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RX50xuaaRl8=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RX50xuabK8k=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RX50xuac8yw=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RX50xuadjR8=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5RX8e8+6VSP4=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RX8e8+6Tpi8=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5RX8e9O6W2xM=", + "_parent": { + "$ref": "AAAAAAF5RX8e8+6VSP4=" + }, + "model": { + "$ref": "AAAAAAF5RX8e8+6Tpi8=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5RX8e9O6XR7Q=", + "_parent": { + "$ref": "AAAAAAF5RX8e9O6W2xM=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -16, + "top": -496, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RX8e9O6YBmI=", + "_parent": { + "$ref": "AAAAAAF5RX8e9O6W2xM=" + }, + "fillColor": "#ffadad", + "font": "Arial;13;1", + "left": 487.5, + "top": 963.5, + "width": 77, + "height": 13, + "text": "提示用户选择" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RX8e9O6ZG1Q=", + "_parent": { + "$ref": "AAAAAAF5RX8e9O6W2xM=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -16, + "top": -496, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RX8e9O6aHT4=", + "_parent": { + "$ref": "AAAAAAF5RX8e9O6W2xM=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -16, + "top": -496, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 482.5, + "top": 956.5, + "width": 88, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5RX8e9O6XR7Q=" + }, + "nameLabel": { + "$ref": "AAAAAAF5RX8e9O6YBmI=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5RX8e9O6ZG1Q=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RX8e9O6aHT4=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5RX8e9O6brFw=", + "_parent": { + "$ref": "AAAAAAF5RX8e8+6VSP4=" + }, + "model": { + "$ref": "AAAAAAF5RX8e8+6Tpi8=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -8, + "top": -248, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5RX8e9O6chUQ=", + "_parent": { + "$ref": "AAAAAAF5RX8e8+6VSP4=" + }, + "model": { + "$ref": "AAAAAAF5RX8e8+6Tpi8=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -8, + "top": -248, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5RX8e9O6d2JQ=", + "_parent": { + "$ref": "AAAAAAF5RX8e8+6VSP4=" + }, + "model": { + "$ref": "AAAAAAF5RX8e8+6Tpi8=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -8, + "top": -248, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5RX8e9O6ehSE=", + "_parent": { + "$ref": "AAAAAAF5RX8e8+6VSP4=" + }, + "model": { + "$ref": "AAAAAAF5RX8e8+6Tpi8=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -8, + "top": -248, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5RX8e9O6fsgA=", + "_parent": { + "$ref": "AAAAAAF5RX8e8+6VSP4=" + }, + "model": { + "$ref": "AAAAAAF5RX8e8+6Tpi8=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -8, + "top": -248, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ffadad", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 464, + "top": 952, + "width": 124, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5RX8e9O6W2xM=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5RX8e9O6brFw=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5RX8e9O6chUQ=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5RX8e9O6d2JQ=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5RX8e9O6ehSE=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5RX8e9O6fsgA=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RX9EYPFfH8Q=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RX9EYPFbm2U=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX9EYPFg5zI=", + "_parent": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "model": { + "$ref": "AAAAAAF5RX9EYPFbm2U=" + }, + "font": "Arial;13;0", + "left": 338, + "top": 986, + "width": 20.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "edgePosition": 1, + "text": "+有" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX9EYPFh+Xw=", + "_parent": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "model": { + "$ref": "AAAAAAF5RX9EYPFbm2U=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 345, + "top": 971, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX9EYPFiQm8=", + "_parent": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "model": { + "$ref": "AAAAAAF5RX9EYPFbm2U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 355, + "top": 1015, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX9EYPFj0XU=", + "_parent": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "model": { + "$ref": "AAAAAAF5RX9EYPFcd3k=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 263, + "top": 1004, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX9EYPFkHH4=", + "_parent": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "model": { + "$ref": "AAAAAAF5RX9EYPFcd3k=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 262, + "top": 991, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX9EYPFlEI4=", + "_parent": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "model": { + "$ref": "AAAAAAF5RX9EYPFcd3k=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 264, + "top": 1032, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX9EYPFmXkk=", + "_parent": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "model": { + "$ref": "AAAAAAF5RX9EYPFdtmc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 434, + "top": 967, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX9EYPFnjvk=", + "_parent": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "model": { + "$ref": "AAAAAAF5RX9EYPFdtmc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 429, + "top": 955, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX9EYPFoLfQ=", + "_parent": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "model": { + "$ref": "AAAAAAF5RX9EYPFdtmc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 444, + "top": 993, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RX9EYPFp0GM=", + "_parent": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "model": { + "$ref": "AAAAAAF5RX9EYPFcd3k=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RX9EYPFqX8k=", + "_parent": { + "$ref": "AAAAAAF5RX9EYPFfH8Q=" + }, + "model": { + "$ref": "AAAAAAF5RX9EYPFdtmc=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5RX8e8+6VSP4=" + }, + "tail": { + "$ref": "AAAAAAF5RX4IzuDknh4=" + }, + "lineStyle": 1, + "points": "241:1031;463:983", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RX9EYPFg5zI=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RX9EYPFh+Xw=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RX9EYPFiQm8=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RX9EYPFj0XU=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RX9EYPFkHH4=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RX9EYPFlEI4=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RX9EYPFmXkk=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RX9EYPFnjvk=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RX9EYPFoLfQ=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RX9EYPFp0GM=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RX9EYPFqX8k=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5RX+92/rtdeY=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RX+92vrrsgo=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5RX+92/ru5aU=", + "_parent": { + "$ref": "AAAAAAF5RX+92/rtdeY=" + }, + "model": { + "$ref": "AAAAAAF5RX+92vrrsgo=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5RX+92/rvMVo=", + "_parent": { + "$ref": "AAAAAAF5RX+92/ru5aU=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 160, + "top": 32, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RX+92/rwk7c=", + "_parent": { + "$ref": "AAAAAAF5RX+92/ru5aU=" + }, + "fillColor": "#ffff91", + "font": "Arial;13;1", + "left": 876, + "top": 1243.5, + "width": 62, + "height": 13, + "text": "切换测回" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RX+92/rxBWI=", + "_parent": { + "$ref": "AAAAAAF5RX+92/ru5aU=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 160, + "top": 32, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RX+92/ryOmk=", + "_parent": { + "$ref": "AAAAAAF5RX+92/ru5aU=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 160, + "top": 32, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 871, + "top": 1236.5, + "width": 72, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5RX+92/rvMVo=" + }, + "nameLabel": { + "$ref": "AAAAAAF5RX+92/rwk7c=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5RX+92/rxBWI=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RX+92/ryOmk=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5RX+92/rzeck=", + "_parent": { + "$ref": "AAAAAAF5RX+92/rtdeY=" + }, + "model": { + "$ref": "AAAAAAF5RX+92vrrsgo=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 80, + "top": 16, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5RX+92/r0UGE=", + "_parent": { + "$ref": "AAAAAAF5RX+92/rtdeY=" + }, + "model": { + "$ref": "AAAAAAF5RX+92vrrsgo=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 80, + "top": 16, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5RX+92/r1dEM=", + "_parent": { + "$ref": "AAAAAAF5RX+92/rtdeY=" + }, + "model": { + "$ref": "AAAAAAF5RX+92vrrsgo=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 80, + "top": 16, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5RX+92/r24rI=", + "_parent": { + "$ref": "AAAAAAF5RX+92/rtdeY=" + }, + "model": { + "$ref": "AAAAAAF5RX+92vrrsgo=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 80, + "top": 16, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5RX+92/r3m0Y=", + "_parent": { + "$ref": "AAAAAAF5RX+92/rtdeY=" + }, + "model": { + "$ref": "AAAAAAF5RX+92vrrsgo=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 80, + "top": 16, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 856, + "top": 1232, + "width": 102, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5RX+92/ru5aU=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5RX+92/rzeck=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5RX+92/r0UGE=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5RX+92/r1dEM=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5RX+92/r24rI=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5RX+92/r3m0Y=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RX/wMv3JNxw=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RX/wMv3F6d4=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX/wM/3KAYY=", + "_parent": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "model": { + "$ref": "AAAAAAF5RX/wMv3F6d4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1343, + "top": 1329, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX/wM/3L2sA=", + "_parent": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "model": { + "$ref": "AAAAAAF5RX/wMv3F6d4=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1346, + "top": 1314, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX/wM/3MDuY=", + "_parent": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "model": { + "$ref": "AAAAAAF5RX/wMv3F6d4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1336, + "top": 1358, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX/wM/3NMMM=", + "_parent": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "model": { + "$ref": "AAAAAAF5RX/wMv3GM64=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 986, + "top": 1246, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX/wM/3OaEE=", + "_parent": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "model": { + "$ref": "AAAAAAF5RX/wMv3GM64=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 991, + "top": 1233, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX/wM/3P2uw=", + "_parent": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "model": { + "$ref": "AAAAAAF5RX/wMv3GM64=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 976, + "top": 1272, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX/wM/3QkNM=", + "_parent": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "model": { + "$ref": "AAAAAAF5RX/wMv3HIz8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1701, + "top": 1412, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX/wM/3RuyM=", + "_parent": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "model": { + "$ref": "AAAAAAF5RX/wMv3HIz8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1701, + "top": 1399, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RX/wM/3SQ5M=", + "_parent": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "model": { + "$ref": "AAAAAAF5RX/wMv3HIz8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1699, + "top": 1440, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RX/wM/3TMvA=", + "_parent": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "model": { + "$ref": "AAAAAAF5RX/wMv3GM64=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 216, + "top": -8, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RX/wM/3Udik=", + "_parent": { + "$ref": "AAAAAAF5RX/wMv3JNxw=" + }, + "model": { + "$ref": "AAAAAAF5RX/wMv3HIz8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 216, + "top": -8, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QMaQUG/rlG8=" + }, + "tail": { + "$ref": "AAAAAAF5RX+92/rtdeY=" + }, + "lineStyle": 1, + "points": "958:1261;1723:1439", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RX/wM/3KAYY=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RX/wM/3L2sA=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RX/wM/3MDuY=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RX/wM/3NMMM=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RX/wM/3OaEE=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RX/wM/3P2uw=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RX/wM/3QkNM=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RX/wM/3RuyM=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RX/wM/3SQ5M=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RX/wM/3TMvA=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RX/wM/3Udik=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RYA6Lgau9u4=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RYA6LQaqG8I=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYA6LgavBvE=", + "_parent": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "model": { + "$ref": "AAAAAAF5RYA6LQaqG8I=" + }, + "font": "Arial;13;0", + "left": 674, + "top": 1090, + "width": 98.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "edgePosition": 1, + "text": "+跳转到相应测回" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYA6LgawDgk=", + "_parent": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "model": { + "$ref": "AAAAAAF5RYA6LQaqG8I=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 732, + "top": 1078, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYA6Lgaxot4=", + "_parent": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "model": { + "$ref": "AAAAAAF5RYA6LQaqG8I=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 706, + "top": 1115, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYA6LgayEWk=", + "_parent": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "model": { + "$ref": "AAAAAAF5RYA6LQaryvU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 578, + "top": 984, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYA6Lgazq+M=", + "_parent": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "model": { + "$ref": "AAAAAAF5RYA6LQaryvU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 588, + "top": 974, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYA6Lga0Sio=", + "_parent": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "model": { + "$ref": "AAAAAAF5RYA6LQaryvU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 559, + "top": 1003, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYA6Lga1FSA=", + "_parent": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "model": { + "$ref": "AAAAAAF5RYA6LQashgM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 869, + "top": 1197, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYA6Lga2vcA=", + "_parent": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "model": { + "$ref": "AAAAAAF5RYA6LQashgM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 875, + "top": 1185, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYA6Lga3b2g=", + "_parent": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "model": { + "$ref": "AAAAAAF5RYA6LQashgM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 857, + "top": 1222, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RYA6Lga4c4g=", + "_parent": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "model": { + "$ref": "AAAAAAF5RYA6LQaryvU=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RYA6Lga51go=", + "_parent": { + "$ref": "AAAAAAF5RYA6Lgau9u4=" + }, + "model": { + "$ref": "AAAAAAF5RYA6LQashgM=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5RX+92/rtdeY=" + }, + "tail": { + "$ref": "AAAAAAF5RX8e8+6VSP4=" + }, + "lineStyle": 1, + "points": "549:987;882:1231", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RYA6LgavBvE=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RYA6LgawDgk=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RYA6Lgaxot4=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RYA6LgayEWk=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RYA6Lgazq+M=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RYA6Lga0Sio=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RYA6Lga1FSA=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RYA6Lga2vcA=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RYA6Lga3b2g=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RYA6Lga4c4g=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RYA6Lga51go=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RYRxIyqNVJQ=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RYRxIiqJIUE=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYRxIyqOsk8=", + "_parent": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "model": { + "$ref": "AAAAAAF5RYRxIiqJIUE=" + }, + "font": "Arial;13;0", + "left": 658, + "top": 706, + "width": 72.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "edgePosition": 1, + "text": "+忽略或取消" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYRxIyqPdMg=", + "_parent": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "model": { + "$ref": "AAAAAAF5RYRxIiqJIUE=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 682, + "top": 697, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYRxIyqQWvY=", + "_parent": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "model": { + "$ref": "AAAAAAF5RYRxIiqJIUE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 719, + "top": 723, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYRxIyqRHT4=", + "_parent": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "model": { + "$ref": "AAAAAAF5RYRxIyqKuUY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 541, + "top": 915, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYRxJCqS57E=", + "_parent": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "model": { + "$ref": "AAAAAAF5RYRxIyqKuUY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 531, + "top": 905, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYRxJCqTkAo=", + "_parent": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "model": { + "$ref": "AAAAAAF5RYRxIyqKuUY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 560, + "top": 934, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYRxJCqUXmw=", + "_parent": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "model": { + "$ref": "AAAAAAF5RYRxIyqLN6Y=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 848, + "top": 497, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYRxJCqVgEY=", + "_parent": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "model": { + "$ref": "AAAAAAF5RYRxIyqLN6Y=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 836, + "top": 491, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYRxJCqWNBU=", + "_parent": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "model": { + "$ref": "AAAAAAF5RYRxIyqLN6Y=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 873, + "top": 509, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RYRxJCqXBjo=", + "_parent": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "model": { + "$ref": "AAAAAAF5RYRxIyqKuUY=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RYRxJCqYdsw=", + "_parent": { + "$ref": "AAAAAAF5RYRxIyqNVJQ=" + }, + "model": { + "$ref": "AAAAAAF5RYRxIyqLN6Y=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QJjLZRML/gk=" + }, + "tail": { + "$ref": "AAAAAAF5RX8e8+6VSP4=" + }, + "lineStyle": 1, + "points": "538:951;876:491", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RYRxIyqOsk8=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RYRxIyqPdMg=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RYRxIyqQWvY=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RYRxIyqRHT4=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RYRxJCqS57E=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RYRxJCqTkAo=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RYRxJCqUXmw=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RYRxJCqVgEY=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RYRxJCqWNBU=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RYRxJCqXBjo=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RYRxJCqYdsw=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5RYWBNj55r2s=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RYWBNT536bM=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5RYWBNj56ll8=", + "_parent": { + "$ref": "AAAAAAF5RYWBNj55r2s=" + }, + "model": { + "$ref": "AAAAAAF5RYWBNT536bM=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5RYWBNj57vDo=", + "_parent": { + "$ref": "AAAAAAF5RYWBNj56ll8=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -32, + "top": 864, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RYWBNj582Gg=", + "_parent": { + "$ref": "AAAAAAF5RYWBNj56ll8=" + }, + "fillColor": "#ffff91", + "font": "Arial;13;1", + "left": 151.5, + "top": 1835.5, + "width": 155, + "height": 13, + "text": "检测其他测回是否有空数据" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RYWBNj59CIs=", + "_parent": { + "$ref": "AAAAAAF5RYWBNj56ll8=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -32, + "top": 864, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RYWBNj5+a6c=", + "_parent": { + "$ref": "AAAAAAF5RYWBNj56ll8=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -32, + "top": 864, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 146.5, + "top": 1828.5, + "width": 166, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5RYWBNj57vDo=" + }, + "nameLabel": { + "$ref": "AAAAAAF5RYWBNj582Gg=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5RYWBNj59CIs=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RYWBNj5+a6c=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5RYWBNj5/meo=", + "_parent": { + "$ref": "AAAAAAF5RYWBNj55r2s=" + }, + "model": { + "$ref": "AAAAAAF5RYWBNT536bM=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -16, + "top": 432, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5RYWBNj6ApFY=", + "_parent": { + "$ref": "AAAAAAF5RYWBNj55r2s=" + }, + "model": { + "$ref": "AAAAAAF5RYWBNT536bM=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -16, + "top": 432, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5RYWBNj6BKos=", + "_parent": { + "$ref": "AAAAAAF5RYWBNj55r2s=" + }, + "model": { + "$ref": "AAAAAAF5RYWBNT536bM=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -16, + "top": 432, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5RYWBNj6CyfU=", + "_parent": { + "$ref": "AAAAAAF5RYWBNj55r2s=" + }, + "model": { + "$ref": "AAAAAAF5RYWBNT536bM=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -16, + "top": 432, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5RYWBNj6DzGw=", + "_parent": { + "$ref": "AAAAAAF5RYWBNj55r2s=" + }, + "model": { + "$ref": "AAAAAAF5RYWBNT536bM=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -16, + "top": 432, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 112, + "top": 1824, + "width": 234, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5RYWBNj56ll8=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5RYWBNj5/meo=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5RYWBNj6ApFY=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5RYWBNj6BKos=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5RYWBNj6CyfU=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5RYWBNj6DzGw=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RYXKoUPzfpc=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RYXKoEPvmVE=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYXKoUP0Xm4=", + "_parent": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "model": { + "$ref": "AAAAAAF5RYXKoEPvmVE=" + }, + "font": "Arial;13;0", + "left": 197, + "top": 1437, + "width": 20.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "edgePosition": 1, + "text": "+无" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYXKoUP1/8o=", + "_parent": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "model": { + "$ref": "AAAAAAF5RYXKoEPvmVE=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 222, + "top": 1436, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYXKoUP2TmE=", + "_parent": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "model": { + "$ref": "AAAAAAF5RYXKoEPvmVE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 178, + "top": 1440, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYXKoUP3dpE=", + "_parent": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "model": { + "$ref": "AAAAAAF5RYXKoUPwWeY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 178, + "top": 1085, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYXKoUP4Dks=", + "_parent": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "model": { + "$ref": "AAAAAAF5RYXKoUPwWeY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 191, + "top": 1086, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYXKoUP5sn0=", + "_parent": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "model": { + "$ref": "AAAAAAF5RYXKoUPwWeY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 150, + "top": 1083, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYXKoUP6dKk=", + "_parent": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "model": { + "$ref": "AAAAAAF5RYXKoUPxCsE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 238, + "top": 1789, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYXKoUP7hGo=", + "_parent": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "model": { + "$ref": "AAAAAAF5RYXKoUPxCsE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 251, + "top": 1786, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYXKoUP8Pbs=", + "_parent": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "model": { + "$ref": "AAAAAAF5RYXKoUPxCsE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 211, + "top": 1796, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RYXKoUP9qJ8=", + "_parent": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "model": { + "$ref": "AAAAAAF5RYXKoUPwWeY=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RYXKokP+OFo=", + "_parent": { + "$ref": "AAAAAAF5RYXKoUPzfpc=" + }, + "model": { + "$ref": "AAAAAAF5RYXKoUPxCsE=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5RYWBNj55r2s=" + }, + "tail": { + "$ref": "AAAAAAF5RX4IzuDknh4=" + }, + "lineStyle": 1, + "points": "161:1067;226:1823", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RYXKoUP0Xm4=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RYXKoUP1/8o=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RYXKoUP2TmE=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RYXKoUP3dpE=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RYXKoUP4Dks=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RYXKoUP5sn0=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RYXKoUP6dKk=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RYXKoUP7hGo=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RYXKoUP8Pbs=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RYXKoUP9qJ8=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RYXKokP+OFo=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RYbKCEsNrL8=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RYbKCEsJsiQ=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYbKCEsOHZ0=", + "_parent": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "model": { + "$ref": "AAAAAAF5RYbKCEsJsiQ=" + }, + "font": "Arial;13;0", + "left": 351, + "top": 1394, + "width": 20.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "edgePosition": 1, + "text": "+有" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYbKCEsP+kM=", + "_parent": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "model": { + "$ref": "AAAAAAF5RYbKCEsJsiQ=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 347, + "top": 1389, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYbKCEsQdPM=", + "_parent": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "model": { + "$ref": "AAAAAAF5RYbKCEsJsiQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 390, + "top": 1403, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYbKCEsRxi0=", + "_parent": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "model": { + "$ref": "AAAAAAF5RYbKCEsKkG0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 228, + "top": 1787, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYbKCEsSIa0=", + "_parent": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "model": { + "$ref": "AAAAAAF5RYbKCEsKkG0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 216, + "top": 1781, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYbKCEsTIOs=", + "_parent": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "model": { + "$ref": "AAAAAAF5RYbKCEsKkG0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 252, + "top": 1800, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYbKCEsUoUc=", + "_parent": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "model": { + "$ref": "AAAAAAF5RYbKCEsLR+0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 496, + "top": 1000, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYbKCUsVQTY=", + "_parent": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "model": { + "$ref": "AAAAAAF5RYbKCEsLR+0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 483, + "top": 998, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYbKCUsWC+U=", + "_parent": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "model": { + "$ref": "AAAAAAF5RYbKCEsLR+0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 523, + "top": 1005, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RYbKCUsX4lU=", + "_parent": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "model": { + "$ref": "AAAAAAF5RYbKCEsKkG0=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RYbKCUsYcdA=", + "_parent": { + "$ref": "AAAAAAF5RYbKCEsNrL8=" + }, + "model": { + "$ref": "AAAAAAF5RYbKCEsLR+0=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5RX8e8+6VSP4=" + }, + "tail": { + "$ref": "AAAAAAF5RYWBNj55r2s=" + }, + "lineStyle": 1, + "points": "234:1823;519:987", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RYbKCEsOHZ0=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RYbKCEsP+kM=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RYbKCEsQdPM=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RYbKCEsRxi0=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RYbKCEsSIa0=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RYbKCEsTIOs=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RYbKCEsUoUc=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RYbKCUsVQTY=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RYbKCUsWC+U=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RYbKCUsX4lU=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RYbKCUsYcdA=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5RYo1sZrzoek=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RYo1sJrxVxU=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5RYo1sZr0KlU=", + "_parent": { + "$ref": "AAAAAAF5RYo1sZrzoek=" + }, + "model": { + "$ref": "AAAAAAF5RYo1sJrxVxU=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5RYo1sZr1HjQ=", + "_parent": { + "$ref": "AAAAAAF5RYo1sZr0KlU=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -256, + "top": 1584, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RYo1sZr2W5c=", + "_parent": { + "$ref": "AAAAAAF5RYo1sZr0KlU=" + }, + "fillColor": "#ffff91", + "font": "Arial;13;1", + "left": 511.5, + "top": 2147.5, + "width": 116, + "height": 13, + "text": "检测其他测回合法性" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RYo1sZr3XYs=", + "_parent": { + "$ref": "AAAAAAF5RYo1sZr0KlU=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -256, + "top": 1584, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RYo1sZr4E80=", + "_parent": { + "$ref": "AAAAAAF5RYo1sZr0KlU=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -256, + "top": 1584, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 506.5, + "top": 2140.5, + "width": 127, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5RYo1sZr1HjQ=" + }, + "nameLabel": { + "$ref": "AAAAAAF5RYo1sZr2W5c=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5RYo1sZr3XYs=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RYo1sZr4E80=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5RYo1sZr5VvI=", + "_parent": { + "$ref": "AAAAAAF5RYo1sZrzoek=" + }, + "model": { + "$ref": "AAAAAAF5RYo1sJrxVxU=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -128, + "top": 792, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5RYo1sZr6Veg=", + "_parent": { + "$ref": "AAAAAAF5RYo1sZrzoek=" + }, + "model": { + "$ref": "AAAAAAF5RYo1sJrxVxU=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -128, + "top": 792, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5RYo1sZr7Dv4=", + "_parent": { + "$ref": "AAAAAAF5RYo1sZrzoek=" + }, + "model": { + "$ref": "AAAAAAF5RYo1sJrxVxU=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -128, + "top": 792, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5RYo1sZr8TjI=", + "_parent": { + "$ref": "AAAAAAF5RYo1sZrzoek=" + }, + "model": { + "$ref": "AAAAAAF5RYo1sJrxVxU=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -128, + "top": 792, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5RYo1sZr9JcM=", + "_parent": { + "$ref": "AAAAAAF5RYo1sZrzoek=" + }, + "model": { + "$ref": "AAAAAAF5RYo1sJrxVxU=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -128, + "top": 792, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 480, + "top": 2136, + "width": 179, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5RYo1sZr0KlU=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5RYo1sZr5VvI=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5RYo1sZr6Veg=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5RYo1sZr7Dv4=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5RYo1sZr8TjI=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5RYo1sZr9JcM=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RYqgkqO2MyI=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RYqgkaOybww=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYqgkqO3BkI=", + "_parent": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "model": { + "$ref": "AAAAAAF5RYqgkaOybww=" + }, + "font": "Arial;13;0", + "left": 379, + "top": 1979, + "width": 59.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "edgePosition": 1, + "text": "+无空测回" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYqgkqO4B50=", + "_parent": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "model": { + "$ref": "AAAAAAF5RYqgkaOybww=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 418, + "top": 1968, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYqgkqO5Eu4=", + "_parent": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "model": { + "$ref": "AAAAAAF5RYqgkaOybww=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 387, + "top": 2002, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYqgkqO6Q3U=", + "_parent": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "model": { + "$ref": "AAAAAAF5RYqgkaOzOcA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 277, + "top": 1859, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYqgkqO7HyE=", + "_parent": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "model": { + "$ref": "AAAAAAF5RYqgkaOzOcA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 287, + "top": 1851, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYqgkqO8jmg=", + "_parent": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "model": { + "$ref": "AAAAAAF5RYqgkaOzOcA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 255, + "top": 1876, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYqgkqO9LA0=", + "_parent": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "model": { + "$ref": "AAAAAAF5RYqgkaO0Gyw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 539, + "top": 2100, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYqgkqO+vZw=", + "_parent": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "model": { + "$ref": "AAAAAAF5RYqgkaO0Gyw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 547, + "top": 2089, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYqgkqO/OQc=", + "_parent": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "model": { + "$ref": "AAAAAAF5RYqgkaO0Gyw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 524, + "top": 2123, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RYqgkqPAF8U=", + "_parent": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "model": { + "$ref": "AAAAAAF5RYqgkaOzOcA=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RYqgkqPBTIk=", + "_parent": { + "$ref": "AAAAAAF5RYqgkqO2MyI=" + }, + "model": { + "$ref": "AAAAAAF5RYqgkaO0Gyw=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5RYo1sZrzoek=" + }, + "tail": { + "$ref": "AAAAAAF5RYWBNj55r2s=" + }, + "lineStyle": 1, + "points": "248:1859;549:2135", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RYqgkqO3BkI=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RYqgkqO4B50=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RYqgkqO5Eu4=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RYqgkqO6Q3U=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RYqgkqO7HyE=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RYqgkqO8jmg=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RYqgkqO9LA0=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RYqgkqO+vZw=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RYqgkqO/OQc=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RYqgkqPAF8U=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RYqgkqPBTIk=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RYuGzq0zcW0=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RYuGza0vDqU=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYuGzq00uWc=", + "_parent": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "model": { + "$ref": "AAAAAAF5RYuGza0vDqU=" + }, + "font": "Arial;13;0", + "left": 2069, + "top": 2029, + "width": 137.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "edgePosition": 1, + "text": "+发现有测回未通过检测" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYuGzq01kJ4=", + "_parent": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "model": { + "$ref": "AAAAAAF5RYuGza0vDqU=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 2122, + "top": 2032, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYuGzq02LjQ=", + "_parent": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "model": { + "$ref": "AAAAAAF5RYuGza0vDqU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2166, + "top": 2022, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYuGzq03E1k=", + "_parent": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "model": { + "$ref": "AAAAAAF5RYuGza0wl4I=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 683, + "top": 2123, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYuGzq044hU=", + "_parent": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "model": { + "$ref": "AAAAAAF5RYuGza0wl4I=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 685, + "top": 2109, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYuGzq05NGE=", + "_parent": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "model": { + "$ref": "AAAAAAF5RYuGza0wl4I=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 681, + "top": 2150, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYuGzq06xW4=", + "_parent": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "model": { + "$ref": "AAAAAAF5RYuGza0xzjs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1912, + "top": 1041, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYuGzq07gn8=", + "_parent": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "model": { + "$ref": "AAAAAAF5RYuGza0xzjs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1899, + "top": 1046, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RYuGzq08/Nc=", + "_parent": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "model": { + "$ref": "AAAAAAF5RYuGza0xzjs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1938, + "top": 1031, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RYuGzq09BO0=", + "_parent": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "model": { + "$ref": "AAAAAAF5RYuGza0wl4I=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RYuGzq0+Fys=", + "_parent": { + "$ref": "AAAAAAF5RYuGzq0zcW0=" + }, + "model": { + "$ref": "AAAAAAF5RYuGza0xzjs=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QKuCwkzY630=" + }, + "tail": { + "$ref": "AAAAAAF5RYo1sZrzoek=" + }, + "lineStyle": 1, + "points": "659:2146;2152:2032;1921:1019", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RYuGzq00uWc=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RYuGzq01kJ4=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RYuGzq02LjQ=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RYuGzq03E1k=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RYuGzq044hU=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RYuGzq05NGE=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RYuGzq06xW4=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RYuGzq07gn8=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RYuGzq08/Nc=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RYuGzq09BO0=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RYuGzq0+Fys=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RY5M47VS/5M=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RY5M4rVOVIM=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY5M47VTDWg=", + "_parent": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "model": { + "$ref": "AAAAAAF5RY5M4rVOVIM=" + }, + "font": "Arial;13;0", + "left": 672, + "top": 1304, + "width": 85.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "edgePosition": 1, + "text": "+全部通过检测" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY5M47VUjKA=", + "_parent": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "model": { + "$ref": "AAAAAAF5RY5M4rVOVIM=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 699, + "top": 1301, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY5M5LVVTlw=", + "_parent": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "model": { + "$ref": "AAAAAAF5RY5M4rVOVIM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 743, + "top": 1309, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY5M5LVWBPw=", + "_parent": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "model": { + "$ref": "AAAAAAF5RY5M4rVPReU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 562, + "top": 2100, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY5M5LVX2xY=", + "_parent": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "model": { + "$ref": "AAAAAAF5RY5M4rVPReU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 549, + "top": 2095, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY5M5LVYskw=", + "_parent": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "model": { + "$ref": "AAAAAAF5RY5M4rVPReU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 588, + "top": 2110, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY5M5LVZo0A=", + "_parent": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "model": { + "$ref": "AAAAAAF5RY5M4rVQGdM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 866, + "top": 507, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY5M5LVaI9U=", + "_parent": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "model": { + "$ref": "AAAAAAF5RY5M4rVQGdM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 852, + "top": 507, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY5M5LVbdjo=", + "_parent": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "model": { + "$ref": "AAAAAAF5RY5M4rVQGdM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 894, + "top": 508, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RY5M5LVcoPg=", + "_parent": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "model": { + "$ref": "AAAAAAF5RY5M4rVPReU=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RY5M5LVdBDo=", + "_parent": { + "$ref": "AAAAAAF5RY5M47VS/5M=" + }, + "model": { + "$ref": "AAAAAAF5RY5M4rVQGdM=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QJjLZRML/gk=" + }, + "tail": { + "$ref": "AAAAAAF5RYo1sZrzoek=" + }, + "lineStyle": 1, + "points": "572:2135;886:491", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RY5M47VTDWg=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RY5M47VUjKA=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RY5M5LVVTlw=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RY5M5LVWBPw=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RY5M5LVX2xY=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RY5M5LVYskw=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RY5M5LVZo0A=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RY5M5LVaI9U=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RY5M5LVbdjo=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RY5M5LVcoPg=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RY5M5LVdBDo=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5RY+P3cq78x4=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RY+P3cq56es=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5RY+P3cq8lrU=", + "_parent": { + "$ref": "AAAAAAF5RY+P3cq78x4=" + }, + "model": { + "$ref": "AAAAAAF5RY+P3cq56es=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5RY+P3cq9UVw=", + "_parent": { + "$ref": "AAAAAAF5RY+P3cq8lrU=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": -192, + "top": 48, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RY+P3cq+inU=", + "_parent": { + "$ref": "AAAAAAF5RY+P3cq8lrU=" + }, + "fillColor": "#8282ff", + "font": "Arial;13;1", + "left": 956.5, + "top": 1331.5, + "width": 101, + "height": 13, + "text": "switchState2Idle" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RY+P3cq/1Xo=", + "_parent": { + "$ref": "AAAAAAF5RY+P3cq8lrU=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": -192, + "top": 48, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RY+P3crAIoY=", + "_parent": { + "$ref": "AAAAAAF5RY+P3cq8lrU=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": -192, + "top": 48, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": 951.5, + "top": 1324.5, + "width": 111.8671875, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5RY+P3cq9UVw=" + }, + "nameLabel": { + "$ref": "AAAAAAF5RY+P3cq+inU=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5RY+P3cq/1Xo=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RY+P3crAIoY=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5RY+P3srBu6A=", + "_parent": { + "$ref": "AAAAAAF5RY+P3cq78x4=" + }, + "model": { + "$ref": "AAAAAAF5RY+P3cq56es=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": -96, + "top": 24, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5RY+P3srCnMw=", + "_parent": { + "$ref": "AAAAAAF5RY+P3cq78x4=" + }, + "model": { + "$ref": "AAAAAAF5RY+P3cq56es=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": -96, + "top": 24, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5RY+P3srDTrA=", + "_parent": { + "$ref": "AAAAAAF5RY+P3cq78x4=" + }, + "model": { + "$ref": "AAAAAAF5RY+P3cq56es=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": -96, + "top": 24, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5RY+P3srE+P0=", + "_parent": { + "$ref": "AAAAAAF5RY+P3cq78x4=" + }, + "model": { + "$ref": "AAAAAAF5RY+P3cq56es=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": -96, + "top": 24, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5RY+P3srFRq4=", + "_parent": { + "$ref": "AAAAAAF5RY+P3cq78x4=" + }, + "model": { + "$ref": "AAAAAAF5RY+P3cq56es=" + }, + "visible": false, + "fillColor": "#8282ff", + "font": "Arial;13;0", + "left": -96, + "top": 24, + "width": 10, + "height": 10 + } + ], + "fillColor": "#8282ff", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 928, + "top": 1320, + "width": 158, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5RY+P3cq8lrU=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5RY+P3srBu6A=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5RY+P3srCnMw=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5RY+P3srDTrA=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5RY+P3srE+P0=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5RY+P3srFRq4=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RY/lW9HunTY=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RY/lWtHqafY=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY/lW9Hvi/A=", + "_parent": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "model": { + "$ref": "AAAAAAF5RY/lWtHqafY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1133, + "top": 858, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY/lW9Hw6yM=", + "_parent": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "model": { + "$ref": "AAAAAAF5RY/lWtHqafY=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1119, + "top": 854, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY/lW9Hx5k8=", + "_parent": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "model": { + "$ref": "AAAAAAF5RY/lWtHqafY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1162, + "top": 867, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY/lW9HyN1A=", + "_parent": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "model": { + "$ref": "AAAAAAF5RY/lW9Hrql4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1004, + "top": 1283, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY/lW9Hz89k=", + "_parent": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "model": { + "$ref": "AAAAAAF5RY/lW9Hrql4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 992, + "top": 1277, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY/lW9H0J0I=", + "_parent": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "model": { + "$ref": "AAAAAAF5RY/lW9Hrql4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1029, + "top": 1295, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY/lW9H1ErY=", + "_parent": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "model": { + "$ref": "AAAAAAF5RY/lW9HsN84=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1263, + "top": 433, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY/lW9H23xw=", + "_parent": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "model": { + "$ref": "AAAAAAF5RY/lW9HsN84=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1249, + "top": 431, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RY/lW9H3Onc=", + "_parent": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "model": { + "$ref": "AAAAAAF5RY/lW9HsN84=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1290, + "top": 437, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RY/lW9H46uE=", + "_parent": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "model": { + "$ref": "AAAAAAF5RY/lW9Hrql4=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RY/lW9H5+K0=", + "_parent": { + "$ref": "AAAAAAF5RY/lW9HunTY=" + }, + "model": { + "$ref": "AAAAAAF5RY/lW9HsN84=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5P5/CAk98zZc=" + }, + "tail": { + "$ref": "AAAAAAF5RY+P3cq78x4=" + }, + "lineStyle": 1, + "points": "1011:1319;1285:419", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RY/lW9Hvi/A=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RY/lW9Hw6yM=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RY/lW9Hx5k8=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RY/lW9HyN1A=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RY/lW9Hz89k=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RY/lW9H0J0I=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RY/lW9H1ErY=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RY/lW9H23xw=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RY/lW9H3Onc=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RY/lW9H46uE=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RY/lW9H5+K0=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5RZAQqNi9KXs=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RZAQp9i7BLM=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5RZAQqNi+U5k=", + "_parent": { + "$ref": "AAAAAAF5RZAQqNi9KXs=" + }, + "model": { + "$ref": "AAAAAAF5RZAQp9i7BLM=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5RZAQqNi/3K4=", + "_parent": { + "$ref": "AAAAAAF5RZAQqNi+U5k=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -368, + "top": 1008, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RZAQqNjAnDw=", + "_parent": { + "$ref": "AAAAAAF5RZAQqNi+U5k=" + }, + "fillColor": "#ffff91", + "font": "Arial;13;1", + "left": 770, + "top": 1891.5, + "width": 90, + "height": 13, + "text": "查找待补测数据" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RZAQqNjB74E=", + "_parent": { + "$ref": "AAAAAAF5RZAQqNi+U5k=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -368, + "top": 1008, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RZAQqNjCvdQ=", + "_parent": { + "$ref": "AAAAAAF5RZAQqNi+U5k=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -368, + "top": 1008, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 765, + "top": 1884.5, + "width": 101, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5RZAQqNi/3K4=" + }, + "nameLabel": { + "$ref": "AAAAAAF5RZAQqNjAnDw=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5RZAQqNjB74E=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RZAQqNjCvdQ=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5RZAQqNjDBLs=", + "_parent": { + "$ref": "AAAAAAF5RZAQqNi9KXs=" + }, + "model": { + "$ref": "AAAAAAF5RZAQp9i7BLM=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -184, + "top": 504, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5RZAQqNjEOXs=", + "_parent": { + "$ref": "AAAAAAF5RZAQqNi9KXs=" + }, + "model": { + "$ref": "AAAAAAF5RZAQp9i7BLM=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -184, + "top": 504, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5RZAQqNjF53M=", + "_parent": { + "$ref": "AAAAAAF5RZAQqNi9KXs=" + }, + "model": { + "$ref": "AAAAAAF5RZAQp9i7BLM=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -184, + "top": 504, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5RZAQqNjGCMk=", + "_parent": { + "$ref": "AAAAAAF5RZAQqNi9KXs=" + }, + "model": { + "$ref": "AAAAAAF5RZAQp9i7BLM=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -184, + "top": 504, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5RZAQqNjHp8s=", + "_parent": { + "$ref": "AAAAAAF5RZAQqNi9KXs=" + }, + "model": { + "$ref": "AAAAAAF5RZAQp9i7BLM=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -184, + "top": 504, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 744, + "top": 1880, + "width": 142, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5RZAQqNi+U5k=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5RZAQqNjDBLs=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5RZAQqNjEOXs=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5RZAQqNjF53M=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5RZAQqNjGCMk=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5RZAQqNjHp8s=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RZDsue7ftRY=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RZDsue7baAw=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZDsue7gCik=", + "_parent": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "model": { + "$ref": "AAAAAAF5RZDsue7baAw=" + }, + "font": "Arial;13;0", + "left": 885, + "top": 1606, + "width": 20.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "edgePosition": 1, + "text": "+有" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZDsue7h1YU=", + "_parent": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "model": { + "$ref": "AAAAAAF5RZDsue7baAw=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 881, + "top": 1601, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZDsue7iQis=", + "_parent": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "model": { + "$ref": "AAAAAAF5RZDsue7baAw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 924, + "top": 1615, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZDsue7jDYo=", + "_parent": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "model": { + "$ref": "AAAAAAF5RZDsue7cAPs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 814, + "top": 1843, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZDsue7kyAA=", + "_parent": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "model": { + "$ref": "AAAAAAF5RZDsue7cAPs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 802, + "top": 1837, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZDsue7ll8Q=", + "_parent": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "model": { + "$ref": "AAAAAAF5RZDsue7cAPs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 838, + "top": 1856, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZDsue7mtW0=", + "_parent": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "model": { + "$ref": "AAAAAAF5RZDsue7dBLs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 977, + "top": 1368, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZDsue7n/oo=", + "_parent": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "model": { + "$ref": "AAAAAAF5RZDsue7dBLs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 964, + "top": 1366, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZDsue7oje8=", + "_parent": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "model": { + "$ref": "AAAAAAF5RZDsue7dBLs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1004, + "top": 1373, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RZDsue7pTkA=", + "_parent": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "model": { + "$ref": "AAAAAAF5RZDsue7cAPs=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RZDsue7qLNI=", + "_parent": { + "$ref": "AAAAAAF5RZDsue7ftRY=" + }, + "model": { + "$ref": "AAAAAAF5RZDsue7dBLs=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5RY+P3cq78x4=" + }, + "tail": { + "$ref": "AAAAAAF5RZAQqNi9KXs=" + }, + "lineStyle": 1, + "points": "820:1879;1000:1355", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RZDsue7gCik=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RZDsue7h1YU=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RZDsue7iQis=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RZDsue7jDYo=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RZDsue7kyAA=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RZDsue7ll8Q=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RZDsue7mtW0=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RZDsue7n/oo=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RZDsue7oje8=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RZDsue7pTkA=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RZDsue7qLNI=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5RZEXNfhC2ho=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RZEXNfhA9nA=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5RZEXNfhDeUQ=", + "_parent": { + "$ref": "AAAAAAF5RZEXNfhC2ho=" + }, + "model": { + "$ref": "AAAAAAF5RZEXNfhA9nA=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5RZEXNfhE1JY=", + "_parent": { + "$ref": "AAAAAAF5RZEXNfhDeUQ=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -304, + "top": -48, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RZEXNfhF08s=", + "_parent": { + "$ref": "AAAAAAF5RZEXNfhDeUQ=" + }, + "fillColor": "#ffff91", + "font": "Arial;13;1", + "left": 813, + "top": 1443.5, + "width": 64, + "height": 13, + "text": "查找空数据" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RZEXNfhGZmc=", + "_parent": { + "$ref": "AAAAAAF5RZEXNfhDeUQ=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -304, + "top": -48, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RZEXNfhHCVU=", + "_parent": { + "$ref": "AAAAAAF5RZEXNfhDeUQ=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -304, + "top": -48, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 808, + "top": 1436.5, + "width": 75, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5RZEXNfhE1JY=" + }, + "nameLabel": { + "$ref": "AAAAAAF5RZEXNfhF08s=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5RZEXNfhGZmc=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RZEXNfhHCVU=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5RZEXNfhIvoY=", + "_parent": { + "$ref": "AAAAAAF5RZEXNfhC2ho=" + }, + "model": { + "$ref": "AAAAAAF5RZEXNfhA9nA=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -152, + "top": -24, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5RZEXNvhJXeE=", + "_parent": { + "$ref": "AAAAAAF5RZEXNfhC2ho=" + }, + "model": { + "$ref": "AAAAAAF5RZEXNfhA9nA=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -152, + "top": -24, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5RZEXNvhKzwc=", + "_parent": { + "$ref": "AAAAAAF5RZEXNfhC2ho=" + }, + "model": { + "$ref": "AAAAAAF5RZEXNfhA9nA=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -152, + "top": -24, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5RZEXNvhLfS4=", + "_parent": { + "$ref": "AAAAAAF5RZEXNfhC2ho=" + }, + "model": { + "$ref": "AAAAAAF5RZEXNfhA9nA=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -152, + "top": -24, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5RZEXNvhM3lA=", + "_parent": { + "$ref": "AAAAAAF5RZEXNfhC2ho=" + }, + "model": { + "$ref": "AAAAAAF5RZEXNfhA9nA=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -152, + "top": -24, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 792, + "top": 1432, + "width": 106, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5RZEXNfhDeUQ=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5RZEXNfhIvoY=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5RZEXNvhJXeE=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5RZEXNvhKzwc=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5RZEXNvhLfS4=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5RZEXNvhM3lA=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RZE5Jvvk8+0=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RZE5JvvgNmk=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZE5J/vlq9g=", + "_parent": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "model": { + "$ref": "AAAAAAF5RZE5JvvgNmk=" + }, + "font": "Arial;13;0", + "left": 804, + "top": 1665, + "width": 20.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "edgePosition": 1, + "text": "+无" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZE5J/vm7FE=", + "_parent": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "model": { + "$ref": "AAAAAAF5RZE5JvvgNmk=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 799, + "top": 1664, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZE5J/vn7vY=", + "_parent": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "model": { + "$ref": "AAAAAAF5RZE5JvvgNmk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 843, + "top": 1668, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZE5J/voHLE=", + "_parent": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "model": { + "$ref": "AAAAAAF5RZE5Jvvh7eI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 801, + "top": 1846, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZE5J/vpdnU=", + "_parent": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "model": { + "$ref": "AAAAAAF5RZE5Jvvh7eI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 788, + "top": 1842, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZE5J/vqSPU=", + "_parent": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "model": { + "$ref": "AAAAAAF5RZE5Jvvh7eI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 828, + "top": 1852, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZE5J/vrD3M=", + "_parent": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "model": { + "$ref": "AAAAAAF5RZE5JvviTz0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 826, + "top": 1485, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZE5J/vslRk=", + "_parent": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "model": { + "$ref": "AAAAAAF5RZE5JvviTz0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 812, + "top": 1487, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZE5J/vtins=", + "_parent": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "model": { + "$ref": "AAAAAAF5RZE5JvviTz0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 854, + "top": 1483, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RZE5J/vuuHI=", + "_parent": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "model": { + "$ref": "AAAAAAF5RZE5Jvvh7eI=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RZE5J/vvgB0=", + "_parent": { + "$ref": "AAAAAAF5RZE5Jvvk8+0=" + }, + "model": { + "$ref": "AAAAAAF5RZE5JvviTz0=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5RZEXNfhC2ho=" + }, + "tail": { + "$ref": "AAAAAAF5RZAQqNi9KXs=" + }, + "lineStyle": 1, + "points": "815:1879;843:1467", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RZE5J/vlq9g=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RZE5J/vm7FE=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RZE5J/vn7vY=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RZE5J/voHLE=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RZE5J/vpdnU=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RZE5J/vqSPU=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RZE5J/vrD3M=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RZE5J/vslRk=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RZE5J/vtins=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RZE5J/vuuHI=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RZE5J/vvgB0=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RZGEZgj/XLs=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RZGEZgj773A=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZGEZgkArOw=", + "_parent": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "model": { + "$ref": "AAAAAAF5RZGEZgj773A=" + }, + "font": "Arial;13;0", + "left": 906, + "top": 1374, + "width": 20.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "edgePosition": 1, + "text": "+有" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZGEZgkB2TY=", + "_parent": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "model": { + "$ref": "AAAAAAF5RZGEZgj773A=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 907, + "top": 1362, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZGEZgkChVo=", + "_parent": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "model": { + "$ref": "AAAAAAF5RZGEZgj773A=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 933, + "top": 1399, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZGEZgkDRjc=", + "_parent": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "model": { + "$ref": "AAAAAAF5RZGEZgj8gpI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 882, + "top": 1397, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZGEZgkERZ0=", + "_parent": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "model": { + "$ref": "AAAAAAF5RZGEZgj8gpI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 877, + "top": 1385, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZGEZgkFONE=", + "_parent": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "model": { + "$ref": "AAAAAAF5RZGEZgj8gpI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 894, + "top": 1422, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZGEZgkGzgA=", + "_parent": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "model": { + "$ref": "AAAAAAF5RZGEZgj9p0E=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 950, + "top": 1351, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZGEZgkHVm4=", + "_parent": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "model": { + "$ref": "AAAAAAF5RZGEZgj9p0E=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 940, + "top": 1341, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZGEZgkIGXU=", + "_parent": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "model": { + "$ref": "AAAAAAF5RZGEZgj9p0E=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 969, + "top": 1371, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RZGEZgkJQgE=", + "_parent": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "model": { + "$ref": "AAAAAAF5RZGEZgj8gpI=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RZGEZgkK2ek=", + "_parent": { + "$ref": "AAAAAAF5RZGEZgj/XLs=" + }, + "model": { + "$ref": "AAAAAAF5RZGEZgj9p0E=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5RY+P3cq78x4=" + }, + "tail": { + "$ref": "AAAAAAF5RZEXNfhC2ho=" + }, + "lineStyle": 1, + "points": "870:1431;980:1355", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RZGEZgkArOw=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RZGEZgkB2TY=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RZGEZgkChVo=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RZGEZgkDRjc=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RZGEZgkERZ0=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RZGEZgkFONE=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RZGEZgkGzgA=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RZGEZgkHVm4=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RZGEZgkIGXU=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RZGEZgkJQgE=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RZGEZgkK2ek=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5RZHb+w38rbY=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RZHb+g34JOw=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZHb+w39z3k=", + "_parent": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "model": { + "$ref": "AAAAAAF5RZHb+g34JOw=" + }, + "font": "Arial;13;0", + "left": 841, + "top": 954, + "width": 20.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "edgePosition": 1, + "text": "+无" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZHb+w3+E8c=", + "_parent": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "model": { + "$ref": "AAAAAAF5RZHb+g34JOw=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 836, + "top": 953, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZHb+w3/cnc=", + "_parent": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "model": { + "$ref": "AAAAAAF5RZHb+g34JOw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 880, + "top": 955, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZHb+w4A7LA=", + "_parent": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "model": { + "$ref": "AAAAAAF5RZHb+g35LNk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 831, + "top": 1398, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZHb+w4BF6A=", + "_parent": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "model": { + "$ref": "AAAAAAF5RZHb+g35LNk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 818, + "top": 1395, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZHb+w4COx0=", + "_parent": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "model": { + "$ref": "AAAAAAF5RZHb+g35LNk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 858, + "top": 1403, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZHb+w4DS1Q=", + "_parent": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "model": { + "$ref": "AAAAAAF5RZHb+g36Mvo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 871, + "top": 510, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZHb+w4Efb8=", + "_parent": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "model": { + "$ref": "AAAAAAF5RZHb+g36Mvo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 858, + "top": 511, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5RZHb+w4Fx+M=", + "_parent": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "model": { + "$ref": "AAAAAAF5RZHb+g36Mvo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 899, + "top": 507, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RZHb+w4GxWE=", + "_parent": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "model": { + "$ref": "AAAAAAF5RZHb+g35LNk=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5RZHb+w4HFa8=", + "_parent": { + "$ref": "AAAAAAF5RZHb+w38rbY=" + }, + "model": { + "$ref": "AAAAAAF5RZHb+g36Mvo=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QJjLZRML/gk=" + }, + "tail": { + "$ref": "AAAAAAF5RZEXNfhC2ho=" + }, + "lineStyle": 1, + "points": "845:1431;888:491", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5RZHb+w39z3k=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5RZHb+w3+E8c=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RZHb+w3/cnc=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5RZHb+w4A7LA=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5RZHb+w4BF6A=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5RZHb+w4COx0=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5RZHb+w4DS1Q=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5RZHb+w4Efb8=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5RZHb+w4Fx+M=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5RZHb+w4GxWE=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5RZHb+w4HFa8=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5RZ6XBji6Gjs=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5RZ6XBTi4yu4=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5RZ6XBji742g=", + "_parent": { + "$ref": "AAAAAAF5RZ6XBji6Gjs=" + }, + "model": { + "$ref": "AAAAAAF5RZ6XBTi4yu4=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5RZ6XBji84Lo=", + "_parent": { + "$ref": "AAAAAAF5RZ6XBji742g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -672, + "top": 880, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RZ6XBji96yI=", + "_parent": { + "$ref": "AAAAAAF5RZ6XBji742g=" + }, + "font": "Arial;13;1", + "left": 776, + "top": 2035.5, + "width": 79, + "height": 13, + "text": "doMoveBack" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RZ6XBji+VvE=", + "_parent": { + "$ref": "AAAAAAF5RZ6XBji742g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -672, + "top": 880, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5RZ6XBji/AjM=", + "_parent": { + "$ref": "AAAAAAF5RZ6XBji742g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -672, + "top": 880, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 771, + "top": 2028.5, + "width": 90.18994140625, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5RZ6XBji84Lo=" + }, + "nameLabel": { + "$ref": "AAAAAAF5RZ6XBji96yI=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5RZ6XBji+VvE=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5RZ6XBji/AjM=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5RZ6XBjjASWk=", + "_parent": { + "$ref": "AAAAAAF5RZ6XBji6Gjs=" + }, + "model": { + "$ref": "AAAAAAF5RZ6XBTi4yu4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -336, + "top": 440, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5RZ6XBzjBtGc=", + "_parent": { + "$ref": "AAAAAAF5RZ6XBji6Gjs=" + }, + "model": { + "$ref": "AAAAAAF5RZ6XBTi4yu4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -336, + "top": 440, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5RZ6XBzjCvBw=", + "_parent": { + "$ref": "AAAAAAF5RZ6XBji6Gjs=" + }, + "model": { + "$ref": "AAAAAAF5RZ6XBTi4yu4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -336, + "top": 440, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5RZ6XBzjD9LY=", + "_parent": { + "$ref": "AAAAAAF5RZ6XBji6Gjs=" + }, + "model": { + "$ref": "AAAAAAF5RZ6XBTi4yu4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -336, + "top": 440, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5RZ6XBzjEkZ0=", + "_parent": { + "$ref": "AAAAAAF5RZ6XBji6Gjs=" + }, + "model": { + "$ref": "AAAAAAF5RZ6XBTi4yu4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -336, + "top": 440, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 752, + "top": 2024, + "width": 127, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5RZ6XBji742g=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5RZ6XBjjASWk=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5RZ6XBzjBtGc=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5RZ6XBzjCvBw=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5RZ6XBzjD9LY=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5RZ6XBzjEkZ0=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5Sr6mnFdIbRQ=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5Sr6mm1dGVLo=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5Sr6mnFdJQes=", + "_parent": { + "$ref": "AAAAAAF5Sr6mnFdIbRQ=" + }, + "model": { + "$ref": "AAAAAAF5Sr6mm1dGVLo=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5Sr6mnFdKY5o=", + "_parent": { + "$ref": "AAAAAAF5Sr6mnFdJQes=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -480, + "top": 96, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5Sr6mnFdL8fY=", + "_parent": { + "$ref": "AAAAAAF5Sr6mnFdJQes=" + }, + "font": "Arial;13;1", + "left": 414, + "top": 1723.5, + "width": 72, + "height": 13, + "text": "doSurveyor" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5Sr6mnFdMXvo=", + "_parent": { + "$ref": "AAAAAAF5Sr6mnFdJQes=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -480, + "top": 96, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5Sr6mnFdNGZc=", + "_parent": { + "$ref": "AAAAAAF5Sr6mnFdJQes=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -480, + "top": 96, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 409, + "top": 1716.5, + "width": 82.24267578125, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5Sr6mnFdKY5o=" + }, + "nameLabel": { + "$ref": "AAAAAAF5Sr6mnFdL8fY=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5Sr6mnFdMXvo=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5Sr6mnFdNGZc=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5Sr6mnVdOubo=", + "_parent": { + "$ref": "AAAAAAF5Sr6mnFdIbRQ=" + }, + "model": { + "$ref": "AAAAAAF5Sr6mm1dGVLo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -240, + "top": 48, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5Sr6mnVdPN3o=", + "_parent": { + "$ref": "AAAAAAF5Sr6mnFdIbRQ=" + }, + "model": { + "$ref": "AAAAAAF5Sr6mm1dGVLo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -240, + "top": 48, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5Sr6mnVdQi1o=", + "_parent": { + "$ref": "AAAAAAF5Sr6mnFdIbRQ=" + }, + "model": { + "$ref": "AAAAAAF5Sr6mm1dGVLo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -240, + "top": 48, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5Sr6mnVdRDJw=", + "_parent": { + "$ref": "AAAAAAF5Sr6mnFdIbRQ=" + }, + "model": { + "$ref": "AAAAAAF5Sr6mm1dGVLo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -240, + "top": 48, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5Sr6mnVdS2zY=", + "_parent": { + "$ref": "AAAAAAF5Sr6mnFdIbRQ=" + }, + "model": { + "$ref": "AAAAAAF5Sr6mm1dGVLo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -240, + "top": 48, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 392, + "top": 1712, + "width": 116, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5Sr6mnFdJQes=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5Sr6mnVdOubo=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5Sr6mnVdPN3o=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5Sr6mnVdQi1o=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5Sr6mnVdRDJw=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5Sr6mnVdS2zY=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5Sr+CM2cB5us=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5Sr+CM2b/I6Q=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5Sr+CM2cCGRA=", + "_parent": { + "$ref": "AAAAAAF5Sr+CM2cB5us=" + }, + "model": { + "$ref": "AAAAAAF5Sr+CM2b/I6Q=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5Sr+CM2cDzn0=", + "_parent": { + "$ref": "AAAAAAF5Sr+CM2cCGRA=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -1104, + "top": -480, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5Sr+CNGcEr4Q=", + "_parent": { + "$ref": "AAAAAAF5Sr+CM2cCGRA=" + }, + "fillColor": "#ffff91", + "font": "Arial;13;1", + "left": 303.5, + "top": 1531.5, + "width": 194, + "height": 13, + "text": "检测其他测回是否有正在测量数据" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5Sr+CNGcFDPg=", + "_parent": { + "$ref": "AAAAAAF5Sr+CM2cCGRA=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -1104, + "top": -480, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5Sr+CNGcG0MQ=", + "_parent": { + "$ref": "AAAAAAF5Sr+CM2cCGRA=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -1104, + "top": -480, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 298.5, + "top": 1524.5, + "width": 205, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5Sr+CM2cDzn0=" + }, + "nameLabel": { + "$ref": "AAAAAAF5Sr+CNGcEr4Q=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5Sr+CNGcFDPg=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5Sr+CNGcG0MQ=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5Sr+CNGcHJ2Y=", + "_parent": { + "$ref": "AAAAAAF5Sr+CM2cB5us=" + }, + "model": { + "$ref": "AAAAAAF5Sr+CM2b/I6Q=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -552, + "top": -240, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5Sr+CNGcILlE=", + "_parent": { + "$ref": "AAAAAAF5Sr+CM2cB5us=" + }, + "model": { + "$ref": "AAAAAAF5Sr+CM2b/I6Q=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -552, + "top": -240, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5Sr+CNGcJ/gk=", + "_parent": { + "$ref": "AAAAAAF5Sr+CM2cB5us=" + }, + "model": { + "$ref": "AAAAAAF5Sr+CM2b/I6Q=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -552, + "top": -240, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5Sr+CNGcKL4U=", + "_parent": { + "$ref": "AAAAAAF5Sr+CM2cB5us=" + }, + "model": { + "$ref": "AAAAAAF5Sr+CM2b/I6Q=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -552, + "top": -240, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5Sr+CNGcLiZA=", + "_parent": { + "$ref": "AAAAAAF5Sr+CM2cB5us=" + }, + "model": { + "$ref": "AAAAAAF5Sr+CM2b/I6Q=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -552, + "top": -240, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 256, + "top": 1520, + "width": 289, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5Sr+CM2cCGRA=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5Sr+CNGcHJ2Y=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5Sr+CNGcILlE=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5Sr+CNGcJ/gk=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5Sr+CNGcKL4U=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5Sr+CNGcLiZA=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5SsC4MnfxyFI=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5SsC4Mnft0S4=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsC4M3fycW0=", + "_parent": { + "$ref": "AAAAAAF5SsC4MnfxyFI=" + }, + "model": { + "$ref": "AAAAAAF5SsC4Mnft0S4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 409, + "top": 1630, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5SsC4MnfxyFI=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsC4M3fz5ec=", + "_parent": { + "$ref": "AAAAAAF5SsC4MnfxyFI=" + }, + "model": { + "$ref": "AAAAAAF5SsC4Mnft0S4=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 394, + "top": 1634, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5SsC4MnfxyFI=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsC4M3f06c0=", + "_parent": { + "$ref": "AAAAAAF5SsC4MnfxyFI=" + }, + "model": { + "$ref": "AAAAAAF5SsC4Mnft0S4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 438, + "top": 1623, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5SsC4MnfxyFI=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsC4M3f1ynk=", + "_parent": { + "$ref": "AAAAAAF5SsC4MnfxyFI=" + }, + "model": { + "$ref": "AAAAAAF5SsC4Mnfuteg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 423, + "top": 1683, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5SsC4MnfxyFI=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsC4M3f212E=", + "_parent": { + "$ref": "AAAAAAF5SsC4MnfxyFI=" + }, + "model": { + "$ref": "AAAAAAF5SsC4Mnfuteg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 409, + "top": 1684, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5SsC4MnfxyFI=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsC4M3f3s5c=", + "_parent": { + "$ref": "AAAAAAF5SsC4MnfxyFI=" + }, + "model": { + "$ref": "AAAAAAF5SsC4Mnfuteg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 450, + "top": 1680, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5SsC4MnfxyFI=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsC4M3f4ln4=", + "_parent": { + "$ref": "AAAAAAF5SsC4MnfxyFI=" + }, + "model": { + "$ref": "AAAAAAF5SsC4Mnfv/lw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 396, + "top": 1577, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5SsC4MnfxyFI=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsC4M3f5q6U=", + "_parent": { + "$ref": "AAAAAAF5SsC4MnfxyFI=" + }, + "model": { + "$ref": "AAAAAAF5SsC4Mnfv/lw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 384, + "top": 1583, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5SsC4MnfxyFI=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsC4M3f6cyo=", + "_parent": { + "$ref": "AAAAAAF5SsC4MnfxyFI=" + }, + "model": { + "$ref": "AAAAAAF5SsC4Mnfv/lw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 422, + "top": 1566, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5SsC4MnfxyFI=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5SsC4M3f7Urg=", + "_parent": { + "$ref": "AAAAAAF5SsC4MnfxyFI=" + }, + "model": { + "$ref": "AAAAAAF5SsC4Mnfuteg=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5SsC4M3f8wRw=", + "_parent": { + "$ref": "AAAAAAF5SsC4MnfxyFI=" + }, + "model": { + "$ref": "AAAAAAF5SsC4Mnfv/lw=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5Sr+CM2cB5us=" + }, + "tail": { + "$ref": "AAAAAAF5Sr6mnFdIbRQ=" + }, + "lineStyle": 1, + "points": "444:1711;405:1555", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5SsC4M3fycW0=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5SsC4M3fz5ec=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5SsC4M3f06c0=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5SsC4M3f1ynk=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5SsC4M3f212E=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5SsC4M3f3s5c=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5SsC4M3f4ln4=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5SsC4M3f5q6U=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5SsC4M3f6cyo=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5SsC4M3f7Urg=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5SsC4M3f8wRw=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5SsEjzYKBxwU=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5SsEjzYJ/d3I=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5SsEjzYKCPow=", + "_parent": { + "$ref": "AAAAAAF5SsEjzYKBxwU=" + }, + "model": { + "$ref": "AAAAAAF5SsEjzYJ/d3I=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5SsEjzYKD6b8=", + "_parent": { + "$ref": "AAAAAAF5SsEjzYKCPow=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -976, + "top": -688, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5SsEjzYKE6p4=", + "_parent": { + "$ref": "AAAAAAF5SsEjzYKCPow=" + }, + "fillColor": "#ffadad", + "font": "Arial;13;1", + "left": 458, + "top": 1363.5, + "width": 129, + "height": 13, + "text": "提示用户是否删除数据" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5SsEjzYKFVEY=", + "_parent": { + "$ref": "AAAAAAF5SsEjzYKCPow=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -976, + "top": -688, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5SsEjzoKGCs4=", + "_parent": { + "$ref": "AAAAAAF5SsEjzYKCPow=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -976, + "top": -688, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": 453, + "top": 1356.5, + "width": 140, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5SsEjzYKD6b8=" + }, + "nameLabel": { + "$ref": "AAAAAAF5SsEjzYKE6p4=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5SsEjzYKFVEY=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5SsEjzoKGCs4=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5SsEjzoKHLwk=", + "_parent": { + "$ref": "AAAAAAF5SsEjzYKBxwU=" + }, + "model": { + "$ref": "AAAAAAF5SsEjzYJ/d3I=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -488, + "top": -344, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5SsEjzoKIZyQ=", + "_parent": { + "$ref": "AAAAAAF5SsEjzYKBxwU=" + }, + "model": { + "$ref": "AAAAAAF5SsEjzYJ/d3I=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -488, + "top": -344, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5SsEjzoKJIsU=", + "_parent": { + "$ref": "AAAAAAF5SsEjzYKBxwU=" + }, + "model": { + "$ref": "AAAAAAF5SsEjzYJ/d3I=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -488, + "top": -344, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5SsEjzoKKdw8=", + "_parent": { + "$ref": "AAAAAAF5SsEjzYKBxwU=" + }, + "model": { + "$ref": "AAAAAAF5SsEjzYJ/d3I=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -488, + "top": -344, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5SsEjzoKLM3w=", + "_parent": { + "$ref": "AAAAAAF5SsEjzYKBxwU=" + }, + "model": { + "$ref": "AAAAAAF5SsEjzYJ/d3I=" + }, + "visible": false, + "fillColor": "#ffadad", + "font": "Arial;13;0", + "left": -488, + "top": -344, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ffadad", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 424, + "top": 1352, + "width": 197, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5SsEjzYKCPow=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5SsEjzoKHLwk=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5SsEjzoKIZyQ=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5SsEjzoKJIsU=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5SsEjzoKKdw8=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5SsEjzoKLM3w=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5SsGTy4vXB4s=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5SsGTyovTQIg=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsGTy4vYy/Y=", + "_parent": { + "$ref": "AAAAAAF5SsGTy4vXB4s=" + }, + "model": { + "$ref": "AAAAAAF5SsGTyovTQIg=" + }, + "font": "Arial;13;0", + "left": 425, + "top": 1438, + "width": 46.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5SsGTy4vXB4s=" + }, + "edgePosition": 1, + "text": "+有数据" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsGTy4vZaQY=", + "_parent": { + "$ref": "AAAAAAF5SsGTy4vXB4s=" + }, + "model": { + "$ref": "AAAAAAF5SsGTyovTQIg=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 436, + "top": 1429, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5SsGTy4vXB4s=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsGTy4va5YE=", + "_parent": { + "$ref": "AAAAAAF5SsGTy4vXB4s=" + }, + "model": { + "$ref": "AAAAAAF5SsGTyovTQIg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 473, + "top": 1455, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5SsGTy4vXB4s=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsGTy4vbO0E=", + "_parent": { + "$ref": "AAAAAAF5SsGTy4vXB4s=" + }, + "model": { + "$ref": "AAAAAAF5SsGTy4vUxm0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 416, + "top": 1483, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5SsGTy4vXB4s=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsGTy4vcDBs=", + "_parent": { + "$ref": "AAAAAAF5SsGTy4vXB4s=" + }, + "model": { + "$ref": "AAAAAAF5SsGTy4vUxm0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 406, + "top": 1473, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5SsGTy4vXB4s=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsGTy4vdZI0=", + "_parent": { + "$ref": "AAAAAAF5SsGTy4vXB4s=" + }, + "model": { + "$ref": "AAAAAAF5SsGTy4vUxm0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 435, + "top": 1502, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5SsGTy4vXB4s=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsGTy4veUmo=", + "_parent": { + "$ref": "AAAAAAF5SsGTy4vXB4s=" + }, + "model": { + "$ref": "AAAAAAF5SsGTy4vVaZ0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 481, + "top": 1393, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5SsGTy4vXB4s=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsGTy4vfcb0=", + "_parent": { + "$ref": "AAAAAAF5SsGTy4vXB4s=" + }, + "model": { + "$ref": "AAAAAAF5SsGTy4vVaZ0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 469, + "top": 1387, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5SsGTy4vXB4s=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsGTy4vgVyo=", + "_parent": { + "$ref": "AAAAAAF5SsGTy4vXB4s=" + }, + "model": { + "$ref": "AAAAAAF5SsGTy4vVaZ0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 506, + "top": 1405, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5SsGTy4vXB4s=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5SsGTy4vhc58=", + "_parent": { + "$ref": "AAAAAAF5SsGTy4vXB4s=" + }, + "model": { + "$ref": "AAAAAAF5SsGTy4vUxm0=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5SsGTy4vi4qg=", + "_parent": { + "$ref": "AAAAAAF5SsGTy4vXB4s=" + }, + "model": { + "$ref": "AAAAAAF5SsGTy4vVaZ0=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5SsEjzYKBxwU=" + }, + "tail": { + "$ref": "AAAAAAF5Sr+CM2cB5us=" + }, + "lineStyle": 1, + "points": "413:1519;509:1387", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5SsGTy4vYy/Y=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5SsGTy4vZaQY=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5SsGTy4va5YE=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5SsGTy4vbO0E=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5SsGTy4vcDBs=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5SsGTy4vdZI0=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5SsGTy4veUmo=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5SsGTy4vfcb0=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5SsGTy4vgVyo=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5SsGTy4vhc58=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5SsGTy4vi4qg=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5SsIvCJpX8B4=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5SsIvB5pTO8k=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsIvCJpYDgw=", + "_parent": { + "$ref": "AAAAAAF5SsIvCJpX8B4=" + }, + "model": { + "$ref": "AAAAAAF5SsIvB5pTO8k=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 691, + "top": 909, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5SsIvCJpX8B4=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsIvCJpZ1dU=", + "_parent": { + "$ref": "AAAAAAF5SsIvCJpX8B4=" + }, + "model": { + "$ref": "AAAAAAF5SsIvB5pTO8k=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 677, + "top": 903, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5SsIvCJpX8B4=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsIvCJpaoIQ=", + "_parent": { + "$ref": "AAAAAAF5SsIvCJpX8B4=" + }, + "model": { + "$ref": "AAAAAAF5SsIvB5pTO8k=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 718, + "top": 920, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5SsIvCJpX8B4=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsIvCJpb9qM=", + "_parent": { + "$ref": "AAAAAAF5SsIvCJpX8B4=" + }, + "model": { + "$ref": "AAAAAAF5SsIvB5pUHxM=" + }, + "font": "Arial;13;0", + "left": 488, + "top": 1315, + "width": 72.22798156738281, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5SsIvCJpX8B4=" + }, + "edgePosition": 2, + "text": "+忽略or取消" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsIvCJpcPdE=", + "_parent": { + "$ref": "AAAAAAF5SsIvCJpX8B4=" + }, + "model": { + "$ref": "AAAAAAF5SsIvB5pUHxM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 513, + "top": 1308, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5SsIvCJpX8B4=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsIvCJpd7pc=", + "_parent": { + "$ref": "AAAAAAF5SsIvCJpX8B4=" + }, + "model": { + "$ref": "AAAAAAF5SsIvB5pUHxM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 548, + "top": 1329, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5SsIvCJpX8B4=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsIvCJpeUhk=", + "_parent": { + "$ref": "AAAAAAF5SsIvCJpX8B4=" + }, + "model": { + "$ref": "AAAAAAF5SsIvB5pVSwc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 858, + "top": 503, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5SsIvCJpX8B4=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsIvCJpfq/M=", + "_parent": { + "$ref": "AAAAAAF5SsIvCJpX8B4=" + }, + "model": { + "$ref": "AAAAAAF5SsIvB5pVSwc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 845, + "top": 500, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5SsIvCJpX8B4=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsIvCJpgY1s=", + "_parent": { + "$ref": "AAAAAAF5SsIvCJpX8B4=" + }, + "model": { + "$ref": "AAAAAAF5SsIvB5pVSwc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 885, + "top": 509, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5SsIvCJpX8B4=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5SsIvCJphgMc=", + "_parent": { + "$ref": "AAAAAAF5SsIvCJpX8B4=" + }, + "model": { + "$ref": "AAAAAAF5SsIvB5pUHxM=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5SsIvCJpi0FU=", + "_parent": { + "$ref": "AAAAAAF5SsIvCJpX8B4=" + }, + "model": { + "$ref": "AAAAAAF5SsIvB5pVSwc=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QJjLZRML/gk=" + }, + "tail": { + "$ref": "AAAAAAF5SsEjzYKBxwU=" + }, + "lineStyle": 1, + "points": "529:1351;882:491", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5SsIvCJpYDgw=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5SsIvCJpZ1dU=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5SsIvCJpaoIQ=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5SsIvCJpb9qM=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5SsIvCJpcPdE=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5SsIvCJpd7pc=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5SsIvCJpeUhk=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5SsIvCJpfq/M=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5SsIvCJpgY1s=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5SsIvCJphgMc=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5SsIvCJpi0FU=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5SsKfZ6cz6GA=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5SsKfZqcx8QM=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5SsKfZ6c0cw0=", + "_parent": { + "$ref": "AAAAAAF5SsKfZ6cz6GA=" + }, + "model": { + "$ref": "AAAAAAF5SsKfZqcx8QM=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5SsKfZ6c1If0=", + "_parent": { + "$ref": "AAAAAAF5SsKfZ6c0cw0=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -1504, + "top": -1264, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5SsKfZ6c22jM=", + "_parent": { + "$ref": "AAAAAAF5SsKfZ6c0cw0=" + }, + "fillColor": "#ffff91", + "font": "Arial;13;1", + "left": 188, + "top": 1195.5, + "width": 62, + "height": 13, + "text": "执行测量" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5SsKfZ6c3y80=", + "_parent": { + "$ref": "AAAAAAF5SsKfZ6c0cw0=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -1504, + "top": -1264, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5SsKfZ6c4/6w=", + "_parent": { + "$ref": "AAAAAAF5SsKfZ6c0cw0=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -1504, + "top": -1264, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 183, + "top": 1188.5, + "width": 72, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5SsKfZ6c1If0=" + }, + "nameLabel": { + "$ref": "AAAAAAF5SsKfZ6c22jM=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5SsKfZ6c3y80=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5SsKfZ6c4/6w=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5SsKfZ6c53s4=", + "_parent": { + "$ref": "AAAAAAF5SsKfZ6cz6GA=" + }, + "model": { + "$ref": "AAAAAAF5SsKfZqcx8QM=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -752, + "top": -632, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5SsKfZ6c6ce4=", + "_parent": { + "$ref": "AAAAAAF5SsKfZ6cz6GA=" + }, + "model": { + "$ref": "AAAAAAF5SsKfZqcx8QM=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -752, + "top": -632, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5SsKfZ6c7vSY=", + "_parent": { + "$ref": "AAAAAAF5SsKfZ6cz6GA=" + }, + "model": { + "$ref": "AAAAAAF5SsKfZqcx8QM=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -752, + "top": -632, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5SsKfZ6c8vrI=", + "_parent": { + "$ref": "AAAAAAF5SsKfZ6cz6GA=" + }, + "model": { + "$ref": "AAAAAAF5SsKfZqcx8QM=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -752, + "top": -632, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5SsKfZ6c9w5g=", + "_parent": { + "$ref": "AAAAAAF5SsKfZ6cz6GA=" + }, + "model": { + "$ref": "AAAAAAF5SsKfZqcx8QM=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": -752, + "top": -632, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 168, + "top": 1184, + "width": 102, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5SsKfZ6c0cw0=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5SsKfZ6c53s4=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5SsKfZ6c6ce4=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5SsKfZ6c7vSY=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5SsKfZ6c8vrI=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5SsKfZ6c9w5g=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5SsLOnqvSnF4=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5SsLOnqvOHTI=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsLOnqvT9Zc=", + "_parent": { + "$ref": "AAAAAAF5SsLOnqvSnF4=" + }, + "model": { + "$ref": "AAAAAAF5SsLOnqvOHTI=" + }, + "font": "Arial;13;0", + "left": 272, + "top": 1370, + "width": 46.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5SsLOnqvSnF4=" + }, + "edgePosition": 1, + "text": "+无数据" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsLOnqvUkow=", + "_parent": { + "$ref": "AAAAAAF5SsLOnqvSnF4=" + }, + "model": { + "$ref": "AAAAAAF5SsLOnqvOHTI=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 282, + "top": 1377, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5SsLOnqvSnF4=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsLOnqvVLTQ=", + "_parent": { + "$ref": "AAAAAAF5SsLOnqvSnF4=" + }, + "model": { + "$ref": "AAAAAAF5SsLOnqvOHTI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 322, + "top": 1355, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5SsLOnqvSnF4=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsLOnqvWnnM=", + "_parent": { + "$ref": "AAAAAAF5SsLOnqvSnF4=" + }, + "model": { + "$ref": "AAAAAAF5SsLOnqvP3jk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 364, + "top": 1497, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5SsLOnqvSnF4=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsLOnqvXr5I=", + "_parent": { + "$ref": "AAAAAAF5SsLOnqvSnF4=" + }, + "model": { + "$ref": "AAAAAAF5SsLOnqvP3jk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 351, + "top": 1501, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5SsLOnqvSnF4=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsLOnqvYxHA=", + "_parent": { + "$ref": "AAAAAAF5SsLOnqvSnF4=" + }, + "model": { + "$ref": "AAAAAAF5SsLOnqvP3jk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 390, + "top": 1488, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5SsLOnqvSnF4=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsLOn6vZ9lI=", + "_parent": { + "$ref": "AAAAAAF5SsLOnqvSnF4=" + }, + "model": { + "$ref": "AAAAAAF5SsLOnqvQ0Oc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 227, + "top": 1242, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5SsLOnqvSnF4=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsLOn6vaP/I=", + "_parent": { + "$ref": "AAAAAAF5SsLOnqvSnF4=" + }, + "model": { + "$ref": "AAAAAAF5SsLOnqvQ0Oc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 216, + "top": 1251, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5SsLOnqvSnF4=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsLOn6vbXrc=", + "_parent": { + "$ref": "AAAAAAF5SsLOnqvSnF4=" + }, + "model": { + "$ref": "AAAAAAF5SsLOnqvQ0Oc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 249, + "top": 1226, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5SsLOnqvSnF4=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5SsLOn6vcdQk=", + "_parent": { + "$ref": "AAAAAAF5SsLOnqvSnF4=" + }, + "model": { + "$ref": "AAAAAAF5SsLOnqvP3jk=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5SsLOn6vdxGs=", + "_parent": { + "$ref": "AAAAAAF5SsLOnqvSnF4=" + }, + "model": { + "$ref": "AAAAAAF5SsLOnqvQ0Oc=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5SsKfZ6cz6GA=" + }, + "tail": { + "$ref": "AAAAAAF5Sr+CM2cB5us=" + }, + "lineStyle": 1, + "points": "390:1519;228:1219", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5SsLOnqvT9Zc=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5SsLOnqvUkow=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5SsLOnqvVLTQ=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5SsLOnqvWnnM=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5SsLOnqvXr5I=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5SsLOnqvYxHA=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5SsLOn6vZ9lI=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5SsLOn6vaP/I=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5SsLOn6vbXrc=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5SsLOn6vcdQk=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5SsLOn6vdxGs=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5SsLnBK6bZAc=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5SsLnA66XUCE=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsLnBK6cpAA=", + "_parent": { + "$ref": "AAAAAAF5SsLnBK6bZAc=" + }, + "model": { + "$ref": "AAAAAAF5SsLnA66XUCE=" + }, + "font": "Arial;13;0", + "left": 333, + "top": 1292, + "width": 59.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5SsLnBK6bZAc=" + }, + "edgePosition": 1, + "text": "+确定删除" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsLnBK6d5AU=", + "_parent": { + "$ref": "AAAAAAF5SsLnBK6bZAc=" + }, + "model": { + "$ref": "AAAAAAF5SsLnA66XUCE=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 355, + "top": 1305, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5SsLnBK6bZAc=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsLnBK6eFBA=", + "_parent": { + "$ref": "AAAAAAF5SsLnBK6bZAc=" + }, + "model": { + "$ref": "AAAAAAF5SsLnA66XUCE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 377, + "top": 1265, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5SsLnBK6bZAc=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsLnBK6fMJY=", + "_parent": { + "$ref": "AAAAAAF5SsLnBK6bZAc=" + }, + "model": { + "$ref": "AAAAAAF5SsLnBK6Y5d4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 459, + "top": 1345, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5SsLnBK6bZAc=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsLnBK6gP4A=", + "_parent": { + "$ref": "AAAAAAF5SsLnBK6bZAc=" + }, + "model": { + "$ref": "AAAAAAF5SsLnBK6Y5d4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 450, + "top": 1356, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5SsLnBK6bZAc=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsLnBK6hs3M=", + "_parent": { + "$ref": "AAAAAAF5SsLnBK6bZAc=" + }, + "model": { + "$ref": "AAAAAAF5SsLnBK6Y5d4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 476, + "top": 1323, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5SsLnBK6bZAc=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsLnBK6ibt8=", + "_parent": { + "$ref": "AAAAAAF5SsLnBK6bZAc=" + }, + "model": { + "$ref": "AAAAAAF5SsLnBK6ZnVU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 266, + "top": 1238, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5SsLnBK6bZAc=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsLnBK6j9qo=", + "_parent": { + "$ref": "AAAAAAF5SsLnBK6bZAc=" + }, + "model": { + "$ref": "AAAAAAF5SsLnBK6ZnVU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 262, + "top": 1251, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5SsLnBK6bZAc=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsLnBK6kw2A=", + "_parent": { + "$ref": "AAAAAAF5SsLnBK6bZAc=" + }, + "model": { + "$ref": "AAAAAAF5SsLnBK6ZnVU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 275, + "top": 1212, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5SsLnBK6bZAc=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5SsLnBK6lciw=", + "_parent": { + "$ref": "AAAAAAF5SsLnBK6bZAc=" + }, + "model": { + "$ref": "AAAAAAF5SsLnBK6Y5d4=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5SsLnBK6mW+g=", + "_parent": { + "$ref": "AAAAAAF5SsLnBK6bZAc=" + }, + "model": { + "$ref": "AAAAAAF5SsLnBK6ZnVU=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5SsKfZ6cz6GA=" + }, + "tail": { + "$ref": "AAAAAAF5SsEjzYKBxwU=" + }, + "lineStyle": 1, + "points": "489:1351;251:1219", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5SsLnBK6cpAA=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5SsLnBK6d5AU=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5SsLnBK6eFBA=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5SsLnBK6fMJY=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5SsLnBK6gP4A=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5SsLnBK6hs3M=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5SsLnBK6ibt8=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5SsLnBK6j9qo=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5SsLnBK6kw2A=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5SsLnBK6lciw=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5SsLnBK6mW+g=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5Ssd41L4Ykm8=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5Ssd4074UW6o=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Ssd41L4Zqt8=", + "_parent": { + "$ref": "AAAAAAF5Ssd41L4Ykm8=" + }, + "model": { + "$ref": "AAAAAAF5Ssd4074UW6o=" + }, + "font": "Arial;13;0", + "left": 298, + "top": 715, + "width": 59.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5Ssd41L4Ykm8=" + }, + "edgePosition": 1, + "text": "+测量成功" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Ssd41L4aA68=", + "_parent": { + "$ref": "AAAAAAF5Ssd41L4Ykm8=" + }, + "model": { + "$ref": "AAAAAAF5Ssd4074UW6o=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 312, + "top": 711, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5Ssd41L4Ykm8=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Ssd41L4bzG4=", + "_parent": { + "$ref": "AAAAAAF5Ssd41L4Ykm8=" + }, + "model": { + "$ref": "AAAAAAF5Ssd4074UW6o=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 356, + "top": 722, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5Ssd41L4Ykm8=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Ssd41L4cBd0=", + "_parent": { + "$ref": "AAAAAAF5Ssd41L4Ykm8=" + }, + "model": { + "$ref": "AAAAAAF5Ssd41L4V+18=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 215, + "top": 1148, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5Ssd41L4Ykm8=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Ssd41L4dOJQ=", + "_parent": { + "$ref": "AAAAAAF5Ssd41L4Ykm8=" + }, + "model": { + "$ref": "AAAAAAF5Ssd41L4V+18=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 202, + "top": 1142, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5Ssd41L4Ykm8=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Ssd41L4eN6A=", + "_parent": { + "$ref": "AAAAAAF5Ssd41L4Ykm8=" + }, + "model": { + "$ref": "AAAAAAF5Ssd41L4V+18=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 240, + "top": 1159, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5Ssd41L4Ykm8=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Ssd41L4fb84=", + "_parent": { + "$ref": "AAAAAAF5Ssd41L4Ykm8=" + }, + "model": { + "$ref": "AAAAAAF5Ssd41L4WIjg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 440, + "top": 282, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5Ssd41L4Ykm8=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Ssd41L4gSW0=", + "_parent": { + "$ref": "AAAAAAF5Ssd41L4Ykm8=" + }, + "model": { + "$ref": "AAAAAAF5Ssd41L4WIjg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 427, + "top": 281, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5Ssd41L4Ykm8=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Ssd41L4hw20=", + "_parent": { + "$ref": "AAAAAAF5Ssd41L4Ykm8=" + }, + "model": { + "$ref": "AAAAAAF5Ssd41L4WIjg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 468, + "top": 285, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5Ssd41L4Ykm8=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5Ssd41L4iA10=", + "_parent": { + "$ref": "AAAAAAF5Ssd41L4Ykm8=" + }, + "model": { + "$ref": "AAAAAAF5Ssd41L4V+18=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5Ssd41L4jXng=", + "_parent": { + "$ref": "AAAAAAF5Ssd41L4Ykm8=" + }, + "model": { + "$ref": "AAAAAAF5Ssd41L4WIjg=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QJ6ahiPXyXI=" + }, + "tail": { + "$ref": "AAAAAAF5SsKfZ6cz6GA=" + }, + "lineStyle": 1, + "points": "223:1183;462:267", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5Ssd41L4Zqt8=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5Ssd41L4aA68=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5Ssd41L4bzG4=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5Ssd41L4cBd0=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5Ssd41L4dOJQ=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5Ssd41L4eN6A=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5Ssd41L4fb84=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5Ssd41L4gSW0=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5Ssd41L4hw20=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5Ssd41L4iA10=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5Ssd41L4jXng=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5Sseu4cD3uPk=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5Sseu4cD1ALY=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5Sseu4cD4dEc=", + "_parent": { + "$ref": "AAAAAAF5Sseu4cD3uPk=" + }, + "model": { + "$ref": "AAAAAAF5Sseu4cD1ALY=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5Sseu4sD5D+g=", + "_parent": { + "$ref": "AAAAAAF5Sseu4cD4dEc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1472, + "top": -1600, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5Sseu4sD6WNI=", + "_parent": { + "$ref": "AAAAAAF5Sseu4cD4dEc=" + }, + "font": "Arial;13;1", + "left": 340, + "top": 1067.5, + "width": 98, + "height": 13, + "text": "SurveyorFailure" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5Sseu4sD7TeQ=", + "_parent": { + "$ref": "AAAAAAF5Sseu4cD4dEc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1472, + "top": -1600, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5Sseu4sD8OGM=", + "_parent": { + "$ref": "AAAAAAF5Sseu4cD4dEc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1472, + "top": -1600, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 335, + "top": 1060.5, + "width": 108.9853515625, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5Sseu4sD5D+g=" + }, + "nameLabel": { + "$ref": "AAAAAAF5Sseu4sD6WNI=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5Sseu4sD7TeQ=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5Sseu4sD8OGM=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5Sseu4sD98rM=", + "_parent": { + "$ref": "AAAAAAF5Sseu4cD3uPk=" + }, + "model": { + "$ref": "AAAAAAF5Sseu4cD1ALY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -736, + "top": -800, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5Sseu4sD+mh8=", + "_parent": { + "$ref": "AAAAAAF5Sseu4cD3uPk=" + }, + "model": { + "$ref": "AAAAAAF5Sseu4cD1ALY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -736, + "top": -800, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5Sseu4sD/yw4=", + "_parent": { + "$ref": "AAAAAAF5Sseu4cD3uPk=" + }, + "model": { + "$ref": "AAAAAAF5Sseu4cD1ALY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -736, + "top": -800, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5Sseu4sEAhqQ=", + "_parent": { + "$ref": "AAAAAAF5Sseu4cD3uPk=" + }, + "model": { + "$ref": "AAAAAAF5Sseu4cD1ALY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -736, + "top": -800, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5Sseu4sEB2Lc=", + "_parent": { + "$ref": "AAAAAAF5Sseu4cD3uPk=" + }, + "model": { + "$ref": "AAAAAAF5Sseu4cD1ALY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -736, + "top": -800, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 312, + "top": 1056, + "width": 154, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5Sseu4cD4dEc=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5Sseu4sD98rM=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5Sseu4sD+mh8=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5Sseu4sD/yw4=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5Sseu4sEAhqQ=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5Sseu4sEB2Lc=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5SsfL8MfWulU=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5SsfL78fSWbs=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsfL8MfXyQI=", + "_parent": { + "$ref": "AAAAAAF5SsfL8MfWulU=" + }, + "model": { + "$ref": "AAAAAAF5SsfL78fSWbs=" + }, + "font": "Arial;13;0", + "left": 264, + "top": 1119, + "width": 59.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5SsfL8MfWulU=" + }, + "edgePosition": 1, + "text": "+测量失败" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsfL8MfYdR0=", + "_parent": { + "$ref": "AAAAAAF5SsfL8MfWulU=" + }, + "model": { + "$ref": "AAAAAAF5SsfL78fSWbs=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 284, + "top": 1107, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5SsfL8MfWulU=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsfL8MfZubw=", + "_parent": { + "$ref": "AAAAAAF5SsfL8MfWulU=" + }, + "model": { + "$ref": "AAAAAAF5SsfL78fSWbs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 312, + "top": 1142, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5SsfL8MfWulU=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsfL8MfaQ2g=", + "_parent": { + "$ref": "AAAAAAF5SsfL8MfWulU=" + }, + "model": { + "$ref": "AAAAAAF5SsfL78fTiS4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 253, + "top": 1149, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5SsfL8MfWulU=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsfL8MfbsfE=", + "_parent": { + "$ref": "AAAAAAF5SsfL8MfWulU=" + }, + "model": { + "$ref": "AAAAAAF5SsfL78fTiS4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 247, + "top": 1137, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5SsfL8MfWulU=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsfL8MfcKqA=", + "_parent": { + "$ref": "AAAAAAF5SsfL8MfWulU=" + }, + "model": { + "$ref": "AAAAAAF5SsfL78fTiS4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 266, + "top": 1173, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5SsfL8MfWulU=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsfL8MfdMu0=", + "_parent": { + "$ref": "AAAAAAF5SsfL8MfWulU=" + }, + "model": { + "$ref": "AAAAAAF5SsfL78fU9Fc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 334, + "top": 1088, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5SsfL8MfWulU=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsfL8MfexH0=", + "_parent": { + "$ref": "AAAAAAF5SsfL8MfWulU=" + }, + "model": { + "$ref": "AAAAAAF5SsfL78fU9Fc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 324, + "top": 1079, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5SsfL8MfWulU=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsfL8MffFqI=", + "_parent": { + "$ref": "AAAAAAF5SsfL8MfWulU=" + }, + "model": { + "$ref": "AAAAAAF5SsfL78fU9Fc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 354, + "top": 1108, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5SsfL8MfWulU=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5SsfL8Mfg/Q0=", + "_parent": { + "$ref": "AAAAAAF5SsfL8MfWulU=" + }, + "model": { + "$ref": "AAAAAAF5SsfL78fTiS4=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5SsfL8MfhnlI=", + "_parent": { + "$ref": "AAAAAAF5SsfL8MfWulU=" + }, + "model": { + "$ref": "AAAAAAF5SsfL78fU9Fc=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5Sseu4cD3uPk=" + }, + "tail": { + "$ref": "AAAAAAF5SsKfZ6cz6GA=" + }, + "lineStyle": 1, + "points": "242:1183;364:1091", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5SsfL8MfXyQI=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5SsfL8MfYdR0=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5SsfL8MfZubw=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5SsfL8MfaQ2g=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5SsfL8MfbsfE=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5SsfL8MfcKqA=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5SsfL8MfdMu0=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5SsfL8MfexH0=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5SsfL8MffFqI=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5SsfL8Mfg/Q0=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5SsfL8MfhnlI=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5Sst98wwqqgM=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5Sst98gwopLY=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5Sst98wwrk5U=", + "_parent": { + "$ref": "AAAAAAF5Sst98wwqqgM=" + }, + "model": { + "$ref": "AAAAAAF5Sst98gwopLY=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5Sst98wwsBT0=", + "_parent": { + "$ref": "AAAAAAF5Sst98wwrk5U=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 48, + "top": -160, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5Sst98wwtbtQ=", + "_parent": { + "$ref": "AAAAAAF5Sst98wwrk5U=" + }, + "fillColor": "#ffff91", + "font": "Arial;13;1", + "left": 1652, + "top": 51.5, + "width": 62, + "height": 13, + "text": "是否闭合" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5Sst98wwumLc=", + "_parent": { + "$ref": "AAAAAAF5Sst98wwrk5U=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 48, + "top": -160, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5Sst98wwvQ7M=", + "_parent": { + "$ref": "AAAAAAF5Sst98wwrk5U=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 48, + "top": -160, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 1647, + "top": 44.5, + "width": 72, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5Sst98wwsBT0=" + }, + "nameLabel": { + "$ref": "AAAAAAF5Sst98wwtbtQ=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5Sst98wwumLc=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5Sst98wwvQ7M=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5Sst98www8Oc=", + "_parent": { + "$ref": "AAAAAAF5Sst98wwqqgM=" + }, + "model": { + "$ref": "AAAAAAF5Sst98gwopLY=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 24, + "top": -80, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5Sst98wwx3u0=", + "_parent": { + "$ref": "AAAAAAF5Sst98wwqqgM=" + }, + "model": { + "$ref": "AAAAAAF5Sst98gwopLY=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 24, + "top": -80, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5Sst98wwya8E=", + "_parent": { + "$ref": "AAAAAAF5Sst98wwqqgM=" + }, + "model": { + "$ref": "AAAAAAF5Sst98gwopLY=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 24, + "top": -80, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5Sst98wwzlK8=", + "_parent": { + "$ref": "AAAAAAF5Sst98wwqqgM=" + }, + "model": { + "$ref": "AAAAAAF5Sst98gwopLY=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 24, + "top": -80, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5Sst98ww0Wjc=", + "_parent": { + "$ref": "AAAAAAF5Sst98wwqqgM=" + }, + "model": { + "$ref": "AAAAAAF5Sst98gwopLY=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 24, + "top": -80, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 1632, + "top": 40, + "width": 102, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5Sst98wwrk5U=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5Sst98www8Oc=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5Sst98wwx3u0=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5Sst98wwya8E=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5Sst98wwzlK8=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5Sst98ww0Wjc=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5SsvDEBJ5KNQ=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5SsvDEBJ10hk=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsvDEBJ65LU=", + "_parent": { + "$ref": "AAAAAAF5SsvDEBJ5KNQ=" + }, + "model": { + "$ref": "AAAAAAF5SsvDEBJ10hk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1525, + "top": 68, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5SsvDEBJ5KNQ=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsvDEBJ7LZg=", + "_parent": { + "$ref": "AAAAAAF5SsvDEBJ5KNQ=" + }, + "model": { + "$ref": "AAAAAAF5SsvDEBJ10hk=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1522, + "top": 53, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5SsvDEBJ5KNQ=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsvDEBJ8W1Y=", + "_parent": { + "$ref": "AAAAAAF5SsvDEBJ5KNQ=" + }, + "model": { + "$ref": "AAAAAAF5SsvDEBJ10hk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1530, + "top": 97, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5SsvDEBJ5KNQ=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsvDEBJ9rec=", + "_parent": { + "$ref": "AAAAAAF5SsvDEBJ5KNQ=" + }, + "model": { + "$ref": "AAAAAAF5SsvDEBJ2t9o=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1447, + "top": 85, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5SsvDEBJ5KNQ=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsvDEBJ+YlY=", + "_parent": { + "$ref": "AAAAAAF5SsvDEBJ5KNQ=" + }, + "model": { + "$ref": "AAAAAAF5SsvDEBJ2t9o=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1446, + "top": 71, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5SsvDEBJ5KNQ=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsvDEBJ/9rs=", + "_parent": { + "$ref": "AAAAAAF5SsvDEBJ5KNQ=" + }, + "model": { + "$ref": "AAAAAAF5SsvDEBJ2t9o=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1448, + "top": 112, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5SsvDEBJ5KNQ=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsvDEBKANc8=", + "_parent": { + "$ref": "AAAAAAF5SsvDEBJ5KNQ=" + }, + "model": { + "$ref": "AAAAAAF5SsvDEBJ3GSY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1602, + "top": 52, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5SsvDEBJ5KNQ=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsvDEBKBIh8=", + "_parent": { + "$ref": "AAAAAAF5SsvDEBJ5KNQ=" + }, + "model": { + "$ref": "AAAAAAF5SsvDEBJ3GSY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1597, + "top": 40, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5SsvDEBJ5KNQ=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsvDERKCEpk=", + "_parent": { + "$ref": "AAAAAAF5SsvDEBJ5KNQ=" + }, + "model": { + "$ref": "AAAAAAF5SsvDEBJ3GSY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1612, + "top": 78, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5SsvDEBJ5KNQ=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5SsvDERKDUNc=", + "_parent": { + "$ref": "AAAAAAF5SsvDEBJ5KNQ=" + }, + "model": { + "$ref": "AAAAAAF5SsvDEBJ2t9o=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5SsvDERKE66g=", + "_parent": { + "$ref": "AAAAAAF5SsvDEBJ5KNQ=" + }, + "model": { + "$ref": "AAAAAAF5SsvDEBJ3GSY=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5Sst98wwqqgM=" + }, + "tail": { + "$ref": "AAAAAAF5QJ8m8Sf6ofY=" + }, + "lineStyle": 1, + "points": "1425:111;1631:68", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5SsvDEBJ65LU=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5SsvDEBJ7LZg=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5SsvDEBJ8W1Y=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5SsvDEBJ9rec=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5SsvDEBJ+YlY=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5SsvDEBJ/9rs=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5SsvDEBKANc8=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5SsvDEBKBIh8=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5SsvDERKCEpk=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5SsvDERKDUNc=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5SsvDERKE66g=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5Ssw/NBbRxlk=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5Ssw/MxbPNVc=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5Ssw/NBbSF2M=", + "_parent": { + "$ref": "AAAAAAF5Ssw/NBbRxlk=" + }, + "model": { + "$ref": "AAAAAAF5Ssw/MxbPNVc=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5Ssw/NBbTP+M=", + "_parent": { + "$ref": "AAAAAAF5Ssw/NBbSF2M=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1440, + "top": 192, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5Ssw/NBbUxMs=", + "_parent": { + "$ref": "AAAAAAF5Ssw/NBbSF2M=" + }, + "font": "Arial;13;1", + "left": 1249, + "top": 251.5, + "width": 124, + "height": 13, + "text": "checkHalfCycleZero" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5Ssw/NBbVQpo=", + "_parent": { + "$ref": "AAAAAAF5Ssw/NBbSF2M=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1440, + "top": 192, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5Ssw/NBbW1cU=", + "_parent": { + "$ref": "AAAAAAF5Ssw/NBbSF2M=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1440, + "top": 192, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 1244, + "top": 244.5, + "width": 134.28076171875, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5Ssw/NBbTP+M=" + }, + "nameLabel": { + "$ref": "AAAAAAF5Ssw/NBbUxMs=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5Ssw/NBbVQpo=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5Ssw/NBbW1cU=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5Ssw/NBbXko4=", + "_parent": { + "$ref": "AAAAAAF5Ssw/NBbRxlk=" + }, + "model": { + "$ref": "AAAAAAF5Ssw/MxbPNVc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -720, + "top": 96, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5Ssw/NBbYUF0=", + "_parent": { + "$ref": "AAAAAAF5Ssw/NBbRxlk=" + }, + "model": { + "$ref": "AAAAAAF5Ssw/MxbPNVc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -720, + "top": 96, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5Ssw/NBbZSlY=", + "_parent": { + "$ref": "AAAAAAF5Ssw/NBbRxlk=" + }, + "model": { + "$ref": "AAAAAAF5Ssw/MxbPNVc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -720, + "top": 96, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5Ssw/NBbaO/g=", + "_parent": { + "$ref": "AAAAAAF5Ssw/NBbRxlk=" + }, + "model": { + "$ref": "AAAAAAF5Ssw/MxbPNVc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -720, + "top": 96, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5Ssw/NBbbK8k=", + "_parent": { + "$ref": "AAAAAAF5Ssw/NBbRxlk=" + }, + "model": { + "$ref": "AAAAAAF5Ssw/MxbPNVc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -720, + "top": 96, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 1216, + "top": 240, + "width": 190, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5Ssw/NBbSF2M=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5Ssw/NBbXko4=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5Ssw/NBbYUF0=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5Ssw/NBbZSlY=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5Ssw/NBbaO/g=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5Ssw/NBbbK8k=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5SsxY9RsnmvY=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5SsxY9BsjL0w=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsxY9Rso3zw=", + "_parent": { + "$ref": "AAAAAAF5SsxY9RsnmvY=" + }, + "model": { + "$ref": "AAAAAAF5SsxY9BsjL0w=" + }, + "font": "Arial;13;0", + "left": 1493, + "top": 164, + "width": 20.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5SsxY9RsnmvY=" + }, + "edgePosition": 1, + "text": "+否" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsxY9RspvS0=", + "_parent": { + "$ref": "AAAAAAF5SsxY9RsnmvY=" + }, + "model": { + "$ref": "AAAAAAF5SsxY9BsjL0w=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1510, + "top": 177, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5SsxY9RsnmvY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsxY9Rsq3L8=", + "_parent": { + "$ref": "AAAAAAF5SsxY9RsnmvY=" + }, + "model": { + "$ref": "AAAAAAF5SsxY9BsjL0w=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1488, + "top": 137, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5SsxY9RsnmvY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsxY9Rsrf8M=", + "_parent": { + "$ref": "AAAAAAF5SsxY9RsnmvY=" + }, + "model": { + "$ref": "AAAAAAF5SsxY9BskgpI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1633, + "top": 94, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5SsxY9RsnmvY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsxY9RssvXQ=", + "_parent": { + "$ref": "AAAAAAF5SsxY9RsnmvY=" + }, + "model": { + "$ref": "AAAAAAF5SsxY9BskgpI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1637, + "top": 107, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5SsxY9RsnmvY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsxY9Rstlgw=", + "_parent": { + "$ref": "AAAAAAF5SsxY9RsnmvY=" + }, + "model": { + "$ref": "AAAAAAF5SsxY9BskgpI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1624, + "top": 68, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5SsxY9RsnmvY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsxY9RsuHms=", + "_parent": { + "$ref": "AAAAAAF5SsxY9RsnmvY=" + }, + "model": { + "$ref": "AAAAAAF5SsxY9Bsl5Tg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1372, + "top": 233, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5SsxY9RsnmvY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsxY9RsvAmg=", + "_parent": { + "$ref": "AAAAAAF5SsxY9RsnmvY=" + }, + "model": { + "$ref": "AAAAAAF5SsxY9Bsl5Tg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1381, + "top": 244, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5SsxY9RsnmvY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SsxY9RswFu4=", + "_parent": { + "$ref": "AAAAAAF5SsxY9RsnmvY=" + }, + "model": { + "$ref": "AAAAAAF5SsxY9Bsl5Tg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1356, + "top": 211, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5SsxY9RsnmvY=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5SsxY9Rsx3zc=", + "_parent": { + "$ref": "AAAAAAF5SsxY9RsnmvY=" + }, + "model": { + "$ref": "AAAAAAF5SsxY9BskgpI=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5SsxY9Rsy0lU=", + "_parent": { + "$ref": "AAAAAAF5SsxY9RsnmvY=" + }, + "model": { + "$ref": "AAAAAAF5SsxY9Bsl5Tg=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5Ssw/NBbRxlk=" + }, + "tail": { + "$ref": "AAAAAAF5Sst98wwqqgM=" + }, + "lineStyle": 1, + "points": "1649:75;1343:239", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5SsxY9Rso3zw=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5SsxY9RspvS0=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5SsxY9Rsq3L8=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5SsxY9Rsrf8M=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5SsxY9RssvXQ=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5SsxY9Rstlgw=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5SsxY9RsuHms=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5SsxY9RsvAmg=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5SsxY9RswFu4=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5SsxY9Rsx3zc=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5SsxY9Rsy0lU=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5SsyaiR+SygU=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5SsyaiR+Q8s8=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5SsyaiR+Tni4=", + "_parent": { + "$ref": "AAAAAAF5SsyaiR+SygU=" + }, + "model": { + "$ref": "AAAAAAF5SsyaiR+Q8s8=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5SsyaiR+UDd8=", + "_parent": { + "$ref": "AAAAAAF5SsyaiR+Tni4=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 256, + "top": -288, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5SsyaiR+VLzI=", + "_parent": { + "$ref": "AAAAAAF5SsyaiR+Tni4=" + }, + "fillColor": "#ffff91", + "font": "Arial;13;1", + "left": 1775.5, + "top": 147.5, + "width": 77, + "height": 13, + "text": "执行归零检测" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5SsyaiR+WGNM=", + "_parent": { + "$ref": "AAAAAAF5SsyaiR+Tni4=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 256, + "top": -288, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5SsyaiR+XOgU=", + "_parent": { + "$ref": "AAAAAAF5SsyaiR+Tni4=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 256, + "top": -288, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 1770.5, + "top": 140.5, + "width": 88, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5SsyaiR+UDd8=" + }, + "nameLabel": { + "$ref": "AAAAAAF5SsyaiR+VLzI=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5SsyaiR+WGNM=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5SsyaiR+XOgU=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5SsyaiR+YmEc=", + "_parent": { + "$ref": "AAAAAAF5SsyaiR+SygU=" + }, + "model": { + "$ref": "AAAAAAF5SsyaiR+Q8s8=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 128, + "top": -144, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5SsyaiR+ZFcg=", + "_parent": { + "$ref": "AAAAAAF5SsyaiR+SygU=" + }, + "model": { + "$ref": "AAAAAAF5SsyaiR+Q8s8=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 128, + "top": -144, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5SsyaiR+aG70=", + "_parent": { + "$ref": "AAAAAAF5SsyaiR+SygU=" + }, + "model": { + "$ref": "AAAAAAF5SsyaiR+Q8s8=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 128, + "top": -144, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5SsyaiR+bvEY=", + "_parent": { + "$ref": "AAAAAAF5SsyaiR+SygU=" + }, + "model": { + "$ref": "AAAAAAF5SsyaiR+Q8s8=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 128, + "top": -144, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5SsyaiR+c1cI=", + "_parent": { + "$ref": "AAAAAAF5SsyaiR+SygU=" + }, + "model": { + "$ref": "AAAAAAF5SsyaiR+Q8s8=" + }, + "visible": false, + "fillColor": "#ffff91", + "font": "Arial;13;0", + "left": 128, + "top": -144, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ffff91", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 1752, + "top": 136, + "width": 124, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5SsyaiR+Tni4=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5SsyaiR+YmEc=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5SsyaiR+ZFcg=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5SsyaiR+aG70=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5SsyaiR+bvEY=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5SsyaiR+c1cI=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5SszpXCjo1EY=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5SszpXCjkGRI=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SszpXCjpTBg=", + "_parent": { + "$ref": "AAAAAAF5SszpXCjo1EY=" + }, + "model": { + "$ref": "AAAAAAF5SszpXCjkGRI=" + }, + "font": "Arial;13;0", + "left": 1745, + "top": 86, + "width": 20.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5SszpXCjo1EY=" + }, + "edgePosition": 1, + "text": "+是" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SszpXCjqUQ0=", + "_parent": { + "$ref": "AAAAAAF5SszpXCjo1EY=" + }, + "model": { + "$ref": "AAAAAAF5SszpXCjkGRI=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1764, + "top": 74, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5SszpXCjo1EY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SszpXSjrtE4=", + "_parent": { + "$ref": "AAAAAAF5SszpXCjo1EY=" + }, + "model": { + "$ref": "AAAAAAF5SszpXCjkGRI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1738, + "top": 111, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5SszpXCjo1EY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SszpXSjsrPY=", + "_parent": { + "$ref": "AAAAAAF5SszpXCjo1EY=" + }, + "model": { + "$ref": "AAAAAAF5SszpXCjl/+8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1736, + "top": 72, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5SszpXCjo1EY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SszpXSjtl3A=", + "_parent": { + "$ref": "AAAAAAF5SszpXCjo1EY=" + }, + "model": { + "$ref": "AAAAAAF5SszpXCjl/+8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1746, + "top": 63, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5SszpXCjo1EY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SszpXSjuzIY=", + "_parent": { + "$ref": "AAAAAAF5SszpXCjo1EY=" + }, + "model": { + "$ref": "AAAAAAF5SszpXCjl/+8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1716, + "top": 91, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5SszpXCjo1EY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SszpXSjvn8g=", + "_parent": { + "$ref": "AAAAAAF5SszpXCjo1EY=" + }, + "model": { + "$ref": "AAAAAAF5SszpXCjmncs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1776, + "top": 101, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5SszpXCjo1EY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SszpXSjwGS4=", + "_parent": { + "$ref": "AAAAAAF5SszpXCjo1EY=" + }, + "model": { + "$ref": "AAAAAAF5SszpXCjmncs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1782, + "top": 89, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5SszpXCjo1EY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5SszpXSjx7DE=", + "_parent": { + "$ref": "AAAAAAF5SszpXCjo1EY=" + }, + "model": { + "$ref": "AAAAAAF5SszpXCjmncs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1763, + "top": 126, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5SszpXCjo1EY=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5SszpXSjytaQ=", + "_parent": { + "$ref": "AAAAAAF5SszpXCjo1EY=" + }, + "model": { + "$ref": "AAAAAAF5SszpXCjl/+8=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5SszpXSjzLNw=", + "_parent": { + "$ref": "AAAAAAF5SszpXCjo1EY=" + }, + "model": { + "$ref": "AAAAAAF5SszpXCjmncs=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5SsyaiR+SygU=" + }, + "tail": { + "$ref": "AAAAAAF5Sst98wwqqgM=" + }, + "lineStyle": 1, + "points": "1707:75;1788:135", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5SszpXCjpTBg=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5SszpXCjqUQ0=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5SszpXSjrtE4=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5SszpXSjsrPY=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5SszpXSjtl3A=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5SszpXSjuzIY=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5SszpXSjvn8g=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5SszpXSjwGS4=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5SszpXSjx7DE=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5SszpXSjytaQ=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5SszpXSjzLNw=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5Ss0jcC4eMnU=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5Ss0jcC4aijg=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Ss0jcC4f1SI=", + "_parent": { + "$ref": "AAAAAAF5Ss0jcC4eMnU=" + }, + "model": { + "$ref": "AAAAAAF5Ss0jcC4aijg=" + }, + "font": "Arial;13;0", + "left": 1561, + "top": 210, + "width": 33.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5Ss0jcC4eMnU=" + }, + "edgePosition": 1, + "text": "+成功" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Ss0jcC4gpjw=", + "_parent": { + "$ref": "AAAAAAF5Ss0jcC4eMnU=" + }, + "model": { + "$ref": "AAAAAAF5Ss0jcC4aijg=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1580, + "top": 225, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5Ss0jcC4eMnU=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Ss0jcC4hyOQ=", + "_parent": { + "$ref": "AAAAAAF5Ss0jcC4eMnU=" + }, + "model": { + "$ref": "AAAAAAF5Ss0jcC4aijg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1570, + "top": 181, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5Ss0jcC4eMnU=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Ss0jcC4ik1U=", + "_parent": { + "$ref": "AAAAAAF5Ss0jcC4eMnU=" + }, + "model": { + "$ref": "AAAAAAF5Ss0jcC4bSQM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1728, + "top": 179, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5Ss0jcC4eMnU=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Ss0jcC4j7WE=", + "_parent": { + "$ref": "AAAAAAF5Ss0jcC4eMnU=" + }, + "model": { + "$ref": "AAAAAAF5Ss0jcC4bSQM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1729, + "top": 193, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5Ss0jcC4eMnU=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Ss0jcC4kJQ0=", + "_parent": { + "$ref": "AAAAAAF5Ss0jcC4eMnU=" + }, + "model": { + "$ref": "AAAAAAF5Ss0jcC4bSQM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1727, + "top": 152, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5Ss0jcC4eMnU=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Ss0jcC4lZO0=", + "_parent": { + "$ref": "AAAAAAF5Ss0jcC4eMnU=" + }, + "model": { + "$ref": "AAAAAAF5Ss0jcC4cI98=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1425, + "top": 242, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5Ss0jcC4eMnU=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Ss0jcC4mJoI=", + "_parent": { + "$ref": "AAAAAAF5Ss0jcC4eMnU=" + }, + "model": { + "$ref": "AAAAAAF5Ss0jcC4cI98=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1430, + "top": 254, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5Ss0jcC4eMnU=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Ss0jcC4nP2o=", + "_parent": { + "$ref": "AAAAAAF5Ss0jcC4eMnU=" + }, + "model": { + "$ref": "AAAAAAF5Ss0jcC4cI98=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1415, + "top": 216, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5Ss0jcC4eMnU=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5Ss0jcC4oHMs=", + "_parent": { + "$ref": "AAAAAAF5Ss0jcC4eMnU=" + }, + "model": { + "$ref": "AAAAAAF5Ss0jcC4bSQM=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5Ss0jcC4pyOo=", + "_parent": { + "$ref": "AAAAAAF5Ss0jcC4eMnU=" + }, + "model": { + "$ref": "AAAAAAF5Ss0jcC4cI98=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5Ssw/NBbRxlk=" + }, + "tail": { + "$ref": "AAAAAAF5SsyaiR+SygU=" + }, + "lineStyle": 1, + "points": "1751:166;1397:239", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5Ss0jcC4f1SI=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5Ss0jcC4gpjw=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5Ss0jcC4hyOQ=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5Ss0jcC4ik1U=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5Ss0jcC4j7WE=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5Ss0jcC4kJQ0=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5Ss0jcC4lZO0=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5Ss0jcC4mJoI=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5Ss0jcC4nP2o=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5Ss0jcC4oHMs=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5Ss0jcC4pyOo=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5Ss1QmDKthXI=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5Ss1QlzKrDlo=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5Ss1QmDKuZC4=", + "_parent": { + "$ref": "AAAAAAF5Ss1QmDKthXI=" + }, + "model": { + "$ref": "AAAAAAF5Ss1QlzKrDlo=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5Ss1QmDKvWlI=", + "_parent": { + "$ref": "AAAAAAF5Ss1QmDKuZC4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -240, + "top": 80, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5Ss1QmDKwG90=", + "_parent": { + "$ref": "AAAAAAF5Ss1QmDKuZC4=" + }, + "font": "Arial;13;1", + "left": 1805, + "top": 379.5, + "width": 105, + "height": 13, + "text": "isReady2CCheck" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5Ss1QmDKxdQY=", + "_parent": { + "$ref": "AAAAAAF5Ss1QmDKuZC4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -240, + "top": 80, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5Ss1QmDKy1Jk=", + "_parent": { + "$ref": "AAAAAAF5Ss1QmDKuZC4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -240, + "top": 80, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 1800, + "top": 372.5, + "width": 115.498046875, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5Ss1QmDKvWlI=" + }, + "nameLabel": { + "$ref": "AAAAAAF5Ss1QmDKwG90=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5Ss1QmDKxdQY=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5Ss1QmDKy1Jk=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5Ss1QmDKzPd4=", + "_parent": { + "$ref": "AAAAAAF5Ss1QmDKthXI=" + }, + "model": { + "$ref": "AAAAAAF5Ss1QlzKrDlo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -120, + "top": 40, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5Ss1QmDK0rgM=", + "_parent": { + "$ref": "AAAAAAF5Ss1QmDKthXI=" + }, + "model": { + "$ref": "AAAAAAF5Ss1QlzKrDlo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -120, + "top": 40, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5Ss1QmDK1URs=", + "_parent": { + "$ref": "AAAAAAF5Ss1QmDKthXI=" + }, + "model": { + "$ref": "AAAAAAF5Ss1QlzKrDlo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -120, + "top": 40, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5Ss1QmDK27BM=", + "_parent": { + "$ref": "AAAAAAF5Ss1QmDKthXI=" + }, + "model": { + "$ref": "AAAAAAF5Ss1QlzKrDlo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -120, + "top": 40, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5Ss1QmTK3KzQ=", + "_parent": { + "$ref": "AAAAAAF5Ss1QmDKthXI=" + }, + "model": { + "$ref": "AAAAAAF5Ss1QlzKrDlo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -120, + "top": 40, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 1776, + "top": 368, + "width": 163, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5Ss1QmDKuZC4=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5Ss1QmDKzPd4=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5Ss1QmDK0rgM=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5Ss1QmDK1URs=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5Ss1QmDK27BM=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5Ss1QmTK3KzQ=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5Ss1sYzc57Aw=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5Ss1sYzc1nBg=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Ss1sYzc6gkg=", + "_parent": { + "$ref": "AAAAAAF5Ss1sYzc57Aw=" + }, + "model": { + "$ref": "AAAAAAF5Ss1sYzc1nBg=" + }, + "font": "Arial;13;0", + "left": 1826, + "top": 260, + "width": 46.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5Ss1sYzc57Aw=" + }, + "edgePosition": 1, + "text": "+未成功" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Ss1sYzc7Ydc=", + "_parent": { + "$ref": "AAAAAAF5Ss1sYzc57Aw=" + }, + "model": { + "$ref": "AAAAAAF5Ss1sYzc1nBg=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1864, + "top": 257, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5Ss1sYzc57Aw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Ss1sYzc8aaQ=", + "_parent": { + "$ref": "AAAAAAF5Ss1sYzc57Aw=" + }, + "model": { + "$ref": "AAAAAAF5Ss1sYzc1nBg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1820, + "top": 265, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5Ss1sYzc57Aw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Ss1sYzc9oVQ=", + "_parent": { + "$ref": "AAAAAAF5Ss1sYzc57Aw=" + }, + "model": { + "$ref": "AAAAAAF5Ss1sYzc28DU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1835, + "top": 187, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5Ss1sYzc57Aw=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Ss1sYzc+1mo=", + "_parent": { + "$ref": "AAAAAAF5Ss1sYzc57Aw=" + }, + "model": { + "$ref": "AAAAAAF5Ss1sYzc28DU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1849, + "top": 187, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5Ss1sYzc57Aw=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Ss1sYzc/qfo=", + "_parent": { + "$ref": "AAAAAAF5Ss1sYzc57Aw=" + }, + "model": { + "$ref": "AAAAAAF5Ss1sYzc28DU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1807, + "top": 188, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5Ss1sYzc57Aw=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Ss1sYzdAwEk=", + "_parent": { + "$ref": "AAAAAAF5Ss1sYzc57Aw=" + }, + "model": { + "$ref": "AAAAAAF5Ss1sYzc3JbA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1863, + "top": 332, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5Ss1sYzc57Aw=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Ss1sYzdBh5I=", + "_parent": { + "$ref": "AAAAAAF5Ss1sYzc57Aw=" + }, + "model": { + "$ref": "AAAAAAF5Ss1sYzc3JbA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1876, + "top": 327, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5Ss1sYzc57Aw=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Ss1sYzdCSbM=", + "_parent": { + "$ref": "AAAAAAF5Ss1sYzc57Aw=" + }, + "model": { + "$ref": "AAAAAAF5Ss1sYzc3JbA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1837, + "top": 342, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5Ss1sYzc57Aw=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5Ss1sYzdDZ80=", + "_parent": { + "$ref": "AAAAAAF5Ss1sYzc57Aw=" + }, + "model": { + "$ref": "AAAAAAF5Ss1sYzc28DU=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5Ss1sYzdEJ2M=", + "_parent": { + "$ref": "AAAAAAF5Ss1sYzc57Aw=" + }, + "model": { + "$ref": "AAAAAAF5Ss1sYzc3JbA=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5Ss1QmDKthXI=" + }, + "tail": { + "$ref": "AAAAAAF5SsyaiR+SygU=" + }, + "lineStyle": 1, + "points": "1816:171;1854:367", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5Ss1sYzc6gkg=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5Ss1sYzc7Ydc=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5Ss1sYzc8aaQ=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5Ss1sYzc9oVQ=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5Ss1sYzc+1mo=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5Ss1sYzc/qfo=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5Ss1sYzdAwEk=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5Ss1sYzdBh5I=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5Ss1sYzdCSbM=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5Ss1sYzdDZ80=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5Ss1sYzdEJ2M=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5StBNjXab2vs=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5StBNjXaXraA=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StBNjnack3k=", + "_parent": { + "$ref": "AAAAAAF5StBNjXab2vs=" + }, + "model": { + "$ref": "AAAAAAF5StBNjXaXraA=" + }, + "font": "Arial;13;0", + "left": 2070, + "top": 347, + "width": 59.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5StBNjXab2vs=" + }, + "edgePosition": 1, + "text": "+满足条件" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StBNjnadVQY=", + "_parent": { + "$ref": "AAAAAAF5StBNjXab2vs=" + }, + "model": { + "$ref": "AAAAAAF5StBNjXaXraA=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 2098, + "top": 332, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5StBNjXab2vs=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StBNjnaesNQ=", + "_parent": { + "$ref": "AAAAAAF5StBNjXab2vs=" + }, + "model": { + "$ref": "AAAAAAF5StBNjXaXraA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2102, + "top": 376, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5StBNjXab2vs=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StBNjnafXzY=", + "_parent": { + "$ref": "AAAAAAF5StBNjXab2vs=" + }, + "model": { + "$ref": "AAAAAAF5StBNjXaYthc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1963, + "top": 356, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5StBNjXab2vs=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StBNjnagLn4=", + "_parent": { + "$ref": "AAAAAAF5StBNjXab2vs=" + }, + "model": { + "$ref": "AAAAAAF5StBNjXaYthc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1965, + "top": 342, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5StBNjXab2vs=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StBNjnah5RQ=", + "_parent": { + "$ref": "AAAAAAF5StBNjXab2vs=" + }, + "model": { + "$ref": "AAAAAAF5StBNjXaYthc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1961, + "top": 384, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5StBNjXab2vs=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StBNjnaisDA=", + "_parent": { + "$ref": "AAAAAAF5StBNjXab2vs=" + }, + "model": { + "$ref": "AAAAAAF5StBNjXaZel4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2236, + "top": 337, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5StBNjXab2vs=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StBNjnaj34U=", + "_parent": { + "$ref": "AAAAAAF5StBNjXab2vs=" + }, + "model": { + "$ref": "AAAAAAF5StBNjXaZel4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2232, + "top": 324, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5StBNjXab2vs=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StBNjnakOhM=", + "_parent": { + "$ref": "AAAAAAF5StBNjXab2vs=" + }, + "model": { + "$ref": "AAAAAAF5StBNjXaZel4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2242, + "top": 364, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5StBNjXab2vs=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5StBNjnalJvg=", + "_parent": { + "$ref": "AAAAAAF5StBNjXab2vs=" + }, + "model": { + "$ref": "AAAAAAF5StBNjXaYthc=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5StBNjnamkmI=", + "_parent": { + "$ref": "AAAAAAF5StBNjXab2vs=" + }, + "model": { + "$ref": "AAAAAAF5StBNjXaZel4=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5P5nMr01oLTI=" + }, + "tail": { + "$ref": "AAAAAAF5Ss1QmDKthXI=" + }, + "lineStyle": 1, + "points": "1939:379;2263:357", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5StBNjnack3k=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5StBNjnadVQY=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5StBNjnaesNQ=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5StBNjnafXzY=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5StBNjnagLn4=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5StBNjnah5RQ=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5StBNjnaisDA=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5StBNjnaj34U=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5StBNjnakOhM=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5StBNjnalJvg=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5StBNjnamkmI=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5StIJ55ESsdQ=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5StIJ5pEQ/FY=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5StIJ6JETau4=", + "_parent": { + "$ref": "AAAAAAF5StIJ55ESsdQ=" + }, + "model": { + "$ref": "AAAAAAF5StIJ5pEQ/FY=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5StIJ6JEUhEM=", + "_parent": { + "$ref": "AAAAAAF5StIJ6JETau4=" + }, + "visible": false, + "font": "Arial;13;0", + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5StIJ6JEVqnE=", + "_parent": { + "$ref": "AAAAAAF5StIJ6JETau4=" + }, + "font": "Arial;13;1", + "left": 2051, + "top": 523.5, + "width": 96, + "height": 13, + "text": "doRecordClean" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5StIJ6JEWP7E=", + "_parent": { + "$ref": "AAAAAAF5StIJ6JETau4=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5StIJ6JEXgV0=", + "_parent": { + "$ref": "AAAAAAF5StIJ6JETau4=" + }, + "visible": false, + "font": "Arial;13;0", + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 2046, + "top": 516.5, + "width": 106.07177734375, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5StIJ6JEUhEM=" + }, + "nameLabel": { + "$ref": "AAAAAAF5StIJ6JEVqnE=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5StIJ6JEWP7E=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5StIJ6JEXgV0=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5StIJ6JEYF5o=", + "_parent": { + "$ref": "AAAAAAF5StIJ55ESsdQ=" + }, + "model": { + "$ref": "AAAAAAF5StIJ5pEQ/FY=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5StIJ6JEZA8U=", + "_parent": { + "$ref": "AAAAAAF5StIJ55ESsdQ=" + }, + "model": { + "$ref": "AAAAAAF5StIJ5pEQ/FY=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5StIJ6JEaYwU=", + "_parent": { + "$ref": "AAAAAAF5StIJ55ESsdQ=" + }, + "model": { + "$ref": "AAAAAAF5StIJ5pEQ/FY=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5StIJ6JEb/UM=", + "_parent": { + "$ref": "AAAAAAF5StIJ55ESsdQ=" + }, + "model": { + "$ref": "AAAAAAF5StIJ5pEQ/FY=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5StIJ6JEcyow=", + "_parent": { + "$ref": "AAAAAAF5StIJ55ESsdQ=" + }, + "model": { + "$ref": "AAAAAAF5StIJ5pEQ/FY=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 2024, + "top": 512, + "width": 150, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5StIJ6JETau4=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5StIJ6JEYF5o=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5StIJ6JEZA8U=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5StIJ6JEaYwU=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5StIJ6JEb/UM=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5StIJ6JEcyow=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5StIhp5XCuNU=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5StIhppW+/2s=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StIhp5XDSVA=", + "_parent": { + "$ref": "AAAAAAF5StIhp5XCuNU=" + }, + "model": { + "$ref": "AAAAAAF5StIhppW+/2s=" + }, + "font": "Arial;13;0", + "left": 1961, + "top": 438, + "width": 46.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5StIhp5XCuNU=" + }, + "edgePosition": 1, + "text": "+不满足" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StIhp5XEOe8=", + "_parent": { + "$ref": "AAAAAAF5StIhp5XCuNU=" + }, + "model": { + "$ref": "AAAAAAF5StIhppW+/2s=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1992, + "top": 425, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5StIhp5XCuNU=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StIhp5XFIgE=", + "_parent": { + "$ref": "AAAAAAF5StIhp5XCuNU=" + }, + "model": { + "$ref": "AAAAAAF5StIhppW+/2s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1969, + "top": 463, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5StIhp5XCuNU=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StIhp5XGV44=", + "_parent": { + "$ref": "AAAAAAF5StIhp5XCuNU=" + }, + "model": { + "$ref": "AAAAAAF5StIhppW/3D0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1916, + "top": 397, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5StIhp5XCuNU=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StIhp5XH9Wk=", + "_parent": { + "$ref": "AAAAAAF5StIhp5XCuNU=" + }, + "model": { + "$ref": "AAAAAAF5StIhppW/3D0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1925, + "top": 387, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5StIhp5XCuNU=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StIhp5XIoUY=", + "_parent": { + "$ref": "AAAAAAF5StIhp5XCuNU=" + }, + "model": { + "$ref": "AAAAAAF5StIhppW/3D0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1899, + "top": 418, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5StIhp5XCuNU=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StIhp5XJabQ=", + "_parent": { + "$ref": "AAAAAAF5StIhp5XCuNU=" + }, + "model": { + "$ref": "AAAAAAF5StIhppXAozs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2053, + "top": 478, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5StIhp5XCuNU=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StIhp5XKQI8=", + "_parent": { + "$ref": "AAAAAAF5StIhp5XCuNU=" + }, + "model": { + "$ref": "AAAAAAF5StIhppXAozs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2058, + "top": 466, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5StIhp5XCuNU=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StIhp5XLdHE=", + "_parent": { + "$ref": "AAAAAAF5StIhp5XCuNU=" + }, + "model": { + "$ref": "AAAAAAF5StIhppXAozs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2043, + "top": 504, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5StIhp5XCuNU=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5StIhp5XMnHk=", + "_parent": { + "$ref": "AAAAAAF5StIhp5XCuNU=" + }, + "model": { + "$ref": "AAAAAAF5StIhppW/3D0=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5StIhp5XNKZI=", + "_parent": { + "$ref": "AAAAAAF5StIhp5XCuNU=" + }, + "model": { + "$ref": "AAAAAAF5StIhppXAozs=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5StIJ55ESsdQ=" + }, + "tail": { + "$ref": "AAAAAAF5Ss1QmDKthXI=" + }, + "lineStyle": 1, + "points": "1887:403;2068:511", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5StIhp5XDSVA=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5StIhp5XEOe8=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5StIhp5XFIgE=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5StIhp5XGV44=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5StIhp5XH9Wk=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5StIhp5XIoUY=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5StIhp5XJabQ=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5StIhp5XKQI8=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5StIhp5XLdHE=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5StIhp5XMnHk=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5StIhp5XNKZI=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5StWKjad/ao4=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5StWKjad7sNs=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StWKjaeAOMw=", + "_parent": { + "$ref": "AAAAAAF5StWKjad/ao4=" + }, + "model": { + "$ref": "AAAAAAF5StWKjad7sNs=" + }, + "font": "Arial;13;0", + "left": 1526, + "top": 470, + "width": 33.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5StWKjad/ao4=" + }, + "edgePosition": 1, + "text": "+完成" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StWKjaeB8T4=", + "_parent": { + "$ref": "AAAAAAF5StWKjad/ao4=" + }, + "model": { + "$ref": "AAAAAAF5StWKjad7sNs=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1538, + "top": 485, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5StWKjad/ao4=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StWKjqeCMfI=", + "_parent": { + "$ref": "AAAAAAF5StWKjad/ao4=" + }, + "model": { + "$ref": "AAAAAAF5StWKjad7sNs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1549, + "top": 441, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5StWKjad/ao4=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StWKjqeD8dI=", + "_parent": { + "$ref": "AAAAAAF5StWKjad/ao4=" + }, + "model": { + "$ref": "AAAAAAF5StWKjad8hyI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1722, + "top": 513, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5StWKjad/ao4=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StWKjqeENZo=", + "_parent": { + "$ref": "AAAAAAF5StWKjad/ao4=" + }, + "model": { + "$ref": "AAAAAAF5StWKjad8hyI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1716, + "top": 525, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5StWKjad/ao4=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StWKjqeFObw=", + "_parent": { + "$ref": "AAAAAAF5StWKjad/ao4=" + }, + "model": { + "$ref": "AAAAAAF5StWKjad8hyI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1732, + "top": 487, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5StWKjad/ao4=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StWKjqeGRb0=", + "_parent": { + "$ref": "AAAAAAF5StWKjad/ao4=" + }, + "model": { + "$ref": "AAAAAAF5StWKjad96kQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1363, + "top": 427, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5StWKjad/ao4=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StWKjqeHI70=", + "_parent": { + "$ref": "AAAAAAF5StWKjad/ao4=" + }, + "model": { + "$ref": "AAAAAAF5StWKjad96kQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1362, + "top": 441, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5StWKjad/ao4=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StWKjqeIy1Y=", + "_parent": { + "$ref": "AAAAAAF5StWKjad/ao4=" + }, + "model": { + "$ref": "AAAAAAF5StWKjad96kQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1365, + "top": 399, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5StWKjad/ao4=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5StWKjqeJDvE=", + "_parent": { + "$ref": "AAAAAAF5StWKjad/ao4=" + }, + "model": { + "$ref": "AAAAAAF5StWKjad8hyI=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5StWKjqeKjN0=", + "_parent": { + "$ref": "AAAAAAF5StWKjad/ao4=" + }, + "model": { + "$ref": "AAAAAAF5StWKjad96kQ=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5P5/CAk98zZc=" + }, + "tail": { + "$ref": "AAAAAAF5QKIG+T9Y4ko=" + }, + "lineStyle": 1, + "points": "1751:511;1342:413", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5StWKjaeAOMw=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5StWKjaeB8T4=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5StWKjqeCMfI=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5StWKjqeD8dI=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5StWKjqeENZo=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5StWKjqeFObw=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5StWKjqeGRb0=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5StWKjqeHI70=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5StWKjqeIy1Y=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5StWKjqeJDvE=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5StWKjqeKjN0=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5StaqW9rGSo4=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5StaqWtrE9ro=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5StaqW9rHsAM=", + "_parent": { + "$ref": "AAAAAAF5StaqW9rGSo4=" + }, + "model": { + "$ref": "AAAAAAF5StaqWtrE9ro=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5StaqW9rIMvI=", + "_parent": { + "$ref": "AAAAAAF5StaqW9rHsAM=" + }, + "visible": false, + "fillColor": "#ffc1ad", + "font": "Arial;13;0", + "left": -448, + "top": -496, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5StaqW9rJ3VU=", + "_parent": { + "$ref": "AAAAAAF5StaqW9rHsAM=" + }, + "fillColor": "#ffc1ad", + "font": "Arial;13;1", + "left": 1738.5, + "top": 715.5, + "width": 168, + "height": 13, + "text": "用户选择是否跳转到其他测回" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5StaqW9rK5Uk=", + "_parent": { + "$ref": "AAAAAAF5StaqW9rHsAM=" + }, + "visible": false, + "fillColor": "#ffc1ad", + "font": "Arial;13;0", + "left": -448, + "top": -496, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5StaqW9rLlM4=", + "_parent": { + "$ref": "AAAAAAF5StaqW9rHsAM=" + }, + "visible": false, + "fillColor": "#ffc1ad", + "font": "Arial;13;0", + "left": -448, + "top": -496, + "height": 13, + "horizontalAlignment": 1 + } + ], + "fillColor": "#ffc1ad", + "font": "Arial;13;0", + "left": 1733.5, + "top": 708.5, + "width": 179, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5StaqW9rIMvI=" + }, + "nameLabel": { + "$ref": "AAAAAAF5StaqW9rJ3VU=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5StaqW9rK5Uk=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5StaqW9rLlM4=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5StaqW9rMapE=", + "_parent": { + "$ref": "AAAAAAF5StaqW9rGSo4=" + }, + "model": { + "$ref": "AAAAAAF5StaqWtrE9ro=" + }, + "visible": false, + "fillColor": "#ffc1ad", + "font": "Arial;13;0", + "left": -224, + "top": -248, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5StaqW9rNzzg=", + "_parent": { + "$ref": "AAAAAAF5StaqW9rGSo4=" + }, + "model": { + "$ref": "AAAAAAF5StaqWtrE9ro=" + }, + "visible": false, + "fillColor": "#ffc1ad", + "font": "Arial;13;0", + "left": -224, + "top": -248, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5StaqW9rON6o=", + "_parent": { + "$ref": "AAAAAAF5StaqW9rGSo4=" + }, + "model": { + "$ref": "AAAAAAF5StaqWtrE9ro=" + }, + "visible": false, + "fillColor": "#ffc1ad", + "font": "Arial;13;0", + "left": -224, + "top": -248, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5StaqW9rPWX8=", + "_parent": { + "$ref": "AAAAAAF5StaqW9rGSo4=" + }, + "model": { + "$ref": "AAAAAAF5StaqWtrE9ro=" + }, + "visible": false, + "fillColor": "#ffc1ad", + "font": "Arial;13;0", + "left": -224, + "top": -248, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5StaqW9rQ9mc=", + "_parent": { + "$ref": "AAAAAAF5StaqW9rGSo4=" + }, + "model": { + "$ref": "AAAAAAF5StaqWtrE9ro=" + }, + "visible": false, + "fillColor": "#ffc1ad", + "font": "Arial;13;0", + "left": -224, + "top": -248, + "width": 10, + "height": 10 + } + ], + "fillColor": "#ffc1ad", + "font": "Arial;13;0", + "containerChangeable": true, + "left": 1696, + "top": 704, + "width": 253, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5StaqW9rHsAM=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5StaqW9rMapE=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5StaqW9rNzzg=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5StaqW9rON6o=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5StaqW9rPWX8=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5StaqW9rQ9mc=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5StcY69+auow=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5StcY69+Wpu4=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StcY69+bJyw=", + "_parent": { + "$ref": "AAAAAAF5StcY69+auow=" + }, + "model": { + "$ref": "AAAAAAF5StcY69+Wpu4=" + }, + "font": "Arial;13;0", + "left": 1815, + "top": 619, + "width": 46.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5StcY69+auow=" + }, + "edgePosition": 1, + "text": "+未完成" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StcY69+crMs=", + "_parent": { + "$ref": "AAAAAAF5StcY69+auow=" + }, + "model": { + "$ref": "AAAAAAF5StcY69+Wpu4=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1853, + "top": 619, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5StcY69+auow=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StcY69+d1N0=", + "_parent": { + "$ref": "AAAAAAF5StcY69+auow=" + }, + "model": { + "$ref": "AAAAAAF5StcY69+Wpu4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1809, + "top": 618, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5StcY69+auow=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StcY7N+esYw=", + "_parent": { + "$ref": "AAAAAAF5StcY69+auow=" + }, + "model": { + "$ref": "AAAAAAF5StcY69+XtIs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1840, + "top": 567, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5StcY69+auow=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StcY7N+f1JY=", + "_parent": { + "$ref": "AAAAAAF5StcY69+auow=" + }, + "model": { + "$ref": "AAAAAAF5StcY69+XtIs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1853, + "top": 569, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5StcY69+auow=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StcY7N+gGlM=", + "_parent": { + "$ref": "AAAAAAF5StcY69+auow=" + }, + "model": { + "$ref": "AAAAAAF5StcY69+XtIs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1812, + "top": 562, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5StcY69+auow=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StcY7N+hLtM=", + "_parent": { + "$ref": "AAAAAAF5StcY69+auow=" + }, + "model": { + "$ref": "AAAAAAF5StcY69+Yoz0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1837, + "top": 671, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5StcY69+auow=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StcY7N+i0N0=", + "_parent": { + "$ref": "AAAAAAF5StcY69+auow=" + }, + "model": { + "$ref": "AAAAAAF5StcY69+Yoz0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1850, + "top": 669, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5StcY69+auow=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StcY7N+jJRk=", + "_parent": { + "$ref": "AAAAAAF5StcY69+auow=" + }, + "model": { + "$ref": "AAAAAAF5StcY69+Yoz0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1810, + "top": 675, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5StcY69+auow=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5StcY7N+k7Ks=", + "_parent": { + "$ref": "AAAAAAF5StcY69+auow=" + }, + "model": { + "$ref": "AAAAAAF5StcY69+XtIs=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5StcY7N+lWqU=", + "_parent": { + "$ref": "AAAAAAF5StcY69+auow=" + }, + "model": { + "$ref": "AAAAAAF5StcY69+Yoz0=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5StaqW9rGSo4=" + }, + "tail": { + "$ref": "AAAAAAF5QKIG+T9Y4ko=" + }, + "lineStyle": 1, + "points": "1826:547;1822:703", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5StcY69+bJyw=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5StcY69+crMs=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5StcY69+d1N0=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5StcY7N+esYw=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5StcY7N+f1JY=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5StcY7N+gGlM=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5StcY7N+hLtM=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5StcY7N+i0N0=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5StcY7N+jJRk=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5StcY7N+k7Ks=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5StcY7N+lWqU=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5StecvuuYlQs=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5StecvuuUiTw=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StecvuuZ8Fw=", + "_parent": { + "$ref": "AAAAAAF5StecvuuYlQs=" + }, + "model": { + "$ref": "AAAAAAF5StecvuuUiTw=" + }, + "font": "Arial;13;0", + "left": 1776, + "top": 1083, + "width": 98.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5StecvuuYlQs=" + }, + "edgePosition": 1, + "text": "+跳转测回后补测" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StecvuuawiY=", + "_parent": { + "$ref": "AAAAAAF5StecvuuYlQs=" + }, + "model": { + "$ref": "AAAAAAF5StecvuuUiTw=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1840, + "top": 1083, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5StecvuuYlQs=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StecvuubliA=", + "_parent": { + "$ref": "AAAAAAF5StecvuuYlQs=" + }, + "model": { + "$ref": "AAAAAAF5StecvuuUiTw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1796, + "top": 1082, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5StecvuuYlQs=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StecvuucS6Y=", + "_parent": { + "$ref": "AAAAAAF5StecvuuYlQs=" + }, + "model": { + "$ref": "AAAAAAF5StecvuuVcKw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1835, + "top": 759, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5StecvuuYlQs=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StecvuudsIs=", + "_parent": { + "$ref": "AAAAAAF5StecvuuYlQs=" + }, + "model": { + "$ref": "AAAAAAF5StecvuuVcKw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1848, + "top": 762, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5StecvuuYlQs=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StecvuueFws=", + "_parent": { + "$ref": "AAAAAAF5StecvuuYlQs=" + }, + "model": { + "$ref": "AAAAAAF5StecvuuVcKw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1807, + "top": 754, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5StecvuuYlQs=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StecvuufPVU=", + "_parent": { + "$ref": "AAAAAAF5StecvuuYlQs=" + }, + "model": { + "$ref": "AAAAAAF5StecvuuWIOM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1816, + "top": 1407, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5StecvuuYlQs=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StecvuugcGo=", + "_parent": { + "$ref": "AAAAAAF5StecvuuYlQs=" + }, + "model": { + "$ref": "AAAAAAF5StecvuuWIOM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1830, + "top": 1405, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5StecvuuYlQs=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StecvuuhAqk=", + "_parent": { + "$ref": "AAAAAAF5StecvuuYlQs=" + }, + "model": { + "$ref": "AAAAAAF5StecvuuWIOM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1789, + "top": 1411, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5StecvuuYlQs=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5StecvuuiooQ=", + "_parent": { + "$ref": "AAAAAAF5StecvuuYlQs=" + }, + "model": { + "$ref": "AAAAAAF5StecvuuVcKw=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5Stecv+uj9kw=", + "_parent": { + "$ref": "AAAAAAF5StecvuuYlQs=" + }, + "model": { + "$ref": "AAAAAAF5StecvuuWIOM=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QMaQUG/rlG8=" + }, + "tail": { + "$ref": "AAAAAAF5StaqW9rGSo4=" + }, + "lineStyle": 1, + "points": "1821:739;1801:1439", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5StecvuuZ8Fw=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5StecvuuawiY=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5StecvuubliA=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5StecvuucS6Y=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5StecvuudsIs=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5StecvuueFws=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5StecvuufPVU=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5StecvuugcGo=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5StecvuuhAqk=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5StecvuuiooQ=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5Stecv+uj9kw=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5Stg/Ofb2A68=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5Stg/N/byEbA=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Stg/Ofb3nog=", + "_parent": { + "$ref": "AAAAAAF5Stg/Ofb2A68=" + }, + "model": { + "$ref": "AAAAAAF5Stg/N/byEbA=" + }, + "font": "Arial;13;0", + "left": 1315, + "top": 605, + "width": 72.22798156738281, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5Stg/Ofb2A68=" + }, + "edgePosition": 1, + "text": "+取消or忽略" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Stg/Ofb45tw=", + "_parent": { + "$ref": "AAAAAAF5Stg/Ofb2A68=" + }, + "model": { + "$ref": "AAAAAAF5Stg/N/byEbA=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1347, + "top": 619, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5Stg/Ofb2A68=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Stg/Ofb5GmI=", + "_parent": { + "$ref": "AAAAAAF5Stg/Ofb2A68=" + }, + "model": { + "$ref": "AAAAAAF5Stg/N/byEbA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1358, + "top": 576, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5Stg/Ofb2A68=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Stg/Ofb6tf0=", + "_parent": { + "$ref": "AAAAAAF5Stg/Ofb2A68=" + }, + "model": { + "$ref": "AAAAAAF5Stg/N/bz2/4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1725, + "top": 704, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5Stg/Ofb2A68=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Stg/Ofb78vU=", + "_parent": { + "$ref": "AAAAAAF5Stg/Ofb2A68=" + }, + "model": { + "$ref": "AAAAAAF5Stg/N/bz2/4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1719, + "top": 717, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5Stg/Ofb2A68=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Stg/Ofb8Jmw=", + "_parent": { + "$ref": "AAAAAAF5Stg/Ofb2A68=" + }, + "model": { + "$ref": "AAAAAAF5Stg/N/bz2/4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1736, + "top": 679, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5Stg/Ofb2A68=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Stg/Ofb9zNg=", + "_parent": { + "$ref": "AAAAAAF5Stg/Ofb2A68=" + }, + "model": { + "$ref": "AAAAAAF5Stg/N/b0VQA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 978, + "top": 506, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5Stg/Ofb2A68=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Stg/Ofb+I1M=", + "_parent": { + "$ref": "AAAAAAF5Stg/Ofb2A68=" + }, + "model": { + "$ref": "AAAAAAF5Stg/N/b0VQA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 977, + "top": 519, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5Stg/Ofb2A68=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Stg/Ofb/AoU=", + "_parent": { + "$ref": "AAAAAAF5Stg/Ofb2A68=" + }, + "model": { + "$ref": "AAAAAAF5Stg/N/b0VQA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 981, + "top": 478, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5Stg/Ofb2A68=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5Stg/OfcA1lA=", + "_parent": { + "$ref": "AAAAAAF5Stg/Ofb2A68=" + }, + "model": { + "$ref": "AAAAAAF5Stg/N/bz2/4=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5Stg/OfcBL2A=", + "_parent": { + "$ref": "AAAAAAF5Stg/Ofb2A68=" + }, + "model": { + "$ref": "AAAAAAF5Stg/N/b0VQA=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QJjLZRML/gk=" + }, + "tail": { + "$ref": "AAAAAAF5StaqW9rGSo4=" + }, + "lineStyle": 1, + "points": "1754:703;957:491", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5Stg/Ofb3nog=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5Stg/Ofb45tw=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5Stg/Ofb5GmI=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5Stg/Ofb6tf0=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5Stg/Ofb78vU=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5Stg/Ofb8Jmw=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5Stg/Ofb9zNg=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5Stg/Ofb+I1M=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5Stg/Ofb/AoU=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5Stg/OfcA1lA=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5Stg/OfcBL2A=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF5Stp87Q6fs2Y=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5Stp87A6d2HY=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF5Stp87g6gqlw=", + "_parent": { + "$ref": "AAAAAAF5Stp87Q6fs2Y=" + }, + "model": { + "$ref": "AAAAAAF5Stp87A6d2HY=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF5Stp87g6h+fQ=", + "_parent": { + "$ref": "AAAAAAF5Stp87g6gqlw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 864, + "top": 48, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5Stp87g6iB2Y=", + "_parent": { + "$ref": "AAAAAAF5Stp87g6gqlw=" + }, + "font": "Arial;13;1", + "left": 2518.5, + "top": 819.5, + "width": 151, + "height": 13, + "text": "isSingleCycleCompleted" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5Stp87g6jrfo=", + "_parent": { + "$ref": "AAAAAAF5Stp87g6gqlw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 864, + "top": 48, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF5Stp87g6koqM=", + "_parent": { + "$ref": "AAAAAAF5Stp87g6gqlw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 864, + "top": 48, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 2513.5, + "top": 812.5, + "width": 161.708984375, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF5Stp87g6h+fQ=" + }, + "nameLabel": { + "$ref": "AAAAAAF5Stp87g6iB2Y=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF5Stp87g6jrfo=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5Stp87g6koqM=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF5Stp87g6lk/c=", + "_parent": { + "$ref": "AAAAAAF5Stp87Q6fs2Y=" + }, + "model": { + "$ref": "AAAAAAF5Stp87A6d2HY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 432, + "top": 24, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF5Stp87g6mFIA=", + "_parent": { + "$ref": "AAAAAAF5Stp87Q6fs2Y=" + }, + "model": { + "$ref": "AAAAAAF5Stp87A6d2HY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 432, + "top": 24, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5Stp87g6nmy0=", + "_parent": { + "$ref": "AAAAAAF5Stp87Q6fs2Y=" + }, + "model": { + "$ref": "AAAAAAF5Stp87A6d2HY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 432, + "top": 24, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF5Stp87g6oJMI=", + "_parent": { + "$ref": "AAAAAAF5Stp87Q6fs2Y=" + }, + "model": { + "$ref": "AAAAAAF5Stp87A6d2HY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 432, + "top": 24, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF5Stp87g6p63M=", + "_parent": { + "$ref": "AAAAAAF5Stp87Q6fs2Y=" + }, + "model": { + "$ref": "AAAAAAF5Stp87A6d2HY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 432, + "top": 24, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 2480, + "top": 808, + "width": 228, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF5Stp87g6gqlw=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF5Stp87g6lk/c=" + }, + "operationCompartment": { + "$ref": "AAAAAAF5Stp87g6mFIA=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5Stp87g6nmy0=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF5Stp87g6oJMI=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF5Stp87g6p63M=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5StrWhROp4Oc=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5StrWhBOl298=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StrWhROqofY=", + "_parent": { + "$ref": "AAAAAAF5StrWhROp4Oc=" + }, + "model": { + "$ref": "AAAAAAF5StrWhBOl298=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2352, + "top": 658, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5StrWhROp4Oc=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StrWhROrA94=", + "_parent": { + "$ref": "AAAAAAF5StrWhROp4Oc=" + }, + "model": { + "$ref": "AAAAAAF5StrWhBOl298=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 2360, + "top": 645, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5StrWhROp4Oc=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StrWhROs2b4=", + "_parent": { + "$ref": "AAAAAAF5StrWhROp4Oc=" + }, + "model": { + "$ref": "AAAAAAF5StrWhBOl298=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2337, + "top": 683, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5StrWhROp4Oc=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StrWhROtkZ8=", + "_parent": { + "$ref": "AAAAAAF5StrWhROp4Oc=" + }, + "model": { + "$ref": "AAAAAAF5StrWhBOmfyU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2157, + "top": 541, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5StrWhROp4Oc=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StrWhROu87A=", + "_parent": { + "$ref": "AAAAAAF5StrWhROp4Oc=" + }, + "model": { + "$ref": "AAAAAAF5StrWhBOmfyU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2166, + "top": 531, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5StrWhROp4Oc=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StrWhROvpPg=", + "_parent": { + "$ref": "AAAAAAF5StrWhROp4Oc=" + }, + "model": { + "$ref": "AAAAAAF5StrWhBOmfyU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2140, + "top": 562, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5StrWhROp4Oc=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StrWhROw9lc=", + "_parent": { + "$ref": "AAAAAAF5StrWhROp4Oc=" + }, + "model": { + "$ref": "AAAAAAF5StrWhBOnvuo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2548, + "top": 774, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5StrWhROp4Oc=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StrWhROxGek=", + "_parent": { + "$ref": "AAAAAAF5StrWhROp4Oc=" + }, + "model": { + "$ref": "AAAAAAF5StrWhBOnvuo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2553, + "top": 762, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5StrWhROp4Oc=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5StrWhROy9qY=", + "_parent": { + "$ref": "AAAAAAF5StrWhROp4Oc=" + }, + "model": { + "$ref": "AAAAAAF5StrWhBOnvuo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2538, + "top": 800, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5StrWhROp4Oc=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5StrWhROzgAM=", + "_parent": { + "$ref": "AAAAAAF5StrWhROp4Oc=" + }, + "model": { + "$ref": "AAAAAAF5StrWhBOmfyU=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5StrWhRO0+cw=", + "_parent": { + "$ref": "AAAAAAF5StrWhROp4Oc=" + }, + "model": { + "$ref": "AAAAAAF5StrWhBOnvuo=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5Stp87Q6fs2Y=" + }, + "tail": { + "$ref": "AAAAAAF5StIJ55ESsdQ=" + }, + "lineStyle": 1, + "points": "2128:547;2563:807", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5StrWhROqofY=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5StrWhROrA94=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5StrWhROs2b4=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5StrWhROtkZ8=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5StrWhROu87A=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5StrWhROvpPg=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5StrWhROw9lc=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5StrWhROxGek=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5StrWhROy9qY=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5StrWhROzgAM=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5StrWhRO0+cw=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5Styi5hf3vEY=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5Styi5Rfz3o0=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Styi5hf45gs=", + "_parent": { + "$ref": "AAAAAAF5Styi5hf3vEY=" + }, + "model": { + "$ref": "AAAAAAF5Styi5Rfz3o0=" + }, + "font": "Arial;13;0", + "left": 2339, + "top": 811, + "width": 46.591796875, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5Styi5hf3vEY=" + }, + "edgePosition": 1, + "text": "+完成" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Styi5hf51HU=", + "_parent": { + "$ref": "AAAAAAF5Styi5hf3vEY=" + }, + "model": { + "$ref": "AAAAAAF5Styi5Rfz3o0=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 2361, + "top": 826, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5Styi5hf3vEY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Styi5hf6gvA=", + "_parent": { + "$ref": "AAAAAAF5Styi5hf3vEY=" + }, + "model": { + "$ref": "AAAAAAF5Styi5Rfz3o0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2365, + "top": 782, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5Styi5hf3vEY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Styi5hf7rXE=", + "_parent": { + "$ref": "AAAAAAF5Styi5hf3vEY=" + }, + "model": { + "$ref": "AAAAAAF5Styi5Rf0fJk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2451, + "top": 820, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5Styi5hf3vEY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Styi5hf8B7M=", + "_parent": { + "$ref": "AAAAAAF5Styi5hf3vEY=" + }, + "model": { + "$ref": "AAAAAAF5Styi5Rf0fJk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2448, + "top": 833, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5Styi5hf3vEY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Styi5hf95Ew=", + "_parent": { + "$ref": "AAAAAAF5Styi5hf3vEY=" + }, + "model": { + "$ref": "AAAAAAF5Styi5Rf0fJk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2458, + "top": 793, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5Styi5hf3vEY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Styi5hf+T+w=", + "_parent": { + "$ref": "AAAAAAF5Styi5hf3vEY=" + }, + "model": { + "$ref": "AAAAAAF5Styi5Rf1+Tk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2274, + "top": 804, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5Styi5hf3vEY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Styi5hf/4I4=", + "_parent": { + "$ref": "AAAAAAF5Styi5hf3vEY=" + }, + "model": { + "$ref": "AAAAAAF5Styi5Rf1+Tk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2275, + "top": 817, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5Styi5hf3vEY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5Styi5hgAAcY=", + "_parent": { + "$ref": "AAAAAAF5Styi5hf3vEY=" + }, + "model": { + "$ref": "AAAAAAF5Styi5Rf1+Tk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2272, + "top": 776, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5Styi5hf3vEY=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5Styi5hgBznc=", + "_parent": { + "$ref": "AAAAAAF5Styi5hf3vEY=" + }, + "model": { + "$ref": "AAAAAAF5Styi5Rf0fJk=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5Styi5hgCPb4=", + "_parent": { + "$ref": "AAAAAAF5Styi5hf3vEY=" + }, + "model": { + "$ref": "AAAAAAF5Styi5Rf1+Tk=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QKE6Ojfzjv0=" + }, + "tail": { + "$ref": "AAAAAAF5Stp87Q6fs2Y=" + }, + "lineStyle": 1, + "points": "2479:814;2250:793", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5Styi5hf45gs=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5Styi5hf51HU=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5Styi5hf6gvA=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5Styi5hf7rXE=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5Styi5hf8B7M=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5Styi5hf95Ew=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5Styi5hf+T+w=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5Styi5hf/4I4=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5Styi5hgAAcY=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5Styi5hgBznc=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5Styi5hgCPb4=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF5St1uUR+q0qc=", + "_parent": { + "$ref": "AAAAAAF5P5m6Qk1jVXQ=" + }, + "model": { + "$ref": "AAAAAAF5St1uUR+mHuk=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5St1uUR+rshY=", + "_parent": { + "$ref": "AAAAAAF5St1uUR+q0qc=" + }, + "model": { + "$ref": "AAAAAAF5St1uUR+mHuk=" + }, + "font": "Arial;13;0", + "left": 2182, + "top": 1146, + "width": 46.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5St1uUR+q0qc=" + }, + "edgePosition": 1, + "text": "+未完成" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5St1uUR+sGjw=", + "_parent": { + "$ref": "AAAAAAF5St1uUR+q0qc=" + }, + "model": { + "$ref": "AAAAAAF5St1uUR+mHuk=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 2214, + "top": 1158, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5St1uUR+q0qc=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5St1uUR+t4JQ=", + "_parent": { + "$ref": "AAAAAAF5St1uUR+q0qc=" + }, + "model": { + "$ref": "AAAAAAF5St1uUR+mHuk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2186, + "top": 1123, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF5St1uUR+q0qc=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5St1uUR+uiWE=", + "_parent": { + "$ref": "AAAAAAF5St1uUR+q0qc=" + }, + "model": { + "$ref": "AAAAAAF5St1uUR+nHko=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2559, + "top": 864, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5St1uUR+q0qc=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5St1uUR+v1Ig=", + "_parent": { + "$ref": "AAAAAAF5St1uUR+q0qc=" + }, + "model": { + "$ref": "AAAAAAF5St1uUR+nHko=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2565, + "top": 876, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5St1uUR+q0qc=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5St1uUR+wJBc=", + "_parent": { + "$ref": "AAAAAAF5St1uUR+q0qc=" + }, + "model": { + "$ref": "AAAAAAF5St1uUR+nHko=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 2545, + "top": 840, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5St1uUR+q0qc=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5St1uUR+xuEc=", + "_parent": { + "$ref": "AAAAAAF5St1uUR+q0qc=" + }, + "model": { + "$ref": "AAAAAAF5St1uUR+oJAQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1852, + "top": 1428, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF5St1uUR+q0qc=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5St1uUR+yEoo=", + "_parent": { + "$ref": "AAAAAAF5St1uUR+q0qc=" + }, + "model": { + "$ref": "AAAAAAF5St1uUR+oJAQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1862, + "top": 1437, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF5St1uUR+q0qc=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF5St1uUR+zGSA=", + "_parent": { + "$ref": "AAAAAAF5St1uUR+q0qc=" + }, + "model": { + "$ref": "AAAAAAF5St1uUR+oJAQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1832, + "top": 1409, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF5St1uUR+q0qc=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5St1uUR+02pE=", + "_parent": { + "$ref": "AAAAAAF5St1uUR+q0qc=" + }, + "model": { + "$ref": "AAAAAAF5St1uUR+nHko=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF5St1uUR+1/EE=", + "_parent": { + "$ref": "AAAAAAF5St1uUR+q0qc=" + }, + "model": { + "$ref": "AAAAAAF5St1uUR+oJAQ=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF5QMaQUG/rlG8=" + }, + "tail": { + "$ref": "AAAAAAF5Stp87Q6fs2Y=" + }, + "lineStyle": 1, + "points": "2570:843;1823:1439", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF5St1uUR+rshY=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF5St1uUR+sGjw=" + }, + "propertyLabel": { + "$ref": "AAAAAAF5St1uUR+t4JQ=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF5St1uUR+uiWE=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF5St1uUR+v1Ig=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF5St1uUR+wJBc=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF5St1uUR+xuEc=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF5St1uUR+yEoo=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF5St1uUR+zGSA=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF5St1uUR+02pE=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF5St1uUR+1/EE=" + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5P5nMrk1mLCw=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "check2C", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5P5saV03F9So=", + "_parent": { + "$ref": "AAAAAAF5P5nMrk1mLCw=" + }, + "name": "通过检测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5P5saV03GReQ=", + "_parent": { + "$ref": "AAAAAAF5P5saV03F9So=" + }, + "reference": { + "$ref": "AAAAAAF5P5nMrk1mLCw=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5P5saV03HrLQ=", + "_parent": { + "$ref": "AAAAAAF5P5saV03F9So=" + }, + "reference": { + "$ref": "AAAAAAF5StIJ5pEQ/FY=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5P56tf07Epig=", + "_parent": { + "$ref": "AAAAAAF5P5nMrk1mLCw=" + }, + "name": "未通过检测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5P56tgE7F7Yk=", + "_parent": { + "$ref": "AAAAAAF5P56tf07Epig=" + }, + "reference": { + "$ref": "AAAAAAF5P5nMrk1mLCw=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5P56tgE7GNNA=", + "_parent": { + "$ref": "AAAAAAF5P56tf07Epig=" + }, + "reference": { + "$ref": "AAAAAAF5P56LY06KFIA=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5P5rmBE2WOV0=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "recordClean" + }, + { + "_type": "UMLUseCaseSubject", + "_id": "AAAAAAF5P5vlT04vpIc=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "用户选择操作" + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5P56LY06KFIA=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "【用户选择操作】", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5P5/ask/ASWM=", + "_parent": { + "$ref": "AAAAAAF5P56LY06KFIA=" + }, + "name": "选择忽略or重测目标", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5P5/ask/BASE=", + "_parent": { + "$ref": "AAAAAAF5P5/ask/ASWM=" + }, + "reference": { + "$ref": "AAAAAAF5P56LY06KFIA=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5P5/ask/CwwU=", + "_parent": { + "$ref": "AAAAAAF5P5/ask/ASWM=" + }, + "reference": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5P6ETu1Fsgo0=", + "_parent": { + "$ref": "AAAAAAF5P56LY06KFIA=" + }, + "name": "重测测回", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5P6ETu1FtUvs=", + "_parent": { + "$ref": "AAAAAAF5P6ETu1Fsgo0=" + }, + "reference": { + "$ref": "AAAAAAF5P56LY06KFIA=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5P6ETu1Fuzfc=", + "_parent": { + "$ref": "AAAAAAF5P6ETu1Fsgo0=" + }, + "reference": { + "$ref": "AAAAAAF5P6Btl1DQYFs=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5P5/CAk96MB0=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "Idle" + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5P6Btl1DQYFs=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "【提示用户是否确定删除整个测回】", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5P6HZl1I+eIg=", + "_parent": { + "$ref": "AAAAAAF5P6Btl1DQYFs=" + }, + "name": "选择忽略or取消", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5P6HZl1I/u/s=", + "_parent": { + "$ref": "AAAAAAF5P6HZl1I+eIg=" + }, + "reference": { + "$ref": "AAAAAAF5P6Btl1DQYFs=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5P6HZl1JAt1Q=", + "_parent": { + "$ref": "AAAAAAF5P6HZl1I+eIg=" + }, + "reference": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5P6Jc6FP89fs=", + "_parent": { + "$ref": "AAAAAAF5P6Btl1DQYFs=" + }, + "name": "确认删除", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5P6Jc6FP9Ay0=", + "_parent": { + "$ref": "AAAAAAF5P6Jc6FP89fs=" + }, + "reference": { + "$ref": "AAAAAAF5P6Btl1DQYFs=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5P6Jc6FP+W/w=", + "_parent": { + "$ref": "AAAAAAF5P6Jc6FP89fs=" + }, + "reference": { + "$ref": "AAAAAAF5P6IYDFMK28k=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5P6IYDFMK28k=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "【执行删除操作】", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5P6KuWFYuLA4=", + "_parent": { + "$ref": "AAAAAAF5P6IYDFMK28k=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5P6KuWFYvXto=", + "_parent": { + "$ref": "AAAAAAF5P6KuWFYuLA4=" + }, + "reference": { + "$ref": "AAAAAAF5P6IYDFMK28k=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5P6KuWFYwtmg=", + "_parent": { + "$ref": "AAAAAAF5P6KuWFYuLA4=" + }, + "reference": { + "$ref": "AAAAAAF5QMaQUG/pf+g=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5P6I/oFN00qM=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "重新搜索目标开启新一轮测量", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QJXgiQky2RI=", + "_parent": { + "$ref": "AAAAAAF5P6I/oFN00qM=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QJXgiQkzVQM=", + "_parent": { + "$ref": "AAAAAAF5QJXgiQky2RI=" + }, + "reference": { + "$ref": "AAAAAAF5P6I/oFN00qM=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QJXgiQk0kU4=", + "_parent": { + "$ref": "AAAAAAF5QJXgiQky2RI=" + }, + "reference": { + "$ref": "AAAAAAF5QJWvCggxZrM=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5QJWvCggxZrM=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "move2NextValidate", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RVWv2lZqu2A=", + "_parent": { + "$ref": "AAAAAAF5QJWvCggxZrM=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RVWv2lZro+8=", + "_parent": { + "$ref": "AAAAAAF5RVWv2lZqu2A=" + }, + "reference": { + "$ref": "AAAAAAF5QJWvCggxZrM=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RVWv2lZs/XI=", + "_parent": { + "$ref": "AAAAAAF5RVWv2lZqu2A=" + }, + "reference": { + "$ref": "AAAAAAF5RZAQp9i7BLM=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5QJc4CA2m0sA=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "checkHalfCycleZero", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QJesYRAUeZI=", + "_parent": { + "$ref": "AAAAAAF5QJc4CA2m0sA=" + }, + "name": "测站不闭合or半测回归零差正常", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QJesYRAV/Pw=", + "_parent": { + "$ref": "AAAAAAF5QJesYRAUeZI=" + }, + "reference": { + "$ref": "AAAAAAF5Ssw/MxbPNVc=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QJesYRAWIno=", + "_parent": { + "$ref": "AAAAAAF5QJesYRAUeZI=" + }, + "reference": { + "$ref": "AAAAAAF5Ss1QlzKrDlo=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QJmQwBdscKg=", + "_parent": { + "$ref": "AAAAAAF5QJc4CA2m0sA=" + }, + "name": "没有通过检测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QJmQwBdt/Nk=", + "_parent": { + "$ref": "AAAAAAF5QJmQwBdscKg=" + }, + "reference": { + "$ref": "AAAAAAF5Ssw/MxbPNVc=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QJmQwBdu0wk=", + "_parent": { + "$ref": "AAAAAAF5QJmQwBdscKg=" + }, + "reference": { + "$ref": "AAAAAAF5QJk5ohVWyGc=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5QJeXAw9WAQQ=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "isReady2CCheck" + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5QJjLZBMJQJ8=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "switchState2StandStill", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QJnk3RnjFKU=", + "_parent": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QJnk3Rnk4S8=", + "_parent": { + "$ref": "AAAAAAF5QJnk3RnjFKU=" + }, + "reference": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QJnk3Rnlvxc=", + "_parent": { + "$ref": "AAAAAAF5QJnk3RnjFKU=" + }, + "reference": { + "$ref": "AAAAAAF5P5/CAk96MB0=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5QJk5ohVWyGc=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "提示半测回归零检测失败", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QJnHsRkKHYc=", + "_parent": { + "$ref": "AAAAAAF5QJk5ohVWyGc=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QJnHsRkLdTo=", + "_parent": { + "$ref": "AAAAAAF5QJnHsRkKHYc=" + }, + "reference": { + "$ref": "AAAAAAF5QJk5ohVWyGc=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QJnHsRkM5N4=", + "_parent": { + "$ref": "AAAAAAF5QJnHsRkKHYc=" + }, + "reference": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5QJ6ahSPVJNg=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "checkReadData", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QJ87Oyj+dCg=", + "_parent": { + "$ref": "AAAAAAF5QJ6ahSPVJNg=" + }, + "name": "单测量or通过检测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QJ87Oyj/TJQ=", + "_parent": { + "$ref": "AAAAAAF5QJ87Oyj+dCg=" + }, + "reference": { + "$ref": "AAAAAAF5QJ6ahSPVJNg=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QJ87OykA4RY=", + "_parent": { + "$ref": "AAAAAAF5QJ87Oyj+dCg=" + }, + "reference": { + "$ref": "AAAAAAF5QJ8m8Sf4R1w=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QJ/Ugywh52g=", + "_parent": { + "$ref": "AAAAAAF5QJ6ahSPVJNg=" + }, + "name": "未通过检测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QJ/Ugywiha4=", + "_parent": { + "$ref": "AAAAAAF5QJ/Ugywh52g=" + }, + "reference": { + "$ref": "AAAAAAF5QJ6ahSPVJNg=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QJ/UgywjRPE=", + "_parent": { + "$ref": "AAAAAAF5QJ/Ugywh52g=" + }, + "reference": { + "$ref": "AAAAAAF5QJ+mRitXafY=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5QJ8m8Sf4R1w=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "isHalfCycleZeroCheckReady", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5SsvDEBJ10hk=", + "_parent": { + "$ref": "AAAAAAF5QJ8m8Sf4R1w=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5SsvDEBJ2t9o=", + "_parent": { + "$ref": "AAAAAAF5SsvDEBJ10hk=" + }, + "reference": { + "$ref": "AAAAAAF5QJ8m8Sf4R1w=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5SsvDEBJ3GSY=", + "_parent": { + "$ref": "AAAAAAF5SsvDEBJ10hk=" + }, + "reference": { + "$ref": "AAAAAAF5Sst98gwopLY=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5QJ+mRitXafY=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "提示读数有误", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QJ/0PCz+xYo=", + "_parent": { + "$ref": "AAAAAAF5QJ+mRitXafY=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QJ/0PCz/2CU=", + "_parent": { + "$ref": "AAAAAAF5QJ/0PCz+xYo=" + }, + "reference": { + "$ref": "AAAAAAF5QJ+mRitXafY=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QJ/0PC0AjHo=", + "_parent": { + "$ref": "AAAAAAF5QJ/0PCz+xYo=" + }, + "reference": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5QKE6OTfx/D4=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "checkSingleCycle", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QKI4y0KDGow=", + "_parent": { + "$ref": "AAAAAAF5QKE6OTfx/D4=" + }, + "name": "通过检测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QKI4zEKEuw8=", + "_parent": { + "$ref": "AAAAAAF5QKI4y0KDGow=" + }, + "reference": { + "$ref": "AAAAAAF5QKE6OTfx/D4=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QKI4zEKFtZg=", + "_parent": { + "$ref": "AAAAAAF5QKI4y0KDGow=" + }, + "reference": { + "$ref": "AAAAAAF5QKIG+T9Wjdo=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QKvMIE8VEZE=", + "_parent": { + "$ref": "AAAAAAF5QKE6OTfx/D4=" + }, + "name": "未通过检测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QKvMIE8WKCE=", + "_parent": { + "$ref": "AAAAAAF5QKvMIE8VEZE=" + }, + "reference": { + "$ref": "AAAAAAF5QKE6OTfx/D4=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QKvMIE8XsG8=", + "_parent": { + "$ref": "AAAAAAF5QKvMIE8VEZE=" + }, + "reference": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5QKIG+T9Wjdo=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "isAllCycleCompleted", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5StWKjad7sNs=", + "_parent": { + "$ref": "AAAAAAF5QKIG+T9Wjdo=" + }, + "name": "完成", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5StWKjad8hyI=", + "_parent": { + "$ref": "AAAAAAF5StWKjad7sNs=" + }, + "reference": { + "$ref": "AAAAAAF5QKIG+T9Wjdo=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5StWKjad96kQ=", + "_parent": { + "$ref": "AAAAAAF5StWKjad7sNs=" + }, + "reference": { + "$ref": "AAAAAAF5P5/CAk96MB0=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5StcY69+Wpu4=", + "_parent": { + "$ref": "AAAAAAF5QKIG+T9Wjdo=" + }, + "name": "未完成", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5StcY69+XtIs=", + "_parent": { + "$ref": "AAAAAAF5StcY69+Wpu4=" + }, + "reference": { + "$ref": "AAAAAAF5QKIG+T9Wjdo=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5StcY69+Yoz0=", + "_parent": { + "$ref": "AAAAAAF5StcY69+Wpu4=" + }, + "reference": { + "$ref": "AAAAAAF5StaqWtrE9ro=" + } + } + } + ] + }, + { + "_type": "UMLUseCaseSubject", + "_id": "AAAAAAF5QKJM6UPX41c=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "UseCaseSubject1" + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5QKuCwkzWMuI=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "提示用户选择", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QK2Ql1lrW/0=", + "_parent": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + }, + "name": "忽略", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QK2Ql1lsCzU=", + "_parent": { + "$ref": "AAAAAAF5QK2Ql1lrW/0=" + }, + "reference": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QK2Ql1ltUBY=", + "_parent": { + "$ref": "AAAAAAF5QK2Ql1lrW/0=" + }, + "reference": { + "$ref": "AAAAAAF5QKzDRVJwpI4=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QLdiW2HmZcI=", + "_parent": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QLdiW2HnzLc=", + "_parent": { + "$ref": "AAAAAAF5QLdiW2HmZcI=" + }, + "reference": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QLdiW2HodP8=", + "_parent": { + "$ref": "AAAAAAF5QLdiW2HmZcI=" + }, + "reference": { + "$ref": "AAAAAAF5QKyR6VB8Gq8=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QMnaf4pzXpA=", + "_parent": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QMnaf4p0R7o=", + "_parent": { + "$ref": "AAAAAAF5QMnaf4pzXpA=" + }, + "reference": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QMnaf4p1n0A=", + "_parent": { + "$ref": "AAAAAAF5QMnaf4pzXpA=" + }, + "reference": { + "$ref": "AAAAAAF5QKysH1F2Xh8=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5QKyR6VB8Gq8=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "重测方向", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QLx6RGoJ91g=", + "_parent": { + "$ref": "AAAAAAF5QKyR6VB8Gq8=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QLx6RGoKxZI=", + "_parent": { + "$ref": "AAAAAAF5QLx6RGoJ91g=" + }, + "reference": { + "$ref": "AAAAAAF5QKyR6VB8Gq8=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QLx6RGoLs1U=", + "_parent": { + "$ref": "AAAAAAF5QLx6RGoJ91g=" + }, + "reference": { + "$ref": "AAAAAAF5QLwOJ2bN7N0=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5QKysH1F2Xh8=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "重测测回", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QNAhapFq3kM=", + "_parent": { + "$ref": "AAAAAAF5QKysH1F2Xh8=" + }, + "name": "取消", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QNAhapFrudc=", + "_parent": { + "$ref": "AAAAAAF5QNAhapFq3kM=" + }, + "reference": { + "$ref": "AAAAAAF5QKysH1F2Xh8=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QNAhapFsZZ8=", + "_parent": { + "$ref": "AAAAAAF5QNAhapFq3kM=" + }, + "reference": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QNFL6qCXEtU=", + "_parent": { + "$ref": "AAAAAAF5QKysH1F2Xh8=" + }, + "name": "忽略", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QNFL6qCY2AQ=", + "_parent": { + "$ref": "AAAAAAF5QNFL6qCXEtU=" + }, + "reference": { + "$ref": "AAAAAAF5QKysH1F2Xh8=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QNFL6qCZ01s=", + "_parent": { + "$ref": "AAAAAAF5QNFL6qCXEtU=" + }, + "reference": { + "$ref": "AAAAAAF5QKzDRVJwpI4=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RVcwNF0hcaI=", + "_parent": { + "$ref": "AAAAAAF5QKysH1F2Xh8=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RVcwNF0iVWE=", + "_parent": { + "$ref": "AAAAAAF5RVcwNF0hcaI=" + }, + "reference": { + "$ref": "AAAAAAF5QKysH1F2Xh8=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RVcwNF0jQf0=", + "_parent": { + "$ref": "AAAAAAF5RVcwNF0hcaI=" + }, + "reference": { + "$ref": "AAAAAAF5RVbpp1nIOnU=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5QKzDRVJwpI4=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "resetSurveyorStateAndKeepPosition", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QK340l0BzRk=", + "_parent": { + "$ref": "AAAAAAF5QKzDRVJwpI4=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QK340l0ChAw=", + "_parent": { + "$ref": "AAAAAAF5QK340l0BzRk=" + }, + "reference": { + "$ref": "AAAAAAF5QKzDRVJwpI4=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QK340l0D79M=", + "_parent": { + "$ref": "AAAAAAF5QK340l0BzRk=" + }, + "reference": { + "$ref": "AAAAAAF5P5/CAk96MB0=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5QLwOJ2bN7N0=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "resurveyPoints", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QMbzEHNMUo0=", + "_parent": { + "$ref": "AAAAAAF5QLwOJ2bN7N0=" + }, + "name": "开始重测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QMbzEHNNh8o=", + "_parent": { + "$ref": "AAAAAAF5QMbzEHNMUo0=" + }, + "reference": { + "$ref": "AAAAAAF5QLwOJ2bN7N0=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QMbzEHNOm6M=", + "_parent": { + "$ref": "AAAAAAF5QMbzEHNMUo0=" + }, + "reference": { + "$ref": "AAAAAAF5QMaQUG/pf+g=" + } + } + }, + { + "_type": "UMLGeneralization", + "_id": "AAAAAAF5QMevPnTKBWs=", + "_parent": { + "$ref": "AAAAAAF5QLwOJ2bN7N0=" + }, + "name": "重测失败", + "source": { + "$ref": "AAAAAAF5QLwOJ2bN7N0=" + }, + "target": { + "$ref": "AAAAAAF5QKzDRVJwpI4=" + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RVTunkvVKUs=", + "_parent": { + "$ref": "AAAAAAF5QLwOJ2bN7N0=" + }, + "name": "重测失败", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RVTun0vWQ0U=", + "_parent": { + "$ref": "AAAAAAF5RVTunkvVKUs=" + }, + "reference": { + "$ref": "AAAAAAF5QLwOJ2bN7N0=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RVTun0vXr0g=", + "_parent": { + "$ref": "AAAAAAF5RVTunkvVKUs=" + }, + "reference": { + "$ref": "AAAAAAF5QKzDRVJwpI4=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5QMaQUG/pf+g=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "switchState2RestartInCurrentCycle", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5QMjEpoXtFac=", + "_parent": { + "$ref": "AAAAAAF5QMaQUG/pf+g=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QMjEpoXuicM=", + "_parent": { + "$ref": "AAAAAAF5QMjEpoXtFac=" + }, + "reference": { + "$ref": "AAAAAAF5QMaQUG/pf+g=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5QMjEpoXvKNs=", + "_parent": { + "$ref": "AAAAAAF5QMjEpoXtFac=" + }, + "reference": { + "$ref": "AAAAAAF5QJWvCggxZrM=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5RVbpp1nIOnU=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "执行测回删除", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RVdEqWBKDgY=", + "_parent": { + "$ref": "AAAAAAF5RVbpp1nIOnU=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RVdEqWBL2Ro=", + "_parent": { + "$ref": "AAAAAAF5RVdEqWBKDgY=" + }, + "reference": { + "$ref": "AAAAAAF5RVbpp1nIOnU=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RVdEqWBMaWs=", + "_parent": { + "$ref": "AAAAAAF5RVdEqWBKDgY=" + }, + "reference": { + "$ref": "AAAAAAF5QMaQUG/pf+g=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5RWbWh5Q82SE=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "doCalScheduleSingleCycle", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RWkDr6/4piw=", + "_parent": { + "$ref": "AAAAAAF5RWbWh5Q82SE=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RWkDr6/5hKI=", + "_parent": { + "$ref": "AAAAAAF5RWkDr6/4piw=" + }, + "reference": { + "$ref": "AAAAAAF5RWbWh5Q82SE=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RWkDr6/6Fyk=", + "_parent": { + "$ref": "AAAAAAF5RWkDr6/4piw=" + }, + "reference": { + "$ref": "AAAAAAF5RWiYh6tdXHE=" + } + } + } + ] + }, + { + "_type": "UMLUseCaseSubject", + "_id": "AAAAAAF5RWdznZ2YK/Q=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "UseCaseSubject2" + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5RWiYh6tdXHE=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "该测回是否完成测量", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RWmAObifwr4=", + "_parent": { + "$ref": "AAAAAAF5RWiYh6tdXHE=" + }, + "name": "未完成", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RWmAObigyuY=", + "_parent": { + "$ref": "AAAAAAF5RWmAObifwr4=" + }, + "reference": { + "$ref": "AAAAAAF5RWiYh6tdXHE=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RWmAObih5u0=", + "_parent": { + "$ref": "AAAAAAF5RWmAObifwr4=" + }, + "reference": { + "$ref": "AAAAAAF5QMaQUG/pf+g=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RWqc8svr3pE=", + "_parent": { + "$ref": "AAAAAAF5RWiYh6tdXHE=" + }, + "name": "完成", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RWqc8svs8AE=", + "_parent": { + "$ref": "AAAAAAF5RWqc8svr3pE=" + }, + "reference": { + "$ref": "AAAAAAF5RWiYh6tdXHE=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RWqc8svtE1U=", + "_parent": { + "$ref": "AAAAAAF5RWqc8svr3pE=" + }, + "reference": { + "$ref": "AAAAAAF5RWo+Icga7No=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5RWo+Icga7No=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "执行单测回检测", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RWvJyNWC314=", + "_parent": { + "$ref": "AAAAAAF5RWo+Icga7No=" + }, + "name": "未通过检测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RWvJyNWDYLg=", + "_parent": { + "$ref": "AAAAAAF5RWvJyNWC314=" + }, + "reference": { + "$ref": "AAAAAAF5RWo+Icga7No=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RWvJyNWEI/s=", + "_parent": { + "$ref": "AAAAAAF5RWvJyNWC314=" + }, + "reference": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RWxGx9n5fHg=", + "_parent": { + "$ref": "AAAAAAF5RWo+Icga7No=" + }, + "name": "通过检测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RWxGx9n6uSs=", + "_parent": { + "$ref": "AAAAAAF5RWxGx9n5fHg=" + }, + "reference": { + "$ref": "AAAAAAF5RWo+Icga7No=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RWxGx9n7A0k=", + "_parent": { + "$ref": "AAAAAAF5RWxGx9n5fHg=" + }, + "reference": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RXgsE81LcLM=", + "_parent": { + "$ref": "AAAAAAF5RWo+Icga7No=" + }, + "name": "通过", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RXgsE81Ml9Y=", + "_parent": { + "$ref": "AAAAAAF5RXgsE81LcLM=" + }, + "reference": { + "$ref": "AAAAAAF5RWo+Icga7No=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RXgsE81Ncj4=", + "_parent": { + "$ref": "AAAAAAF5RXgsE81LcLM=" + }, + "reference": { + "$ref": "AAAAAAF5RXZT3reRJjE=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5RWzzg+QnXQo=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "doCalScheduleAllCycle", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RXS1D5dDHCY=", + "_parent": { + "$ref": "AAAAAAF5RWzzg+QnXQo=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RXS1D5dEJJs=", + "_parent": { + "$ref": "AAAAAAF5RXS1D5dDHCY=" + }, + "reference": { + "$ref": "AAAAAAF5RWzzg+QnXQo=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RXS1D5dF2N4=", + "_parent": { + "$ref": "AAAAAAF5RXS1D5dDHCY=" + }, + "reference": { + "$ref": "AAAAAAF5RWiYh6tdXHE=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5RXZT3reRJjE=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "是否是doCalScheduleAllCycle状态", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RXiiW9aJDaw=", + "_parent": { + "$ref": "AAAAAAF5RXZT3reRJjE=" + }, + "name": "不是", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RXiiW9aKkno=", + "_parent": { + "$ref": "AAAAAAF5RXiiW9aJDaw=" + }, + "reference": { + "$ref": "AAAAAAF5RXZT3reRJjE=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RXiiW9aL3M4=", + "_parent": { + "$ref": "AAAAAAF5RXiiW9aJDaw=" + }, + "reference": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RX50xeaOm84=", + "_parent": { + "$ref": "AAAAAAF5RXZT3reRJjE=" + }, + "name": "是", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RX50xeaPW6s=", + "_parent": { + "$ref": "AAAAAAF5RX50xeaOm84=" + }, + "reference": { + "$ref": "AAAAAAF5RXZT3reRJjE=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RX50xeaQJxA=", + "_parent": { + "$ref": "AAAAAAF5RX50xeaOm84=" + }, + "reference": { + "$ref": "AAAAAAF5RX4IzeDinbw=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5RX4IzeDinbw=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "检测其他测回是否有待补测数据", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RX9EYPFbm2U=", + "_parent": { + "$ref": "AAAAAAF5RX4IzeDinbw=" + }, + "name": "有", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RX9EYPFcd3k=", + "_parent": { + "$ref": "AAAAAAF5RX9EYPFbm2U=" + }, + "reference": { + "$ref": "AAAAAAF5RX4IzeDinbw=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RX9EYPFdtmc=", + "_parent": { + "$ref": "AAAAAAF5RX9EYPFbm2U=" + }, + "reference": { + "$ref": "AAAAAAF5RX8e8+6Tpi8=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RYXKoEPvmVE=", + "_parent": { + "$ref": "AAAAAAF5RX4IzeDinbw=" + }, + "name": "无", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RYXKoUPwWeY=", + "_parent": { + "$ref": "AAAAAAF5RYXKoEPvmVE=" + }, + "reference": { + "$ref": "AAAAAAF5RX4IzeDinbw=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RYXKoUPxCsE=", + "_parent": { + "$ref": "AAAAAAF5RYXKoEPvmVE=" + }, + "reference": { + "$ref": "AAAAAAF5RYWBNT536bM=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5RX8e8+6Tpi8=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "提示用户选择", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RYA6LQaqG8I=", + "_parent": { + "$ref": "AAAAAAF5RX8e8+6Tpi8=" + }, + "name": "跳转到相应测回", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RYA6LQaryvU=", + "_parent": { + "$ref": "AAAAAAF5RYA6LQaqG8I=" + }, + "reference": { + "$ref": "AAAAAAF5RX8e8+6Tpi8=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RYA6LQashgM=", + "_parent": { + "$ref": "AAAAAAF5RYA6LQaqG8I=" + }, + "reference": { + "$ref": "AAAAAAF5RX+92vrrsgo=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RYRxIiqJIUE=", + "_parent": { + "$ref": "AAAAAAF5RX8e8+6Tpi8=" + }, + "name": "忽略或取消", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RYRxIyqKuUY=", + "_parent": { + "$ref": "AAAAAAF5RYRxIiqJIUE=" + }, + "reference": { + "$ref": "AAAAAAF5RX8e8+6Tpi8=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RYRxIyqLN6Y=", + "_parent": { + "$ref": "AAAAAAF5RYRxIiqJIUE=" + }, + "reference": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5RX+92vrrsgo=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "切换测回", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RX/wMv3F6d4=", + "_parent": { + "$ref": "AAAAAAF5RX+92vrrsgo=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RX/wMv3GM64=", + "_parent": { + "$ref": "AAAAAAF5RX/wMv3F6d4=" + }, + "reference": { + "$ref": "AAAAAAF5RX+92vrrsgo=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RX/wMv3HIz8=", + "_parent": { + "$ref": "AAAAAAF5RX/wMv3F6d4=" + }, + "reference": { + "$ref": "AAAAAAF5QMaQUG/pf+g=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5RYWBNT536bM=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "检测其他测回是否有空数据", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RYbKCEsJsiQ=", + "_parent": { + "$ref": "AAAAAAF5RYWBNT536bM=" + }, + "name": "有", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RYbKCEsKkG0=", + "_parent": { + "$ref": "AAAAAAF5RYbKCEsJsiQ=" + }, + "reference": { + "$ref": "AAAAAAF5RYWBNT536bM=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RYbKCEsLR+0=", + "_parent": { + "$ref": "AAAAAAF5RYbKCEsJsiQ=" + }, + "reference": { + "$ref": "AAAAAAF5RX8e8+6Tpi8=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RYqgkaOybww=", + "_parent": { + "$ref": "AAAAAAF5RYWBNT536bM=" + }, + "name": "无空测回", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RYqgkaOzOcA=", + "_parent": { + "$ref": "AAAAAAF5RYqgkaOybww=" + }, + "reference": { + "$ref": "AAAAAAF5RYWBNT536bM=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RYqgkaO0Gyw=", + "_parent": { + "$ref": "AAAAAAF5RYqgkaOybww=" + }, + "reference": { + "$ref": "AAAAAAF5RYo1sJrxVxU=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5RYo1sJrxVxU=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "检测其他测回合法性", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RYuGza0vDqU=", + "_parent": { + "$ref": "AAAAAAF5RYo1sJrxVxU=" + }, + "name": "发现有测回未通过检测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RYuGza0wl4I=", + "_parent": { + "$ref": "AAAAAAF5RYuGza0vDqU=" + }, + "reference": { + "$ref": "AAAAAAF5RYo1sJrxVxU=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RYuGza0xzjs=", + "_parent": { + "$ref": "AAAAAAF5RYuGza0vDqU=" + }, + "reference": { + "$ref": "AAAAAAF5QKuCwkzWMuI=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RY5M4rVOVIM=", + "_parent": { + "$ref": "AAAAAAF5RYo1sJrxVxU=" + }, + "name": "全部通过检测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RY5M4rVPReU=", + "_parent": { + "$ref": "AAAAAAF5RY5M4rVOVIM=" + }, + "reference": { + "$ref": "AAAAAAF5RYo1sJrxVxU=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RY5M4rVQGdM=", + "_parent": { + "$ref": "AAAAAAF5RY5M4rVOVIM=" + }, + "reference": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5RY+P3cq56es=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "switchState2Idle", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RY/lWtHqafY=", + "_parent": { + "$ref": "AAAAAAF5RY+P3cq56es=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RY/lW9Hrql4=", + "_parent": { + "$ref": "AAAAAAF5RY/lWtHqafY=" + }, + "reference": { + "$ref": "AAAAAAF5RY+P3cq56es=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RY/lW9HsN84=", + "_parent": { + "$ref": "AAAAAAF5RY/lWtHqafY=" + }, + "reference": { + "$ref": "AAAAAAF5P5/CAk96MB0=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5RZAQp9i7BLM=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "查找待补测数据", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RZDsue7baAw=", + "_parent": { + "$ref": "AAAAAAF5RZAQp9i7BLM=" + }, + "name": "有", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RZDsue7cAPs=", + "_parent": { + "$ref": "AAAAAAF5RZDsue7baAw=" + }, + "reference": { + "$ref": "AAAAAAF5RZAQp9i7BLM=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RZDsue7dBLs=", + "_parent": { + "$ref": "AAAAAAF5RZDsue7baAw=" + }, + "reference": { + "$ref": "AAAAAAF5RY+P3cq56es=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RZE5JvvgNmk=", + "_parent": { + "$ref": "AAAAAAF5RZAQp9i7BLM=" + }, + "name": "无", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RZE5Jvvh7eI=", + "_parent": { + "$ref": "AAAAAAF5RZE5JvvgNmk=" + }, + "reference": { + "$ref": "AAAAAAF5RZAQp9i7BLM=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RZE5JvviTz0=", + "_parent": { + "$ref": "AAAAAAF5RZE5JvvgNmk=" + }, + "reference": { + "$ref": "AAAAAAF5RZEXNfhA9nA=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5RZEXNfhA9nA=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "查找空数据", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RZGEZgj773A=", + "_parent": { + "$ref": "AAAAAAF5RZEXNfhA9nA=" + }, + "name": "有", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RZGEZgj8gpI=", + "_parent": { + "$ref": "AAAAAAF5RZGEZgj773A=" + }, + "reference": { + "$ref": "AAAAAAF5RZEXNfhA9nA=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RZGEZgj9p0E=", + "_parent": { + "$ref": "AAAAAAF5RZGEZgj773A=" + }, + "reference": { + "$ref": "AAAAAAF5RY+P3cq56es=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5RZHb+g34JOw=", + "_parent": { + "$ref": "AAAAAAF5RZEXNfhA9nA=" + }, + "name": "无", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RZHb+g35LNk=", + "_parent": { + "$ref": "AAAAAAF5RZHb+g34JOw=" + }, + "reference": { + "$ref": "AAAAAAF5RZEXNfhA9nA=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5RZHb+g36Mvo=", + "_parent": { + "$ref": "AAAAAAF5RZHb+g34JOw=" + }, + "reference": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5RZ6XBTi4yu4=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "doMoveBack" + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5Sr6mm1dGVLo=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "doSurveyor", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5SsC4Mnft0S4=", + "_parent": { + "$ref": "AAAAAAF5Sr6mm1dGVLo=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5SsC4Mnfuteg=", + "_parent": { + "$ref": "AAAAAAF5SsC4Mnft0S4=" + }, + "reference": { + "$ref": "AAAAAAF5Sr6mm1dGVLo=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5SsC4Mnfv/lw=", + "_parent": { + "$ref": "AAAAAAF5SsC4Mnft0S4=" + }, + "reference": { + "$ref": "AAAAAAF5Sr+CM2b/I6Q=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5Sr+CM2b/I6Q=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "检测其他测回是否有正在测量数据", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5SsGTyovTQIg=", + "_parent": { + "$ref": "AAAAAAF5Sr+CM2b/I6Q=" + }, + "name": "有数据", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5SsGTy4vUxm0=", + "_parent": { + "$ref": "AAAAAAF5SsGTyovTQIg=" + }, + "reference": { + "$ref": "AAAAAAF5Sr+CM2b/I6Q=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5SsGTy4vVaZ0=", + "_parent": { + "$ref": "AAAAAAF5SsGTyovTQIg=" + }, + "reference": { + "$ref": "AAAAAAF5SsEjzYJ/d3I=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5SsLOnqvOHTI=", + "_parent": { + "$ref": "AAAAAAF5Sr+CM2b/I6Q=" + }, + "name": "无数据", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5SsLOnqvP3jk=", + "_parent": { + "$ref": "AAAAAAF5SsLOnqvOHTI=" + }, + "reference": { + "$ref": "AAAAAAF5Sr+CM2b/I6Q=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5SsLOnqvQ0Oc=", + "_parent": { + "$ref": "AAAAAAF5SsLOnqvOHTI=" + }, + "reference": { + "$ref": "AAAAAAF5SsKfZqcx8QM=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5SsEjzYJ/d3I=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "提示用户是否删除数据", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5SsIvB5pTO8k=", + "_parent": { + "$ref": "AAAAAAF5SsEjzYJ/d3I=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5SsIvB5pUHxM=", + "_parent": { + "$ref": "AAAAAAF5SsIvB5pTO8k=" + }, + "name": "忽略or取消", + "reference": { + "$ref": "AAAAAAF5SsEjzYJ/d3I=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5SsIvB5pVSwc=", + "_parent": { + "$ref": "AAAAAAF5SsIvB5pTO8k=" + }, + "reference": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5SsLnA66XUCE=", + "_parent": { + "$ref": "AAAAAAF5SsEjzYJ/d3I=" + }, + "name": "确定删除", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5SsLnBK6Y5d4=", + "_parent": { + "$ref": "AAAAAAF5SsLnA66XUCE=" + }, + "reference": { + "$ref": "AAAAAAF5SsEjzYJ/d3I=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5SsLnBK6ZnVU=", + "_parent": { + "$ref": "AAAAAAF5SsLnA66XUCE=" + }, + "reference": { + "$ref": "AAAAAAF5SsKfZqcx8QM=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5SsKfZqcx8QM=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "执行测量", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5Ssd4074UW6o=", + "_parent": { + "$ref": "AAAAAAF5SsKfZqcx8QM=" + }, + "name": "测量成功", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5Ssd41L4V+18=", + "_parent": { + "$ref": "AAAAAAF5Ssd4074UW6o=" + }, + "reference": { + "$ref": "AAAAAAF5SsKfZqcx8QM=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5Ssd41L4WIjg=", + "_parent": { + "$ref": "AAAAAAF5Ssd4074UW6o=" + }, + "reference": { + "$ref": "AAAAAAF5QJ6ahSPVJNg=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5SsfL78fSWbs=", + "_parent": { + "$ref": "AAAAAAF5SsKfZqcx8QM=" + }, + "name": "测量失败", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5SsfL78fTiS4=", + "_parent": { + "$ref": "AAAAAAF5SsfL78fSWbs=" + }, + "reference": { + "$ref": "AAAAAAF5SsKfZqcx8QM=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5SsfL78fU9Fc=", + "_parent": { + "$ref": "AAAAAAF5SsfL78fSWbs=" + }, + "reference": { + "$ref": "AAAAAAF5Sseu4cD1ALY=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5SsdYcrYFUTc=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "checkReadData" + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5Sseu4cD1ALY=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "SurveyorFailure" + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5Sst98gwopLY=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "是否闭合", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5SsxY9BsjL0w=", + "_parent": { + "$ref": "AAAAAAF5Sst98gwopLY=" + }, + "name": "否", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5SsxY9BskgpI=", + "_parent": { + "$ref": "AAAAAAF5SsxY9BsjL0w=" + }, + "reference": { + "$ref": "AAAAAAF5Sst98gwopLY=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5SsxY9Bsl5Tg=", + "_parent": { + "$ref": "AAAAAAF5SsxY9BsjL0w=" + }, + "reference": { + "$ref": "AAAAAAF5Ssw/MxbPNVc=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5SszpXCjkGRI=", + "_parent": { + "$ref": "AAAAAAF5Sst98gwopLY=" + }, + "name": "是", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5SszpXCjl/+8=", + "_parent": { + "$ref": "AAAAAAF5SszpXCjkGRI=" + }, + "reference": { + "$ref": "AAAAAAF5Sst98gwopLY=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5SszpXCjmncs=", + "_parent": { + "$ref": "AAAAAAF5SszpXCjkGRI=" + }, + "reference": { + "$ref": "AAAAAAF5SsyaiR+Q8s8=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5Ssw/MxbPNVc=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "checkHalfCycleZero" + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5SsyaiR+Q8s8=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "执行归零检测", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5Ss0jcC4aijg=", + "_parent": { + "$ref": "AAAAAAF5SsyaiR+Q8s8=" + }, + "name": "成功", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5Ss0jcC4bSQM=", + "_parent": { + "$ref": "AAAAAAF5Ss0jcC4aijg=" + }, + "reference": { + "$ref": "AAAAAAF5SsyaiR+Q8s8=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5Ss0jcC4cI98=", + "_parent": { + "$ref": "AAAAAAF5Ss0jcC4aijg=" + }, + "reference": { + "$ref": "AAAAAAF5Ssw/MxbPNVc=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5Ss1sYzc1nBg=", + "_parent": { + "$ref": "AAAAAAF5SsyaiR+Q8s8=" + }, + "name": "未成功", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5Ss1sYzc28DU=", + "_parent": { + "$ref": "AAAAAAF5Ss1sYzc1nBg=" + }, + "reference": { + "$ref": "AAAAAAF5SsyaiR+Q8s8=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5Ss1sYzc3JbA=", + "_parent": { + "$ref": "AAAAAAF5Ss1sYzc1nBg=" + }, + "reference": { + "$ref": "AAAAAAF5Ss1QlzKrDlo=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5Ss1QlzKrDlo=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "isReady2CCheck", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5StBNjXaXraA=", + "_parent": { + "$ref": "AAAAAAF5Ss1QlzKrDlo=" + }, + "name": "满足条件", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5StBNjXaYthc=", + "_parent": { + "$ref": "AAAAAAF5StBNjXaXraA=" + }, + "reference": { + "$ref": "AAAAAAF5Ss1QlzKrDlo=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5StBNjXaZel4=", + "_parent": { + "$ref": "AAAAAAF5StBNjXaXraA=" + }, + "reference": { + "$ref": "AAAAAAF5P5nMrk1mLCw=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5StIhppW+/2s=", + "_parent": { + "$ref": "AAAAAAF5Ss1QlzKrDlo=" + }, + "name": "不满足", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5StIhppW/3D0=", + "_parent": { + "$ref": "AAAAAAF5StIhppW+/2s=" + }, + "reference": { + "$ref": "AAAAAAF5Ss1QlzKrDlo=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5StIhppXAozs=", + "_parent": { + "$ref": "AAAAAAF5StIhppW+/2s=" + }, + "reference": { + "$ref": "AAAAAAF5StIJ5pEQ/FY=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5Ss//822MKvk=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "check2C" + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5StIJ5pEQ/FY=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "doRecordClean", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5StrWhBOl298=", + "_parent": { + "$ref": "AAAAAAF5StIJ5pEQ/FY=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5StrWhBOmfyU=", + "_parent": { + "$ref": "AAAAAAF5StrWhBOl298=" + }, + "reference": { + "$ref": "AAAAAAF5StIJ5pEQ/FY=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5StrWhBOnvuo=", + "_parent": { + "$ref": "AAAAAAF5StrWhBOl298=" + }, + "reference": { + "$ref": "AAAAAAF5Stp87A6d2HY=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5StaqWtrE9ro=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "用户选择是否跳转到其他测回", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5StecvuuUiTw=", + "_parent": { + "$ref": "AAAAAAF5StaqWtrE9ro=" + }, + "name": "跳转测回后补测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5StecvuuVcKw=", + "_parent": { + "$ref": "AAAAAAF5StecvuuUiTw=" + }, + "reference": { + "$ref": "AAAAAAF5StaqWtrE9ro=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5StecvuuWIOM=", + "_parent": { + "$ref": "AAAAAAF5StecvuuUiTw=" + }, + "reference": { + "$ref": "AAAAAAF5QMaQUG/pf+g=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5Stg/N/byEbA=", + "_parent": { + "$ref": "AAAAAAF5StaqWtrE9ro=" + }, + "name": "取消or忽略", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5Stg/N/bz2/4=", + "_parent": { + "$ref": "AAAAAAF5Stg/N/byEbA=" + }, + "reference": { + "$ref": "AAAAAAF5StaqWtrE9ro=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5Stg/N/b0VQA=", + "_parent": { + "$ref": "AAAAAAF5Stg/N/byEbA=" + }, + "reference": { + "$ref": "AAAAAAF5QJjLZBMJQJ8=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF5Stp87A6d2HY=", + "_parent": { + "$ref": "AAAAAAFElm6BOFNpegQ=" + }, + "name": "isSingleCycleCompleted", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5Styi5Rfz3o0=", + "_parent": { + "$ref": "AAAAAAF5Stp87A6d2HY=" + }, + "name": "完成", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5Styi5Rf0fJk=", + "_parent": { + "$ref": "AAAAAAF5Styi5Rfz3o0=" + }, + "reference": { + "$ref": "AAAAAAF5Stp87A6d2HY=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5Styi5Rf1+Tk=", + "_parent": { + "$ref": "AAAAAAF5Styi5Rfz3o0=" + }, + "reference": { + "$ref": "AAAAAAF5QKE6OTfx/D4=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF5St1uUR+mHuk=", + "_parent": { + "$ref": "AAAAAAF5Stp87A6d2HY=" + }, + "name": "未完成", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5St1uUR+nHko=", + "_parent": { + "$ref": "AAAAAAF5St1uUR+mHuk=" + }, + "reference": { + "$ref": "AAAAAAF5Stp87A6d2HY=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF5St1uUR+oJAQ=", + "_parent": { + "$ref": "AAAAAAF5St1uUR+mHuk=" + }, + "reference": { + "$ref": "AAAAAAF5QMaQUG/pf+g=" + } + } + } + ] + } + ] + }, + { + "_type": "UMLProfile", + "_id": "AAAAAAFElnEzslS1AuE=", + "_parent": { + "$ref": "AAAAAAFElm5XMFNoGY0=" + }, + "name": "UMLStandardProfile", + "ownedElements": [ + { + "_type": "UMLProfileDiagram", + "_id": "AAAAAAFElnFUQFS4mT4=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "StandardProfileL2", + "ownedViews": [ + { + "_type": "UMLMetaClassView", + "_id": "AAAAAAFElnFrT1S8vVg=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFElnFrT1S7Kic=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFElnFrT1S9WOE=", + "_parent": { + "$ref": "AAAAAAFElnFrT1S8vVg=" + }, + "model": { + "$ref": "AAAAAAFElnFrT1S7Kic=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFElnFrT1S+aHM=", + "_parent": { + "$ref": "AAAAAAFElnFrT1S9WOE=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": -44, + "top": -16, + "width": 1, + "height": 12 + }, + { + "_type": "LabelView", + "_id": "AAAAAAFElnFrT1S/1HM=", + "_parent": { + "$ref": "AAAAAAFElnFrT1S9WOE=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 57, + "top": 59, + "width": 81, + "height": 12, + "text": "«metaClass»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFElnFrT1TAD0M=", + "_parent": { + "$ref": "AAAAAAFElnFrT1S9WOE=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;1", + "containerChangeable": true, + "containerExtending": true, + "left": 57, + "top": 73, + "width": 81, + "height": 12, + "text": "UMLClassifier" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFElnFrT1TBaUI=", + "_parent": { + "$ref": "AAAAAAFElnFrT1S9WOE=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": -44, + "top": -16, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFElnFrT1TCF/Y=", + "_parent": { + "$ref": "AAAAAAFElnFrT1S9WOE=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": -44, + "top": -16, + "width": 1, + "height": 12, + "horizontalAlignment": 1 + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 52, + "top": 52, + "width": 91, + "height": 38, + "stereotypeLabel": { + "$ref": "AAAAAAFElnFrT1S/1HM=" + }, + "nameLabel": { + "$ref": "AAAAAAFElnFrT1TAD0M=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFElnFrT1TBaUI=" + }, + "propertyLabel": { + "$ref": "AAAAAAFElnFrT1TCF/Y=" + } + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 52, + "top": 52, + "width": 91, + "height": 101, + "nameCompartment": { + "$ref": "AAAAAAFElnFrT1S9WOE=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFElnF1nFTadPw=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFElnF1nFTY/Sw=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqCEfLOas=", + "_parent": { + "$ref": "AAAAAAFElnF1nFTadPw=" + }, + "model": { + "$ref": "AAAAAAFElnF1nFTY/Sw=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFElnF1nFTbplQ=", + "_parent": { + "$ref": "AAAAAAFElnF1nFTadPw=" + }, + "model": { + "$ref": "AAAAAAFElnF1nFTY/Sw=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFElnF1nVTcCng=", + "_parent": { + "$ref": "AAAAAAFElnF1nFTbplQ=" + }, + "visible": false, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 60, + "top": -116, + "width": 1, + "height": 12 + }, + { + "_type": "LabelView", + "_id": "AAAAAAFElnF1nVTd3xg=", + "_parent": { + "$ref": "AAAAAAFElnF1nFTbplQ=" + }, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 213, + "top": 55, + "width": 83, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFElnF1nVTewJM=", + "_parent": { + "$ref": "AAAAAAFElnF1nFTbplQ=" + }, + "font": "Arial;12;1", + "containerChangeable": true, + "containerExtending": true, + "left": 213, + "top": 69, + "width": 83, + "height": 12, + "text": "Realization" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFElnF1nVTfQRQ=", + "_parent": { + "$ref": "AAAAAAFElnF1nFTbplQ=" + }, + "visible": false, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 60, + "top": -116, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFElnF1nVTgrV8=", + "_parent": { + "$ref": "AAAAAAFElnF1nFTbplQ=" + }, + "visible": false, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 60, + "top": -116, + "width": 1, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 208, + "top": 48, + "width": 93, + "height": 38, + "stereotypeLabel": { + "$ref": "AAAAAAFElnF1nVTd3xg=" + }, + "nameLabel": { + "$ref": "AAAAAAFElnF1nVTewJM=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFElnF1nVTfQRQ=" + }, + "propertyLabel": { + "$ref": "AAAAAAFElnF1nVTgrV8=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFElnF1nVThfqA=", + "_parent": { + "$ref": "AAAAAAFElnF1nFTadPw=" + }, + "model": { + "$ref": "AAAAAAFElnF1nFTY/Sw=" + }, + "visible": false, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 208, + "top": 86, + "width": 93, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFElnF1nVTiFXA=", + "_parent": { + "$ref": "AAAAAAFElnF1nFTadPw=" + }, + "model": { + "$ref": "AAAAAAFElnF1nFTY/Sw=" + }, + "visible": false, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 208, + "top": 96, + "width": 93, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFElnF1nVTjasU=", + "_parent": { + "$ref": "AAAAAAFElnF1nFTadPw=" + }, + "model": { + "$ref": "AAAAAAFElnF1nFTY/Sw=" + }, + "visible": false, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 60, + "top": -116, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 208, + "top": 48, + "width": 93, + "height": 38, + "nameCompartment": { + "$ref": "AAAAAAFElnF1nFTbplQ=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFElnF1nVThfqA=" + }, + "operationCompartment": { + "$ref": "AAAAAAFElnF1nVTiFXA=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqCEfLOas=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFElnF1nVTjasU=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFElnGGLFUGHnM=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFElnGGLFUFZFA=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFElnGGLFUH+8s=", + "_parent": { + "$ref": "AAAAAAFElnGGLFUGHnM=" + }, + "model": { + "$ref": "AAAAAAFElnGGLFUFZFA=" + }, + "visible": false, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 174, + "top": 73, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFElnGGLFUGHnM=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFElnGGLFUIOR8=", + "_parent": { + "$ref": "AAAAAAFElnGGLFUGHnM=" + }, + "model": { + "$ref": "AAAAAAFElnGGLFUFZFA=" + }, + "visible": null, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 174, + "top": 88, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFElnGGLFUGHnM=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFElnGGLFUJv6k=", + "_parent": { + "$ref": "AAAAAAFElnGGLFUGHnM=" + }, + "model": { + "$ref": "AAAAAAFElnGGLFUFZFA=" + }, + "visible": false, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 175, + "top": 43, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFElnGGLFUGHnM=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "head": { + "$ref": "AAAAAAFElnFrT1S8vVg=" + }, + "tail": { + "$ref": "AAAAAAFElnF1nFTadPw=" + }, + "points": "208:64;142:64", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFElnGGLFUH+8s=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFElnGGLFUIOR8=" + }, + "propertyLabel": { + "$ref": "AAAAAAFElnGGLFUJv6k=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFElnJRglVMyB8=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFElnJRglVKSoc=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqCkfpKls=", + "_parent": { + "$ref": "AAAAAAFElnJRglVMyB8=" + }, + "model": { + "$ref": "AAAAAAFElnJRglVKSoc=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFElnJRglVN/RI=", + "_parent": { + "$ref": "AAAAAAFElnJRglVMyB8=" + }, + "model": { + "$ref": "AAAAAAFElnJRglVKSoc=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFElnJRglVO7ow=", + "_parent": { + "$ref": "AAAAAAFElnJRglVN/RI=" + }, + "visible": false, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 104, + "top": -176, + "width": 1, + "height": 12 + }, + { + "_type": "LabelView", + "_id": "AAAAAAFElnJRglVPiBM=", + "_parent": { + "$ref": "AAAAAAFElnJRglVN/RI=" + }, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 217, + "top": 119, + "width": 74.73593139648438, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFElnJRglVQT1k=", + "_parent": { + "$ref": "AAAAAAFElnJRglVN/RI=" + }, + "font": "Arial;12;1", + "containerChangeable": true, + "containerExtending": true, + "left": 217, + "top": 133, + "width": 74.73593139648438, + "height": 12, + "text": "Specification" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFElnJRglVRdk8=", + "_parent": { + "$ref": "AAAAAAFElnJRglVN/RI=" + }, + "visible": false, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 104, + "top": -176, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFElnJRglVSFic=", + "_parent": { + "$ref": "AAAAAAFElnJRglVN/RI=" + }, + "visible": false, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 104, + "top": -176, + "width": 1, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 212, + "top": 112, + "width": 84.73593139648438, + "height": 38, + "stereotypeLabel": { + "$ref": "AAAAAAFElnJRglVPiBM=" + }, + "nameLabel": { + "$ref": "AAAAAAFElnJRglVQT1k=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFElnJRglVRdk8=" + }, + "propertyLabel": { + "$ref": "AAAAAAFElnJRglVSFic=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFElnJRglVTXPE=", + "_parent": { + "$ref": "AAAAAAFElnJRglVMyB8=" + }, + "model": { + "$ref": "AAAAAAFElnJRglVKSoc=" + }, + "visible": false, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 212, + "top": 150, + "width": 84, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFElnJRglVUe0c=", + "_parent": { + "$ref": "AAAAAAFElnJRglVMyB8=" + }, + "model": { + "$ref": "AAAAAAFElnJRglVKSoc=" + }, + "visible": false, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 212, + "top": 160, + "width": 84, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFElnJRg1VVWNU=", + "_parent": { + "$ref": "AAAAAAFElnJRglVMyB8=" + }, + "model": { + "$ref": "AAAAAAFElnJRglVKSoc=" + }, + "visible": false, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 104, + "top": -176, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 212, + "top": 112, + "width": 84.73593139648438, + "height": 38, + "nameCompartment": { + "$ref": "AAAAAAFElnJRglVN/RI=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFElnJRglVTXPE=" + }, + "operationCompartment": { + "$ref": "AAAAAAFElnJRglVUe0c=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqCkfpKls=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFElnJRg1VVWNU=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFElnKVuVV5hVg=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFElnKVuVV4pBU=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFElnKVuVV6VLo=", + "_parent": { + "$ref": "AAAAAAFElnKVuVV5hVg=" + }, + "model": { + "$ref": "AAAAAAFElnKVuVV4pBU=" + }, + "visible": false, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 176, + "top": 141, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFElnKVuVV5hVg=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFElnKVuVV7m9U=", + "_parent": { + "$ref": "AAAAAAFElnKVuVV5hVg=" + }, + "model": { + "$ref": "AAAAAAFElnKVuVV4pBU=" + }, + "visible": null, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 176, + "top": 156, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFElnKVuVV5hVg=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFElnKVuVV8bvU=", + "_parent": { + "$ref": "AAAAAAFElnKVuVV5hVg=" + }, + "model": { + "$ref": "AAAAAAFElnKVuVV4pBU=" + }, + "visible": false, + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 177, + "top": 111, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFElnKVuVV5hVg=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "head": { + "$ref": "AAAAAAFElnFrT1S8vVg=" + }, + "tail": { + "$ref": "AAAAAAFElnJRglVMyB8=" + }, + "points": "212:132;142:132", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFElnKVuVV6VLo=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFElnKVuVV7m9U=" + }, + "propertyLabel": { + "$ref": "AAAAAAFElnKVuVV8bvU=" + } + }, + { + "_type": "UMLMetaClassView", + "_id": "AAAAAAFFJsZbpDNpnkE=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFJsZbpDNobIs=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFJsZbpTNq6XM=", + "_parent": { + "$ref": "AAAAAAFFJsZbpDNpnkE=" + }, + "model": { + "$ref": "AAAAAAFFJsZbpDNobIs=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFJsZbpTNrbHw=", + "_parent": { + "$ref": "AAAAAAFFJsZbpTNq6XM=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 561, + "top": 209, + "width": 87, + "height": 12, + "text": "«metaClass»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFJsZbpTNsdGc=", + "_parent": { + "$ref": "AAAAAAFFJsZbpTNq6XM=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;1", + "containerChangeable": true, + "containerExtending": true, + "left": 561, + "top": 223, + "width": 87, + "height": 12, + "text": "UMLClass" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFJsZbpTNtikk=", + "_parent": { + "$ref": "AAAAAAFFJsZbpTNq6XM=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 1500, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFJsZbpTNuOXU=", + "_parent": { + "$ref": "AAAAAAFFJsZbpTNq6XM=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 1500, + "width": 1, + "height": 12, + "horizontalAlignment": 1 + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 556, + "top": 204, + "width": 97, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFJsZbpTNrbHw=" + }, + "nameLabel": { + "$ref": "AAAAAAFFJsZbpTNsdGc=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFJsZbpTNtikk=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFJsZbpTNuOXU=" + } + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerChangeable": true, + "containerExtending": true, + "left": 556, + "top": 204, + "width": 97, + "height": 305, + "nameCompartment": { + "$ref": "AAAAAAFFJsZbpTNq6XM=" + } + }, + { + "_type": "UMLMetaClassView", + "_id": "AAAAAAFFwKqhJFq1z2Y=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwKqhJFq06mA=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwKqhJFq2eQM=", + "_parent": { + "$ref": "AAAAAAFFwKqhJFq1z2Y=" + }, + "model": { + "$ref": "AAAAAAFFwKqhJFq06mA=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwKqhJFq3hUU=", + "_parent": { + "$ref": "AAAAAAFFwKqhJFq2eQM=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 57, + "top": 209, + "width": 79, + "height": 12, + "text": "«metaClass»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKqhJFq4Vb4=", + "_parent": { + "$ref": "AAAAAAFFwKqhJFq2eQM=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;1", + "containerExtending": true, + "left": 57, + "top": 223, + "width": 79, + "height": 12, + "text": "UMLArtifact" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKqhJFq5GlQ=", + "_parent": { + "$ref": "AAAAAAFFwKqhJFq2eQM=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": -12, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKqhJFq6Fls=", + "_parent": { + "$ref": "AAAAAAFFwKqhJFq2eQM=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": -12, + "height": 12, + "horizontalAlignment": 1 + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 52, + "top": 204, + "width": 89, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwKqhJFq3hUU=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwKqhJFq4Vb4=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwKqhJFq5GlQ=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwKqhJFq6Fls=" + } + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 52, + "top": 204, + "width": 89, + "height": 329, + "nameCompartment": { + "$ref": "AAAAAAFFwKqhJFq2eQM=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwKsvdVrTyNI=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwKsvdVrRJUQ=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqDUglDBo=", + "_parent": { + "$ref": "AAAAAAFFwKsvdVrTyNI=" + }, + "model": { + "$ref": "AAAAAAFFwKsvdVrRJUQ=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwKsvdVrUE8w=", + "_parent": { + "$ref": "AAAAAAFFwKsvdVrTyNI=" + }, + "model": { + "$ref": "AAAAAAFFwKsvdVrRJUQ=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwKsvdVrVvYg=", + "_parent": { + "$ref": "AAAAAAFFwKsvdVrUE8w=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 237, + "top": 209, + "width": 119, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKsvdVrW/Dg=", + "_parent": { + "$ref": "AAAAAAFFwKsvdVrUE8w=" + }, + "font": "Arial;12;3", + "containerExtending": true, + "left": 237, + "top": 223, + "width": 119, + "height": 12, + "text": "File" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKsvdVrXXrQ=", + "_parent": { + "$ref": "AAAAAAFFwKsvdVrUE8w=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 48, + "top": -12, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKsvdVrYnv8=", + "_parent": { + "$ref": "AAAAAAFFwKsvdVrUE8w=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 48, + "top": -12, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 232, + "top": 204, + "width": 129, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwKsvdVrVvYg=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwKsvdVrW/Dg=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwKsvdVrXXrQ=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwKsvdVrYnv8=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwKsvdVrZA0U=", + "_parent": { + "$ref": "AAAAAAFFwKsvdVrTyNI=" + }, + "model": { + "$ref": "AAAAAAFFwKsvdVrRJUQ=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 248, + "top": 236, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwKsvdlraVvA=", + "_parent": { + "$ref": "AAAAAAFFwKsvdVrTyNI=" + }, + "model": { + "$ref": "AAAAAAFFwKsvdVrRJUQ=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 248, + "top": 236, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwKsvdlrbd2U=", + "_parent": { + "$ref": "AAAAAAFFwKsvdVrTyNI=" + }, + "model": { + "$ref": "AAAAAAFFwKsvdVrRJUQ=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 32, + "top": -8, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 232, + "top": 204, + "width": 129, + "height": 37, + "nameCompartment": { + "$ref": "AAAAAAFFwKsvdVrUE8w=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwKsvdVrZA0U=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwKsvdlraVvA=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqDUglDBo=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwKsvdlrbd2U=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwKtwS1r8DQQ=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwKtwS1r6wew=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqDUg7My0=", + "_parent": { + "$ref": "AAAAAAFFwKtwS1r8DQQ=" + }, + "model": { + "$ref": "AAAAAAFFwKtwS1r6wew=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwKtwS1r9YJ4=", + "_parent": { + "$ref": "AAAAAAFFwKtwS1r8DQQ=" + }, + "model": { + "$ref": "AAAAAAFFwKtwS1r6wew=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwKtwS1r+fw8=", + "_parent": { + "$ref": "AAAAAAFFwKtwS1r9YJ4=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 189, + "top": 313, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKtwS1r/Lsw=", + "_parent": { + "$ref": "AAAAAAFFwKtwS1r9YJ4=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 189, + "top": 327, + "width": 72.51593017578125, + "height": 12, + "text": "Document" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKtwS1sAGYA=", + "_parent": { + "$ref": "AAAAAAFFwKtwS1r9YJ4=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 24, + "top": 24, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKtwS1sB7y4=", + "_parent": { + "$ref": "AAAAAAFFwKtwS1r9YJ4=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 24, + "top": 24, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 184, + "top": 308, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwKtwS1r+fw8=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwKtwS1r/Lsw=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwKtwS1sAGYA=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwKtwS1sB7y4=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwKtwTFsC02k=", + "_parent": { + "$ref": "AAAAAAFFwKtwS1r8DQQ=" + }, + "model": { + "$ref": "AAAAAAFFwKtwS1r6wew=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 192, + "top": 352, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwKtwTFsD5lc=", + "_parent": { + "$ref": "AAAAAAFFwKtwS1r8DQQ=" + }, + "model": { + "$ref": "AAAAAAFFwKtwS1r6wew=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 192, + "top": 352, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwKtwTFsEQlE=", + "_parent": { + "$ref": "AAAAAAFFwKtwS1r8DQQ=" + }, + "model": { + "$ref": "AAAAAAFFwKtwS1r6wew=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 16, + "top": 16, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 184, + "top": 308, + "width": 82.51593017578125, + "height": 36, + "nameCompartment": { + "$ref": "AAAAAAFFwKtwS1r9YJ4=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwKtwTFsC02k=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwKtwTFsD5lc=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqDUg7My0=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwKtwTFsEQlE=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwKuBulskCVg=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwKuBulsidLQ=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqDkhRFFg=", + "_parent": { + "$ref": "AAAAAAFFwKuBulskCVg=" + }, + "model": { + "$ref": "AAAAAAFFwKuBulsidLQ=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwKuBulsld0g=", + "_parent": { + "$ref": "AAAAAAFFwKuBulskCVg=" + }, + "model": { + "$ref": "AAAAAAFFwKuBulsidLQ=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwKuBulsmb/s=", + "_parent": { + "$ref": "AAAAAAFFwKuBulsld0g=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 257, + "top": 357, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKuBulsnKBI=", + "_parent": { + "$ref": "AAAAAAFFwKuBulsld0g=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 257, + "top": 371, + "width": 72.51593017578125, + "height": 12, + "text": "Executable" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKuBu1soKF0=", + "_parent": { + "$ref": "AAAAAAFFwKuBulsld0g=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 96, + "top": -48, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKuBu1spOXA=", + "_parent": { + "$ref": "AAAAAAFFwKuBulsld0g=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 96, + "top": -48, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 252, + "top": 352, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwKuBulsmb/s=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwKuBulsnKBI=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwKuBu1soKF0=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwKuBu1spOXA=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwKuBu1sqPhk=", + "_parent": { + "$ref": "AAAAAAFFwKuBulskCVg=" + }, + "model": { + "$ref": "AAAAAAFFwKuBulsidLQ=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 284, + "top": 372, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwKuBu1srnoE=", + "_parent": { + "$ref": "AAAAAAFFwKuBulskCVg=" + }, + "model": { + "$ref": "AAAAAAFFwKuBulsidLQ=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 284, + "top": 372, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwKuBu1ssVVg=", + "_parent": { + "$ref": "AAAAAAFFwKuBulskCVg=" + }, + "model": { + "$ref": "AAAAAAFFwKuBulsidLQ=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 64, + "top": -32, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 252, + "top": 352, + "width": 82.51593017578125, + "height": 36, + "nameCompartment": { + "$ref": "AAAAAAFFwKuBulsld0g=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwKuBu1sqPhk=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwKuBu1srnoE=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqDkhRFFg=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwKuBu1ssVVg=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwKuIMltMJw4=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwKuIMltKnQQ=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqD0hnnhc=", + "_parent": { + "$ref": "AAAAAAFFwKuIMltMJw4=" + }, + "model": { + "$ref": "AAAAAAFFwKuIMltKnQQ=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwKuIMltNJK8=", + "_parent": { + "$ref": "AAAAAAFFwKuIMltMJw4=" + }, + "model": { + "$ref": "AAAAAAFFwKuIMltKnQQ=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwKuIM1tO63M=", + "_parent": { + "$ref": "AAAAAAFFwKuIMltNJK8=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 321, + "top": 405, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKuIM1tPj60=", + "_parent": { + "$ref": "AAAAAAFFwKuIMltNJK8=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 321, + "top": 419, + "width": 72.51593017578125, + "height": 12, + "text": "Library" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKuIM1tQD7A=", + "_parent": { + "$ref": "AAAAAAFFwKuIMltNJK8=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 132, + "top": -108, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKuIM1tRSSY=", + "_parent": { + "$ref": "AAAAAAFFwKuIMltNJK8=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 132, + "top": -108, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 316, + "top": 400, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwKuIM1tO63M=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwKuIM1tPj60=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwKuIM1tQD7A=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwKuIM1tRSSY=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwKuIM1tSiN4=", + "_parent": { + "$ref": "AAAAAAFFwKuIMltMJw4=" + }, + "model": { + "$ref": "AAAAAAFFwKuIMltKnQQ=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 360, + "top": 400, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwKuIM1tTPjo=", + "_parent": { + "$ref": "AAAAAAFFwKuIMltMJw4=" + }, + "model": { + "$ref": "AAAAAAFFwKuIMltKnQQ=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 360, + "top": 400, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwKuIM1tUHbM=", + "_parent": { + "$ref": "AAAAAAFFwKuIMltMJw4=" + }, + "model": { + "$ref": "AAAAAAFFwKuIMltKnQQ=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 88, + "top": -72, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 316, + "top": 400, + "width": 82.51593017578125, + "height": 36, + "nameCompartment": { + "$ref": "AAAAAAFFwKuIMltNJK8=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwKuIM1tSiN4=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwKuIM1tTPjo=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqD0hnnhc=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwKuIM1tUHbM=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwKuS0lt0dAE=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwKuS0ltysPk=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqEEh93KM=", + "_parent": { + "$ref": "AAAAAAFFwKuS0lt0dAE=" + }, + "model": { + "$ref": "AAAAAAFFwKuS0ltysPk=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwKuS0lt1+MM=", + "_parent": { + "$ref": "AAAAAAFFwKuS0lt0dAE=" + }, + "model": { + "$ref": "AAAAAAFFwKuS0ltysPk=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwKuS0lt2XgE=", + "_parent": { + "$ref": "AAAAAAFFwKuS0lt1+MM=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 385, + "top": 453, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKuS0lt36r8=", + "_parent": { + "$ref": "AAAAAAFFwKuS0lt1+MM=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 385, + "top": 467, + "width": 72.51593017578125, + "height": 12, + "text": "Script" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKuS0lt4pP4=", + "_parent": { + "$ref": "AAAAAAFFwKuS0lt1+MM=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 180, + "top": -180, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKuS0lt5mi4=", + "_parent": { + "$ref": "AAAAAAFFwKuS0lt1+MM=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 180, + "top": -180, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 380, + "top": 448, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwKuS0lt2XgE=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwKuS0lt36r8=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwKuS0lt4pP4=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwKuS0lt5mi4=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwKuS0lt6gjg=", + "_parent": { + "$ref": "AAAAAAFFwKuS0lt0dAE=" + }, + "model": { + "$ref": "AAAAAAFFwKuS0ltysPk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 440, + "top": 424, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwKuS0lt7fo0=", + "_parent": { + "$ref": "AAAAAAFFwKuS0lt0dAE=" + }, + "model": { + "$ref": "AAAAAAFFwKuS0ltysPk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 440, + "top": 424, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwKuS0lt8w2A=", + "_parent": { + "$ref": "AAAAAAFFwKuS0lt0dAE=" + }, + "model": { + "$ref": "AAAAAAFFwKuS0ltysPk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 120, + "top": -120, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 380, + "top": 448, + "width": 82.51593017578125, + "height": 36, + "nameCompartment": { + "$ref": "AAAAAAFFwKuS0lt1+MM=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwKuS0lt6gjg=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwKuS0lt7fo0=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqEEh93KM=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwKuS0lt8w2A=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwKueMluc5bE=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwKueMVuaLXM=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqEUiTykw=", + "_parent": { + "$ref": "AAAAAAFFwKueMluc5bE=" + }, + "model": { + "$ref": "AAAAAAFFwKueMVuaLXM=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwKueMludFfk=", + "_parent": { + "$ref": "AAAAAAFFwKueMluc5bE=" + }, + "model": { + "$ref": "AAAAAAFFwKueMVuaLXM=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwKueMlueAco=", + "_parent": { + "$ref": "AAAAAAFFwKueMludFfk=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 445, + "top": 501, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKueMluflfo=", + "_parent": { + "$ref": "AAAAAAFFwKueMludFfk=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 445, + "top": 515, + "width": 72.51593017578125, + "height": 12, + "text": "Source" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKueMlughos=", + "_parent": { + "$ref": "AAAAAAFFwKueMludFfk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "top": -108, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwKueMluhfws=", + "_parent": { + "$ref": "AAAAAAFFwKueMludFfk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "top": -108, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 440, + "top": 496, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwKueMlueAco=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwKueMluflfo=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwKueMlughos=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwKueMluhfws=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwKueMluihu4=", + "_parent": { + "$ref": "AAAAAAFFwKueMluc5bE=" + }, + "model": { + "$ref": "AAAAAAFFwKueMVuaLXM=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 440, + "top": 500, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwKueMlujEyo=", + "_parent": { + "$ref": "AAAAAAFFwKueMluc5bE=" + }, + "model": { + "$ref": "AAAAAAFFwKueMVuaLXM=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 440, + "top": 500, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwKueMlukJo8=", + "_parent": { + "$ref": "AAAAAAFFwKueMluc5bE=" + }, + "model": { + "$ref": "AAAAAAFFwKueMVuaLXM=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "top": -72, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 440, + "top": 496, + "width": 82.51593017578125, + "height": 36, + "nameCompartment": { + "$ref": "AAAAAAFFwKueMludFfk=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwKueMluihu4=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwKueMlujEyo=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqEUiTykw=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwKueMlukJo8=" + } + }, + { + "_type": "UMLGeneralizationView", + "_id": "AAAAAAFFwKzkslvYVdw=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwKzkslvX4gU=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwKzkslvZbd0=", + "_parent": { + "$ref": "AAAAAAFFwKzkslvYVdw=" + }, + "model": { + "$ref": "AAAAAAFFwKzkslvX4gU=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 258, + "top": 267, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwKzkslvYVdw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwKzks1vasdU=", + "_parent": { + "$ref": "AAAAAAFFwKzkslvYVdw=" + }, + "model": { + "$ref": "AAAAAAFFwKzkslvX4gU=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 258, + "top": 252, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwKzkslvYVdw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwKzks1vby/c=", + "_parent": { + "$ref": "AAAAAAFFwKzkslvYVdw=" + }, + "model": { + "$ref": "AAAAAAFFwKzkslvX4gU=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 258, + "top": 297, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwKzkslvYVdw=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwKsvdVrTyNI=" + }, + "tail": { + "$ref": "AAAAAAFFwKtwS1r8DQQ=" + }, + "points": "216:308;216:288;300:288;300:240", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwKzkslvZbd0=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwKzks1vasdU=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwKzks1vby/c=" + } + }, + { + "_type": "UMLGeneralizationView", + "_id": "AAAAAAFFwKzsCVvpt2A=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwKzsCVvo11g=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwKzsCVvqAUg=", + "_parent": { + "$ref": "AAAAAAFFwKzsCVvpt2A=" + }, + "model": { + "$ref": "AAAAAAFFwKzsCVvo11g=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 285, + "top": 289, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwKzsCVvpt2A=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwKzsCVvrTi8=", + "_parent": { + "$ref": "AAAAAAFFwKzsCVvpt2A=" + }, + "model": { + "$ref": "AAAAAAFFwKzsCVvo11g=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 270, + "top": 289, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwKzsCVvpt2A=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwKzsCVvsewQ=", + "_parent": { + "$ref": "AAAAAAFFwKzsCVvpt2A=" + }, + "model": { + "$ref": "AAAAAAFFwKzsCVvo11g=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 314, + "top": 290, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwKzsCVvpt2A=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwKsvdVrTyNI=" + }, + "tail": { + "$ref": "AAAAAAFFwKuBulskCVg=" + }, + "points": "300:352;300:240", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwKzsCVvqAUg=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwKzsCVvrTi8=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwKzsCVvsewQ=" + } + }, + { + "_type": "UMLGeneralizationView", + "_id": "AAAAAAFFwKzxcVv6A2c=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwKzxcVv56Dg=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwKzxcVv7wpA=", + "_parent": { + "$ref": "AAAAAAFFwKzxcVv6A2c=" + }, + "model": { + "$ref": "AAAAAAFFwKzxcVv56Dg=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 327, + "top": 297, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwKzxcVv6A2c=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwKzxcVv8NxM=", + "_parent": { + "$ref": "AAAAAAFFwKzxcVv6A2c=" + }, + "model": { + "$ref": "AAAAAAFFwKzxcVv56Dg=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 327, + "top": 312, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwKzxcVv6A2c=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwKzxcVv9X58=", + "_parent": { + "$ref": "AAAAAAFFwKzxcVv6A2c=" + }, + "model": { + "$ref": "AAAAAAFFwKzxcVv56Dg=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 328, + "top": 267, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwKzxcVv6A2c=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwKsvdVrTyNI=" + }, + "tail": { + "$ref": "AAAAAAFFwKuIMltMJw4=" + }, + "points": "356:400;356:288;300:288;300:240", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwKzxcVv7wpA=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwKzxcVv8NxM=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwKzxcVv9X58=" + } + }, + { + "_type": "UMLGeneralizationView", + "_id": "AAAAAAFFwKz3OVwLl+8=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwKz3OVwK9hs=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwKz3OVwMNB4=", + "_parent": { + "$ref": "AAAAAAFFwKz3OVwLl+8=" + }, + "model": { + "$ref": "AAAAAAFFwKz3OVwK9hs=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 357, + "top": 297, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwKz3OVwLl+8=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwKz3OVwNd3E=", + "_parent": { + "$ref": "AAAAAAFFwKz3OVwLl+8=" + }, + "model": { + "$ref": "AAAAAAFFwKz3OVwK9hs=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 357, + "top": 312, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwKz3OVwLl+8=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwKz3OVwODiI=", + "_parent": { + "$ref": "AAAAAAFFwKz3OVwLl+8=" + }, + "model": { + "$ref": "AAAAAAFFwKz3OVwK9hs=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 358, + "top": 267, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwKz3OVwLl+8=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwKsvdVrTyNI=" + }, + "tail": { + "$ref": "AAAAAAFFwKuS0lt0dAE=" + }, + "points": "416:448;416:288;300:288;300:240", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwKz3OVwMNB4=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwKz3OVwNd3E=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwKz3OVwODiI=" + } + }, + { + "_type": "UMLGeneralizationView", + "_id": "AAAAAAFFwKz9mVwcos8=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwKz9mFwbfDg=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwKz9mVwdsGc=", + "_parent": { + "$ref": "AAAAAAFFwKz9mVwcos8=" + }, + "model": { + "$ref": "AAAAAAFFwKz9mFwbfDg=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 391, + "top": 297, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwKz9mVwcos8=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwKz9mVweYvs=", + "_parent": { + "$ref": "AAAAAAFFwKz9mVwcos8=" + }, + "model": { + "$ref": "AAAAAAFFwKz9mFwbfDg=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 391, + "top": 312, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwKz9mVwcos8=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwKz9mVwfOSk=", + "_parent": { + "$ref": "AAAAAAFFwKz9mVwcos8=" + }, + "model": { + "$ref": "AAAAAAFFwKz9mFwbfDg=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 392, + "top": 267, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwKz9mVwcos8=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwKsvdVrTyNI=" + }, + "tail": { + "$ref": "AAAAAAFFwKueMluc5bE=" + }, + "points": "484:496;484:288;300:288;300:240", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwKz9mVwdsGc=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwKz9mVweYvs=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwKz9mVwfOSk=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwK4k1VxFxwI=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwK4k1VxEEpM=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK4k1lxGUvg=", + "_parent": { + "$ref": "AAAAAAFFwK4k1VxFxwI=" + }, + "model": { + "$ref": "AAAAAAFFwK4k1VxEEpM=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 161, + "top": 333, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwK4k1VxFxwI=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK4k1lxHABk=", + "_parent": { + "$ref": "AAAAAAFFwK4k1VxFxwI=" + }, + "model": { + "$ref": "AAAAAAFFwK4k1VxEEpM=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 161, + "top": 348, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwK4k1VxFxwI=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK4k1lxIpIg=", + "_parent": { + "$ref": "AAAAAAFFwK4k1VxFxwI=" + }, + "model": { + "$ref": "AAAAAAFFwK4k1VxEEpM=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 162, + "top": 303, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwK4k1VxFxwI=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwKqhJFq1z2Y=" + }, + "tail": { + "$ref": "AAAAAAFFwKtwS1r8DQQ=" + }, + "points": "184:324;140:324", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwK4k1lxGUvg=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwK4k1lxHABk=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwK4k1lxIpIg=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwK4o4VxWQBI=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwK4o4VxVx00=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK4o4VxXVGc=", + "_parent": { + "$ref": "AAAAAAFFwK4o4VxWQBI=" + }, + "model": { + "$ref": "AAAAAAFFwK4o4VxVx00=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 195, + "top": 378, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwK4o4VxWQBI=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK4o4VxYgZc=", + "_parent": { + "$ref": "AAAAAAFFwK4o4VxWQBI=" + }, + "model": { + "$ref": "AAAAAAFFwK4o4VxVx00=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 195, + "top": 393, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwK4o4VxWQBI=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK4o4VxZqsQ=", + "_parent": { + "$ref": "AAAAAAFFwK4o4VxWQBI=" + }, + "model": { + "$ref": "AAAAAAFFwK4o4VxVx00=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 196, + "top": 348, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwK4o4VxWQBI=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwKqhJFq1z2Y=" + }, + "tail": { + "$ref": "AAAAAAFFwKuBulskCVg=" + }, + "points": "252:369;140:369", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwK4o4VxXVGc=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwK4o4VxYgZc=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwK4o4VxZqsQ=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwK4tiVxnpno=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwK4tiVxmVJM=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK4tiVxoTEk=", + "_parent": { + "$ref": "AAAAAAFFwK4tiVxnpno=" + }, + "model": { + "$ref": "AAAAAAFFwK4tiVxmVJM=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 227, + "top": 429, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwK4tiVxnpno=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK4tiVxpG0I=", + "_parent": { + "$ref": "AAAAAAFFwK4tiVxnpno=" + }, + "model": { + "$ref": "AAAAAAFFwK4tiVxmVJM=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 227, + "top": 444, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwK4tiVxnpno=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK4tiVxqKIY=", + "_parent": { + "$ref": "AAAAAAFFwK4tiVxnpno=" + }, + "model": { + "$ref": "AAAAAAFFwK4tiVxmVJM=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 228, + "top": 399, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwK4tiVxnpno=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwKqhJFq1z2Y=" + }, + "tail": { + "$ref": "AAAAAAFFwKuIMltMJw4=" + }, + "points": "316:420;140:420", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwK4tiVxoTEk=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwK4tiVxpG0I=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwK4tiVxqKIY=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwK41YVx4sZw=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwK41YVx3Hr0=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK41YVx5rZ4=", + "_parent": { + "$ref": "AAAAAAFFwK41YVx4sZw=" + }, + "model": { + "$ref": "AAAAAAFFwK41YVx3Hr0=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 259, + "top": 473, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwK41YVx4sZw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK41YVx6mfE=", + "_parent": { + "$ref": "AAAAAAFFwK41YVx4sZw=" + }, + "model": { + "$ref": "AAAAAAFFwK41YVx3Hr0=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 259, + "top": 488, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwK41YVx4sZw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK41YVx7lFo=", + "_parent": { + "$ref": "AAAAAAFFwK41YVx4sZw=" + }, + "model": { + "$ref": "AAAAAAFFwK41YVx3Hr0=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 260, + "top": 443, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwK41YVx4sZw=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwKqhJFq1z2Y=" + }, + "tail": { + "$ref": "AAAAAAFFwKuS0lt0dAE=" + }, + "points": "380:464;140:464", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwK41YVx5rZ4=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwK41YVx6mfE=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwK41YVx7lFo=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwK47MFyJhkk=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwK47MFyIL/c=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK47MFyKeH8=", + "_parent": { + "$ref": "AAAAAAFFwK47MFyJhkk=" + }, + "model": { + "$ref": "AAAAAAFFwK47MFyIL/c=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 289, + "top": 521, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwK47MFyJhkk=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK47MVyL2Gg=", + "_parent": { + "$ref": "AAAAAAFFwK47MFyJhkk=" + }, + "model": { + "$ref": "AAAAAAFFwK47MFyIL/c=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 289, + "top": 536, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwK47MFyJhkk=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK47MVyMJyk=", + "_parent": { + "$ref": "AAAAAAFFwK47MFyJhkk=" + }, + "model": { + "$ref": "AAAAAAFFwK47MFyIL/c=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 290, + "top": 491, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwK47MFyJhkk=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwKqhJFq1z2Y=" + }, + "tail": { + "$ref": "AAAAAAFFwKueMluc5bE=" + }, + "points": "440:512;140:512", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwK47MFyKeH8=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwK47MVyL2Gg=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwK47MVyMJyk=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwK5AeFyarms=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwK5AeFyZpVg=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK5AeFybX8s=", + "_parent": { + "$ref": "AAAAAAFFwK5AeFyarms=" + }, + "model": { + "$ref": "AAAAAAFFwK5AeFyZpVg=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 185, + "top": 229, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwK5AeFyarms=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK5AeFycm2c=", + "_parent": { + "$ref": "AAAAAAFFwK5AeFyarms=" + }, + "model": { + "$ref": "AAAAAAFFwK5AeFyZpVg=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 185, + "top": 244, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwK5AeFyarms=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwK5AeVydbSU=", + "_parent": { + "$ref": "AAAAAAFFwK5AeFyarms=" + }, + "model": { + "$ref": "AAAAAAFFwK5AeFyZpVg=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 186, + "top": 199, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwK5AeFyarms=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwKqhJFq1z2Y=" + }, + "tail": { + "$ref": "AAAAAAFFwKsvdVrTyNI=" + }, + "points": "232:220;140:220", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwK5AeFybX8s=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwK5AeFycm2c=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwK5AeVydbSU=" + } + }, + { + "_type": "UMLMetaClassView", + "_id": "AAAAAAFFwK/k1ly1mNU=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwK/k1ly00Ec=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwK/k1ly236Y=", + "_parent": { + "$ref": "AAAAAAFFwK/k1ly1mNU=" + }, + "model": { + "$ref": "AAAAAAFFwK/k1ly00Ec=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwK/k1ly3kes=", + "_parent": { + "$ref": "AAAAAAFFwK/k1ly236Y=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 385, + "top": 585, + "width": 132, + "height": 12, + "text": "«metaClass»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwK/k1ly4Kb0=", + "_parent": { + "$ref": "AAAAAAFFwK/k1ly236Y=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;1", + "containerExtending": true, + "left": 385, + "top": 599, + "width": 132, + "height": 12, + "text": "UMLBehavioralFeature" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwK/k11y5jis=", + "_parent": { + "$ref": "AAAAAAFFwK/k1ly236Y=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 972, + "top": 60, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwK/k11y6pH4=", + "_parent": { + "$ref": "AAAAAAFFwK/k1ly236Y=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 972, + "top": 60, + "height": 12, + "horizontalAlignment": 1 + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 380, + "top": 580, + "width": 142, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwK/k1ly3kes=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwK/k1ly4Kb0=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwK/k11y5jis=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwK/k11y6pH4=" + } + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 380, + "top": 580, + "width": 142, + "height": 101, + "nameCompartment": { + "$ref": "AAAAAAFFwK/k1ly236Y=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwLBdPFzSzQk=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLBdO1zQosE=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqFkkF9pQ=", + "_parent": { + "$ref": "AAAAAAFFwLBdPFzSzQk=" + }, + "model": { + "$ref": "AAAAAAFFwLBdO1zQosE=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwLBdPFzT/sk=", + "_parent": { + "$ref": "AAAAAAFFwLBdPFzSzQk=" + }, + "model": { + "$ref": "AAAAAAFFwLBdO1zQosE=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwLBdPFzUtqg=", + "_parent": { + "$ref": "AAAAAAFFwLBdPFzT/sk=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 241, + "top": 589, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLBdPFzVTVM=", + "_parent": { + "$ref": "AAAAAAFFwLBdPFzT/sk=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 241, + "top": 603, + "width": 72.51593017578125, + "height": 12, + "text": "Destroy" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLBdPFzWXGg=", + "_parent": { + "$ref": "AAAAAAFFwLBdPFzT/sk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 120, + "top": 24, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLBdPFzX7Kw=", + "_parent": { + "$ref": "AAAAAAFFwLBdPFzT/sk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 120, + "top": 24, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 236, + "top": 584, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLBdPFzUtqg=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwLBdPFzVTVM=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwLBdPFzWXGg=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLBdPFzX7Kw=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwLBdPFzYl0A=", + "_parent": { + "$ref": "AAAAAAFFwLBdPFzSzQk=" + }, + "model": { + "$ref": "AAAAAAFFwLBdO1zQosE=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 220, + "top": 632, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwLBdPFzZMKQ=", + "_parent": { + "$ref": "AAAAAAFFwLBdPFzSzQk=" + }, + "model": { + "$ref": "AAAAAAFFwLBdO1zQosE=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 220, + "top": 632, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwLBdPFzaqUA=", + "_parent": { + "$ref": "AAAAAAFFwLBdPFzSzQk=" + }, + "model": { + "$ref": "AAAAAAFFwLBdO1zQosE=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 80, + "top": 16, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 236, + "top": 584, + "width": 82.51593017578125, + "height": 37, + "nameCompartment": { + "$ref": "AAAAAAFFwLBdPFzT/sk=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwLBdPFzYl0A=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwLBdPFzZMKQ=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqFkkF9pQ=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwLBdPFzaqUA=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwLDMaFz6CG0=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLDMaFz5C14=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLDMaFz7zuA=", + "_parent": { + "$ref": "AAAAAAFFwLDMaFz6CG0=" + }, + "model": { + "$ref": "AAAAAAFFwLDMaFz5C14=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 349, + "top": 579, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLDMaFz6CG0=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLDMaFz8JJ4=", + "_parent": { + "$ref": "AAAAAAFFwLDMaFz6CG0=" + }, + "model": { + "$ref": "AAAAAAFFwLDMaFz5C14=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 349, + "top": 564, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwLDMaFz6CG0=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLDMaFz92bU=", + "_parent": { + "$ref": "AAAAAAFFwLDMaFz6CG0=" + }, + "model": { + "$ref": "AAAAAAFFwLDMaFz5C14=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 349, + "top": 609, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLDMaFz6CG0=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwK/k1ly1mNU=" + }, + "tail": { + "$ref": "AAAAAAFFwLBdPFzSzQk=" + }, + "points": "318:600;380:600", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwLDMaFz7zuA=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLDMaFz8JJ4=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLDMaFz92bU=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwLFUbV0ScDI=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLFUbV0QQVA=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqF0kiyCM=", + "_parent": { + "$ref": "AAAAAAFFwLFUbV0ScDI=" + }, + "model": { + "$ref": "AAAAAAFFwLFUbV0QQVA=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwLFUbV0TTdY=", + "_parent": { + "$ref": "AAAAAAFFwLFUbV0ScDI=" + }, + "model": { + "$ref": "AAAAAAFFwLFUbV0QQVA=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwLFUbV0UvYs=", + "_parent": { + "$ref": "AAAAAAFFwLFUbV0TTdY=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 725, + "top": 209, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLFUbV0V4oU=", + "_parent": { + "$ref": "AAAAAAFFwLFUbV0TTdY=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 725, + "top": 223, + "width": 72.51593017578125, + "height": 12, + "text": "Auxiliary" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLFUbV0WLEA=", + "_parent": { + "$ref": "AAAAAAFFwLFUbV0TTdY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -60, + "top": -336, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLFUbV0XEPg=", + "_parent": { + "$ref": "AAAAAAFFwLFUbV0TTdY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -60, + "top": -336, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 204, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLFUbV0UvYs=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwLFUbV0V4oU=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwLFUbV0WLEA=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLFUbV0XEPg=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwLFUbV0YxWc=", + "_parent": { + "$ref": "AAAAAAFFwLFUbV0ScDI=" + }, + "model": { + "$ref": "AAAAAAFFwLFUbV0QQVA=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 700, + "top": 128, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwLFUbV0Z3Xk=", + "_parent": { + "$ref": "AAAAAAFFwLFUbV0ScDI=" + }, + "model": { + "$ref": "AAAAAAFFwLFUbV0QQVA=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 700, + "top": 128, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwLFUbV0aLJo=", + "_parent": { + "$ref": "AAAAAAFFwLFUbV0ScDI=" + }, + "model": { + "$ref": "AAAAAAFFwLFUbV0QQVA=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -40, + "top": -224, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 204, + "width": 82.51593017578125, + "height": 36, + "nameCompartment": { + "$ref": "AAAAAAFFwLFUbV0TTdY=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwLFUbV0YxWc=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwLFUbV0Z3Xk=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqF0kiyCM=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwLFUbV0aLJo=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwLFu9F06sWk=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLFu8104he4=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqGEk49nc=", + "_parent": { + "$ref": "AAAAAAFFwLFu9F06sWk=" + }, + "model": { + "$ref": "AAAAAAFFwLFu8104he4=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwLFu9F07mo0=", + "_parent": { + "$ref": "AAAAAAFFwLFu9F06sWk=" + }, + "model": { + "$ref": "AAAAAAFFwLFu8104he4=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwLFu9F08FIY=", + "_parent": { + "$ref": "AAAAAAFFwLFu9F07mo0=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 725, + "top": 261, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLFu9F09Ig0=", + "_parent": { + "$ref": "AAAAAAFFwLFu9F07mo0=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 725, + "top": 275, + "width": 72.51593017578125, + "height": 12, + "text": "Focus" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLFu9F0+sYU=", + "_parent": { + "$ref": "AAAAAAFFwLFu9F07mo0=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -60, + "top": -420, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLFu9F0/2cA=", + "_parent": { + "$ref": "AAAAAAFFwLFu9F07mo0=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -60, + "top": -420, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 256, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLFu9F08FIY=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwLFu9F09Ig0=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwLFu9F0+sYU=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLFu9F0/2cA=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwLFu9F1A690=", + "_parent": { + "$ref": "AAAAAAFFwLFu9F06sWk=" + }, + "model": { + "$ref": "AAAAAAFFwLFu8104he4=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 700, + "top": 152, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwLFu9F1BAsU=", + "_parent": { + "$ref": "AAAAAAFFwLFu9F06sWk=" + }, + "model": { + "$ref": "AAAAAAFFwLFu8104he4=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 700, + "top": 152, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwLFu9F1CLR8=", + "_parent": { + "$ref": "AAAAAAFFwLFu9F06sWk=" + }, + "model": { + "$ref": "AAAAAAFFwLFu8104he4=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -40, + "top": -280, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 256, + "width": 82.51593017578125, + "height": 36, + "nameCompartment": { + "$ref": "AAAAAAFFwLFu9F07mo0=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwLFu9F1A690=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwLFu9F1BAsU=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqGEk49nc=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwLFu9F1CLR8=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwLF4tF1iftI=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLF4tF1g4No=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqGUlOO9I=", + "_parent": { + "$ref": "AAAAAAFFwLF4tF1iftI=" + }, + "model": { + "$ref": "AAAAAAFFwLF4tF1g4No=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwLF4tF1jr/w=", + "_parent": { + "$ref": "AAAAAAFFwLF4tF1iftI=" + }, + "model": { + "$ref": "AAAAAAFFwLF4tF1g4No=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwLF4tF1kg2Y=", + "_parent": { + "$ref": "AAAAAAFFwLF4tF1jr/w=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 725, + "top": 313, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLF4tF1la4E=", + "_parent": { + "$ref": "AAAAAAFFwLF4tF1jr/w=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 725, + "top": 327, + "width": 72.51593017578125, + "height": 12, + "text": "Metaclass" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLF4tF1mW9o=", + "_parent": { + "$ref": "AAAAAAFFwLF4tF1jr/w=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -60, + "top": -480, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLF4tF1ngPk=", + "_parent": { + "$ref": "AAAAAAFFwLF4tF1jr/w=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -60, + "top": -480, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 308, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLF4tF1kg2Y=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwLF4tF1la4E=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwLF4tF1mW9o=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLF4tF1ngPk=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwLF4tF1oP5U=", + "_parent": { + "$ref": "AAAAAAFFwLF4tF1iftI=" + }, + "model": { + "$ref": "AAAAAAFFwLF4tF1g4No=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 700, + "top": 184, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwLF4tF1pEYI=", + "_parent": { + "$ref": "AAAAAAFFwLF4tF1iftI=" + }, + "model": { + "$ref": "AAAAAAFFwLF4tF1g4No=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 700, + "top": 184, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwLF4tF1qaMM=", + "_parent": { + "$ref": "AAAAAAFFwLF4tF1iftI=" + }, + "model": { + "$ref": "AAAAAAFFwLF4tF1g4No=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -40, + "top": -320, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 308, + "width": 82.51593017578125, + "height": 36, + "nameCompartment": { + "$ref": "AAAAAAFFwLF4tF1jr/w=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwLF4tF1oP5U=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwLF4tF1pEYI=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqGUlOO9I=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwLF4tF1qaMM=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwLF/G12KFPg=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLF/G12IJ54=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqGUlk1Tc=", + "_parent": { + "$ref": "AAAAAAFFwLF/G12KFPg=" + }, + "model": { + "$ref": "AAAAAAFFwLF/G12IJ54=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwLF/G12LESY=", + "_parent": { + "$ref": "AAAAAAFFwLF/G12KFPg=" + }, + "model": { + "$ref": "AAAAAAFFwLF/G12IJ54=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwLF/G12MFWs=", + "_parent": { + "$ref": "AAAAAAFFwLF/G12LESY=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 725, + "top": 365, + "width": 121, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLF/G12Nq6M=", + "_parent": { + "$ref": "AAAAAAFFwLF/G12LESY=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 725, + "top": 379, + "width": 121, + "height": 12, + "text": "ImplementationClass" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLF/G12OWK0=", + "_parent": { + "$ref": "AAAAAAFFwLF/G12LESY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -48, + "top": -564, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLF/G12PipY=", + "_parent": { + "$ref": "AAAAAAFFwLF/G12LESY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -48, + "top": -564, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 360, + "width": 131, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLF/G12MFWs=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwLF/G12Nq6M=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwLF/G12OWK0=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLF/G12PipY=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwLF/G12QJs8=", + "_parent": { + "$ref": "AAAAAAFFwLF/G12KFPg=" + }, + "model": { + "$ref": "AAAAAAFFwLF/G12IJ54=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 704, + "top": 208, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwLF/G12Rf8c=", + "_parent": { + "$ref": "AAAAAAFFwLF/G12KFPg=" + }, + "model": { + "$ref": "AAAAAAFFwLF/G12IJ54=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 704, + "top": 208, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwLF/HF2Sm8E=", + "_parent": { + "$ref": "AAAAAAFFwLF/G12KFPg=" + }, + "model": { + "$ref": "AAAAAAFFwLF/G12IJ54=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -32, + "top": -376, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 360, + "width": 131, + "height": 36, + "nameCompartment": { + "$ref": "AAAAAAFFwLF/G12LESY=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwLF/G12QJs8=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwLF/G12Rf8c=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqGUlk1Tc=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwLF/HF2Sm8E=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwLGEPF2y6SI=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLGEO12wqJ8=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqHEl6Zbo=", + "_parent": { + "$ref": "AAAAAAFFwLGEPF2y6SI=" + }, + "model": { + "$ref": "AAAAAAFFwLGEO12wqJ8=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwLGEPF2zyUI=", + "_parent": { + "$ref": "AAAAAAFFwLGEPF2y6SI=" + }, + "model": { + "$ref": "AAAAAAFFwLGEO12wqJ8=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwLGEPF20OuI=", + "_parent": { + "$ref": "AAAAAAFFwLGEPF2zyUI=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 725, + "top": 421, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLGEPF21TcM=", + "_parent": { + "$ref": "AAAAAAFFwLGEPF2zyUI=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 725, + "top": 435, + "width": 72.51593017578125, + "height": 12, + "text": "Type" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLGEPF22f/8=", + "_parent": { + "$ref": "AAAAAAFFwLGEPF2zyUI=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -48, + "top": -624, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLGEPF23oz0=", + "_parent": { + "$ref": "AAAAAAFFwLGEPF2zyUI=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -48, + "top": -624, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 416, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLGEPF20OuI=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwLGEPF21TcM=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwLGEPF22f/8=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLGEPF23oz0=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwLGEPF24D5Y=", + "_parent": { + "$ref": "AAAAAAFFwLGEPF2y6SI=" + }, + "model": { + "$ref": "AAAAAAFFwLGEO12wqJ8=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 704, + "top": 244, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwLGEPF252Tg=", + "_parent": { + "$ref": "AAAAAAFFwLGEPF2y6SI=" + }, + "model": { + "$ref": "AAAAAAFFwLGEO12wqJ8=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 704, + "top": 244, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwLGEPF26r38=", + "_parent": { + "$ref": "AAAAAAFFwLGEPF2y6SI=" + }, + "model": { + "$ref": "AAAAAAFFwLGEO12wqJ8=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -32, + "top": -416, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 416, + "width": 82.51593017578125, + "height": 36, + "nameCompartment": { + "$ref": "AAAAAAFFwLGEPF2zyUI=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwLGEPF24D5Y=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwLGEPF252Tg=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqHEl6Zbo=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwLGEPF26r38=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwLGI813a/Lo=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLGI813YL3s=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqHEmQAJ4=", + "_parent": { + "$ref": "AAAAAAFFwLGI813a/Lo=" + }, + "model": { + "$ref": "AAAAAAFFwLGI813YL3s=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwLGI813bmDw=", + "_parent": { + "$ref": "AAAAAAFFwLGI813a/Lo=" + }, + "model": { + "$ref": "AAAAAAFFwLGI813YL3s=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwLGI9F3c6dc=", + "_parent": { + "$ref": "AAAAAAFFwLGI813bmDw=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 725, + "top": 477, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLGI9F3dgjo=", + "_parent": { + "$ref": "AAAAAAFFwLGI813bmDw=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 725, + "top": 491, + "width": 72.51593017578125, + "height": 12, + "text": "Utility" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLGI9F3eWQw=", + "_parent": { + "$ref": "AAAAAAFFwLGI813bmDw=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -48, + "top": -672, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLGI9F3fVUI=", + "_parent": { + "$ref": "AAAAAAFFwLGI813bmDw=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -48, + "top": -672, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 472, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLGI9F3c6dc=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwLGI9F3dgjo=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwLGI9F3eWQw=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLGI9F3fVUI=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwLGI9F3g9+w=", + "_parent": { + "$ref": "AAAAAAFFwLGI813a/Lo=" + }, + "model": { + "$ref": "AAAAAAFFwLGI813YL3s=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 704, + "top": 284, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwLGI9F3hmIE=", + "_parent": { + "$ref": "AAAAAAFFwLGI813a/Lo=" + }, + "model": { + "$ref": "AAAAAAFFwLGI813YL3s=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 704, + "top": 284, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwLGI9F3i+8k=", + "_parent": { + "$ref": "AAAAAAFFwLGI813a/Lo=" + }, + "model": { + "$ref": "AAAAAAFFwLGI813YL3s=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -32, + "top": -448, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 472, + "width": 82.51593017578125, + "height": 36, + "nameCompartment": { + "$ref": "AAAAAAFFwLGI813bmDw=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwLGI9F3g9+w=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwLGI9F3hmIE=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqHEmQAJ4=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwLGI9F3i+8k=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwLNej158NLk=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLNej157D6Y=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLNej1590I0=", + "_parent": { + "$ref": "AAAAAAFFwLNej158NLk=" + }, + "model": { + "$ref": "AAAAAAFFwLNej157D6Y=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 685, + "top": 233, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLNej158NLk=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLNej15+8jc=", + "_parent": { + "$ref": "AAAAAAFFwLNej158NLk=" + }, + "model": { + "$ref": "AAAAAAFFwLNej157D6Y=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 685, + "top": 248, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwLNej158NLk=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLNej15/BRY=", + "_parent": { + "$ref": "AAAAAAFFwLNej158NLk=" + }, + "model": { + "$ref": "AAAAAAFFwLNej157D6Y=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 686, + "top": 203, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLNej158NLk=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFJsZbpDNpnkE=" + }, + "tail": { + "$ref": "AAAAAAFFwLFUbV0ScDI=" + }, + "points": "720:224;652:224", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwLNej1590I0=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLNej15+8jc=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLNej15/BRY=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwLNkZ16NQ/Q=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLNkZ16Mp7Y=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLNkZ16OhBQ=", + "_parent": { + "$ref": "AAAAAAFFwLNkZ16NQ/Q=" + }, + "model": { + "$ref": "AAAAAAFFwLNkZ16Mp7Y=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 685, + "top": 281, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLNkZ16NQ/Q=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLNkZ16PBtY=", + "_parent": { + "$ref": "AAAAAAFFwLNkZ16NQ/Q=" + }, + "model": { + "$ref": "AAAAAAFFwLNkZ16Mp7Y=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 685, + "top": 296, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwLNkZ16NQ/Q=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLNkZ16QvLQ=", + "_parent": { + "$ref": "AAAAAAFFwLNkZ16NQ/Q=" + }, + "model": { + "$ref": "AAAAAAFFwLNkZ16Mp7Y=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 686, + "top": 251, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLNkZ16NQ/Q=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFJsZbpDNpnkE=" + }, + "tail": { + "$ref": "AAAAAAFFwLFu9F06sWk=" + }, + "points": "720:272;652:272", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwLNkZ16OhBQ=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLNkZ16PBtY=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLNkZ16QvLQ=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwLNn916eDZQ=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLNn916d4Yc=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLNn916fvYQ=", + "_parent": { + "$ref": "AAAAAAFFwLNn916eDZQ=" + }, + "model": { + "$ref": "AAAAAAFFwLNn916d4Yc=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 685, + "top": 333, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLNn916eDZQ=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLNn916guUU=", + "_parent": { + "$ref": "AAAAAAFFwLNn916eDZQ=" + }, + "model": { + "$ref": "AAAAAAFFwLNn916d4Yc=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 685, + "top": 348, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwLNn916eDZQ=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLNn916hjhM=", + "_parent": { + "$ref": "AAAAAAFFwLNn916eDZQ=" + }, + "model": { + "$ref": "AAAAAAFFwLNn916d4Yc=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 686, + "top": 303, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLNn916eDZQ=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFJsZbpDNpnkE=" + }, + "tail": { + "$ref": "AAAAAAFFwLF4tF1iftI=" + }, + "points": "720:324;652:324", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwLNn916fvYQ=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLNn916guUU=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLNn916hjhM=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwLNr116vKpE=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLNr116u93k=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLNr116weUM=", + "_parent": { + "$ref": "AAAAAAFFwLNr116vKpE=" + }, + "model": { + "$ref": "AAAAAAFFwLNr116u93k=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 685, + "top": 385, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLNr116vKpE=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLNr116xjvo=", + "_parent": { + "$ref": "AAAAAAFFwLNr116vKpE=" + }, + "model": { + "$ref": "AAAAAAFFwLNr116u93k=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 685, + "top": 400, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwLNr116vKpE=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLNr116yGN0=", + "_parent": { + "$ref": "AAAAAAFFwLNr116vKpE=" + }, + "model": { + "$ref": "AAAAAAFFwLNr116u93k=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 686, + "top": 355, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLNr116vKpE=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFJsZbpDNpnkE=" + }, + "tail": { + "$ref": "AAAAAAFFwLF/G12KFPg=" + }, + "points": "720:376;652:376", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwLNr116weUM=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLNr116xjvo=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLNr116yGN0=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwLNvdl7AF7U=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLNvdl6/WJI=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLNvd17Byl0=", + "_parent": { + "$ref": "AAAAAAFFwLNvdl7AF7U=" + }, + "model": { + "$ref": "AAAAAAFFwLNvdl6/WJI=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 685, + "top": 442, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLNvdl7AF7U=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLNvd17Cmyo=", + "_parent": { + "$ref": "AAAAAAFFwLNvdl7AF7U=" + }, + "model": { + "$ref": "AAAAAAFFwLNvdl6/WJI=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 685, + "top": 457, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwLNvdl7AF7U=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLNvd17DduQ=", + "_parent": { + "$ref": "AAAAAAFFwLNvdl7AF7U=" + }, + "model": { + "$ref": "AAAAAAFFwLNvdl6/WJI=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 686, + "top": 412, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLNvdl7AF7U=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFJsZbpDNpnkE=" + }, + "tail": { + "$ref": "AAAAAAFFwLGEPF2y6SI=" + }, + "points": "720:433;652:433", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwLNvd17Byl0=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLNvd17Cmyo=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLNvd17DduQ=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwLN0fl7RscA=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLN0fl7QL9o=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLN0fl7SzeE=", + "_parent": { + "$ref": "AAAAAAFFwLN0fl7RscA=" + }, + "model": { + "$ref": "AAAAAAFFwLN0fl7QL9o=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 685, + "top": 498, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLN0fl7RscA=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLN0fl7Tq3c=", + "_parent": { + "$ref": "AAAAAAFFwLN0fl7RscA=" + }, + "model": { + "$ref": "AAAAAAFFwLN0fl7QL9o=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 685, + "top": 513, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwLN0fl7RscA=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLN0f17UptI=", + "_parent": { + "$ref": "AAAAAAFFwLN0fl7RscA=" + }, + "model": { + "$ref": "AAAAAAFFwLN0fl7QL9o=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 686, + "top": 468, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLN0fl7RscA=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFJsZbpDNpnkE=" + }, + "tail": { + "$ref": "AAAAAAFFwLGI813a/Lo=" + }, + "points": "720:489;652:489", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwLN0fl7SzeE=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLN0fl7Tq3c=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLN0f17UptI=" + } + }, + { + "_type": "UMLMetaClassView", + "_id": "AAAAAAFFwLRECl7stC8=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLRECl7r1R4=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwLRECl7tsQE=", + "_parent": { + "$ref": "AAAAAAFFwLRECl7stC8=" + }, + "model": { + "$ref": "AAAAAAFFwLRECl7r1R4=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwLRECl7u5vE=", + "_parent": { + "$ref": "AAAAAAFFwLRECl7tsQE=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 561, + "top": 545, + "width": 92.85594177246094, + "height": 12, + "text": "«metaClass»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLRECl7vrCk=", + "_parent": { + "$ref": "AAAAAAFFwLRECl7tsQE=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;1", + "containerExtending": true, + "left": 561, + "top": 559, + "width": 92.85594177246094, + "height": 12, + "text": "UMLComponent" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLRECl7wqHs=", + "_parent": { + "$ref": "AAAAAAFFwLRECl7tsQE=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "top": 504, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLRECl7xJrI=", + "_parent": { + "$ref": "AAAAAAFFwLRECl7tsQE=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "top": 504, + "height": 12, + "horizontalAlignment": 1 + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 556, + "top": 540, + "width": 102.85594177246094, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLRECl7u5vE=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwLRECl7vrCk=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwLRECl7wqHs=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLRECl7xJrI=" + } + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 556, + "top": 540, + "width": 102.85594177246094, + "height": 261, + "nameCompartment": { + "$ref": "AAAAAAFFwLRECl7tsQE=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwLR8CV8I99Y=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLR8CF8G68k=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqH0nfZIU=", + "_parent": { + "$ref": "AAAAAAFFwLR8CV8I99Y=" + }, + "model": { + "$ref": "AAAAAAFFwLR8CF8G68k=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwLR8CV8JFWY=", + "_parent": { + "$ref": "AAAAAAFFwLR8CV8I99Y=" + }, + "model": { + "$ref": "AAAAAAFFwLR8CF8G68k=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwLR8CV8Knxc=", + "_parent": { + "$ref": "AAAAAAFFwLR8CV8JFWY=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 725, + "top": 549, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLR8CV8LWIw=", + "_parent": { + "$ref": "AAAAAAFFwLR8CV8JFWY=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 725, + "top": 563, + "width": 72.51593017578125, + "height": 12, + "text": "Entity" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLR8CV8Mvqc=", + "_parent": { + "$ref": "AAAAAAFFwLR8CV8JFWY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "top": 504, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLR8CV8NdIc=", + "_parent": { + "$ref": "AAAAAAFFwLR8CV8JFWY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "top": 504, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 544, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLR8CV8Knxc=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwLR8CV8LWIw=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwLR8CV8Mvqc=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLR8CV8NdIc=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwLR8CV8OpVY=", + "_parent": { + "$ref": "AAAAAAFFwLR8CV8I99Y=" + }, + "model": { + "$ref": "AAAAAAFFwLR8CF8G68k=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 748, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwLR8CV8PW8k=", + "_parent": { + "$ref": "AAAAAAFFwLR8CV8I99Y=" + }, + "model": { + "$ref": "AAAAAAFFwLR8CF8G68k=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 748, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwLR8Cl8QCTM=", + "_parent": { + "$ref": "AAAAAAFFwLR8CV8I99Y=" + }, + "model": { + "$ref": "AAAAAAFFwLR8CF8G68k=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "top": 336, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 544, + "width": 82.51593017578125, + "height": 36, + "nameCompartment": { + "$ref": "AAAAAAFFwLR8CV8JFWY=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwLR8CV8OpVY=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwLR8CV8PW8k=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqH0nfZIU=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwLR8Cl8QCTM=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwLSByF8w+gI=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLSByF8umMo=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqIEn1Irc=", + "_parent": { + "$ref": "AAAAAAFFwLSByF8w+gI=" + }, + "model": { + "$ref": "AAAAAAFFwLSByF8umMo=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwLSByF8x/Yc=", + "_parent": { + "$ref": "AAAAAAFFwLSByF8w+gI=" + }, + "model": { + "$ref": "AAAAAAFFwLSByF8umMo=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwLSByF8yMLo=", + "_parent": { + "$ref": "AAAAAAFFwLSByF8x/Yc=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 725, + "top": 597, + "width": 88.67578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLSByF8zspI=", + "_parent": { + "$ref": "AAAAAAFFwLSByF8x/Yc=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 725, + "top": 611, + "width": 88.67578125, + "height": 12, + "text": "Implementation" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLSByF80AnU=", + "_parent": { + "$ref": "AAAAAAFFwLSByF8x/Yc=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -12, + "top": 420, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLSByF81b24=", + "_parent": { + "$ref": "AAAAAAFFwLSByF8x/Yc=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -12, + "top": 420, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 592, + "width": 98.67578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLSByF8yMLo=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwLSByF8zspI=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwLSByF80AnU=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLSByF81b24=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwLSByF82e10=", + "_parent": { + "$ref": "AAAAAAFFwLSByF8w+gI=" + }, + "model": { + "$ref": "AAAAAAFFwLSByF8umMo=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 716, + "top": 768, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwLSByF83aE4=", + "_parent": { + "$ref": "AAAAAAFFwLSByF8w+gI=" + }, + "model": { + "$ref": "AAAAAAFFwLSByF8umMo=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 716, + "top": 768, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwLSByF84G88=", + "_parent": { + "$ref": "AAAAAAFFwLSByF8w+gI=" + }, + "model": { + "$ref": "AAAAAAFFwLSByF8umMo=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -8, + "top": 280, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 592, + "width": 98.67578125, + "height": 36, + "nameCompartment": { + "$ref": "AAAAAAFFwLSByF8x/Yc=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwLSByF82e10=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwLSByF83aE4=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqIEn1Irc=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwLSByF84G88=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwLSIN19Ytdk=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLSIN19WMnE=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqIUoLdrY=", + "_parent": { + "$ref": "AAAAAAFFwLSIN19Ytdk=" + }, + "model": { + "$ref": "AAAAAAFFwLSIN19WMnE=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwLSIN19ZQ0U=", + "_parent": { + "$ref": "AAAAAAFFwLSIN19Ytdk=" + }, + "model": { + "$ref": "AAAAAAFFwLSIN19WMnE=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwLSIOF9a8kE=", + "_parent": { + "$ref": "AAAAAAFFwLSIN19ZQ0U=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 725, + "top": 653, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLSIOF9bYBg=", + "_parent": { + "$ref": "AAAAAAFFwLSIN19ZQ0U=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 725, + "top": 667, + "width": 72.51593017578125, + "height": 12, + "text": "Process" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLSIOF9cqZQ=", + "_parent": { + "$ref": "AAAAAAFFwLSIN19ZQ0U=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -12, + "top": 348, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLSIOF9dI5U=", + "_parent": { + "$ref": "AAAAAAFFwLSIN19ZQ0U=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -12, + "top": 348, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 648, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLSIOF9a8kE=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwLSIOF9bYBg=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwLSIOF9cqZQ=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLSIOF9dI5U=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwLSIOF9ekq0=", + "_parent": { + "$ref": "AAAAAAFFwLSIN19Ytdk=" + }, + "model": { + "$ref": "AAAAAAFFwLSIN19WMnE=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 716, + "top": 800, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwLSIOF9fibc=", + "_parent": { + "$ref": "AAAAAAFFwLSIN19Ytdk=" + }, + "model": { + "$ref": "AAAAAAFFwLSIN19WMnE=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 716, + "top": 800, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwLSIOF9gUN0=", + "_parent": { + "$ref": "AAAAAAFFwLSIN19Ytdk=" + }, + "model": { + "$ref": "AAAAAAFFwLSIN19WMnE=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -8, + "top": 232, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 648, + "width": 82.51593017578125, + "height": 36, + "nameCompartment": { + "$ref": "AAAAAAFFwLSIN19ZQ0U=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwLSIOF9ekq0=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwLSIOF9fibc=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqIUoLdrY=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwLSIOF9gUN0=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwLSO/1+AoeQ=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLSO/19+cMY=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqIkohl1g=", + "_parent": { + "$ref": "AAAAAAFFwLSO/1+AoeQ=" + }, + "model": { + "$ref": "AAAAAAFFwLSO/19+cMY=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwLSO/1+BWGA=", + "_parent": { + "$ref": "AAAAAAFFwLSO/1+AoeQ=" + }, + "model": { + "$ref": "AAAAAAFFwLSO/19+cMY=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwLSO/1+CG1s=", + "_parent": { + "$ref": "AAAAAAFFwLSO/1+BWGA=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 725, + "top": 709, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLSO/1+DoUc=", + "_parent": { + "$ref": "AAAAAAFFwLSO/1+BWGA=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 725, + "top": 723, + "width": 72.51593017578125, + "height": 12, + "text": "Service" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLSPAF+EVIo=", + "_parent": { + "$ref": "AAAAAAFFwLSO/1+BWGA=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -12, + "top": 312, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLSPAF+FZR8=", + "_parent": { + "$ref": "AAAAAAFFwLSO/1+BWGA=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -12, + "top": 312, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 704, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLSO/1+CG1s=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwLSO/1+DoUc=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwLSPAF+EVIo=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLSPAF+FZR8=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwLSPAF+GnaI=", + "_parent": { + "$ref": "AAAAAAFFwLSO/1+AoeQ=" + }, + "model": { + "$ref": "AAAAAAFFwLSO/19+cMY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 716, + "top": 844, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwLSPAF+Ho/s=", + "_parent": { + "$ref": "AAAAAAFFwLSO/1+AoeQ=" + }, + "model": { + "$ref": "AAAAAAFFwLSO/19+cMY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 716, + "top": 844, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwLSPAF+I3E8=", + "_parent": { + "$ref": "AAAAAAFFwLSO/1+AoeQ=" + }, + "model": { + "$ref": "AAAAAAFFwLSO/19+cMY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -8, + "top": 208, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 704, + "width": 82.51593017578125, + "height": 36, + "nameCompartment": { + "$ref": "AAAAAAFFwLSO/1+BWGA=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwLSPAF+GnaI=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwLSPAF+Ho/s=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqIkohl1g=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwLSPAF+I3E8=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwLSXP1+o0Kw=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLSXP1+mTVk=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqIko3HYE=", + "_parent": { + "$ref": "AAAAAAFFwLSXP1+o0Kw=" + }, + "model": { + "$ref": "AAAAAAFFwLSXP1+mTVk=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwLSXP1+peko=", + "_parent": { + "$ref": "AAAAAAFFwLSXP1+o0Kw=" + }, + "model": { + "$ref": "AAAAAAFFwLSXP1+mTVk=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwLSXP1+qR3g=", + "_parent": { + "$ref": "AAAAAAFFwLSXP1+peko=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 725, + "top": 765, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLSXP1+rnfg=", + "_parent": { + "$ref": "AAAAAAFFwLSXP1+peko=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 725, + "top": 779, + "width": 72.51593017578125, + "height": 12, + "text": "Subsystem" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLSXP1+sqCM=", + "_parent": { + "$ref": "AAAAAAFFwLSXP1+peko=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "top": 252, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLSXP1+t4Mc=", + "_parent": { + "$ref": "AAAAAAFFwLSXP1+peko=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "top": 252, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 760, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLSXP1+qR3g=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwLSXP1+rnfg=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwLSXP1+sqCM=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLSXP1+t4Mc=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwLSXP1+uKrA=", + "_parent": { + "$ref": "AAAAAAFFwLSXP1+o0Kw=" + }, + "model": { + "$ref": "AAAAAAFFwLSXP1+mTVk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 880, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwLSXP1+vdxM=", + "_parent": { + "$ref": "AAAAAAFFwLSXP1+o0Kw=" + }, + "model": { + "$ref": "AAAAAAFFwLSXP1+mTVk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 880, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwLSXP1+woFc=", + "_parent": { + "$ref": "AAAAAAFFwLSXP1+o0Kw=" + }, + "model": { + "$ref": "AAAAAAFFwLSXP1+mTVk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "top": 168, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 720, + "top": 760, + "width": 82.51593017578125, + "height": 36, + "nameCompartment": { + "$ref": "AAAAAAFFwLSXP1+peko=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwLSXP1+uKrA=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwLSXP1+vdxM=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqIko3HYE=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwLSXP1+woFc=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwLV9gV/Ybio=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLV9gV/Xhk4=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLV9gV/Z8CU=", + "_parent": { + "$ref": "AAAAAAFFwLV9gV/Ybio=" + }, + "model": { + "$ref": "AAAAAAFFwLV9gV/Xhk4=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 688, + "top": 569, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLV9gV/Ybio=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLV9gl/a23I=", + "_parent": { + "$ref": "AAAAAAFFwLV9gV/Ybio=" + }, + "model": { + "$ref": "AAAAAAFFwLV9gV/Xhk4=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 688, + "top": 584, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwLV9gV/Ybio=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLV9gl/b3BU=", + "_parent": { + "$ref": "AAAAAAFFwLV9gV/Ybio=" + }, + "model": { + "$ref": "AAAAAAFFwLV9gV/Xhk4=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 689, + "top": 539, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLV9gV/Ybio=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwLRECl7stC8=" + }, + "tail": { + "$ref": "AAAAAAFFwLR8CV8I99Y=" + }, + "points": "720:560;658:560", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwLV9gV/Z8CU=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLV9gl/a23I=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLV9gl/b3BU=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwLWA0V/pWEg=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLWA0V/olVk=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLWA0V/q2AI=", + "_parent": { + "$ref": "AAAAAAFFwLWA0V/pWEg=" + }, + "model": { + "$ref": "AAAAAAFFwLWA0V/olVk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 688, + "top": 621, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLWA0V/pWEg=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLWA0V/rrYc=", + "_parent": { + "$ref": "AAAAAAFFwLWA0V/pWEg=" + }, + "model": { + "$ref": "AAAAAAFFwLWA0V/olVk=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 688, + "top": 636, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwLWA0V/pWEg=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLWA0V/spgM=", + "_parent": { + "$ref": "AAAAAAFFwLWA0V/pWEg=" + }, + "model": { + "$ref": "AAAAAAFFwLWA0V/olVk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 689, + "top": 591, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLWA0V/pWEg=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwLRECl7stC8=" + }, + "tail": { + "$ref": "AAAAAAFFwLSByF8w+gI=" + }, + "points": "720:612;658:612", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwLWA0V/q2AI=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLWA0V/rrYc=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLWA0V/spgM=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwLWEUV/6d1E=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLWEUV/5Qq4=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLWEUV/78Ig=", + "_parent": { + "$ref": "AAAAAAFFwLWEUV/6d1E=" + }, + "model": { + "$ref": "AAAAAAFFwLWEUV/5Qq4=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 688, + "top": 677, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLWEUV/6d1E=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLWEUV/8eIM=", + "_parent": { + "$ref": "AAAAAAFFwLWEUV/6d1E=" + }, + "model": { + "$ref": "AAAAAAFFwLWEUV/5Qq4=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 688, + "top": 692, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwLWEUV/6d1E=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLWEUV/9T0A=", + "_parent": { + "$ref": "AAAAAAFFwLWEUV/6d1E=" + }, + "model": { + "$ref": "AAAAAAFFwLWEUV/5Qq4=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 689, + "top": 647, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLWEUV/6d1E=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwLRECl7stC8=" + }, + "tail": { + "$ref": "AAAAAAFFwLSIN19Ytdk=" + }, + "points": "720:668;658:668", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwLWEUV/78Ig=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLWEUV/8eIM=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLWEUV/9T0A=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwLWIQWALE8M=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLWIQWAKKPo=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLWIQWAMDo8=", + "_parent": { + "$ref": "AAAAAAFFwLWIQWALE8M=" + }, + "model": { + "$ref": "AAAAAAFFwLWIQWAKKPo=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 688, + "top": 737, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLWIQWALE8M=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLWIQWANo/A=", + "_parent": { + "$ref": "AAAAAAFFwLWIQWALE8M=" + }, + "model": { + "$ref": "AAAAAAFFwLWIQWAKKPo=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 688, + "top": 752, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwLWIQWALE8M=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLWIQWAO6qA=", + "_parent": { + "$ref": "AAAAAAFFwLWIQWALE8M=" + }, + "model": { + "$ref": "AAAAAAFFwLWIQWAKKPo=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 689, + "top": 707, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLWIQWALE8M=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwLRECl7stC8=" + }, + "tail": { + "$ref": "AAAAAAFFwLSO/1+AoeQ=" + }, + "points": "720:728;658:728", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwLWIQWAMDo8=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLWIQWANo/A=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLWIQWAO6qA=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwLWMgWAcaQw=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwLWMgWAb2Sk=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLWMgWAd1rc=", + "_parent": { + "$ref": "AAAAAAFFwLWMgWAcaQw=" + }, + "model": { + "$ref": "AAAAAAFFwLWMgWAb2Sk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 688, + "top": 789, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLWMgWAcaQw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLWMgWAeZ8k=", + "_parent": { + "$ref": "AAAAAAFFwLWMgWAcaQw=" + }, + "model": { + "$ref": "AAAAAAFFwLWMgWAb2Sk=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 688, + "top": 804, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwLWMgWAcaQw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLWMgWAfxqc=", + "_parent": { + "$ref": "AAAAAAFFwLWMgWAcaQw=" + }, + "model": { + "$ref": "AAAAAAFFwLWMgWAb2Sk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 689, + "top": 759, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLWMgWAcaQw=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwLRECl7stC8=" + }, + "tail": { + "$ref": "AAAAAAFFwLSXP1+o0Kw=" + }, + "points": "720:780;658:780", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwLWMgWAd1rc=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLWMgWAeZ8k=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLWMgWAfxqc=" + } + }, + { + "_type": "UMLMetaClassView", + "_id": "AAAAAAFFwL2WeWA5NQI=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwL2WeGA460g=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwL2WeWA62bI=", + "_parent": { + "$ref": "AAAAAAFFwL2WeWA5NQI=" + }, + "model": { + "$ref": "AAAAAAFFwL2WeGA460g=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwL2WeWA7mnk=", + "_parent": { + "$ref": "AAAAAAFFwL2WeWA62bI=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 61, + "top": 649, + "width": 98, + "height": 12, + "text": "«metaClass»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL2WeWA8/Wk=", + "_parent": { + "$ref": "AAAAAAFFwL2WeWA62bI=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;1", + "containerExtending": true, + "left": 61, + "top": 663, + "width": 98, + "height": 12, + "text": "UMLDependency" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL2WeWA9NaM=", + "_parent": { + "$ref": "AAAAAAFFwL2WeWA62bI=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "top": 144, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL2WeWA+CiM=", + "_parent": { + "$ref": "AAAAAAFFwL2WeWA62bI=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "top": 144, + "height": 12, + "horizontalAlignment": 1 + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 56, + "top": 644, + "width": 108, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwL2WeWA7mnk=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwL2WeWA8/Wk=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwL2WeWA9NaM=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwL2WeWA+CiM=" + } + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 56, + "top": 644, + "width": 108, + "height": 277, + "nameCompartment": { + "$ref": "AAAAAAFFwL2WeWA62bI=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwL4D0mBZIkY=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwL4D0mBXwu4=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqJkp/rUc=", + "_parent": { + "$ref": "AAAAAAFFwL4D0mBZIkY=" + }, + "model": { + "$ref": "AAAAAAFFwL4D0mBXwu4=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwL4D0mBaqmw=", + "_parent": { + "$ref": "AAAAAAFFwL4D0mBZIkY=" + }, + "model": { + "$ref": "AAAAAAFFwL4D0mBXwu4=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwL4D0mBbBNE=", + "_parent": { + "$ref": "AAAAAAFFwL4D0mBaqmw=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 241, + "top": 649, + "width": 69.380859375, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL4D0mBc7go=", + "_parent": { + "$ref": "AAAAAAFFwL4D0mBaqmw=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 241, + "top": 663, + "width": 69.380859375, + "height": 12, + "text": "Create" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL4D02Bd3+g=", + "_parent": { + "$ref": "AAAAAAFFwL4D0mBaqmw=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -48, + "top": -48, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL4D02BeWA8=", + "_parent": { + "$ref": "AAAAAAFFwL4D0mBaqmw=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -48, + "top": -48, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 236, + "top": 644, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwL4D0mBbBNE=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwL4D0mBc7go=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwL4D02Bd3+g=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwL4D02BeWA8=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwL4D02Bf0q0=", + "_parent": { + "$ref": "AAAAAAFFwL4D0mBZIkY=" + }, + "model": { + "$ref": "AAAAAAFFwL4D0mBXwu4=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 220, + "top": 664, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwL4D02BgYs8=", + "_parent": { + "$ref": "AAAAAAFFwL4D0mBZIkY=" + }, + "model": { + "$ref": "AAAAAAFFwL4D0mBXwu4=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 220, + "top": 664, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwL4D02BhsHw=", + "_parent": { + "$ref": "AAAAAAFFwL4D0mBZIkY=" + }, + "model": { + "$ref": "AAAAAAFFwL4D0mBXwu4=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -32, + "top": -32, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 236, + "top": 644, + "width": 79.380859375, + "height": 36, + "autoResize": true, + "nameCompartment": { + "$ref": "AAAAAAFFwL4D0mBaqmw=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwL4D02Bf0q0=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwL4D02BgYs8=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqJkp/rUc=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwL4D02BhsHw=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwL4h4WCCAAY=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwL4h4WCAEkg=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqJ0qVBvA=", + "_parent": { + "$ref": "AAAAAAFFwL4h4WCCAAY=" + }, + "model": { + "$ref": "AAAAAAFFwL4h4WCAEkg=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwL4h4WCD82Y=", + "_parent": { + "$ref": "AAAAAAFFwL4h4WCCAAY=" + }, + "model": { + "$ref": "AAAAAAFFwL4h4WCAEkg=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwL4h4mCE1YI=", + "_parent": { + "$ref": "AAAAAAFFwL4h4WCD82Y=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 241, + "top": 713, + "width": 69.380859375, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL4h4mCFbHY=", + "_parent": { + "$ref": "AAAAAAFFwL4h4WCD82Y=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 241, + "top": 727, + "width": 69.380859375, + "height": 12, + "text": "Call" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL4h4mCG+Bo=", + "_parent": { + "$ref": "AAAAAAFFwL4h4WCD82Y=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -48, + "top": -108, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL4h4mCHhD8=", + "_parent": { + "$ref": "AAAAAAFFwL4h4WCD82Y=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -48, + "top": -108, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 236, + "top": 708, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwL4h4mCE1YI=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwL4h4mCFbHY=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwL4h4mCG+Bo=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwL4h4mCHhD8=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwL4h4mCIEqs=", + "_parent": { + "$ref": "AAAAAAFFwL4h4WCCAAY=" + }, + "model": { + "$ref": "AAAAAAFFwL4h4WCAEkg=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 220, + "top": 708, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwL4h4mCJktQ=", + "_parent": { + "$ref": "AAAAAAFFwL4h4WCCAAY=" + }, + "model": { + "$ref": "AAAAAAFFwL4h4WCAEkg=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 220, + "top": 708, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwL4h4mCKdqI=", + "_parent": { + "$ref": "AAAAAAFFwL4h4WCCAAY=" + }, + "model": { + "$ref": "AAAAAAFFwL4h4WCAEkg=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -32, + "top": -72, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 236, + "top": 708, + "width": 79.380859375, + "height": 36, + "autoResize": true, + "nameCompartment": { + "$ref": "AAAAAAFFwL4h4WCD82Y=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwL4h4mCIEqs=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwL4h4mCJktQ=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqJ0qVBvA=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwL4h4mCKdqI=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwL45WWCr3cU=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwL45WWCpJ0o=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqJ0qrDxY=", + "_parent": { + "$ref": "AAAAAAFFwL45WWCr3cU=" + }, + "model": { + "$ref": "AAAAAAFFwL45WWCpJ0o=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwL45WWCsDkc=", + "_parent": { + "$ref": "AAAAAAFFwL45WWCr3cU=" + }, + "model": { + "$ref": "AAAAAAFFwL45WWCpJ0o=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwL45WWCtTBI=", + "_parent": { + "$ref": "AAAAAAFFwL45WWCsDkc=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 241, + "top": 769, + "width": 69.380859375, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL45WWCuTW0=", + "_parent": { + "$ref": "AAAAAAFFwL45WWCsDkc=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 241, + "top": 783, + "width": 69.380859375, + "height": 12, + "text": "Instantiate" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL45WWCv18Q=", + "_parent": { + "$ref": "AAAAAAFFwL45WWCsDkc=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -48, + "top": -192, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL45WWCwZzE=", + "_parent": { + "$ref": "AAAAAAFFwL45WWCsDkc=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -48, + "top": -192, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 236, + "top": 764, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwL45WWCtTBI=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwL45WWCuTW0=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwL45WWCv18Q=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwL45WWCwZzE=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwL45WWCxsuk=", + "_parent": { + "$ref": "AAAAAAFFwL45WWCr3cU=" + }, + "model": { + "$ref": "AAAAAAFFwL45WWCpJ0o=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 220, + "top": 736, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwL45WmCy+mU=", + "_parent": { + "$ref": "AAAAAAFFwL45WWCr3cU=" + }, + "model": { + "$ref": "AAAAAAFFwL45WWCpJ0o=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 220, + "top": 736, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwL45WmCzW1Y=", + "_parent": { + "$ref": "AAAAAAFFwL45WWCr3cU=" + }, + "model": { + "$ref": "AAAAAAFFwL45WWCpJ0o=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -32, + "top": -128, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 236, + "top": 764, + "width": 79.380859375, + "height": 36, + "autoResize": true, + "nameCompartment": { + "$ref": "AAAAAAFFwL45WWCsDkc=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwL45WWCxsuk=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwL45WmCy+mU=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqJ0qrDxY=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwL45WmCzW1Y=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwL5hQGDUxa0=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwL5hP2DSEFk=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqKErBHOc=", + "_parent": { + "$ref": "AAAAAAFFwL5hQGDUxa0=" + }, + "model": { + "$ref": "AAAAAAFFwL5hP2DSEFk=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwL5hQGDVSBg=", + "_parent": { + "$ref": "AAAAAAFFwL5hQGDUxa0=" + }, + "model": { + "$ref": "AAAAAAFFwL5hP2DSEFk=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwL5hQGDWrwI=", + "_parent": { + "$ref": "AAAAAAFFwL5hQGDVSBg=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 241, + "top": 825, + "width": 82.013671875, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL5hQGDXPFU=", + "_parent": { + "$ref": "AAAAAAFFwL5hQGDVSBg=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 241, + "top": 839, + "width": 82.013671875, + "height": 12, + "text": "Responsibility" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL5hQGDYpi0=", + "_parent": { + "$ref": "AAAAAAFFwL5hQGDVSBg=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -48, + "top": -252, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL5hQGDZAt8=", + "_parent": { + "$ref": "AAAAAAFFwL5hQGDVSBg=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -48, + "top": -252, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 236, + "top": 820, + "width": 92.013671875, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwL5hQGDWrwI=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwL5hQGDXPFU=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwL5hQGDYpi0=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwL5hQGDZAt8=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwL5hQGDa1nY=", + "_parent": { + "$ref": "AAAAAAFFwL5hQGDUxa0=" + }, + "model": { + "$ref": "AAAAAAFFwL5hP2DSEFk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 220, + "top": 772, + "width": 91, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwL5hQGDbixI=", + "_parent": { + "$ref": "AAAAAAFFwL5hQGDUxa0=" + }, + "model": { + "$ref": "AAAAAAFFwL5hP2DSEFk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 220, + "top": 772, + "width": 91, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwL5hQGDcuS4=", + "_parent": { + "$ref": "AAAAAAFFwL5hQGDUxa0=" + }, + "model": { + "$ref": "AAAAAAFFwL5hP2DSEFk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -32, + "top": -168, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 236, + "top": 820, + "width": 92.013671875, + "height": 36, + "autoResize": true, + "nameCompartment": { + "$ref": "AAAAAAFFwL5hQGDVSBg=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwL5hQGDa1nY=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwL5hQGDbixI=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqKErBHOc=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwL5hQGDcuS4=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwL7KdWEqew0=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwL7KdWEoDhA=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqKErXxgY=", + "_parent": { + "$ref": "AAAAAAFFwL7KdWEqew0=" + }, + "model": { + "$ref": "AAAAAAFFwL7KdWEoDhA=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwL7KdWEr60A=", + "_parent": { + "$ref": "AAAAAAFFwL7KdWEqew0=" + }, + "model": { + "$ref": "AAAAAAFFwL7KdWEoDhA=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwL7KdWEspPc=", + "_parent": { + "$ref": "AAAAAAFFwL7KdWEr60A=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 241, + "top": 881, + "width": 69.380859375, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL7KdWEt7g0=", + "_parent": { + "$ref": "AAAAAAFFwL7KdWEr60A=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 241, + "top": 895, + "width": 69.380859375, + "height": 12, + "text": "Send" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL7KdWEum1Q=", + "_parent": { + "$ref": "AAAAAAFFwL7KdWEr60A=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -60, + "top": -324, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwL7KdWEv3Yk=", + "_parent": { + "$ref": "AAAAAAFFwL7KdWEr60A=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -60, + "top": -324, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 236, + "top": 876, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwL7KdWEspPc=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwL7KdWEt7g0=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwL7KdWEum1Q=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwL7KdWEv3Yk=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwL7KdWEwzHc=", + "_parent": { + "$ref": "AAAAAAFFwL7KdWEqew0=" + }, + "model": { + "$ref": "AAAAAAFFwL7KdWEoDhA=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 216, + "top": 804, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwL7KdWExRWs=", + "_parent": { + "$ref": "AAAAAAFFwL7KdWEqew0=" + }, + "model": { + "$ref": "AAAAAAFFwL7KdWEoDhA=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 216, + "top": 804, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwL7KdWEyL0Q=", + "_parent": { + "$ref": "AAAAAAFFwL7KdWEqew0=" + }, + "model": { + "$ref": "AAAAAAFFwL7KdWEoDhA=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -40, + "top": -216, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 236, + "top": 876, + "width": 79.380859375, + "height": 36, + "autoResize": true, + "nameCompartment": { + "$ref": "AAAAAAFFwL7KdWEr60A=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwL7KdWEwzHc=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwL7KdWExRWs=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqKErXxgY=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwL7KdWEyL0Q=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwL+LCGFgCjw=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwL+LCGFfPQs=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+LCGFhp5w=", + "_parent": { + "$ref": "AAAAAAFFwL+LCGFgCjw=" + }, + "model": { + "$ref": "AAAAAAFFwL+LCGFfPQs=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 347, + "top": 634, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwL+LCGFgCjw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+LCGFihK4=", + "_parent": { + "$ref": "AAAAAAFFwL+LCGFgCjw=" + }, + "model": { + "$ref": "AAAAAAFFwL+LCGFfPQs=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 347, + "top": 619, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwL+LCGFgCjw=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+LCGFjcmE=", + "_parent": { + "$ref": "AAAAAAFFwL+LCGFgCjw=" + }, + "model": { + "$ref": "AAAAAAFFwL+LCGFfPQs=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 347, + "top": 664, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwL+LCGFgCjw=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwK/k1ly1mNU=" + }, + "tail": { + "$ref": "AAAAAAFFwL4D0mBZIkY=" + }, + "points": "314:655;380:655", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwL+LCGFhp5w=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwL+LCGFihK4=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwL+LCGFjcmE=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwL+O8GFxUF4=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwL+O8GFwbog=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+O8GFyCzY=", + "_parent": { + "$ref": "AAAAAAFFwL+O8GFxUF4=" + }, + "model": { + "$ref": "AAAAAAFFwL+O8GFwbog=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 198, + "top": 677, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwL+O8GFxUF4=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+O8GFzT+A=", + "_parent": { + "$ref": "AAAAAAFFwL+O8GFxUF4=" + }, + "model": { + "$ref": "AAAAAAFFwL+O8GFwbog=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 198, + "top": 692, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwL+O8GFxUF4=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+O8GF0qhg=", + "_parent": { + "$ref": "AAAAAAFFwL+O8GFxUF4=" + }, + "model": { + "$ref": "AAAAAAFFwL+O8GFwbog=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 199, + "top": 647, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwL+O8GFxUF4=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwL2WeWA5NQI=" + }, + "tail": { + "$ref": "AAAAAAFFwL4D0mBZIkY=" + }, + "points": "236:668;163:668", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwL+O8GFyCzY=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwL+O8GFzT+A=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwL+O8GF0qhg=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwL+SkWGC/a4=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwL+SkWGBCOg=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+SkWGDbeA=", + "_parent": { + "$ref": "AAAAAAFFwL+SkWGC/a4=" + }, + "model": { + "$ref": "AAAAAAFFwL+SkWGBCOg=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 198, + "top": 731, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwL+SkWGC/a4=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+SkWGEkxM=", + "_parent": { + "$ref": "AAAAAAFFwL+SkWGC/a4=" + }, + "model": { + "$ref": "AAAAAAFFwL+SkWGBCOg=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 198, + "top": 746, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwL+SkWGC/a4=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+SkWGFVnU=", + "_parent": { + "$ref": "AAAAAAFFwL+SkWGC/a4=" + }, + "model": { + "$ref": "AAAAAAFFwL+SkWGBCOg=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 199, + "top": 701, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwL+SkWGC/a4=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwL2WeWA5NQI=" + }, + "tail": { + "$ref": "AAAAAAFFwL4h4WCCAAY=" + }, + "points": "236:722;163:722", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwL+SkWGDbeA=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwL+SkWGEkxM=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwL+SkWGFVnU=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwL+WL2GTesQ=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwL+WL2GScgY=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+WL2GUDZ4=", + "_parent": { + "$ref": "AAAAAAFFwL+WL2GTesQ=" + }, + "model": { + "$ref": "AAAAAAFFwL+WL2GScgY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 198, + "top": 797, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwL+WL2GTesQ=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+WL2GVfH8=", + "_parent": { + "$ref": "AAAAAAFFwL+WL2GTesQ=" + }, + "model": { + "$ref": "AAAAAAFFwL+WL2GScgY=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 198, + "top": 812, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwL+WL2GTesQ=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+WL2GW4Ys=", + "_parent": { + "$ref": "AAAAAAFFwL+WL2GTesQ=" + }, + "model": { + "$ref": "AAAAAAFFwL+WL2GScgY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 199, + "top": 767, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwL+WL2GTesQ=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwL2WeWA5NQI=" + }, + "tail": { + "$ref": "AAAAAAFFwL45WWCr3cU=" + }, + "points": "236:788;163:788", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwL+WL2GUDZ4=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwL+WL2GVfH8=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwL+WL2GW4Ys=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwL+Z72GkT5Y=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwL+Z72GjzGw=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+Z72GllyU=", + "_parent": { + "$ref": "AAAAAAFFwL+Z72GkT5Y=" + }, + "model": { + "$ref": "AAAAAAFFwL+Z72GjzGw=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 198, + "top": 854, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwL+Z72GkT5Y=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+Z72Gm6K8=", + "_parent": { + "$ref": "AAAAAAFFwL+Z72GkT5Y=" + }, + "model": { + "$ref": "AAAAAAFFwL+Z72GjzGw=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 198, + "top": 869, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwL+Z72GkT5Y=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+Z72GnawI=", + "_parent": { + "$ref": "AAAAAAFFwL+Z72GkT5Y=" + }, + "model": { + "$ref": "AAAAAAFFwL+Z72GjzGw=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 199, + "top": 824, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwL+Z72GkT5Y=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwL2WeWA5NQI=" + }, + "tail": { + "$ref": "AAAAAAFFwL5hQGDUxa0=" + }, + "points": "236:845;163:845", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwL+Z72GllyU=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwL+Z72Gm6K8=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwL+Z72GnawI=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwL+eh2G1gXM=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwL+eh2G01aU=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+eh2G2oXg=", + "_parent": { + "$ref": "AAAAAAFFwL+eh2G1gXM=" + }, + "model": { + "$ref": "AAAAAAFFwL+eh2G01aU=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 198, + "top": 910, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwL+eh2G1gXM=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+eh2G3GpE=", + "_parent": { + "$ref": "AAAAAAFFwL+eh2G1gXM=" + }, + "model": { + "$ref": "AAAAAAFFwL+eh2G01aU=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 198, + "top": 925, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwL+eh2G1gXM=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwL+eh2G4woY=", + "_parent": { + "$ref": "AAAAAAFFwL+eh2G1gXM=" + }, + "model": { + "$ref": "AAAAAAFFwL+eh2G01aU=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 199, + "top": 880, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwL+eh2G1gXM=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwL2WeWA5NQI=" + }, + "tail": { + "$ref": "AAAAAAFFwL7KdWEqew0=" + }, + "points": "236:901;163:901", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwL+eh2G2oXg=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwL+eh2G3GpE=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwL+eh2G4woY=" + } + }, + { + "_type": "UMLMetaClassView", + "_id": "AAAAAAFFwMFq1GHZe+E=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwMFq1GHYSKM=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwMFq1GHa5CM=", + "_parent": { + "$ref": "AAAAAAFFwMFq1GHZe+E=" + }, + "model": { + "$ref": "AAAAAAFFwMFq1GHYSKM=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwMFq1GHbxIU=", + "_parent": { + "$ref": "AAAAAAFFwMFq1GHa5CM=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 561, + "top": 33, + "width": 93, + "height": 12, + "text": "«metaClass»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMFq1GHc3zA=", + "_parent": { + "$ref": "AAAAAAFFwMFq1GHa5CM=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;1", + "containerExtending": true, + "left": 561, + "top": 47, + "width": 93, + "height": 12, + "text": "UMLAbstraction" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMFq1GHdTFI=", + "_parent": { + "$ref": "AAAAAAFFwMFq1GHa5CM=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": -12, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMFq1GHeicg=", + "_parent": { + "$ref": "AAAAAAFFwMFq1GHa5CM=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": -12, + "height": 12, + "horizontalAlignment": 1 + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 556, + "top": 28, + "width": 103, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwMFq1GHbxIU=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwMFq1GHc3zA=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwMFq1GHdTFI=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwMFq1GHeicg=" + } + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 556, + "top": 28, + "width": 103, + "height": 153, + "nameCompartment": { + "$ref": "AAAAAAFFwMFq1GHa5CM=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwMGle2H29zI=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwMGlemH0Tq8=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqKksmed8=", + "_parent": { + "$ref": "AAAAAAFFwMGle2H29zI=" + }, + "model": { + "$ref": "AAAAAAFFwMGlemH0Tq8=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwMGle2H3I+8=", + "_parent": { + "$ref": "AAAAAAFFwMGle2H29zI=" + }, + "model": { + "$ref": "AAAAAAFFwMGlemH0Tq8=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwMGle2H4B8s=", + "_parent": { + "$ref": "AAAAAAFFwMGle2H3I+8=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 745, + "top": 29, + "width": 110.396484375, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMGle2H5FWo=", + "_parent": { + "$ref": "AAAAAAFFwMGle2H3I+8=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 745, + "top": 43, + "width": 110.396484375, + "height": 12, + "text": "Derive" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMGle2H6wQw=", + "_parent": { + "$ref": "AAAAAAFFwMGle2H3I+8=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 252, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMGle2H7ifs=", + "_parent": { + "$ref": "AAAAAAFFwMGle2H3I+8=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 252, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 740, + "top": 24, + "width": 120.396484375, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwMGle2H4B8s=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwMGle2H5FWo=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwMGle2H6wQw=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwMGle2H7ifs=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwMGle2H8ZWU=", + "_parent": { + "$ref": "AAAAAAFFwMGle2H29zI=" + }, + "model": { + "$ref": "AAAAAAFFwMGlemH0Tq8=" + }, + "subViews": [ + { + "_type": "UMLAttributeView", + "_id": "AAAAAAFFwMJPAWJ40Vg=", + "_parent": { + "$ref": "AAAAAAFFwMGle2H8ZWU=" + }, + "model": { + "$ref": "AAAAAAFFwMJO92J1Y/s=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 745, + "top": 65, + "width": 110.396484375, + "height": 12, + "text": "+computation: String", + "horizontalAlignment": 0 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 740, + "top": 60, + "width": 127.16787719726562, + "height": 22 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwMGle2H9VL8=", + "_parent": { + "$ref": "AAAAAAFFwMGle2H29zI=" + }, + "model": { + "$ref": "AAAAAAFFwMGlemH0Tq8=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 824, + "top": 60, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwMGle2H+hpQ=", + "_parent": { + "$ref": "AAAAAAFFwMGle2H29zI=" + }, + "model": { + "$ref": "AAAAAAFFwMGlemH0Tq8=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 168, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 740, + "top": 24, + "width": 120.396484375, + "height": 58, + "autoResize": true, + "nameCompartment": { + "$ref": "AAAAAAFFwMGle2H3I+8=" + }, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwMGle2H8ZWU=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwMGle2H9VL8=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqKksmed8=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwMGle2H+hpQ=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwMGo6mIepMc=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwMGo6mIcITc=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqK0s9CwU=", + "_parent": { + "$ref": "AAAAAAFFwMGo6mIepMc=" + }, + "model": { + "$ref": "AAAAAAFFwMGo6mIcITc=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwMGo6mIfS5g=", + "_parent": { + "$ref": "AAAAAAFFwMGo6mIepMc=" + }, + "model": { + "$ref": "AAAAAAFFwMGo6mIcITc=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwMGo6mIgcys=", + "_parent": { + "$ref": "AAAAAAFFwMGo6mIfS5g=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 745, + "top": 101, + "width": 69.380859375, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMGo6mIha40=", + "_parent": { + "$ref": "AAAAAAFFwMGo6mIfS5g=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 745, + "top": 115, + "width": 69.380859375, + "height": 12, + "text": "Refine" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMGo6mIiGvE=", + "_parent": { + "$ref": "AAAAAAFFwMGo6mIfS5g=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 276, + "top": 120, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMGo6mIjVCs=", + "_parent": { + "$ref": "AAAAAAFFwMGo6mIfS5g=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 276, + "top": 120, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 740, + "top": 96, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwMGo6mIgcys=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwMGo6mIha40=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwMGo6mIiGvE=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwMGo6mIjVCs=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwMGo6mIkY0Y=", + "_parent": { + "$ref": "AAAAAAFFwMGo6mIepMc=" + }, + "model": { + "$ref": "AAAAAAFFwMGo6mIcITc=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 832, + "top": 172, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwMGo6mIlYhc=", + "_parent": { + "$ref": "AAAAAAFFwMGo6mIepMc=" + }, + "model": { + "$ref": "AAAAAAFFwMGo6mIcITc=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 832, + "top": 172, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwMGo6mImbZE=", + "_parent": { + "$ref": "AAAAAAFFwMGo6mIepMc=" + }, + "model": { + "$ref": "AAAAAAFFwMGo6mIcITc=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 184, + "top": 80, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 740, + "top": 96, + "width": 79.380859375, + "height": 36, + "autoResize": true, + "nameCompartment": { + "$ref": "AAAAAAFFwMGo6mIfS5g=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwMGo6mIkY0Y=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwMGo6mIlYhc=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqK0s9CwU=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwMGo6mImbZE=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwMGrimJGJ0s=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwMGrimJEvvk=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqK0tTuyw=", + "_parent": { + "$ref": "AAAAAAFFwMGrimJGJ0s=" + }, + "model": { + "$ref": "AAAAAAFFwMGrimJEvvk=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwMGrimJHZ7Y=", + "_parent": { + "$ref": "AAAAAAFFwMGrimJGJ0s=" + }, + "model": { + "$ref": "AAAAAAFFwMGrimJEvvk=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwMGrimJIfxU=", + "_parent": { + "$ref": "AAAAAAFFwMGrimJHZ7Y=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 745, + "top": 153, + "width": 69.380859375, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMGrimJJ7uc=", + "_parent": { + "$ref": "AAAAAAFFwMGrimJHZ7Y=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 745, + "top": 167, + "width": 69.380859375, + "height": 12, + "text": "Trace" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMGrimJKI9M=", + "_parent": { + "$ref": "AAAAAAFFwMGrimJHZ7Y=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 324, + "top": 168, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMGrimJL3ag=", + "_parent": { + "$ref": "AAAAAAFFwMGrimJHZ7Y=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 324, + "top": 168, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 740, + "top": 148, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwMGrimJIfxU=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwMGrimJJ7uc=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwMGrimJKI9M=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwMGrimJL3ag=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwMGrimJMCIQ=", + "_parent": { + "$ref": "AAAAAAFFwMGrimJGJ0s=" + }, + "model": { + "$ref": "AAAAAAFFwMGrimJEvvk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 848, + "top": 240, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwMGrimJNPbE=", + "_parent": { + "$ref": "AAAAAAFFwMGrimJGJ0s=" + }, + "model": { + "$ref": "AAAAAAFFwMGrimJEvvk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 848, + "top": 240, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwMGrimJOkXc=", + "_parent": { + "$ref": "AAAAAAFFwMGrimJGJ0s=" + }, + "model": { + "$ref": "AAAAAAFFwMGrimJEvvk=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 216, + "top": 112, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 740, + "top": 148, + "width": 79.380859375, + "height": 36, + "autoResize": true, + "nameCompartment": { + "$ref": "AAAAAAFFwMGrimJHZ7Y=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwMGrimJMCIQ=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwMGrimJNPbE=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqK0tTuyw=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwMGrimJOkXc=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwMLTm2KEAI0=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwMLTmmKDF1M=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwMLTm2KFRRg=", + "_parent": { + "$ref": "AAAAAAFFwMLTm2KEAI0=" + }, + "model": { + "$ref": "AAAAAAFFwMLTmmKDF1M=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 698, + "top": 61, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwMLTm2KEAI0=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwMLTm2KGrkQ=", + "_parent": { + "$ref": "AAAAAAFFwMLTm2KEAI0=" + }, + "model": { + "$ref": "AAAAAAFFwMLTmmKDF1M=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 698, + "top": 76, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwMLTm2KEAI0=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwMLTm2KHZTE=", + "_parent": { + "$ref": "AAAAAAFFwMLTm2KEAI0=" + }, + "model": { + "$ref": "AAAAAAFFwMLTmmKDF1M=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 699, + "top": 31, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwMLTm2KEAI0=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwMFq1GHZe+E=" + }, + "tail": { + "$ref": "AAAAAAFFwMGle2H29zI=" + }, + "points": "740:52;658:52", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwMLTm2KFRRg=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwMLTm2KGrkQ=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwMLTm2KHZTE=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwMLXQmKVDuM=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwMLXQmKUyu0=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwMLXQmKW+3c=", + "_parent": { + "$ref": "AAAAAAFFwMLXQmKVDuM=" + }, + "model": { + "$ref": "AAAAAAFFwMLXQmKUyu0=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 698, + "top": 121, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwMLXQmKVDuM=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwMLXQmKXpUQ=", + "_parent": { + "$ref": "AAAAAAFFwMLXQmKVDuM=" + }, + "model": { + "$ref": "AAAAAAFFwMLXQmKUyu0=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 698, + "top": 136, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwMLXQmKVDuM=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwMLXQmKYWOg=", + "_parent": { + "$ref": "AAAAAAFFwMLXQmKVDuM=" + }, + "model": { + "$ref": "AAAAAAFFwMLXQmKUyu0=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 699, + "top": 91, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwMLXQmKVDuM=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwMFq1GHZe+E=" + }, + "tail": { + "$ref": "AAAAAAFFwMGo6mIepMc=" + }, + "points": "740:112;658:112", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwMLXQmKW+3c=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwMLXQmKXpUQ=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwMLXQmKYWOg=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwMLbmmKmAvI=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwMLbmmKloGE=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwMLbmmKnMuM=", + "_parent": { + "$ref": "AAAAAAFFwMLbmmKmAvI=" + }, + "model": { + "$ref": "AAAAAAFFwMLbmmKloGE=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 698, + "top": 169, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwMLbmmKmAvI=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwMLbmmKonTw=", + "_parent": { + "$ref": "AAAAAAFFwMLbmmKmAvI=" + }, + "model": { + "$ref": "AAAAAAFFwMLbmmKloGE=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 698, + "top": 184, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwMLbmmKmAvI=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwMLbmmKpbLQ=", + "_parent": { + "$ref": "AAAAAAFFwMLbmmKmAvI=" + }, + "model": { + "$ref": "AAAAAAFFwMLbmmKloGE=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 699, + "top": 139, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwMLbmmKmAvI=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwMFq1GHZe+E=" + }, + "tail": { + "$ref": "AAAAAAFFwMGrimJGJ0s=" + }, + "points": "740:160;658:160", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwMLbmmKnMuM=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwMLbmmKonTw=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwMLbmmKpbLQ=" + } + }, + { + "_type": "UMLMetaClassView", + "_id": "AAAAAAFFwMYNEWK8jeA=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwMYNEWK7ItA=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwMYNEWK9Wb8=", + "_parent": { + "$ref": "AAAAAAFFwMYNEWK8jeA=" + }, + "model": { + "$ref": "AAAAAAFFwMYNEWK7ItA=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwMYNEWK++fU=", + "_parent": { + "$ref": "AAAAAAFFwMYNEWK9Wb8=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 561, + "top": 833, + "width": 91, + "height": 12, + "text": "«metaClass»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMYNEWK/PY8=", + "_parent": { + "$ref": "AAAAAAFFwMYNEWK9Wb8=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;1", + "containerExtending": true, + "left": 561, + "top": 847, + "width": 91, + "height": 12, + "text": "UMLPackage" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMYNEWLAHjA=", + "_parent": { + "$ref": "AAAAAAFFwMYNEWK9Wb8=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMYNEWLBm9I=", + "_parent": { + "$ref": "AAAAAAFFwMYNEWK9Wb8=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "height": 12, + "horizontalAlignment": 1 + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 556, + "top": 828, + "width": 101, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwMYNEWK++fU=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwMYNEWK/PY8=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwMYNEWLAHjA=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwMYNEWLBm9I=" + } + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 556, + "top": 828, + "width": 101, + "height": 101, + "nameCompartment": { + "$ref": "AAAAAAFFwMYNEWK9Wb8=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwMdnrWLZAY8=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwMdnrWLXWLA=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqLUuNRhM=", + "_parent": { + "$ref": "AAAAAAFFwMdnrWLZAY8=" + }, + "model": { + "$ref": "AAAAAAFFwMdnrWLXWLA=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwMdnrWLaXkY=", + "_parent": { + "$ref": "AAAAAAFFwMdnrWLZAY8=" + }, + "model": { + "$ref": "AAAAAAFFwMdnrWLXWLA=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwMdnrmLbib0=", + "_parent": { + "$ref": "AAAAAAFFwMdnrWLaXkY=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 729, + "top": 837, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMdnrmLclU4=", + "_parent": { + "$ref": "AAAAAAFFwMdnrWLaXkY=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 729, + "top": 851, + "width": 72.51593017578125, + "height": 12, + "text": "Framework" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMdnrmLdBNU=", + "_parent": { + "$ref": "AAAAAAFFwMdnrWLaXkY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMdnrmLeF4I=", + "_parent": { + "$ref": "AAAAAAFFwMdnrWLaXkY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 724, + "top": 832, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwMdnrmLbib0=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwMdnrmLclU4=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwMdnrmLdBNU=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwMdnrmLeF4I=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwMdnrmLf950=", + "_parent": { + "$ref": "AAAAAAFFwMdnrWLZAY8=" + }, + "model": { + "$ref": "AAAAAAFFwMdnrWLXWLA=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 724, + "top": 868, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwMdnrmLgzek=", + "_parent": { + "$ref": "AAAAAAFFwMdnrWLZAY8=" + }, + "model": { + "$ref": "AAAAAAFFwMdnrWLXWLA=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 724, + "top": 878, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwMdnrmLhmpQ=", + "_parent": { + "$ref": "AAAAAAFFwMdnrWLZAY8=" + }, + "model": { + "$ref": "AAAAAAFFwMdnrWLXWLA=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 724, + "top": 832, + "width": 82.51593017578125, + "height": 37, + "nameCompartment": { + "$ref": "AAAAAAFFwMdnrWLaXkY=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwMdnrmLf950=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwMdnrmLgzek=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqLUuNRhM=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwMdnrmLhmpQ=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwMeIHGMCTCk=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwMeIHGMAPDc=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqLUujT3E=", + "_parent": { + "$ref": "AAAAAAFFwMeIHGMCTCk=" + }, + "model": { + "$ref": "AAAAAAFFwMeIHGMAPDc=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwMeIHGMDiPY=", + "_parent": { + "$ref": "AAAAAAFFwMeIHGMCTCk=" + }, + "model": { + "$ref": "AAAAAAFFwMeIHGMAPDc=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwMeIHGMEN4g=", + "_parent": { + "$ref": "AAAAAAFFwMeIHGMDiPY=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 729, + "top": 893, + "width": 75.345703125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMeIHGMFxQc=", + "_parent": { + "$ref": "AAAAAAFFwMeIHGMDiPY=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 729, + "top": 907, + "width": 75.345703125, + "height": 12, + "text": "ModelLibrary" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMeIHGMG6CQ=", + "_parent": { + "$ref": "AAAAAAFFwMeIHGMDiPY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "top": -60, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwMeIHGMH2dQ=", + "_parent": { + "$ref": "AAAAAAFFwMeIHGMDiPY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "top": -60, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 724, + "top": 888, + "width": 85.345703125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwMeIHGMEN4g=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwMeIHGMFxQc=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwMeIHGMG6CQ=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwMeIHGMH2dQ=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwMeIHGMI7hI=", + "_parent": { + "$ref": "AAAAAAFFwMeIHGMCTCk=" + }, + "model": { + "$ref": "AAAAAAFFwMeIHGMAPDc=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 724, + "top": 904, + "width": 85, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwMeIHGMJi90=", + "_parent": { + "$ref": "AAAAAAFFwMeIHGMCTCk=" + }, + "model": { + "$ref": "AAAAAAFFwMeIHGMAPDc=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 724, + "top": 914, + "width": 85, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwMeIHGMK1pc=", + "_parent": { + "$ref": "AAAAAAFFwMeIHGMCTCk=" + }, + "model": { + "$ref": "AAAAAAFFwMeIHGMAPDc=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "top": -40, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 724, + "top": 888, + "width": 85.345703125, + "height": 37, + "nameCompartment": { + "$ref": "AAAAAAFFwMeIHGMDiPY=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwMeIHGMI7hI=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwMeIHGMJi90=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqLUujT3E=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwMeIHGMK1pc=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwMevo2Mq4Ew=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwMevo2MpIU4=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwMevo2Mr7wQ=", + "_parent": { + "$ref": "AAAAAAFFwMevo2Mq4Ew=" + }, + "model": { + "$ref": "AAAAAAFFwMevo2MpIU4=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 689, + "top": 861, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwMevo2Mq4Ew=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwMevo2Msv/w=", + "_parent": { + "$ref": "AAAAAAFFwMevo2Mq4Ew=" + }, + "model": { + "$ref": "AAAAAAFFwMevo2MpIU4=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 689, + "top": 876, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwMevo2Mq4Ew=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwMevo2MtL5c=", + "_parent": { + "$ref": "AAAAAAFFwMevo2Mq4Ew=" + }, + "model": { + "$ref": "AAAAAAFFwMevo2MpIU4=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 690, + "top": 831, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwMevo2Mq4Ew=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwMYNEWK8jeA=" + }, + "tail": { + "$ref": "AAAAAAFFwMdnrWLZAY8=" + }, + "points": "724:852;656:852", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwMevo2Mr7wQ=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwMevo2Msv/w=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwMevo2MtL5c=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwMe0G2M7rmg=", + "_parent": { + "$ref": "AAAAAAFElnFUQFS4mT4=" + }, + "model": { + "$ref": "AAAAAAFFwMe0G2M69PQ=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwMe0G2M8gls=", + "_parent": { + "$ref": "AAAAAAFFwMe0G2M7rmg=" + }, + "model": { + "$ref": "AAAAAAFFwMe0G2M69PQ=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 689, + "top": 917, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwMe0G2M7rmg=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwMe0G2M9WEg=", + "_parent": { + "$ref": "AAAAAAFFwMe0G2M7rmg=" + }, + "model": { + "$ref": "AAAAAAFFwMe0G2M69PQ=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 689, + "top": 932, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwMe0G2M7rmg=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwMe0G2M+CD8=", + "_parent": { + "$ref": "AAAAAAFFwMe0G2M7rmg=" + }, + "model": { + "$ref": "AAAAAAFFwMe0G2M69PQ=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 690, + "top": 887, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwMe0G2M7rmg=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwMYNEWK8jeA=" + }, + "tail": { + "$ref": "AAAAAAFFwMeIHGMCTCk=" + }, + "points": "724:908;656:908", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwMe0G2M8gls=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwMe0G2M9WEg=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwMe0G2M+CD8=" + } + } + ] + }, + { + "_type": "UMLMetaClass", + "_id": "AAAAAAFElnFrT1S7Kic=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "UMLClassifier" + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFElnF1nFTY/Sw=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Realization", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFElnGGLFUFZFA=", + "_parent": { + "$ref": "AAAAAAFElnF1nFTY/Sw=" + }, + "source": { + "$ref": "AAAAAAFElnF1nFTY/Sw=" + }, + "target": { + "$ref": "AAAAAAFElnFrT1S7Kic=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFElnF1nFTZHOU=", + "_parent": { + "$ref": "AAAAAAFElnF1nFTY/Sw=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFElnJRglVKSoc=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Specification", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFElnKVuVV4pBU=", + "_parent": { + "$ref": "AAAAAAFElnJRglVKSoc=" + }, + "source": { + "$ref": "AAAAAAFElnJRglVKSoc=" + }, + "target": { + "$ref": "AAAAAAFElnFrT1S7Kic=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFElnJRglVLifA=", + "_parent": { + "$ref": "AAAAAAFElnJRglVKSoc=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFJsYgDTM+Z6E=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "entity", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFJsZx3DOCac8=", + "_parent": { + "$ref": "AAAAAAFFJsYgDTM+Z6E=" + }, + "source": { + "$ref": "AAAAAAFFJsYgDTM+Z6E=" + }, + "target": { + "$ref": "AAAAAAFFJsZbpDNobIs=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFJsYgDTM/qY8=", + "_parent": { + "$ref": "AAAAAAFFJsYgDTM+Z6E=" + }, + "width": 40, + "height": 40, + "content": "var w = rect.getWidth(),\n m = w / 10;\ncanvas.fillEllipse(rect.x1 + m, rect.y1 + m, rect.x2 - m, rect.y2 - m);\ncanvas.ellipse(rect.x1 + m, rect.y1 + m, rect.x2 - m, rect.y2 - m);\ncanvas.line(rect.x1 + m, rect.y2 - m, rect.x2 - m, rect.y2 - m);\n" + } + }, + { + "_type": "UMLMetaClass", + "_id": "AAAAAAFFJsZbpDNobIs=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "UMLClass" + }, + { + "_type": "UMLMetaClass", + "_id": "AAAAAAFFwKqhJFq06mA=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "UMLArtifact" + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwKsvdVrRJUQ=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "File", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwK5AeFyZpVg=", + "_parent": { + "$ref": "AAAAAAFFwKsvdVrRJUQ=" + }, + "source": { + "$ref": "AAAAAAFFwKsvdVrRJUQ=" + }, + "target": { + "$ref": "AAAAAAFFwKqhJFq06mA=" + } + } + ], + "isAbstract": true, + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwKsvdVrSLo0=", + "_parent": { + "$ref": "AAAAAAFFwKsvdVrRJUQ=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwKtwS1r6wew=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Document", + "ownedElements": [ + { + "_type": "UMLGeneralization", + "_id": "AAAAAAFFwKzkslvX4gU=", + "_parent": { + "$ref": "AAAAAAFFwKtwS1r6wew=" + }, + "source": { + "$ref": "AAAAAAFFwKtwS1r6wew=" + }, + "target": { + "$ref": "AAAAAAFFwKsvdVrRJUQ=" + } + }, + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwK4k1VxEEpM=", + "_parent": { + "$ref": "AAAAAAFFwKtwS1r6wew=" + }, + "source": { + "$ref": "AAAAAAFFwKtwS1r6wew=" + }, + "target": { + "$ref": "AAAAAAFFwKqhJFq06mA=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwKtwS1r7XqE=", + "_parent": { + "$ref": "AAAAAAFFwKtwS1r6wew=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwKuBulsidLQ=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Executable", + "ownedElements": [ + { + "_type": "UMLGeneralization", + "_id": "AAAAAAFFwKzsCVvo11g=", + "_parent": { + "$ref": "AAAAAAFFwKuBulsidLQ=" + }, + "source": { + "$ref": "AAAAAAFFwKuBulsidLQ=" + }, + "target": { + "$ref": "AAAAAAFFwKsvdVrRJUQ=" + } + }, + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwK4o4VxVx00=", + "_parent": { + "$ref": "AAAAAAFFwKuBulsidLQ=" + }, + "source": { + "$ref": "AAAAAAFFwKuBulsidLQ=" + }, + "target": { + "$ref": "AAAAAAFFwKqhJFq06mA=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwKuBulsjhp0=", + "_parent": { + "$ref": "AAAAAAFFwKuBulsidLQ=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwKuIMltKnQQ=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Library", + "ownedElements": [ + { + "_type": "UMLGeneralization", + "_id": "AAAAAAFFwKzxcVv56Dg=", + "_parent": { + "$ref": "AAAAAAFFwKuIMltKnQQ=" + }, + "source": { + "$ref": "AAAAAAFFwKuIMltKnQQ=" + }, + "target": { + "$ref": "AAAAAAFFwKsvdVrRJUQ=" + } + }, + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwK4tiVxmVJM=", + "_parent": { + "$ref": "AAAAAAFFwKuIMltKnQQ=" + }, + "source": { + "$ref": "AAAAAAFFwKuIMltKnQQ=" + }, + "target": { + "$ref": "AAAAAAFFwKqhJFq06mA=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwKuIMltLkmg=", + "_parent": { + "$ref": "AAAAAAFFwKuIMltKnQQ=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwKuS0ltysPk=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Script", + "ownedElements": [ + { + "_type": "UMLGeneralization", + "_id": "AAAAAAFFwKz3OVwK9hs=", + "_parent": { + "$ref": "AAAAAAFFwKuS0ltysPk=" + }, + "source": { + "$ref": "AAAAAAFFwKuS0ltysPk=" + }, + "target": { + "$ref": "AAAAAAFFwKsvdVrRJUQ=" + } + }, + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwK41YVx3Hr0=", + "_parent": { + "$ref": "AAAAAAFFwKuS0ltysPk=" + }, + "source": { + "$ref": "AAAAAAFFwKuS0ltysPk=" + }, + "target": { + "$ref": "AAAAAAFFwKqhJFq06mA=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwKuS0ltz9pw=", + "_parent": { + "$ref": "AAAAAAFFwKuS0ltysPk=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwKueMVuaLXM=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Source", + "ownedElements": [ + { + "_type": "UMLGeneralization", + "_id": "AAAAAAFFwKz9mFwbfDg=", + "_parent": { + "$ref": "AAAAAAFFwKueMVuaLXM=" + }, + "source": { + "$ref": "AAAAAAFFwKueMVuaLXM=" + }, + "target": { + "$ref": "AAAAAAFFwKsvdVrRJUQ=" + } + }, + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwK47MFyIL/c=", + "_parent": { + "$ref": "AAAAAAFFwKueMVuaLXM=" + }, + "source": { + "$ref": "AAAAAAFFwKueMVuaLXM=" + }, + "target": { + "$ref": "AAAAAAFFwKqhJFq06mA=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwKueMlubedY=", + "_parent": { + "$ref": "AAAAAAFFwKueMVuaLXM=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLMetaClass", + "_id": "AAAAAAFFwK/k1ly00Ec=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "UMLBehavioralFeature" + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwLBdO1zQosE=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Destroy", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwLDMaFz5C14=", + "_parent": { + "$ref": "AAAAAAFFwLBdO1zQosE=" + }, + "source": { + "$ref": "AAAAAAFFwLBdO1zQosE=" + }, + "target": { + "$ref": "AAAAAAFFwK/k1ly00Ec=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwLBdO1zR7Ak=", + "_parent": { + "$ref": "AAAAAAFFwLBdO1zQosE=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwLFUbV0QQVA=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Auxiliary", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwLNej157D6Y=", + "_parent": { + "$ref": "AAAAAAFFwLFUbV0QQVA=" + }, + "source": { + "$ref": "AAAAAAFFwLFUbV0QQVA=" + }, + "target": { + "$ref": "AAAAAAFFJsZbpDNobIs=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwLFUbV0RoPU=", + "_parent": { + "$ref": "AAAAAAFFwLFUbV0QQVA=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwLFu8104he4=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Focus", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwLNkZ16Mp7Y=", + "_parent": { + "$ref": "AAAAAAFFwLFu8104he4=" + }, + "source": { + "$ref": "AAAAAAFFwLFu8104he4=" + }, + "target": { + "$ref": "AAAAAAFFJsZbpDNobIs=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwLFu9F05JGE=", + "_parent": { + "$ref": "AAAAAAFFwLFu8104he4=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwLF4tF1g4No=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Metaclass", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwLNn916d4Yc=", + "_parent": { + "$ref": "AAAAAAFFwLF4tF1g4No=" + }, + "source": { + "$ref": "AAAAAAFFwLF4tF1g4No=" + }, + "target": { + "$ref": "AAAAAAFFJsZbpDNobIs=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwLF4tF1h94I=", + "_parent": { + "$ref": "AAAAAAFFwLF4tF1g4No=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwLF/G12IJ54=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "ImplementationClass", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwLNr116u93k=", + "_parent": { + "$ref": "AAAAAAFFwLF/G12IJ54=" + }, + "source": { + "$ref": "AAAAAAFFwLF/G12IJ54=" + }, + "target": { + "$ref": "AAAAAAFFJsZbpDNobIs=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwLF/G12JIns=", + "_parent": { + "$ref": "AAAAAAFFwLF/G12IJ54=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwLGEO12wqJ8=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Type", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwLNvdl6/WJI=", + "_parent": { + "$ref": "AAAAAAFFwLGEO12wqJ8=" + }, + "source": { + "$ref": "AAAAAAFFwLGEO12wqJ8=" + }, + "target": { + "$ref": "AAAAAAFFJsZbpDNobIs=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwLGEPF2x7bg=", + "_parent": { + "$ref": "AAAAAAFFwLGEO12wqJ8=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwLGI813YL3s=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Utility", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwLN0fl7QL9o=", + "_parent": { + "$ref": "AAAAAAFFwLGI813YL3s=" + }, + "source": { + "$ref": "AAAAAAFFwLGI813YL3s=" + }, + "target": { + "$ref": "AAAAAAFFJsZbpDNobIs=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwLGI813ZPxY=", + "_parent": { + "$ref": "AAAAAAFFwLGI813YL3s=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLProfileDiagram", + "_id": "AAAAAAFFwLKxU14QPaE=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Robustness Stereotypes", + "ownedViews": [ + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwLL0NF4VWXk=", + "_parent": { + "$ref": "AAAAAAFFwLKxU14QPaE=" + }, + "model": { + "$ref": "AAAAAAFFJsYgDTM+Z6E=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqMEwRREE=", + "_parent": { + "$ref": "AAAAAAFFwLL0NF4VWXk=" + }, + "model": { + "$ref": "AAAAAAFFJsYgDTM+Z6E=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwLL0NF4WzoE=", + "_parent": { + "$ref": "AAAAAAFFwLL0NF4VWXk=" + }, + "model": { + "$ref": "AAAAAAFFJsYgDTM+Z6E=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwLL0NF4X88I=", + "_parent": { + "$ref": "AAAAAAFFwLL0NF4WzoE=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 217, + "top": 89, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLL0NF4YSt8=", + "_parent": { + "$ref": "AAAAAAFFwLL0NF4WzoE=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 217, + "top": 103, + "width": 72.51593017578125, + "height": 12, + "text": "entity" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLL0NF4ZQaQ=", + "_parent": { + "$ref": "AAAAAAFFwLL0NF4WzoE=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -1065, + "top": -270, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLL0NF4asxs=", + "_parent": { + "$ref": "AAAAAAFFwLL0NF4WzoE=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -1065, + "top": -270, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 212, + "top": 84, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLL0NF4X88I=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwLL0NF4YSt8=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwLL0NF4ZQaQ=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLL0NF4asxs=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwLL0NF4bgXg=", + "_parent": { + "$ref": "AAAAAAFFwLL0NF4VWXk=" + }, + "model": { + "$ref": "AAAAAAFFJsYgDTM+Z6E=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 92, + "top": -28, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwLL0NF4cZ88=", + "_parent": { + "$ref": "AAAAAAFFwLL0NF4VWXk=" + }, + "model": { + "$ref": "AAAAAAFFJsYgDTM+Z6E=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 92, + "top": -18, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwLL0NF4dJaE=", + "_parent": { + "$ref": "AAAAAAFFwLL0NF4VWXk=" + }, + "model": { + "$ref": "AAAAAAFFJsYgDTM+Z6E=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -710, + "top": -180, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 212, + "top": 84, + "width": 82.51593017578125, + "height": 37, + "nameCompartment": { + "$ref": "AAAAAAFFwLL0NF4WzoE=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwLL0NF4bgXg=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwLL0NF4cZ88=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqMEwRREE=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwLL0NF4dJaE=" + } + }, + { + "_type": "UMLMetaClassView", + "_id": "AAAAAAFFwLMO8l44tWU=", + "_parent": { + "$ref": "AAAAAAFFwLKxU14QPaE=" + }, + "model": { + "$ref": "AAAAAAFFJsZbpDNobIs=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwLMO8l45ook=", + "_parent": { + "$ref": "AAAAAAFFwLMO8l44tWU=" + }, + "model": { + "$ref": "AAAAAAFFJsZbpDNobIs=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwLMO8l46Nac=", + "_parent": { + "$ref": "AAAAAAFFwLMO8l45ook=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 33, + "top": 33, + "width": 79, + "height": 12, + "text": "«metaClass»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLMO8l47xu4=", + "_parent": { + "$ref": "AAAAAAFFwLMO8l45ook=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;1", + "containerExtending": true, + "left": 33, + "top": 47, + "width": 79, + "height": 12, + "text": "UMLClass" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLMO8l48V+s=", + "_parent": { + "$ref": "AAAAAAFFwLMO8l45ook=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": -489, + "top": -414, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwLMO8l490+g=", + "_parent": { + "$ref": "AAAAAAFFwLMO8l45ook=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": -489, + "top": -414, + "height": 12, + "horizontalAlignment": 1 + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 28, + "top": 28, + "width": 89, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLMO8l46Nac=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwLMO8l47xu4=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwLMO8l48V+s=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLMO8l490+g=" + } + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 28, + "top": 28, + "width": 89, + "height": 149, + "nameCompartment": { + "$ref": "AAAAAAFFwLMO8l45ook=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwLMO814+17w=", + "_parent": { + "$ref": "AAAAAAFFwLKxU14QPaE=" + }, + "model": { + "$ref": "AAAAAAFFJsZx3DOCac8=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLMO814/vLk=", + "_parent": { + "$ref": "AAAAAAFFwLMO814+17w=" + }, + "model": { + "$ref": "AAAAAAFFJsZx3DOCac8=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 163, + "top": 109, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLMO814+17w=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLMO815A2sw=", + "_parent": { + "$ref": "AAAAAAFFwLMO814+17w=" + }, + "model": { + "$ref": "AAAAAAFFJsZx3DOCac8=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 163, + "top": 124, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwLMO814+17w=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwLMO815BAcU=", + "_parent": { + "$ref": "AAAAAAFFwLMO814+17w=" + }, + "model": { + "$ref": "AAAAAAFFJsZx3DOCac8=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 164, + "top": 79, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwLMO814+17w=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwLMO8l44tWU=" + }, + "tail": { + "$ref": "AAAAAAFFwLL0NF4VWXk=" + }, + "points": "212:100;116:100", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwLMO814/vLk=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwLMO815A2sw=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwLMO815BAcU=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwx8Q/35wG9A=", + "_parent": { + "$ref": "AAAAAAFFwLKxU14QPaE=" + }, + "model": { + "$ref": "AAAAAAFFwx8Q/35u/80=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqMUw9MBk=", + "_parent": { + "$ref": "AAAAAAFFwx8Q/35wG9A=" + }, + "model": { + "$ref": "AAAAAAFFwx8Q/35u/80=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwx8Q/35xpyY=", + "_parent": { + "$ref": "AAAAAAFFwx8Q/35wG9A=" + }, + "model": { + "$ref": "AAAAAAFFwx8Q/35u/80=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwx8Q/35yVU8=", + "_parent": { + "$ref": "AAAAAAFFwx8Q/35xpyY=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 217, + "top": 37, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwx8Q/35z0VE=", + "_parent": { + "$ref": "AAAAAAFFwx8Q/35xpyY=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 217, + "top": 51, + "width": 72.51593017578125, + "height": 12, + "text": "control" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwx8Q/3506PU=", + "_parent": { + "$ref": "AAAAAAFFwx8Q/35xpyY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -336, + "top": -312, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwx8Q/351cP0=", + "_parent": { + "$ref": "AAAAAAFFwx8Q/35xpyY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -336, + "top": -312, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 212, + "top": 32, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwx8Q/35yVU8=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwx8Q/35z0VE=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwx8Q/3506PU=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwx8Q/351cP0=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwx8RAH52xko=", + "_parent": { + "$ref": "AAAAAAFFwx8Q/35wG9A=" + }, + "model": { + "$ref": "AAAAAAFFwx8Q/35u/80=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 76, + "top": -4, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwx8RAH53MWs=", + "_parent": { + "$ref": "AAAAAAFFwx8Q/35wG9A=" + }, + "model": { + "$ref": "AAAAAAFFwx8Q/35u/80=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 76, + "top": 6, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwx8RAH54kik=", + "_parent": { + "$ref": "AAAAAAFFwx8Q/35wG9A=" + }, + "model": { + "$ref": "AAAAAAFFwx8Q/35u/80=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": -224, + "top": -208, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 212, + "top": 32, + "width": 82.51593017578125, + "height": 37, + "nameCompartment": { + "$ref": "AAAAAAFFwx8Q/35xpyY=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwx8RAH52xko=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwx8RAH53MWs=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqMUw9MBk=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwx8RAH54kik=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwyAHeH6a9yk=", + "_parent": { + "$ref": "AAAAAAFFwLKxU14QPaE=" + }, + "model": { + "$ref": "AAAAAAFFwyAHeH6Znas=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwyAHeX6b9JY=", + "_parent": { + "$ref": "AAAAAAFFwyAHeH6a9yk=" + }, + "model": { + "$ref": "AAAAAAFFwyAHeH6Znas=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 163, + "top": 61, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwyAHeH6a9yk=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwyAHeX6cKyY=", + "_parent": { + "$ref": "AAAAAAFFwyAHeH6a9yk=" + }, + "model": { + "$ref": "AAAAAAFFwyAHeH6Znas=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 163, + "top": 76, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwyAHeH6a9yk=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwyAHeX6dvIk=", + "_parent": { + "$ref": "AAAAAAFFwyAHeH6a9yk=" + }, + "model": { + "$ref": "AAAAAAFFwyAHeH6Znas=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 164, + "top": 31, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwyAHeH6a9yk=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwLMO8l44tWU=" + }, + "tail": { + "$ref": "AAAAAAFFwx8Q/35wG9A=" + }, + "points": "212:52;116:52", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwyAHeX6b9JY=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwyAHeX6cKyY=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwyAHeX6dvIk=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFw0h1/QXNqo4=", + "_parent": { + "$ref": "AAAAAAFFwLKxU14QPaE=" + }, + "model": { + "$ref": "AAAAAAFFw0h1/QXL978=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqMkxa+TA=", + "_parent": { + "$ref": "AAAAAAFFw0h1/QXNqo4=" + }, + "model": { + "$ref": "AAAAAAFFw0h1/QXL978=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFw0h1/gXOBI4=", + "_parent": { + "$ref": "AAAAAAFFw0h1/QXNqo4=" + }, + "model": { + "$ref": "AAAAAAFFw0h1/QXL978=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFw0h1/gXPA/w=", + "_parent": { + "$ref": "AAAAAAFFw0h1/gXOBI4=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 217, + "top": 141, + "width": 72.51593017578125, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFw0h1/gXQ/LI=", + "_parent": { + "$ref": "AAAAAAFFw0h1/gXOBI4=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 217, + "top": 155, + "width": 72.51593017578125, + "height": 12, + "text": "boundary" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFw0h1/gXRrB4=", + "_parent": { + "$ref": "AAAAAAFFw0h1/gXOBI4=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 96, + "top": -360, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFw0h1/gXSVgA=", + "_parent": { + "$ref": "AAAAAAFFw0h1/gXOBI4=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 96, + "top": -360, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 212, + "top": 136, + "width": 82.51593017578125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFw0h1/gXPA/w=" + }, + "nameLabel": { + "$ref": "AAAAAAFFw0h1/gXQ/LI=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFw0h1/gXRrB4=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFw0h1/gXSVgA=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFw0h1/gXTCRY=", + "_parent": { + "$ref": "AAAAAAFFw0h1/QXNqo4=" + }, + "model": { + "$ref": "AAAAAAFFw0h1/QXL978=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 72, + "top": -20, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFw0h1/gXUu1g=", + "_parent": { + "$ref": "AAAAAAFFw0h1/QXNqo4=" + }, + "model": { + "$ref": "AAAAAAFFw0h1/QXL978=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 72, + "top": -10, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFw0h1/gXVEL8=", + "_parent": { + "$ref": "AAAAAAFFw0h1/QXNqo4=" + }, + "model": { + "$ref": "AAAAAAFFw0h1/QXL978=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 64, + "top": -240, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 212, + "top": 136, + "width": 82.51593017578125, + "height": 37, + "nameCompartment": { + "$ref": "AAAAAAFFw0h1/gXOBI4=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFw0h1/gXTCRY=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFw0h1/gXUu1g=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqMkxa+TA=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFw0h1/gXVEL8=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFw0o5p5IVMGM=", + "_parent": { + "$ref": "AAAAAAFFwLKxU14QPaE=" + }, + "model": { + "$ref": "AAAAAAFFw0o5ppIUB2s=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFw0o5p5IW5Js=", + "_parent": { + "$ref": "AAAAAAFFw0o5p5IVMGM=" + }, + "model": { + "$ref": "AAAAAAFFw0o5ppIUB2s=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 163, + "top": 165, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFw0o5p5IVMGM=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFw0o5p5IXSKA=", + "_parent": { + "$ref": "AAAAAAFFw0o5p5IVMGM=" + }, + "model": { + "$ref": "AAAAAAFFw0o5ppIUB2s=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 163, + "top": 180, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFw0o5p5IVMGM=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFw0o5p5IY/GE=", + "_parent": { + "$ref": "AAAAAAFFw0o5p5IVMGM=" + }, + "model": { + "$ref": "AAAAAAFFw0o5ppIUB2s=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 164, + "top": 135, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFw0o5p5IVMGM=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwLMO8l44tWU=" + }, + "tail": { + "$ref": "AAAAAAFFw0h1/QXNqo4=" + }, + "points": "212:156;116:156", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFw0o5p5IW5Js=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFw0o5p5IXSKA=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFw0o5p5IY/GE=" + } + } + ] + }, + { + "_type": "UMLMetaClass", + "_id": "AAAAAAFFwLRECl7r1R4=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "UMLComponent" + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwLR8CF8G68k=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Entity", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwLV9gV/Xhk4=", + "_parent": { + "$ref": "AAAAAAFFwLR8CF8G68k=" + }, + "source": { + "$ref": "AAAAAAFFwLR8CF8G68k=" + }, + "target": { + "$ref": "AAAAAAFFwLRECl7r1R4=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwLR8CF8HOik=", + "_parent": { + "$ref": "AAAAAAFFwLR8CF8G68k=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwLSByF8umMo=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Implementation", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwLWA0V/olVk=", + "_parent": { + "$ref": "AAAAAAFFwLSByF8umMo=" + }, + "source": { + "$ref": "AAAAAAFFwLSByF8umMo=" + }, + "target": { + "$ref": "AAAAAAFFwLRECl7r1R4=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwLSByF8vzKA=", + "_parent": { + "$ref": "AAAAAAFFwLSByF8umMo=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwLSIN19WMnE=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Process", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwLWEUV/5Qq4=", + "_parent": { + "$ref": "AAAAAAFFwLSIN19WMnE=" + }, + "source": { + "$ref": "AAAAAAFFwLSIN19WMnE=" + }, + "target": { + "$ref": "AAAAAAFFwLRECl7r1R4=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwLSIN19XVng=", + "_parent": { + "$ref": "AAAAAAFFwLSIN19WMnE=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwLSO/19+cMY=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Service", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwLWIQWAKKPo=", + "_parent": { + "$ref": "AAAAAAFFwLSO/19+cMY=" + }, + "source": { + "$ref": "AAAAAAFFwLSO/19+cMY=" + }, + "target": { + "$ref": "AAAAAAFFwLRECl7r1R4=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwLSO/19/YUk=", + "_parent": { + "$ref": "AAAAAAFFwLSO/19+cMY=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwLSXP1+mTVk=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Subsystem", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwLWMgWAb2Sk=", + "_parent": { + "$ref": "AAAAAAFFwLSXP1+mTVk=" + }, + "source": { + "$ref": "AAAAAAFFwLSXP1+mTVk=" + }, + "target": { + "$ref": "AAAAAAFFwLRECl7r1R4=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwLSXP1+njeI=", + "_parent": { + "$ref": "AAAAAAFFwLSXP1+mTVk=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLMetaClass", + "_id": "AAAAAAFFwL2WeGA460g=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "UMLDependency" + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwL4D0mBXwu4=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Create", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwL+LCGFfPQs=", + "_parent": { + "$ref": "AAAAAAFFwL4D0mBXwu4=" + }, + "source": { + "$ref": "AAAAAAFFwL4D0mBXwu4=" + }, + "target": { + "$ref": "AAAAAAFFwK/k1ly00Ec=" + } + }, + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwL+O8GFwbog=", + "_parent": { + "$ref": "AAAAAAFFwL4D0mBXwu4=" + }, + "source": { + "$ref": "AAAAAAFFwL4D0mBXwu4=" + }, + "target": { + "$ref": "AAAAAAFFwL2WeGA460g=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwL4D0mBYXVU=", + "_parent": { + "$ref": "AAAAAAFFwL4D0mBXwu4=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwL4h4WCAEkg=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Call", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwL+SkWGBCOg=", + "_parent": { + "$ref": "AAAAAAFFwL4h4WCAEkg=" + }, + "source": { + "$ref": "AAAAAAFFwL4h4WCAEkg=" + }, + "target": { + "$ref": "AAAAAAFFwL2WeGA460g=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwL4h4WCBKPU=", + "_parent": { + "$ref": "AAAAAAFFwL4h4WCAEkg=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwL45WWCpJ0o=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Instantiate", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwL+WL2GScgY=", + "_parent": { + "$ref": "AAAAAAFFwL45WWCpJ0o=" + }, + "source": { + "$ref": "AAAAAAFFwL45WWCpJ0o=" + }, + "target": { + "$ref": "AAAAAAFFwL2WeGA460g=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwL45WWCq/8I=", + "_parent": { + "$ref": "AAAAAAFFwL45WWCpJ0o=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwL5hP2DSEFk=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Responsibility", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwL+Z72GjzGw=", + "_parent": { + "$ref": "AAAAAAFFwL5hP2DSEFk=" + }, + "source": { + "$ref": "AAAAAAFFwL5hP2DSEFk=" + }, + "target": { + "$ref": "AAAAAAFFwL2WeGA460g=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwL5hQGDTCjI=", + "_parent": { + "$ref": "AAAAAAFFwL5hP2DSEFk=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwL7KdWEoDhA=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Send", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwL+eh2G01aU=", + "_parent": { + "$ref": "AAAAAAFFwL7KdWEoDhA=" + }, + "source": { + "$ref": "AAAAAAFFwL7KdWEoDhA=" + }, + "target": { + "$ref": "AAAAAAFFwL2WeGA460g=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwL7KdWEpx8M=", + "_parent": { + "$ref": "AAAAAAFFwL7KdWEoDhA=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLMetaClass", + "_id": "AAAAAAFFwMFq1GHYSKM=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "UMLAbstraction" + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwMGlemH0Tq8=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Derive", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwMLTmmKDF1M=", + "_parent": { + "$ref": "AAAAAAFFwMGlemH0Tq8=" + }, + "source": { + "$ref": "AAAAAAFFwMGlemH0Tq8=" + }, + "target": { + "$ref": "AAAAAAFFwMFq1GHYSKM=" + } + } + ], + "attributes": [ + { + "_type": "UMLAttribute", + "_id": "AAAAAAFFwMJO92J1Y/s=", + "_parent": { + "$ref": "AAAAAAFFwMGlemH0Tq8=" + }, + "name": "computation", + "type": "String" + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwMGlemH1M8k=", + "_parent": { + "$ref": "AAAAAAFFwMGlemH0Tq8=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwMGo6mIcITc=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Refine", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwMLXQmKUyu0=", + "_parent": { + "$ref": "AAAAAAFFwMGo6mIcITc=" + }, + "source": { + "$ref": "AAAAAAFFwMGo6mIcITc=" + }, + "target": { + "$ref": "AAAAAAFFwMFq1GHYSKM=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwMGo6mIdBMU=", + "_parent": { + "$ref": "AAAAAAFFwMGo6mIcITc=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwMGrimJEvvk=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Trace", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwMLbmmKloGE=", + "_parent": { + "$ref": "AAAAAAFFwMGrimJEvvk=" + }, + "source": { + "$ref": "AAAAAAFFwMGrimJEvvk=" + }, + "target": { + "$ref": "AAAAAAFFwMFq1GHYSKM=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwMGrimJF+z8=", + "_parent": { + "$ref": "AAAAAAFFwMGrimJEvvk=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLMetaClass", + "_id": "AAAAAAFFwMYNEWK7ItA=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "UMLPackage" + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwMdnrWLXWLA=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Framework", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwMevo2MpIU4=", + "_parent": { + "$ref": "AAAAAAFFwMdnrWLXWLA=" + }, + "source": { + "$ref": "AAAAAAFFwMdnrWLXWLA=" + }, + "target": { + "$ref": "AAAAAAFFwMYNEWK7ItA=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwMdnrWLYFcM=", + "_parent": { + "$ref": "AAAAAAFFwMdnrWLXWLA=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwMeIHGMAPDc=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "ModelLibrary", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwMe0G2M69PQ=", + "_parent": { + "$ref": "AAAAAAFFwMeIHGMAPDc=" + }, + "source": { + "$ref": "AAAAAAFFwMeIHGMAPDc=" + }, + "target": { + "$ref": "AAAAAAFFwMYNEWK7ItA=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwMeIHGMBKKk=", + "_parent": { + "$ref": "AAAAAAFFwMeIHGMAPDc=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLProfileDiagram", + "_id": "AAAAAAFFwQCuI7bLjDk=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "StandardProfileL3", + "ownedViews": [ + { + "_type": "UMLMetaClassView", + "_id": "AAAAAAFFwQHC9rbwK6A=", + "_parent": { + "$ref": "AAAAAAFFwQCuI7bLjDk=" + }, + "model": { + "$ref": "AAAAAAFFwQHC9rbvUkk=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwQHC9rbx7Lo=", + "_parent": { + "$ref": "AAAAAAFFwQHC9rbwK6A=" + }, + "model": { + "$ref": "AAAAAAFFwQHC9rbvUkk=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwQHC9rbyTUQ=", + "_parent": { + "$ref": "AAAAAAFFwQHC9rbx7Lo=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 45, + "top": 121, + "width": 107, + "height": 12, + "text": "«metaClass»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwQHC9rbzlgQ=", + "_parent": { + "$ref": "AAAAAAFFwQHC9rbx7Lo=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;1", + "containerExtending": true, + "left": 45, + "top": 135, + "width": 107, + "height": 12, + "text": "UMLModel" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwQHC9rb0L9g=", + "_parent": { + "$ref": "AAAAAAFFwQHC9rbx7Lo=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": -48, + "top": -168, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwQHC9rb1XIk=", + "_parent": { + "$ref": "AAAAAAFFwQHC9rbx7Lo=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": -48, + "top": -168, + "height": 12, + "horizontalAlignment": 1 + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 40, + "top": 116, + "width": 117, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwQHC9rbyTUQ=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwQHC9rbzlgQ=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwQHC9rb0L9g=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwQHC9rb1XIk=" + } + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 40, + "top": 116, + "width": 117, + "height": 97, + "nameCompartment": { + "$ref": "AAAAAAFFwQHC9rbx7Lo=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwQHjjbcLQPM=", + "_parent": { + "$ref": "AAAAAAFFwQCuI7bLjDk=" + }, + "model": { + "$ref": "AAAAAAFFwQHjjbcJ4Ks=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqN0zJrS0=", + "_parent": { + "$ref": "AAAAAAFFwQHjjbcLQPM=" + }, + "model": { + "$ref": "AAAAAAFFwQHjjbcJ4Ks=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwQHjjbcMlRY=", + "_parent": { + "$ref": "AAAAAAFFwQHjjbcLQPM=" + }, + "model": { + "$ref": "AAAAAAFFwQHjjbcJ4Ks=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwQHjjbcNrIk=", + "_parent": { + "$ref": "AAAAAAFFwQHjjbcMlRY=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 229, + "top": 41, + "width": 115, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwQHjjbcOnWs=", + "_parent": { + "$ref": "AAAAAAFFwQHjjbcMlRY=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 229, + "top": 55, + "width": 115, + "height": 12, + "text": "BuildComponent" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwQHjjbcPLIM=", + "_parent": { + "$ref": "AAAAAAFFwQHjjbcMlRY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 108, + "top": -48, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwQHjjbcQOtc=", + "_parent": { + "$ref": "AAAAAAFFwQHjjbcMlRY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 108, + "top": -48, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 224, + "top": 36, + "width": 125, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwQHjjbcNrIk=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwQHjjbcOnWs=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwQHjjbcPLIM=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwQHjjbcQOtc=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwQHjjrcRsYI=", + "_parent": { + "$ref": "AAAAAAFFwQHjjbcLQPM=" + }, + "model": { + "$ref": "AAAAAAFFwQHjjbcJ4Ks=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 260, + "top": 56, + "width": 105, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwQHjjrcSCoc=", + "_parent": { + "$ref": "AAAAAAFFwQHjjbcLQPM=" + }, + "model": { + "$ref": "AAAAAAFFwQHjjbcJ4Ks=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 260, + "top": 66, + "width": 105, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwQHjjrcTWEY=", + "_parent": { + "$ref": "AAAAAAFFwQHjjbcLQPM=" + }, + "model": { + "$ref": "AAAAAAFFwQHjjbcJ4Ks=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 72, + "top": -32, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 224, + "top": 36, + "width": 125, + "height": 37, + "nameCompartment": { + "$ref": "AAAAAAFFwQHjjbcMlRY=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwQHjjrcRsYI=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwQHjjrcSCoc=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqN0zJrS0=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwQHjjrcTWEY=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwQIPLLc0Q7M=", + "_parent": { + "$ref": "AAAAAAFFwQCuI7bLjDk=" + }, + "model": { + "$ref": "AAAAAAFFwQIPLLcykEY=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqOEzfvr8=", + "_parent": { + "$ref": "AAAAAAFFwQIPLLc0Q7M=" + }, + "model": { + "$ref": "AAAAAAFFwQIPLLcykEY=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwQIPLLc1jrg=", + "_parent": { + "$ref": "AAAAAAFFwQIPLLc0Q7M=" + }, + "model": { + "$ref": "AAAAAAFFwQIPLLcykEY=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwQIPLLc2rps=", + "_parent": { + "$ref": "AAAAAAFFwQIPLLc1jrg=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 229, + "top": 121, + "width": 83, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwQIPLLc3wdo=", + "_parent": { + "$ref": "AAAAAAFFwQIPLLc1jrg=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 229, + "top": 135, + "width": 83, + "height": 12, + "text": "Metamodel" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwQIPLLc4SHA=", + "_parent": { + "$ref": "AAAAAAFFwQIPLLc1jrg=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 108, + "top": -84, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwQIPLLc5Qvc=", + "_parent": { + "$ref": "AAAAAAFFwQIPLLc1jrg=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 108, + "top": -84, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 224, + "top": 116, + "width": 93, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwQIPLLc2rps=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwQIPLLc3wdo=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwQIPLLc4SHA=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwQIPLLc5Qvc=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwQIPLLc63qc=", + "_parent": { + "$ref": "AAAAAAFFwQIPLLc0Q7M=" + }, + "model": { + "$ref": "AAAAAAFFwQIPLLcykEY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 260, + "top": 124, + "width": 81, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwQIPLbc7y2w=", + "_parent": { + "$ref": "AAAAAAFFwQIPLLc0Q7M=" + }, + "model": { + "$ref": "AAAAAAFFwQIPLLcykEY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 260, + "top": 134, + "width": 81, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwQIPLbc8jC8=", + "_parent": { + "$ref": "AAAAAAFFwQIPLLc0Q7M=" + }, + "model": { + "$ref": "AAAAAAFFwQIPLLcykEY=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 72, + "top": -56, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 224, + "top": 116, + "width": 93, + "height": 37, + "nameCompartment": { + "$ref": "AAAAAAFFwQIPLLc1jrg=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwQIPLLc63qc=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwQIPLbc7y2w=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqOEzfvr8=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwQIPLbc8jC8=" + } + }, + { + "_type": "UMLStereotypeView", + "_id": "AAAAAAFFwQIrDLddK/I=", + "_parent": { + "$ref": "AAAAAAFFwQCuI7bLjDk=" + }, + "model": { + "$ref": "AAAAAAFFwQIrDLdbTko=" + }, + "subViews": [ + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF5P5kqOEz1SWk=", + "_parent": { + "$ref": "AAAAAAFFwQIrDLddK/I=" + }, + "model": { + "$ref": "AAAAAAFFwQIrDLdbTko=" + }, + "visible": false, + "font": "Arial;12;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwQIrDLdevJE=", + "_parent": { + "$ref": "AAAAAAFFwQIrDLddK/I=" + }, + "model": { + "$ref": "AAAAAAFFwQIrDLdbTko=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwQIrDLdfcec=", + "_parent": { + "$ref": "AAAAAAFFwQIrDLdevJE=" + }, + "font": "Arial;12;0", + "containerExtending": true, + "left": 229, + "top": 181, + "width": 83, + "height": 12, + "text": "«stereotype»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwQIrDLdgsTM=", + "_parent": { + "$ref": "AAAAAAFFwQIrDLdevJE=" + }, + "font": "Arial;12;1", + "containerExtending": true, + "left": 229, + "top": 195, + "width": 83, + "height": 12, + "text": "SystemModel" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwQIrDLdhAR0=", + "_parent": { + "$ref": "AAAAAAFFwQIrDLdevJE=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 120, + "top": -168, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwQIrDLdiiuQ=", + "_parent": { + "$ref": "AAAAAAFFwQIrDLdevJE=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 120, + "top": -168, + "height": 12, + "horizontalAlignment": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 224, + "top": 176, + "width": 93, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwQIrDLdfcec=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwQIrDLdgsTM=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwQIrDLdhAR0=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwQIrDLdiiuQ=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAFFwQIrDLdjYt8=", + "_parent": { + "$ref": "AAAAAAFFwQIrDLddK/I=" + }, + "model": { + "$ref": "AAAAAAFFwQIrDLdbTko=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 264, + "top": 156, + "width": 88, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAFFwQIrDLdkEoo=", + "_parent": { + "$ref": "AAAAAAFFwQIrDLddK/I=" + }, + "model": { + "$ref": "AAAAAAFFwQIrDLdbTko=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 264, + "top": 166, + "width": 88, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAFFwQIrDLdlkbo=", + "_parent": { + "$ref": "AAAAAAFFwQIrDLddK/I=" + }, + "model": { + "$ref": "AAAAAAFFwQIrDLdbTko=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 80, + "top": -112, + "width": 10, + "height": 10 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "left": 224, + "top": 176, + "width": 93, + "height": 37, + "nameCompartment": { + "$ref": "AAAAAAFFwQIrDLdevJE=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAFFwQIrDLdjYt8=" + }, + "operationCompartment": { + "$ref": "AAAAAAFFwQIrDLdkEoo=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF5P5kqOEz1SWk=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAFFwQIrDLdlkbo=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwQLOH7eRZzI=", + "_parent": { + "$ref": "AAAAAAFFwQCuI7bLjDk=" + }, + "model": { + "$ref": "AAAAAAFFwQLOH7eQuvE=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwQLOH7eSzo8=", + "_parent": { + "$ref": "AAAAAAFFwQLOH7eRZzI=" + }, + "model": { + "$ref": "AAAAAAFFwQLOH7eQuvE=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 189, + "top": 145, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwQLOH7eRZzI=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwQLOILeTl4U=", + "_parent": { + "$ref": "AAAAAAFFwQLOH7eRZzI=" + }, + "model": { + "$ref": "AAAAAAFFwQLOH7eQuvE=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 189, + "top": 160, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwQLOH7eRZzI=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwQLOILeU1qE=", + "_parent": { + "$ref": "AAAAAAFFwQLOH7eRZzI=" + }, + "model": { + "$ref": "AAAAAAFFwQLOH7eQuvE=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 190, + "top": 115, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwQLOH7eRZzI=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwQHC9rbwK6A=" + }, + "tail": { + "$ref": "AAAAAAFFwQIPLLc0Q7M=" + }, + "points": "224:136;156:136", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwQLOH7eSzo8=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwQLOILeTl4U=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwQLOILeU1qE=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwQLSp7eim6s=", + "_parent": { + "$ref": "AAAAAAFFwQCuI7bLjDk=" + }, + "model": { + "$ref": "AAAAAAFFwQLSp7eh5o0=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwQLSp7ejdqM=", + "_parent": { + "$ref": "AAAAAAFFwQLSp7eim6s=" + }, + "model": { + "$ref": "AAAAAAFFwQLSp7eh5o0=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 189, + "top": 205, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwQLSp7eim6s=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwQLSp7ekT+I=", + "_parent": { + "$ref": "AAAAAAFFwQLSp7eim6s=" + }, + "model": { + "$ref": "AAAAAAFFwQLSp7eh5o0=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 189, + "top": 220, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwQLSp7eim6s=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwQLSp7el67w=", + "_parent": { + "$ref": "AAAAAAFFwQLSp7eim6s=" + }, + "model": { + "$ref": "AAAAAAFFwQLSp7eh5o0=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 190, + "top": 175, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwQLSp7eim6s=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwQHC9rbwK6A=" + }, + "tail": { + "$ref": "AAAAAAFFwQIrDLddK/I=" + }, + "points": "224:196;156:196", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwQLSp7ejdqM=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwQLSp7ekT+I=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwQLSp7el67w=" + } + }, + { + "_type": "UMLMetaClassView", + "_id": "AAAAAAFFwQdYRLfPnZs=", + "_parent": { + "$ref": "AAAAAAFFwQCuI7bLjDk=" + }, + "model": { + "$ref": "AAAAAAFFwLRECl7r1R4=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAFFwQdYRLfQc8o=", + "_parent": { + "$ref": "AAAAAAFFwQdYRLfPnZs=" + }, + "model": { + "$ref": "AAAAAAFFwLRECl7r1R4=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAFFwQdYRLfRm/U=", + "_parent": { + "$ref": "AAAAAAFFwQdYRLfQc8o=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 45, + "top": 41, + "width": 107, + "height": 12, + "text": "«metaClass»" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwQdYRLfSwyU=", + "_parent": { + "$ref": "AAAAAAFFwQdYRLfQc8o=" + }, + "fillColor": "#e2e2e2", + "font": "Arial;12;1", + "containerExtending": true, + "left": 45, + "top": 55, + "width": 107, + "height": 12, + "text": "UMLComponent" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwQdYRLfTyV4=", + "_parent": { + "$ref": "AAAAAAFFwQdYRLfQc8o=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": -702, + "top": -954, + "width": 150.64784240722656, + "height": 12, + "text": "(from UMLStandardProfile)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAFFwQdYRLfUafY=", + "_parent": { + "$ref": "AAAAAAFFwQdYRLfQc8o=" + }, + "visible": false, + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": -702, + "top": -954, + "height": 12, + "horizontalAlignment": 1 + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 40, + "top": 36, + "width": 117, + "height": 36, + "stereotypeLabel": { + "$ref": "AAAAAAFFwQdYRLfRm/U=" + }, + "nameLabel": { + "$ref": "AAAAAAFFwQdYRLfSwyU=" + }, + "namespaceLabel": { + "$ref": "AAAAAAFFwQdYRLfTyV4=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwQdYRLfUafY=" + } + } + ], + "fillColor": "#e2e2e2", + "font": "Arial;12;0", + "containerExtending": true, + "left": 40, + "top": 36, + "width": 117, + "height": 41, + "nameCompartment": { + "$ref": "AAAAAAFFwQdYRLfQc8o=" + } + }, + { + "_type": "UMLExtensionView", + "_id": "AAAAAAFFwQgwnLf7u0w=", + "_parent": { + "$ref": "AAAAAAFFwQCuI7bLjDk=" + }, + "model": { + "$ref": "AAAAAAFFwQgwnLf6Q+0=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwQgwnLf82nE=", + "_parent": { + "$ref": "AAAAAAFFwQgwnLf7u0w=" + }, + "model": { + "$ref": "AAAAAAFFwQgwnLf6Q+0=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 189, + "top": 64, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwQgwnLf7u0w=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwQgwnbf9bFo=", + "_parent": { + "$ref": "AAAAAAFFwQgwnLf7u0w=" + }, + "model": { + "$ref": "AAAAAAFFwQgwnLf6Q+0=" + }, + "visible": null, + "font": "Arial;12;0", + "containerExtending": true, + "left": 189, + "top": 79, + "height": 12, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAFFwQgwnLf7u0w=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAFFwQgwnbf+ckE=", + "_parent": { + "$ref": "AAAAAAFFwQgwnLf7u0w=" + }, + "model": { + "$ref": "AAAAAAFFwQgwnLf6Q+0=" + }, + "visible": false, + "font": "Arial;12;0", + "containerExtending": true, + "left": 190, + "top": 34, + "height": 12, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAFFwQgwnLf7u0w=" + }, + "edgePosition": 1 + } + ], + "font": "Arial;12;0", + "containerExtending": true, + "head": { + "$ref": "AAAAAAFFwQdYRLfPnZs=" + }, + "tail": { + "$ref": "AAAAAAFFwQHjjbcLQPM=" + }, + "lineStyle": 1, + "points": "223:55;157:55", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAFFwQgwnLf82nE=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAFFwQgwnbf9bFo=" + }, + "propertyLabel": { + "$ref": "AAAAAAFFwQgwnbf+ckE=" + } + } + ] + }, + { + "_type": "UMLMetaClass", + "_id": "AAAAAAFFwQHC9rbvUkk=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "UMLModel" + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwQHjjbcJ4Ks=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "BuildComponent", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwQgwnLf6Q+0=", + "_parent": { + "$ref": "AAAAAAFFwQHjjbcJ4Ks=" + }, + "source": { + "$ref": "AAAAAAFFwQHjjbcJ4Ks=" + }, + "target": { + "$ref": "AAAAAAFFwLRECl7r1R4=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwQHjjbcKYjk=", + "_parent": { + "$ref": "AAAAAAFFwQHjjbcJ4Ks=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwQIPLLcykEY=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "Metamodel", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwQLOH7eQuvE=", + "_parent": { + "$ref": "AAAAAAFFwQIPLLcykEY=" + }, + "source": { + "$ref": "AAAAAAFFwQIPLLcykEY=" + }, + "target": { + "$ref": "AAAAAAFFwQHC9rbvUkk=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwQIPLLcz/1A=", + "_parent": { + "$ref": "AAAAAAFFwQIPLLcykEY=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwQIrDLdbTko=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "SystemModel", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwQLSp7eh5o0=", + "_parent": { + "$ref": "AAAAAAFFwQIrDLdbTko=" + }, + "source": { + "$ref": "AAAAAAFFwQIrDLdbTko=" + }, + "target": { + "$ref": "AAAAAAFFwQHC9rbvUkk=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwQIrDLdcjKw=", + "_parent": { + "$ref": "AAAAAAFFwQIrDLdbTko=" + }, + "width": 40, + "height": 40 + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFwx8Q/35u/80=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "control", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFwyAHeH6Znas=", + "_parent": { + "$ref": "AAAAAAFFwx8Q/35u/80=" + }, + "source": { + "$ref": "AAAAAAFFwx8Q/35u/80=" + }, + "target": { + "$ref": "AAAAAAFFJsZbpDNobIs=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFwx8Q/35vMf0=", + "_parent": { + "$ref": "AAAAAAFFwx8Q/35u/80=" + }, + "width": 40, + "height": 40, + "content": "var w = rect.getWidth(),\n h = w / 2,\n m = w / 8;\ncanvas.fillEllipse(rect.x1 + m, rect.y1 + m, rect.x2 - m, rect.y2 - m);\ncanvas.ellipse(rect.x1 + m, rect.y1 + m, rect.x2 - m, rect.y2 - m);\ncanvas.line(rect.x1 + h, rect.y1 + m, rect.x1 + h + m, rect.y1);\ncanvas.line(rect.x1 + h, rect.y1 + m, rect.x1 + h + m, rect.y1 + 2 * m);\n" + } + }, + { + "_type": "UMLStereotype", + "_id": "AAAAAAFFw0h1/QXL978=", + "_parent": { + "$ref": "AAAAAAFElnEzslS1AuE=" + }, + "name": "boundary", + "ownedElements": [ + { + "_type": "UMLExtension", + "_id": "AAAAAAFFw0o5ppIUB2s=", + "_parent": { + "$ref": "AAAAAAFFw0h1/QXL978=" + }, + "source": { + "$ref": "AAAAAAFFw0h1/QXL978=" + }, + "target": { + "$ref": "AAAAAAFFJsZbpDNobIs=" + } + } + ], + "icon": { + "_type": "UMLImage", + "_id": "AAAAAAFFw0h1/QXM/ss=", + "_parent": { + "$ref": "AAAAAAFFw0h1/QXL978=" + }, + "width": "50", + "height": 40, + "content": "var w = rect.getWidth(),\n h = rect.getHeight(),\n m = w / 5;\ncanvas.fillEllipse(rect.x1 + m, rect.y1, rect.x2, rect.y2);\ncanvas.ellipse(rect.x1 + m, rect.y1, rect.x2, rect.y2);\ncanvas.line(rect.x1, rect.y1, rect.x1, rect.y2);\ncanvas.line(rect.x1, rect.y1 + h/2, rect.x1 + m, rect.y1 + h/2);\n" + } + } + ] + } + ] +} \ No newline at end of file diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..c8f43e2 --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1,276 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in C:\Users\Administrator\AppData\Local\Android\sdk/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} +-keepclassmembers class * { + public (org.json.JSONObject); +} +-keep public class cn.liuyanbing.surveyor.R$*{ +public static final int *; +} +-keepclassmembers enum * { + public static **[] values(); + public static ** valueOf(java.lang.String); +} +#混淆前后的映射 +-printmapping mapping.txt + +-keep class androidx.appcompat.widget.SearchView { *; } +-keep class cn.aigestudio.datepicker.**{*;} + +-dontwarn javax.** + +-keep class com.tencent.mm.sdk.** { + *; +} + +-dontwarn com.tencent.** +-keep class com.tencent.** {*;} + +-ignorewarnings + +# Apache POI +-dontwarn org.apache.** +-dontwarn org.openxmlformats.schemas.** +-dontwarn org.etsi.** +-dontwarn org.w3.** +-dontwarn com.microsoft.schemas.** +-dontwarn com.fasterxml.** +-dontwarn javax.naming.** +-dontwarn java.lang.management.** +-dontwarn org.slf4j.impl.** + +-dontnote org.apache.** +-dontnote org.openxmlformats.schemas.** +-dontnote org.etsi.** +-dontnote org.w3.** +-dontnote com.microsoft.schemas.** +-dontnote com.fasterxml.** +-dontnote javax.naming.** +-dontnote java.lang.management.** +-dontnote org.slf4j.impl.** + +-keeppackagenames org.apache.poi.ss.formula.function + +-keep class org.apache.** {*;} +-keep class org.openxmlformats.** {*;} +-keep class org.etsi.** {*;} +-keep class org.w3.** {*;} +-keep class com.microsoft.** {*;} +-keep class com.fasterxml.** {*;} +-keep class schemaorg_apache_xmlbeans.** {*;} + +# ------------------------ leancloud sdk ------------------------ +-keepattributes Signature +-dontwarn com.jcraft.jzlib.** +-keep class com.jcraft.jzlib.** { *;} + +-dontwarn sun.misc.** +-keep class sun.misc.** { *;} + +-dontwarn alibaba.fastjson.** +-dontnote alibaba.fastjson.** +-keep class alibaba.fastjson.** { *;} + +-dontwarn sun.security.** +-keep class sun.security.** { *; } + +-dontwarn com.google.** +-keep class com.google.** { *;} + +-dontwarn com.avos.** +-dontnote com.avos.** +-keep class com.avos.** { *;} + +-dontwarn cn.leancloud.** +-dontnote cn.leancloud.** +-keep class cn.leancloud.** { *;} + +-keep public class android.net.http.SslError +-keep public class android.webkit.WebViewClient + +-dontwarn android.webkit.WebView +-dontwarn android.net.http.SslError +-dontwarn android.webkit.WebViewClient +-dontnote android.net.http.** + +-dontwarn android.support.** + +-dontwarn org.jivesoftware.smack.** +-keep class org.jivesoftware.smack.** { *;} + +-dontwarn com.loopj.** +-keep class com.loopj.** { *;} + +-dontwarn com.squareup.okhttp.** +-keep class com.squareup.okhttp.** { *;} +-keep interface com.squareup.okhttp.** { *; } + +# keep okhttp3、okio +-dontwarn okhttp3.** +-keep class okhttp3.** { *;} +-keep interface okhttp3.** { *; } +-dontwarn okio.** + +-keep class com.google.protobuf.** { *; } +-keep public class * extends com.google.protobuf.** { *; } +-dontwarn com.google.protobuf.** + +-dontwarn org.xbill.** +-keep class org.xbill.** { *;} + +-keepattributes *Annotation* + + +# ------------------------ ChatKit ------------------------ +-dontwarn cn.leancloud.chatkit.** +-keep class cn.leancloud.chatkit.** { *;} +-dontnote cn.leancloud.chatkit.** + +# ------------------------ picasso ------------------------ +-dontwarn com.squareup.picasso** +-keep class com.squareup.picasso.**{*;} + +# ------------------------ eventbus ------------------------ +-keepattributes *Annotation* +-keepclassmembers class * { + @org.greenrobot.eventbus.Subscribe ; +} +-keep enum org.greenrobot.eventbus.ThreadMode { *; } + +# Only required if you use AsyncExecutor +-keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent { + (java.lang.Throwable); +} +#--------------------------工具集----------------------------- +-keep class blankj.utilcode.** { *; } +-keepclassmembers class blankj.utilcode.** { *; } +-dontwarn blankj.utilcode.** + +-keep class com.chad.library.adapter.** { +*; +} +-keep public class * extends com.chad.library.adapter.base.BaseQuickAdapter +-keep public class * extends com.chad.library.adapter.base.BaseViewHolder +-keepclassmembers class **$** extends com.chad.library.adapter.base.BaseViewHolder { + (...); +} + +# glide 的混淆代码 +-keep public class * implements com.bumptech.glide.module.GlideModule +-keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** { + **[] $VALUES; + public *; +} +# banner 的混淆代码 +-keep class com.youth.banner.** { + *; + } +# 华测sdk + -keep class com.chc.gnss.sdk.** { *; } + -dontwarn com.chc.gnss.sdk.** +# 中国移动sdk + -keep class com.cmcc.sy.hap.** { *; } + -dontwarn com.cmcc.sy.hap.** +# 梦想CAD sdk + -keep class org.cocos2dx.** { *; } + -dontwarn org.cocos2dx.** + -keep class com.chukong.cocosplay.client.** { *; } + -dontwarn com.chukong.cocosplay.client.** + -keep class com.MxDraw.** { *; } + -dontwarn com.MxDraw.** +#agentweb + -keep class com.just.agentweb.** { + *; + } + -dontwarn com.just.agentweb.** + +#androidx + -keep class com.google.android.material.** {*;} + -keep class androidx.** {*;} + -keep public class * extends androidx.** + -keep interface androidx.** {*;} + -dontwarn com.google.android.material.** + -dontnote com.google.android.material.** + -dontwarn androidx.** + +# 南方坐标转换 + -keep class com.qxwz.sdk.** { *; } + -dontwarn com.qxwz.sdk.** + + -keep class com.bingce.device.rtk.configuration.** { *; } + -keep class com.bingce.device.rtk.model.** { *; } + -keep class com.bingce.totalstation.TsConfig { *; } + + #OkSocket + -dontwarn xuhao.didi.socket.client.** + -dontwarn xuhao.didi.socket.common.** + -dontwarn xuhao.didi.socket.server.** + -dontwarn xuhao.didi.core.** + + -keep class xuhao.didi.socket.client.** { *; } + -keep class xuhao.didi.socket.common.** { *; } + -keep class xuhao.didi.socket.server.** { *; } + -keep class xuhao.didi.core.** { *; } + + -keep class xuhao.didi.socket.client.sdk.client.OkSocketOptions$* { + *; + } + -keep class xuhao.didi.socket.server.impl.OkServerOptions$* { + *; + } + + #gsyvideoplayer + -keep class com.shuyu.gsyvideoplayer.video.** { *; } + -dontwarn com.shuyu.gsyvideoplayer.video.** + -keep class com.shuyu.gsyvideoplayer.video.base.** { *; } + -dontwarn com.shuyu.gsyvideoplayer.video.base.** + -keep class com.shuyu.gsyvideoplayer.utils.** { *; } + -dontwarn com.shuyu.gsyvideoplayer.utils.** + -keep class tv.danmaku.ijk.** { *; } + -dontwarn tv.danmaku.ijk.** + + -keep public class * extends android.view.View{ + *** get*(); + void set*(***); + public (android.content.Context); + public (android.content.Context, android.util.AttributeSet); + public (android.content.Context, android.util.AttributeSet, int); + } + +# # keep rx +# -dontwarn sun.misc.** +# -keepclassmembers class rx.internal.util.unsafe.*ArrayQueue*Field* { +# long producerIndex; +# long consumerIndex; +# } +# -keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueProducerNodeRef { +# rx.internal.util.atomic.LinkedQueueNode producerNode; +# } +# -keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueConsumerNodeRef { +# rx.internal.util.atomic.LinkedQueueNode consumerNode; +# } +# +# -keep class cn.liuyanbing.surveyor.model.base.SerializableStringArray { *; } + +-dontwarn com.yalantis.ucrop** +-keep class com.yalantis.ucrop** { *; } +-keep interface com.yalantis.ucrop** { *; } + +-keep class com.bingce.event.WxLoginSuccessEvent{ *; } + +# 友盟 + -keep class com.umeng.** {*;} \ No newline at end of file diff --git a/app/src/androidTest/java/cn/liuyanbing/surveyor/activity/MainActivityTest.java b/app/src/androidTest/java/cn/liuyanbing/surveyor/activity/MainActivityTest.java new file mode 100644 index 0000000..eed3c00 --- /dev/null +++ b/app/src/androidTest/java/cn/liuyanbing/surveyor/activity/MainActivityTest.java @@ -0,0 +1,19 @@ +package cn.liuyanbing.surveyor.activity; + +import android.util.Log; + +import org.junit.Test; + +public class MainActivityTest { + + @Test + public void initSound() { + Log.d("hwhw", "initSound"); + } + + @Test + public void onCreate() { + Log.d("hwhw", "onCreate"); + + } +} \ No newline at end of file diff --git a/app/src/androidTest/kotlin/HelloKotlin.kt b/app/src/androidTest/kotlin/HelloKotlin.kt new file mode 100644 index 0000000..f967c63 --- /dev/null +++ b/app/src/androidTest/kotlin/HelloKotlin.kt @@ -0,0 +1,49 @@ +import android.util.Log +import com.bingce.controlnetwork.http.RetrofitClient +import com.bingce.controlnetwork.http.sevice.CommonService +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch +import kotlinx.coroutines.runBlocking +import org.junit.Test + +class HelloKotlin { + + @Test + fun test() { +// runBlocking { +// +// launch { +// Log.d("hwhw", "请求1") +// +// delay(1000) +// Log.d("hwhw", "请求1 delay") +// +// val apiCall = RetrofitClient.apiCall { +// RetrofitClient.createService().getPassageData() +// } +// +// apiCall?.let { +// Log.d("hwhw", "请求成功1,$it") +// } +// } +// +// launch { +// Log.d("hwhw", "请求2") +// +// delay(1000) +// Log.d("hwhw", "请求2 delay") +// +// val apiCall1 = RetrofitClient.apiCall { +// RetrofitClient.createService().getPassageData() +// } +// apiCall1?.let { +// Log.d("hwhw", "请求成功2,$it") +// } +// } +// +// +// } + } + + +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..14c79cf --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,217 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/README.md b/app/src/main/README.md new file mode 100644 index 0000000..ef62895 --- /dev/null +++ b/app/src/main/README.md @@ -0,0 +1 @@ +#controlnetwork diff --git a/app/src/main/assets/Roboto-Light.ttf b/app/src/main/assets/Roboto-Light.ttf new file mode 100644 index 0000000..d43e943 Binary files /dev/null and b/app/src/main/assets/Roboto-Light.ttf differ diff --git a/app/src/main/assets/Roboto-Medium.ttf b/app/src/main/assets/Roboto-Medium.ttf new file mode 100644 index 0000000..8798341 Binary files /dev/null and b/app/src/main/assets/Roboto-Medium.ttf differ diff --git a/app/src/main/assets/agreement_policy_summary.xml b/app/src/main/assets/agreement_policy_summary.xml new file mode 100644 index 0000000..28e3305 --- /dev/null +++ b/app/src/main/assets/agreement_policy_summary.xml @@ -0,0 +1,8 @@ + + + 欢迎使用导线助手App!我们将通过《用户协议》和《隐私政策》帮助您了解我们收集、使用、存储和共享个人信息的情况,以及您所享有的相关权利。 + • 为了向您提供语音播报、文件生成存储、头像上传、用户注册等功能服务,我们需要使用您的一些存储权限、音视频录制权限、相机权限、获取设备信息等权限及信息。 + • 我们会采用业界领先的安全技术保护好您的个人信息。 + 您可以通过阅读完整版用户隐私政策,了解个人信息类型与用途的对应关系等更加详尽的个人信息处理规则。 + 如您同意,请点击“同意”开始接受我们的服务。 + \ No newline at end of file diff --git a/app/src/main/assets/agreement_policy_summary_en.xml b/app/src/main/assets/agreement_policy_summary_en.xml new file mode 100644 index 0000000..4e76303 --- /dev/null +++ b/app/src/main/assets/agreement_policy_summary_en.xml @@ -0,0 +1,4 @@ + + + Welcome to the Surveyor App! Through the "User Agreement" and "Privacy Policy", we will help you understand our collection, use, storage and sharing of personal information, as well as your related rights. • In order to provide you with voice broadcasting, file generation and storage, avatar upload, user registration and other functional services, we need to use some of your storage permissions, audio and video recording permissions, camera permissions, access to device information and other permissions and information. • We will protect your personal information with industry-leading security technology. You can read the full version of the user's privacy policy to understand the more detailed personal information processing rules such as the correspondence between personal information types and uses. If you agree, please click "Agree" to start accepting our services. + \ No newline at end of file diff --git a/app/src/main/assets/default_tolerance b/app/src/main/assets/default_tolerance new file mode 100644 index 0000000..e13dc04 --- /dev/null +++ b/app/src/main/assets/default_tolerance @@ -0,0 +1,868 @@ +[{ + "name": "城市轨道交通", + "level": [{ + "name": "城市轨道交通精密导线", + "precision": [{ + "name": "I级", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "6", + "horCycleDirect2CDifference": "9", + "horCyclesDirectValueDifference": "6", + "hor2C": "9", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "3", + "singleCycleDistanceDifference": "3", + "allCycleDistanceDifference": "4", + "cycleCount": "4" + }, { + "name": "II级", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "8", + "horCycleDirect2CDifference": "13", + "horCyclesDirectValueDifference": "9", + "hor2C": "13", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "4", + "singleCycleDistanceDifference": "4", + "allCycleDistanceDifference": "6", + "cycleCount": "6" + }] + }] +}, { + "name": "铁路工程测量", + "level": [{ + "name": "铁路工程测量二等导线", + "precision": [{ + "name": "0.5秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "4", + "horCycleDirect2CDifference": "6", + "horCyclesDirectValueDifference": "4", + "hor2C": "6", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "2", + "singleCycleDistanceDifference": "2", + "allCycleDistanceDifference": "3", + "cycleCount": "2" + }, { + "name": "1秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "6", + "horCycleDirect2CDifference": "9", + "horCyclesDirectValueDifference": "6", + "hor2C": "6", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "2" + }] + }, { + "name": "铁路工程测量三等导线", + "precision": [{ + "name": "0.5秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "4", + "horCycleDirect2CDifference": "6", + "horCyclesDirectValueDifference": "4", + "hor2C": "6", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "2", + "singleCycleDistanceDifference": "2", + "allCycleDistanceDifference": "3", + "cycleCount": "2" + }, { + "name": "1秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "6", + "horCycleDirect2CDifference": "9", + "horCyclesDirectValueDifference": "6", + "hor2C": "9", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "2", + "singleCycleDistanceDifference": "2", + "allCycleDistanceDifference": "3", + "cycleCount": "2" + }, { + "name": "2秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "8", + "horCycleDirect2CDifference": "13", + "horCyclesDirectValueDifference": "9", + "hor2C": "13", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "2" + }] + }, { + "name": "铁路工程测量四等导线", + "precision": [{ + "name": "0.5秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "4", + "horCycleDirect2CDifference": "*", + "horCyclesDirectValueDifference": "4", + "hor2C": "6", + "horCyclesDirect2CDifference": "6", + "distanceReadDifference": "2", + "singleCycleDistanceDifference": "2", + "allCycleDistanceDifference": "3", + "cycleCount": "2" + }, { + "name": "1秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "6", + "horCycleDirect2CDifference": "9", + "horCyclesDirectValueDifference": "6", + "hor2C": "9", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "3" + }, { + "name": "2秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "8", + "horCycleDirect2CDifference": "13", + "horCyclesDirectValueDifference": "9", + "hor2C": "13", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "10", + "singleCycleDistanceDifference": "10", + "allCycleDistanceDifference": "15", + "cycleCount": "3" + }] + }, { + "name": "铁路工程测量一级导线", + "precision": [{ + "name": "0.5秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "12", + "horCycleDirect2CDifference": "18", + "horCyclesDirectValueDifference": "12", + "hor2C": "18", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "2", + "singleCycleDistanceDifference": "2", + "allCycleDistanceDifference": "?", + "cycleCount": "3" + }, { + "name": "1秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "12", + "horCycleDirect2CDifference": "18", + "horCyclesDirectValueDifference": "12", + "hor2C": "18", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "?", + "cycleCount": "3" + }, { + "name": "2秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "12", + "horCycleDirect2CDifference": "18", + "horCyclesDirectValueDifference": "12", + "hor2C": "18", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "10", + "singleCycleDistanceDifference": "10", + "allCycleDistanceDifference": "15", + "cycleCount": "3" + }] + }, { + "name": "铁路工程测量二级导线", + "precision": [{ + "name": "0.5秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "12", + "horCycleDirect2CDifference": "18", + "horCyclesDirectValueDifference": "12", + "hor2C": "18", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "2", + "singleCycleDistanceDifference": "2", + "allCycleDistanceDifference": "?", + "cycleCount": "3" + }, { + "name": "1秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "12", + "horCycleDirect2CDifference": "18", + "horCyclesDirectValueDifference": "12", + "hor2C": "18", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "?", + "cycleCount": "3" + }, { + "name": "2秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "12", + "horCycleDirect2CDifference": "18", + "horCyclesDirectValueDifference": "12", + "hor2C": "18", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "10", + "singleCycleDistanceDifference": "10", + "allCycleDistanceDifference": "15", + "cycleCount": "3" + }, { + "name": "6秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "18", + "horCycleDirect2CDifference": "*", + "horCyclesDirectValueDifference": "24", + "hor2C": "*", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "20", + "singleCycleDistanceDifference": "20", + "allCycleDistanceDifference": "30", + "cycleCount": "3" + }] + }] +}, { + "name": "水利水电工程测量", + "level": [{ + "name": "水利水电工程测量二等导线", + "precision": [{ + "name": "0.5秒", + "horReadDifference": "2", + "horHalfReturnZeroDifference": "4", + "horCycleDirect2CDifference": "6", + "horCyclesDirectValueDifference": "3", + "hor2C": "6", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "3" + }, { + "name": "1秒", + "horReadDifference": "4", + "horHalfReturnZeroDifference": "6", + "horCycleDirect2CDifference": "9", + "horCyclesDirectValueDifference": "6", + "hor2C": "9", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "3" + }, { + "name": "2秒", + "horReadDifference": "6", + "horHalfReturnZeroDifference": "8", + "horCycleDirect2CDifference": "13", + "horCyclesDirectValueDifference": "9", + "hor2C": "13", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "3" + }] + }, { + "name": "水利水电工程测量三等导线", + "precision": [{ + "name": "0.5秒", + "horReadDifference": "2", + "horHalfReturnZeroDifference": "4", + "horCycleDirect2CDifference": "6", + "horCyclesDirectValueDifference": "3", + "hor2C": "6", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "3" + }, { + "name": "1秒", + "horReadDifference": "4", + "horHalfReturnZeroDifference": "6", + "horCycleDirect2CDifference": "9", + "horCyclesDirectValueDifference": "6", + "hor2C": "9", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "3" + }, { + "name": "2秒", + "horReadDifference": "6", + "horHalfReturnZeroDifference": "8", + "horCycleDirect2CDifference": "13", + "horCyclesDirectValueDifference": "9", + "hor2C": "13", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "3" + }] + }, { + "name": "水利水电工程测量四等导线", + "precision": [{ + "name": "0.5秒", + "horReadDifference": "2", + "horHalfReturnZeroDifference": "4", + "horCycleDirect2CDifference": "6", + "horCyclesDirectValueDifference": "3", + "hor2C": "6", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "3" + }, { + "name": "1秒", + "horReadDifference": "4", + "horHalfReturnZeroDifference": "6", + "horCycleDirect2CDifference": "9", + "horCyclesDirectValueDifference": "6", + "hor2C": "9", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "3" + }, { + "name": "2秒", + "horReadDifference": "6", + "horHalfReturnZeroDifference": "8", + "horCycleDirect2CDifference": "13", + "horCyclesDirectValueDifference": "9", + "hor2C": "13", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "3" + }] + }, { + "name": "水利水电工程测量五等导线", + "precision": [{ + "name": "0.5秒", + "horReadDifference": "4", + "horHalfReturnZeroDifference": "6", + "horCycleDirect2CDifference": "9", + "horCyclesDirectValueDifference": "6", + "hor2C": "9", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "3" + }, { + "name": "1秒", + "horReadDifference": "4", + "horHalfReturnZeroDifference": "6", + "horCycleDirect2CDifference": "9", + "horCyclesDirectValueDifference": "6", + "hor2C": "9", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "2" + }, { + "name": "2秒", + "horReadDifference": "6", + "horHalfReturnZeroDifference": "8", + "horCycleDirect2CDifference": "13", + "horCyclesDirectValueDifference": "9", + "hor2C": "13", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "2" + }, { + "name": "6秒", + "horReadDifference": "12", + "horHalfReturnZeroDifference": "18", + "horCycleDirect2CDifference": "24", + "horCyclesDirectValueDifference": "24", + "hor2C": "24", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "2" + }] + }] +}, { + "name": "工程测量", + "level": [{ + "name": "工程测量三等导线", + "precision": [{ + "name": "0.5秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "6", + "horCycleDirect2CDifference": "9", + "horCyclesDirectValueDifference": "6", + "hor2C": "9", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "2" + }, { + "name": "1秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "6", + "horCycleDirect2CDifference": "9", + "horCyclesDirectValueDifference": "6", + "hor2C": "9", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "2" + }, { + "name": "2秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "8", + "horCycleDirect2CDifference": "13", + "horCyclesDirectValueDifference": "9", + "hor2C": "13", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "2" + }] + }, { + "name": "工程测量四等导线", + "precision": [{ + "name": "0.5秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "6", + "horCycleDirect2CDifference": "9", + "horCyclesDirectValueDifference": "6", + "hor2C": "9", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "2" + }, { + "name": "1秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "6", + "horCycleDirect2CDifference": "9", + "horCyclesDirectValueDifference": "6", + "hor2C": "9", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "2" + }, { + "name": "2秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "8", + "horCycleDirect2CDifference": "13", + "horCyclesDirectValueDifference": "9", + "hor2C": "13", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "2" + }] + }, { + "name": "工程测量一级导线", + "precision": [{ + "name": "0.5秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "12", + "horCycleDirect2CDifference": "18", + "horCyclesDirectValueDifference": "12", + "hor2C": "18", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "10", + "singleCycleDistanceDifference": "10", + "allCycleDistanceDifference": "15", + "cycleCount": "2" + }, { + "name": "1秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "12", + "horCycleDirect2CDifference": "18", + "horCyclesDirectValueDifference": "12", + "hor2C": "18", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "10", + "singleCycleDistanceDifference": "10", + "allCycleDistanceDifference": "15", + "cycleCount": "2" + }, { + "name": "2秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "12", + "horCycleDirect2CDifference": "18", + "horCyclesDirectValueDifference": "12", + "hor2C": "18", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "10", + "singleCycleDistanceDifference": "10", + "allCycleDistanceDifference": "15", + "cycleCount": "2" + }, { + "name": "6秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "18", + "horCycleDirect2CDifference": "*", + "horCyclesDirectValueDifference": "24", + "hor2C": "*", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "10", + "singleCycleDistanceDifference": "10", + "allCycleDistanceDifference": "15", + "cycleCount": "2" + }] + }, { + "name": "工程测量二级导线", + "precision": [{ + "name": "0.5秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "6", + "horCycleDirect2CDifference": "9", + "horCyclesDirectValueDifference": "6", + "hor2C": "9", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "10", + "singleCycleDistanceDifference": "10", + "allCycleDistanceDifference": "15", + "cycleCount": "2" + }, { + "name": "1秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "6", + "horCycleDirect2CDifference": "9", + "horCyclesDirectValueDifference": "6", + "hor2C": "9", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "10", + "singleCycleDistanceDifference": "10", + "allCycleDistanceDifference": "15", + "cycleCount": "2" + }, { + "name": "2秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "8", + "horCycleDirect2CDifference": "13", + "horCyclesDirectValueDifference": "9", + "hor2C": "13", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "10", + "singleCycleDistanceDifference": "10", + "allCycleDistanceDifference": "15", + "cycleCount": "2" + }, { + "name": "6秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "18", + "horCycleDirect2CDifference": "24", + "horCyclesDirectValueDifference": "24", + "hor2C": "24", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "10", + "singleCycleDistanceDifference": "10", + "allCycleDistanceDifference": "15", + "cycleCount": "2" + }] + }, { + "name": "工程测量三级导线", + "precision": [{ + "name": "0.5秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "6", + "horCycleDirect2CDifference": "9", + "horCyclesDirectValueDifference": "6", + "hor2C": "9", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "10", + "singleCycleDistanceDifference": "10", + "allCycleDistanceDifference": "15", + "cycleCount": "2" + }, { + "name": "1秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "6", + "horCycleDirect2CDifference": "9", + "horCyclesDirectValueDifference": "6", + "hor2C": "9", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "10", + "singleCycleDistanceDifference": "10", + "allCycleDistanceDifference": "15", + "cycleCount": "2" + }, { + "name": "2秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "8", + "horCycleDirect2CDifference": "13", + "horCyclesDirectValueDifference": "9", + "hor2C": "13", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "10", + "singleCycleDistanceDifference": "10", + "allCycleDistanceDifference": "15", + "cycleCount": "2" + }, { + "name": "6秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "18", + "horCycleDirect2CDifference": "24", + "horCyclesDirectValueDifference": "24", + "hor2C": "24", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "10", + "singleCycleDistanceDifference": "10", + "allCycleDistanceDifference": "15", + "cycleCount": "2" + }] + }] +}, { + "name": "城市测量", + "level": [{ + "name": "城市测量三等导线", + "precision": [{ + "name": "0.5秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "6", + "horCycleDirect2CDifference": "9", + "horCyclesDirectValueDifference": "6", + "hor2C": "9", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "2" + }, { + "name": "1秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "6", + "horCycleDirect2CDifference": "9", + "horCyclesDirectValueDifference": "6", + "hor2C": "9", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "2" + }, { + "name": "2秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "8", + "horCycleDirect2CDifference": "13", + "horCyclesDirectValueDifference": "9", + "hor2C": "13", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "2" + }] + }, { + "name": "城市测量四等导线", + "precision": [{ + "name": "0.5秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "6", + "horCycleDirect2CDifference": "9", + "horCyclesDirectValueDifference": "6", + "hor2C": "9", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "2" + }, { + "name": "1秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "6", + "horCycleDirect2CDifference": "9", + "horCyclesDirectValueDifference": "6", + "hor2C": "9", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "2" + }, { + "name": "2秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "8", + "horCycleDirect2CDifference": "13", + "horCyclesDirectValueDifference": "9", + "hor2C": "13", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "2" + }] + }, { + "name": "城市测量一级导线", + "precision": [{ + "name": "0.5秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "8", + "horCycleDirect2CDifference": "13", + "horCyclesDirectValueDifference": "9", + "hor2C": "13", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "2" + }, { + "name": "1秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "8", + "horCycleDirect2CDifference": "13", + "horCyclesDirectValueDifference": "9", + "hor2C": "13", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "2" + }, { + "name": "2秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "8", + "horCycleDirect2CDifference": "13", + "horCyclesDirectValueDifference": "9", + "hor2C": "13", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "2" + }, { + "name": "6秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "18", + "horCycleDirect2CDifference": "*", + "horCyclesDirectValueDifference": "24", + "hor2C": "*", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "2" + }] + }, { + "name": "城市测量二级导线", + "precision": [{ + "name": "0.5秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "8", + "horCycleDirect2CDifference": "13", + "horCyclesDirectValueDifference": "9", + "hor2C": "13", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "2" + }, { + "name": "1秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "8", + "horCycleDirect2CDifference": "13", + "horCyclesDirectValueDifference": "9", + "hor2C": "13", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "2" + }, { + "name": "2秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "8", + "horCycleDirect2CDifference": "13", + "horCyclesDirectValueDifference": "9", + "hor2C": "13", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "2" + }, { + "name": "6秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "18", + "horCycleDirect2CDifference": "*", + "horCyclesDirectValueDifference": "24", + "hor2C": "*", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "2" + }] + }, { + "name": "城市测量三级导线", + "precision": [{ + "name": "0.5秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "8", + "horCycleDirect2CDifference": "13", + "horCyclesDirectValueDifference": "9", + "hor2C": "13", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "2" + }, { + "name": "1秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "8", + "horCycleDirect2CDifference": "13", + "horCyclesDirectValueDifference": "9", + "hor2C": "13", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "2" + }, { + "name": "2秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "8", + "horCycleDirect2CDifference": "13", + "horCyclesDirectValueDifference": "9", + "hor2C": "13", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "2" + }, { + "name": "6秒", + "horReadDifference": "3", + "horHalfReturnZeroDifference": "18", + "horCycleDirect2CDifference": "*", + "horCyclesDirectValueDifference": "24", + "hor2C": "*", + "horCyclesDirect2CDifference": "*", + "distanceReadDifference": "5", + "singleCycleDistanceDifference": "5", + "allCycleDistanceDifference": "7", + "cycleCount": "2" + }] + }] +}] \ No newline at end of file diff --git a/app/src/main/assets/features.hcc b/app/src/main/assets/features.hcc new file mode 100644 index 0000000..5ea2931 --- /dev/null +++ b/app/src/main/assets/features.hcc @@ -0,0 +1,574 @@ +[Group][Radio] +[Model][Valid] +Baudrate:1:4800,9600,19200:1,0,2 +Power:10:1,2,5,10,20:2,6,3,4,5 +Stepper:10:125,250:0,2 +[Model][RadioChannels] +High:456.05,456.55,457.05,458.05,459.05,460.05,461.05,462.05,462.55 +Middle:430.00,432.50,435.00,437.50,440.00,442.50,445.00,447.50,450.00 +Low:415.05,416.05,417.05,418.05,419.05,420.05,421.05,422.05,423.05 +[Model][Advanced For Satel] +Step-Protocol-Baudrate:125-8-9600 +Step-Protocol-Baudrate:125-16-9600 +Step-Protocol-Baudrate:125-2-4800 +Step-Protocol-Baudrate:125-4-4800 +Step-Protocol-Baudrate:250-8-19200 +Step-Protocol-Baudrate:250-16-19200 +Step-Protocol-Baudrate:250-2-9600 +Step-Protocol-Baudrate:250-4-9600 +[Model][Advanced For HuaXin] +Step-Protocol-Baudrate:250-1-9600 +Step-Protocol-Baudrate:250-1-19200 +Step-Protocol-Baudrate:250-2-9600 +Step-Protocol-Baudrate:250-4-9600 +[Model][Advanced For HuaXin-EX] +Step-Protocol-Baudrate:125-1-4800 +Step-Protocol-Baudrate:125-2-4800 +Step-Protocol-Baudrate:125-4-4800 +Step-Protocol-Baudrate:250-1-9600 +Step-Protocol-Baudrate:250-2-9600 +Step-Protocol-Baudrate:250-4-9600 +Step-Protocol-Baudrate:250-1-19200 +[Model][Advanced For HuaXin-EX2] +Step-Protocol-Baudrate:250-2-9600 +Step-Protocol-Baudrate:250-4-9600 +Step-Protocol-Baudrate:250-256-9600 +Step-Protocol-Baudrate:250-512-9600 +Step-Protocol-Baudrate:250-256-19200 +Step-Protocol-Baudrate:250-512-19200 +[Model][Advanced For HuaXin-SOUTH] +Step-Protocol-Baudrate:125-1-4800 +Step-Protocol-Baudrate:125-2-4800 +Step-Protocol-Baudrate:125-4-4800 +Step-Protocol-Baudrate:125-256-4800 +Step-Protocol-Baudrate:250-1-9600 +Step-Protocol-Baudrate:250-2-9600 +Step-Protocol-Baudrate:250-4-9600 +Step-Protocol-Baudrate:250-256-9600 +Step-Protocol-Baudrate:250-1-19200 +Step-Protocol-Baudrate:250-256-19200 +[Model][Advanced For D352] +Step-Protocol-Baudrate:125-1-9600 +Step-Protocol-Baudrate:125-2-9600 +Step-Protocol-Baudrate:125-4-9600 +Step-Protocol-Baudrate:125-1-19200 +Step-Protocol-Baudrate:125-2-19200 +Step-Protocol-Baudrate:125-4-19200 +Step-Protocol-Baudrate:200-1-9600 +Step-Protocol-Baudrate:200-2-9600 +Step-Protocol-Baudrate:200-4-9600 +Step-Protocol-Baudrate:200-1-19200 +Step-Protocol-Baudrate:200-2-19200 +Step-Protocol-Baudrate:200-4-19200 +Step-Protocol-Baudrate:250-1-9600 +Step-Protocol-Baudrate:250-2-9600 +Step-Protocol-Baudrate:250-4-9600 +Step-Protocol-Baudrate:250-1-19200 +Step-Protocol-Baudrate:250-2-19200 +Step-Protocol-Baudrate:250-4-19200 +[Model][Advanced For D352_CHCX] +Step-Protocol-Baudrate:125-1-9600 +Step-Protocol-Baudrate:125-2-9600 +Step-Protocol-Baudrate:125-4-9600 +Step-Protocol-Baudrate:125-2-19200 +Step-Protocol-Baudrate:125-4-19200 +Step-Protocol-Baudrate:125-4096-19200 +Step-Protocol-Baudrate:200-1-9600 +Step-Protocol-Baudrate:200-2-9600 +Step-Protocol-Baudrate:200-4-9600 +Step-Protocol-Baudrate:200-2-19200 +Step-Protocol-Baudrate:200-4-19200 +Step-Protocol-Baudrate:200-4096-19200 +Step-Protocol-Baudrate:250-1-9600 +Step-Protocol-Baudrate:250-2-9600 +Step-Protocol-Baudrate:250-4-9600 +Step-Protocol-Baudrate:250-2-19200 +Step-Protocol-Baudrate:250-4-19200 +Step-Protocol-Baudrate:250-4096-19200 +[Model][Advanced For HuaXin-SOUTH_CHCX] +Step-Protocol-Baudrate:125-1-4800 +Step-Protocol-Baudrate:125-2-4800 +Step-Protocol-Baudrate:125-4-4800 +Step-Protocol-Baudrate:125-256-4800 +Step-Protocol-Baudrate:250-1-9600 +Step-Protocol-Baudrate:250-2-9600 +Step-Protocol-Baudrate:250-4-9600 +Step-Protocol-Baudrate:250-256-9600 +Step-Protocol-Baudrate:250-256-19200 +Step-Protocol-Baudrate:250-4096-19200 +[Model][Advanced For HuaXin_SOUTH_ZHD_CHCX] +Step-Protocol-Baudrate:250-2-9600 +Step-Protocol-Baudrate:250-4-9600 +Step-Protocol-Baudrate:250-256-9600 +Step-Protocol-Baudrate:250-512-9600 +Step-Protocol-Baudrate:250-256-19200 +Step-Protocol-Baudrate:250-512-19200 +Step-Protocol-Baudrate:250-4096-19200 +[Model][Advanced For HuaXin_SOUTH_ZHD] +Step-Protocol-Baudrate:250-1-9600 +Step-Protocol-Baudrate:250-2-9600 +Step-Protocol-Baudrate:250-4-9600 +Step-Protocol-Baudrate:250-256-9600 +Step-Protocol-Baudrate:250-512-9600 +Step-Protocol-Baudrate:250-1-19200 +Step-Protocol-Baudrate:250-256-19200 +Step-Protocol-Baudrate:250-512-19200 +[Model][Features] +Size:19 +ID:1:RX +Range:450,470 +Baudrate:4800,9600,19200 +Stepper:125 +Protocol:1,2,4 +Power:NONE +[Model][Operations] +Frequency:1,1 +Baudrate:1,1 +Power:0,0 +Sensitivity:0,0 +FEC:0,0 +Stepper:0,0 +CallSign:0,0 +ID:2:RXTX +Range:450,470 +Baudrate:9600 +Stepper:125 +Protocol:1,2,4,128 +Power:1,5,10,20 +[Model][Operations] +Frequency:1,1 +Baudrate:0,0 +Power:1,1 +Sensitivity:0,0 +FEC:0,0 +Stepper:0,0 +CallSign:0,0 +ID:3:Satel +Range:403,473 +Baudrate:4800,9600,19200 +Stepper:125,250 +Protocol:2,4,8,16 +Power:1,5,10 +[Model][Operations] +Frequency:1,1 +Baudrate:0,0 +Power:1,1 +Sensitivity:1,1 +FEC:1,1 +Stepper:1,1 +CallSign:1,1 +ID:4:LFS +Range:455,463 +Baudrate:9600 +Stepper:250 +Protocol:1 +Power:1,5,10,20 +[Model][Operations] +Frequency:1,1 +Baudrate:0,0 +Power:1,1 +Sensitivity:0,0 +FEC:0,0 +Stepper:0,0 +CallSign:0,0 +ID:5:RXTX-MOREBAUDS +Range:450,470 +Baudrate:4800,9600,19200 +Stepper:125 +Protocol:1,2,4 +Power:1,5,10,20 +[Model][Operations] +Frequency:1,1 +Baudrate:1,1 +Power:1,1 +Sensitivity:0,0 +FEC:0,0 +Stepper:0,0 +CallSign:0,0 +ID:6:LFS-MOREBAUDS +Range:455,463 +Baudrate:9600,19200 +Stepper:250 +Protocol:1 +Power:1,5,10,20 +[Model][Operations] +Frequency:1,1 +Baudrate:1,1 +Power:1,1 +Sensitivity:0,0 +FEC:0,0 +Stepper:0,0 +CallSign:0,0 +ID:7:LFS-Low +Range:412,422 +Baudrate:9600 +Stepper:250 +Protocol:1 +Power:1,5,10,20 +[Model][Operations] +Frequency:1,1 +Baudrate:0,0 +Power:1,1 +Sensitivity:0,0 +FEC:0,0 +Stepper:0,0 +CallSign:0,0 +ID:8:Satel-I80 +Range:403,473 +Baudrate:4800,9600,19200 +Stepper:125,250 +Protocol:2,4,8,16 +Power:1,2,5,10 +[Model][Operations] +Frequency:1,1 +Baudrate:1,0 +Power:1,1 +Sensitivity:1,1 +FEC:1,1 +Stepper:1,1 +CallSign:1,1 +ID:9:HX +Range:410,470 +Baudrate:9600,19200 +Stepper:250 +Protocol:1,2,4 +Power:5,10,20 +[Model][Operations] +Frequency:1,1 +Baudrate:1,1 +Power:1,1 +Sensitivity:0,0 +FEC:0,0 +Stepper:0,0 +CallSign:0,0 +ID:10:HX-EX +Range:410,470 +Baudrate:4800,9600,19200 +Stepper:125,250 +Protocol:1,2,4 +Power:5,10,20 +[Model][Operations] +Frequency:1,1 +Baudrate:1,1 +Power:1,1 +Sensitivity:0,0 +FEC:0,0 +Stepper:1,1 +CallSign:0,0 +ID:11:Satel-TR8 +Range:865,867 +Baudrate:19200 +Stepper:250 +Protocol:8 +Power:1,5,10 +[Model][Operations] +Frequency:1,1 +Baudrate:1,1 +Power:1,1 +Sensitivity:0,0 +FEC:1,1 +Stepper:1,1 +CallSign:0,0 +ID:12:HX-EX2 +Range:410,470 +Baudrate:4800,9600,19200 +Stepper:125,250 +Protocol:2,4,256,512 +Power:5,10,20 +[Model][Operations] +Frequency:1,1 +Baudrate:1,1 +Power:1,1 +Sensitivity:0,0 +FEC:0,0 +Stepper:1,1 +CallSign:0,0 +ID:13:D352 +Range:410,470 +Baudrate:9600,19200 +Stepper:125,200,250 +Protocol:1,2,4 +Power:5,10,20 +[Model][Operations] +Frequency:1,1 +Baudrate:1,1 +Power:1,1 +Sensitivity:0,0 +FEC:0,0 +Stepper:1,1 +CallSign:0,0 +ID:14:HX_SOUTH +Range:410,470 +Baudrate:4800,9600,19200 +Stepper:125,250 +Protocol:1,2,4,256 +Power:5,10,20 +[Model][Operations] +Frequency:1,1 +Baudrate:1,1 +Power:1,1 +Sensitivity:0,0 +FEC:0,0 +Stepper:1,1 +CallSign:0,0 +ID:15:HX_865 +Range:1,8 +Baudrate:19200 +Stepper:125 +Protocol:1 +Power:5,10 +[Model][Operations] +Frequency:1,1 +Baudrate:1,1 +Power:1,1 +Sensitivity:0,0 +FEC:0,0 +Stepper:1,1 +CallSign:0,0 +ID:16:D352_CHCX +Range:410,470 +Baudrate:9600,19200 +Stepper:125,200,250 +Protocol:1,2,4,4096 +Power:5,10,20 +[Model][Operations] +Frequency:1,1 +Baudrate:1,1 +Power:1,1 +Sensitivity:0,0 +FEC:0,0 +Stepper:1,1 +CallSign:0,0 +ID:17:HX_SOUTH_CHCX +Range:410,470 +Baudrate:4800,9600,19200 +Stepper:125,250 +Protocol:1,2,4,256,4096 +Power:5,10,20 +[Model][Operations] +Frequency:1,1 +Baudrate:1,1 +Power:1,1 +Sensitivity:0,0 +FEC:0,0 +Stepper:1,1 +CallSign:0,0 +ID:18:HX_SOUTH_ZHD_CHCX +Range:410,470 +Baudrate:9600,19200 +Stepper:125,250 +Protocol:2,4,256,512,4096 +Power:5,10,20 +[Model][Operations] +Frequency:1,1 +Baudrate:1,1 +Power:1,1 +Sensitivity:0,0 +FEC:0,0 +Stepper:1,1 +CallSign:0,0 +ID:19:HX_SOUTH_ZHD +Range:410,470 +Baudrate:9600,19200 +Stepper:125,250 +Protocol:1,2,4,256,512 +Power:5,10,20 +[Model][Operations] +Frequency:1,1 +Baudrate:1,1 +Power:1,1 +Sensitivity:0,0 +FEC:0,0 +Stepper:1,1 +CallSign:0,0 +[Group][NMEA] +[Model][Features] +Size:8 +ID:1 +Type:1,2,3,4,5,6,7,8,9,12,13,14,19,20 +Frequency:3,4,5,6,7,8,9,10,11 +ID:2 +Type:1,2,3,4,5,6,7,8,9,10,11,12 +Frequency:4,5,6,7,8,9,10,11 +ID:4 +Type:1,2,3,4,5,6,7,8,9,12,15,16 +Frequency:5,6,7,8 +ID:6 +Type:1,2,3,5,6,7,8,9,10,11 +Frequency:4,5,6,7,8,9,10,11 +ID:7 +Type:1,2,3,4,5,6,7,8,9,12,15,16 +Frequency:5,6,7,8,9,10,11 +ID:8 +Type:1,2,3,4,5,6,7,8,9,12,13,14,17,18,19,20,21,22,23,24,25 +Frequency:5,6,7,8,9,10 +ID:12 +Type:1,2,3,4,5,6,7,8,9,12,19 +Frequency:8,9,10,11 +ID:14 +Type:1,2,3,5,6,7,8,9,10,11 +Frequency:4,5,6,7,8,9,10,11 +[Group][Precision] +[Model][Features] +Size:5 +ID:1 +HP:0.2 +VP:0.2 +XP:0.2 +YP:0.2 +RMS:0.2 +Status:11 +DiffAge:-1 +ID:2 +HP:0.6 +VP:0.6 +XP:0.6 +YP:0.6 +RMS:0.6 +Status:-1 +DiffAge:5 +ID:3 +HP:0.6 +VP:0.6 +XP:0.6 +YP:0.6 +RMS:0.6 +Status:-1 +DiffAge:5 +ID:7 +HP:0.3 +VP:0.3 +XP:0.3 +YP:0.3 +RMS:0.3 +Status:11 +DiffAge:-1 +ID:8 +HP:0.2 +VP:0.2 +XP:0.2 +YP:0.2 +RMS:0.2 +Status:11 +DiffAge:-1 +[Group][EBubbleMatrix] +[Model][Features] +Size:4 +ID:1 +Type:-2 +Matrix:0,1,-1,0 +ID:2 +Type:-1 +Matrix:1,0,0,1 +ID:3 +Type:0 +Matrix:-1,0,0,1 +ID:4 +Type:1 +Matrix:-1,0,0,1 +[Group][StaticSampleFreq] +[Model][Features] +Size:4 +ID:1 +Type:0 +FreqList:7,8,9,10,11,12,15,16 +ID:2 +Type:1 +FreqList:4,5,6,7,8,9,10,11,12,15,16 +ID:3 +Type:2 +FreqList:6,8,9,10,11,12,15,16 +ID:4 +Type:3 +FreqList:8,9,10,11 +[Group][SmartGNSSPN] +[Model][Features] +Size:13 +ID:1 +Type:1 +Name:N72 +CalibrationType:1 +Main:72 +Sub:00,01,10 +ID:2 +Type:2 +Name:I80 +CalibrationType:1 +Main:80 +Sub:00,01 +ID:3 +Type:3 +Name:X10 +CalibrationType:1 +Main:80 +Sub:02,03 +ID:4 +Type:4 +Name:T8 +CalibrationType:1 +Main:80 +Sub:06,07 +ID:5 +Type:5 +Name:X9 +CalibrationType:1 +Main:80 +Sub:11,15 +ID:6 +Type:6 +Name:M6 +CalibrationType:2 +Main:80 +Sub:08 +ID:7 +Type:7 +Name:I70 +CalibrationType:1 +Main:80 +Sub:09,10,13 +ID:8 +Type:8 +Name:T7 +CalibrationType:1 +Main:80 +Sub:14 +ID:9 +Type:9 +Name:X360 +CalibrationType:1 +Main:36 +Sub: +ID:10 +Type:10 +Name:NX100 +CalibrationType:0 +Main:74 +Sub:12,24 +ID:11 +Type:11 +Name:NX101 +CalibrationType:0 +Main:75 +Sub: +ID:12 +Type:12 +Name:MC100 +CalibrationType:0 +Main:76 +Sub:00,01 +ID:13 +Type:13 +Name:NX200 +CalibrationType:0 +Main:77 +Sub: +[Group][SupportGNSSType] +[Model][SMARTGNSS] +Type:0 +MainBoard:0 +[Model][ARM] +Type:0 +MainBoard:0 +[Model][DIRECT] +Type:0 +MainBoard:0 \ No newline at end of file diff --git a/app/src/main/assets/network_error.png b/app/src/main/assets/network_error.png new file mode 100644 index 0000000..c1fed83 Binary files /dev/null and b/app/src/main/assets/network_error.png differ diff --git a/app/src/main/assets/privacyPolicy.xml b/app/src/main/assets/privacyPolicy.xml new file mode 100644 index 0000000..0389a6e --- /dev/null +++ b/app/src/main/assets/privacyPolicy.xml @@ -0,0 +1,170 @@ + + + 本政策仅适用于河南冰测科技有限公司的导线助手产品或服务。 最近更新日期:2023年9月8日。 + 本政策将帮助您了解以下内容: + 一、我们如何收集和使用您的用户信息 + 二、我们如何使用 Cookie 和同类技术 + 三、我们如何共享、转让、公开披露您的用户信息 + 四、我们如何保护您的用户信息 + 五、您的权利 + 六、您的用户信息如何储存及如何在全球范围转移 + 七、本政策如何更新 + 八、如何联系我们 + + 我们深知用户信息对您的重要性,并会尽全力保护您的用户信息安全可靠。我们致力于维持您对我们的信任,恪守以下原则,保护您的用户信息:权责一致原则、目的明确原则、选择同意原则、最少够用原则、确保安全原则、主体参与原则、公开透明原则等。同时,我们承诺,我们将按业界成熟的安全标准,采取相应的安全保护措施来保护您的用户信息。 + 请在使用我们的产品(或服务)前,仔细阅读并了解本隐私政策。 + + 一、我们如何收集和使用您的用户信息 + (一)您使用我司产品或服务过程中我们收集和使用的信息 + 我们仅会出于本政策所述的业务功能,收集和使用您的用户信息,收集用户信息的目的在于向您提供产品或服务,您有权自行选择是否提供该信息,但多数情况下,如果您不提供,我们可能无法向您提供相应的服务,也无法回应您遇到的问题: + 在您使用我们的服务时,允许我们收集您自行向我们提供的或为向您提供服务所必要的信息包括:账号密码信息、电子邮件地址、手机号码、设备信息、外接设备连接信息、设备信息(IMEI/MAC/Android ID/IDFA/OpenUDID/GUID/IP地址/SIM 卡 IMSI 信息等)、位置信息、网络身份标识信息、应用列表、剪切板、读写存储设备SD卡。 + 以下对我们用到的信息做详细说明: + 1.您的账号密码信息将被用来登录您的账户,保证您个人数据的安全,防止被其他用户盗用。 + 2.您的邮箱地址将被用来做为登录方式之一,也可以做为找回、重置账户密码的方式。 + 3.您的手机号将被用来作为登录方式之一,也可以用来作为找回、重置账户密码的方式。 + 4.您的设备信息将被用来优化软件的适配,比如手机的屏幕分辨率可以优化软件界面的布局、手机网络模式用来优化节约用户流量信息。 + 5.您的外接设备连接信息和外接设备状态将被用来优化软件与第三方设备的适配,比如外接gps、北斗定位设备时,可以通过设备型号,发送不同的通信指令,以便提高通讯的可靠性。 + 6.您的位置信息将被用来识别定位差分信息,我们的软件为了提高定位精度,采用的gps、北斗等卫星定位系统差分技术,此技术可以将定位精度提高到厘米级,但是此技术需要把用户的位置信息传送到差分服务提供商的服务器,以便获取合适的差分数据。同时,软件为了连接第三方gps、北斗设备,需要用蓝牙通讯,而蓝牙搜索时,安卓系统需要使用定位权限,因此,蓝牙搜索连接也会需要定位权限。 + 7.您的网络身份标识信息将被用来降低账号的异地登录、盗号等风险。 + 8.您的应用列表信息将被用来验证是否安装我们公司开发的其他软件,以便我司软件间的数据共享、调用。 + 9.您的剪切板信息将被用来在软件不同的界面间,快捷复制粘贴数据,提供您的工作效率。 + 10.读写存储SD卡权限将被用于读取CAD文件、读取用户要导入的文件、保存用户导出的私人数据、备份用户的私人数据。 + + 您提供的上述信息,将在您使用本服务期间持续授权我们使用。在您停止使用推送服务时,我们将停止使用并删除上述信息。 + 我们保证会依法对收集后的用户信息进行去标识化或匿名化处理,对于无法单独或者与其他信息结合识别自然人个人身份的信息,不属于法律意义上的个人信息。如果我们将非个人信息与其他信息结合识别到您的个人身份时,或者与您的个人信息结合使用时,我们会在结合使用期间,将此类信息作为您的个人信息按照本隐私政策对其进行处理和保护。 + 为了更好运营和改善我们的技术和服务,或出于商业策略的变化,当我们提供的产品或服务所需的用户信息收集、使用、处理超出上述范围或者要将收集到的用户信息用于本隐私政策未载明的其他用途,或当我们要将基于特定目的收集而来的信息用于其他目的时,我们会在获取用户信息后的合理期限内或处理用户信息前通知您,并获得您的授权同意。 + + (二)征得授权同意的例外 + 请您理解,根据法律法规及相关国家标准,以下情形中,我们收集和使用您的用户信息无需征得您的授权同意: + 1、与国家安全、国防安全直接相关的; + 2、与公共安全、公共卫生、重大公共利益直接相关的; + 3、与犯罪侦查、起诉、审判和判决执行等直接相关的; + 4、出于维护您或其他个人的生命、财产等重大合法权益但又很难得到本人同意的; + 5、所收集的您的用户信息是您自行向社会公众公开的; + 6、从合法公开披露的信息中收集的您的用户信息,如合法的新闻报道、政府信息公开等渠道; + 7、根据您的要求签订或履行合同所必需的; + 8、用于维护软件及相关服务的安全稳定运行所必需的,例如发现、处置软件及相关服务的故障; + 9、 个人信息控制者为新闻单位且其在开展合法的新闻报道所必需的; + 10、学术研究机构基于公共利益开展统计或学术研究所必要,且对外提供学术研究或描述的结果时,对结果中所包含的个人信息进行去标识化处理的。 + 11、法律法规规定的其他情形。 + + 二、我们如何使用 Cookie 和同类技术 + (一)Cookie + 为确保网站正常运转,我们会在您的计算机或移动设备上存储名为 Cookie 的小数据文件。Cookie 通常包含标识符、站点名称以及一些号码和字符。借助于 Cookie,网站能够存储您的访问偏好数据。 + 我们不会将 Cookie 用于本政策所述目的之外的任何用途。您可根据自己的偏好管理或删除 Cookie。您可以清除计算机上保存的所有 Cookie,大部分网络浏览器都设有阻止Cookie 的功能。但如果您这么做,则需要在每一次访问我们的网站时亲自更改用户设置。 + + (二)网站信标和像素标签 + 除 Cookie 外,我们还会在网站上使用网站信标和像素标签等其他同类技术。例如,我们向您发送的电子邮件可能含有链接至我们网站内容的点击URL。 + 如果您点击该链接,我们则会跟踪此次点击,帮助我们了解您的产品或服务偏好并改善客户服务。网站信标通常是一种嵌入到网站或电子邮件中的透明图像。借助于电子邮件中的像素标签,我们能够获知电子邮件是否被打开。如果您不希望自己的活动以这种方式被追踪,则可以随时从我们的寄信名单中退订。 + + (三)Do Not Track(请勿追踪) + 很多网络浏览器均设有Do Not Track功能,该功能可向网站发布Do Not Track请求。目前,主要互联网标准组织尚未设立相关政策来规定网站应如何应对此类请求。但如果您的浏览器启用了 Do Not Track,那么我们的所有网站都会尊重您的选择。 + + 三、我们如何共享、转让、公开披露您的用户信息 + (一)共享 + 我们不会与其他的任何公司、组织和个人分享您的用户信息,但以下情况除外: + 1、在获取明确同意的情况下共享:获得您的明确同意后,我们会与其他方共享您的用户信息。 + 2、我们可能会根据法律法规规定,或按政府主管部门的强制性要求,对外共享您的用户信息。 + 3、与我们的关联公司共享:您的用户信息可能会与我们的关联公司共享。我们只会共享必要的用户信息,且受本隐私政策中所声明目的的约束。关联公司如要改变用户信息的处理目的,将再次征求您的授权同意。 + 4、与授权合作伙伴共享:仅为实现本政策中声明的目的,我们的某些服务将由授权合作伙伴提供。我们可能会与合作伙伴共享您的某些用户信息,以提供更好的客户服务和用户体验。我们仅会出于合法、正当、必要、特定、明确的目的共享您的用户信息,并且只会共享提供服务所必要的用户信息。为了更好运营和改善技术和服务,您同意我们和授权合作伙伴在符合相关法律法规的前提下可将收集的信息用于其他服务和用途。 + 以下列举了具体的授权合作伙伴,并提供了该第三方的隐私政策链接,我们建议您阅读该第三方的隐私政策: + + (一)统计服务供应商:由北京锐讯灵通科技有限公司提供统计技术服务,我们可能会收集您的设备信息(IMEI/MAC/Android ID/IDFA/OpenUDID/GUID/IP地址/SIM 卡 IMSI 信息等)提供给北京锐讯灵通科技有限公司,用于为您提供统计技术服务。详细内容请访问《友盟统计隐私政策》。友盟统计隐私政策链接:https://www.umeng.com/page/policy + (二)广告、媒体:我们可能会将收集到的信息共享给广告、媒体以及我们的其他授权合作伙伴,用于包括优化广告投放和提升营销效果等商业化用途。 + (三)推送服务供应商:由美味书签(北京)信息技术有限公司提供推送技术服务,我们可能会将您的设备平台、设备厂商、设备品牌、设备识别码等设备信息,应用列表信息、网络信息以及位置相关信息提供给美味书签(北京)信息技术有限公司,用于为您提供推送技术服务。 + 对我们与之共享用户信息的公司、组织和个人,我们会与其签署严格的保密协定,要求他们按照我们的说明、本隐私政策以及其他任何相关的保密和安全措施来处理用户信息。 + + (二)转让 + 我们不会将您的用户信息转让给任何公司、组织和个人,但以下情况除外: + 1、在获取明确同意的情况下转让:获得您的明确同意后,我们会向其他方转让您的用户信息; + 2、在涉及合并、收购或破产清算时,如涉及到用户信息转让,我们会再要求新的持有您用户信息的公司、组织继续受此隐私政策的约束,否则我们将要求该公司、组织重新向您征求授权同意。 + + (三)公开披露 + 我们仅会在以下情况下,公开披露您的用户信息: + 1、获得您明确同意后; + 2、基于法律的披露:在法律、法律程序、诉讼或政府主管部门强制性要求的情况下,我们可能会公开披露您的用户信息。 + + (四)共享、转让、公开披露信息时事先征得授权同意的例外 + 请您理解,根据法律法规及相关国家标准,以下情形中,我们共享、转让、公开披露您的用户信息无需征得您的授权同意: + 1、与国家安全、国防安全直接相关的; + 2、与公共安全、公共卫生、重大公共利益直接相关的; + 3、与犯罪侦查、起诉、审判和判决执行等直接相关的; + 4、出于维护您或其他个人的生命、财产等重大合法权益但又很难得到本人同意的; + 5、您自行向社会公众公开的信息; + 6、从合法公开披露的信息中收集的,如合法的新闻报道、政府信息公开等渠道。 + + 四、我们如何保护您的用户信息 + (一)我们已使用符合业界标准的安全防护措施保护您提供的用户信息,防止数据遭到未经授权的访问、公开披露、使用、修改、损坏或丢失。我们会采取一切合理可行的措施,保护您的用户信息。例如,在您的浏览器与“服务”之间交换数据时受 SSL 加密保护;我们同时对网站提供https安全浏览方式;我们会使用加密技术确保数据的保密性;我们会使用受信赖的保护机制防止数据遭到恶意攻击;我们会部署访问控制机制,确保只有授权人员才可访问用户信息;以及我们会举办安全和隐私保护培训课程,加强员工对于保护用户信息重要性的认识。 + (二)我们会采取一切合理可行的措施,确保未收集无关的用户信息。我们只会在达成本政策所述目的所需的期限内保留您的用户信息,除非需要延长保留期或受到法律的允许。 + (三)互联网并非绝对安全的环境,而且电子邮件、即时通讯、及与其他用户的交流方式并未加密,我们强烈建议您不要通过此类方式发送用户信息。 + (四)互联网环境并非百分之百安全,我们将尽力确保您发送给我们的任何信息的安全性。即使我们做出了很大努力,采取了一切合理且必要的措施,仍然有可能无法杜绝您的用户信息被非法访问、被非法盗取,被非法篡改或毁坏,导致您的合法权益受损,请您理解信息网络的上述风险并自愿承担。 + (五)在不幸发生用户信息安全事件后,我们将按照法律法规的要求,及时向您告知:安全事件的基本情况和可能的影响、我们已采取或将要采取的处置措施、您可自主防范和降低风险的建议、对您的补救措施等。我们将及时将事件相关情况以邮件、信函、电话、推送通知等方式告知您,难以逐一告知用户信息主体时,我们会采取合理、有效的方式发布公告。同时,我们还将按照监管部门要求,主动上报用户信息安全事件的处置情况。 + + 五、您的权利 + 按照中国相关的法律、法规、标准,以及其他国家、地区的通行做法,我们保障您对自己的用户信息行使以下权利: + (一)访问您的用户信息 + 您有权访问您的用户信息,法律法规规定的例外情况除外。如果您想行使数据访问权,可以通过以下方式自行访问:www.bingce.com + 如果您无法通过上述链接访问这些用户信息,您可以随时使用我们的 Web 表单联系,或发送电子邮件至liu@bingce.com。我们将在30天内回复您的访问请求。 + 对于您在使用我们的产品或服务过程中产生的其他用户信息,只要我们不需要过多投入,我们会向您提供。如果您想行使数据访问权,请发送电子邮件至liu@bingce.com。 + + (二)更正您的用户信息 + 当您发现我们处理的关于您的用户信息有错误时,您有权要求我们作出更正。您可以通过“(一)访问您的用户信息”中罗列的方式提出更正申请。 如果您无法通过上述链接更正这些用户信息,您可以随时使用我们的 Web 表单联系,或发送电子邮件至liu@bingce.com。我们将在30天内回复您的更正请求。 + + (三)删除您的用户信息 + 在以下情形中,您可以向我们提出删除用户信息的请求: + 1、如果我们处理用户信息的行为违反法律法规; + 2、如果我们收集、使用您的用户信息,却未征得您的同意; + 3、如果我们处理用户信息的行为违反了与您的约定; + 4、如果您不再使用我们的产品或服务,或您注销了账号; + 5、如果我们不再为您提供产品或服务。 + 我们将会根据您的删除请求进行评估,若满足相应规定,我们将会采取相应步骤进行处理。当您向我们提出删除请求时,我们可能会要求您进行身份验证,以保障账户的安全。当您从我们的服务中删除信息后,因为适用的法律和安全技术,我们可能不会立即从备份系统中删除相应的信息,我们将安全存储您的信息直到备份可以清除或实现匿名化。 + + (四)改变您授权同意的范围 + 每个业务功能需要一些基本的用户信息才能得以完成(见本政策“第一部分”)。对于用户信息的收集和使用,您可以随时给予或收回您的授权同意。您可以通过以下方式自行操作:在安卓系统设置应用管理中找到本应用,找到权限管理,可以打开或关闭某些权限。 + 当您收回同意后,我们将不再处理相应的用户信息。同时也请您注意,您撤销授权同意可能会导致某些后果,例如我们可能无法继续为您提供相应的服务或特定的功能,但您收回同意的决定,不会影响此前基于您的授权而开展的用户信息处理。 + + (五)用户信息主体注销账户 + 您随时可注销此前注册的账户,您可以通过以下方式操作:发送邮件到liu@bingce.com,我们将提供人工服务。在注销账户之后,我们将停止为您提供产品或服务并依据您的要求,删除或匿名化您的信息,法律法规另有规定的除外。这也将可能导致您失去对您账户中数据的访问权,请您谨慎操作。 + + (六)用户信息主体获取用户信息副本 + 您有权获取您的用户信息副本,您可以通过以下方式操作:发送邮件到liu@bingce.com,我们将提供人工服务。在技术可行的前提下,例如数据接口匹配,我们还可按您的要求,直接将您的用户信息副本传输给您指定的第三方。 + + (七)约束信息系统自动决策 + 在某些业务功能中,我们可能仅依据信息系统、算法等在内的非人工自动决策机制作出决定。如果这些决定显著影响您的合法权益,您有权要求我们作出解释,我们也将提供适当的救济方式。 + + (八)响应您的上述请求 + 为保障安全,您可能需要提供书面请求,或以其他方式证明您的身份。我们可能会先要求您验证自己的身份,然后再处理您的请求。 + 我们将在三十天内作出答复。如您不满意,还可以通过以下途径投诉:向有关部门投诉。对于您合理的请求,我们原则上不收取费用,但对多次重复、超出合理限度的请求,我们将视情况收取一定成本费用。对于那些无端重复、需要过多技术手段(例如,需要开发新系统或从根本上改变现行惯例)、给他人合法权益带来风险或者非常不切实际的请求,我们可能会予以拒绝。也请您理解,出于安全保障的考虑、相关法律法规的要求或技术上的限制,对于您的某些请求我们可能无法做出响应,例如以下情形: + 1、与用户信息控制者履行法律法规规定的义务相关的; + 2、与国家安全、国防安全直接相关的; + 3、与公共安全、公共卫生、重大公共利益直接相关的; + 4、与犯罪侦查、起诉、审判和执行判决等直接相关的; + 5、用户信息控制者有充分证据表明用户信息主体存在主观恶意或滥用权利的; + 6、出于维护用户信息主体或其他个人的生命、财产等重大合法权益但又很难得到本人同意的; + 7、响应用户信息主体的请求将导致用户信息主体或其他个人、组织的合法权益受到严重损害的; + 8、涉及商业秘密的。 + + 六、您的用户信息如何储存以及如何在全球范围转移 + 原则上,我们在中华人民共和国境内收集和产生的用户信息,将存储在中华人民共和国境内。我们只会在本政策所述目的和用途所需的期限内和法律法规规定的最短期限内保留您的用户信息,超出上述保留期间后,我们会根据适用法律法规的要求删除您的用户信息或匿名化处理。法律法规另有规定,或出于公共利益、科学历史研究等的目的,或您的另行授权同意的除外,我们可能需要较长时间保留相关数据。 + 由于我们通过遍布全球的资源和服务器提供产品或服务,这意味着,在获得您的授权同意后,您的用户信息可能会被转移到您使用产品或服务所在国家/地区的境外管辖区,或者受到来自这些管辖区的访问。 + 此类管辖区可能设有不同的数据保护法,甚至未设立相关法律。在此类情况下,我们会确保您的用户信息得到在中华人民共和国境内足够同等的保护。例如,我们会请求您对跨境转移用户信息的同意,或者在跨境数据转移之前实施数据去标识化等安全举措。 + + 七、本政策如何更新 + 我们的隐私政策可能变更。未经您明确同意,我们不会削减您按照本隐私政策所应享有的权利。我们会在本页面上发布对本政策所做的任何变更。 + 对于重大变更,我们还会提供更为显著的通知。本政策所指的重大变更包括但不限于: + 1、我们的服务模式发生重大变化。如处理用户信息的目的、处理的用户信息类型、用户信息的使用方式等; + 2、我们在所有权结构、组织架构等方面发生重大变化。如业务调整、破产并购等引起的所有者变更等; + 3、用户信息共享、转让或公开披露的主要对象发生变化; + 4、您参与用户信息处理方面的权利及其行使方式发生重大变化; + 5、我们负责处理用户信息安全的责任部门、联络方式及投诉渠道发生变化时; + 6、用户信息安全影响评估报告表明存在高风险时。 + 我们还会将本政策的旧版本存档,供您查阅。 + + 八、如何联系我们 + 如果您对本隐私政策有任何疑问、意见或建议,通过以下方式与我们联系: + 电子邮件:liu@bingce.com + 电  话:13657190002 + 我们设立了用户信息保护专职部门,您可以通过以下方式与相关人员联系:liu@bingce.com + 一般情况下,我们将在三十天内回复。 + 如果您对我们的回复不满意,特别是我们的用户信息处理行为损害了您的合法权益,您还可以通过以下外部途径寻求解决方案:向有关部门投诉。 + \ No newline at end of file diff --git a/app/src/main/assets/privacyPolicy_en.xml b/app/src/main/assets/privacyPolicy_en.xml new file mode 100644 index 0000000..414dac4 --- /dev/null +++ b/app/src/main/assets/privacyPolicy_en.xml @@ -0,0 +1,45 @@ + + + This application respects and protects the personal privacy of all users of the service. In order to provide you with more accurate and personalized services, this application will use and disclose your personal information in accordance with the provisions of this privacy policy. However, this application will treat this information with a high degree of diligence and prudence. Except as otherwise provided in this Privacy Policy, this application will not disclose this information to third parties or provide it to third parties without your prior permission. This app will update this privacy policy from time to time. +When you agree to this application service use agreement, you are deemed to have agreed to the entire content of this privacy policy. This privacy policy is an integral part of this application service usage agreement. + +Scope of application +(a) when you register for this application account, the personal registration information you provided in accordance with the requirements of this application; +(b) +When you use this application web service or visit this application platform web page, this application automatically receives and records information on your browser and computer, including but not limited to your IP address, browser type, language used , Access date and time, software and hardware characteristic information, and web page records such as your requirements; +(c) User personal data obtained by this application from business partners through legal channels. +You understand and agree that the following information does not apply to this privacy policy: +(a) the keyword information you enter when using the search services provided by this application platform; +(b) relevant information and data collected by this application and released by you in this application, including but not limited to participation activities, transaction information and evaluation details; +(c) Violations of laws or violations of this application rule and the actions this application has taken against you. +2. Use of information +(a) This application will not provide, sell, rent, share or trade your personal information to any unrelated third party, unless you have obtained your permission in advance, or the third party and this application (including this application affiliate) alone or jointly To provide you with a service, and after the service has ended, it will be barred from access to all of this material, including its previous access. +(b) This application also does not allow any third party to collect, edit, sell or disseminate your personal information by any means. If any user of this application platform engages in the above activities, once found, this application has the right to immediately terminate the service agreement with that user. +(c) +For the purpose of serving users, this application may provide you with information that is of interest to you by using your personal information, including but not limited to sending you product and service information, or sharing information with this application partner so that they can send you Information about its products and services (the latter requires your prior consent). +3. Information disclosure +Under the following circumstances, this application will disclose your personal information in whole or in part according to your personal wishes or legal requirements: +(a) disclosure to third parties with your prior consent; +(b) in order to provide the products and services you have requested, your personal information must be shared with third parties; +(c) disclosure to third parties or administrative or judicial bodies in accordance with the relevant provisions of the law or the requirements of administrative or judicial bodies; +(d) if you have violated relevant Chinese laws, regulations or this application service agreement or related rules, you need to disclose it to a third party; +(e) If you are a qualified intellectual property complainant and have filed a complaint, you should disclose it to the respondent at the request of the respondent so that both parties can deal with possible disputes over rights; +(f) In a transaction created on the application platform, if any party to the transaction fulfills or partially fulfills the transaction obligations and requests for information disclosure, the application has the right to determine the necessary means to provide the user with the contact method of the counterparty Information to facilitate the completion of a transaction or the resolution of a dispute. +(g) Other disclosures that this application deems appropriate in accordance with laws, regulations or website policies. +4. Information storage and exchange +The information and data collected about you by this application will be stored on the server of this application and / or its affiliates. Such information and data may be transferred to your country, region or outside the country where the information and data are collected by this application and in Accessed, stored and displayed overseas. +5. Use of cookies +(a) If you do not refuse to accept cookies, this application will set or access cookies on your computer +So that you can log in or use the services or features of this application platform that rely on cookies. This application uses cookies to provide you with more thoughtful personalized services, including promotion services. +(b) +You have the right to choose to accept or decline cookies. You can refuse to accept cookies by modifying your browser settings. However, if you choose to decline cookies, you may not be able to log in or use the web services or features of this application that rely on cookies. +(c) The relevant information obtained through the cookies set by this application will apply this policy. +6. Information security +(a) +This application account has security protection functions, please keep your username and password information properly. This application will ensure that your information is not lost, misused and altered by security measures such as encrypting user passwords. Despite the aforementioned security measures, please also note that there are no "perfect security measures" on the information network. +(b) When using this application network service for online transactions, you must inevitably ask the counterparty or potential transaction pair +7. Changes to this privacy policy +(a) if we decide to change our privacy policy, we will post those changes in this policy, on our website, and where we deem appropriate, so that you understand how we collect and use your personal information and who can access it, And under what circumstances we will disclose this information. +(b) The company reserves the right to modify this policy at any time, so please check it frequently. If major changes are made to this policy, the company will notify through a website notification. +Party to disclose their personal information, such as contact information or postal address. Please protect your personal information and provide it to others only when necessary. If you find that your personal information has been leaked, especially the user name and password of this application, please contact the customer service of this application immediately so that this application can take corresponding measures. + \ No newline at end of file diff --git a/app/src/main/assets/service_default.html b/app/src/main/assets/service_default.html new file mode 100644 index 0000000..a5a2796 --- /dev/null +++ b/app/src/main/assets/service_default.html @@ -0,0 +1,51 @@ + + + + + + + + + +
+
+ +
点击刷新
+
+
+ + + \ No newline at end of file diff --git a/app/src/main/assets/supplierconfig.json b/app/src/main/assets/supplierconfig.json new file mode 100644 index 0000000..5f5f8e0 --- /dev/null +++ b/app/src/main/assets/supplierconfig.json @@ -0,0 +1,13 @@ +{ + "supplier": { + "vivo": { + "appid": "100215079" + }, + "xiaomi": { + }, + "huawei": { + }, + "oppo": { + } + } +} \ No newline at end of file diff --git a/app/src/main/assets/template_tolerance b/app/src/main/assets/template_tolerance new file mode 100644 index 0000000..0cc2af3 --- /dev/null +++ b/app/src/main/assets/template_tolerance @@ -0,0 +1,93 @@ +[{ + "createDate": "Jan 27, 2021 9:37:42 AM", + "hor2C": 5.0, + "horCycleDirect2CDifference": 5.0, + "horCyclesDirect2CDifference": 5.0, + "horCyclesDirectValueDifference": 5.0, + "horHalfReturnZeroDifference": 5.0, + "horReadDifference": 5.0, + "id": "20210127093742841174", + "isTemplate": true, + "name": "限差模板0", + "singleSurveyor": true, + "slopeCycleDistanceDifference": 5.0, + "slopeLensDistanceDifference": 5.0, + "slopeReadDifference": 5.0, + "surveyorCycleCount": 2, + "verCheckWhenAngle3": true, + "verCycleDirectIDifference": 5.0, + "verCyclesAngleDifference": 5.0, + "verCyclesIDifference": 5.0, + "verIDifference": 5.0, + "verReadDifference": 5.0 + }, + { + "createDate": "Jan 27, 2021 9:37:43 AM", + "hor2C": 5.0, + "horCycleDirect2CDifference": 5.0, + "horCyclesDirect2CDifference": 5.0, + "horCyclesDirectValueDifference": 5.0, + "horHalfReturnZeroDifference": 5.0, + "horReadDifference": 5.0, + "id": "20210127093743841174", + "isTemplate": true, + "name": "限差模板1", + "singleSurveyor": true, + "slopeCycleDistanceDifference": 5.0, + "slopeLensDistanceDifference": 5.0, + "slopeReadDifference": 5.0, + "surveyorCycleCount": 2, + "verCheckWhenAngle3": true, + "verCycleDirectIDifference": 5.0, + "verCyclesAngleDifference": 5.0, + "verCyclesIDifference": 5.0, + "verIDifference": 5.0, + "verReadDifference": 5.0 + }, + { + "createDate": "Jan 27, 2021 9:37:44 AM", + "hor2C": 5.0, + "horCycleDirect2CDifference": 5.0, + "horCyclesDirect2CDifference": 5.0, + "horCyclesDirectValueDifference": 5.0, + "horHalfReturnZeroDifference": 5.0, + "horReadDifference": 5.0, + "id": "20210127093744841174", + "isTemplate": true, + "name": "限差模板2", + "singleSurveyor": true, + "slopeCycleDistanceDifference": 5.0, + "slopeLensDistanceDifference": 5.0, + "slopeReadDifference": 5.0, + "surveyorCycleCount": 2, + "verCheckWhenAngle3": true, + "verCycleDirectIDifference": 5.0, + "verCyclesAngleDifference": 5.0, + "verCyclesIDifference": 5.0, + "verIDifference": 5.0, + "verReadDifference": 5.0 + }, + { + "createDate": "Jan 27, 2021 9:37:45 AM", + "hor2C": 5.0, + "horCycleDirect2CDifference": 5.0, + "horCyclesDirect2CDifference": 5.0, + "horCyclesDirectValueDifference": 5.0, + "horHalfReturnZeroDifference": 5.0, + "horReadDifference": 5.0, + "id": "20210127093745841174", + "isTemplate": true, + "name": "限差模板3", + "singleSurveyor": true, + "slopeCycleDistanceDifference": 5.0, + "slopeLensDistanceDifference": 5.0, + "slopeReadDifference": 5.0, + "surveyorCycleCount": 2, + "verCheckWhenAngle3": true, + "verCycleDirectIDifference": 5.0, + "verCyclesAngleDifference": 5.0, + "verCyclesIDifference": 5.0, + "verIDifference": 5.0, + "verReadDifference": 5.0 + } +] \ No newline at end of file diff --git a/app/src/main/assets/userAgreement.xml b/app/src/main/assets/userAgreement.xml new file mode 100644 index 0000000..519f577 --- /dev/null +++ b/app/src/main/assets/userAgreement.xml @@ -0,0 +1,117 @@ + + + 本协议是导线助手手机应用程序(以下简称导线助手或“本应用”)与应用使用人(以下简称“用户”或“您”)所达成的协议。为使用导线助手应用的服务,您应当阅读并遵守本《用户服务协议》(以下简称“本协议”)。请您使用本应用以前,务必审慎阅读、充分理解各条款内容,特别是免除或者限制责任的条款、管辖与法律适用条款,以及开通或使用某项服务的单独协议。限制、免责条款可能以黑体加粗或加下划线的形式提示您重点注意。 + 您使用本应用的服务即视为您已仔细阅读并充分了解前述协议的内容,并同意接受上述协议的约束。除非您已阅读并接受本协议所有条款,否则您无权使用本应用所提供的服务。 + 如果您未满18周岁,请在法定监护人的陪同下阅读本协议,并特别注意未成年人使用条款。 + 我们的产品会传输用户已安装应用的相关信息。在使用这些信息之前,我们会先获取用户的授权,经许 可后,才会进行下一步。我们不会将这些信息用于任何其它非法用途。 + 一、使用者非个人化信息 + 我们将通过您的IP地址来收集使用者非个人化的信息,例如您的操作系统的版本、运行环境、运营商等,以优化在您手机屏幕上显示的页面。通过收集上述信息,我们亦进行客流量统计,从而改进本应用的管理和服务。 + 这些无关个人身份的信息能帮助我们辨别导线助手最受欢迎的地区并确定我们推广活动的有效性。此外,我们也可能将这些信息披露给我们的客户,使他们知道点击他们广告的人数。 + 二、个人资料 + 当您在本用于进行用户注册登记、参加网上论坛等各种活动,或者在使用本应用特定服务时,本应用可能会通过注册表格等形式要求您提供一些个人资料。这些个人资料可能包括: + 个人识别资料:如姓名、性别、年龄、出生日期、身份证号码(或护照号码)、电话、通信地址、住址、电子邮件地址等; + 个人背景:如职业、教育程度、收入状况、家庭状况、征信记录等; + 个人经历:如个人职业经历、社会履历等。 + 特定情形下,需要您按照本应用的要求提供所需个人资料后才能继续使用本应用的全部或部分服务,请您务必按照要求提供个人资料。否则,可能无法继续 + 使用本应用的全部或部分服务。在前述情形下,本应用会提前向您提醒并说明。除非适用法律法规、政府机关、司法机关或者其他第三方对本应用作出强制要 + 求,本应用不会对您提供的信息进行实质审核,如果您提供的信息错误或者不准确,由此产生的责任由您自行承担。 + 请了解,在未经您同意及确认之前,本应用不会将您为参加本应用之特定活动所提供的资料利用于经您同意的用途以外的其它目的。惟有按下列第六条规定按照政府及法律要求披露时不在此限。 + 三、信息安全 + 本应用将对您所提供的资料进行严格的管理及保护,本应用将使用相应的技术,防止您的个人资料丢失、被盗用或遭篡改。但因计算机系统和网络技术的限制,本应用可能会因受到第三方的攻击或破坏,导致用户的个人信息被恶意篡改、盗取或泄露,本应用将采取合理措施防止类似事件的发生,并将配合国家机关和第三方对类似事件进行调查或提起必要的行动(包括但不限于诉讼等)。对于非因本应用过错原因而导致的信息安全问题,您同意给予谅解并豁免本应用可能承担的任何责任。 + 四、用户权利 + 您对于自己的个人资料享有以下的权利: + 随时查询及请求阅览; + 随时请求补充或更正; + 随时请求删除; + 请求停止电脑处理及利用。 + 五、限制利用原则 + 本应用惟在符合下列条件之一,方对收集之个人资料进行必要范围以外之使用: + 已取得您的书面同意; + 为免除您在生命、身体或财产方面之急迫危险; + 为防止他人权益之重大危害; + 为增进公共利益,且无损于您的重大利益。 + 六、披露个人资料 + 当政府机关依照法定程序要求本应用披露个人资料时,本应用将根据执法单位之要求或为公共安全之目的提供个人资料。在此情况下之任何披露,本应用均得免责。 + 七、Cookies + Cookies是指一种技术,当使用者使用没有Cookies装置的本应用时,本应用之服务器会自动发送Cookies至您的浏览器内,并存储到您的手机硬盘内, + 此Cookies便负责记录日后您访问本应用的种种活动、个人资料、浏览习惯、消费习惯甚至信用记录。 + 运用Cookies技术,本应用能够为您提供更加周到的服务,本应用将会运用Cookies追访您的喜好,从而向您提供感兴趣的信息资料或存储密码,以便您造访本应用时不必每次重复输入密码。 + 八、未成年人隐私权的保护 + 本应用将建立和维持合理的程序,以保护未成年人个人资料的保密性及安全性。本应用郑重声明:任何18岁以下的未成年人参加网上活动应事先 + 得到家长或其法定监护人(以下统称为“监护人”)的可经查证的同意。 + 监护人应该承担保护未成年人在网络环境下的隐私权的首要责任。 + 本应用收集未成年人的个人资料,仅为回复未成年人特定要求的目的,一经回复完毕即从记录中删除,而不会保留这些资料做进一步的利用。 + 未经监护人之同意,本应用将不会使用未成年人之个人资料,亦不会向任何第三方披露或传送可识别该未成年人的个人资料。本应用如收集监护人或未成年人的姓名或其它网络通讯资料之目的仅是为获得监护人同意,则在经过一段合理时间仍未获得同意时,将主动从记录中删除此类资料。 + 若经未成年人之监护人同意,本应用可对未成年人之个人资料进行收集,本应用将向监护人提供: + 审视自其子女或被监护人收集之资料的机会; + 拒绝其子女或被监护人的个人资料被进一步的收集或利用的机会; + 变更或删除其子女或被监护人个人资料的方式。 + 监护人有权拒绝本应用与其子女或被监护人做进一步的联络。 + 本应用收集未成年人的个人资料,这些资料只是单纯作为保护未成年人参与网络活动时的安全,而非是作为其它目的来利用。本应用保证不会要求未成年人提供额外的个人资料,以作为允许其参与网上活动的条件。 + 九、用户违法行为 + 您在使用本应用服务时须遵守法律法规,不得利用本应用服务从事任何违法违规行为,包括但不限于: + (1)发布、传送、传播、储存危害国家安全统一、破坏社会稳定、违反公序良俗、侮辱、诽谤、淫秽、暴力以及任何违反国家法律法规的内容; + (2)发布、传送、传播、储存侵害他人知识产权、商业秘密等合法权利的内容; + (3)虚构事实、隐瞒真相以误导、欺骗他人; + (4)发布、传送、传播广告信息及垃圾信息; + (5)其他法律法规禁止的行为。 + 如果您违反本条之约定,有权国家机关可能会对您提起诉讼、罚款或采取其他制裁措施,并要求本应用给予协助或支持,由此产生的责任均应当由您自行承担。造成损害的,您应依法予以赔偿,本应用不承担任何责任。 + 如果在您使用本应用服务时违反本条约定,本应用有权进行独立判断并采取技术手段予以删除、屏蔽或断开链接。同时,本应用有权视您的行为性质,采取包括但不限于暂停或终止服务,限制、冻结或终止注册账号等,追究法律责任等措施。 + 如果您违反本条约定,导致任何第三方损害的,您应当独立承担责任;导致本应用遭受损失的,您也应当一并赔偿。 + 十、遵守法律和监管政策 + 您在使用本服务过程中应当遵守当地相关的法律法规和监管政策,并尊重当地的道德和风俗习惯。如果您的行为违反了当地法律法规或道德风俗,您应当为此独立承担责任。 + 您应避免因使用本服务而使本应用卷入政治和公共事件,否则本应用有权暂停或终止对您的服务。 + 十一、合法传播和第三方投诉处理 + 您通过本服务发送或传播的内容(包括但不限于网页、文字、图片、音频、视频、图表等)均由您自行承担责任。 + 您发送或传播的内容应有合法来源,相关内容为您所有或您已获得权利人的授权。 + 您同意本应用可为履行本协议或提供本服务的目的而使用您发送或传播的内容。 + 如果本应用收到权利人通知,主张您发送或传播的内容侵犯其相关权利的,您同意本应用有权进行独立判断并采取删除、屏蔽或断开链接等措施。 + 您使用本服务时不得违反国家法律法规、侵害他人合法权益。您理解并同意,如您被他人投诉侵权或您投诉他人侵权,本应用有权将争议中相关方的主体、联系方式、 + 投诉相关内容等必要信息提供给其他争议方或相关部门,以便及时解决投诉纠纷,保护他人合法权益。 + 十二、免责 + 除上述第六条规定属免责外,下列情况时本应用亦不需承担任何责任: + 不可抗力或意外事件等风险因素,导致本应用服务发生中断。 + 由于您将用户密码告知他人或与他人共享注册账户,或者您操作不当而导致的任何损失; + 任何由于计算机问题、黑客攻击、计算机病毒侵入或发作、因政府管制而造成的暂时性关闭等影响网络正常经营之不可抗力而造成的个人资料泄露、丢失、被盗用或被篡改等; + 用户或本应用的电脑软件、系统、硬件和通信线路出现故障; + 本应用的网页上有与其他网站网页的链接,包括网页上的广告。本应用对其他任何网站的内容、隐私政策或运营,或经营这些网站的公司的行为概不负责。在向这些网与本应用链接的其他网站提供个人信息以前,请查阅它们的隐私政策。 + 用户通过非本应用授权的方式使用本服务; + 由于与本应用链接的其它网站所造成之个人资料泄露及由此而导致的任何法律争议。 + 由于用户使用第三方服务而导致的损失或产生的任何争议。其他本应用无法控制或合理预见的情形。 + 由于用户粗心、图纸错误、放样方法错误等个人原因或第三方原因导致的损失。 + 由于用户上传具有保密级别数据而导致的泄密行为 + 您理解并同意,在使用本服务的过程中,可能会遇到网络信息或其他用户行为带来的风险,本应用不对任何信息的真实性、适用性、合法性承担责任,也不对因侵权行为给您造成的损害负责。 + 十三、第三方服务 + 您在本应用平台上使用第三方提供的产品或服务时,除遵守本协议约定外,还应遵守第三方的用户协议。 + 您已知悉并了解,本应用平台上所链接或嵌入的第三方服务并非本应用提供,如果您对第三方服务有异议,可以直接与第三方联系,也可以向本应用反馈。本应用将协助您联系第三方并转达您的需求和意见。 + 您确认并同意,在您使用第三方服务时,除非适用法律有明确规定,您和第三方的纠纷应由您和第三方解决。根据适用法律的规定,本应用需要承担责任的,本应用和第三方对可能出现的纠纷在法律规定和约定的范围内各自承担责任。 + 十四、协议的生效与变更 + 您使用本应用的服务即视为您已阅读本协议并接受本协议的约束。 + 本应用有权在必要时修改本协议条款。您可以在相关服务页面查阅最新版本的协议条款。 + 本协议条款变更后,如果您继续使用本应用提供的软件或服务,即视为您已接受修改后的协议。如果您不接受修改后的协议,应当停止使用本应用提供的软件或服务。 + 十五、服务的变更、中断、终止 + 本应用可能会对服务内容进行变更,也可能会中断、中止或终止服务。您理解并同意,本应用有权自主决定经营策略。 + 在本应用发生合并、分立、收购、资产转让时,本应用可向第三方转让本服务下相关资产;本应用也可在单方通知您后,将本协议下部分或全部服务转交由第三方运营或履行。具体受让主体以本应用通知的为准。 + 如发生下列任何一种情形,本应用有权不经通知而中断或终止向您提供的服务: + (1)根据法律规定您应提交真实信息,而您提供的个人资料不真实、或与注册时信息不一致又未能提供合理证明; + (2)您违反相关法律法规或本协议的约定; + (3)按照法律规定或主管部门的要求; + (4)出于安全的原因或其他必要的情形。 + 您有责任自行备份存储在本服务中的数据。如果您的服务被终止,本应用可以从服务器上永久地删除您的数据,但法律法规另有规定的除外。服务终止后,本应用没有义务向您返还数据。 + 十六、管辖与法律适用 + 本协议的成立、生效、履行、解释及纠纷解决,适用中华人民共和国大陆地区法律(不包括冲突法)。 + 本协议签订地为中华人民共和国上海市静安区。 + 若您和本应用之间发生任何纠纷或争议,首先应友好协商解决;协商不成的,您同意将纠纷或争议提交本协议签订地(即中国郑州市)有管辖权的人民法院管辖。 + 本协议所有条款的标题仅为阅读方便,本身并无实际涵义,不能作为本协议涵义解释的依据。 + 本协议条款无论因何种原因部分无效或不可执行,其余条款仍有效,对双方具有约束力。 + 十七、激活许可 + 导线助手内部有两种激活形式,激活后可以使用部分限制功能 + 1.绑定手机硬件(主板)形式,软件里可以自助激活,或找客服人员索要,换手机或更换主板需要重新购买 + 2.按服务周期购买形式,供购买的服务周期分为月、季、半年、年,分别对应30天、90天、180天和365天。服务到期后,部分功能将无法使用,您可以选择再次购买一个服务周期。 + 本平台可能会对服务内容进行变更,也可能会中断、中止或终止服务。您理解并同意,本平台有权自主决定经营策略。 + 如果发生本平台未能在服务周期内提供应许内容的情况,您有权申请退还剩余服务周期对应的款项。 + 如您因发布广告等其他垃圾信息被注销账号,本平台将不对您购买的服务周期另做补偿。 + 如果因安卓系统等第三方更新导致导线助手无法识别手机硬件信息而导致用户无法继续使用付费项目的,导线助手有权停止服务。当用户降级系统或撤销更新,手机回到购买时状态时,导线助手应继续免费提供相应的服务。 + + 导线助手对以上条款保有最终解释权。 + \ No newline at end of file diff --git a/app/src/main/assets/userAgreement_en.xml b/app/src/main/assets/userAgreement_en.xml new file mode 100644 index 0000000..a911fda --- /dev/null +++ b/app/src/main/assets/userAgreement_en.xml @@ -0,0 +1,116 @@ + + + This agreement is an agreement reached between the surveyor's mobile application (hereinafter referred to as surveyor or "this application") and the application user (hereinafter referred to as "user" or "you"). In order to use the services of the Surveyor Application, you should read and abide by this User Service Agreement (hereinafter referred to as "this Agreement"). Before using this application, please read carefully and fully understand the content of each clause, especially the clauses of exemption or limitation of liability, the provisions of jurisdiction and law, and the separate agreement to open or use a service. Limitations and disclaimers may be highlighted in bold or underlined. +Your use of the services of this application shall be deemed that you have carefully read and fully understood the contents of the foregoing agreement, and agree to be bound by the foregoing agreement. Unless you have read and accepted all the terms of this agreement, you are not authorized to use the services provided by this application. +If you are under the age of 18, please read this agreement with your legal guardian and pay special attention to the terms of use for minors. +Our products transmit information about apps that users have installed. Before using this information, we will obtain authorization from the user, and then proceed to the next step after permission is obtained. We will not use this information for any other illegal purpose. +I. User non-personalized information +We will collect non-personalized information of users through your IP address, such as your operating system version, operating environment, operator, etc., to optimize the pages displayed on your mobile phone screen. By collecting the above information, we also perform passenger traffic statistics to improve the management and service of this application. +This non-personally identifiable information helps us identify the most popular areas for surveyors and determine the effectiveness of our promotional activities. In addition, we may disclose this information to our customers so that they know how many people click on their ads. +Personal data +When you are using this application for user registration, participating in online forums and other activities, or when using specific services of this application, this application may ask you to provide some personal information through registration forms and other forms. These personal data may include: +Personal identification information: such as name, gender, age, date of birth, ID number (or passport number), telephone, mailing address, residential address, email address, etc .; +Personal background: such as occupation, education, income status, family status, credit history, etc .; +Personal experience: such as personal professional experience, social resume, etc. +In certain situations, you need to provide the required personal information in accordance with the requirements of this application before you can continue to use all or part of the services of this application. Please be sure to provide personal information in accordance with the requirements. Otherwise, you may not be able to continue +Use all or part of the services of this application. In the aforementioned situation, this app will remind and explain to you in advance. Unless applicable laws and regulations, government agencies, judicial authorities, or other third parties mandate this application +Request, this application will not conduct a substantive review of the information you provide. If the information you provide is wrong or inaccurate, you will be responsible for the resulting responsibility. +Please understand that without your consent and confirmation, this app will not use the data you provide for participating in specific activities of this app for purposes other than those for which you have agreed. Except when the disclosure is required by the government and the law in accordance with Article 6 below. +Information security +This application will strictly manage and protect the information you provide. This application will use corresponding technology to prevent your personal data from being lost, stolen or tampered with. However, due to the limitations of computer systems and network technologies, this application may be attacked or damaged by third parties, resulting in the user's personal information being maliciously tampered with, stolen or leaked. This application will take reasonable measures to prevent similar incidents, and Will cooperate with national authorities and third parties to investigate similar matters or initiate necessary actions (including but not limited to litigation, etc.). For information security issues that are not caused by the fault of this application, you agree to understand and waive any responsibility that this application may assume. +User rights +You have the following rights regarding your personal data: +Enquiries and requests for viewing at any time; +Request supplements or corrections at any time; +Request deletion at any time; +Request to stop computer processing and use. +V. Restricted Use Principle +This application can only use the collected personal data beyond the necessary scope if it meets one of the following conditions: +Has obtained your written consent; +To relieve you of imminent danger in life, body or property; +To prevent major harm to the rights and interests of others; +To promote the public interest without prejudice to your major interests. +6. Disclosure of Personal Information +When government agencies require this application to disclose personal data in accordance with legal procedures, this application will provide personal data at the request of law enforcement agencies or for public safety purposes. Any disclosure in this case shall be exempt from this application. +7. Cookies +Cookies refer to a technology. When a user uses this application without a cookie device, the server of this application will automatically send cookies to your browser and store them on your mobile hard disk. +These cookies are responsible for recording your various activities, personal data, browsing habits, spending habits and even credit history of your future access to this application. +Using cookies technology, this application can provide you with more thoughtful services. This application will use cookies to follow your preferences, so as to provide you with interesting information or storage passwords so that you do not have to repeat each time you visit this application enter password. +Protection of the privacy of minors +This application will establish and maintain reasonable procedures to protect the confidentiality and security of minors' personal data. This application solemnly declares that any minor under 18 years of age should participate in online activities in advance +Obtain the verifiable consent of the parent or his legal guardian (collectively referred to as the "guardian"). +The guardian should bear the primary responsibility for protecting the privacy of minors in the online environment. +This application collects the personal data of minors for the purpose of responding to the specific requirements of the minors. Once the response is completed, it will be deleted from the records without retaining these data for further use. +Without the consent of the guardian, this application will not use the personal data of the minor, nor will it disclose or transmit to any third party personal data that can identify the minor. If this application collects the name of a guardian or a minor or other online communication materials for the sole purpose of obtaining the consent of the guardian, if no consent has been obtained after a reasonable period of time, such information will be actively deleted from the record. +With the consent of the guardian of the minor, this app can collect the personal data of the minor, and this app will provide the guardian with: +Opportunities to review information collected from their children or guardians; +Opportunities to deny the further collection or use of the personal data of their children or guardians; +How to change or delete personal information of their children or guardians. +The guardian has the right to refuse this application to make further contact with its children or ward. +This application collects personal data of minors. These data are only used to protect the safety of minors when they participate in online activities, and not for other purposes. This app guarantees that minors will not be required to provide additional personal information as a condition to allow them to participate in online activities. +Nine, user illegal behavior +You must abide by laws and regulations when using this application service, and you must not use this application service to engage in any illegal acts, including but not limited to: +(1) Publishing, transmitting, disseminating, and storing contents that endanger national security and unity, undermine social stability, violate public order and good customs, insult, defamation, obscenity, violence, and any content that violates national laws and regulations; +(2) Publishing, transmitting, disseminating, and storing content that infringes on the intellectual property rights, trade secrets, and other legal rights of others; +(3) Fictional facts, concealing the truth to mislead and deceive others; +(4) Publishing, transmitting, and disseminating advertising information and spam; +(5) Other acts prohibited by laws and regulations. +If you violate the provisions of this article, the competent state authority may file a lawsuit, fine or take other sanctions against you, and ask for assistance or support for this application, and the resulting responsibility should be borne by you. If it causes damage, you should compensate it according to law, and this application will not bear any responsibility. +If you violate this agreement when you use this application service, this application has the right to make independent judgment and take technical measures to delete, block or disconnect the link. At the same time, depending on the nature of your behavior, this application has the right to take measures including, but not limited to, suspending or terminating services, restricting, freezing, or terminating registered accounts, etc., and pursue legal responsibilities. +If you violate this agreement and cause damage to any third party, you shall be solely responsible; if you cause losses to this application, you shall also pay compensation. +X. Compliance with laws and regulatory policies +In using this service, you should abide by relevant local laws and regulations and regulatory policies, and respect local morals and customs. If your actions violate local laws and regulations or ethics, you are solely responsible for this. +You should avoid getting the app involved in political and public events as a result of using the service, otherwise the app has the right to suspend or terminate the service to you. +Eleven, legal dissemination and handling of third-party complaints +The content (including but not limited to web pages, text, pictures, audio, video, graphics, etc.) that you send or disseminate through this service is your responsibility. +The content you send or disseminate should be from a legitimate source, the content is owned by you or you have been authorized by the right holder. +You agree that this application may use the content you send or distribute for the purpose of fulfilling this agreement or providing this service. +If the app receives notification from the right holder that the content you sent or transmitted violates its related rights, you agree that the app has the right to make independent judgments and take measures such as removing, blocking or disconnecting the link. +When using this service, you must not violate national laws and regulations and infringe on the legal rights and interests of others. You understand and agree that if you are complained of infringement by others or you have complained of infringement by others, this app has the right to change the subject, contact information, +The necessary information such as the content of the complaint is provided to other dispute parties or relevant departments in order to resolve the complaint dispute in a timely manner and protect the legitimate rights and interests of others. +12. Disclaimer +In addition to the exemption provided in Article 6 above, this application does not need to bear any responsibility in the following situations: +Risk factors such as force majeure or accidents cause the application service to be interrupted. +Any loss caused by you telling your user password to others or sharing a registered account with others, or your improper operation; +Any personal data leakage, loss, theft or tampering caused by computer force, force majeure that affects the normal operation of the network due to computer problems, hacking attacks, computer virus intrusion or outbreak, temporary shutdown due to government control, etc. +The user or the application's computer software, system, hardware, and communication lines have failed; +The web pages of this application have links to the web pages of other websites, including advertisements on the web pages. This application is not responsible for the content, privacy policies, or operations of any other website, or the behavior of the company that operates those websites. Please review their privacy policies before providing personal information to these websites and other websites linked to this application. +Users use the service in ways not authorized by this application; +Personal data leakage caused by other websites linked to this application and any legal disputes arising therefrom. +Loss or any dispute arising from the use of third party services by the user. Other situations beyond the control of this application or reasonably foreseeable. +Loss due to personal care or user's carelessness, wrong drawing, wrong stakeout method, etc. +Leaks due to users uploading confidential data +You understand and agree that in the process of using this service, you may encounter risks brought by network information or other user behaviors. This application is not responsible for the authenticity, applicability, legality of any information, and is not responsible for infringement Liability for damage caused to you. +Thirteenth party services +When you use products or services provided by third parties on this application platform, in addition to complying with this agreement, you should also comply with the third party's user agreement. +You know and understand that the third-party services linked or embedded on this application platform are not provided by this application. If you have any objection to the third-party services, you can directly contact the third party or provide feedback to this application. This application will assist you in contacting third parties and communicating your needs and opinions. +You acknowledge and agree that when you use third-party services, unless you are clearly required by applicable law, your dispute with the third party shall be resolved by you and the third party. According to the provisions of applicable laws, if this application needs to bear responsibility, this application and the third party shall bear their own responsibility for possible disputes within the scope stipulated by law and agreement. +14. Effectiveness and changes of the agreement +Your use of the services of this application is deemed that you have read this agreement and are bound by this agreement. +This application reserves the right to modify the terms of this agreement if necessary. You can find the latest version of the agreement terms on the relevant service page. +After changing the terms of this agreement, if you continue to use the software or services provided by this application, you are deemed to have accepted the modified agreement. If you do not accept the modified agreement, you should stop using the software or services provided by this application. + 15. Change, Interruption and Termination of Services +This application may change the content of the service, and may also interrupt, suspend or terminate the service. You understand and agree that this application has the right to determine its own business strategy. +When the application merges, splits, acquires, or transfers assets, the application can transfer the relevant assets under the service to a third party; the application can also transfer some or all of the services under this agreement to a third party for operation after the unilateral notification Or fulfill. The specific transferee is subject to the notification in this application. +This app reserves the right to interrupt or terminate the services provided to you without notice if any of the following situations occur: +(1) According to the law, you should submit true information, and the personal information you provided is not true, or is inconsistent with the information at the time of registration, and fails to provide reasonable proof; +(2) you violate the relevant laws and regulations or the agreement of this agreement; +(3) In accordance with legal regulations or requirements of competent authorities; +(4) For security reasons or other necessary situations. +You are responsible for backing up the data stored in the Service yourself. If your service is terminated, this application may permanently delete your data from the server, unless otherwise provided by laws and regulations. After the service is terminated, the app is not obliged to return data to you. +16.Jurisdiction and application of law +The establishment, entry into force, performance, interpretation and dispute resolution of this agreement shall be governed by the laws of the People's Republic of China (excluding conflict of laws). +This agreement was signed in Zhengzhou, People's Republic of China. +If there is any dispute or dispute between you and this application, it should be settled through friendly negotiation first; if the negotiation fails, you agree to submit the dispute or dispute to the jurisdiction of the people's court in the place where this agreement is signed (ie Zhengzhou, China). +The headings of all the terms of this agreement are for convenience only. They have no actual meaning and cannot be used as a basis for interpreting the meaning of this agreement. +No matter what the terms of this agreement are partially invalid or unenforceable, the remaining terms are still valid and binding on both parties. +Seventeen, pay +Charge for some functions in surveyor +Binding mobile phone hardware (motherboard), and automatically generate an activation code after payment, or ask for customer service personnel, you need to pay for a new phone or motherboard +This platform may change the content of the service, and may also interrupt, suspend or terminate the service. You understand and agree that the platform has the right to independently determine its business strategy. +In the event that the platform fails to provide the promised content during the service period, you have the right to apply for a refund of the amount corresponding to the remaining service period. +If your account is cancelled due to other spam information such as advertising, this platform will not make additional compensation for the service cycle you purchased. +If a third-party update such as the Android system prevents the surveyor from recognizing the hardware information of the phone and the user cannot continue to use the paid item, the surveyor has the right to stop the service. When the user downgrades the system or cancels the update, and the phone returns to the state it was in, the surveyor should continue to provide corresponding services for free. + +Surveyors reserve the right of final interpretation. + \ No newline at end of file diff --git a/app/src/main/design.sketch b/app/src/main/design.sketch new file mode 100644 index 0000000..244c413 Binary files /dev/null and b/app/src/main/design.sketch differ diff --git a/app/src/main/doc/测绘云流程图.mdj b/app/src/main/doc/测绘云流程图.mdj new file mode 100644 index 0000000..2ba0b6c --- /dev/null +++ b/app/src/main/doc/测绘云流程图.mdj @@ -0,0 +1,12064 @@ +{ + "_type": "Project", + "_id": "AAAAAAFF+h6SjaM2Hec=", + "name": "Untitled", + "ownedElements": [ + { + "_type": "UMLModel", + "_id": "AAAAAAFF+qBWK6M3Z8Y=", + "_parent": { + "$ref": "AAAAAAFF+h6SjaM2Hec=" + }, + "name": "Model", + "ownedElements": [ + { + "_type": "UMLClassDiagram", + "_id": "AAAAAAFF+qBtyKM79qY=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "Main", + "defaultDiagram": true + }, + { + "_type": "UMLUseCaseDiagram", + "_id": "AAAAAAF2+mcHh6BjMLk=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "UseCaseDiagram1", + "ownedViews": [ + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF2+mcRVqBoffw=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2+mcRVqBmJfY=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF2+mcRVqBpas8=", + "_parent": { + "$ref": "AAAAAAF2+mcRVqBoffw=" + }, + "model": { + "$ref": "AAAAAAF2+mcRVqBmJfY=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF2+mcRVqBq5fo=", + "_parent": { + "$ref": "AAAAAAF2+mcRVqBpas8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -208, + "top": -512, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+mcRVqBrTyU=", + "_parent": { + "$ref": "AAAAAAF2+mcRVqBpas8=" + }, + "font": "Arial;13;1", + "left": 86, + "top": 67.5, + "width": 72, + "height": 13, + "text": "doSurveyor" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+mcRV6BsSvw=", + "_parent": { + "$ref": "AAAAAAF2+mcRVqBpas8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -208, + "top": -512, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+mcRV6BtFlw=", + "_parent": { + "$ref": "AAAAAAF2+mcRVqBpas8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -208, + "top": -512, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 81, + "top": 60.5, + "width": 82.24267578125, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF2+mcRVqBq5fo=" + }, + "nameLabel": { + "$ref": "AAAAAAF2+mcRVqBrTyU=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF2+mcRV6BsSvw=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2+mcRV6BtFlw=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF2+mcRV6Bu9xo=", + "_parent": { + "$ref": "AAAAAAF2+mcRVqBoffw=" + }, + "model": { + "$ref": "AAAAAAF2+mcRVqBmJfY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -104, + "top": -256, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF2+mcRV6BvRaU=", + "_parent": { + "$ref": "AAAAAAF2+mcRVqBoffw=" + }, + "model": { + "$ref": "AAAAAAF2+mcRVqBmJfY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -104, + "top": -256, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF2+mcRV6BwxMs=", + "_parent": { + "$ref": "AAAAAAF2+mcRVqBoffw=" + }, + "model": { + "$ref": "AAAAAAF2+mcRVqBmJfY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -104, + "top": -256, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF2+mcRV6BxmtM=", + "_parent": { + "$ref": "AAAAAAF2+mcRVqBoffw=" + }, + "model": { + "$ref": "AAAAAAF2+mcRVqBmJfY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -104, + "top": -256, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF2+mcRV6ByVVo=", + "_parent": { + "$ref": "AAAAAAF2+mcRVqBoffw=" + }, + "model": { + "$ref": "AAAAAAF2+mcRVqBmJfY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -104, + "top": -256, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 64, + "top": 56, + "width": 116, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF2+mcRVqBpas8=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF2+mcRV6Bu9xo=" + }, + "operationCompartment": { + "$ref": "AAAAAAF2+mcRV6BvRaU=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF2+mcRV6BwxMs=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF2+mcRV6BxmtM=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF2+mcRV6ByVVo=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF2+mdRV6CXVyE=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2+mdRV6CVRE8=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF2+mdRV6CYpcE=", + "_parent": { + "$ref": "AAAAAAF2+mdRV6CXVyE=" + }, + "model": { + "$ref": "AAAAAAF2+mdRV6CVRE8=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF2+mdRV6CZOus=", + "_parent": { + "$ref": "AAAAAAF2+mdRV6CYpcE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -320, + "top": -272, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+mdRWKCaX8Q=", + "_parent": { + "$ref": "AAAAAAF2+mdRV6CYpcE=" + }, + "font": "Arial;13;1", + "left": 134.5, + "top": 147.5, + "width": 111, + "height": 13, + "text": "checkReadData" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+mdRWKCbUZ0=", + "_parent": { + "$ref": "AAAAAAF2+mdRV6CYpcE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -320, + "top": -272, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+mdRWKCcYaU=", + "_parent": { + "$ref": "AAAAAAF2+mdRV6CYpcE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -320, + "top": -272, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 129.5, + "top": 140.5, + "width": 121, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF2+mdRV6CZOus=" + }, + "nameLabel": { + "$ref": "AAAAAAF2+mdRWKCaX8Q=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF2+mdRWKCbUZ0=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2+mdRWKCcYaU=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF2+mdRWKCdx0Q=", + "_parent": { + "$ref": "AAAAAAF2+mdRV6CXVyE=" + }, + "model": { + "$ref": "AAAAAAF2+mdRV6CVRE8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -160, + "top": -136, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF2+mdRWKCeh8A=", + "_parent": { + "$ref": "AAAAAAF2+mdRV6CXVyE=" + }, + "model": { + "$ref": "AAAAAAF2+mdRV6CVRE8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -160, + "top": -136, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF2+mdRWKCfFBs=", + "_parent": { + "$ref": "AAAAAAF2+mdRV6CXVyE=" + }, + "model": { + "$ref": "AAAAAAF2+mdRV6CVRE8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -160, + "top": -136, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF2+mdRWKCgSTk=", + "_parent": { + "$ref": "AAAAAAF2+mdRV6CXVyE=" + }, + "model": { + "$ref": "AAAAAAF2+mdRV6CVRE8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -160, + "top": -136, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF2+mdRWKChHfo=", + "_parent": { + "$ref": "AAAAAAF2+mdRV6CXVyE=" + }, + "model": { + "$ref": "AAAAAAF2+mdRV6CVRE8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -160, + "top": -136, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 104, + "top": 136, + "width": 172, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF2+mdRV6CYpcE=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF2+mdRWKCdx0Q=" + }, + "operationCompartment": { + "$ref": "AAAAAAF2+mdRWKCeh8A=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF2+mdRWKCfFBs=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF2+mdRWKCgSTk=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF2+mdRWKChHfo=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF2+memFaDHSqA=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2+memFKDDSP0=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+memFaDI0Ig=", + "_parent": { + "$ref": "AAAAAAF2+memFaDHSqA=" + }, + "model": { + "$ref": "AAAAAAF2+memFKDDSP0=" + }, + "font": "Arial;13;0", + "left": 150, + "top": 97, + "width": 33.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF2+memFaDHSqA=" + }, + "edgePosition": 1, + "text": "+成功" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+memFqDJfpw=", + "_parent": { + "$ref": "AAAAAAF2+memFaDHSqA=" + }, + "model": { + "$ref": "AAAAAAF2+memFKDDSP0=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 177, + "top": 87, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+memFaDHSqA=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+memFqDKHFY=", + "_parent": { + "$ref": "AAAAAAF2+memFaDHSqA=" + }, + "model": { + "$ref": "AAAAAAF2+memFKDDSP0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 143, + "top": 116, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF2+memFaDHSqA=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+memFqDLP6k=", + "_parent": { + "$ref": "AAAAAAF2+memFaDHSqA=" + }, + "model": { + "$ref": "AAAAAAF2+memFaDE9N8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 164, + "top": 94, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+memFaDHSqA=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+memFqDMvYQ=", + "_parent": { + "$ref": "AAAAAAF2+memFaDHSqA=" + }, + "model": { + "$ref": "AAAAAAF2+memFaDE9N8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 175, + "top": 87, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF2+memFaDHSqA=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+memFqDNR6U=", + "_parent": { + "$ref": "AAAAAAF2+memFaDHSqA=" + }, + "model": { + "$ref": "AAAAAAF2+memFaDE9N8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 140, + "top": 109, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF2+memFaDHSqA=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+memFqDO+bI=", + "_parent": { + "$ref": "AAAAAAF2+memFaDHSqA=" + }, + "model": { + "$ref": "AAAAAAF2+memFaDFhUw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 168, + "top": 99, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+memFaDHSqA=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+memFqDP+fU=", + "_parent": { + "$ref": "AAAAAAF2+memFaDHSqA=" + }, + "model": { + "$ref": "AAAAAAF2+memFaDFhUw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 176, + "top": 89, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF2+memFaDHSqA=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+memFqDQoeo=", + "_parent": { + "$ref": "AAAAAAF2+memFaDHSqA=" + }, + "model": { + "$ref": "AAAAAAF2+memFaDFhUw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 150, + "top": 120, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF2+memFaDHSqA=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF2+memFqDRZjQ=", + "_parent": { + "$ref": "AAAAAAF2+memFaDHSqA=" + }, + "model": { + "$ref": "AAAAAAF2+memFaDE9N8=" + }, + "visible": false, + "font": "Arial;13;0", + "top": -184, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF2+memFqDSnhY=", + "_parent": { + "$ref": "AAAAAAF2+memFaDHSqA=" + }, + "model": { + "$ref": "AAAAAAF2+memFaDFhUw=" + }, + "visible": false, + "font": "Arial;13;0", + "top": -184, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF2+mdRV6CXVyE=" + }, + "tail": { + "$ref": "AAAAAAF2+mcRVqBoffw=" + }, + "lineStyle": 1, + "points": "136:91;174:135", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF2+memFaDI0Ig=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF2+memFqDJfpw=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2+memFqDKHFY=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF2+memFqDLP6k=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF2+memFqDMvYQ=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF2+memFqDNR6U=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF2+memFqDO+bI=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF2+memFqDP+fU=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF2+memFqDQoeo=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF2+memFqDRZjQ=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF2+memFqDSnhY=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF2+mkD1KIJSsk=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2+mkD1KIH4O4=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF2+mkD1KIKN1Y=", + "_parent": { + "$ref": "AAAAAAF2+mkD1KIJSsk=" + }, + "model": { + "$ref": "AAAAAAF2+mkD1KIH4O4=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF2+mkD1KILUvM=", + "_parent": { + "$ref": "AAAAAAF2+mkD1KIKN1Y=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1424, + "top": 800, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+mkD1aIMgv4=", + "_parent": { + "$ref": "AAAAAAF2+mkD1KIKN1Y=" + }, + "font": "Arial;13;1", + "left": 1116, + "top": 899.5, + "width": 98, + "height": 13, + "text": "SurveyorFailure" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+mkD1aINBig=", + "_parent": { + "$ref": "AAAAAAF2+mkD1KIKN1Y=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1424, + "top": 800, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+mkD1aIOP5w=", + "_parent": { + "$ref": "AAAAAAF2+mkD1KIKN1Y=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1424, + "top": 800, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 1111, + "top": 892.5, + "width": 108.9853515625, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF2+mkD1KILUvM=" + }, + "nameLabel": { + "$ref": "AAAAAAF2+mkD1aIMgv4=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF2+mkD1aINBig=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2+mkD1aIOP5w=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF2+mkD1aIPWB4=", + "_parent": { + "$ref": "AAAAAAF2+mkD1KIJSsk=" + }, + "model": { + "$ref": "AAAAAAF2+mkD1KIH4O4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 712, + "top": 400, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF2+mkD1aIQdMs=", + "_parent": { + "$ref": "AAAAAAF2+mkD1KIJSsk=" + }, + "model": { + "$ref": "AAAAAAF2+mkD1KIH4O4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 712, + "top": 400, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF2+mkD1aIRjCw=", + "_parent": { + "$ref": "AAAAAAF2+mkD1KIJSsk=" + }, + "model": { + "$ref": "AAAAAAF2+mkD1KIH4O4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 712, + "top": 400, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF2+mkD1aISQKk=", + "_parent": { + "$ref": "AAAAAAF2+mkD1KIJSsk=" + }, + "model": { + "$ref": "AAAAAAF2+mkD1KIH4O4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 712, + "top": 400, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF2+mkD1aITnSE=", + "_parent": { + "$ref": "AAAAAAF2+mkD1KIJSsk=" + }, + "model": { + "$ref": "AAAAAAF2+mkD1KIH4O4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 712, + "top": 400, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 1088, + "top": 888, + "width": 154, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF2+mkD1KIKN1Y=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF2+mkD1aIPWB4=" + }, + "operationCompartment": { + "$ref": "AAAAAAF2+mkD1aIQdMs=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF2+mkD1aIRjCw=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF2+mkD1aISQKk=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF2+mkD1aITnSE=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF2+mntyKOOOdo=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2+mntyKOMDSM=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF2+mntyKOPRlw=", + "_parent": { + "$ref": "AAAAAAF2+mntyKOOOdo=" + }, + "model": { + "$ref": "AAAAAAF2+mntyKOMDSM=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF2+mntyaOQPU8=", + "_parent": { + "$ref": "AAAAAAF2+mntyKOPRlw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1424, + "top": 272, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+mntyaORm4U=", + "_parent": { + "$ref": "AAAAAAF2+mntyKOPRlw=" + }, + "font": "Arial;13;1", + "left": 60, + "top": 235.5, + "width": 175, + "height": 13, + "text": "isHalfCycleZeroCheckReady" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+mntyaOSZzs=", + "_parent": { + "$ref": "AAAAAAF2+mntyKOPRlw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1424, + "top": 272, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+mntyaOTchM=", + "_parent": { + "$ref": "AAAAAAF2+mntyKOPRlw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1424, + "top": 272, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 55, + "top": 228.5, + "width": 186.2998046875, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF2+mntyaOQPU8=" + }, + "nameLabel": { + "$ref": "AAAAAAF2+mntyaORm4U=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF2+mntyaOSZzs=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2+mntyaOTchM=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF2+mntyaOUZOw=", + "_parent": { + "$ref": "AAAAAAF2+mntyKOOOdo=" + }, + "model": { + "$ref": "AAAAAAF2+mntyKOMDSM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -712, + "top": 136, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF2+mntyaOVKGs=", + "_parent": { + "$ref": "AAAAAAF2+mntyKOOOdo=" + }, + "model": { + "$ref": "AAAAAAF2+mntyKOMDSM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -712, + "top": 136, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF2+mntyaOWiEg=", + "_parent": { + "$ref": "AAAAAAF2+mntyKOOOdo=" + }, + "model": { + "$ref": "AAAAAAF2+mntyKOMDSM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -712, + "top": 136, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF2+mntyaOXRTU=", + "_parent": { + "$ref": "AAAAAAF2+mntyKOOOdo=" + }, + "model": { + "$ref": "AAAAAAF2+mntyKOMDSM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -712, + "top": 136, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF2+mntyaOYDwo=", + "_parent": { + "$ref": "AAAAAAF2+mntyKOOOdo=" + }, + "model": { + "$ref": "AAAAAAF2+mntyKOMDSM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -712, + "top": 136, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 16, + "top": 224, + "width": 263, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF2+mntyKOPRlw=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF2+mntyaOUZOw=" + }, + "operationCompartment": { + "$ref": "AAAAAAF2+mntyaOVKGs=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF2+mntyaOWiEg=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF2+mntyaOXRTU=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF2+mntyaOYDwo=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF2+moC5KQPBko=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2+moC5KQL07Q=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+moC5KQQceg=", + "_parent": { + "$ref": "AAAAAAF2+moC5KQPBko=" + }, + "model": { + "$ref": "AAAAAAF2+moC5KQL07Q=" + }, + "font": "Arial;13;0", + "left": 152, + "top": 197, + "width": 59.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF2+moC5KQPBko=" + }, + "edgePosition": 1, + "text": "+通过检测" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+moC5KQRJ/g=", + "_parent": { + "$ref": "AAAAAAF2+moC5KQPBko=" + }, + "model": { + "$ref": "AAAAAAF2+moC5KQL07Q=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 195, + "top": 203, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+moC5KQPBko=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+moC5KQSRfg=", + "_parent": { + "$ref": "AAAAAAF2+moC5KQPBko=" + }, + "model": { + "$ref": "AAAAAAF2+moC5KQL07Q=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 154, + "top": 184, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF2+moC5KQPBko=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+moC5KQT7kk=", + "_parent": { + "$ref": "AAAAAAF2+moC5KQPBko=" + }, + "model": { + "$ref": "AAAAAAF2+moC5KQMlXg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 182, + "top": 194, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+moC5KQPBko=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+moC5KQU3fw=", + "_parent": { + "$ref": "AAAAAAF2+moC5KQPBko=" + }, + "model": { + "$ref": "AAAAAAF2+moC5KQMlXg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 193, + "top": 202, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF2+moC5KQPBko=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+moC5KQV8KI=", + "_parent": { + "$ref": "AAAAAAF2+moC5KQPBko=" + }, + "model": { + "$ref": "AAAAAAF2+moC5KQMlXg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 159, + "top": 179, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF2+moC5KQPBko=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+moC5KQWyNA=", + "_parent": { + "$ref": "AAAAAAF2+moC5KQPBko=" + }, + "model": { + "$ref": "AAAAAAF2+moC5KQNhhs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 180, + "top": 199, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+moC5KQPBko=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+moC5KQXfeg=", + "_parent": { + "$ref": "AAAAAAF2+moC5KQPBko=" + }, + "model": { + "$ref": "AAAAAAF2+moC5KQNhhs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 193, + "top": 203, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF2+moC5KQPBko=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+moC5KQYo5E=", + "_parent": { + "$ref": "AAAAAAF2+moC5KQPBko=" + }, + "model": { + "$ref": "AAAAAAF2+moC5KQNhhs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 153, + "top": 192, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF2+moC5KQPBko=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF2+moC5KQZHbs=", + "_parent": { + "$ref": "AAAAAAF2+moC5KQPBko=" + }, + "model": { + "$ref": "AAAAAAF2+moC5KQMlXg=" + }, + "visible": false, + "font": "Arial;13;0", + "top": -184, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF2+moC5KQar0s=", + "_parent": { + "$ref": "AAAAAAF2+moC5KQPBko=" + }, + "model": { + "$ref": "AAAAAAF2+moC5KQNhhs=" + }, + "visible": false, + "font": "Arial;13;0", + "top": -184, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF2+mntyKOOOdo=" + }, + "tail": { + "$ref": "AAAAAAF2+mdRV6CXVyE=" + }, + "lineStyle": 1, + "points": "180:171;156:223", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF2+moC5KQQceg=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF2+moC5KQRJ/g=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2+moC5KQSRfg=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF2+moC5KQT7kk=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF2+moC5KQU3fw=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF2+moC5KQV8KI=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF2+moC5KQWyNA=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF2+moC5KQXfeg=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF2+moC5KQYo5E=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF2+moC5KQZHbs=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF2+moC5KQar0s=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF2+mq6h6SuwYA=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2+mq6h6Ss6fQ=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF2+mq6h6Sv0Ic=", + "_parent": { + "$ref": "AAAAAAF2+mq6h6SuwYA=" + }, + "model": { + "$ref": "AAAAAAF2+mq6h6Ss6fQ=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF2+mq6iKSwPhE=", + "_parent": { + "$ref": "AAAAAAF2+mq6h6Sv0Ic=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 400, + "top": 1008, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+mq6iKSxaL0=", + "_parent": { + "$ref": "AAAAAAF2+mq6h6Sv0Ic=" + }, + "font": "Arial;13;1", + "left": 1035.5, + "top": 763.5, + "width": 136, + "height": 13, + "text": "doDeleteCurrentCycle" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+mq6iKSyJ1A=", + "_parent": { + "$ref": "AAAAAAF2+mq6h6Sv0Ic=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 400, + "top": 1008, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+mq6iKSzjnI=", + "_parent": { + "$ref": "AAAAAAF2+mq6h6Sv0Ic=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 400, + "top": 1008, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 1030.5, + "top": 756.5, + "width": 146.5380859375, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF2+mq6iKSwPhE=" + }, + "nameLabel": { + "$ref": "AAAAAAF2+mq6iKSxaL0=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF2+mq6iKSyJ1A=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2+mq6iKSzjnI=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF2+mq6iKS0rdE=", + "_parent": { + "$ref": "AAAAAAF2+mq6h6SuwYA=" + }, + "model": { + "$ref": "AAAAAAF2+mq6h6Ss6fQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 200, + "top": 504, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF2+mq6iKS1PJ4=", + "_parent": { + "$ref": "AAAAAAF2+mq6h6SuwYA=" + }, + "model": { + "$ref": "AAAAAAF2+mq6h6Ss6fQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 200, + "top": 504, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF2+mq6iKS2Mes=", + "_parent": { + "$ref": "AAAAAAF2+mq6h6SuwYA=" + }, + "model": { + "$ref": "AAAAAAF2+mq6h6Ss6fQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 200, + "top": 504, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF2+mq6iKS3ZVY=", + "_parent": { + "$ref": "AAAAAAF2+mq6h6SuwYA=" + }, + "model": { + "$ref": "AAAAAAF2+mq6h6Ss6fQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 200, + "top": 504, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF2+mq6iKS4Kqg=", + "_parent": { + "$ref": "AAAAAAF2+mq6h6SuwYA=" + }, + "model": { + "$ref": "AAAAAAF2+mq6h6Ss6fQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 200, + "top": 504, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 1000, + "top": 752, + "width": 207, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF2+mq6h6Sv0Ic=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF2+mq6iKS0rdE=" + }, + "operationCompartment": { + "$ref": "AAAAAAF2+mq6iKS1PJ4=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF2+mq6iKS2Mes=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF2+mq6iKS3ZVY=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF2+mq6iKS4Kqg=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF2+mrOv6VKaJI=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2+mrOv6VGNxM=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+mrOv6VLPnA=", + "_parent": { + "$ref": "AAAAAAF2+mrOv6VKaJI=" + }, + "model": { + "$ref": "AAAAAAF2+mrOv6VGNxM=" + }, + "font": "Arial;13;0", + "left": 535, + "top": 107, + "width": 267.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF2+mrOv6VKaJI=" + }, + "edgePosition": 1, + "text": "+未通过检测提示目标两次读数超限请重新测量" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+mrOv6VMamw=", + "_parent": { + "$ref": "AAAAAAF2+mrOv6VKaJI=" + }, + "model": { + "$ref": "AAAAAAF2+mrOv6VGNxM=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 667, + "top": 92, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+mrOv6VKaJI=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+mrOv6VN3Ss=", + "_parent": { + "$ref": "AAAAAAF2+mrOv6VKaJI=" + }, + "model": { + "$ref": "AAAAAAF2+mrOv6VGNxM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 669, + "top": 136, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF2+mrOv6VKaJI=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+mrOv6VO7dE=", + "_parent": { + "$ref": "AAAAAAF2+mrOv6VKaJI=" + }, + "model": { + "$ref": "AAAAAAF2+mrOv6VHNRw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 301, + "top": 125, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+mrOv6VKaJI=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+mrOv6VPrV4=", + "_parent": { + "$ref": "AAAAAAF2+mrOv6VKaJI=" + }, + "model": { + "$ref": "AAAAAAF2+mrOv6VHNRw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 302, + "top": 112, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF2+mrOv6VKaJI=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+mrOv6VQWxU=", + "_parent": { + "$ref": "AAAAAAF2+mrOv6VKaJI=" + }, + "model": { + "$ref": "AAAAAAF2+mrOv6VHNRw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 298, + "top": 153, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF2+mrOv6VKaJI=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+mrOv6VRiCs=", + "_parent": { + "$ref": "AAAAAAF2+mrOv6VKaJI=" + }, + "model": { + "$ref": "AAAAAAF2+mrOv6VIVq0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1036, + "top": 88, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+mrOv6VKaJI=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+mrOv6VSM/w=", + "_parent": { + "$ref": "AAAAAAF2+mrOv6VKaJI=" + }, + "model": { + "$ref": "AAAAAAF2+mrOv6VIVq0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1033, + "top": 75, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF2+mrOv6VKaJI=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+mrOv6VTlbY=", + "_parent": { + "$ref": "AAAAAAF2+mrOv6VKaJI=" + }, + "model": { + "$ref": "AAAAAAF2+mrOv6VIVq0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1042, + "top": 115, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF2+mrOv6VKaJI=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF2+mrOv6VUz6Q=", + "_parent": { + "$ref": "AAAAAAF2+mrOv6VKaJI=" + }, + "model": { + "$ref": "AAAAAAF2+mrOv6VHNRw=" + }, + "visible": false, + "font": "Arial;13;0", + "top": -184, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF2+mrOv6VV49g=", + "_parent": { + "$ref": "AAAAAAF2+mrOv6VKaJI=" + }, + "model": { + "$ref": "AAAAAAF2+mrOv6VIVq0=" + }, + "visible": false, + "font": "Arial;13;0", + "top": -184, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF2+mwCOqh1UGk=" + }, + "tail": { + "$ref": "AAAAAAF2+mdRV6CXVyE=" + }, + "lineStyle": 1, + "points": "276:148;1063:108", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF2+mrOv6VLPnA=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF2+mrOv6VMamw=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2+mrOv6VN3Ss=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF2+mrOv6VO7dE=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF2+mrOv6VPrV4=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF2+mrOv6VQWxU=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF2+mrOv6VRiCs=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF2+mrOv6VSM/w=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF2+mrOv6VTlbY=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF2+mrOv6VUz6Q=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF2+mrOv6VV49g=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF2+mvXKaZ9JcA=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2+mvXKaZ71tg=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF2+mvXKaZ+a7s=", + "_parent": { + "$ref": "AAAAAAF2+mvXKaZ9JcA=" + }, + "model": { + "$ref": "AAAAAAF2+mvXKaZ71tg=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF2+mvXKaZ/YSQ=", + "_parent": { + "$ref": "AAAAAAF2+mvXKaZ+a7s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1664, + "top": 544, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+mvXKaaAI84=", + "_parent": { + "$ref": "AAAAAAF2+mvXKaZ+a7s=" + }, + "font": "Arial;13;1", + "left": 73, + "top": 643.5, + "width": 124, + "height": 13, + "text": "checkHalfCycleZero" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+mvXKaaB8qQ=", + "_parent": { + "$ref": "AAAAAAF2+mvXKaZ+a7s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1664, + "top": 544, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+mvXKaaCW0M=", + "_parent": { + "$ref": "AAAAAAF2+mvXKaZ+a7s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1664, + "top": 544, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 68, + "top": 636.5, + "width": 134.28076171875, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF2+mvXKaZ/YSQ=" + }, + "nameLabel": { + "$ref": "AAAAAAF2+mvXKaaAI84=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF2+mvXKaaB8qQ=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2+mvXKaaCW0M=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF2+mvXKaaD/VM=", + "_parent": { + "$ref": "AAAAAAF2+mvXKaZ9JcA=" + }, + "model": { + "$ref": "AAAAAAF2+mvXKaZ71tg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -832, + "top": 272, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF2+mvXKaaE660=", + "_parent": { + "$ref": "AAAAAAF2+mvXKaZ9JcA=" + }, + "model": { + "$ref": "AAAAAAF2+mvXKaZ71tg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -832, + "top": 272, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF2+mvXKaaFnDM=", + "_parent": { + "$ref": "AAAAAAF2+mvXKaZ9JcA=" + }, + "model": { + "$ref": "AAAAAAF2+mvXKaZ71tg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -832, + "top": 272, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF2+mvXKaaGOXs=", + "_parent": { + "$ref": "AAAAAAF2+mvXKaZ9JcA=" + }, + "model": { + "$ref": "AAAAAAF2+mvXKaZ71tg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -832, + "top": 272, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF2+mvXKaaHvGE=", + "_parent": { + "$ref": "AAAAAAF2+mvXKaZ9JcA=" + }, + "model": { + "$ref": "AAAAAAF2+mvXKaZ71tg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -832, + "top": 272, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 40, + "top": 632, + "width": 190, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF2+mvXKaZ+a7s=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF2+mvXKaaD/VM=" + }, + "operationCompartment": { + "$ref": "AAAAAAF2+mvXKaaE660=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF2+mvXKaaFnDM=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF2+mvXKaaGOXs=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF2+mvXKaaHvGE=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF2+mvs0qc0M6s=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2+mvs0qcw0ng=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+mvs0qc1wM8=", + "_parent": { + "$ref": "AAAAAAF2+mvs0qc0M6s=" + }, + "model": { + "$ref": "AAAAAAF2+mvs0qcw0ng=" + }, + "font": "Arial;13;0", + "left": 125, + "top": 439, + "width": 59.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF2+mvs0qc0M6s=" + }, + "edgePosition": 1, + "text": "+满足条件" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+mvs0qc202A=", + "_parent": { + "$ref": "AAAAAAF2+mvs0qc0M6s=" + }, + "model": { + "$ref": "AAAAAAF2+mvs0qcw0ng=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 169, + "top": 439, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+mvs0qc0M6s=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+mvs0qc3e6M=", + "_parent": { + "$ref": "AAAAAAF2+mvs0qc0M6s=" + }, + "model": { + "$ref": "AAAAAAF2+mvs0qcw0ng=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 125, + "top": 438, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF2+mvs0qc0M6s=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+mvs0qc4Drs=", + "_parent": { + "$ref": "AAAAAAF2+mvs0qc0M6s=" + }, + "model": { + "$ref": "AAAAAAF2+mvs0qcx6HM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 160, + "top": 279, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+mvs0qc0M6s=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+mvs0qc5vMI=", + "_parent": { + "$ref": "AAAAAAF2+mvs0qc0M6s=" + }, + "model": { + "$ref": "AAAAAAF2+mvs0qcx6HM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 173, + "top": 282, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF2+mvs0qc0M6s=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+mvs0qc6Rdg=", + "_parent": { + "$ref": "AAAAAAF2+mvs0qc0M6s=" + }, + "model": { + "$ref": "AAAAAAF2+mvs0qcx6HM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 132, + "top": 274, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF2+mvs0qc0M6s=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+mvs0qc7l5k=", + "_parent": { + "$ref": "AAAAAAF2+mvs0qc0M6s=" + }, + "model": { + "$ref": "AAAAAAF2+mvs0qcyuaY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 150, + "top": 599, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+mvs0qc0M6s=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+mvs0qc8asw=", + "_parent": { + "$ref": "AAAAAAF2+mvs0qc0M6s=" + }, + "model": { + "$ref": "AAAAAAF2+mvs0qcyuaY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 164, + "top": 597, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF2+mvs0qc0M6s=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+mvs0qc9HoU=", + "_parent": { + "$ref": "AAAAAAF2+mvs0qc0M6s=" + }, + "model": { + "$ref": "AAAAAAF2+mvs0qcyuaY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 123, + "top": 602, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF2+mvs0qc0M6s=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF2+mvs0qc+Nck=", + "_parent": { + "$ref": "AAAAAAF2+mvs0qc0M6s=" + }, + "model": { + "$ref": "AAAAAAF2+mvs0qcx6HM=" + }, + "visible": false, + "font": "Arial;13;0", + "top": -184, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF2+mvs0qc/jzw=", + "_parent": { + "$ref": "AAAAAAF2+mvs0qc0M6s=" + }, + "model": { + "$ref": "AAAAAAF2+mvs0qcyuaY=" + }, + "visible": false, + "font": "Arial;13;0", + "top": -184, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF2+mvXKaZ9JcA=" + }, + "tail": { + "$ref": "AAAAAAF2+mntyKOOOdo=" + }, + "lineStyle": 1, + "points": "146:259;135:631", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF2+mvs0qc1wM8=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF2+mvs0qc202A=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2+mvs0qc3e6M=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF2+mvs0qc4Drs=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF2+mvs0qc5vMI=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF2+mvs0qc6Rdg=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF2+mvs0qc7l5k=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF2+mvs0qc8asw=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF2+mvs0qc9HoU=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF2+mvs0qc+Nck=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF2+mvs0qc/jzw=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF2+mwCOqh1UGk=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2+mwCOqhz6ko=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF2+mwCO6h22P0=", + "_parent": { + "$ref": "AAAAAAF2+mwCOqh1UGk=" + }, + "model": { + "$ref": "AAAAAAF2+mwCOqhz6ko=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF2+mwCO6h3Ono=", + "_parent": { + "$ref": "AAAAAAF2+mwCO6h22P0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 928, + "top": -640, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+mwCO6h4ZQA=", + "_parent": { + "$ref": "AAAAAAF2+mwCO6h22P0=" + }, + "font": "Arial;13;1", + "left": 1084, + "top": 99.5, + "width": 62, + "height": 13, + "text": "Idle" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+mwCO6h565A=", + "_parent": { + "$ref": "AAAAAAF2+mwCO6h22P0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 928, + "top": -640, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+mwCO6h6b3M=", + "_parent": { + "$ref": "AAAAAAF2+mwCO6h22P0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 928, + "top": -640, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 1079, + "top": 92.5, + "width": 72, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF2+mwCO6h3Ono=" + }, + "nameLabel": { + "$ref": "AAAAAAF2+mwCO6h4ZQA=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF2+mwCO6h565A=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2+mwCO6h6b3M=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF2+mwCO6h75qU=", + "_parent": { + "$ref": "AAAAAAF2+mwCOqh1UGk=" + }, + "model": { + "$ref": "AAAAAAF2+mwCOqhz6ko=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 464, + "top": -320, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF2+mwCO6h8WBM=", + "_parent": { + "$ref": "AAAAAAF2+mwCOqh1UGk=" + }, + "model": { + "$ref": "AAAAAAF2+mwCOqhz6ko=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 464, + "top": -320, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF2+mwCO6h9qfA=", + "_parent": { + "$ref": "AAAAAAF2+mwCOqh1UGk=" + }, + "model": { + "$ref": "AAAAAAF2+mwCOqhz6ko=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 464, + "top": -320, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF2+mwCO6h+cG0=", + "_parent": { + "$ref": "AAAAAAF2+mwCOqh1UGk=" + }, + "model": { + "$ref": "AAAAAAF2+mwCOqhz6ko=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 464, + "top": -320, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF2+mwCO6h/PzE=", + "_parent": { + "$ref": "AAAAAAF2+mwCOqh1UGk=" + }, + "model": { + "$ref": "AAAAAAF2+mwCOqhz6ko=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 464, + "top": -320, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 1064, + "top": 88, + "width": 102, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF2+mwCO6h22P0=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF2+mwCO6h75qU=" + }, + "operationCompartment": { + "$ref": "AAAAAAF2+mwCO6h8WBM=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF2+mwCO6h9qfA=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF2+mwCO6h+cG0=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF2+mwCO6h/PzE=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF2+mw/iqlHhw8=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2+mw/ialD1P0=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+mw/iqlICrw=", + "_parent": { + "$ref": "AAAAAAF2+mw/iqlHhw8=" + }, + "model": { + "$ref": "AAAAAAF2+mw/ialD1P0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1093, + "top": 430, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF2+mw/iqlHhw8=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+mw/iqlJZUA=", + "_parent": { + "$ref": "AAAAAAF2+mw/iqlHhw8=" + }, + "model": { + "$ref": "AAAAAAF2+mw/ialD1P0=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1078, + "top": 430, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+mw/iqlHhw8=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+mw/iqlKnVA=", + "_parent": { + "$ref": "AAAAAAF2+mw/iqlHhw8=" + }, + "model": { + "$ref": "AAAAAAF2+mw/ialD1P0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1122, + "top": 431, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF2+mw/iqlHhw8=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+mw/iqlLEKc=", + "_parent": { + "$ref": "AAAAAAF2+mw/iqlHhw8=" + }, + "model": { + "$ref": "AAAAAAF2+mw/iqlEWtE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1088, + "top": 718, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+mw/iqlHhw8=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+mw/iqlMafs=", + "_parent": { + "$ref": "AAAAAAF2+mw/iqlHhw8=" + }, + "model": { + "$ref": "AAAAAAF2+mw/iqlEWtE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1075, + "top": 716, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF2+mw/iqlHhw8=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+mw/iqlNnYc=", + "_parent": { + "$ref": "AAAAAAF2+mw/iqlHhw8=" + }, + "model": { + "$ref": "AAAAAAF2+mw/iqlEWtE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1115, + "top": 723, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF2+mw/iqlHhw8=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+mw/iqlOQrw=", + "_parent": { + "$ref": "AAAAAAF2+mw/iqlHhw8=" + }, + "model": { + "$ref": "AAAAAAF2+mw/iqlF64M=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1098, + "top": 142, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+mw/iqlHhw8=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+mw/iqlPlDs=", + "_parent": { + "$ref": "AAAAAAF2+mw/iqlHhw8=" + }, + "model": { + "$ref": "AAAAAAF2+mw/iqlF64M=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1085, + "top": 144, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF2+mw/iqlHhw8=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+mw/iqlQdOY=", + "_parent": { + "$ref": "AAAAAAF2+mw/iqlHhw8=" + }, + "model": { + "$ref": "AAAAAAF2+mw/iqlF64M=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1126, + "top": 138, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF2+mw/iqlHhw8=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF2+mw/iqlRtpI=", + "_parent": { + "$ref": "AAAAAAF2+mw/iqlHhw8=" + }, + "model": { + "$ref": "AAAAAAF2+mw/iqlEWtE=" + }, + "visible": false, + "font": "Arial;13;0", + "top": -184, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF2+mw/iqlS6xc=", + "_parent": { + "$ref": "AAAAAAF2+mw/iqlHhw8=" + }, + "model": { + "$ref": "AAAAAAF2+mw/iqlF64M=" + }, + "visible": false, + "font": "Arial;13;0", + "top": -184, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF2+mwCOqh1UGk=" + }, + "tail": { + "$ref": "AAAAAAF2+mq6h6SuwYA=" + }, + "lineStyle": 1, + "points": "1103:751;1114:123", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF2+mw/iqlICrw=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF2+mw/iqlJZUA=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2+mw/iqlKnVA=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF2+mw/iqlLEKc=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF2+mw/iqlMafs=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF2+mw/iqlNnYc=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF2+mw/iqlOQrw=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF2+mw/iqlPlDs=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF2+mw/iqlQdOY=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF2+mw/iqlRtpI=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF2+mw/iqlS6xc=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF2+m3Ng67WXiU=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2+m3Ng67UQ3Q=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF2+m3Ng67Xic8=", + "_parent": { + "$ref": "AAAAAAF2+m3Ng67WXiU=" + }, + "model": { + "$ref": "AAAAAAF2+m3Ng67UQ3Q=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF2+m3Ng67YH00=", + "_parent": { + "$ref": "AAAAAAF2+m3Ng67Xic8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1744, + "top": 368, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+m3Ng67ZMKU=", + "_parent": { + "$ref": "AAAAAAF2+m3Ng67Xic8=" + }, + "font": "Arial;13;1", + "left": 261, + "top": 355.5, + "width": 105, + "height": 13, + "text": "isReady2CCheck" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+m3Ng67aYAg=", + "_parent": { + "$ref": "AAAAAAF2+m3Ng67Xic8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1744, + "top": 368, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+m3Ng67b7tk=", + "_parent": { + "$ref": "AAAAAAF2+m3Ng67Xic8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1744, + "top": 368, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 256, + "top": 348.5, + "width": 115.498046875, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF2+m3Ng67YH00=" + }, + "nameLabel": { + "$ref": "AAAAAAF2+m3Ng67ZMKU=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF2+m3Ng67aYAg=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2+m3Ng67b7tk=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF2+m3Ng67cquY=", + "_parent": { + "$ref": "AAAAAAF2+m3Ng67WXiU=" + }, + "model": { + "$ref": "AAAAAAF2+m3Ng67UQ3Q=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -872, + "top": 184, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF2+m3NhK7dOGY=", + "_parent": { + "$ref": "AAAAAAF2+m3Ng67WXiU=" + }, + "model": { + "$ref": "AAAAAAF2+m3Ng67UQ3Q=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -872, + "top": 184, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF2+m3NhK7ePSk=", + "_parent": { + "$ref": "AAAAAAF2+m3Ng67WXiU=" + }, + "model": { + "$ref": "AAAAAAF2+m3Ng67UQ3Q=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -872, + "top": 184, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF2+m3NhK7f3Bg=", + "_parent": { + "$ref": "AAAAAAF2+m3Ng67WXiU=" + }, + "model": { + "$ref": "AAAAAAF2+m3Ng67UQ3Q=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -872, + "top": 184, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF2+m3NhK7gUrI=", + "_parent": { + "$ref": "AAAAAAF2+m3Ng67WXiU=" + }, + "model": { + "$ref": "AAAAAAF2+m3Ng67UQ3Q=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -872, + "top": 184, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 232, + "top": 344, + "width": 163, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF2+m3Ng67Xic8=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF2+m3Ng67cquY=" + }, + "operationCompartment": { + "$ref": "AAAAAAF2+m3NhK7dOGY=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF2+m3NhK7ePSk=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF2+m3NhK7f3Bg=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF2+m3NhK7gUrI=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF2+m3lu6/DOUc=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2+m3lu6+/SvE=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m3lu6/E2Do=", + "_parent": { + "$ref": "AAAAAAF2+m3lu6/DOUc=" + }, + "model": { + "$ref": "AAAAAAF2+m3lu6+/SvE=" + }, + "font": "Arial;13;0", + "left": 181, + "top": 491, + "width": 59.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF2+m3lu6/DOUc=" + }, + "edgePosition": 1, + "text": "+通过检测" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m3lu6/FDO0=", + "_parent": { + "$ref": "AAAAAAF2+m3lu6/DOUc=" + }, + "model": { + "$ref": "AAAAAAF2+m3lu6+/SvE=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 197, + "top": 483, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+m3lu6/DOUc=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m3lu6/Gi08=", + "_parent": { + "$ref": "AAAAAAF2+m3lu6/DOUc=" + }, + "model": { + "$ref": "AAAAAAF2+m3lu6+/SvE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 235, + "top": 506, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF2+m3lu6/DOUc=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m3lu6/Hf44=", + "_parent": { + "$ref": "AAAAAAF2+m3lu6/DOUc=" + }, + "model": { + "$ref": "AAAAAAF2+m3lu6/AYdA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 146, + "top": 595, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+m3lu6/DOUc=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m3lu6/IqJw=", + "_parent": { + "$ref": "AAAAAAF2+m3lu6/DOUc=" + }, + "model": { + "$ref": "AAAAAAF2+m3lu6/AYdA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 135, + "top": 586, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF2+m3lu6/DOUc=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m3lu6/JdkM=", + "_parent": { + "$ref": "AAAAAAF2+m3lu6/DOUc=" + }, + "model": { + "$ref": "AAAAAAF2+m3lu6/AYdA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 167, + "top": 613, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF2+m3lu6/DOUc=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m3lu6/KoQg=", + "_parent": { + "$ref": "AAAAAAF2+m3lu6/DOUc=" + }, + "model": { + "$ref": "AAAAAAF2+m3lu6/BCoQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 275, + "top": 387, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+m3lu6/DOUc=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m3lu6/LFko=", + "_parent": { + "$ref": "AAAAAAF2+m3lu6/DOUc=" + }, + "model": { + "$ref": "AAAAAAF2+m3lu6/BCoQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 263, + "top": 382, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF2+m3lu6/DOUc=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m3lu6/MT0A=", + "_parent": { + "$ref": "AAAAAAF2+m3lu6/DOUc=" + }, + "model": { + "$ref": "AAAAAAF2+m3lu6/BCoQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 301, + "top": 397, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF2+m3lu6/DOUc=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF2+m3lu6/N6Ng=", + "_parent": { + "$ref": "AAAAAAF2+m3lu6/DOUc=" + }, + "model": { + "$ref": "AAAAAAF2+m3lu6/AYdA=" + }, + "visible": false, + "font": "Arial;13;0", + "top": -184, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF2+m3lu6/Ooek=", + "_parent": { + "$ref": "AAAAAAF2+m3lu6/DOUc=" + }, + "model": { + "$ref": "AAAAAAF2+m3lu6/BCoQ=" + }, + "visible": false, + "font": "Arial;13;0", + "top": -184, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF2+m3Ng67WXiU=" + }, + "tail": { + "$ref": "AAAAAAF2+mvXKaZ9JcA=" + }, + "lineStyle": 1, + "points": "145:631;302:379", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF2+m3lu6/E2Do=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF2+m3lu6/FDO0=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2+m3lu6/Gi08=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF2+m3lu6/Hf44=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF2+m3lu6/IqJw=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF2+m3lu6/JdkM=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF2+m3lu6/KoQg=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF2+m3lu6/LFko=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF2+m3lu6/MT0A=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF2+m3lu6/N6Ng=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF2+m3lu6/Ooek=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF2+m4Cd7DQ378=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2+m4Cd7DMOyM=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m4Cd7DRAVE=", + "_parent": { + "$ref": "AAAAAAF2+m4Cd7DQ378=" + }, + "model": { + "$ref": "AAAAAAF2+m4Cd7DMOyM=" + }, + "font": "Arial;13;0", + "left": 579, + "top": 687, + "width": 72.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF2+m4Cd7DQ378=" + }, + "edgePosition": 1, + "text": "+未通过检测" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m4Cd7DScfk=", + "_parent": { + "$ref": "AAAAAAF2+m4Cd7DQ378=" + }, + "model": { + "$ref": "AAAAAAF2+m4Cd7DMOyM=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 617, + "top": 672, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+m4Cd7DQ378=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m4Cd7DTMTY=", + "_parent": { + "$ref": "AAAAAAF2+m4Cd7DQ378=" + }, + "model": { + "$ref": "AAAAAAF2+m4Cd7DMOyM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 612, + "top": 716, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF2+m4Cd7DQ378=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m4Cd7DUVcI=", + "_parent": { + "$ref": "AAAAAAF2+m4Cd7DQ378=" + }, + "model": { + "$ref": "AAAAAAF2+m4Cd7DNh98=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 257, + "top": 643, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+m4Cd7DQ378=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m4Cd7DVlvI=", + "_parent": { + "$ref": "AAAAAAF2+m4Cd7DQ378=" + }, + "model": { + "$ref": "AAAAAAF2+m4Cd7DNh98=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 261, + "top": 630, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF2+m4Cd7DQ378=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m4Cd7DWLMQ=", + "_parent": { + "$ref": "AAAAAAF2+m4Cd7DQ378=" + }, + "model": { + "$ref": "AAAAAAF2+m4Cd7DNh98=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 249, + "top": 670, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF2+m4Cd7DQ378=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m4Cd7DXhyw=", + "_parent": { + "$ref": "AAAAAAF2+m4Cd7DQ378=" + }, + "model": { + "$ref": "AAAAAAF2+m4Cd7DOnkA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 975, + "top": 731, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+m4Cd7DQ378=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m4Cd7DYDkU=", + "_parent": { + "$ref": "AAAAAAF2+m4Cd7DQ378=" + }, + "model": { + "$ref": "AAAAAAF2+m4Cd7DOnkA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 974, + "top": 718, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF2+m4Cd7DQ378=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m4Cd7DZShc=", + "_parent": { + "$ref": "AAAAAAF2+m4Cd7DQ378=" + }, + "model": { + "$ref": "AAAAAAF2+m4Cd7DOnkA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 975, + "top": 759, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF2+m4Cd7DQ378=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF2+m4Cd7DaWVU=", + "_parent": { + "$ref": "AAAAAAF2+m4Cd7DQ378=" + }, + "model": { + "$ref": "AAAAAAF2+m4Cd7DNh98=" + }, + "visible": false, + "font": "Arial;13;0", + "top": -184, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF2+m4Cd7Dbwu8=", + "_parent": { + "$ref": "AAAAAAF2+m4Cd7DQ378=" + }, + "model": { + "$ref": "AAAAAAF2+m4Cd7DOnkA=" + }, + "visible": false, + "font": "Arial;13;0", + "top": -184, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF2+mq6h6SuwYA=" + }, + "tail": { + "$ref": "AAAAAAF2+mvXKaZ9JcA=" + }, + "lineStyle": 1, + "points": "230:661;999:756", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF2+m4Cd7DRAVE=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF2+m4Cd7DScfk=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2+m4Cd7DTMTY=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF2+m4Cd7DUVcI=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF2+m4Cd7DVlvI=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF2+m4Cd7DWLMQ=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF2+m4Cd7DXhyw=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF2+m4Cd7DYDkU=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF2+m4Cd7DZShc=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF2+m4Cd7DaWVU=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF2+m4Cd7Dbwu8=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF2+m6507J/Zuo=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2+m650rJ78WY=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m6507KAvO0=", + "_parent": { + "$ref": "AAAAAAF2+m6507J/Zuo=" + }, + "model": { + "$ref": "AAAAAAF2+m650rJ78WY=" + }, + "font": "Arial;13;0", + "left": 215, + "top": 282, + "width": 46.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF2+m6507J/Zuo=" + }, + "edgePosition": 1, + "text": "+不满足" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m6507KBRDQ=", + "_parent": { + "$ref": "AAAAAAF2+m6507J/Zuo=" + }, + "model": { + "$ref": "AAAAAAF2+m650rJ78WY=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 247, + "top": 270, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+m6507J/Zuo=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m6507KCcvI=", + "_parent": { + "$ref": "AAAAAAF2+m6507J/Zuo=" + }, + "model": { + "$ref": "AAAAAAF2+m650rJ78WY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 221, + "top": 307, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF2+m6507J/Zuo=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m6507KDh+o=", + "_parent": { + "$ref": "AAAAAAF2+m6507J/Zuo=" + }, + "model": { + "$ref": "AAAAAAF2+m650rJ8zw4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 201, + "top": 256, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+m6507J/Zuo=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m6507KECBE=", + "_parent": { + "$ref": "AAAAAAF2+m6507J/Zuo=" + }, + "model": { + "$ref": "AAAAAAF2+m650rJ8zw4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 211, + "top": 246, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF2+m6507J/Zuo=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m6507KFH0o=", + "_parent": { + "$ref": "AAAAAAF2+m6507J/Zuo=" + }, + "model": { + "$ref": "AAAAAAF2+m650rJ8zw4=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 182, + "top": 275, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF2+m6507J/Zuo=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m6507KGgnk=", + "_parent": { + "$ref": "AAAAAAF2+m6507J/Zuo=" + }, + "model": { + "$ref": "AAAAAAF2+m650rJ9BDM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 275, + "top": 309, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+m6507J/Zuo=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m6507KHvxk=", + "_parent": { + "$ref": "AAAAAAF2+m6507J/Zuo=" + }, + "model": { + "$ref": "AAAAAAF2+m650rJ9BDM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 281, + "top": 297, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF2+m6507J/Zuo=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m6507KIBfg=", + "_parent": { + "$ref": "AAAAAAF2+m6507J/Zuo=" + }, + "model": { + "$ref": "AAAAAAF2+m650rJ9BDM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 263, + "top": 334, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF2+m6507J/Zuo=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF2+m6507KJ9Bk=", + "_parent": { + "$ref": "AAAAAAF2+m6507J/Zuo=" + }, + "model": { + "$ref": "AAAAAAF2+m650rJ8zw4=" + }, + "visible": false, + "font": "Arial;13;0", + "top": -184, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF2+m6507KKLw0=", + "_parent": { + "$ref": "AAAAAAF2+m6507J/Zuo=" + }, + "model": { + "$ref": "AAAAAAF2+m650rJ9BDM=" + }, + "visible": false, + "font": "Arial;13;0", + "top": -184, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF2+m3Ng67WXiU=" + }, + "tail": { + "$ref": "AAAAAAF2+mntyKOOOdo=" + }, + "lineStyle": 1, + "points": "172:259;288:343", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF2+m6507KAvO0=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF2+m6507KBRDQ=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2+m6507KCcvI=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF2+m6507KDh+o=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF2+m6507KECBE=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF2+m6507KFH0o=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF2+m6507KGgnk=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF2+m6507KHvxk=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF2+m6507KIBfg=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF2+m6507KJ9Bk=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF2+m6507KKLw0=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF2+m+73bQ4m2I=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2+m+73LQ2jlo=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF2+m+73bQ51AA=", + "_parent": { + "$ref": "AAAAAAF2+m+73bQ4m2I=" + }, + "model": { + "$ref": "AAAAAAF2+m+73LQ2jlo=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF2+m+73bQ6nXw=", + "_parent": { + "$ref": "AAAAAAF2+m+73bQ51AA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1408, + "top": -752, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+m+73bQ744s=", + "_parent": { + "$ref": "AAAAAAF2+m+73bQ51AA=" + }, + "font": "Arial;13;1", + "left": 492, + "top": 203.5, + "width": 62, + "height": 13, + "text": "check2C" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+m+73bQ8TTM=", + "_parent": { + "$ref": "AAAAAAF2+m+73bQ51AA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1408, + "top": -752, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+m+73bQ9+Mw=", + "_parent": { + "$ref": "AAAAAAF2+m+73bQ51AA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1408, + "top": -752, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 487, + "top": 196.5, + "width": 72, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF2+m+73bQ6nXw=" + }, + "nameLabel": { + "$ref": "AAAAAAF2+m+73bQ744s=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF2+m+73bQ8TTM=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2+m+73bQ9+Mw=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF2+m+73bQ+qzE=", + "_parent": { + "$ref": "AAAAAAF2+m+73bQ4m2I=" + }, + "model": { + "$ref": "AAAAAAF2+m+73LQ2jlo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -704, + "top": -376, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF2+m+73bQ/52s=", + "_parent": { + "$ref": "AAAAAAF2+m+73bQ4m2I=" + }, + "model": { + "$ref": "AAAAAAF2+m+73LQ2jlo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -704, + "top": -376, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF2+m+73bRAXBQ=", + "_parent": { + "$ref": "AAAAAAF2+m+73bQ4m2I=" + }, + "model": { + "$ref": "AAAAAAF2+m+73LQ2jlo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -704, + "top": -376, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF2+m+73bRBpqA=", + "_parent": { + "$ref": "AAAAAAF2+m+73bQ4m2I=" + }, + "model": { + "$ref": "AAAAAAF2+m+73LQ2jlo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -704, + "top": -376, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF2+m+73bRCY/s=", + "_parent": { + "$ref": "AAAAAAF2+m+73bQ4m2I=" + }, + "model": { + "$ref": "AAAAAAF2+m+73LQ2jlo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -704, + "top": -376, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 472, + "top": 192, + "width": 102, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF2+m+73bQ51AA=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF2+m+73bQ+qzE=" + }, + "operationCompartment": { + "$ref": "AAAAAAF2+m+73bQ/52s=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF2+m+73bRAXBQ=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF2+m+73bRBpqA=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF2+m+73bRCY/s=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF2+m/aRbZnCCE=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2+m/aRbZjsQw=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m/aRbZoX2c=", + "_parent": { + "$ref": "AAAAAAF2+m/aRbZnCCE=" + }, + "model": { + "$ref": "AAAAAAF2+m/aRbZjsQw=" + }, + "font": "Arial;13;0", + "left": 379, + "top": 266, + "width": 59.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF2+m/aRbZnCCE=" + }, + "edgePosition": 1, + "text": "+满足条件" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m/aRbZpYP8=", + "_parent": { + "$ref": "AAAAAAF2+m/aRbZnCCE=" + }, + "model": { + "$ref": "AAAAAAF2+m/aRbZjsQw=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 399, + "top": 254, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+m/aRbZnCCE=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m/aRbZq7mM=", + "_parent": { + "$ref": "AAAAAAF2+m/aRbZnCCE=" + }, + "model": { + "$ref": "AAAAAAF2+m/aRbZjsQw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 425, + "top": 291, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF2+m/aRbZnCCE=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m/aRbZrfg0=", + "_parent": { + "$ref": "AAAAAAF2+m/aRbZnCCE=" + }, + "model": { + "$ref": "AAAAAAF2+m/aRbZkwdI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 350, + "top": 309, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+m/aRbZnCCE=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m/aRbZsE+c=", + "_parent": { + "$ref": "AAAAAAF2+m/aRbZnCCE=" + }, + "model": { + "$ref": "AAAAAAF2+m/aRbZkwdI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 344, + "top": 297, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF2+m/aRbZnCCE=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m/aRbZtnbI=", + "_parent": { + "$ref": "AAAAAAF2+m/aRbZnCCE=" + }, + "model": { + "$ref": "AAAAAAF2+m/aRbZkwdI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 362, + "top": 334, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF2+m/aRbZnCCE=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m/aRbZuIZ4=", + "_parent": { + "$ref": "AAAAAAF2+m/aRbZnCCE=" + }, + "model": { + "$ref": "AAAAAAF2+m/aRbZlRAA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 467, + "top": 224, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+m/aRbZnCCE=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m/aRrZv/So=", + "_parent": { + "$ref": "AAAAAAF2+m/aRbZnCCE=" + }, + "model": { + "$ref": "AAAAAAF2+m/aRbZlRAA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 457, + "top": 214, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF2+m/aRbZnCCE=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+m/aRrZw+Wc=", + "_parent": { + "$ref": "AAAAAAF2+m/aRbZnCCE=" + }, + "model": { + "$ref": "AAAAAAF2+m/aRbZlRAA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 486, + "top": 243, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF2+m/aRbZnCCE=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF2+m/aRrZxzMY=", + "_parent": { + "$ref": "AAAAAAF2+m/aRbZnCCE=" + }, + "model": { + "$ref": "AAAAAAF2+m/aRbZkwdI=" + }, + "visible": false, + "font": "Arial;13;0", + "top": -184, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF2+m/aRrZyYfg=", + "_parent": { + "$ref": "AAAAAAF2+m/aRbZnCCE=" + }, + "model": { + "$ref": "AAAAAAF2+m/aRbZlRAA=" + }, + "visible": false, + "font": "Arial;13;0", + "top": -184, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF2+m+73bQ4m2I=" + }, + "tail": { + "$ref": "AAAAAAF2+m3Ng67WXiU=" + }, + "lineStyle": 1, + "points": "338:343;497:227", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF2+m/aRbZoX2c=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF2+m/aRbZpYP8=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2+m/aRbZq7mM=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF2+m/aRbZrfg0=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF2+m/aRbZsE+c=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF2+m/aRbZtnbI=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF2+m/aRbZuIZ4=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF2+m/aRrZv/So=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF2+m/aRrZw+Wc=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF2+m/aRrZxzMY=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF2+m/aRrZyYfg=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF2+nB7EcWvyhg=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2+nB7EcWt+n8=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF2+nB7EsWwrGE=", + "_parent": { + "$ref": "AAAAAAF2+nB7EcWvyhg=" + }, + "model": { + "$ref": "AAAAAAF2+nB7EcWt+n8=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF2+nB7EsWxRXc=", + "_parent": { + "$ref": "AAAAAAF2+nB7EsWwrGE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1632, + "top": 896, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+nB7EsWyp7A=", + "_parent": { + "$ref": "AAAAAAF2+nB7EsWwrGE=" + }, + "font": "Arial;13;1", + "left": 606.5, + "top": 627.5, + "width": 151, + "height": 13, + "text": "isSingleCycleCompleted" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+nB7EsWzuj0=", + "_parent": { + "$ref": "AAAAAAF2+nB7EsWwrGE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1632, + "top": 896, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+nB7EsW0vEM=", + "_parent": { + "$ref": "AAAAAAF2+nB7EsWwrGE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1632, + "top": 896, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 601.5, + "top": 620.5, + "width": 161.708984375, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF2+nB7EsWxRXc=" + }, + "nameLabel": { + "$ref": "AAAAAAF2+nB7EsWyp7A=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF2+nB7EsWzuj0=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2+nB7EsW0vEM=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF2+nB7EsW1O74=", + "_parent": { + "$ref": "AAAAAAF2+nB7EcWvyhg=" + }, + "model": { + "$ref": "AAAAAAF2+nB7EcWt+n8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -816, + "top": 448, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF2+nB7EsW24Ak=", + "_parent": { + "$ref": "AAAAAAF2+nB7EcWvyhg=" + }, + "model": { + "$ref": "AAAAAAF2+nB7EcWt+n8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -816, + "top": 448, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF2+nB7EsW3La4=", + "_parent": { + "$ref": "AAAAAAF2+nB7EcWvyhg=" + }, + "model": { + "$ref": "AAAAAAF2+nB7EcWt+n8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -816, + "top": 448, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF2+nB7EsW4CYw=", + "_parent": { + "$ref": "AAAAAAF2+nB7EcWvyhg=" + }, + "model": { + "$ref": "AAAAAAF2+nB7EcWt+n8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -816, + "top": 448, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF2+nB7EsW5ziA=", + "_parent": { + "$ref": "AAAAAAF2+nB7EcWvyhg=" + }, + "model": { + "$ref": "AAAAAAF2+nB7EcWt+n8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -816, + "top": 448, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 568, + "top": 616, + "width": 228, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF2+nB7EsWwrGE=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF2+nB7EsW1O74=" + }, + "operationCompartment": { + "$ref": "AAAAAAF2+nB7EsW24Ak=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF2+nB7EsW3La4=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF2+nB7EsW4CYw=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF2+nB7EsW5ziA=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF2+nC6Y8gyCOM=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2+nC6YsguVIY=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nC6Y8gzGbk=", + "_parent": { + "$ref": "AAAAAAF2+nC6Y8gyCOM=" + }, + "model": { + "$ref": "AAAAAAF2+nC6YsguVIY=" + }, + "font": "Arial;13;0", + "left": 423, + "top": 400, + "width": 59.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF2+nC6Y8gyCOM=" + }, + "edgePosition": 1, + "text": "+通过检测" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nC6Y8g0Btw=", + "_parent": { + "$ref": "AAAAAAF2+nC6Y8gyCOM=" + }, + "model": { + "$ref": "AAAAAAF2+nC6YsguVIY=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 466, + "top": 406, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+nC6Y8gyCOM=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nC6Y8g1YTc=", + "_parent": { + "$ref": "AAAAAAF2+nC6Y8gyCOM=" + }, + "model": { + "$ref": "AAAAAAF2+nC6YsguVIY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 425, + "top": 389, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF2+nC6Y8gyCOM=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nC6Y8g2LKo=", + "_parent": { + "$ref": "AAAAAAF2+nC6Y8gyCOM=" + }, + "model": { + "$ref": "AAAAAAF2+nC6Y8gvJw0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 517, + "top": 250, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+nC6Y8gyCOM=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nC6Y8g3efU=", + "_parent": { + "$ref": "AAAAAAF2+nC6Y8gyCOM=" + }, + "model": { + "$ref": "AAAAAAF2+nC6Y8gvJw0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 528, + "top": 258, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF2+nC6Y8gyCOM=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nC6Y8g4m7s=", + "_parent": { + "$ref": "AAAAAAF2+nC6Y8gyCOM=" + }, + "model": { + "$ref": "AAAAAAF2+nC6Y8gvJw0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 493, + "top": 235, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF2+nC6Y8gyCOM=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nC6Y8g5UNs=", + "_parent": { + "$ref": "AAAAAAF2+nC6Y8gyCOM=" + }, + "model": { + "$ref": "AAAAAAF2+nC6Y8gwxpA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 389, + "top": 551, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+nC6Y8gyCOM=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nC6Y8g6C1c=", + "_parent": { + "$ref": "AAAAAAF2+nC6Y8gyCOM=" + }, + "model": { + "$ref": "AAAAAAF2+nC6Y8gwxpA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 402, + "top": 554, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF2+nC6Y8gyCOM=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nC6Y8g7AZQ=", + "_parent": { + "$ref": "AAAAAAF2+nC6Y8gyCOM=" + }, + "model": { + "$ref": "AAAAAAF2+nC6Y8gwxpA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 362, + "top": 544, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF2+nC6Y8gyCOM=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF2+nC6Y8g8U9U=", + "_parent": { + "$ref": "AAAAAAF2+nC6Y8gyCOM=" + }, + "model": { + "$ref": "AAAAAAF2+nC6Y8gvJw0=" + }, + "visible": false, + "font": "Arial;13;0", + "top": -184, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF2+nC6ZMg9Wfs=", + "_parent": { + "$ref": "AAAAAAF2+nC6Y8gyCOM=" + }, + "model": { + "$ref": "AAAAAAF2+nC6Y8gwxpA=" + }, + "visible": false, + "font": "Arial;13;0", + "top": -184, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF2+nIha+T0PKc=" + }, + "tail": { + "$ref": "AAAAAAF2+m+73bQ4m2I=" + }, + "lineStyle": 1, + "points": "514:227;365:575", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF2+nC6Y8gzGbk=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF2+nC6Y8g0Btw=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2+nC6Y8g1YTc=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF2+nC6Y8g2LKo=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF2+nC6Y8g3efU=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF2+nC6Y8g4m7s=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF2+nC6Y8g5UNs=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF2+nC6Y8g6C1c=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF2+nC6Y8g7AZQ=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF2+nC6Y8g8U9U=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF2+nC6ZMg9Wfs=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF2+nIha+T0PKc=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2+nIhauTyfGU=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF2+nIha+T1GkI=", + "_parent": { + "$ref": "AAAAAAF2+nIha+T0PKc=" + }, + "model": { + "$ref": "AAAAAAF2+nIhauTyfGU=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF2+nIha+T2NuQ=", + "_parent": { + "$ref": "AAAAAAF2+nIha+T1GkI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1504, + "top": -304, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+nIha+T3MZE=", + "_parent": { + "$ref": "AAAAAAF2+nIha+T1GkI=" + }, + "font": "Arial;13;1", + "left": 291, + "top": 587.5, + "width": 133, + "height": 13, + "text": "doRecordClean" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+nIha+T42aU=", + "_parent": { + "$ref": "AAAAAAF2+nIha+T1GkI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1504, + "top": -304, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+nIha+T5gIo=", + "_parent": { + "$ref": "AAAAAAF2+nIha+T1GkI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1504, + "top": -304, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 286, + "top": 580.5, + "width": 143, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF2+nIha+T2NuQ=" + }, + "nameLabel": { + "$ref": "AAAAAAF2+nIha+T3MZE=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF2+nIha+T42aU=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2+nIha+T5gIo=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF2+nIha+T6I/s=", + "_parent": { + "$ref": "AAAAAAF2+nIha+T0PKc=" + }, + "model": { + "$ref": "AAAAAAF2+nIhauTyfGU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -752, + "top": -152, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF2+nIha+T7f88=", + "_parent": { + "$ref": "AAAAAAF2+nIha+T0PKc=" + }, + "model": { + "$ref": "AAAAAAF2+nIhauTyfGU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -752, + "top": -152, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF2+nIha+T8JnQ=", + "_parent": { + "$ref": "AAAAAAF2+nIha+T0PKc=" + }, + "model": { + "$ref": "AAAAAAF2+nIhauTyfGU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -752, + "top": -152, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF2+nIha+T97Co=", + "_parent": { + "$ref": "AAAAAAF2+nIha+T0PKc=" + }, + "model": { + "$ref": "AAAAAAF2+nIhauTyfGU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -752, + "top": -152, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF2+nIha+T+yMo=", + "_parent": { + "$ref": "AAAAAAF2+nIha+T0PKc=" + }, + "model": { + "$ref": "AAAAAAF2+nIhauTyfGU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -752, + "top": -152, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 256, + "top": 576, + "width": 203, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF2+nIha+T1GkI=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF2+nIha+T6I/s=" + }, + "operationCompartment": { + "$ref": "AAAAAAF2+nIha+T7f88=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF2+nIha+T8JnQ=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF2+nIha+T97Co=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF2+nIha+T+yMo=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF2+nJuA+o1SCQ=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2+nJuA+oxvHQ=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nJuA+o2CrU=", + "_parent": { + "$ref": "AAAAAAF2+nJuA+o1SCQ=" + }, + "model": { + "$ref": "AAAAAAF2+nJuA+oxvHQ=" + }, + "font": "Arial;13;0", + "left": 313, + "top": 468, + "width": 72.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF2+nJuA+o1SCQ=" + }, + "edgePosition": 1, + "text": "+不满足条件" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nJuA+o3+MU=", + "_parent": { + "$ref": "AAAAAAF2+nJuA+o1SCQ=" + }, + "model": { + "$ref": "AAAAAAF2+nJuA+oxvHQ=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 364, + "top": 465, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+nJuA+o1SCQ=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nJuA+o4dNs=", + "_parent": { + "$ref": "AAAAAAF2+nJuA+o1SCQ=" + }, + "model": { + "$ref": "AAAAAAF2+nJuA+oxvHQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 320, + "top": 473, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF2+nJuA+o1SCQ=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nJuBOo5VPw=", + "_parent": { + "$ref": "AAAAAAF2+nJuA+o1SCQ=" + }, + "model": { + "$ref": "AAAAAAF2+nJuA+oyVzg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 335, + "top": 395, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+nJuA+o1SCQ=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nJuBOo6yNA=", + "_parent": { + "$ref": "AAAAAAF2+nJuA+o1SCQ=" + }, + "model": { + "$ref": "AAAAAAF2+nJuA+oyVzg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 349, + "top": 395, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF2+nJuA+o1SCQ=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nJuBOo7uM0=", + "_parent": { + "$ref": "AAAAAAF2+nJuA+o1SCQ=" + }, + "model": { + "$ref": "AAAAAAF2+nJuA+oyVzg=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 307, + "top": 396, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF2+nJuA+o1SCQ=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nJuBOo8SD0=", + "_parent": { + "$ref": "AAAAAAF2+nJuA+o1SCQ=" + }, + "model": { + "$ref": "AAAAAAF2+nJuA+ozWP8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 363, + "top": 540, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+nJuA+o1SCQ=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nJuBOo9a+E=", + "_parent": { + "$ref": "AAAAAAF2+nJuA+o1SCQ=" + }, + "model": { + "$ref": "AAAAAAF2+nJuA+ozWP8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 376, + "top": 535, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF2+nJuA+o1SCQ=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nJuBOo+Ck4=", + "_parent": { + "$ref": "AAAAAAF2+nJuA+o1SCQ=" + }, + "model": { + "$ref": "AAAAAAF2+nJuA+ozWP8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 337, + "top": 550, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF2+nJuA+o1SCQ=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF2+nJuBOo/2Pk=", + "_parent": { + "$ref": "AAAAAAF2+nJuA+o1SCQ=" + }, + "model": { + "$ref": "AAAAAAF2+nJuA+oyVzg=" + }, + "visible": false, + "font": "Arial;13;0", + "top": -184, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF2+nJuBOpAePc=", + "_parent": { + "$ref": "AAAAAAF2+nJuA+o1SCQ=" + }, + "model": { + "$ref": "AAAAAAF2+nJuA+ozWP8=" + }, + "visible": false, + "font": "Arial;13;0", + "top": -184, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF2+nIha+T0PKc=" + }, + "tail": { + "$ref": "AAAAAAF2+m3Ng67WXiU=" + }, + "lineStyle": 1, + "points": "316:379;354:575", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF2+nJuA+o2CrU=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF2+nJuA+o3+MU=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2+nJuA+o4dNs=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF2+nJuBOo5VPw=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF2+nJuBOo6yNA=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF2+nJuBOo7uM0=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF2+nJuBOo8SD0=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF2+nJuBOo9a+E=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF2+nJuBOo+Ck4=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF2+nJuBOo/2Pk=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF2+nJuBOpAePc=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF2+nQJoxCDdok=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2+nQJohB/pjc=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nQJoxCEJ/4=", + "_parent": { + "$ref": "AAAAAAF2+nQJoxCDdok=" + }, + "model": { + "$ref": "AAAAAAF2+nQJohB/pjc=" + }, + "font": "Arial;13;0", + "left": 629, + "top": 524, + "width": 46.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF2+nQJoxCDdok=" + }, + "edgePosition": 1, + "text": "+未通过" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nQJoxCFIAk=", + "_parent": { + "$ref": "AAAAAAF2+nQJoxCDdok=" + }, + "model": { + "$ref": "AAAAAAF2+nQJohB/pjc=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 637, + "top": 526, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+nQJoxCDdok=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nQJoxCGzfs=", + "_parent": { + "$ref": "AAAAAAF2+nQJoxCDdok=" + }, + "model": { + "$ref": "AAAAAAF2+nQJohB/pjc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 681, + "top": 521, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF2+nQJoxCDdok=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nQJoxCHSY0=", + "_parent": { + "$ref": "AAAAAAF2+nQJoxCDdok=" + }, + "model": { + "$ref": "AAAAAAF2+nQJohCAKVI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 660, + "top": 585, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+nQJoxCDdok=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nQJoxCIs3Y=", + "_parent": { + "$ref": "AAAAAAF2+nQJoxCDdok=" + }, + "model": { + "$ref": "AAAAAAF2+nQJohCAKVI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 647, + "top": 584, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF2+nQJoxCDdok=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nQJoxCJhbQ=", + "_parent": { + "$ref": "AAAAAAF2+nQJoxCDdok=" + }, + "model": { + "$ref": "AAAAAAF2+nQJohCAKVI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 688, + "top": 585, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF2+nQJoxCDdok=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nQJoxCKIrE=", + "_parent": { + "$ref": "AAAAAAF2+nQJoxCDdok=" + }, + "model": { + "$ref": "AAAAAAF2+nQJohCBbxs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 644, + "top": 464, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+nQJoxCDdok=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nQJoxCLFVw=", + "_parent": { + "$ref": "AAAAAAF2+nQJoxCDdok=" + }, + "model": { + "$ref": "AAAAAAF2+nQJohCBbxs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 631, + "top": 468, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF2+nQJoxCDdok=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nQJoxCMLbI=", + "_parent": { + "$ref": "AAAAAAF2+nQJoxCDdok=" + }, + "model": { + "$ref": "AAAAAAF2+nQJohCBbxs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 671, + "top": 456, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF2+nQJoxCDdok=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF2+nQJoxCNff4=", + "_parent": { + "$ref": "AAAAAAF2+nQJoxCDdok=" + }, + "model": { + "$ref": "AAAAAAF2+nQJohCAKVI=" + }, + "visible": false, + "font": "Arial;13;0", + "top": -184, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF2+nQJoxCO0rE=", + "_parent": { + "$ref": "AAAAAAF2+nQJoxCDdok=" + }, + "model": { + "$ref": "AAAAAAF2+nQJohCBbxs=" + }, + "visible": false, + "font": "Arial;13;0", + "top": -184, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF2+n8X9HOVNKs=" + }, + "tail": { + "$ref": "AAAAAAF2+nB7EcWvyhg=" + }, + "lineStyle": 1, + "points": "679:615;656:443", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF2+nQJoxCEJ/4=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF2+nQJoxCFIAk=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2+nQJoxCGzfs=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF2+nQJoxCHSY0=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF2+nQJoxCIs3Y=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF2+nQJoxCJhbQ=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF2+nQJoxCKIrE=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF2+nQJoxCLFVw=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF2+nQJoxCMLbI=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF2+nQJoxCNff4=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF2+nQJoxCO0rE=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF2+nRKkx5Vaw4=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2+nRKkx5T21c=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF2+nRKkx5Wffo=", + "_parent": { + "$ref": "AAAAAAF2+nRKkx5Vaw4=" + }, + "model": { + "$ref": "AAAAAAF2+nRKkx5T21c=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF2+nRKkx5X/zo=", + "_parent": { + "$ref": "AAAAAAF2+nRKkx5Wffo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1904, + "top": 720, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+nRKkx5Y40M=", + "_parent": { + "$ref": "AAAAAAF2+nRKkx5Wffo=" + }, + "font": "Arial;13;1", + "left": 894, + "top": 531.5, + "width": 110, + "height": 13, + "text": "checkSingleCycle" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+nRKlB5ZYRU=", + "_parent": { + "$ref": "AAAAAAF2+nRKkx5Wffo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1904, + "top": 720, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+nRKlB5aPXo=", + "_parent": { + "$ref": "AAAAAAF2+nRKkx5Wffo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -1904, + "top": 720, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 889, + "top": 524.5, + "width": 120.55712890625, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF2+nRKkx5X/zo=" + }, + "nameLabel": { + "$ref": "AAAAAAF2+nRKkx5Y40M=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF2+nRKlB5ZYRU=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2+nRKlB5aPXo=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF2+nRKlB5bsGs=", + "_parent": { + "$ref": "AAAAAAF2+nRKkx5Vaw4=" + }, + "model": { + "$ref": "AAAAAAF2+nRKkx5T21c=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -952, + "top": 360, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF2+nRKlB5calY=", + "_parent": { + "$ref": "AAAAAAF2+nRKkx5Vaw4=" + }, + "model": { + "$ref": "AAAAAAF2+nRKkx5T21c=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -952, + "top": 360, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF2+nRKlB5doOk=", + "_parent": { + "$ref": "AAAAAAF2+nRKkx5Vaw4=" + }, + "model": { + "$ref": "AAAAAAF2+nRKkx5T21c=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -952, + "top": 360, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF2+nRKlB5eoWY=", + "_parent": { + "$ref": "AAAAAAF2+nRKkx5Vaw4=" + }, + "model": { + "$ref": "AAAAAAF2+nRKkx5T21c=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -952, + "top": 360, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF2+nRKlB5fYaI=", + "_parent": { + "$ref": "AAAAAAF2+nRKkx5Vaw4=" + }, + "model": { + "$ref": "AAAAAAF2+nRKkx5T21c=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -952, + "top": 360, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 864, + "top": 520, + "width": 170, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF2+nRKkx5Wffo=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF2+nRKlB5bsGs=" + }, + "operationCompartment": { + "$ref": "AAAAAAF2+nRKlB5calY=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF2+nRKlB5doOk=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF2+nRKlB5eoWY=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF2+nRKlB5fYaI=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF2+nS1vB//BAk=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2+nS1vB/7hWk=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nS1vCAA1/w=", + "_parent": { + "$ref": "AAAAAAF2+nS1vB//BAk=" + }, + "model": { + "$ref": "AAAAAAF2+nS1vB/7hWk=" + }, + "font": "Arial;13;0", + "left": 779, + "top": 564, + "width": 59.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF2+nS1vB//BAk=" + }, + "edgePosition": 1, + "text": "+满足条件" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nS1vSABc/8=", + "_parent": { + "$ref": "AAAAAAF2+nS1vB//BAk=" + }, + "model": { + "$ref": "AAAAAAF2+nS1vB/7hWk=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 803, + "top": 550, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+nS1vB//BAk=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nS1vSACp60=", + "_parent": { + "$ref": "AAAAAAF2+nS1vB//BAk=" + }, + "model": { + "$ref": "AAAAAAF2+nS1vB/7hWk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 819, + "top": 593, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF2+nS1vB//BAk=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nS1vSAD2nc=", + "_parent": { + "$ref": "AAAAAAF2+nS1vB//BAk=" + }, + "model": { + "$ref": "AAAAAAF2+nS1vB/8CFI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 750, + "top": 586, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+nS1vB//BAk=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nS1vSAE3Cg=", + "_parent": { + "$ref": "AAAAAAF2+nS1vB//BAk=" + }, + "model": { + "$ref": "AAAAAAF2+nS1vB/8CFI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 748, + "top": 572, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF2+nS1vB//BAk=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nS1vSAFUjQ=", + "_parent": { + "$ref": "AAAAAAF2+nS1vB//BAk=" + }, + "model": { + "$ref": "AAAAAAF2+nS1vB/8CFI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 755, + "top": 613, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF2+nS1vB//BAk=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nS1vSAGNTg=", + "_parent": { + "$ref": "AAAAAAF2+nS1vB//BAk=" + }, + "model": { + "$ref": "AAAAAAF2+nS1vB/9vRE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 868, + "top": 543, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+nS1vB//BAk=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nS1vSAHtw0=", + "_parent": { + "$ref": "AAAAAAF2+nS1vB//BAk=" + }, + "model": { + "$ref": "AAAAAAF2+nS1vB/9vRE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 861, + "top": 531, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF2+nS1vB//BAk=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+nS1vSAIfWc=", + "_parent": { + "$ref": "AAAAAAF2+nS1vB//BAk=" + }, + "model": { + "$ref": "AAAAAAF2+nS1vB/9vRE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 881, + "top": 568, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF2+nS1vB//BAk=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF2+nS1vSAJTTM=", + "_parent": { + "$ref": "AAAAAAF2+nS1vB//BAk=" + }, + "model": { + "$ref": "AAAAAAF2+nS1vB/8CFI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -8, + "top": 8, + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF2+nS1vSAK/NU=", + "_parent": { + "$ref": "AAAAAAF2+nS1vB//BAk=" + }, + "model": { + "$ref": "AAAAAAF2+nS1vB/9vRE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -8, + "top": 8, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF2+nRKkx5Vaw4=" + }, + "tail": { + "$ref": "AAAAAAF2+nB7EcWvyhg=" + }, + "lineStyle": 1, + "points": "731:615;898:555", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF2+nS1vCAA1/w=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF2+nS1vSABc/8=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2+nS1vSACp60=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF2+nS1vSAD2nc=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF2+nS1vSAE3Cg=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF2+nS1vSAFUjQ=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF2+nS1vSAGNTg=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF2+nS1vSAHtw0=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF2+nS1vSAIfWc=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF2+nS1vSAJTTM=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF2+nS1vSAK/NU=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF2+nWEKyMwAMc=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2+nWEKyMuLhQ=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF2+nWEKyMxf1Q=", + "_parent": { + "$ref": "AAAAAAF2+nWEKyMwAMc=" + }, + "model": { + "$ref": "AAAAAAF2+nWEKyMuLhQ=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF2+nWEKyMyBP8=", + "_parent": { + "$ref": "AAAAAAF2+nWEKyMxf1Q=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 800, + "top": -992, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+nWEKyMzemE=", + "_parent": { + "$ref": "AAAAAAF2+nWEKyMxf1Q=" + }, + "font": "Arial;13;1", + "left": 2066, + "top": 11.5, + "width": 129, + "height": 13, + "text": "isAllCycleCompleted" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+nWEKyM01LQ=", + "_parent": { + "$ref": "AAAAAAF2+nWEKyMxf1Q=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 800, + "top": -992, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+nWEKyM1r1Q=", + "_parent": { + "$ref": "AAAAAAF2+nWEKyMxf1Q=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 800, + "top": -992, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 2061, + "top": 4.5, + "width": 139.314453125, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF2+nWEKyMyBP8=" + }, + "nameLabel": { + "$ref": "AAAAAAF2+nWEKyMzemE=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF2+nWEKyM01LQ=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2+nWEKyM1r1Q=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF2+nWEKyM2sSI=", + "_parent": { + "$ref": "AAAAAAF2+nWEKyMwAMc=" + }, + "model": { + "$ref": "AAAAAAF2+nWEKyMuLhQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 400, + "top": -496, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF2+nWEKyM3PmE=", + "_parent": { + "$ref": "AAAAAAF2+nWEKyMwAMc=" + }, + "model": { + "$ref": "AAAAAAF2+nWEKyMuLhQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 400, + "top": -496, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF2+nWEKyM4Ihc=", + "_parent": { + "$ref": "AAAAAAF2+nWEKyMwAMc=" + }, + "model": { + "$ref": "AAAAAAF2+nWEKyMuLhQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 400, + "top": -496, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF2+nWELCM5C+g=", + "_parent": { + "$ref": "AAAAAAF2+nWEKyMwAMc=" + }, + "model": { + "$ref": "AAAAAAF2+nWEKyMuLhQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 400, + "top": -496, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF2+nWELCM6KvA=", + "_parent": { + "$ref": "AAAAAAF2+nWEKyMwAMc=" + }, + "model": { + "$ref": "AAAAAAF2+nWEKyMuLhQ=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 400, + "top": -496, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 2032, + "width": 197, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF2+nWEKyMxf1Q=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF2+nWEKyM2sSI=" + }, + "operationCompartment": { + "$ref": "AAAAAAF2+nWEKyM3PmE=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF2+nWEKyM4Ihc=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF2+nWELCM5C+g=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF2+nWELCM6KvA=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF2+nfCMZ3BUsM=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2+nfCMJ2/R+8=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF2+nfCMp3C1RI=", + "_parent": { + "$ref": "AAAAAAF2+nfCMZ3BUsM=" + }, + "model": { + "$ref": "AAAAAAF2+nfCMJ2/R+8=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF2+nfCMp3DNmU=", + "_parent": { + "$ref": "AAAAAAF2+nfCMp3C1RI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1456, + "top": -2448, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+nfCMp3ECXU=", + "_parent": { + "$ref": "AAAAAAF2+nfCMp3C1RI=" + }, + "font": "Arial;13;1", + "left": 882, + "top": 403.5, + "width": 129, + "height": 13, + "text": "isAllCycleCompleted" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+nfCMp3FeYo=", + "_parent": { + "$ref": "AAAAAAF2+nfCMp3C1RI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1456, + "top": -2448, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+nfCMp3Gpdk=", + "_parent": { + "$ref": "AAAAAAF2+nfCMp3C1RI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1456, + "top": -2448, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 877, + "top": 396.5, + "width": 139.314453125, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF2+nfCMp3DNmU=" + }, + "nameLabel": { + "$ref": "AAAAAAF2+nfCMp3ECXU=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF2+nfCMp3FeYo=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2+nfCMp3Gpdk=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF2+nfCMp3Hk/w=", + "_parent": { + "$ref": "AAAAAAF2+nfCMZ3BUsM=" + }, + "model": { + "$ref": "AAAAAAF2+nfCMJ2/R+8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 728, + "top": -1224, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF2+nfCMp3Ipoc=", + "_parent": { + "$ref": "AAAAAAF2+nfCMZ3BUsM=" + }, + "model": { + "$ref": "AAAAAAF2+nfCMJ2/R+8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 728, + "top": -1224, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF2+nfCMp3J3MA=", + "_parent": { + "$ref": "AAAAAAF2+nfCMZ3BUsM=" + }, + "model": { + "$ref": "AAAAAAF2+nfCMJ2/R+8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 728, + "top": -1224, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF2+nfCMp3KD9I=", + "_parent": { + "$ref": "AAAAAAF2+nfCMZ3BUsM=" + }, + "model": { + "$ref": "AAAAAAF2+nfCMJ2/R+8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 728, + "top": -1224, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF2+nfCMp3LjAc=", + "_parent": { + "$ref": "AAAAAAF2+nfCMZ3BUsM=" + }, + "model": { + "$ref": "AAAAAAF2+nfCMJ2/R+8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 728, + "top": -1224, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 848, + "top": 392, + "width": 197, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF2+nfCMp3C1RI=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF2+nfCMp3Hk/w=" + }, + "operationCompartment": { + "$ref": "AAAAAAF2+nfCMp3Ipoc=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF2+nfCMp3J3MA=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF2+nfCMp3KD9I=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF2+nfCMp3LjAc=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF2+nmf8//Gfbw=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2+nmf8//EQJ0=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF2+nmf8//HI2g=", + "_parent": { + "$ref": "AAAAAAF2+nmf8//Gfbw=" + }, + "model": { + "$ref": "AAAAAAF2+nmf8//EQJ0=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF2+nmf9P/I6yI=", + "_parent": { + "$ref": "AAAAAAF2+nmf8//HI2g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -960, + "top": -1456, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+nmf9P/JtnQ=", + "_parent": { + "$ref": "AAAAAAF2+nmf8//HI2g=" + }, + "font": "Arial;13;1", + "left": 541.5, + "top": 315.5, + "width": 105, + "height": 13, + "text": "doDeleteAllCycle" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+nmf9P/KQDY=", + "_parent": { + "$ref": "AAAAAAF2+nmf8//HI2g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -960, + "top": -1456, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+nmf9P/LlNA=", + "_parent": { + "$ref": "AAAAAAF2+nmf8//HI2g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -960, + "top": -1456, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 536.5, + "top": 308.5, + "width": 116.20263671875, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF2+nmf9P/I6yI=" + }, + "nameLabel": { + "$ref": "AAAAAAF2+nmf9P/JtnQ=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF2+nmf9P/KQDY=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2+nmf9P/LlNA=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF2+nmf9P/MVYQ=", + "_parent": { + "$ref": "AAAAAAF2+nmf8//Gfbw=" + }, + "model": { + "$ref": "AAAAAAF2+nmf8//EQJ0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -480, + "top": -728, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF2+nmf9P/N0tE=", + "_parent": { + "$ref": "AAAAAAF2+nmf8//Gfbw=" + }, + "model": { + "$ref": "AAAAAAF2+nmf8//EQJ0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -480, + "top": -728, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF2+nmf9P/OUoc=", + "_parent": { + "$ref": "AAAAAAF2+nmf8//Gfbw=" + }, + "model": { + "$ref": "AAAAAAF2+nmf8//EQJ0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -480, + "top": -728, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF2+nmf9P/PSrQ=", + "_parent": { + "$ref": "AAAAAAF2+nmf8//Gfbw=" + }, + "model": { + "$ref": "AAAAAAF2+nmf8//EQJ0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -480, + "top": -728, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF2+nmf9P/QKKU=", + "_parent": { + "$ref": "AAAAAAF2+nmf8//Gfbw=" + }, + "model": { + "$ref": "AAAAAAF2+nmf8//EQJ0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -480, + "top": -728, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 512, + "top": 304, + "width": 164, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF2+nmf8//HI2g=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF2+nmf9P/MVYQ=" + }, + "operationCompartment": { + "$ref": "AAAAAAF2+nmf9P/N0tE=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF2+nmf9P/OUoc=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF2+nmf9P/PSrQ=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF2+nmf9P/QKKU=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF2+nq2QxzFIJA=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2+nq2QxzDZ/U=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF2+nq2QxzGCOI=", + "_parent": { + "$ref": "AAAAAAF2+nq2QxzFIJA=" + }, + "model": { + "$ref": "AAAAAAF2+nq2QxzDZ/U=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF2+nq2QxzHPGg=", + "_parent": { + "$ref": "AAAAAAF2+nq2QxzGCOI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 816, + "top": -1376, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+nq2QxzIGSU=", + "_parent": { + "$ref": "AAAAAAF2+nq2QxzGCOI=" + }, + "font": "Arial;13;1", + "left": 473.5, + "top": 899.5, + "width": 87, + "height": 13, + "text": "checkAllCycle" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+nq2QxzJNkI=", + "_parent": { + "$ref": "AAAAAAF2+nq2QxzGCOI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 816, + "top": -1376, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+nq2QxzK1gc=", + "_parent": { + "$ref": "AAAAAAF2+nq2QxzGCOI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 816, + "top": -1376, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 468.5, + "top": 892.5, + "width": 98.16259765625, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF2+nq2QxzHPGg=" + }, + "nameLabel": { + "$ref": "AAAAAAF2+nq2QxzIGSU=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF2+nq2QxzJNkI=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2+nq2QxzK1gc=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF2+nq2QxzLAgw=", + "_parent": { + "$ref": "AAAAAAF2+nq2QxzFIJA=" + }, + "model": { + "$ref": "AAAAAAF2+nq2QxzDZ/U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 408, + "top": -688, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF2+nq2QxzMb90=", + "_parent": { + "$ref": "AAAAAAF2+nq2QxzFIJA=" + }, + "model": { + "$ref": "AAAAAAF2+nq2QxzDZ/U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 408, + "top": -688, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF2+nq2QxzN8NY=", + "_parent": { + "$ref": "AAAAAAF2+nq2QxzFIJA=" + }, + "model": { + "$ref": "AAAAAAF2+nq2QxzDZ/U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 408, + "top": -688, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF2+nq2QxzOrKA=", + "_parent": { + "$ref": "AAAAAAF2+nq2QxzFIJA=" + }, + "model": { + "$ref": "AAAAAAF2+nq2QxzDZ/U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 408, + "top": -688, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF2+nq2QxzPhCY=", + "_parent": { + "$ref": "AAAAAAF2+nq2QxzFIJA=" + }, + "model": { + "$ref": "AAAAAAF2+nq2QxzDZ/U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 408, + "top": -688, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 448, + "top": 888, + "width": 138, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF2+nq2QxzGCOI=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF2+nq2QxzLAgw=" + }, + "operationCompartment": { + "$ref": "AAAAAAF2+nq2QxzMb90=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF2+nq2QxzN8NY=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF2+nq2QxzOrKA=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF2+nq2QxzPhCY=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF2+nsueip2TzQ=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2+nsueSp07D8=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF2+nsueip3gdc=", + "_parent": { + "$ref": "AAAAAAF2+nsueip2TzQ=" + }, + "model": { + "$ref": "AAAAAAF2+nsueSp07D8=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF2+nsueip4ids=", + "_parent": { + "$ref": "AAAAAAF2+nsueip3gdc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1360, + "top": -1696, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+nsueip54uU=", + "_parent": { + "$ref": "AAAAAAF2+nsueip3gdc=" + }, + "font": "Arial;13;1", + "left": 772, + "top": 915.5, + "width": 62, + "height": 13, + "text": "Finish" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+nsueip60ls=", + "_parent": { + "$ref": "AAAAAAF2+nsueip3gdc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1360, + "top": -1696, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+nsueip7mbo=", + "_parent": { + "$ref": "AAAAAAF2+nsueip3gdc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1360, + "top": -1696, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 767, + "top": 908.5, + "width": 72, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF2+nsueip4ids=" + }, + "nameLabel": { + "$ref": "AAAAAAF2+nsueip54uU=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF2+nsueip60ls=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2+nsueip7mbo=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF2+nsueip8654=", + "_parent": { + "$ref": "AAAAAAF2+nsueip2TzQ=" + }, + "model": { + "$ref": "AAAAAAF2+nsueSp07D8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 680, + "top": -848, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF2+nsueip9KyQ=", + "_parent": { + "$ref": "AAAAAAF2+nsueip2TzQ=" + }, + "model": { + "$ref": "AAAAAAF2+nsueSp07D8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 680, + "top": -848, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF2+nsueip+40A=", + "_parent": { + "$ref": "AAAAAAF2+nsueip2TzQ=" + }, + "model": { + "$ref": "AAAAAAF2+nsueSp07D8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 680, + "top": -848, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF2+nsueip/CZI=", + "_parent": { + "$ref": "AAAAAAF2+nsueip2TzQ=" + }, + "model": { + "$ref": "AAAAAAF2+nsueSp07D8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 680, + "top": -848, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF2+nsueyqAa5A=", + "_parent": { + "$ref": "AAAAAAF2+nsueip2TzQ=" + }, + "model": { + "$ref": "AAAAAAF2+nsueSp07D8=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 680, + "top": -848, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 752, + "top": 904, + "width": 102, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF2+nsueip3gdc=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF2+nsueip8654=" + }, + "operationCompartment": { + "$ref": "AAAAAAF2+nsueip9KyQ=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF2+nsueip+40A=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF2+nsueip/CZI=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF2+nsueyqAa5A=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF2+n3z7GQDM/o=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2+n3z62QBjMI=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF2+n3z7GQEn4U=", + "_parent": { + "$ref": "AAAAAAF2+n3z7GQDM/o=" + }, + "model": { + "$ref": "AAAAAAF2+n3z62QBjMI=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF2+n3z7GQFG64=", + "_parent": { + "$ref": "AAAAAAF2+n3z7GQEn4U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 112, + "top": 1072, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+n3z7GQGJmk=", + "_parent": { + "$ref": "AAAAAAF2+n3z7GQEn4U=" + }, + "font": "Arial;13;1", + "left": 913.5, + "top": 907.5, + "width": 87, + "height": 13, + "text": "doRecordSkip" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+n3z7GQHHNY=", + "_parent": { + "$ref": "AAAAAAF2+n3z7GQEn4U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 112, + "top": 1072, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+n3z7GQIaUk=", + "_parent": { + "$ref": "AAAAAAF2+n3z7GQEn4U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 112, + "top": 1072, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 908.5, + "top": 900.5, + "width": 98.12451171875, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF2+n3z7GQFG64=" + }, + "nameLabel": { + "$ref": "AAAAAAF2+n3z7GQGJmk=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF2+n3z7GQHHNY=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2+n3z7GQIaUk=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF2+n3z7GQJ098=", + "_parent": { + "$ref": "AAAAAAF2+n3z7GQDM/o=" + }, + "model": { + "$ref": "AAAAAAF2+n3z62QBjMI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 56, + "top": 536, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF2+n3z7GQKV2I=", + "_parent": { + "$ref": "AAAAAAF2+n3z7GQDM/o=" + }, + "model": { + "$ref": "AAAAAAF2+n3z62QBjMI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 56, + "top": 536, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF2+n3z7GQLZiI=", + "_parent": { + "$ref": "AAAAAAF2+n3z7GQDM/o=" + }, + "model": { + "$ref": "AAAAAAF2+n3z62QBjMI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 56, + "top": 536, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF2+n3z7GQMex8=", + "_parent": { + "$ref": "AAAAAAF2+n3z7GQDM/o=" + }, + "model": { + "$ref": "AAAAAAF2+n3z62QBjMI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 56, + "top": 536, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF2+n3z7WQNVSc=", + "_parent": { + "$ref": "AAAAAAF2+n3z7GQDM/o=" + }, + "model": { + "$ref": "AAAAAAF2+n3z62QBjMI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 56, + "top": 536, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 888, + "top": 896, + "width": 138, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF2+n3z7GQEn4U=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF2+n3z7GQJ098=" + }, + "operationCompartment": { + "$ref": "AAAAAAF2+n3z7GQKV2I=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF2+n3z7GQLZiI=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF2+n3z7GQMex8=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF2+n3z7WQNVSc=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF2+n8X9HOVNKs=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2+n8X9HOTo5I=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF2+n8X9HOWLww=", + "_parent": { + "$ref": "AAAAAAF2+n8X9HOVNKs=" + }, + "model": { + "$ref": "AAAAAAF2+n8X9HOTo5I=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF2+n8X9XOXkdk=", + "_parent": { + "$ref": "AAAAAAF2+n8X9HOWLww=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -976, + "top": -320, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+n8X9XOY3/k=", + "_parent": { + "$ref": "AAAAAAF2+n8X9HOWLww=" + }, + "font": "Arial;13;1", + "left": 587.5, + "top": 419.5, + "width": 135, + "height": 13, + "text": "doMove2NextValidate" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+n8X9XOZd4c=", + "_parent": { + "$ref": "AAAAAAF2+n8X9HOWLww=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -976, + "top": -320, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2+n8X9XOalho=", + "_parent": { + "$ref": "AAAAAAF2+n8X9HOWLww=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -976, + "top": -320, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 582.5, + "top": 412.5, + "width": 145, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF2+n8X9XOXkdk=" + }, + "nameLabel": { + "$ref": "AAAAAAF2+n8X9XOY3/k=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF2+n8X9XOZd4c=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2+n8X9XOalho=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF2+n8X9XObuaA=", + "_parent": { + "$ref": "AAAAAAF2+n8X9HOVNKs=" + }, + "model": { + "$ref": "AAAAAAF2+n8X9HOTo5I=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -488, + "top": -160, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF2+n8X9XOc/uM=", + "_parent": { + "$ref": "AAAAAAF2+n8X9HOVNKs=" + }, + "model": { + "$ref": "AAAAAAF2+n8X9HOTo5I=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -488, + "top": -160, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF2+n8X9XOdBOU=", + "_parent": { + "$ref": "AAAAAAF2+n8X9HOVNKs=" + }, + "model": { + "$ref": "AAAAAAF2+n8X9HOTo5I=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -488, + "top": -160, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF2+n8X9XOeXy8=", + "_parent": { + "$ref": "AAAAAAF2+n8X9HOVNKs=" + }, + "model": { + "$ref": "AAAAAAF2+n8X9HOTo5I=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -488, + "top": -160, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF2+n8X9XOfF+Y=", + "_parent": { + "$ref": "AAAAAAF2+n8X9HOVNKs=" + }, + "model": { + "$ref": "AAAAAAF2+n8X9HOTo5I=" + }, + "visible": false, + "font": "Arial;13;0", + "left": -488, + "top": -160, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 552, + "top": 408, + "width": 206, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF2+n8X9HOWLww=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF2+n8X9XObuaA=" + }, + "operationCompartment": { + "$ref": "AAAAAAF2+n8X9XOc/uM=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF2+n8X9XOdBOU=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF2+n8X9XOeXy8=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF2+n8X9XOfF+Y=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF2+oUnoB1S/NM=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2+oUnnx1ORxs=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3GYHfzyUBIH8=", + "_parent": { + "$ref": "AAAAAAF2+oUnoB1S/NM=" + }, + "model": { + "$ref": "AAAAAAF2+oUnnx1ORxs=" + }, + "font": "Arial;13;0", + "left": 826, + "top": 246, + "width": 98.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF2+oUnoB1S/NM=" + }, + "edgePosition": 1, + "text": "+计算下一个目标" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+oUnoB1U2Yg=", + "_parent": { + "$ref": "AAAAAAF2+oUnoB1S/NM=" + }, + "model": { + "$ref": "AAAAAAF2+oUnnx1ORxs=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 866, + "top": 234, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+oUnoB1S/NM=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+oUnoB1V4II=", + "_parent": { + "$ref": "AAAAAAF2+oUnoB1S/NM=" + }, + "model": { + "$ref": "AAAAAAF2+oUnnx1ORxs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 892, + "top": 271, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF2+oUnoB1S/NM=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+oUnoR1Ww1E=", + "_parent": { + "$ref": "AAAAAAF2+oUnoB1S/NM=" + }, + "model": { + "$ref": "AAAAAAF2+oUnnx1PoOw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 692, + "top": 373, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+oUnoB1S/NM=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+oUnoR1XLyA=", + "_parent": { + "$ref": "AAAAAAF2+oUnoB1S/NM=" + }, + "model": { + "$ref": "AAAAAAF2+oUnnx1PoOw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 687, + "top": 361, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF2+oUnoB1S/NM=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+oUnoR1Y5p0=", + "_parent": { + "$ref": "AAAAAAF2+oUnoB1S/NM=" + }, + "model": { + "$ref": "AAAAAAF2+oUnnx1PoOw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 704, + "top": 398, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF2+oUnoB1S/NM=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+oUnoR1ZY1E=", + "_parent": { + "$ref": "AAAAAAF2+oUnoB1S/NM=" + }, + "model": { + "$ref": "AAAAAAF2+oUnnx1Q1uk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1058, + "top": 119, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF2+oUnoB1S/NM=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+oUnoR1aRTo=", + "_parent": { + "$ref": "AAAAAAF2+oUnoB1S/NM=" + }, + "model": { + "$ref": "AAAAAAF2+oUnnx1Q1uk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1048, + "top": 109, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF2+oUnoB1S/NM=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF2+oUnoR1bUzg=", + "_parent": { + "$ref": "AAAAAAF2+oUnoB1S/NM=" + }, + "model": { + "$ref": "AAAAAAF2+oUnnx1Q1uk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1077, + "top": 139, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF2+oUnoB1S/NM=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF2+oUnoR1cIHg=", + "_parent": { + "$ref": "AAAAAAF2+oUnoB1S/NM=" + }, + "model": { + "$ref": "AAAAAAF2+oUnnx1PoOw=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF2+oUnoR1d4qE=", + "_parent": { + "$ref": "AAAAAAF2+oUnoB1S/NM=" + }, + "model": { + "$ref": "AAAAAAF2+oUnnx1Q1uk=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF2+mwCOqh1UGk=" + }, + "tail": { + "$ref": "AAAAAAF2+n8X9HOVNKs=" + }, + "lineStyle": 1, + "points": "680:407;1088:123", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF3GYHfzyUBIH8=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF2+oUnoB1U2Yg=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2+oUnoB1V4II=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF2+oUnoR1Ww1E=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF2+oUnoR1XLyA=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF2+oUnoR1Y5p0=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF2+oUnoR1ZY1E=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF2+oUnoR1aRTo=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF2+oUnoR1bUzg=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF2+oUnoR1cIHg=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF2+oUnoR1d4qE=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF2/55prhrf+xg=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF2/55prRrd34g=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF2/55prhrgemE=", + "_parent": { + "$ref": "AAAAAAF2/55prhrf+xg=" + }, + "model": { + "$ref": "AAAAAAF2/55prRrd34g=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF2/55prhrh4Oo=", + "_parent": { + "$ref": "AAAAAAF2/55prhrgemE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 48, + "top": 448, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2/55prhrinco=", + "_parent": { + "$ref": "AAAAAAF2/55prhrgemE=" + }, + "font": "Arial;13;1", + "left": 619, + "top": 899.5, + "width": 96, + "height": 13, + "text": "doRecordDirty" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2/55prhrjBVk=", + "_parent": { + "$ref": "AAAAAAF2/55prhrgemE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 48, + "top": 448, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF2/55prhrkkxo=", + "_parent": { + "$ref": "AAAAAAF2/55prhrgemE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 48, + "top": 448, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 614, + "top": 892.5, + "width": 106, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF2/55prhrh4Oo=" + }, + "nameLabel": { + "$ref": "AAAAAAF2/55prhrinco=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF2/55prhrjBVk=" + }, + "propertyLabel": { + "$ref": "AAAAAAF2/55prhrkkxo=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF2/55prhrl5zY=", + "_parent": { + "$ref": "AAAAAAF2/55prhrf+xg=" + }, + "model": { + "$ref": "AAAAAAF2/55prRrd34g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 24, + "top": 224, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF2/55prhrmK5A=", + "_parent": { + "$ref": "AAAAAAF2/55prhrf+xg=" + }, + "model": { + "$ref": "AAAAAAF2/55prRrd34g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 24, + "top": 224, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF2/55prhrnGxY=", + "_parent": { + "$ref": "AAAAAAF2/55prhrf+xg=" + }, + "model": { + "$ref": "AAAAAAF2/55prRrd34g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 24, + "top": 224, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF2/55prhroX/Q=", + "_parent": { + "$ref": "AAAAAAF2/55prhrf+xg=" + }, + "model": { + "$ref": "AAAAAAF2/55prRrd34g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 24, + "top": 224, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF2/55prhrpOzg=", + "_parent": { + "$ref": "AAAAAAF2/55prhrf+xg=" + }, + "model": { + "$ref": "AAAAAAF2/55prRrd34g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 24, + "top": 224, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 592, + "top": 888, + "width": 150, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF2/55prhrgemE=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF2/55prhrl5zY=" + }, + "operationCompartment": { + "$ref": "AAAAAAF2/55prhrmK5A=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF2/55prhrnGxY=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF2/55prhroX/Q=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF2/55prhrpOzg=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF3AAi3NvRv3KY=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF3AAi3NfRr6EY=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3AAi3NvRwDN8=", + "_parent": { + "$ref": "AAAAAAF3AAi3NvRv3KY=" + }, + "model": { + "$ref": "AAAAAAF3AAi3NfRr6EY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 847, + "top": 193, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF3AAi3NvRv3KY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3AAi3NvRxRCk=", + "_parent": { + "$ref": "AAAAAAF3AAi3NvRv3KY=" + }, + "model": { + "$ref": "AAAAAAF3AAi3NfRr6EY=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 841, + "top": 179, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF3AAi3NvRv3KY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3AAi3NvRypxI=", + "_parent": { + "$ref": "AAAAAAF3AAi3NvRv3KY=" + }, + "model": { + "$ref": "AAAAAAF3AAi3NfRr6EY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 858, + "top": 220, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF3AAi3NvRv3KY=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3AAi3NvRziZA=", + "_parent": { + "$ref": "AAAAAAF3AAi3NvRv3KY=" + }, + "model": { + "$ref": "AAAAAAF3AAi3NfRsLF0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 654, + "top": 273, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF3AAi3NvRv3KY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3AAi3NvR0i3M=", + "_parent": { + "$ref": "AAAAAAF3AAi3NvRv3KY=" + }, + "model": { + "$ref": "AAAAAAF3AAi3NfRsLF0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 651, + "top": 260, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF3AAi3NvRv3KY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3AAi3NvR1v00=", + "_parent": { + "$ref": "AAAAAAF3AAi3NvRv3KY=" + }, + "model": { + "$ref": "AAAAAAF3AAi3NfRsLF0=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 660, + "top": 300, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF3AAi3NvRv3KY=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3AAi3NvR27EA=", + "_parent": { + "$ref": "AAAAAAF3AAi3NvRv3KY=" + }, + "model": { + "$ref": "AAAAAAF3AAi3NfRtPso=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1041, + "top": 113, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF3AAi3NvRv3KY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3AAi3NvR3NBA=", + "_parent": { + "$ref": "AAAAAAF3AAi3NvRv3KY=" + }, + "model": { + "$ref": "AAAAAAF3AAi3NfRtPso=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1034, + "top": 101, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF3AAi3NvRv3KY=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3AAi3NvR46nA=", + "_parent": { + "$ref": "AAAAAAF3AAi3NvRv3KY=" + }, + "model": { + "$ref": "AAAAAAF3AAi3NfRtPso=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1055, + "top": 136, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF3AAi3NvRv3KY=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF3AAi3NvR5srI=", + "_parent": { + "$ref": "AAAAAAF3AAi3NvRv3KY=" + }, + "model": { + "$ref": "AAAAAAF3AAi3NfRsLF0=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF3AAi3NvR6YUo=", + "_parent": { + "$ref": "AAAAAAF3AAi3NvRv3KY=" + }, + "model": { + "$ref": "AAAAAAF3AAi3NfRtPso=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF2+mwCOqh1UGk=" + }, + "tail": { + "$ref": "AAAAAAF2+nmf8//Gfbw=" + }, + "lineStyle": 1, + "points": "636:303;1071:123", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF3AAi3NvRwDN8=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF3AAi3NvRxRCk=" + }, + "propertyLabel": { + "$ref": "AAAAAAF3AAi3NvRypxI=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF3AAi3NvRziZA=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF3AAi3NvR0i3M=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF3AAi3NvR1v00=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF3AAi3NvR27EA=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF3AAi3NvR3NBA=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF3AAi3NvR46nA=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF3AAi3NvR5srI=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF3AAi3NvR6YUo=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF3AAkuEf3u4rc=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF3AAkuEf3qL3g=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3AAkuEf3vFUU=", + "_parent": { + "$ref": "AAAAAAF3AAkuEf3u4rc=" + }, + "model": { + "$ref": "AAAAAAF3AAkuEf3qL3g=" + }, + "font": "Arial;13;0", + "left": 786, + "top": 136, + "width": 59.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF3AAkuEf3u4rc=" + }, + "edgePosition": 1, + "text": "+重新测量" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3AAkuEf3wr8I=", + "_parent": { + "$ref": "AAAAAAF3AAkuEf3u4rc=" + }, + "model": { + "$ref": "AAAAAAF3AAkuEf3qL3g=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 812, + "top": 121, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF3AAkuEf3u4rc=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3AAkuEf3x3Io=", + "_parent": { + "$ref": "AAAAAAF3AAkuEf3u4rc=" + }, + "model": { + "$ref": "AAAAAAF3AAkuEf3qL3g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 820, + "top": 165, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF3AAkuEf3u4rc=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3AAkuEf3yj1w=", + "_parent": { + "$ref": "AAAAAAF3AAkuEf3u4rc=" + }, + "model": { + "$ref": "AAAAAAF3AAkuEf3rpYI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 596, + "top": 174, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF3AAkuEf3u4rc=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3AAkuEf3zA9Y=", + "_parent": { + "$ref": "AAAAAAF3AAkuEf3u4rc=" + }, + "model": { + "$ref": "AAAAAAF3AAkuEf3rpYI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 596, + "top": 161, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF3AAkuEf3u4rc=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3AAkuEf30kh0=", + "_parent": { + "$ref": "AAAAAAF3AAkuEf3u4rc=" + }, + "model": { + "$ref": "AAAAAAF3AAkuEf3rpYI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 597, + "top": 202, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF3AAkuEf3u4rc=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3AAkuEf31ZFk=", + "_parent": { + "$ref": "AAAAAAF3AAkuEf3u4rc=" + }, + "model": { + "$ref": "AAAAAAF3AAkuEf3seOw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1034, + "top": 97, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF3AAkuEf3u4rc=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3AAkuEf32s54=", + "_parent": { + "$ref": "AAAAAAF3AAkuEf3u4rc=" + }, + "model": { + "$ref": "AAAAAAF3AAkuEf3seOw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1030, + "top": 85, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF3AAkuEf3u4rc=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3AAkuEf33mtU=", + "_parent": { + "$ref": "AAAAAAF3AAkuEf3u4rc=" + }, + "model": { + "$ref": "AAAAAAF3AAkuEf3seOw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1043, + "top": 124, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF3AAkuEf3u4rc=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF3AAkuEf341iM=", + "_parent": { + "$ref": "AAAAAAF3AAkuEf3u4rc=" + }, + "model": { + "$ref": "AAAAAAF3AAkuEf3rpYI=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF3AAkuEf35gXc=", + "_parent": { + "$ref": "AAAAAAF3AAkuEf3u4rc=" + }, + "model": { + "$ref": "AAAAAAF3AAkuEf3seOw=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF2+mwCOqh1UGk=" + }, + "tail": { + "$ref": "AAAAAAF2+m+73bQ4m2I=" + }, + "lineStyle": 1, + "points": "574:200;1063:114", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF3AAkuEf3vFUU=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF3AAkuEf3wr8I=" + }, + "propertyLabel": { + "$ref": "AAAAAAF3AAkuEf3x3Io=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF3AAkuEf3yj1w=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF3AAkuEf3zA9Y=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF3AAkuEf30kh0=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF3AAkuEf31ZFk=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF3AAkuEf32s54=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF3AAkuEf33mtU=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF3AAkuEf341iM=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF3AAkuEf35gXc=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF3AAllGAV4vW0=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF3AAllGAV08Nw=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3AAllGAV5JwE=", + "_parent": { + "$ref": "AAAAAAF3AAllGAV4vW0=" + }, + "model": { + "$ref": "AAAAAAF3AAllGAV08Nw=" + }, + "font": "Arial;13;0", + "left": 540, + "top": 250, + "width": 59.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF3AAllGAV4vW0=" + }, + "edgePosition": 1, + "text": "+清空测量" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3AAllGAV6J1c=", + "_parent": { + "$ref": "AAAAAAF3AAllGAV4vW0=" + }, + "model": { + "$ref": "AAAAAAF3AAllGAV08Nw=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 582, + "top": 242, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF3AAllGAV4vW0=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3AAllGAV7E+E=", + "_parent": { + "$ref": "AAAAAAF3AAllGAV4vW0=" + }, + "model": { + "$ref": "AAAAAAF3AAllGAV08Nw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 544, + "top": 267, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF3AAllGAV4vW0=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3AAllGAV8Fz4=", + "_parent": { + "$ref": "AAAAAAF3AAllGAV4vW0=" + }, + "model": { + "$ref": "AAAAAAF3AAllGAV1sLI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 559, + "top": 234, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF3AAllGAV4vW0=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3AAllGAV9EBE=", + "_parent": { + "$ref": "AAAAAAF3AAllGAV4vW0=" + }, + "model": { + "$ref": "AAAAAAF3AAllGAV1sLI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 572, + "top": 229, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF3AAllGAV4vW0=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3AAllGAV+La8=", + "_parent": { + "$ref": "AAAAAAF3AAllGAV4vW0=" + }, + "model": { + "$ref": "AAAAAAF3AAllGAV1sLI=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 534, + "top": 245, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF3AAllGAV4vW0=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3AAllGAV/WHE=", + "_parent": { + "$ref": "AAAAAAF3AAllGAV4vW0=" + }, + "model": { + "$ref": "AAAAAAF3AAllGAV2oyY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 580, + "top": 267, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF3AAllGAV4vW0=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3AAllGAWA3ZU=", + "_parent": { + "$ref": "AAAAAAF3AAllGAV4vW0=" + }, + "model": { + "$ref": "AAAAAAF3AAllGAV2oyY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 590, + "top": 257, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF3AAllGAV4vW0=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3AAllGAWB0W0=", + "_parent": { + "$ref": "AAAAAAF3AAllGAV4vW0=" + }, + "model": { + "$ref": "AAAAAAF3AAllGAV2oyY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 559, + "top": 285, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF3AAllGAV4vW0=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF3AAllGAWCqYI=", + "_parent": { + "$ref": "AAAAAAF3AAllGAV4vW0=" + }, + "model": { + "$ref": "AAAAAAF3AAllGAV1sLI=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF3AAllGAWDVu4=", + "_parent": { + "$ref": "AAAAAAF3AAllGAV4vW0=" + }, + "model": { + "$ref": "AAAAAAF3AAllGAV2oyY=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF2+nmf8//Gfbw=" + }, + "tail": { + "$ref": "AAAAAAF2+m+73bQ4m2I=" + }, + "lineStyle": 1, + "points": "533:227;582:303", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF3AAllGAV5JwE=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF3AAllGAV6J1c=" + }, + "propertyLabel": { + "$ref": "AAAAAAF3AAllGAV7E+E=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF3AAllGAV8Fz4=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF3AAllGAV9EBE=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF3AAllGAV+La8=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF3AAllGAV/WHE=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF3AAllGAWA3ZU=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF3AAllGAWB0W0=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF3AAllGAWCqYI=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF3AAllGAWDVu4=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF3ABeWIk8op44=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF3ABeWIk8kkqs=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3ABeWIk8pzMQ=", + "_parent": { + "$ref": "AAAAAAF3ABeWIk8op44=" + }, + "model": { + "$ref": "AAAAAAF3ABeWIk8kkqs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 514, + "top": 591, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF3ABeWIk8op44=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3ABeWIk8qvK8=", + "_parent": { + "$ref": "AAAAAAF3ABeWIk8op44=" + }, + "model": { + "$ref": "AAAAAAF3ABeWIk8kkqs=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 516, + "top": 576, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF3ABeWIk8op44=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3ABeWIk8rXNY=", + "_parent": { + "$ref": "AAAAAAF3ABeWIk8op44=" + }, + "model": { + "$ref": "AAAAAAF3ABeWIk8kkqs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 511, + "top": 620, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF3ABeWIk8op44=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3ABeWIk8sd3M=", + "_parent": { + "$ref": "AAAAAAF3ABeWIk8op44=" + }, + "model": { + "$ref": "AAAAAAF3ABeWIk8l/nk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 486, + "top": 588, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF3ABeWIk8op44=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3ABeWIk8tucs=", + "_parent": { + "$ref": "AAAAAAF3ABeWIk8op44=" + }, + "model": { + "$ref": "AAAAAAF3ABeWIk8l/nk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 490, + "top": 575, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF3ABeWIk8op44=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3ABeWIk8uDSU=", + "_parent": { + "$ref": "AAAAAAF3ABeWIk8op44=" + }, + "model": { + "$ref": "AAAAAAF3ABeWIk8l/nk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 479, + "top": 614, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF3ABeWIk8op44=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3ABeWIk8v4Ak=", + "_parent": { + "$ref": "AAAAAAF3ABeWIk8op44=" + }, + "model": { + "$ref": "AAAAAAF3ABeWIk8mwTw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 542, + "top": 595, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF3ABeWIk8op44=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3ABeWIk8wWtM=", + "_parent": { + "$ref": "AAAAAAF3ABeWIk8op44=" + }, + "model": { + "$ref": "AAAAAAF3ABeWIk8mwTw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 542, + "top": 581, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF3ABeWIk8op44=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3ABeWIk8xBTc=", + "_parent": { + "$ref": "AAAAAAF3ABeWIk8op44=" + }, + "model": { + "$ref": "AAAAAAF3ABeWIk8mwTw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 544, + "top": 622, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF3ABeWIk8op44=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF3ABeWIk8yQcs=", + "_parent": { + "$ref": "AAAAAAF3ABeWIk8op44=" + }, + "model": { + "$ref": "AAAAAAF3ABeWIk8l/nk=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF3ABeWIk8z5Rc=", + "_parent": { + "$ref": "AAAAAAF3ABeWIk8op44=" + }, + "model": { + "$ref": "AAAAAAF3ABeWIk8mwTw=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF2+nB7EcWvyhg=" + }, + "tail": { + "$ref": "AAAAAAF2+nIha+T0PKc=" + }, + "lineStyle": 1, + "points": "459:606;567:619", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF3ABeWIk8pzMQ=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF3ABeWIk8qvK8=" + }, + "propertyLabel": { + "$ref": "AAAAAAF3ABeWIk8rXNY=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF3ABeWIk8sd3M=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF3ABeWIk8tucs=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF3ABeWIk8uDSU=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF3ABeWIk8v4Ak=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF3ABeWIk8wWtM=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF3ABeWIk8xBTc=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF3ABeWIk8yQcs=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF3ABeWIk8z5Rc=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF3FYXf89UtfGE=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF3FYXf8tUp5SY=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYXf89UuSck=", + "_parent": { + "$ref": "AAAAAAF3FYXf89UtfGE=" + }, + "model": { + "$ref": "AAAAAAF3FYXf8tUp5SY=" + }, + "font": "Arial;13;0", + "left": 903, + "top": 467, + "width": 59.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF3FYXf89UtfGE=" + }, + "edgePosition": 1, + "text": "+通过检测" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYXf89Uv0GE=", + "_parent": { + "$ref": "AAAAAAF3FYXf89UtfGE=" + }, + "model": { + "$ref": "AAAAAAF3FYXf8tUp5SY=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 917, + "top": 467, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF3FYXf89UtfGE=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYXf89UwhBk=", + "_parent": { + "$ref": "AAAAAAF3FYXf89UtfGE=" + }, + "model": { + "$ref": "AAAAAAF3FYXf8tUp5SY=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 961, + "top": 466, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF3FYXf89UtfGE=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYXf89Ux8/0=", + "_parent": { + "$ref": "AAAAAAF3FYXf89UtfGE=" + }, + "model": { + "$ref": "AAAAAAF3FYXf8tUqXjA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 932, + "top": 487, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF3FYXf89UtfGE=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYXf89Uyiek=", + "_parent": { + "$ref": "AAAAAAF3FYXf89UtfGE=" + }, + "model": { + "$ref": "AAAAAAF3FYXf8tUqXjA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 919, + "top": 485, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF3FYXf89UtfGE=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYXf89Uz1EE=", + "_parent": { + "$ref": "AAAAAAF3FYXf89UtfGE=" + }, + "model": { + "$ref": "AAAAAAF3FYXf8tUqXjA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 960, + "top": 491, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF3FYXf89UtfGE=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYXf89U0nxQ=", + "_parent": { + "$ref": "AAAAAAF3FYXf89UtfGE=" + }, + "model": { + "$ref": "AAAAAAF3FYXf89Uremo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 931, + "top": 447, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF3FYXf89UtfGE=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYXf89U16n8=", + "_parent": { + "$ref": "AAAAAAF3FYXf89UtfGE=" + }, + "model": { + "$ref": "AAAAAAF3FYXf89Uremo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 918, + "top": 449, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF3FYXf89UtfGE=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYXf89U2Rmk=", + "_parent": { + "$ref": "AAAAAAF3FYXf89UtfGE=" + }, + "model": { + "$ref": "AAAAAAF3FYXf89Uremo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 958, + "top": 442, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF3FYXf89UtfGE=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF3FYXf89U3eCA=", + "_parent": { + "$ref": "AAAAAAF3FYXf89UtfGE=" + }, + "model": { + "$ref": "AAAAAAF3FYXf8tUqXjA=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF3FYXf89U4/vg=", + "_parent": { + "$ref": "AAAAAAF3FYXf89UtfGE=" + }, + "model": { + "$ref": "AAAAAAF3FYXf89Uremo=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF2+nfCMZ3BUsM=" + }, + "tail": { + "$ref": "AAAAAAF2+nRKkx5Vaw4=" + }, + "lineStyle": 1, + "points": "948:519;946:427", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF3FYXf89UuSck=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF3FYXf89Uv0GE=" + }, + "propertyLabel": { + "$ref": "AAAAAAF3FYXf89UwhBk=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF3FYXf89Ux8/0=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF3FYXf89Uyiek=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF3FYXf89Uz1EE=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF3FYXf89U0nxQ=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF3FYXf89U16n8=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF3FYXf89U2Rmk=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF3FYXf89U3eCA=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF3FYXf89U4/vg=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF3FYY3Odi5Qvo=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF3FYY3ONi1k54=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYY3Odi62oY=", + "_parent": { + "$ref": "AAAAAAF3FYY3Odi5Qvo=" + }, + "model": { + "$ref": "AAAAAAF3FYY3ONi1k54=" + }, + "font": "Arial;13;0", + "left": 993, + "top": 243, + "width": 46.864990234375, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF3FYY3Odi5Qvo=" + }, + "edgePosition": 1, + "text": "+未完成" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYY3Odi7tcE=", + "_parent": { + "$ref": "AAAAAAF3FYY3Odi5Qvo=" + }, + "model": { + "$ref": "AAAAAAF3FYY3ONi1k54=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1003, + "top": 236, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF3FYY3Odi5Qvo=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYY3Odi8lBY=", + "_parent": { + "$ref": "AAAAAAF3FYY3Odi5Qvo=" + }, + "model": { + "$ref": "AAAAAAF3FYY3ONi1k54=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1043, + "top": 258, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF3FYY3Odi5Qvo=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYY3Odi96UE=", + "_parent": { + "$ref": "AAAAAAF3FYY3Odi5Qvo=" + }, + "model": { + "$ref": "AAAAAAF3FYY3Odi2Kgc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 955, + "top": 355, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF3FYY3Odi5Qvo=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYY3Odi+RAs=", + "_parent": { + "$ref": "AAAAAAF3FYY3Odi5Qvo=" + }, + "model": { + "$ref": "AAAAAAF3FYY3Odi2Kgc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 944, + "top": 346, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF3FYY3Odi5Qvo=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYY3Odi/zVk=", + "_parent": { + "$ref": "AAAAAAF3FYY3Odi5Qvo=" + }, + "model": { + "$ref": "AAAAAAF3FYY3Odi2Kgc=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 977, + "top": 372, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF3FYY3Odi5Qvo=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYY3OdjAr2E=", + "_parent": { + "$ref": "AAAAAAF3FYY3Odi5Qvo=" + }, + "model": { + "$ref": "AAAAAAF3FYY3Odi3/4g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1078, + "top": 132, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF3FYY3Odi5Qvo=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYY3OdjB8MY=", + "_parent": { + "$ref": "AAAAAAF3FYY3Odi5Qvo=" + }, + "model": { + "$ref": "AAAAAAF3FYY3Odi3/4g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1065, + "top": 128, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF3FYY3Odi5Qvo=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYY3OdjC1b8=", + "_parent": { + "$ref": "AAAAAAF3FYY3Odi5Qvo=" + }, + "model": { + "$ref": "AAAAAAF3FYY3Odi3/4g=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1104, + "top": 141, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF3FYY3Odi5Qvo=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF3FYY3OdjDoGI=", + "_parent": { + "$ref": "AAAAAAF3FYY3Odi5Qvo=" + }, + "model": { + "$ref": "AAAAAAF3FYY3Odi2Kgc=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF3FYY3OdjEpKI=", + "_parent": { + "$ref": "AAAAAAF3FYY3Odi5Qvo=" + }, + "model": { + "$ref": "AAAAAAF3FYY3Odi3/4g=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF2+mwCOqh1UGk=" + }, + "tail": { + "$ref": "AAAAAAF2+nfCMZ3BUsM=" + }, + "lineStyle": 1, + "points": "956:391;1104:123", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF3FYY3Odi62oY=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF3FYY3Odi7tcE=" + }, + "propertyLabel": { + "$ref": "AAAAAAF3FYY3Odi8lBY=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF3FYY3Odi96UE=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF3FYY3Odi+RAs=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF3FYY3Odi/zVk=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF3FYY3OdjAr2E=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF3FYY3OdjB8MY=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF3FYY3OdjC1b8=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF3FYY3OdjDoGI=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF3FYY3OdjEpKI=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF3FYZbFNuAuzw=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF3FYZbFNt+k4c=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF3FYZbFNuBlYE=", + "_parent": { + "$ref": "AAAAAAF3FYZbFNuAuzw=" + }, + "model": { + "$ref": "AAAAAAF3FYZbFNt+k4c=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF3FYZbFduC04Q=", + "_parent": { + "$ref": "AAAAAAF3FYZbFNuBlYE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 16, + "top": 464, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF3FYZbFduDcAk=", + "_parent": { + "$ref": "AAAAAAF3FYZbFNuBlYE=" + }, + "font": "Arial;13;1", + "left": 852, + "top": 843.5, + "width": 62, + "height": 13, + "text": "需要补测" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF3FYZbFduER9s=", + "_parent": { + "$ref": "AAAAAAF3FYZbFNuBlYE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 16, + "top": 464, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF3FYZbFduFXxc=", + "_parent": { + "$ref": "AAAAAAF3FYZbFNuBlYE=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 16, + "top": 464, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 847, + "top": 836.5, + "width": 72, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF3FYZbFduC04Q=" + }, + "nameLabel": { + "$ref": "AAAAAAF3FYZbFduDcAk=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF3FYZbFduER9s=" + }, + "propertyLabel": { + "$ref": "AAAAAAF3FYZbFduFXxc=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF3FYZbFduGvug=", + "_parent": { + "$ref": "AAAAAAF3FYZbFNuAuzw=" + }, + "model": { + "$ref": "AAAAAAF3FYZbFNt+k4c=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 8, + "top": 232, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF3FYZbFduHXxg=", + "_parent": { + "$ref": "AAAAAAF3FYZbFNuAuzw=" + }, + "model": { + "$ref": "AAAAAAF3FYZbFNt+k4c=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 8, + "top": 232, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF3FYZbFduIknI=", + "_parent": { + "$ref": "AAAAAAF3FYZbFNuAuzw=" + }, + "model": { + "$ref": "AAAAAAF3FYZbFNt+k4c=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 8, + "top": 232, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF3FYZbFduJrfE=", + "_parent": { + "$ref": "AAAAAAF3FYZbFNuAuzw=" + }, + "model": { + "$ref": "AAAAAAF3FYZbFNt+k4c=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 8, + "top": 232, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF3FYZbFduKuNA=", + "_parent": { + "$ref": "AAAAAAF3FYZbFNuAuzw=" + }, + "model": { + "$ref": "AAAAAAF3FYZbFNt+k4c=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 8, + "top": 232, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 832, + "top": 832, + "width": 102, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF3FYZbFNuBlYE=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF3FYZbFduGvug=" + }, + "operationCompartment": { + "$ref": "AAAAAAF3FYZbFduHXxg=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF3FYZbFduIknI=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF3FYZbFduJrfE=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF3FYZbFduKuNA=" + } + }, + { + "_type": "UMLUseCaseView", + "_id": "AAAAAAF3FYeGO+xbgps=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF3FYeGOuxZC7s=" + }, + "subViews": [ + { + "_type": "UMLNameCompartmentView", + "_id": "AAAAAAF3FYeGO+xcNdU=", + "_parent": { + "$ref": "AAAAAAF3FYeGO+xbgps=" + }, + "model": { + "$ref": "AAAAAAF3FYeGOuxZC7s=" + }, + "subViews": [ + { + "_type": "LabelView", + "_id": "AAAAAAF3FYeGO+xdFmg=", + "_parent": { + "$ref": "AAAAAAF3FYeGO+xcNdU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 208, + "top": 144, + "height": 13 + }, + { + "_type": "LabelView", + "_id": "AAAAAAF3FYeGO+xeMok=", + "_parent": { + "$ref": "AAAAAAF3FYeGO+xcNdU=" + }, + "font": "Arial;13;1", + "left": 1324, + "top": 795.5, + "width": 62, + "height": 13, + "text": "补测" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF3FYeGO+xfBVg=", + "_parent": { + "$ref": "AAAAAAF3FYeGO+xcNdU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 208, + "top": 144, + "width": 78.28593444824219, + "height": 13, + "text": "(from Model)" + }, + { + "_type": "LabelView", + "_id": "AAAAAAF3FYeGO+xgJBc=", + "_parent": { + "$ref": "AAAAAAF3FYeGO+xcNdU=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 208, + "top": 144, + "height": 13, + "horizontalAlignment": 1 + } + ], + "font": "Arial;13;0", + "left": 1319, + "top": 788.5, + "width": 72, + "height": 25, + "stereotypeLabel": { + "$ref": "AAAAAAF3FYeGO+xdFmg=" + }, + "nameLabel": { + "$ref": "AAAAAAF3FYeGO+xeMok=" + }, + "namespaceLabel": { + "$ref": "AAAAAAF3FYeGO+xfBVg=" + }, + "propertyLabel": { + "$ref": "AAAAAAF3FYeGO+xgJBc=" + } + }, + { + "_type": "UMLAttributeCompartmentView", + "_id": "AAAAAAF3FYeGPOxh8UQ=", + "_parent": { + "$ref": "AAAAAAF3FYeGO+xbgps=" + }, + "model": { + "$ref": "AAAAAAF3FYeGOuxZC7s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 104, + "top": 72, + "width": 10, + "height": 10 + }, + { + "_type": "UMLOperationCompartmentView", + "_id": "AAAAAAF3FYeGPOxiyA8=", + "_parent": { + "$ref": "AAAAAAF3FYeGO+xbgps=" + }, + "model": { + "$ref": "AAAAAAF3FYeGOuxZC7s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 104, + "top": 72, + "width": 10, + "height": 10 + }, + { + "_type": "UMLReceptionCompartmentView", + "_id": "AAAAAAF3FYeGPOxjOfM=", + "_parent": { + "$ref": "AAAAAAF3FYeGO+xbgps=" + }, + "model": { + "$ref": "AAAAAAF3FYeGOuxZC7s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 104, + "top": 72, + "width": 10, + "height": 10 + }, + { + "_type": "UMLTemplateParameterCompartmentView", + "_id": "AAAAAAF3FYeGPOxk208=", + "_parent": { + "$ref": "AAAAAAF3FYeGO+xbgps=" + }, + "model": { + "$ref": "AAAAAAF3FYeGOuxZC7s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 104, + "top": 72, + "width": 10, + "height": 10 + }, + { + "_type": "UMLExtensionPointCompartmentView", + "_id": "AAAAAAF3FYeGPOxlhv8=", + "_parent": { + "$ref": "AAAAAAF3FYeGO+xbgps=" + }, + "model": { + "$ref": "AAAAAAF3FYeGOuxZC7s=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 104, + "top": 72, + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "containerChangeable": true, + "left": 1304, + "top": 784, + "width": 102, + "height": 35, + "nameCompartment": { + "$ref": "AAAAAAF3FYeGO+xcNdU=" + }, + "suppressAttributes": true, + "suppressOperations": true, + "attributeCompartment": { + "$ref": "AAAAAAF3FYeGPOxh8UQ=" + }, + "operationCompartment": { + "$ref": "AAAAAAF3FYeGPOxiyA8=" + }, + "receptionCompartment": { + "$ref": "AAAAAAF3FYeGPOxjOfM=" + }, + "templateParameterCompartment": { + "$ref": "AAAAAAF3FYeGPOxk208=" + }, + "extensionPointCompartment": { + "$ref": "AAAAAAF3FYeGPOxlhv8=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF3FYfmnPCIr84=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF3FYfmm/CEg44=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYfmnPCJbKg=", + "_parent": { + "$ref": "AAAAAAF3FYfmnPCIr84=" + }, + "model": { + "$ref": "AAAAAAF3FYfmm/CEg44=" + }, + "font": "Arial;13;0", + "left": 676, + "top": 471, + "width": 216.61895751953125, + "height": 13, + "alpha": 0.1884747434719145, + "distance": 17.26267650163207, + "hostEdge": { + "$ref": "AAAAAAF3FYfmnPCIr84=" + }, + "edgePosition": 1, + "text": "+未通过检测,将补测数据标识为dirty" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYfmnPCK6BE=", + "_parent": { + "$ref": "AAAAAAF3FYfmnPCIr84=" + }, + "model": { + "$ref": "AAAAAAF3FYfmm/CEg44=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 790, + "top": 503, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF3FYfmnPCIr84=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYfmnPCLgus=", + "_parent": { + "$ref": "AAAAAAF3FYfmnPCIr84=" + }, + "model": { + "$ref": "AAAAAAF3FYfmm/CEg44=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 806, + "top": 460, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF3FYfmnPCIr84=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYfmnPCMTXU=", + "_parent": { + "$ref": "AAAAAAF3FYfmnPCIr84=" + }, + "model": { + "$ref": "AAAAAAF3FYfmm/CF45U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 871, + "top": 517, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF3FYfmnPCIr84=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYfmnPCN6dg=", + "_parent": { + "$ref": "AAAAAAF3FYfmnPCIr84=" + }, + "model": { + "$ref": "AAAAAAF3FYfmm/CF45U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 864, + "top": 529, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF3FYfmnPCIr84=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYfmnPCO0WE=", + "_parent": { + "$ref": "AAAAAAF3FYfmnPCIr84=" + }, + "model": { + "$ref": "AAAAAAF3FYfmm/CF45U=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 885, + "top": 493, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF3FYfmnPCIr84=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYfmnPCPTs4=", + "_parent": { + "$ref": "AAAAAAF3FYfmnPCIr84=" + }, + "model": { + "$ref": "AAAAAAF3FYfmm/CGlMo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 719, + "top": 460, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF3FYfmnPCIr84=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYfmnPCQ4ZQ=", + "_parent": { + "$ref": "AAAAAAF3FYfmnPCIr84=" + }, + "model": { + "$ref": "AAAAAAF3FYfmm/CGlMo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 717, + "top": 473, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF3FYfmnPCIr84=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYfmnPCR0YI=", + "_parent": { + "$ref": "AAAAAAF3FYfmnPCIr84=" + }, + "model": { + "$ref": "AAAAAAF3FYfmm/CGlMo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 725, + "top": 433, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF3FYfmnPCIr84=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF3FYfmnPCS3/Q=", + "_parent": { + "$ref": "AAAAAAF3FYfmnPCIr84=" + }, + "model": { + "$ref": "AAAAAAF3FYfmm/CF45U=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF3FYfmnPCTkR4=", + "_parent": { + "$ref": "AAAAAAF3FYfmnPCIr84=" + }, + "model": { + "$ref": "AAAAAAF3FYfmm/CGlMo=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF2+n8X9HOVNKs=" + }, + "tail": { + "$ref": "AAAAAAF2+nRKkx5Vaw4=" + }, + "lineStyle": 1, + "points": "901:519;701:443", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF3FYfmnPCJbKg=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF3FYfmnPCK6BE=" + }, + "propertyLabel": { + "$ref": "AAAAAAF3FYfmnPCLgus=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF3FYfmnPCMTXU=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF3FYfmnPCN6dg=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF3FYfmnPCO0WE=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF3FYfmnPCPTs4=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF3FYfmnPCQ4ZQ=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF3FYfmnPCR0YI=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF3FYfmnPCS3/Q=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF3FYfmnPCTkR4=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF3FYiOTvpbRvo=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF3FYiOTvpXxUA=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYiOTvpckKI=", + "_parent": { + "$ref": "AAAAAAF3FYiOTvpbRvo=" + }, + "model": { + "$ref": "AAAAAAF3FYiOTvpXxUA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 875, + "top": 246, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF3FYiOTvpbRvo=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYiOTvpdswc=", + "_parent": { + "$ref": "AAAAAAF3FYiOTvpbRvo=" + }, + "model": { + "$ref": "AAAAAAF3FYiOTvpXxUA=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 866, + "top": 234, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF3FYiOTvpbRvo=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYiOTvpeCiY=", + "_parent": { + "$ref": "AAAAAAF3FYiOTvpbRvo=" + }, + "model": { + "$ref": "AAAAAAF3FYiOTvpXxUA=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 892, + "top": 271, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF3FYiOTvpbRvo=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYiOTvpf64s=", + "_parent": { + "$ref": "AAAAAAF3FYiOTvpbRvo=" + }, + "model": { + "$ref": "AAAAAAF3FYiOTvpYHAk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 692, + "top": 373, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF3FYiOTvpbRvo=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYiOTvpgCV4=", + "_parent": { + "$ref": "AAAAAAF3FYiOTvpbRvo=" + }, + "model": { + "$ref": "AAAAAAF3FYiOTvpYHAk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 687, + "top": 361, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF3FYiOTvpbRvo=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYiOTvph4mg=", + "_parent": { + "$ref": "AAAAAAF3FYiOTvpbRvo=" + }, + "model": { + "$ref": "AAAAAAF3FYiOTvpYHAk=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 704, + "top": 398, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF3FYiOTvpbRvo=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYiOTvpiVXw=", + "_parent": { + "$ref": "AAAAAAF3FYiOTvpbRvo=" + }, + "model": { + "$ref": "AAAAAAF3FYiOTvpZRGM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1058, + "top": 119, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF3FYiOTvpbRvo=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYiOTvpj6rs=", + "_parent": { + "$ref": "AAAAAAF3FYiOTvpbRvo=" + }, + "model": { + "$ref": "AAAAAAF3FYiOTvpZRGM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1048, + "top": 109, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF3FYiOTvpbRvo=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYiOTvpkLlM=", + "_parent": { + "$ref": "AAAAAAF3FYiOTvpbRvo=" + }, + "model": { + "$ref": "AAAAAAF3FYiOTvpZRGM=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1077, + "top": 139, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF3FYiOTvpbRvo=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF3FYiOTvplKeU=", + "_parent": { + "$ref": "AAAAAAF3FYiOTvpbRvo=" + }, + "model": { + "$ref": "AAAAAAF3FYiOTvpYHAk=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF3FYiOTvpmbVY=", + "_parent": { + "$ref": "AAAAAAF3FYiOTvpbRvo=" + }, + "model": { + "$ref": "AAAAAAF3FYiOTvpZRGM=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF2+mwCOqh1UGk=" + }, + "tail": { + "$ref": "AAAAAAF2+n8X9HOVNKs=" + }, + "lineStyle": 1, + "points": "680:407;1088:123", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF3FYiOTvpckKI=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF3FYiOTvpdswc=" + }, + "propertyLabel": { + "$ref": "AAAAAAF3FYiOTvpeCiY=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF3FYiOTvpf64s=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF3FYiOTvpgCV4=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF3FYiOTvph4mg=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF3FYiOTvpiVXw=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF3FYiOTvpj6rs=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF3FYiOTvpkLlM=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF3FYiOTvplKeU=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF3FYiOTvpmbVY=" + } + }, + { + "_type": "UMLAssociationView", + "_id": "AAAAAAF3FYjyg/5tJuM=", + "_parent": { + "$ref": "AAAAAAF2+mcHh6BjMLk=" + }, + "model": { + "$ref": "AAAAAAF3FYjyg/5pmRs=" + }, + "subViews": [ + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYjyg/5u2LA=", + "_parent": { + "$ref": "AAAAAAF3FYjyg/5tJuM=" + }, + "model": { + "$ref": "AAAAAAF3FYjyg/5pmRs=" + }, + "font": "Arial;13;0", + "left": 907, + "top": 613, + "width": 163.864990234375, + "height": 13, + "alpha": -2.906930651480722, + "distance": 49.64876634922564, + "hostEdge": { + "$ref": "AAAAAAF3FYjyg/5tJuM=" + }, + "edgePosition": 1, + "text": "+未通过检测,选择清空测回" + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYjyg/5vWMM=", + "_parent": { + "$ref": "AAAAAAF3FYjyg/5tJuM=" + }, + "model": { + "$ref": "AAAAAAF3FYjyg/5pmRs=" + }, + "visible": null, + "font": "Arial;13;0", + "left": 1049, + "top": 630, + "height": 13, + "alpha": 1.5707963267948966, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF3FYjyg/5tJuM=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYjyhP5wgnA=", + "_parent": { + "$ref": "AAAAAAF3FYjyg/5tJuM=" + }, + "model": { + "$ref": "AAAAAAF3FYjyg/5pmRs=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1012, + "top": 655, + "height": 13, + "alpha": -1.5707963267948966, + "distance": 15, + "hostEdge": { + "$ref": "AAAAAAF3FYjyg/5tJuM=" + }, + "edgePosition": 1 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYjyhP5x/LY=", + "_parent": { + "$ref": "AAAAAAF3FYjyg/5tJuM=" + }, + "model": { + "$ref": "AAAAAAF3FYjyg/5q+Kw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 986, + "top": 562, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF3FYjyg/5tJuM=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYjyhP5yX1g=", + "_parent": { + "$ref": "AAAAAAF3FYjyg/5tJuM=" + }, + "model": { + "$ref": "AAAAAAF3FYjyg/5q+Kw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 999, + "top": 556, + "height": 13, + "alpha": 0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF3FYjyg/5tJuM=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYjyhP5z07A=", + "_parent": { + "$ref": "AAAAAAF3FYjyg/5tJuM=" + }, + "model": { + "$ref": "AAAAAAF3FYjyg/5q+Kw=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 961, + "top": 573, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF3FYjyg/5tJuM=" + }, + "edgePosition": 2 + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYjyhP502Qw=", + "_parent": { + "$ref": "AAAAAAF3FYjyg/5tJuM=" + }, + "model": { + "$ref": "AAAAAAF3FYjyg/5rtgo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1089, + "top": 715, + "height": 13, + "alpha": -0.5235987755982988, + "distance": 30, + "hostEdge": { + "$ref": "AAAAAAF3FYjyg/5tJuM=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYjyhP51mnU=", + "_parent": { + "$ref": "AAAAAAF3FYjyg/5tJuM=" + }, + "model": { + "$ref": "AAAAAAF3FYjyg/5rtgo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1098, + "top": 705, + "height": 13, + "alpha": -0.7853981633974483, + "distance": 40, + "hostEdge": { + "$ref": "AAAAAAF3FYjyg/5tJuM=" + } + }, + { + "_type": "EdgeLabelView", + "_id": "AAAAAAF3FYjyhP52OCQ=", + "_parent": { + "$ref": "AAAAAAF3FYjyg/5tJuM=" + }, + "model": { + "$ref": "AAAAAAF3FYjyg/5rtgo=" + }, + "visible": false, + "font": "Arial;13;0", + "left": 1068, + "top": 733, + "height": 13, + "alpha": 0.5235987755982988, + "distance": 25, + "hostEdge": { + "$ref": "AAAAAAF3FYjyg/5tJuM=" + } + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF3FYjyhP53e10=", + "_parent": { + "$ref": "AAAAAAF3FYjyg/5tJuM=" + }, + "model": { + "$ref": "AAAAAAF3FYjyg/5q+Kw=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + }, + { + "_type": "UMLQualifierCompartmentView", + "_id": "AAAAAAF3FYjyhP54iWg=", + "_parent": { + "$ref": "AAAAAAF3FYjyg/5tJuM=" + }, + "model": { + "$ref": "AAAAAAF3FYjyg/5rtgo=" + }, + "visible": false, + "font": "Arial;13;0", + "width": 10, + "height": 10 + } + ], + "font": "Arial;13;0", + "head": { + "$ref": "AAAAAAF2+mq6h6SuwYA=" + }, + "tail": { + "$ref": "AAAAAAF2+nRKkx5Vaw4=" + }, + "lineStyle": 1, + "points": "960:555;1091:751", + "showVisibility": true, + "nameLabel": { + "$ref": "AAAAAAF3FYjyg/5u2LA=" + }, + "stereotypeLabel": { + "$ref": "AAAAAAF3FYjyg/5vWMM=" + }, + "propertyLabel": { + "$ref": "AAAAAAF3FYjyhP5wgnA=" + }, + "tailRoleNameLabel": { + "$ref": "AAAAAAF3FYjyhP5x/LY=" + }, + "tailPropertyLabel": { + "$ref": "AAAAAAF3FYjyhP5yX1g=" + }, + "tailMultiplicityLabel": { + "$ref": "AAAAAAF3FYjyhP5z07A=" + }, + "headRoleNameLabel": { + "$ref": "AAAAAAF3FYjyhP502Qw=" + }, + "headPropertyLabel": { + "$ref": "AAAAAAF3FYjyhP51mnU=" + }, + "headMultiplicityLabel": { + "$ref": "AAAAAAF3FYjyhP52OCQ=" + }, + "tailQualifiersCompartment": { + "$ref": "AAAAAAF3FYjyhP53e10=" + }, + "headQualifiersCompartment": { + "$ref": "AAAAAAF3FYjyhP54iWg=" + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF2+mcRVqBmJfY=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "doSurveyor", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF2+memFKDDSP0=", + "_parent": { + "$ref": "AAAAAAF2+mcRVqBmJfY=" + }, + "name": "成功", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+memFaDE9N8=", + "_parent": { + "$ref": "AAAAAAF2+memFKDDSP0=" + }, + "reference": { + "$ref": "AAAAAAF2+mcRVqBmJfY=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+memFaDFhUw=", + "_parent": { + "$ref": "AAAAAAF2+memFKDDSP0=" + }, + "reference": { + "$ref": "AAAAAAF2+mdRV6CVRE8=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF2+mglyqGKrLA=", + "_parent": { + "$ref": "AAAAAAF2+mcRVqBmJfY=" + }, + "name": "测量失败次数过多", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+mgly6GLeNY=", + "_parent": { + "$ref": "AAAAAAF2+mglyqGKrLA=" + }, + "reference": { + "$ref": "AAAAAAF2+mcRVqBmJfY=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+mgly6GM4vI=", + "_parent": { + "$ref": "AAAAAAF2+mglyqGKrLA=" + }, + "reference": { + "$ref": "AAAAAAF2+mgPp6E+Z94=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF2+mlDdqJrvAs=", + "_parent": { + "$ref": "AAAAAAF2+mcRVqBmJfY=" + }, + "name": "测量失败,又没有允许重复尝试", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+mlDdqJshZY=", + "_parent": { + "$ref": "AAAAAAF2+mlDdqJrvAs=" + }, + "reference": { + "$ref": "AAAAAAF2+mcRVqBmJfY=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+mlDdqJtw60=", + "_parent": { + "$ref": "AAAAAAF2+mlDdqJrvAs=" + }, + "reference": { + "$ref": "AAAAAAF2+mkD1KIH4O4=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF2+mdRV6CVRE8=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "checkReadData", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF2+moC5KQL07Q=", + "_parent": { + "$ref": "AAAAAAF2+mdRV6CVRE8=" + }, + "name": "通过检测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+moC5KQMlXg=", + "_parent": { + "$ref": "AAAAAAF2+moC5KQL07Q=" + }, + "reference": { + "$ref": "AAAAAAF2+mdRV6CVRE8=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+moC5KQNhhs=", + "_parent": { + "$ref": "AAAAAAF2+moC5KQL07Q=" + }, + "reference": { + "$ref": "AAAAAAF2+mntyKOMDSM=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF2+mrOv6VGNxM=", + "_parent": { + "$ref": "AAAAAAF2+mdRV6CVRE8=" + }, + "name": "未通过检测提示目标两次读数超限请重新测量", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+mrOv6VHNRw=", + "_parent": { + "$ref": "AAAAAAF2+mrOv6VGNxM=" + }, + "reference": { + "$ref": "AAAAAAF2+mdRV6CVRE8=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+mrOv6VIVq0=", + "_parent": { + "$ref": "AAAAAAF2+mrOv6VGNxM=" + }, + "reference": { + "$ref": "AAAAAAF2+mwCOqhz6ko=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF2+mgPp6E+Z94=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "RecordDirty" + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF2+mkD1KIH4O4=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "SurveyorFailure", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF2+n5IxmZmfb4=", + "_parent": { + "$ref": "AAAAAAF2+mkD1KIH4O4=" + }, + "name": "决定跳过", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+n5IxmZn2bs=", + "_parent": { + "$ref": "AAAAAAF2+n5IxmZmfb4=" + }, + "reference": { + "$ref": "AAAAAAF2+mkD1KIH4O4=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+n5IxmZowY8=", + "_parent": { + "$ref": "AAAAAAF2+n5IxmZmfb4=" + }, + "reference": { + "$ref": "AAAAAAF2+n3z62QBjMI=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF2+n7Ipmp5/TQ=", + "_parent": { + "$ref": "AAAAAAF2+mkD1KIH4O4=" + }, + "name": "取消跳过", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+n7Ipmp6n4I=", + "_parent": { + "$ref": "AAAAAAF2+n7Ipmp5/TQ=" + }, + "reference": { + "$ref": "AAAAAAF2+mkD1KIH4O4=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+n7Ipmp7myU=", + "_parent": { + "$ref": "AAAAAAF2+n7Ipmp5/TQ=" + }, + "reference": { + "$ref": "AAAAAAF2+mwCOqhz6ko=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF2+mntyKOMDSM=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "isHalfCycleZeroCheckReady", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF2+mvs0qcw0ng=", + "_parent": { + "$ref": "AAAAAAF2+mntyKOMDSM=" + }, + "name": "满足条件", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+mvs0qcx6HM=", + "_parent": { + "$ref": "AAAAAAF2+mvs0qcw0ng=" + }, + "reference": { + "$ref": "AAAAAAF2+mntyKOMDSM=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+mvs0qcyuaY=", + "_parent": { + "$ref": "AAAAAAF2+mvs0qcw0ng=" + }, + "reference": { + "$ref": "AAAAAAF2+mvXKaZ71tg=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF2+m650rJ78WY=", + "_parent": { + "$ref": "AAAAAAF2+mntyKOMDSM=" + }, + "name": "不满足", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+m650rJ8zw4=", + "_parent": { + "$ref": "AAAAAAF2+m650rJ78WY=" + }, + "reference": { + "$ref": "AAAAAAF2+mntyKOMDSM=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+m650rJ9BDM=", + "_parent": { + "$ref": "AAAAAAF2+m650rJ78WY=" + }, + "reference": { + "$ref": "AAAAAAF2+m3Ng67UQ3Q=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF2+mq6h6Ss6fQ=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "doDeleteCurrentCycle", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF2+mw/ialD1P0=", + "_parent": { + "$ref": "AAAAAAF2+mq6h6Ss6fQ=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+mw/iqlEWtE=", + "_parent": { + "$ref": "AAAAAAF2+mw/ialD1P0=" + }, + "reference": { + "$ref": "AAAAAAF2+mq6h6Ss6fQ=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+mw/iqlF64M=", + "_parent": { + "$ref": "AAAAAAF2+mw/ialD1P0=" + }, + "reference": { + "$ref": "AAAAAAF2+mwCOqhz6ko=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF2+mvXKaZ71tg=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "checkHalfCycleZero", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF2+m3lu6+/SvE=", + "_parent": { + "$ref": "AAAAAAF2+mvXKaZ71tg=" + }, + "name": "通过检测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+m3lu6/AYdA=", + "_parent": { + "$ref": "AAAAAAF2+m3lu6+/SvE=" + }, + "reference": { + "$ref": "AAAAAAF2+mvXKaZ71tg=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+m3lu6/BCoQ=", + "_parent": { + "$ref": "AAAAAAF2+m3lu6+/SvE=" + }, + "reference": { + "$ref": "AAAAAAF2+m3Ng67UQ3Q=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF2+m4Cd7DMOyM=", + "_parent": { + "$ref": "AAAAAAF2+mvXKaZ71tg=" + }, + "name": "未通过检测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+m4Cd7DNh98=", + "_parent": { + "$ref": "AAAAAAF2+m4Cd7DMOyM=" + }, + "reference": { + "$ref": "AAAAAAF2+mvXKaZ71tg=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+m4Cd7DOnkA=", + "_parent": { + "$ref": "AAAAAAF2+m4Cd7DMOyM=" + }, + "reference": { + "$ref": "AAAAAAF2+mq6h6Ss6fQ=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF2+mwCOqhz6ko=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "Idle" + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF2+m3Ng67UQ3Q=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "isReady2CCheck", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF2+m/aRbZjsQw=", + "_parent": { + "$ref": "AAAAAAF2+m3Ng67UQ3Q=" + }, + "name": "满足条件", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+m/aRbZkwdI=", + "_parent": { + "$ref": "AAAAAAF2+m/aRbZjsQw=" + }, + "reference": { + "$ref": "AAAAAAF2+m3Ng67UQ3Q=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+m/aRbZlRAA=", + "_parent": { + "$ref": "AAAAAAF2+m/aRbZjsQw=" + }, + "reference": { + "$ref": "AAAAAAF2+m+73LQ2jlo=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF2+nJuA+oxvHQ=", + "_parent": { + "$ref": "AAAAAAF2+m3Ng67UQ3Q=" + }, + "name": "不满足条件", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+nJuA+oyVzg=", + "_parent": { + "$ref": "AAAAAAF2+nJuA+oxvHQ=" + }, + "reference": { + "$ref": "AAAAAAF2+m3Ng67UQ3Q=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+nJuA+ozWP8=", + "_parent": { + "$ref": "AAAAAAF2+nJuA+oxvHQ=" + }, + "reference": { + "$ref": "AAAAAAF2+nIhauTyfGU=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF2+m+73LQ2jlo=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "check2C", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF2+nC6YsguVIY=", + "_parent": { + "$ref": "AAAAAAF2+m+73LQ2jlo=" + }, + "name": "通过检测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+nC6Y8gvJw0=", + "_parent": { + "$ref": "AAAAAAF2+nC6YsguVIY=" + }, + "reference": { + "$ref": "AAAAAAF2+m+73LQ2jlo=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+nC6Y8gwxpA=", + "_parent": { + "$ref": "AAAAAAF2+nC6YsguVIY=" + }, + "reference": { + "$ref": "AAAAAAF2+nIhauTyfGU=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF2+owe6Cfh2+U=", + "_parent": { + "$ref": "AAAAAAF2+m+73LQ2jlo=" + }, + "name": "忽略错误", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+owe6CfiblE=", + "_parent": { + "$ref": "AAAAAAF2+owe6Cfh2+U=" + }, + "reference": { + "$ref": "AAAAAAF2+m+73LQ2jlo=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+owe6CfjEGs=", + "_parent": { + "$ref": "AAAAAAF2+owe6Cfh2+U=" + }, + "reference": { + "$ref": "AAAAAAF2/55prRrd34g=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF3AAkuEf3qL3g=", + "_parent": { + "$ref": "AAAAAAF2+m+73LQ2jlo=" + }, + "name": "重新测量", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF3AAkuEf3rpYI=", + "_parent": { + "$ref": "AAAAAAF3AAkuEf3qL3g=" + }, + "reference": { + "$ref": "AAAAAAF2+m+73LQ2jlo=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF3AAkuEf3seOw=", + "_parent": { + "$ref": "AAAAAAF3AAkuEf3qL3g=" + }, + "reference": { + "$ref": "AAAAAAF2+mwCOqhz6ko=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF3AAllGAV08Nw=", + "_parent": { + "$ref": "AAAAAAF2+m+73LQ2jlo=" + }, + "name": "清空测量", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF3AAllGAV1sLI=", + "_parent": { + "$ref": "AAAAAAF3AAllGAV08Nw=" + }, + "reference": { + "$ref": "AAAAAAF2+m+73LQ2jlo=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF3AAllGAV2oyY=", + "_parent": { + "$ref": "AAAAAAF3AAllGAV08Nw=" + }, + "reference": { + "$ref": "AAAAAAF2+nmf8//EQJ0=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF2+nB7EcWt+n8=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "isSingleCycleCompleted", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF2+nQJohB/pjc=", + "_parent": { + "$ref": "AAAAAAF2+nB7EcWt+n8=" + }, + "name": "未通过", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+nQJohCAKVI=", + "_parent": { + "$ref": "AAAAAAF2+nQJohB/pjc=" + }, + "reference": { + "$ref": "AAAAAAF2+nB7EcWt+n8=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+nQJohCBbxs=", + "_parent": { + "$ref": "AAAAAAF2+nQJohB/pjc=" + }, + "reference": { + "$ref": "AAAAAAF2+n8X9HOTo5I=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF2+nS1vB/7hWk=", + "_parent": { + "$ref": "AAAAAAF2+nB7EcWt+n8=" + }, + "name": "满足条件", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+nS1vB/8CFI=", + "_parent": { + "$ref": "AAAAAAF2+nS1vB/7hWk=" + }, + "reference": { + "$ref": "AAAAAAF2+nB7EcWt+n8=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+nS1vB/9vRE=", + "_parent": { + "$ref": "AAAAAAF2+nS1vB/7hWk=" + }, + "reference": { + "$ref": "AAAAAAF2+nRKkx5T21c=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF2+nIhauTyfGU=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "doRecordClean", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF2+n9ElngPQXA=", + "_parent": { + "$ref": "AAAAAAF2+nIhauTyfGU=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+n9ElngQC7s=", + "_parent": { + "$ref": "AAAAAAF2+n9ElngPQXA=" + }, + "reference": { + "$ref": "AAAAAAF2+nIhauTyfGU=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+n9ElngRO/w=", + "_parent": { + "$ref": "AAAAAAF2+n9ElngPQXA=" + }, + "reference": { + "$ref": "AAAAAAF2+n8X9HOTo5I=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF3ABeWIk8kkqs=", + "_parent": { + "$ref": "AAAAAAF2+nIhauTyfGU=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF3ABeWIk8l/nk=", + "_parent": { + "$ref": "AAAAAAF3ABeWIk8kkqs=" + }, + "reference": { + "$ref": "AAAAAAF2+nIhauTyfGU=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF3ABeWIk8mwTw=", + "_parent": { + "$ref": "AAAAAAF3ABeWIk8kkqs=" + }, + "reference": { + "$ref": "AAAAAAF2+nB7EcWt+n8=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF2+nRKkx5T21c=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "checkSingleCycle", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF2+nhS8LdviJA=", + "_parent": { + "$ref": "AAAAAAF2+nRKkx5T21c=" + }, + "name": "通过检测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+nhS8bdwtKo=", + "_parent": { + "$ref": "AAAAAAF2+nhS8LdviJA=" + }, + "reference": { + "$ref": "AAAAAAF2+nRKkx5T21c=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+nhS8bdxqW4=", + "_parent": { + "$ref": "AAAAAAF2+nhS8LdviJA=" + }, + "reference": { + "$ref": "AAAAAAF2+nfCMJ2/R+8=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF2+nm/XgG9mDY=", + "_parent": { + "$ref": "AAAAAAF2+nRKkx5T21c=" + }, + "name": "未通过检测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+nm/XgG+7Ao=", + "_parent": { + "$ref": "AAAAAAF2+nm/XgG9mDY=" + }, + "reference": { + "$ref": "AAAAAAF2+nRKkx5T21c=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+nm/XgG/cLw=", + "_parent": { + "$ref": "AAAAAAF2+nm/XgG9mDY=" + }, + "reference": { + "$ref": "AAAAAAF2+nmf8//EQJ0=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF3FYXf8tUp5SY=", + "_parent": { + "$ref": "AAAAAAF2+nRKkx5T21c=" + }, + "name": "通过检测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF3FYXf8tUqXjA=", + "_parent": { + "$ref": "AAAAAAF3FYXf8tUp5SY=" + }, + "reference": { + "$ref": "AAAAAAF2+nRKkx5T21c=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF3FYXf89Uremo=", + "_parent": { + "$ref": "AAAAAAF3FYXf8tUp5SY=" + }, + "reference": { + "$ref": "AAAAAAF2+nfCMJ2/R+8=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF3FYfmm/CEg44=", + "_parent": { + "$ref": "AAAAAAF2+nRKkx5T21c=" + }, + "name": "未通过检测,将补测数据标识为dirty", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF3FYfmm/CF45U=", + "_parent": { + "$ref": "AAAAAAF3FYfmm/CEg44=" + }, + "reference": { + "$ref": "AAAAAAF2+nRKkx5T21c=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF3FYfmm/CGlMo=", + "_parent": { + "$ref": "AAAAAAF3FYfmm/CEg44=" + }, + "reference": { + "$ref": "AAAAAAF2+n8X9HOTo5I=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF3FYjyg/5pmRs=", + "_parent": { + "$ref": "AAAAAAF2+nRKkx5T21c=" + }, + "name": "未通过检测,选择清空测回", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF3FYjyg/5q+Kw=", + "_parent": { + "$ref": "AAAAAAF3FYjyg/5pmRs=" + }, + "reference": { + "$ref": "AAAAAAF2+nRKkx5T21c=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF3FYjyg/5rtgo=", + "_parent": { + "$ref": "AAAAAAF3FYjyg/5pmRs=" + }, + "reference": { + "$ref": "AAAAAAF2+mq6h6Ss6fQ=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF2+nWEKyMuLhQ=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "isAllCycleCompleted" + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF2+nfCMJ2/R+8=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "isAllCycleCompleted", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF2+nkxU+qk8wM=", + "_parent": { + "$ref": "AAAAAAF2+nfCMJ2/R+8=" + }, + "name": "不满足条件", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+nkxVOqlU+M=", + "_parent": { + "$ref": "AAAAAAF2+nkxU+qk8wM=" + }, + "reference": { + "$ref": "AAAAAAF2+nfCMJ2/R+8=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+nkxVOqmmi4=", + "_parent": { + "$ref": "AAAAAAF2+nkxU+qk8wM=" + }, + "reference": { + "$ref": "AAAAAAF2+nIhauTyfGU=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF2+nsWEifnmc4=", + "_parent": { + "$ref": "AAAAAAF2+nfCMJ2/R+8=" + }, + "name": "满足条件", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+nsWEifod44=", + "_parent": { + "$ref": "AAAAAAF2+nsWEifnmc4=" + }, + "reference": { + "$ref": "AAAAAAF2+nfCMJ2/R+8=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+nsWEifpM0I=", + "_parent": { + "$ref": "AAAAAAF2+nsWEifnmc4=" + }, + "reference": { + "$ref": "AAAAAAF2+nq2QxzDZ/U=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF3FYY3ONi1k54=", + "_parent": { + "$ref": "AAAAAAF2+nfCMJ2/R+8=" + }, + "name": "未完成", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF3FYY3Odi2Kgc=", + "_parent": { + "$ref": "AAAAAAF3FYY3ONi1k54=" + }, + "reference": { + "$ref": "AAAAAAF2+nfCMJ2/R+8=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF3FYY3Odi3/4g=", + "_parent": { + "$ref": "AAAAAAF3FYY3ONi1k54=" + }, + "reference": { + "$ref": "AAAAAAF2+mwCOqhz6ko=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF2+nmf8//EQJ0=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "doDeleteAllCycle", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF2+nnjTAPYxiQ=", + "_parent": { + "$ref": "AAAAAAF2+nmf8//EQJ0=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+nnjTAPZd8A=", + "_parent": { + "$ref": "AAAAAAF2+nnjTAPYxiQ=" + }, + "reference": { + "$ref": "AAAAAAF2+nmf8//EQJ0=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+nnjTAPaO1I=", + "_parent": { + "$ref": "AAAAAAF2+nnjTAPYxiQ=" + }, + "reference": { + "$ref": "AAAAAAF2+mwCOqhz6ko=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF3AAi3NfRr6EY=", + "_parent": { + "$ref": "AAAAAAF2+nmf8//EQJ0=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF3AAi3NfRsLF0=", + "_parent": { + "$ref": "AAAAAAF3AAi3NfRr6EY=" + }, + "reference": { + "$ref": "AAAAAAF2+nmf8//EQJ0=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF3AAi3NfRtPso=", + "_parent": { + "$ref": "AAAAAAF3AAi3NfRr6EY=" + }, + "reference": { + "$ref": "AAAAAAF2+mwCOqhz6ko=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF2+nq2QxzDZ/U=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "checkAllCycle", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF2+ntEUyxG5GE=", + "_parent": { + "$ref": "AAAAAAF2+nq2QxzDZ/U=" + }, + "name": "通过检测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+ntEUyxHkJg=", + "_parent": { + "$ref": "AAAAAAF2+ntEUyxG5GE=" + }, + "reference": { + "$ref": "AAAAAAF2+nq2QxzDZ/U=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+ntEUyxITXI=", + "_parent": { + "$ref": "AAAAAAF2+ntEUyxG5GE=" + }, + "reference": { + "$ref": "AAAAAAF2+nsueSp07D8=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF2+nt66S40Bz8=", + "_parent": { + "$ref": "AAAAAAF2+nq2QxzDZ/U=" + }, + "name": "未通过检测", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+nt66S41kFQ=", + "_parent": { + "$ref": "AAAAAAF2+nt66S40Bz8=" + }, + "reference": { + "$ref": "AAAAAAF2+nq2QxzDZ/U=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+nt66S42nQw=", + "_parent": { + "$ref": "AAAAAAF2+nt66S40Bz8=" + }, + "reference": { + "$ref": "AAAAAAF2+nmf8//EQJ0=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF2+nsueSp07D8=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "Finish" + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF2+n3z62QBjMI=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "doRecordSkip", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF2+n81lnZzRwY=", + "_parent": { + "$ref": "AAAAAAF2+n3z62QBjMI=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+n81lnZ00eg=", + "_parent": { + "$ref": "AAAAAAF2+n81lnZzRwY=" + }, + "reference": { + "$ref": "AAAAAAF2+n3z62QBjMI=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+n81lnZ1tkU=", + "_parent": { + "$ref": "AAAAAAF2+n81lnZzRwY=" + }, + "reference": { + "$ref": "AAAAAAF2+n8X9HOTo5I=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF2+n8X9HOTo5I=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "doMove2NextValidate", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF2+oUnnx1ORxs=", + "_parent": { + "$ref": "AAAAAAF2+n8X9HOTo5I=" + }, + "name": "计算下一个目标", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+oUnnx1PoOw=", + "_parent": { + "$ref": "AAAAAAF2+oUnnx1ORxs=" + }, + "reference": { + "$ref": "AAAAAAF2+n8X9HOTo5I=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2+oUnnx1Q1uk=", + "_parent": { + "$ref": "AAAAAAF2+oUnnx1ORxs=" + }, + "reference": { + "$ref": "AAAAAAF2+mwCOqhz6ko=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF3FYiOTvpXxUA=", + "_parent": { + "$ref": "AAAAAAF2+n8X9HOTo5I=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF3FYiOTvpYHAk=", + "_parent": { + "$ref": "AAAAAAF3FYiOTvpXxUA=" + }, + "reference": { + "$ref": "AAAAAAF2+n8X9HOTo5I=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF3FYiOTvpZRGM=", + "_parent": { + "$ref": "AAAAAAF3FYiOTvpXxUA=" + }, + "reference": { + "$ref": "AAAAAAF2+mwCOqhz6ko=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF2/55prRrd34g=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "doRecordDirty", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF2/57X7ycUMD0=", + "_parent": { + "$ref": "AAAAAAF2/55prRrd34g=" + }, + "name": "单测回完成", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2/57X7ycVqls=", + "_parent": { + "$ref": "AAAAAAF2/57X7ycUMD0=" + }, + "reference": { + "$ref": "AAAAAAF2/55prRrd34g=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2/57X7ycW028=", + "_parent": { + "$ref": "AAAAAAF2/57X7ycUMD0=" + }, + "reference": { + "$ref": "AAAAAAF2+nB7EcWt+n8=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF3ABn9InDG0I8=", + "_parent": { + "$ref": "AAAAAAF2/55prRrd34g=" + }, + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF3ABn9InDHYy0=", + "_parent": { + "$ref": "AAAAAAF3ABn9InDG0I8=" + }, + "reference": { + "$ref": "AAAAAAF2/55prRrd34g=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF3ABn9InDIm3A=", + "_parent": { + "$ref": "AAAAAAF3ABn9InDG0I8=" + }, + "reference": { + "$ref": "AAAAAAF2+nB7EcWt+n8=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF2/+4lLTMZ3R0=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "isSingleCycleCompletedAfterDirty", + "ownedElements": [ + { + "_type": "UMLAssociation", + "_id": "AAAAAAF2/+8EZEWEVSo=", + "_parent": { + "$ref": "AAAAAAF2/+4lLTMZ3R0=" + }, + "name": "单测回未完成", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2/+8EZEWFV4M=", + "_parent": { + "$ref": "AAAAAAF2/+8EZEWEVSo=" + }, + "reference": { + "$ref": "AAAAAAF2/55prRrd34g=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2/+8EZEWGccA=", + "_parent": { + "$ref": "AAAAAAF2/+8EZEWEVSo=" + }, + "reference": { + "$ref": "AAAAAAF2+n8X9HOTo5I=" + } + } + }, + { + "_type": "UMLAssociation", + "_id": "AAAAAAF2/+8rLEgaoTY=", + "_parent": { + "$ref": "AAAAAAF2/+4lLTMZ3R0=" + }, + "name": "满足", + "end1": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2/+8rLEgb+jA=", + "_parent": { + "$ref": "AAAAAAF2/+8rLEgaoTY=" + }, + "reference": { + "$ref": "AAAAAAF2/+4lLTMZ3R0=" + }, + "navigable": false + }, + "end2": { + "_type": "UMLAssociationEnd", + "_id": "AAAAAAF2/+8rLEgciEE=", + "_parent": { + "$ref": "AAAAAAF2/+8rLEgaoTY=" + }, + "reference": { + "$ref": "AAAAAAF2+nRKkx5T21c=" + } + } + } + ] + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF2/+6bzj11GxQ=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "checkSingleCycleAfterDirty" + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF3FYZbFNt+k4c=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "需要补测" + }, + { + "_type": "UMLUseCase", + "_id": "AAAAAAF3FYeGOuxZC7s=", + "_parent": { + "$ref": "AAAAAAFF+qBWK6M3Z8Y=" + }, + "name": "补测" + } + ] + } + ] +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/App.java b/app/src/main/java/com/bingce/controlnetwork/App.java new file mode 100644 index 0000000..fc35294 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/App.java @@ -0,0 +1,202 @@ +package com.bingce.controlnetwork; + +import static com.bingce.AppChannel.customChannel; + +import android.content.SharedPreferences; +import android.graphics.drawable.Drawable; +import android.net.Uri; +import android.text.TextUtils; +import android.util.Log; +import android.widget.ImageView; + +import androidx.preference.PreferenceManager; + +import com.bingce.AppChannel; +import com.bingce.RepositoryBaseApp; +import com.bingce.controlapphelper.datasource.database.SurveyorDataBase; +import com.bingce.controlapphelper.datasource.database.tolerance.load.ToleranceLoadUtil; +import com.bingce.controlapphelper.surveyor.surveyor.ISurveyorConstants; +import com.bingce.controlapphelper.util.SettingValueUtil; +import com.bingce.controlnetwork.activity.NotificationActivity; +import com.bingce.utils.DES; +import com.bingce.utils.ThreadPoolUtil; +import com.bumptech.glide.Glide; +import com.mikepenz.materialdrawer.util.AbstractDrawerImageLoader; +import com.mikepenz.materialdrawer.util.DrawerImageLoader; +import com.umeng.commonsdk.UMConfigure; + +import net.tatans.tensorflowtts.tts.TtsManager; + +import org.polaric.colorful.Colorful; + +import blankj.utilcode.util.ActivityUtils; +import blankj.utilcode.util.Utils; +import cn.leancloud.LCInstallation; +import cn.leancloud.LCLogger; +import cn.leancloud.LeanCloud; +import cn.leancloud.push.PushService; +import cn.liuyanbing.surveyor.AppConfig; +import io.reactivex.functions.Consumer; +import io.reactivex.plugins.RxJavaPlugins; + +public class App extends RepositoryBaseApp { + + /** + * 试用次数 + */ + public int tryCount = 0; //非setting + /** + * 上次手动点击跳过首屏广告的时间 + */ + public long lastSplashShowTime = 0;//非setting + /** + * 磁偏角,用于校正指南针 + */ + public float magneticDeclination = 0; + /** + * 蓝牙是否连接 + */ + public boolean isBluetoothConnected = false; + /** + * 蓝牙是否重连 + */ + public boolean isBluetoothReconnect = false; + /** + * 退出软件后是否关闭设备 + */ + public boolean isCloseInstrumentAfterExit = false; + /** + * 用户状态发生变化,例如登录 + */ + public boolean isUserStatusChanged = false; + /** + * 注册码第二版 + */ + public String registerCodeV2 = ""; + + public String wifiChatClientIp = ""; + public String lastPhoneLocation = ""; + + public String levelSurveyorTime; + + private static App app; + + @Override + public void onCreate() { + customChannel = AppChannel.CUSTOM_CONTROL_PUBLIC;//AppChannel.CUSTOM_PUBLIC; + super.onCreate(); + app = this; + + initThemeDark(); + + RxJavaPlugins.setErrorHandler(new Consumer() { + @Override + public void accept(Throwable throwable) { + Log.e("rxThrowable", String.valueOf(throwable)); + } + }); + + UMConfigure.preInit(this, "62c2c24705844627b5d6f943", "public"); + + // 在 LeanCloud.initialize() 之前调用 + LeanCloud.setLogLevel(LCLogger.Level.DEBUG); + + LeanCloud.initialize(this + , DES.decryptIt("//HYY/P0uNjW2bvmcfWVsRqUZcBGI1mjKeLw17mtlc4poF3nDQzo0Q==")//id,BvjcpX3kNB69xP8N0fHxDQav-gzGzoHsz + , DES.decryptIt("LBk6WfZhiDVIlf/vpesX6s8j4ik+d23atgE0QGuwyw8=") + , "https://leancloud.bingce.com"); + + PushService.setDefaultPushCallback(this, NotificationActivity.class); + PushService.setAutoWakeUp(true); + PushService.setDefaultChannelId(this, "normal"); + LCInstallation.getCurrentInstallation().saveInBackground().subscribe(); + + DrawerImageLoader.init(new AbstractDrawerImageLoader() { + @Override + public void set(ImageView imageView, Uri uri, Drawable placeholder) { +// Picasso.get().load(uri).placeholder(placeholder).into(imageView); + Glide.with(App.this).load(uri).into(imageView); + } + + @Override + public void cancel(ImageView imageView) { + Glide.with(App.this).clear(imageView); +// Picasso.get().cancelRequest(imageView); + } + }); + + restorePrefs(); + + if (customChannel == AppChannel.CUSTOM_CONTROL_PRO) { + Colorful.config(this).primaryColor(Colorful.ThemeColor.BROWN).apply(); + Colorful.config(this).accentColor(Colorful.ThemeColor.BROWN).apply(); + } + + + initControlApp(); + } + + private void initThemeDark() { + Colorful.defaults() + .primaryColor(Colorful.ThemeColor.BLUE) + .accentColor(Colorful.ThemeColor.BLUE) + .translucent(false) + .dark(SettingValueUtil.isThemeDark()); + Colorful.init(this); + } + + private void restorePrefs() { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); + registerCodeV2 = prefs.getString("registerCodeV2", ""); + lastSplashShowTime = prefs.getLong("lastSplashShowTime", 0); + wifiChatClientIp = prefs.getString("wifiChatClientIp", ""); + isCloseInstrumentAfterExit = prefs.getBoolean("isCloseInstrumentAfterExit", false); + magneticDeclination = prefs.getFloat("magneticDeclination", 0); + lastPhoneLocation = prefs.getString("lastPhoneLocation", ""); + levelSurveyorTime = prefs.getString("levelSurveyorTime", "1"); + if (TextUtils.isEmpty(levelSurveyorTime)) { + levelSurveyorTime = "1"; + } + } + + @Override + public void onTrimMemory(int level) { + super.onTrimMemory(level); + if (level == TRIM_MEMORY_MODERATE) { + //开始自杀,清场掉所有的activity + ActivityUtils.finishAllActivities(); + } + } + + @Override + public String applicationId() { + return BuildConfig.APPLICATION_ID; + } + + @Override + public boolean isThemeDark() { + return false; + } + + @Override + public int angleNotNumber() { + return AppConfig.instance.angleDotNum(); + } + + public static App getApp() { + return app; + } + + @Override + protected void initTtsManager() { + TtsManager.getInstance().init(this); + } + + private void initControlApp() { + ISurveyorConstants.isOpenAtr = SettingValueUtil.isOpenAtr(); + Utils.init(this); + ThreadPoolUtil.execute(ToleranceLoadUtil::init); + //数据库 + SurveyorDataBase.getInstance(); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/activity/AboutActivity.java b/app/src/main/java/com/bingce/controlnetwork/activity/AboutActivity.java new file mode 100644 index 0000000..56fc655 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/activity/AboutActivity.java @@ -0,0 +1,83 @@ +package com.bingce.controlnetwork.activity; + +import android.annotation.SuppressLint; +import android.os.Bundle; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.widget.FrameLayout; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.widget.Toolbar; + +import com.bingce.controlapphelper.util.CheckStorageUtil; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; + +import org.polaric.colorful.ColorfulActivity; + +import blankj.utilcode.util.ToastUtils; +import blankj.utilcode.util.Utils; + +public class AboutActivity extends ColorfulActivity { + private Toolbar mToolbar; + + @SuppressLint("SourceLockedOrientationActivity") + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_about); + mToolbar = findViewById(R.id.toolbar); + setSupportActionBar(mToolbar); + if (getSupportActionBar() != null) + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + final FrameLayout flHolder = findViewById(R.id.activity_about_frame); + View tianjinView = getTianjinView(); + flHolder.addView(tianjinView); + } + + @Override + public boolean onCreateOptionsMenu(@NonNull Menu menu) { + getMenuInflater().inflate(R.menu.menu_activity_about, menu); + return super.onCreateOptionsMenu(menu); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + finish(); + break; + case R.id.menu_debug_switch: + startOpenCloseMeasureDebug(); + break; + } + return super.onOptionsItemSelected(item); + } + + private View getTianjinView() { + View viewTianjin = View.inflate(this, R.layout.item_about_tj_one, null); + TextView tvUnit = viewTianjin.findViewById(R.id.tvUnit); + TextView tvVersion = viewTianjin.findViewById(R.id.tvVersion); + tvVersion.setText("版本:" + Tools.getVersionName()); + return viewTianjin; + } + + /** + * 开始打开或关闭调试 + */ + private void startOpenCloseMeasureDebug() { + CheckStorageUtil.check(this, () -> { + Utils.isTest = !Utils.isTest; + if (Utils.isTest) { + ToastUtils.showShort(R.string.debug_on); + } else { + ToastUtils.showShort(R.string.debug_off); + } + }); + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/activity/BaseActivity.java b/app/src/main/java/com/bingce/controlnetwork/activity/BaseActivity.java new file mode 100644 index 0000000..93d121d --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/activity/BaseActivity.java @@ -0,0 +1,55 @@ +package com.bingce.controlnetwork.activity; + +import android.os.Bundle; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.Nullable; +import androidx.appcompat.widget.Toolbar; + +import org.polaric.colorful.ColorfulActivity; + +import com.bingce.controlnetwork.R; + +public abstract class BaseActivity extends ColorfulActivity { + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + } + + @Override + public void setContentView(View view) { + super.setContentView(view); + Toolbar mToolbar = findViewById(R.id.toolbar); + setSupportActionBar(mToolbar); + if (getSupportActionBar() != null) + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + } + + @Override + public void setContentView(int layoutResID) { + super.setContentView(layoutResID); + Toolbar mToolbar = findViewById(R.id.toolbar); + setSupportActionBar(mToolbar); + if (getSupportActionBar() != null) + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + } + + @Override + public void setContentView(View view, ViewGroup.LayoutParams params) { + super.setContentView(view, params); + Toolbar mToolbar = findViewById(R.id.toolbar); + setSupportActionBar(mToolbar); + if (getSupportActionBar() != null) + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (item.getItemId() == android.R.id.home) { + finish(); + } + return super.onOptionsItemSelected(item); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/activity/ChangelogActivity.java b/app/src/main/java/com/bingce/controlnetwork/activity/ChangelogActivity.java new file mode 100644 index 0000000..ee63361 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/activity/ChangelogActivity.java @@ -0,0 +1,38 @@ +package com.bingce.controlnetwork.activity; + +import android.annotation.SuppressLint; +import android.os.Bundle; +import android.view.MenuItem; + +import androidx.appcompat.widget.Toolbar; + +import org.polaric.colorful.ColorfulActivity; + +import com.bingce.controlnetwork.R; + +/** + * 更新日志 + */ +public class ChangelogActivity extends ColorfulActivity { + private static final String TAG = "ChangelogActivity"; + private Toolbar mToolbar; + + @SuppressLint("SourceLockedOrientationActivity") + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_changelog); + mToolbar = findViewById(R.id.toolbar); + setSupportActionBar(mToolbar); + if (getSupportActionBar() != null) + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (item.getItemId() == android.R.id.home) { + finish(); + } + return super.onOptionsItemSelected(item); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/activity/LogCollectActivity.java b/app/src/main/java/com/bingce/controlnetwork/activity/LogCollectActivity.java new file mode 100644 index 0000000..8f211f7 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/activity/LogCollectActivity.java @@ -0,0 +1,26 @@ +package com.bingce.controlnetwork.activity; + +import android.content.Context; +import android.content.Intent; + +import com.bingce.activity.AbstractLogCollectActivity; + +import com.bingce.controlnetwork.App; +import com.bingce.controlnetwork.BuildConfig; + +public class LogCollectActivity extends AbstractLogCollectActivity { + @Override + protected String applicationId() { + return BuildConfig.APPLICATION_ID; + } + + @Override + protected boolean isLandscape() { + return ((App) getApplication()).isLandscape(); + } + + public static void start(Context context) { + Intent intent = new Intent(context, LogCollectActivity.class); + context.startActivity(intent); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/activity/MainActivity.java b/app/src/main/java/com/bingce/controlnetwork/activity/MainActivity.java new file mode 100644 index 0000000..d5e80c8 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/activity/MainActivity.java @@ -0,0 +1,997 @@ +package com.bingce.controlnetwork.activity; + +import android.annotation.SuppressLint; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.SharedPreferences; +import android.graphics.Color; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; +import android.view.KeyEvent; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.WindowManager; +import android.widget.CheckBox; +import android.widget.CompoundButton; + +import androidx.annotation.NonNull; +import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.Toolbar; +import androidx.core.content.ContextCompat; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; +import androidx.lifecycle.ViewModelProvider; +import androidx.preference.PreferenceManager; +import androidx.viewpager.widget.ViewPager; + +import com.afollestad.materialdialogs.DialogAction; +import com.afollestad.materialdialogs.MaterialDialog; +import com.bingce.AppChannel; +import com.bingce.BaseApp; +import com.bingce.activity.BaseMainActivity; +import com.bingce.controlapphelper.event.DatabaseReadyEvent; +import com.bingce.controlapphelper.event.SwitchPageEvent; +import com.bingce.controlapphelper.util.InterfaceUtil; +import com.bingce.controlapphelper.util.SettingValueUtil; +import com.bingce.controlnetwork.App; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.activity.backup.launch.BackupImportHelper; +import com.bingce.controlnetwork.activity.user.LoginActivity; +import com.bingce.controlnetwork.activity.user.RegisterActivity; +import com.bingce.controlnetwork.activity.user.UserInfoActivity; +import com.bingce.controlnetwork.bean.MainUserBean; +import com.bingce.controlnetwork.fragment.MainSurveyFragment; +import com.bingce.controlnetwork.fragment.ProjectListFragment; +import com.bingce.controlnetwork.newui.configfragment.ConfigFragment; +import com.bingce.controlnetwork.newui.mefragment.MeFragment; +import com.bingce.controlnetwork.util.CheckControlUpdateUtil; +import com.bingce.controlnetwork.viewmodel.MainActivityViewModel; +import com.bingce.data.sync.GlobalFlowCenter; +import com.bingce.data.sync.utils.LeanCloudConfigLoader; +import com.bingce.device.Device; +import com.bingce.device.ui.manager.DeviceConnectManager; +import com.bingce.device.ui.manager.DeviceRemindManager; +import com.bingce.device.ui.manager.DeviceRequestManager; +import com.bingce.event.CountDownEvent; +import com.bingce.event.OpenShortUrlEvent; +import com.bingce.surveyor.agentweb.AgentWebActivity; +import com.bingce.totalstation.TotalStation; +import com.bingce.ui.TabEntity; +import com.bingce.utils.ColorUtil; +import com.bingce.utils.CrashCollector; +import com.bingce.utils.DateUtils; +import com.bingce.utils.LCDeviceUtil; +import com.bingce.utils.SdkUtils; +import com.bingce.utils.ServiceDateUtils; +import com.bingce.utils.SoundPoolUtil; +import com.bingce.utils.StringUtil; +import com.bingce.utils.ThreadPoolUtil; +import com.bingce.utils.Util; +import com.bingce.utils.VipManager; +import com.daimajia.numberprogressbar.NumberProgressBar; +import com.flyco.tablayout.CommonTabLayout; +import com.flyco.tablayout.listener.CustomTabEntity; +import com.flyco.tablayout.listener.OnTabSelectListener; +import com.jkyeo.splashview.SplashView; +import com.mikepenz.iconics.IconicsDrawable; +import com.mikepenz.material_design_iconic_typeface_library.MaterialDesignIconic; +import com.tencent.mm.opensdk.openapi.IWXAPI; +import com.tencent.mm.opensdk.openapi.WXAPIFactory; +import com.umeng.commonsdk.UMConfigure; + +import net.tatans.tensorflowtts.tts.TtsManager; + +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; +import org.greenrobot.eventbus.ThreadMode; +import org.jetbrains.annotations.NotNull; +import org.polaric.colorful.Colorful; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import blankj.utilcode.util.ActivityUtils; +import blankj.utilcode.util.ServiceUtils; +import blankj.utilcode.util.StringUtils; +import blankj.utilcode.util.ToastUtils; +import blankj.utilcode.util.Utils; +import cn.leancloud.LCException; +import cn.leancloud.LCFile; +import cn.leancloud.LCObject; +import cn.leancloud.LCQuery; +import cn.leancloud.LCUser; +import io.reactivex.Observer; +import io.reactivex.disposables.Disposable; + +public class MainActivity extends BaseMainActivity implements Device.IDeviceConnectListener, Device.IDeviceRequestListener, Device.IDeviceRemindListener { + public MainActivityUtils mainActivityUtils = new MainActivityUtils(this, () -> this); + private final DeviceConnectManager deviceConnectManager = new DeviceConnectManager(this, this); + public final DeviceRequestManager deviceRequestManager = new DeviceRequestManager(this, this); + public final DeviceRemindManager deviceRemindManager = new DeviceRemindManager(this, this); + public final static String MAIN_IN_ACTION_NAME = "cn.liuyanbing.surveyor.main_activity_local_receiver"; + private Toolbar mToolbar; + // private AccountHeader accountHeader = null; +// private Drawer drawerLeft = null; + private NumberProgressBar cutDownProgressBar; + private CheckBox powerOffCheckbox; + private final List mFragments = new ArrayList<>(); + private String[] mTitles; + private final int[] mIconUnSelectIds = new int[]{R.drawable.ic_tab_project_unselect, R.drawable.ic_ruler_unselected, R.mipmap.tab_home_unselect, R.mipmap.tab_me_unselect}; + private final int[] mIconSelectIds = new int[]{R.drawable.ic_tab_project_selected, R.drawable.ic_ruler_selected, R.mipmap.tab_home_select, R.mipmap.tab_me_select}; + private final ArrayList mTabEntities = new ArrayList<>(); + private ViewPager mViewPager; + private CommonTabLayout mTabLayout; + private BackupImportHelper backupImportUtil = new BackupImportHelper(this); + private MaterialDialog langDialog, unbindDeviceDialog; + + private MainActivityViewModel mainActivityViewModel; + + @SuppressLint("SourceLockedOrientationActivity") + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + mainActivityViewModel = new ViewModelProvider(this).get(MainActivityViewModel.class); + EventBus.getDefault().register(this); + + if (isThemeDark()) { + setTheme(R.style.CustomThemeDark); + } + Colorful.applyTheme(this); + setContentView(R.layout.activity_main); + initWidgetListener(savedInstanceState);//初始化组件和监听器 + + ((App) Utils.getApp()).tryCount = 0; + IntentFilter filter = new IntentFilter(); + filter.addAction(MAIN_IN_ACTION_NAME); + + if (LCUser.getCurrentUser() != null && LCUser.getCurrentUser().isAuthenticated()) { + VipManager.getInstance().controlSdkRefresh(this, ((App) Utils.getApp()).registerCodeV2, new VipManager.OnSdkRefreshListener() { + @Override + public void onRefreshSuccess() { + + } + + @Override + public void onRefreshFailed(int errorCode) { + + } + }); + } + + updateHeaderResult(); + + LCDeviceUtil.updateDeviceInfo("controlnetwork", ((App) Utils.getApp()).registerCodeV2, null); + + checkAgreementPermission(); + + //解决某个版本的bug: + //由于升级数据库,导致限差方案丢失,所以启动的时候检测所有project,为没有限差的项目重新添加限差 +// DatabaseFixUtils.changeDefaultTolerance(); + //尝试上传crashLog + ThreadPoolUtil.execute(() -> CrashCollector.tryUploadCrashLogInWorkerThread(this, CrashCollector.APP_LABEL_CONTROL)); + LeanCloudConfigLoader.loadLeanCloudConfig(); + } + + /** + * 初始化组件和监听器,屏幕方向发生改变时执行一次 + */ + private void initWidgetListener(Bundle savedInstanceState) { + mToolbar = findViewById(R.id.toolbar); + setSupportActionBar(mToolbar); + setTitle(R.string.app_name); + //set the back arrow in the toolbar + if (getSupportActionBar() != null) { + getSupportActionBar().setDisplayHomeAsUpEnabled(false); + getSupportActionBar().setDisplayShowTitleEnabled(true); + } + cutDownProgressBar = findViewById(R.id.cut_down_progressbar); + mViewPager = findViewById(R.id.activity_main_viewpager); + mTabLayout = findViewById(R.id.activity_main_tab_layout); + if (isThemeDark()) { + if (mTabLayout != null) { + mTabLayout.setBackgroundColor(Color.DKGRAY); + mTabLayout.setTextUnselectColor(Color.LTGRAY); + mTabLayout.setUnderlineColor(Color.BLACK); + } + } + mTitles = new String[]{getString(R.string.project), getString(R.string.survey), getString(R.string.label_manager), getString(R.string.me)}; + mFragments.add(new ProjectListFragment()); + mFragments.add(new MainSurveyFragment()); + mFragments.add(new ConfigFragment()); +// mFragments.add(new ServiceFragment()); + mFragments.add(new MeFragment()); + for (int i = 0; i < mTitles.length; i++) { + mTabEntities.add(new TabEntity(mTitles[i], mIconSelectIds[i], mIconUnSelectIds[i])); + } + + mTabLayout.setTabData(mTabEntities); + mTabLayout.setOnTabSelectListener(new OnTabSelectListener() { + @Override + public void onTabSelect(int position) { + mViewPager.setCurrentItem(position); + } + + @Override + public void onTabReselect(int position) { + if (position == 0) { +// mTabLayout.showMsg(0, mRandom.nextInt(100) + 1); +// UnreadMsgUtils.show(mTabLayout_2.getMsgView(0), mRandom.nextInt(100) + 1); + } + } + }); + + mViewPager.setAdapter(new MyPagerAdapter(getSupportFragmentManager())); + mViewPager.setCurrentItem(0); + mViewPager.setOffscreenPageLimit(4); + + mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + setCurrentTab(position); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + } + + public void setCurrentTab(int position) { + mTabLayout.setCurrentTab(position); + } + + + private void updateSplashLog(final boolean autoDismiss, final boolean skipDismiss, final boolean clickImageDismiss) { + if (AppChannel.customChannel != AppChannel.CUSTOM_CONTROL_PUBLIC) + return;//只统计公版 + final Date today = DateUtils.reverse2Date(DateUtils.getTodayStartTime()); + new LCQuery<>("SplashLog") + .whereEqualTo("date", today) + .findInBackground().subscribe(new Observer>() { + @Override + public void onSubscribe(Disposable d) { + + } + + @Override + public void onNext(List avObjects) { + if (avObjects != null && !avObjects.isEmpty()) { + avObjects.get(0).increment("showTimes"); + if (autoDismiss) + avObjects.get(0).increment("autoDismissTimes"); + if (skipDismiss) + avObjects.get(0).increment("skipTimes"); + if (clickImageDismiss) + avObjects.get(0).increment("clickTimes"); + avObjects.get(0).saveInBackground().subscribe(); + } else { + LCObject splashLog = new LCObject("SplashLog"); + splashLog.put("date", today); + splashLog.saveInBackground().subscribe(); + } + } + + @Override + public void onError(Throwable e) { + + } + + @Override + public void onComplete() { + + } + }); + } + + /** + * 读取项目文件 + */ + @Override + public void initialize() { + //友盟统计 + UMConfigure.init(this, "62c2c24705844627b5d6f943", "public", UMConfigure.DEVICE_TYPE_PHONE, ""); + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {//安卓10以下,请求读取硬件信息 + mainActivityUtils.requestPhonePermission(); + } + try {//微信插件实例化 + if (Utils.getApp() instanceof BaseApp) { + IWXAPI wxApi = WXAPIFactory.createWXAPI(this, "wx8b41ad369eba83a9"); + wxApi.registerApp("wx8b41ad369eba83a9"); + ((BaseApp) Utils.getApp()).setWxApi(wxApi); + } + } catch (Exception ignored) { + } +// CheckControlUpdateUtil.checkUpdate(this, false); + EventBus.getDefault().post(new DatabaseReadyEvent()); + + if (LCUser.getCurrentUser() == null) { + VipManager.getInstance().controlSdkRefresh(this, ((App) Utils.getApp()).registerCodeV2, new VipManager.OnSdkRefreshListener() { + @Override + public void onRefreshSuccess() { + Log.d("controlSdkRefresh", "onRefreshSuccess"); + } + + @Override + public void onRefreshFailed(int errorCode) { + Log.d("controlSdkRefresh", "onRefreshFailed--errorCode--" + errorCode); + } + }); + } + + GlobalFlowCenter.Companion.getInstance().onMainActivityInitial(); + } + + // this piece of code is show how to press twice back button to exit App + private long exitTime = 0; + + public void ExitApp() { + if ((System.currentTimeMillis() - exitTime) > 2000) { + ToastUtils.showShort(getString(R.string.press_again_exit)); + exitTime = System.currentTimeMillis(); + } else { + if (((App) Utils.getApp()).isBluetoothConnected) { + if (TotalStation.getInstance().isSupportPowerOff()) { + showPowerOffDialog(); + } else { + finish(); + } + } else { + finish(); + } + } + } + + public void showPowerOffDialog() { + MaterialDialog dialog = new MaterialDialog.Builder(this) + .title(R.string.hint) + .customView(R.layout.dialog_power_off, false) + .onPositive(new MaterialDialog.SingleButtonCallback() { + @Override + public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) { + if (((App) Utils.getApp()).isCloseInstrumentAfterExit) { + TotalStation.getInstance().powerOff(); + } + finish(); + } + }) + .positiveText(getString(R.string.confirm)) + .negativeText(getString(R.string.cancel)).build(); + + powerOffCheckbox = dialog.getCustomView().findViewById(R.id.dialog_power_off_checkbox); + powerOffCheckbox.setChecked(((App) Utils.getApp()).isCloseInstrumentAfterExit); + powerOffCheckbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + ((App) Utils.getApp()).isCloseInstrumentAfterExit = isChecked; + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(Utils.getApp()); + SharedPreferences.Editor editor = prefs.edit(); + editor.putBoolean("isCloseInstrumentAfterExit", ((App) Utils.getApp()).isCloseInstrumentAfterExit); + editor.apply(); + } + }); + dialog.show(); + } + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { +// if (drawerLeft != null && drawerLeft.isDrawerOpen()) { +// drawerLeft.closeDrawer(); +// return true; +// } + + if (mViewPager != null) { + Fragment viewPagerFragment = getViewPagerFragment(this, mViewPager.getId(), mViewPager.getCurrentItem()); + if (viewPagerFragment instanceof InterfaceUtil.ICustomGroup) { + if (((InterfaceUtil.ICustomGroup) viewPagerFragment).isEditModel()) { + ((InterfaceUtil.ICustomGroup) viewPagerFragment).cancelEditModel(); + return true; + } + } + } + ExitApp(); + return true; + } + return super.onKeyDown(keyCode, event); + } + + public static Fragment getViewPagerFragment(AppCompatActivity activity, int viewId, int index) { + String tag = "android:switcher:" + viewId + ":" + index; + return activity.getSupportFragmentManager().findFragmentByTag(tag); + } + + @Override + protected void onSaveInstanceState(Bundle outState) { +// //add the values which need to be saved from the drawer to the bundle +// if (drawerLeft != null) +// outState = drawerLeft.saveInstanceState(outState); +// //add the values which need to be saved from the accountHeader to the bundle +// if (accountHeader != null) +// outState = accountHeader.saveInstanceState(outState); + super.onSaveInstanceState(outState); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.menu_activity_main, menu); + menu.findItem(R.id.menu_activity_main_bluetooth).setIcon( + new IconicsDrawable(Utils.getApp()).icon(MaterialDesignIconic.Icon.gmi_bluetooth).color(Color.WHITE).sizeDp(20)); + menu.findItem(R.id.menu_activity_main_bound_device_activate).setTitle(R.string.bound_device_activate); + return super.onCreateOptionsMenu(menu); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + onBackPressed(); + case R.id.menu_activity_main_bluetooth: + mainActivityUtils.requestBluetoothPermission(); + break; + case R.id.menu_activity_main_bound_device_activate: + showActivateType(); + break; + case R.id.menu_activity_main_settings: + Intent intent4 = new Intent(Utils.getApp(), SettingsActivity.class); + startActivityForResult(intent4, 331); + break; + } + return super.onOptionsItemSelected(item); + } + + /** + * 选择激活方式 + */ + private void showActivateType() { + if (AppChannel.customChannel == AppChannel.CUSTOM_CONTROL_PUBLIC) { + if (LCUser.getCurrentUser() == null) { + Intent intent = new Intent(Utils.getApp(), LoginActivity.class); + intent.putExtra("finishTo", UserInfoActivity.class.getName()); + startActivity(intent); + } else { + startActivity(new Intent(MainActivity.this, UserInfoActivity.class)); + } + } else { + startActivity(new Intent(MainActivity.this, RegisterActivity.class)); + } + } + + @Override + public void onResume() { + super.onResume(); + //如果是从其他Activity返回到MainActivity时,不显示广告,如果是从后台切换出来,检查并显示广告; + //一定放到super.onResume前,否则TopActivity始终是MainActivity,因为App的onActivityResumed在super.onResume内执行 + + if (((App) Utils.getApp()).isUserStatusChanged) { + ((App) Utils.getApp()).isUserStatusChanged = false; +// if (drawerLeft != null) +// drawerLeft.openDrawer(); +// if (accountHeader != null) +// accountHeader.toggleSelectionList(MainActivity.this); + updateHeaderResult(); + } + //按照设置选项,保持屏幕常亮,放在onResume而不放在onCreate里是因为,用户更改设置后返回主页就要开始常亮了 + boolean isWakeLock = PreferenceManager.getDefaultSharedPreferences(this).getBoolean("key_is_wake_lock", false); + if (isWakeLock) { + getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + } else { + getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + } + + SdkUtils.tick(); + EventBus.getDefault().post(new CountDownEvent()); + } + + @Override + public void onPause() { + super.onPause(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + EventBus.getDefault().unregister(this); + + TtsManager.getInstance().stopTts(); + VipManager.getInstance().destroy(); + + SoundPoolUtil.getInstance().onDestroy(); + ((App) Utils.getApp()).isBluetoothReconnect = false; + TotalStation.getInstance().stopAll(); + Device.getInstance().requestDisconnect(); + for (String serviceName : ServiceUtils.getAllRunningServices()) { + ServiceUtils.stopService(serviceName); + } + ActivityUtils.finishAllActivities(); + + GlobalFlowCenter.Companion.getInstance().onMainActivityDestroy(); + } + + @Subscribe(threadMode = ThreadMode.MAIN) + public void onMessageEvent(SwitchPageEvent event) { + int type = event.getType(); + try { + int index = 1; + if (type == SwitchPageEvent.TYPE_SWITCH_TO_MEASURE_PAGE_AND_DATA) { + mViewPager.setCurrentItem(index); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + @Subscribe(threadMode = ThreadMode.MAIN) + public void onMessageEvent(OpenShortUrlEvent event) { + if (event.getShortUrl() != null) { +// Intent intent = new Intent(); +// intent.setClass(Utils.getApp(), AgentWebActivity.class); +// intent.putExtra("short_url", event.getShortUrl()); +// startActivity(intent); + AgentWebActivity.navigation2(MainActivity.this, event.getShortUrl()); + } + } + + public void showTryVipDialog() { + if (TotalStation.getInstance().isSupportMotor() && !VipManager.getInstance().checkReg()) { + LeanCloudConfigLoader.findInBackground("android_control_network_pro_try_switch", instance -> { + if (instance != null && "true".equals(instance.value)) { + if (LCUser.getCurrentUser() != null) { + ServiceDateUtils.getServerDate(new DateUtils.OnServerDateCallBack() { + @Override + public void get(Date serverDate) { + if (VipManager.getInstance().controlLevel == 0) { + new MaterialDialog.Builder(ActivityUtils.getTopActivity()) + .title(R.string.congratulations) + .content("你获得了3天的专业版试用机会,可以驱动马达进行自动观测") + .positiveText("马上试用") + .onPositive(new MaterialDialog.SingleButtonCallback() { + @Override + public void onClick(@NonNull @NotNull MaterialDialog dialog, @NonNull @NotNull DialogAction which) { + Date newExpireDate = DateUtils.addDayOfMonth(serverDate, 3, false, true);//多1天是为了显示 + LCUser.getCurrentUser().put("controlLevel", 1); + LCUser.getCurrentUser().put("controlExpireDate", newExpireDate); + LCUser.getCurrentUser().saveInBackground().subscribe(new Observer() { + @Override + public void onSubscribe(Disposable d) { + + } + + @Override + public void onNext(LCObject avObject) { + VipManager.getInstance().controlSdkRefresh(MainActivity.this, ((App) Utils.getApp()).registerCodeV2, new VipManager.OnSdkRefreshListener() { + @Override + public void onRefreshSuccess() { + new MaterialDialog.Builder(ActivityUtils.getTopActivity()) + .title(R.string.success) + .content("开通成功,当前到期时间为" + DateUtils.toFull(newExpireDate)) + .positiveText(R.string.confirm) + .show(); + } + + @Override + public void onRefreshFailed(int errorCode) { + + } + }); + } + + @Override + public void onError(Throwable e) { + ToastUtils.showShort("开通失败,错误码:" + new LCException(e).getCode()); + } + + @Override + public void onComplete() { + + } + }); + } + }) + .negativeText("取消") + .show(); + } else if (VipManager.getInstance().controlLevel == 1) { + if (!VipManager.getInstance().isControlInExpireDate) + new MaterialDialog.Builder(ActivityUtils.getTopActivity()) + .title(R.string.congratulations) + .content("你获得了7天的专业版试用机会,可以驱动马达自动观测,请联系客服申请开通") + .positiveText("马上申请") + .onPositive(new MaterialDialog.SingleButtonCallback() { + @Override + public void onClick(@NonNull @NotNull MaterialDialog dialog, @NonNull @NotNull DialogAction which) { + Intent intent = new Intent(); + intent.setClass(Utils.getApp(), AgentWebActivity.class); + intent.putExtra("short_url", "android_url_business_manager"); + startActivity(intent); + } + }) + .negativeText("取消") + .show(); + } + } + + @Override + public void error(Throwable throwable) { + ToastUtils.showShort(R.string.get_server_date_failed); + } + }); + } else { + new MaterialDialog.Builder(ActivityUtils.getTopActivity()) + .title(R.string.log_in_to_try) + .content("登录后,您将获取3-7天的试用机会,请登录") + .positiveText("登录") + .onPositive(new MaterialDialog.SingleButtonCallback() { + @Override + public void onClick(@NonNull @NotNull MaterialDialog dialog, @NonNull @NotNull DialogAction which) { + Intent intent = new Intent(); + intent.setClass(Utils.getApp(), LoginActivity.class); + intent.putExtra("finishTo", UserInfoActivity.class.getName()); + startActivity(intent); + } + }) + .negativeText("取消") + .show(); + } + } + }); + } + } + + @Subscribe(threadMode = ThreadMode.MAIN) + public void onMessageEvent(CountDownEvent event) { + if (cutDownProgressBar != null) { + cutDownProgressBar.setVisibility(View.VISIBLE); + if (!SdkUtils.isRegCodeValidate() && SdkUtils.isVipValidate()) { + int maxProgress = (int) (SdkUtils.availableTimeMax() / 60 / 1000L); + cutDownProgressBar.setMax(maxProgress); + int progress = Math.max((int) (SdkUtils.availableTime() / 60 / 1000L), 0);//可用时间可能小于0 + cutDownProgressBar.setProgress(progress); + if (progress < 60) { + cutDownProgressBar.setPrefix(getString(R.string.remaining_offline_time) + progress + getString(R.string.minute) + " "); + } else { + cutDownProgressBar.setPrefix(getString(R.string.remaining_offline_time) + progress / 60 + getString(R.string.hour) + progress % 60 + getString(R.string.minute) + " "); + } + if (event.isNeedRefresh()) { + VipManager.getInstance().controlSdkRefresh(this, ((App) Utils.getApp()).registerCodeV2, null); + } + if (progress == 240 || progress == 180 || progress == 120 || progress == 60 || (progress > 0 && progress < 60 && progress % 10 == 0)) { + new AlertDialog.Builder(this) + .setTitle(R.string.warning) + .setMessage(getString(R.string.remaining_offline_time) + progress + getString(R.string.minute) + "," + getString(R.string.the_network_reboot_software_can_reset_the_remaining_time_offline)) + .setPositiveButton(R.string.i_know, null) + .show(); + } + if (progress > 240) {//离线时间大于4小时,主题色显示 + cutDownProgressBar.setProgressTextColor(ColorUtil.getColorPrimary(this)); + cutDownProgressBar.setReachedBarColor(ColorUtil.getColorPrimary(this)); + cutDownProgressBar.setUnreachedBarColor(ColorUtil.getColorPrimary(this)); + } else if (progress > 120) {//离线时间2-5小时间显示橙色警告 + cutDownProgressBar.setProgressTextColor(ContextCompat.getColor(this, R.color.md_orange_800)); + cutDownProgressBar.setReachedBarColor(ContextCompat.getColor(this, R.color.md_orange_800)); + cutDownProgressBar.setUnreachedBarColor(ContextCompat.getColor(this, R.color.md_orange_800)); + } else {//离线时间小于2小时红色警告 + cutDownProgressBar.setProgressTextColor(Color.RED); + cutDownProgressBar.setReachedBarColor(Color.RED); + cutDownProgressBar.setUnreachedBarColor(Color.RED); + } + Log.d("cutdownProgressBar", "setProgress" + progress); + } else { + cutDownProgressBar.setVisibility(View.GONE); + } + } + } + + /** + * 教程列表 + */ + public void showTutorialListDialog() { + new MaterialDialog.Builder(this) + .title(R.string.video_tutorial) + .items(new String[]{getString(R.string.bilibili) + , getString(R.string.tencent_video) + , getString(R.string.baidudisk) + , getString(R.string.surveyor_home)}) + .itemsCallback(new MaterialDialog.ListCallback() { + @Override + public void onSelection(MaterialDialog dialog, View itemView, int which, CharSequence text) { + switch (which) { + case 0: +// Intent intent1 = new Intent(); +// intent1.setClass(Utils.getApp(), AgentWebActivity.class); +// intent1.putExtra("short_url", "android_url_bilibili_tutorial"); +// startActivity(intent1); + AgentWebActivity.navigation2( + MainActivity.this, "android_url_bilibili_tutorial" + ); + break; + case 1: +// Intent intent2 = new Intent(); +// intent2.setClass(Utils.getApp(), AgentWebActivity.class); +// intent2.putExtra("short_url", "android_url_tencent_video_tutorial"); +// startActivity(intent2); + AgentWebActivity.navigation2( + MainActivity.this, "android_url_tencent_video_tutorial" + ); + break; + case 2: +// Intent intent3 = new Intent(); +// intent3.setClass(Utils.getApp(), AgentWebActivity.class); +// intent3.putExtra("short_url", "android_url_baidu_pan_tutorial"); +// startActivity(intent3); + AgentWebActivity.navigation2( + MainActivity.this, "android_url_baidu_pan_tutorial" + ); + break; + case 3: +// Intent intent4 = new Intent(); +// intent4.setClass(Utils.getApp(), AgentWebActivity.class); +// intent4.putExtra("short_url", "android_url_surveyor_home"); +// startActivity(intent4); + AgentWebActivity.navigation2( + MainActivity.this, "android_url_surveyor_home" + ); + break; + } + } + }).show(); + } + + /** + * 刷新左侧用户信息 + */ + public void updateHeaderResult() { + Log.d("updateHeaderResult", "updateHeaderResult"); +// if (drawerLeft == null || accountHeader == null) +// return; +// for (int i = accountHeader.getProfiles().size() - 1; i >= 0; i--) { +// accountHeader.removeProfile(accountHeader.getProfiles().get(i)); +// } + +// if (LCUser.getCurrentUser() == null || !LCUser.getCurrentUser().isAuthenticated()) { +// accountHeader.addProfiles( +// new ProfileSettingDrawerItem().withName(getString(R.string.log_in)) +// .withIcon(new IconicsDrawable(this).icon(MaterialDesignIconic.Icon.gmi_sign_in).paddingDp(5)) +// .withIdentifier(1000).withOnDrawerItemClickListener(new Drawer.OnDrawerItemClickListener() { +// @Override +// public boolean onItemClick(View view, int position, IDrawerItem drawerItem) { +// Intent intent = new Intent(Utils.getApp(), LoginActivity.class); +// intent.putExtra("finishTo", UserInfoActivity.class.getName()); +// startActivity(intent); +// return false; +// } +// })); +// } else { +// accountHeader.addProfiles(new ProfileSettingDrawerItem().withName(getString(R.string.user_info)).withIcon(new IconicsDrawable(this).icon(MaterialDesignIconic.Icon.gmi_account).paddingDp(5)).withIdentifier(1000).withOnDrawerItemClickListener(new Drawer.OnDrawerItemClickListener() { +// @Override +// public boolean onItemClick(View view, int position, IDrawerItem drawerItem) { +// startActivity(new Intent(MainActivity.this, UserInfoActivity.class)); +// return false; +// } +// })); +// } + + + updateProfileItem(); + } + + private void updateProfileItem() { + if (LCUser.getCurrentUser() != null) { + String nickname = LCUser.getCurrentUser().getString("nickname"); + LCFile avatarFile = LCUser.getCurrentUser().getLCFile("avatar"); + if (!StringUtils.isEmpty(nickname)) { +// ProfileDrawerItem item = new ProfileDrawerItem().withName(nickname).withEmail(LCUser.getCurrentUser().getUsername()).withIdentifier(1003); +// if (avatarFile == null) { +// item.withIcon(R.drawable.app_logo); +// } else { +// item.withIcon(avatarFile.getUrl()); +// } +// accountHeader.addProfiles(item); + + String avatarUrl = null; + if (avatarFile != null) { + avatarUrl = avatarFile.getUrl(); + } + + mainActivityViewModel.getRefreshLoginUserLiveData().setValue( + new MainUserBean(LCUser.getCurrentUser().getUsername(), + nickname, avatarUrl)); + } else { + LCObject userProfile = LCUser.getCurrentUser().getLCObject("profile"); + if (userProfile != null) { + userProfile.fetchInBackground().subscribe(new Observer() { + @Override + public void onSubscribe(Disposable d) { + + } + + @Override + public void onNext(LCObject avObject) { + if (isFinishing()) return; + String nickname = avObject.getString("nickname"); + LCFile avatarFile = avObject.getLCFile("avatar"); + if (!StringUtils.isEmpty(nickname)) { +// ProfileDrawerItem item = new ProfileDrawerItem().withName(nickname).withEmail(LCUser.getCurrentUser().getUsername()).withIdentifier(1003); +// if (avatarFile == null) { +// item.withIcon(R.drawable.app_logo); +// } else { +// item.withIcon(avatarFile.getUrl()); +// } +// accountHeader.addProfiles(item); + + //保存到_User,下次不再查Profile + LCUser.getCurrentUser().put("nickname", nickname); + + String avatarUrl = null; + if (avatarFile != null) { + LCUser.getCurrentUser().put("avatar", avatarFile); + avatarUrl = avatarFile.getUrl(); + } + LCUser.getCurrentUser().saveInBackground().subscribe(); + + + mainActivityViewModel.getRefreshLoginUserLiveData().setValue( + new MainUserBean(LCUser.getCurrentUser().getUsername(), + nickname, avatarUrl)); + } + } + + @Override + public void onError(Throwable e) { + } + + @Override + public void onComplete() { + + } + }); + } else { + new LCQuery<>("Profile") + .whereEqualTo("creatorId", LCUser.getCurrentUser().getObjectId()) + .findInBackground() + .subscribe(new Observer>() { + @Override + public void onSubscribe(Disposable d) { + + } + + @Override + public void onNext(List list) { + if (isFinishing()) return; + if (list != null && !list.isEmpty()) { + String nickname = list.get(0).getString("nickname"); + LCFile avatarFile = list.get(0).getLCFile("avatar"); + if (!StringUtils.isEmpty(nickname)) { +// ProfileDrawerItem item = new ProfileDrawerItem().withName(nickname).withEmail(LCUser.getCurrentUser().getUsername()).withIdentifier(1003); +// if (avatarFile == null) { +// item.withIcon(R.drawable.app_logo); +// } else { +// item.withIcon(avatarFile.getUrl()); +// } +// accountHeader.addProfiles(item); + + String avatarUrl = null; + + //保存到_User,下次不再查Profile + LCUser.getCurrentUser().put("nickname", nickname); + + if (avatarFile != null) { + LCUser.getCurrentUser().put("avatar", avatarFile); + avatarUrl = avatarFile.getUrl(); + } + LCUser.getCurrentUser().saveInBackground().subscribe(); + + mainActivityViewModel.getRefreshLoginUserLiveData().setValue( + new MainUserBean(LCUser.getCurrentUser().getUsername(), + nickname, avatarUrl)); + } + } + } + + @Override + public void onError(Throwable e) { + + } + + @Override + public void onComplete() { + + } + }); + } + } + } else { +// accountHeader.addProfiles(new ProfileDrawerItem().withEmail(getString(R.string.click_avatar_to_log_in)).withIcon(R.drawable.app_logo).withIdentifier(1003)); + mainActivityViewModel.getRefreshLoginUserLiveData().setValue( + new MainUserBean(null, + null, null)); + } + } + + /** + * 开启左侧菜单 + */ + public void openLeftDrawer() { +// if (drawerLeft != null) +// drawerLeft.openDrawer(); + } + + @Override + public void onDeviceConnectLost() { + mainActivityUtils.onDeviceConnectLost(); + } + + @Override + public void onDeviceConnectFailed() { + mainActivityUtils.onDeviceConnectFailed(); + } + + @Override + public void onDeviceConnectSucceed() { + mainActivityUtils.onDeviceConnectSucceed(); + } + + @Override + public void onDeviceConnectNeedOpenBT() { + } + + @Override + public void onDeviceRequestConnect() { + mainActivityUtils.onRequestConnect(); + } + + @Override + public void onDeviceRequestDisconnect() { + + } + + @Override + public void onDeviceRequestSetupChat() { + + } + + @Override + public void onRemindConnectDevice() { + mainActivityUtils.showRemindConnectDeviceDialog(); + } + + private class MyPagerAdapter extends FragmentPagerAdapter { + public MyPagerAdapter(@NonNull FragmentManager fm) { + super(fm); + } + + public MyPagerAdapter(@NonNull FragmentManager fm, int behavior) { + super(fm, behavior); + } + + @NonNull + @Override + public Fragment getItem(int position) { + return mFragments.get(position); + } + + @Override + public int getCount() { + return mFragments.size(); + } + } + + private void restartApplication() { + android.os.Process.killProcess(android.os.Process.myPid()); + } + + private boolean isThemeDark() { + return SettingValueUtil.isThemeDark(); + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/activity/MainActivityUtils.java b/app/src/main/java/com/bingce/controlnetwork/activity/MainActivityUtils.java new file mode 100644 index 0000000..01e45ef --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/activity/MainActivityUtils.java @@ -0,0 +1,464 @@ +package com.bingce.controlnetwork.activity; + +import android.Manifest; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationManager; +import android.os.Build; +import android.provider.Settings; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatActivity; +import androidx.core.app.ActivityCompat; +import androidx.lifecycle.Lifecycle; +import androidx.lifecycle.LifecycleEventObserver; +import androidx.lifecycle.LifecycleOwner; + +import com.afollestad.materialdialogs.DialogAction; +import com.afollestad.materialdialogs.MaterialDialog; +import com.bingce.AppChannel; +import com.bingce.BaseApp; +import com.bingce.controlnetwork.R; +import com.bingce.device.Device; +import com.bingce.device.enums.ConnectTypeEnum; +import com.bingce.device.enums.DeviceTypeEnum; +import com.bingce.device.service.comm.ble.BleService; +import com.bingce.device.service.comm.emulator.EmulatorService; +import com.bingce.device.service.comm.localgps.LocationService; +import com.bingce.device.service.comm.localgps.NativePositioningService; +import com.bingce.device.service.comm.otg.OTGCommService; +import com.bingce.device.service.comm.socket.TsSocketService; +import com.bingce.device.service.comm.spp.BTService; +import com.bingce.device.ui.ConnectLevelActivity; +import com.bingce.device.ui.ConnectRtkActivity; +import com.bingce.device.ui.ConnectTSActivity; +import com.bingce.device.ui.utils.DeviceUtil; +import com.bingce.device.ui.widget.BCProgressDialog; +import com.bingce.level.Level; +import com.bingce.rtk.event.RtkSpeechEvent; +import com.bingce.totalstation.TotalStation; +import com.bingce.totalstation.TsConfig; +import com.bingce.utils.AppCompatActivityProviderUtils; +import com.bingce.utils.IProvider; +import com.bingce.utils.RomUtil; +import com.bingce.utils.SoundPoolUtil; +import com.bingce.utils.ThreadPoolUtil; +import com.bingce.utils.Util; +import com.bingce.utils.ValidateUtil; +import com.hjq.permissions.OnPermissionCallback; +import com.hjq.permissions.OnPermissionPageCallback; +import com.hjq.permissions.Permission; +import com.hjq.permissions.XXPermissions; + +import net.tatans.tensorflowtts.tts.TtsManager; + +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; +import org.greenrobot.eventbus.ThreadMode; + +import java.util.List; + +import blankj.utilcode.util.ActivityUtils; +import blankj.utilcode.util.ServiceUtils; +import blankj.utilcode.util.StringUtils; +import blankj.utilcode.util.ToastUtils; +import blankj.utilcode.util.Utils; + +public class MainActivityUtils extends AppCompatActivityProviderUtils { + private BCProgressDialog deviceConnectingProgressDialog; + + public MainActivityUtils(AppCompatActivity activity, IProvider activityIProvider) { + super(activityIProvider); + activity.getLifecycle().addObserver(new LifecycleEventObserver() { + @Override + public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) { + switch (event) { + case ON_CREATE: + EventBus.getDefault().register(MainActivityUtils.this); + SoundPoolUtil.getInstance().initHintSing(activity, SoundPoolUtil.TEST, R.raw.savedone); + break; + case ON_DESTROY: + EventBus.getDefault().unregister(MainActivityUtils.this); + SoundPoolUtil.getInstance().onDestroy(); + break; + } + } + }); + } + + @Subscribe(threadMode = ThreadMode.MAIN) + public void onMessageEvent(RtkSpeechEvent event) { + if (!StringUtils.isEmpty(event.getText())) TtsManager.getInstance().speak(event.getText()); + } + + /** + * 连接设备成功后,启动相关服务,因为Ntrip与SN无关,可以在此执行,与SN相关的服务在RtkReceivedSerialNumberEvent事件后执行 + */ + public void onDeviceConnectSucceed() { + if (deviceConnectingProgressDialog != null && deviceConnectingProgressDialog.isShowing()) { + deviceConnectingProgressDialog.dismiss(); + } + + if (Device.getInstance().deviceType == DeviceTypeEnum.DEVICE_TYPE_TS) { + TotalStation.getInstance().runnableStart(); + TotalStation.getInstance().init(); + } else if (Device.getInstance().deviceType == DeviceTypeEnum.DEVICE_TYPE_LEVEL) { + Level.getInstance().init(); + } + //记录用户联机时手机定位的大概位置 + if (ActivityCompat.checkSelfPermission(/*this*/context(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { + LocationManager mLocationManager = ((LocationManager) context().getSystemService(Context.LOCATION_SERVICE)); + if (mLocationManager != null) { + List providers = mLocationManager.getProviders(true); + if (providers.contains(LocationManager.GPS_PROVIDER)) { + Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + if (location != null) { + ((BaseApp) Utils.getApp()).lastPhoneLocation = location.getLatitude() + "," + location.getLongitude(); + Util.putPreference("lastPhoneLocation", ((BaseApp) Utils.getApp()).lastPhoneLocation); + } + } + } + } + } + + + public void onDeviceConnectFailed() { + if (deviceConnectingProgressDialog != null && deviceConnectingProgressDialog.isShowing()) { + deviceConnectingProgressDialog.dismiss(); + ToastUtils.showShort(R.string.device_connect_failed); + } + } + + public void onDeviceConnectLost() { + ToastUtils.showShort(R.string.device_connect_lost); + } + + public void onRequestConnect() { + if (deviceConnectingProgressDialog == null || !deviceConnectingProgressDialog.isShowing()) { + deviceConnectingProgressDialog = new BCProgressDialog.Builder(ActivityUtils.getTopActivity()).title(R.string.connect_device).build(); + deviceConnectingProgressDialog.show(); + } + } + + /** + * 连接蓝牙先请求打开定位权限 + */ + public void requestBluetoothPermission() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && XXPermissions.isGranted(ActivityUtils.getTopActivity(), Permission.BLUETOOTH_CONNECT)) {//S及以后不需要位置权限 + checkConnectLast(); + } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {//S及以后不需要位置权限,此时只需请求connect权限 + if (XXPermissions.isGranted(ActivityUtils.getTopActivity(), Permission.BLUETOOTH_CONNECT)) { + checkConnectLast(); + } else { + new MaterialDialog.Builder(ActivityUtils.getTopActivity()) + .title(R.string.location_permission) + .content(R.string.bluetooth_need_location_permission) + .canceledOnTouchOutside(false) + .positiveText(R.string.to_allow) + .negativeText(R.string.refuse) + .onPositive((dialog, which) -> { + XXPermissions.with(ActivityUtils.getTopActivity()) + .permission(Permission.BLUETOOTH_CONNECT) + .request(new OnPermissionCallback() { + @Override + public void onGranted(List permissions, boolean all) { + checkConnectLast(); + } + + @Override + public void onDenied(List permissions, boolean never) { + if (never) { + ToastUtils.showLong(R.string.bluetooth_connect_need_permission); + XXPermissions.startPermissionActivity(ActivityUtils.getTopActivity(), permissions, new OnPermissionPageCallback() { + @Override + public void onGranted() { + requestBluetoothPermission(); + } + + @Override + public void onDenied() { + ToastUtils.showLong(R.string.bluetooth_connect_need_permission); + } + }); + } else { + requestBluetoothPermission(); + } + } + }); + }) + .onNegative((dialog, which) -> { + + }).show(); + } + } else {//S以下,需要请求两个权限,位置和Connect权限 + if (XXPermissions.isGranted(ActivityUtils.getTopActivity(), Permission.ACCESS_FINE_LOCATION, Permission.BLUETOOTH_CONNECT)) { + checkConnectLast(); + } else { + new MaterialDialog.Builder(ActivityUtils.getTopActivity()) + .title(R.string.location_permission) + .content(R.string.bluetooth_need_location_permission) + .canceledOnTouchOutside(false) + .positiveText(R.string.to_allow) + .negativeText(R.string.refuse) + .onPositive((dialog, which) -> { + XXPermissions.with(ActivityUtils.getTopActivity()) + .permission(Permission.ACCESS_FINE_LOCATION, Permission.BLUETOOTH_CONNECT) + .request(new OnPermissionCallback() { + @Override + public void onGranted(List permissions, boolean all) { + if (all) { + checkConnectLast(); + } else { + requestBluetoothPermission(); + } + } + + @Override + public void onDenied(List permissions, boolean never) { + if (never) { + ToastUtils.showLong(R.string.bluetooth_connection_requires_positioning_permission_please_turn_it_on_manually); + XXPermissions.startPermissionActivity(ActivityUtils.getTopActivity(), permissions, new OnPermissionPageCallback() { + @Override + public void onGranted() { + requestBluetoothPermission(); + } + + @Override + public void onDenied() { + ToastUtils.showLong(R.string.bluetooth_connect_need_permission); + } + }); + } else { + requestBluetoothPermission(); + } + } + }); + }) + .onNegative((dialog, which) -> { + + }).show(); + } + } + } + + /** + * 检查权限 + */ + public void requestPhonePermission() { + if (!XXPermissions.isGranted(ActivityUtils.getTopActivity(), Permission.READ_PHONE_STATE)) { + long lastReadPhoneStateDeniedTime = Util.getLongPreference("lastReadPhoneStateDeniedTime", 0L); + if (System.currentTimeMillis() - lastReadPhoneStateDeniedTime > 48 * 60 * 60 * 1000L) {//每48小时提示一次 + new MaterialDialog.Builder(ActivityUtils.getTopActivity()) + .title(R.string.mobile_phone_permissions) + .content(R.string.verify_imei_imsi_code_to_prevent_account_theft) + .canceledOnTouchOutside(false) + .positiveText(R.string.to_allow) + .negativeText(R.string.refuse) + .onPositive(new MaterialDialog.SingleButtonCallback() { + @Override + public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) { + XXPermissions.with(ActivityUtils.getTopActivity()) + .permission(Permission.READ_PHONE_STATE) + .request(new OnPermissionCallback() { + @Override + public void onGranted(List permissions, boolean all) { + } + + @Override + public void onDenied(List permissions, boolean never) { + if (never) { + ToastUtils.showShort(R.string.manually_enable_the_phone_state_permission_to_bind_hardware_devices); + } + Util.putPreference("lastReadPhoneStateDeniedTime", System.currentTimeMillis()); + } + }); + } + }) + .onNegative(new MaterialDialog.SingleButtonCallback() { + @Override + public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) { + Util.putPreference("lastReadPhoneStateDeniedTime", System.currentTimeMillis()); + } + }).show(); + } + } + } + + public void showRemindConnectDeviceDialog() { + new MaterialDialog.Builder(ActivityUtils.getTopActivity()) + .title(R.string.hint) + .content(R.string.no_instrument_connected) + .positiveText(R.string.connect) + .onPositive(new MaterialDialog.SingleButtonCallback() { + @Override + public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) { + checkConnectLast(); + } + }) + .negativeText(R.string.cancel) + .show(); + } + + + public void checkConnectLast() { + if (Device.getInstance().connectType == ConnectTypeEnum.CONNECT_TYPE_SPP) { + if (!ServiceUtils.isServiceRunning(BTService.class.getName())) { + ServiceUtils.startService(BTService.class); + } + } else if (Device.getInstance().connectType == ConnectTypeEnum.CONNECT_TYPE_BLE) { + if (!ServiceUtils.isServiceRunning(BleService.class.getName())) { + ServiceUtils.startService(BleService.class); + } + } else if (Device.getInstance().connectType == ConnectTypeEnum.CONNECT_TYPE_QXBT) { + //千寻RTK需要GnssServer连接蓝牙 + } else if (Device.getInstance().connectType == ConnectTypeEnum.CONNECT_TYPE_HOTSPOT) { + if (!ServiceUtils.isServiceRunning(TsSocketService.class.getName())) { + ServiceUtils.startService(TsSocketService.class); + } + } else if (Device.getInstance().connectType == ConnectTypeEnum.CONNECT_TYPE_OTG) { + if (!ServiceUtils.isServiceRunning(OTGCommService.class.getName())) { + ServiceUtils.startService(OTGCommService.class); + } + } else if (Device.getInstance().connectType == ConnectTypeEnum.CONNECT_TYPE_TPCOM) { + if (!ServiceUtils.isServiceRunning(TsSocketService.class.getName())) { + ServiceUtils.startService(TsSocketService.class); + } + } else if (Device.getInstance().connectType == ConnectTypeEnum.CONNECT_TYPE_PHONE_LOCATION) { + if (!ServiceUtils.isServiceRunning(NativePositioningService.class.getName())) { + ServiceUtils.startService(NativePositioningService.class); + } + } else if (Device.getInstance().connectType == ConnectTypeEnum.CONNECT_TYPE_EMULATOR) { + if (!ServiceUtils.isServiceRunning(EmulatorService.class.getName())) { + ServiceUtils.startService(EmulatorService.class); + } + } + if (!Device.getInstance().isDeviceConnected()) { + if (!"".equals(Device.getInstance().deviceBlueName)) { + String instrumentInfo = ActivityUtils.getTopActivity().getString(R.string.instrument_name) + ":" + Device.getInstance().deviceBlueName + "\n" + ActivityUtils.getTopActivity().getString(R.string.instrument_type_name) + ":" + Device.getInstance().deviceBrand; + new MaterialDialog.Builder(ActivityUtils.getTopActivity()) + .title(R.string.quick_connect) + .content(instrumentInfo) + .positiveText(R.string.connect) + .negativeText(R.string.config) + .neutralText(R.string.switch_instrument) + .onPositive(new MaterialDialog.SingleButtonCallback() { + @Override + public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) { + if (Device.getInstance().connectType == ConnectTypeEnum.CONNECT_TYPE_HOTSPOT) { + startHotspotComm(); + } else { + Device.getInstance().requestConnect(); + ToastUtils.showShort(R.string.connecting_please_wait); + } + } + }).onNegative(new MaterialDialog.SingleButtonCallback() { + @Override + public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) { + Intent intent; + if (Device.getInstance().deviceType == DeviceTypeEnum.DEVICE_TYPE_TS) { + intent = new Intent(ActivityUtils.getTopActivity(), ConnectTSActivity.class); + } else if (Device.getInstance().deviceType == DeviceTypeEnum.DEVICE_TYPE_LEVEL) { + intent = new Intent(ActivityUtils.getTopActivity(), ConnectLevelActivity.class); + } else { + intent = new Intent(ActivityUtils.getTopActivity(), ConnectRtkActivity.class); + } + intent.putExtra("customChannel", AppChannel.customChannel); + ActivityUtils.getTopActivity().startActivity(intent); + } + }).onNeutral(new MaterialDialog.SingleButtonCallback() { + @Override + public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) { + chooseInstrumentType(); + } + }).show(); + } else { + chooseInstrumentType(); + } + } else { + if (Device.getInstance().connectType == ConnectTypeEnum.CONNECT_TYPE_PHONE_LOCATION) { + ToastUtils.showShort(R.string.native_rtk_is_running); + } else { + Intent intent; + if (Device.getInstance().deviceType == DeviceTypeEnum.DEVICE_TYPE_TS) { + intent = new Intent(ActivityUtils.getTopActivity(), ConnectTSActivity.class); + } else if (Device.getInstance().deviceType == DeviceTypeEnum.DEVICE_TYPE_LEVEL) { + intent = new Intent(ActivityUtils.getTopActivity(), ConnectLevelActivity.class); + } else { + intent = new Intent(ActivityUtils.getTopActivity(), ConnectRtkActivity.class); + } + intent.putExtra("customChannel", AppChannel.customChannel); + ActivityUtils.getTopActivity().startActivity(intent); + } + } + } + + private void chooseInstrumentType() { + new MaterialDialog.Builder(ActivityUtils.getTopActivity()) + .title(R.string.choose_instrument_type) + .items(new String[]{ActivityUtils.getTopActivity().getString(R.string.total_station), ActivityUtils.getTopActivity().getString(R.string.device_type_level)}) + .itemsCallback(new MaterialDialog.ListCallback() { + @Override + public void onSelection(MaterialDialog dialog, View itemView, int which, CharSequence text) { + switch (which) { + case 0: + Intent intent = new Intent(ActivityUtils.getTopActivity(), ConnectTSActivity.class); + intent.putExtra("customChannel", AppChannel.customChannel); + ActivityUtils.getTopActivity().startActivity(intent); + break; + case 1: + Intent intent2 = new Intent(ActivityUtils.getTopActivity(), ConnectLevelActivity.class); + intent2.putExtra("customChannel", AppChannel.customChannel); + ActivityUtils.getTopActivity().startActivity(intent2); + break; + } + } + }).show(); + } + + + /** + * 开启wifi通信 + */ + private void startHotspotComm() { + if (!ValidateUtil.isIPAddress(TsConfig.getInstance().getIp())) { + ToastUtils.showShort(R.string.please_input_correct_ip); + return; + } + if (TsConfig.getInstance().getPort() < 1024 || TsConfig.getInstance().getPort() > 65535) { + ToastUtils.showShort(R.string.please_input_correct_port); + return; + } + if (DeviceUtil.isWifiApOpen()) { + ServiceUtils.stopService(EmulatorService.class); + ServiceUtils.stopService(LocationService.class); + ServiceUtils.stopService(NativePositioningService.class); + ServiceUtils.stopService(BTService.class); + ServiceUtils.stopService(BleService.class); + ServiceUtils.startService(TsSocketService.class); + ThreadPoolUtil.execute(new Runnable() { + @Override + public void run() { + Device.getInstance().requestConnect(); + } + }, 200); + } else { + ToastUtils.showShort(R.string.please_open_hotspot_first); + //打开网络共享与热点设置页面 + if (RomUtil.isOppo() || RomUtil.isLenove() || RomUtil.isGionee()) { + //OPPO系统系统特殊,会让在Manifest.xml声明Settings$TetherSettingsActivity,现在让用户自己找热点界面,并开启 + ToastUtils.showShort(R.string.find_tether_setting_and_open); + ActivityUtils.getTopActivity().startActivity(new Intent(Settings.ACTION_SETTINGS)); + } else { + Intent intent = new Intent(); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + ComponentName comp = new ComponentName("com.android.settings", "com.android.settings.Settings$TetherSettingsActivity"); + intent.setComponent(comp); + ActivityUtils.getTopActivity().startActivity(intent); + } + } + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/activity/NotificationActivity.java b/app/src/main/java/com/bingce/controlnetwork/activity/NotificationActivity.java new file mode 100644 index 0000000..9e087ee --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/activity/NotificationActivity.java @@ -0,0 +1,250 @@ +package com.bingce.controlnetwork.activity; + +import android.annotation.SuppressLint; +import android.content.Intent; +import android.graphics.Bitmap; +import android.net.Uri; +import android.os.Bundle; +import android.text.TextUtils; +import android.util.Log; +import android.view.KeyEvent; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.webkit.WebResourceRequest; +import android.webkit.WebView; +import android.widget.LinearLayout; +import android.widget.TextView; + +import androidx.annotation.Nullable; +import androidx.appcompat.widget.Toolbar; + +import com.bingce.data.sync.utils.LeanCloudConfigLoader; +import com.bingce.utils.ClipboardUtils; +import com.bingce.utils.StringUtil; +import com.just.agentweb.AgentWeb; +import com.just.agentweb.DefaultWebClient; +import com.just.agentweb.WebChromeClient; +import com.just.agentweb.WebViewClient; + +import org.polaric.colorful.ColorfulActivity; + +import blankj.utilcode.util.ToastUtils; + +import com.bingce.controlnetwork.R; + +/** + * Created by cenxiaozhong on 2017/5/26. + *

+ * source code https://github.com/Justson/AgentWeb + */ + +public class NotificationActivity extends ColorfulActivity { + protected AgentWeb mAgentWeb; + private LinearLayout mLinearLayout; + private Toolbar mToolbar; + private TextView mTitleTextView; + + @SuppressLint("SourceLockedOrientationActivity") + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_agentweb_base); + + mLinearLayout = this.findViewById(R.id.container); + mToolbar = this.findViewById(R.id.toolbar); + mToolbar.setTitle(""); + mToolbar.setNavigationIcon(R.mipmap.icon_close_x); + mTitleTextView = this.findViewById(R.id.toolbar_title); + setSupportActionBar(mToolbar); + if (getSupportActionBar() != null) + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + mToolbar.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + + mAgentWeb = AgentWeb.with(this) + .setAgentWebParent(mLinearLayout, new LinearLayout.LayoutParams(-1, -1)) + .useDefaultIndicator() + .setWebChromeClient(mWebChromeClient) + .setWebViewClient(mWebViewClient) + .setMainFrameErrorView(R.layout.agentweb_error_page, -1) + .setSecurityType(AgentWeb.SecurityType.STRICT_CHECK) + .setOpenOtherPageWays(DefaultWebClient.OpenOtherPageWays.ASK)//打开其他应用时,弹窗咨询用户是否前往其他应用 + .interceptUnkownUrl() //拦截找不到相关页面的Scheme + .createAgentWeb() + .ready() + .go(getUrl()); + + mAgentWeb.getWebCreator().getWebView().getSettings().setSupportZoom(true); + mAgentWeb.getWebCreator().getWebView().getSettings().setBuiltInZoomControls(true); + mAgentWeb.getWebCreator().getWebView().getSettings().setDisplayZoomControls(false); + mAgentWeb.getWebCreator().getWebView().getSettings().setUseWideViewPort(true); + + LeanCloudConfigLoader.findInBackground("notificationUrl", instance -> { +// new LCQuery<>("Configuration") +// .whereEqualTo("name", "notificationUrl") +// .limit(1) +// .findInBackground().subscribe(new Observer>() { +// @Override +// public void onSubscribe(Disposable d) { +// +// } +// +// @Override +// public void onNext(List avObjects) { + if (isFinishing()) return; + if (/*avObjects != null && !avObjects.isEmpty() && avObjects.get(0).getString("value") != null*/instance != null && StringUtil.isNotEmpty(instance.value)) { + String url = /*avObjects.get(0).getString("value")*/instance.value; + mAgentWeb.getUrlLoader().loadUrl(url); + } else { + mAgentWeb.getUrlLoader().loadUrl("https://www.bingce.com"); + } +// } +// +// @Override +// public void onError(Throwable e) { +// +// } +// +// @Override +// public void onComplete() { +// +// } + }); + } + + private final WebViewClient mWebViewClient = new WebViewClient() { + @Override + public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) { + return super.shouldOverrideUrlLoading(view, request); + } + + @Override + public void onPageStarted(WebView view, String url, Bitmap favicon) { + //do you work + Log.i("Info", "AgentWebActivity onPageStarted"); + } + }; + private final WebChromeClient mWebChromeClient = new WebChromeClient() { + @Override + public void onReceivedTitle(WebView view, String title) { + super.onReceivedTitle(view, title); + if (mTitleTextView != null) { + mTitleTextView.setText(title); + } + } + }; + + public String getUrl() { + return null; + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.menu_activity_agentweb, menu); + return super.onCreateOptionsMenu(menu); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + // true表示AgentWeb处理了该事件 + if (!mAgentWeb.back()) { + finish(); + } + break; + case R.id.refresh: + if (mAgentWeb != null) { + mAgentWeb.getUrlLoader().reload(); // 刷新 + } + break; + case R.id.copy_url: + if (mAgentWeb != null) { + ClipboardUtils.copyText(mAgentWeb.getWebCreator().getWebView().getUrl()); + ToastUtils.showShort(R.string.copy_success); + } + break; + case R.id.clean: + toCleanWebCache(); + break; + case R.id.open_with_broswer: + if (mAgentWeb != null) { + openBrowser(mAgentWeb.getWebCreator().getWebView().getUrl()); + } + break; + } + return super.onOptionsItemSelected(item); + } + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (mAgentWeb.handleKeyEvent(keyCode, event)) { + return true; + } + return super.onKeyDown(keyCode, event); + } + + @Override + protected void onPause() { + mAgentWeb.getWebLifeCycle().onPause(); + super.onPause(); + + } + + @Override + protected void onResume() { + mAgentWeb.getWebLifeCycle().onResume(); + super.onResume(); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + Log.i("Info", "onResult:" + requestCode + " onResult:" + resultCode); + super.onActivityResult(requestCode, resultCode, data); + } + + + @Override + protected void onDestroy() { + super.onDestroy(); + //mAgentWeb.destroy(); + mAgentWeb.getWebLifeCycle().onDestroy(); + } + + /** + * 清除 WebView 缓存 + */ + private void toCleanWebCache() { + if (this.mAgentWeb != null) { + //清理所有跟WebView相关的缓存 ,数据库, 历史记录 等。 + this.mAgentWeb.clearWebCache(); + ToastUtils.showShort("已清理缓存"); + //清空所有 AgentWeb 硬盘缓存,包括 WebView 的缓存 , AgentWeb 下载的图片 ,视频 ,apk 等文件。 +// AgentWebConfig.clearDiskCache(this.getContext()); + } + } + + /** + * 打开浏览器 + * + * @param targetUrl 外部浏览器打开的地址 + */ + private void openBrowser(String targetUrl) { + if (TextUtils.isEmpty(targetUrl) || targetUrl.startsWith("file://")) { + ToastUtils.showShort(targetUrl + " 该链接无法使用浏览器打开。"); + return; + } + Intent intent = new Intent(); + intent.setAction("android.intent.action.VIEW"); + Uri mUri = Uri.parse(targetUrl); + intent.setData(mUri); + startActivity(intent); + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/activity/SettingsActivity.java b/app/src/main/java/com/bingce/controlnetwork/activity/SettingsActivity.java new file mode 100644 index 0000000..14ff5fd --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/activity/SettingsActivity.java @@ -0,0 +1,198 @@ +package com.bingce.controlnetwork.activity; + + +import android.annotation.SuppressLint; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.os.Bundle; +import android.view.MenuItem; +import android.view.WindowManager; + +import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.widget.Toolbar; +import androidx.fragment.app.Fragment; +import androidx.preference.ListPreference; +import androidx.preference.PreferenceFragmentCompat; +import androidx.preference.SwitchPreferenceCompat; + +import com.bingce.AppChannel; +import com.bingce.controlapphelper.surveyor.surveyor.ISurveyorConstants; +import com.bingce.controlnetwork.App; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.controller.KeyEventAction; + +import org.polaric.colorful.ColorPickerPreference; +import org.polaric.colorful.Colorful; +import org.polaric.colorful.ColorfulActivity; + +/** + * 设置页面 + */ +public class SettingsActivity extends ColorfulActivity { + private Toolbar mToolbar; + + @SuppressLint("SourceLockedOrientationActivity") + @Override + protected void onCreate(Bundle savedInstanceState) { + App app = App.getApp(); + if (app.isLandscape()) { + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE); + getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); + } else { + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); + getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); + } + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_settings); + mToolbar = findViewById(R.id.toolbar); + setSupportActionBar(mToolbar); + if (getSupportActionBar() != null) + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + if (savedInstanceState == null) { + getSupportFragmentManager().beginTransaction() + .add(R.id.activity_settings_content, createSettingFragment()) + .commit(); + } + } + + private Fragment createSettingFragment() { + return new SettingsFragment(); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (item.getItemId() == android.R.id.home) { + finish(); + } + return super.onOptionsItemSelected(item); + } + + public static class SettingsFragment extends PreferenceFragmentCompat { + private SwitchPreferenceCompat nightModePrefs; + private SwitchPreferenceCompat isOpenAtr; + private ColorPickerPreference themePrimaryColor, themeAccentColor; + + private ListPreference volume_plus_prefs, volume_minus_prefs; + + @Override + public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { + setPreferencesFromResource(R.xml.prefs, rootKey); + + nightModePrefs = findPreference("key_is_night_mode"); + themePrimaryColor = findPreference("key_theme_primary_color"); + themeAccentColor = findPreference("key_theme_accent_color"); + + + volume_plus_prefs = findPreference("key_volume_plus_function"); + volume_minus_prefs = findPreference("key_volume_minus_function"); + + volume_plus_prefs.setSummary(volume_plus_prefs.getEntry()); + volume_minus_prefs.setSummary(volume_minus_prefs.getEntry()); + + isOpenAtr = findPreference("key_is_open_atr"); + + nightModePrefs.setOnPreferenceChangeListener((preference, newValue) -> { + Colorful.config(App.getApp()).dark((Boolean) newValue).apply(); + new AlertDialog.Builder(getActivity()) + .setMessage(R.string.please_restart_to_apply_new_theme) + .setPositiveButton(R.string.confirm, null) + .setOnDismissListener(dialogInterface -> { + Intent intent = new Intent(); + intent.putExtra("isThemeChanged", true); + getActivity().setResult(RESULT_OK, intent); + getActivity().finish(); + }).show(); + return true; + }); + + + //主色 + themePrimaryColor.setOnPreferenceChangeListener((preference, newValue) -> { + new AlertDialog.Builder(getActivity()) + .setMessage(R.string.please_restart_to_apply_new_theme) + .setPositiveButton(R.string.confirm, null) + .setOnDismissListener(new DialogInterface.OnDismissListener() { + @Override + public void onDismiss(DialogInterface dialogInterface) { + Intent intent = new Intent(); + intent.putExtra("isThemeChanged", true); + getActivity().setResult(RESULT_OK, intent); + getActivity().finish(); + } + }).show(); + return true; + }); + //配色 + themeAccentColor.setOnPreferenceChangeListener((preference, newValue) -> { + new AlertDialog.Builder(getActivity()) + .setMessage(R.string.please_restart_to_apply_new_theme) + .setPositiveButton(R.string.confirm, null) + .setOnDismissListener(new DialogInterface.OnDismissListener() { + @Override + public void onDismiss(DialogInterface dialogInterface) { + Intent intent = new Intent(); + intent.putExtra("isThemeChanged", true); + getActivity().setResult(RESULT_OK, intent); + getActivity().finish(); + } + }).show(); + return true; + }); + + volume_plus_prefs.setOnPreferenceChangeListener((preference, newValue) -> { + setKeyEvent(newValue, volume_plus_prefs); + return true; + }); + volume_minus_prefs.setOnPreferenceChangeListener((preference, newValue) -> { + setKeyEvent(newValue, volume_minus_prefs); + return true; + }); + + isOpenAtr.setOnPreferenceChangeListener((preference, newValue) -> { + ISurveyorConstants.isOpenAtr = (boolean) newValue; + return true; + }); + + if (AppChannel.customChannel != AppChannel.CUSTOM_CONTROL_PUBLIC) { + //主配色隐藏 + themePrimaryColor.setVisible(false); + themeAccentColor.setVisible(false); + } + + } + + private void setKeyEvent(Object newValue, ListPreference volume_minus_prefs) { + switch (String.valueOf(newValue)) { + case KeyEventAction.NONE: + volume_minus_prefs.setSummary("无"); + break; + case KeyEventAction.CAL: + volume_minus_prefs.setSummary("计算"); + break; + case KeyEventAction.SURVEY: + volume_minus_prefs.setSummary("观测"); + break; + case KeyEventAction.RECORD: + volume_minus_prefs.setSummary("记录"); + break; + case KeyEventAction.LAST: + volume_minus_prefs.setSummary("上一点"); + break; + case KeyEventAction.NEXT: + volume_minus_prefs.setSummary("下一点"); + break; + case KeyEventAction.SURVEY_NO_SEND: + volume_minus_prefs.setSummary("观测后不发送结果"); + break; + case KeyEventAction.SURVEY_AND_RECORD: + volume_minus_prefs.setSummary("观测并记录"); + break; + } + } + + } + + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/activity/SplashActivity.java b/app/src/main/java/com/bingce/controlnetwork/activity/SplashActivity.java new file mode 100644 index 0000000..9a777ab --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/activity/SplashActivity.java @@ -0,0 +1,231 @@ +package com.bingce.controlnetwork.activity; + +import static com.king.app.updater.util.AppUtils.getPackageInfo; + +import android.annotation.SuppressLint; +import android.content.Intent; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.Nullable; + +import com.bingce.file.FileOperator; +import com.bingce.path.PathManager; +import com.bingce.utils.NetworkUtil; +import com.bingce.utils.ThreadPoolUtil; +import com.bingce.zip.ZipUtil; + +import org.polaric.colorful.ColorfulActivity; + +import java.io.File; +import java.io.FileNotFoundException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.List; +import java.util.Locale; + +import cn.leancloud.LCFile; +import cn.leancloud.LCObject; +import cn.leancloud.LCQuery; + +import com.bingce.controlnetwork.databinding.ActivitySplashBinding; + +/** + * 欢迎页 + */ +@SuppressLint("CustomSplashScreen") +public class SplashActivity extends ColorfulActivity { + + private static final String CODE_NO_UPLOAD = "0"; + private static final String CODE_UPLOAD_COMPARE_SMALL_WITH_FIRST = "1"; + private static final String CODE_UPLOAD_COMPARE_SMALL_WITHOUT_FIRST = "2"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); +// getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); + ActivitySplashBinding binding = ActivitySplashBinding.inflate(getLayoutInflater()); + setContentView(binding.getRoot()); + + startCopyDbFileToCache(); + } + + private void startCopyDbFileToCache() { + ThreadPoolUtil.execute(() -> { + try { + File copyFolder = PathManager.appDocumentFolder(); + File[] files = copyFolder.listFiles(); + List collectFileList = null; + if (files != null) { + collectFileList = new ArrayList<>(Arrays.asList(files)); + } + + if (collectFileList != null && !collectFileList.isEmpty()) { + + SimpleDateFormat simple = new SimpleDateFormat("yyyyMMddHHmmss", Locale.getDefault()); + String fileName = "导线助手数据备份_" + "_" + getVersionName() + "_" + simple.format(new Date()); + File zipTartFile = new File(copyFolder, fileName + ".zip"); + boolean zip = ZipUtil.zip(zipTartFile, collectFileList); + + if (zip) { + //获取上一次备份的文件 + File lastFile = getBeforeTargetFile(targetFolder()); + //备份文件 + File targetFile = new File(targetFolder().getAbsolutePath(), fileName); + boolean isCopySuccess = FileOperator.copyFile(zipTartFile.getAbsolutePath(), targetFile.getAbsolutePath()); + //无论备份成功或者失败都删除压缩后的文件 + zipTartFile.delete(); + if (isCopySuccess) { + //delete多余文件 + deleteRemainCacheFile(lastFile, targetFile); + + if (NetworkUtil.isNetworkAvailable(SplashActivity.this)) { + String code = queryUploadConfig(); + checkUpload(code, lastFile, targetFile); + } + } + } + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + goMainActivity(); + } + }); + } + + /** + * 文件个数大于3就删除 + * + * @param lastFile + * @param targetFile + */ + private void deleteRemainCacheFile(File lastFile, File targetFile) { + File file = targetFolder(); + if (file != null) { + File[] files = file.listFiles(); + if (files != null && files.length > 3) { + File deleteFile = null; + for (File fileEach : files) { + String eachName = fileEach.getName(); + if (eachName.equals(getFileName(lastFile)) || eachName.equals(getFileName(targetFile))) { + continue; + } + if (deleteFile != null && deleteFile.lastModified() > fileEach.lastModified()) { + deleteFile = fileEach; + } + if (deleteFile == null) { + deleteFile = fileEach; + } + } + if (deleteFile != null) { + deleteFile.delete(); + } + } + } + } + + private String getFileName(File file) { + if (file != null) { + return file.getName(); + } + return null; + } + + /** + * 导线助手是否自动上传可能错误的数据库 + * 0.不上传 + * 1.比上次小就上传上次备份数据;但是如果是首次备份,也将该备份上传 + * 2.比上次小就上传上次备份数据;如果是首次备份,不会将该备份上传 + */ + private void checkUpload(String code, File lastFile, File targetFile) throws FileNotFoundException { + if (CODE_NO_UPLOAD.equals(code)) { + //不上传 + } else if (CODE_UPLOAD_COMPARE_SMALL_WITH_FIRST.equals(code)) { + if (compareSmall(lastFile, targetFile)) { + uploadFile(lastFile); + } else if (lastFile == null) { + uploadFile(targetFile); + } + } else if (CODE_UPLOAD_COMPARE_SMALL_WITHOUT_FIRST.equals(code) && compareSmall(lastFile, targetFile)) { + uploadFile(lastFile); + } + } + + /** + * 是否比上次小 + * + * @param lastFile + * @param targetFile + * @return + */ + private boolean compareSmall(File lastFile, File targetFile) { + return lastFile != null && targetFile.length() < lastFile.length() / 2; + } + + /** + * 获取上次备份的文件 + * + * @param fileFolder + * @return + */ + private File getBeforeTargetFile(File fileFolder) { + File targetFile = null; + if (fileFolder != null) { + File[] files = fileFolder.listFiles(); + if (files != null) { + for (File eachFile : files) { + if (targetFile == null || targetFile.lastModified() < eachFile.lastModified()) { + targetFile = eachFile; + } + } + } + } + return targetFile; + } + + /** + * 上传leanCloud文件 + */ + private void uploadFile(File zipTartFile) throws FileNotFoundException { + Log.d("hwhw", "数据库备份文件上传LeanCloud"); + LCFile lcFile = LCFile.withAbsoluteLocalPath(zipTartFile.getName(), zipTartFile.getAbsolutePath()); + lcFile.save(); + } + + private void goMainActivity() { + startActivity(new Intent(this, MainActivity.class)); + finish(); + } + + + public File targetFolder() { + File cacheFolder = getCacheDir(); + File targetFolder = new File(cacheFolder, "dbBackUp"); + if (!targetFolder.exists()) { + targetFolder.mkdirs(); + } + return targetFolder; + } + + private String getVersionName() { + try { + return getPackageInfo(this).versionName; + } catch (Exception e) { + e.printStackTrace(); + } + return ""; + } + + private String queryUploadConfig() { + List avObjects = new LCQuery<>("Configuration").whereEqualTo("name", "ControlAppAutoUploadErrorDatabase") + .limit(1).find(); + if (avObjects != null && !avObjects.isEmpty() && avObjects.get(0).getString("value") != null) { + return avObjects.get(0).getString("value"); + } + return CODE_NO_UPLOAD; + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/activity/backup/AbstractBackupExportActivity.java b/app/src/main/java/com/bingce/controlnetwork/activity/backup/AbstractBackupExportActivity.java new file mode 100644 index 0000000..a4f5b85 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/activity/backup/AbstractBackupExportActivity.java @@ -0,0 +1,266 @@ +package com.bingce.controlnetwork.activity.backup; + +import android.content.Context; +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; +import android.view.View; +import android.view.WindowManager; +import android.widget.Button; + +import androidx.annotation.Nullable; +import androidx.annotation.WorkerThread; +import androidx.appcompat.widget.AppCompatTextView; + +import com.afollestad.materialdialogs.MaterialDialog; +import com.bingce.controlapphelper.datasource.database.SurveyorDataBase; +import com.bingce.controlapphelper.util.CheckStorageUtil; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.databinding.ActivityExportLayoutBinding; +import com.bingce.file.DownloadFileWriter; +import com.bingce.file.FileOperator; +import com.bingce.path.PathManager; +import com.bingce.utils.AsynchronousHelper; +import com.bingce.utils.FileUtil; +import com.bingce.utils.ThreadPoolUtil; +import com.bingce.zip.ZipUtil; +import com.github.ybq.android.spinkit.SpinKitView; + +import org.polaric.colorful.ColorfulActivity; + +import java.io.File; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Locale; + +import blankj.utilcode.util.StringUtils; +import blankj.utilcode.util.ToastUtils; + +public abstract class AbstractBackupExportActivity extends ColorfulActivity implements AsynchronousHelper.IDelegate { + + public static final String BACKUP_NAME = "导线助手数据"; + public static final String FOLDER_DADA_DATABASES = "dada_databases"; + public static final String FOLDER_DATA_FILE_PROJECT = "data_file_project"; + public static final String FOLDER_ANDROID = "android"; + public static final String FOLDER_SDCARD = "sdcard"; + public static final String BACKUP_TXT = "backup.txt"; + + + private final AsynchronousHelper asynchronousHelper = new AsynchronousHelper(this); + private File zipFile = null; + + protected abstract String tipsString(); + + private ActivityExportLayoutBinding binding; + + @Override + final protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + binding = ActivityExportLayoutBinding.inflate(getLayoutInflater()); + getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); + setContentView(binding.getRoot()); + binding.shareButton.setOnClickListener(v -> doCollect()); + binding.progressText.setText(tipsString()); + } + + protected abstract String applicationId(); + + protected abstract String zipFileName(String dateString, String projectName); + + private void doCollect() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { //如果是>=Q版本,不需要申请权限 + doExport(); + } else { //如果是低于Q版本,则先申请存储权限 + //检测是否有写权限 + requestStoragePermission(); + } + } + + public void requestStoragePermission() { + CheckStorageUtil.check(this, this::doExport); + } + + private void doExport() { + if (zipFile == null) { + startCollect(); + } else { + FileOperator.shareFile(this, zipFile, /*BuildConfig.APPLICATION_ID*/applicationId()); + } + } + + private void startCollect() { +// + binding.progressText.setText(""); + asynchronousHelper.start(); + binding.shareButton.setEnabled(false); + binding.spinKit.setVisibility(View.VISIBLE); + binding.tvCompleted.setVisibility(View.GONE); + ThreadPoolUtil.execute(() -> { + + File packageFile = getFilesDir().getParentFile(); + + //1 + File database1 = new File(packageFile, "databases"); + File[] files = database1.listFiles(); + List dataDatabasesFiles = getDbListFiles(files); + //2 + File file2 = new File(PathManager.appFolder(), "NOPROJECT"); + File[] files2 = file2.listFiles(); + List dataProjectFiles = getDbListFiles(files2); + //3 + File file3 = PathManager.appDocumentFolder(); + File[] files3 = file3.listFiles(); + List androidFiles = getDbListFiles(files3); + //4 + File file4 = new File(FileUtil.getSDPath(), "导线助手"); + File[] files4 = file4.listFiles(); + List sdFiles = getDbListFiles(files4); + + File fileTargetP = new File(PathManager.appCacheFolder(this), BACKUP_NAME); + FileUtil.deleteDir(fileTargetP); + + File fileTxt = new File(fileTargetP, "backup.txt"); + FileUtil.writeString(FOLDER_ANDROID, fileTxt); + + copyFile(dataDatabasesFiles, new File(fileTargetP, FOLDER_DADA_DATABASES)); + copyFile(dataProjectFiles, new File(fileTargetP, FOLDER_DATA_FILE_PROJECT)); + copyFile(androidFiles, new File(fileTargetP, FOLDER_ANDROID)); + copyFile(sdFiles, new File(fileTargetP, FOLDER_SDCARD)); + + SimpleDateFormat simple = new SimpleDateFormat("yyyyMMddHHmmss", Locale.getDefault()); + String fileName = zipFileName(simple.format(new Date()), ""); + File target = new File(fileTargetP, fileName + ".zip"); + List list = new ArrayList<>(); + list.add(fileTargetP); + boolean zip = ZipUtil.zip(target, list); + Log.d("hwhw", "备份是否ok" + zip); + if (zip) { + zipFile = target; + } + asynchronousHelper.completed(); + }); + } + + @Override + public void onBackPressed() { + if (asynchronousHelper.isWorking()) { + ToastUtils.showShort("数据收集中,请稍候。"); + return; + } + super.onBackPressed(); + } + + public static void start(Context context, Class clz) { + start(context, clz, null); + } + + private static final String KEY_PROJECT_NAME = "key_project_name"; + + public static void start(Context context, Class clz, String projectName) { + Intent intent = new Intent(context, clz); + if (!StringUtils.isEmpty(projectName)) { + intent.putExtra(KEY_PROJECT_NAME, projectName); + } + context.startActivity(intent); + } + + @Override + public void onUpdateProgress(String msg) { + String string = binding.progressText.getText().toString(); + binding.progressText.setText(string + "\n" + msg); + binding.scrollView.post(() -> binding.scrollView.fullScroll(View.FOCUS_DOWN)); + } + + @Override + public void onCompleted() { + if (zipFile == null) { + return; + } + if (isDestroyed() || isFinishing()) { + return; + } + Button shareButton = findViewById(R.id.share_button); + if (shareButton != null) { + shareButton.setEnabled(true); + shareButton.setText(R.string.share); + } + SpinKitView spinKitView = findViewById(R.id.spin_kit); + if (spinKitView != null) { + spinKitView.setVisibility(View.INVISIBLE); + } + AppCompatTextView completeTv = findViewById(R.id.tv_completed); + if (completeTv != null) { + completeTv.setText(Tools.getString(R.string.collection_completed)); + completeTv.setVisibility(View.VISIBLE); + } + //将文件存储到download中 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + String tipsString; + if (DownloadFileWriter.writeHigherQ(this, zipFile)) { + tipsString = "数据备份完毕,存储在根目录「Download\\" + zipFile.getName() + "」压缩包中."; + } else { + tipsString = "数据备份完毕,请存放到安全位置以便日后恢复."; + } + //弾框提示 + showDialog(this, applicationId(), tipsString, zipFile); + } else { + File resultFile = DownloadFileWriter.writeLowerQ(zipFile); + String tipsString; + if (resultFile != null) { + tipsString = "数据备份完毕,存储在「" + resultFile.getAbsolutePath() + "」压缩包中."; + } else { + tipsString = "数据备份完毕,请存放到安全位置以便日后恢复."; + } + showDialog(this, applicationId(), tipsString, zipFile); + } + } + + private static void showDialog(Context context, String applicationId, String title, File zipFile) { + //弾框提示 + new MaterialDialog.Builder(context).title(Tools.getString(R.string.notice)) + .content(title) + .positiveText(R.string.send_to) + .negativeText(R.string.cancel) + .cancelable(false) + .onPositive((dialog, which) -> FileOperator.shareFile(context, zipFile, /*BuildConfig.APPLICATION_ID*/applicationId)) + .show(); + } + + + /** + * 筛选出需要的db文件 + * + * @param files + * @return + */ + @WorkerThread + private List getDbListFiles(File[] files) { + List fileList = new ArrayList<>(); + if (files != null) { + for (File file : files) { + if (file.getName().contains(SurveyorDataBase.DB_NAME)) { + fileList.add(file); + } + } + } + return fileList; + } + + @WorkerThread + private void copyFile(List files, File targetFile) { + if (files != null && !files.isEmpty()) { + if (!targetFile.exists()) { + targetFile.mkdirs(); + } + + for (File file : files) { + FileOperator.copyFile(file.getAbsolutePath(), targetFile.getAbsolutePath() + File.separator + file.getName()); + } + } + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/activity/backup/BackupExportActivity.java b/app/src/main/java/com/bingce/controlnetwork/activity/backup/BackupExportActivity.java new file mode 100644 index 0000000..7164bca --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/activity/backup/BackupExportActivity.java @@ -0,0 +1,30 @@ +package com.bingce.controlnetwork.activity.backup; + +import blankj.utilcode.util.StringUtils; + +import com.bingce.controlnetwork.BuildConfig; +import com.bingce.controlnetwork.R; + +public class BackupExportActivity extends AbstractBackupExportActivity { + @Override + protected String tipsString() { + return getString(R.string.back_up_data_tips); + } + + @Override + protected String applicationId() { + return BuildConfig.APPLICATION_ID; + } + + @Override + protected String zipFileName(String dateString, String projectName) { + StringBuilder stringBuilder = new StringBuilder(BACKUP_NAME); + if (!StringUtils.isEmpty(projectName)) { + stringBuilder.append("[") + .append(projectName) + .append("]"); + } + stringBuilder.append(dateString); + return stringBuilder.toString(); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/activity/backup/launch/BackupImportHelper.java b/app/src/main/java/com/bingce/controlnetwork/activity/backup/launch/BackupImportHelper.java new file mode 100644 index 0000000..84ca3a7 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/activity/backup/launch/BackupImportHelper.java @@ -0,0 +1,45 @@ +package com.bingce.controlnetwork.activity.backup.launch; + +import android.app.Activity; +import android.content.Context; +import android.content.Intent; + +import androidx.activity.result.ActivityResultLauncher; +import androidx.activity.result.contract.ActivityResultContracts; +import androidx.appcompat.app.AppCompatActivity; +import androidx.fragment.app.Fragment; + +public class BackupImportHelper { + private ICallback callback; + private final ActivityResultLauncher importLauncher; + + public BackupImportHelper(AppCompatActivity activity) { + importLauncher = activity.registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> { + if (callback == null) { + return; + } + boolean success = result != null && Activity.RESULT_OK == result.getResultCode(); + callback.onImported(success); + }); + } + + public BackupImportHelper(Fragment fragment) { + importLauncher = fragment.registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> { + if (callback == null) { + return; + } + boolean success = result != null && Activity.RESULT_OK == result.getResultCode(); + callback.onImported(success); + }); + } + + public void doImport(Context context, ICallback callback) { + this.callback = callback; + Intent intent = MigrationFolder2PrivateRoomActivity.intent(context, true); + importLauncher.launch(intent); + } + + public interface ICallback { + void onImported(boolean success); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/activity/backup/launch/MigrationFolder2PrivateRoomActivity.java b/app/src/main/java/com/bingce/controlnetwork/activity/backup/launch/MigrationFolder2PrivateRoomActivity.java new file mode 100644 index 0000000..0fe5496 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/activity/backup/launch/MigrationFolder2PrivateRoomActivity.java @@ -0,0 +1,124 @@ +package com.bingce.controlnetwork.activity.backup.launch; + +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.view.View; +import android.view.WindowManager; + +import androidx.annotation.Nullable; + +import com.bingce.file.DownloadFilePicker; +import com.bingce.utils.AsynchronousHelper; +import com.bingce.utils.IntentUtil; + +import org.polaric.colorful.ColorfulActivity; + +import com.bingce.controlnetwork.databinding.ActivityMigration2PrivateFolderLayoutBinding; + +public class MigrationFolder2PrivateRoomActivity extends ColorfulActivity implements AsynchronousHelper.IDelegate { + private final DownloadFilePicker downloadFilePicker = new DownloadFilePicker(this); + private final AsynchronousHelper migrationHelper = new AsynchronousHelper(this); + private ActivityMigration2PrivateFolderLayoutBinding binding; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); + binding = ActivityMigration2PrivateFolderLayoutBinding.inflate(getLayoutInflater()); + setContentView(binding.getRoot()); + + //从备份文件导入 + binding.backupFromZip.setOnClickListener(v -> { + binding.layout2.setVisibility(View.INVISIBLE); + ZipMigrationUtils.importFromZip(MigrationFolder2PrivateRoomActivity.this, + "导线助手数据+日期", + migrationHelper, + downloadFilePicker, + new ZipMigrationUtils.IMigrationListener() { + @Override + public void onMigrationStart() { + showWorkLayout(); + } + + @Override + public void onMigrationInterrupt() { + back2Layout2(); + } + }); + }); + boolean fromMainActivity = IntentUtil.boolExtra(this, KEY_FROM_MAIN_ACTIVITY); + if (fromMainActivity) { + binding.enterAppDirect.setVisibility(View.GONE); + } else { + binding.enterAppDirect.setOnClickListener(v -> { + binding.backupFromZip.setEnabled(false); + binding.enterAppDirect.setEnabled(false); + enterApp(MigrationFolder2PrivateRoomActivity.this); + }); + } + } + + private void showWorkLayout() { + binding.workLayout.setVisibility(View.VISIBLE); + binding.back.setEnabled(false); + binding.back.setOnClickListener(v -> back2Layout2()); + binding.next.setEnabled(false); + binding.next.setOnClickListener(v -> { + binding.back.setEnabled(false); + binding.next.setEnabled(false); + enterApp(MigrationFolder2PrivateRoomActivity.this); + }); + binding.tvCompleted.setVisibility(View.INVISIBLE); + binding.spinKit.setVisibility(View.VISIBLE); + binding.progressText.setText(""); + } + + private void back2Layout2() { + binding.workLayout.setVisibility(View.INVISIBLE); + binding.layout2.setVisibility(View.VISIBLE); + } + + private static void enterApp(Activity activity) { + boolean fromMainActivity = IntentUtil.boolExtra(activity, KEY_FROM_MAIN_ACTIVITY); + if (fromMainActivity) { + activity.setResult(Activity.RESULT_OK); + activity.finish(); + } + } + + @Override + public void onBackPressed() { + boolean fromMainActivity = IntentUtil.boolExtra(this, KEY_FROM_MAIN_ACTIVITY); + if (fromMainActivity) { + super.onBackPressed(); + } + } + + @Override + public void onUpdateProgress(String msg) { + binding.progressText.setText(binding.progressText.getText() + "\n" + msg); + binding.scrollView.post(() -> binding.scrollView.fullScroll(View.FOCUS_DOWN)); + } + + @Override + public void onCompleted() { + binding.next.setEnabled(true); + binding.back.setEnabled(true); + binding.tvCompleted.setVisibility(View.VISIBLE); + binding.spinKit.setVisibility(View.INVISIBLE); + } + + private static final String KEY_FROM_MAIN_ACTIVITY = "from_main_activity"; + + public static void start(Context context) { + context.startActivity(intent(context, false)); + } + + public static Intent intent(Context context, boolean fromMainActivity) { + Intent intent = new Intent(context, MigrationFolder2PrivateRoomActivity.class); + intent.putExtra(KEY_FROM_MAIN_ACTIVITY, fromMainActivity); + return intent; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/activity/backup/launch/ZipMigrationUtils.java b/app/src/main/java/com/bingce/controlnetwork/activity/backup/launch/ZipMigrationUtils.java new file mode 100644 index 0000000..2dbf664 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/activity/backup/launch/ZipMigrationUtils.java @@ -0,0 +1,124 @@ +package com.bingce.controlnetwork.activity.backup.launch; + +import android.content.Context; +import android.text.TextUtils; + +import com.bingce.controlnetwork.activity.backup.AbstractBackupExportActivity; +import com.bingce.file.DownloadFilePicker; +import com.bingce.file.FileOperator; +import com.bingce.path.PathManager; +import com.bingce.utils.AsynchronousHelper; +import com.bingce.utils.FileUtil; +import com.bingce.utils.ThreadPoolUtil; +import com.bingce.zip.ZipHelper; + +import java.io.File; + +import blankj.utilcode.util.FileUtils; +import blankj.utilcode.util.ToastUtils; + +import com.bingce.controlnetwork.activity.backup.AbstractBackupExportActivity; + +public class ZipMigrationUtils { + + public static void importFromZip(Context context, String backupName, AsynchronousHelper asynchronousHelper, DownloadFilePicker downloadFilePicker, IMigrationListener listener) { + downloadFilePicker.doPick(duplicate -> { + String errorString = "请选择正确的备份数据,位于根目录Download文件夹内,名称样式为「" + backupName + ".zip」"; + if (duplicate == null || !duplicate.exists()) { + ToastUtils.showShort(errorString); + if (listener != null) { + listener.onMigrationInterrupt(); + } + return; + } + if (!duplicate.getName().endsWith(".zip")) { + ToastUtils.showShort(errorString); + if (listener != null) { + listener.onMigrationInterrupt(); + } + return; + } + asynchronousHelper.start(); + if (listener != null) { + listener.onMigrationStart(); + } + //切换线路执行数据解压 + ThreadPoolUtil.execute(() -> { + //解压缩 + + File unzipFolder = new File(context.getExternalCacheDir(), duplicate.getName().replace(".zip", "")); + File[] prjFolders = unzipBackupFile(duplicate, unzipFolder, errorString); + if (prjFolders == null) { + return; + } + + for (File file : prjFolders) { + File[] folder = file.listFiles(); + String backUpType = null; + for (File fileBackup : folder) { + if (!fileBackup.isDirectory()) { + if (fileBackup.getName().equals(AbstractBackupExportActivity.BACKUP_TXT)) { + FileUtil.ReadFileResult readFileResult = FileUtil.readStringFrom(fileBackup); + if (readFileResult.success) { + backUpType = readFileResult.string; + } + break; + } + } + } + + for (File fileBackup : folder) { + if (fileBackup.isDirectory()) { + String name = fileBackup.getName(); + if (TextUtils.equals(name, backUpType)) { + File[] dbFileList = fileBackup.listFiles(); + for (File dbFile : dbFileList) { + FileOperator.copy(dbFile, PathManager.appDocumentFolder()); + } + } + } + } + } + + + //完成数据导入 + asynchronousHelper.completed(); + }); + }); + } + + private static File[] unzipBackupFile(File duplicate, File unzipFolder, String errorString) { + if (!unzipFolder.exists()) { + if (!unzipFolder.mkdirs()) { + ToastUtils.showShort("解压备份文件失败"); + return null; + } + } else { + //先删除,再创建 + try { + FileUtils.delete(unzipFolder); + } catch (Exception e) { + e.printStackTrace(); + ToastUtils.showShort("解压备份文件失败"); + return null; + } + if (!unzipFolder.mkdirs()) { + ToastUtils.showShort("解压备份文件失败"); + return null; + } + } + if (!ZipHelper.unZipFile(unzipFolder.getAbsolutePath(), duplicate.getAbsolutePath())) { + ToastUtils.showShort(errorString); + return null; + } + //解析文件内容 + return unzipFolder.listFiles(); + } + + + public interface IMigrationListener { + void onMigrationStart(); + + void onMigrationInterrupt(); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/activity/fragmentcontainer/FragmentContainer.java b/app/src/main/java/com/bingce/controlnetwork/activity/fragmentcontainer/FragmentContainer.java new file mode 100644 index 0000000..c118304 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/activity/fragmentcontainer/FragmentContainer.java @@ -0,0 +1,92 @@ +package com.bingce.controlnetwork.activity.fragmentcontainer; + +import android.os.Bundle; + +import androidx.fragment.app.Fragment; + +import com.bingce.controlnetwork.fragment.PickPointFragment; +import com.bingce.controlnetwork.fragment.PointListFragment; +import com.bingce.controlnetwork.fragment.PrismManageFragment; +import com.bingce.controlnetwork.fragment.ProjectToleranceSettingFragment; +import com.bingce.controlnetwork.fragment.SelectExportHeightTraverseFragment; +import com.bingce.controlnetwork.fragment.SelectExportSurveyorRecordFragment; +import com.bingce.controlnetwork.fragment.SelectExportSurveyorRecordWireFileFragment; +import com.bingce.controlnetwork.fragment.SurveyorSettingsFragment; +import com.bingce.controlnetwork.fragment.ToleranceDetailFragment; +import com.bingce.controlnetwork.fragment.ToleranceManageFragment; +import com.bingce.controlnetwork.fragment.ToleranceSelectFragment; +import com.bingce.controlnetwork.fragment.projectdetail.ProjectDetailHeightTraverseFragment; +import com.bingce.controlnetwork.fragment.projectdetail.ProjectDetailTriangleFragment; +import com.bingce.controlnetwork.fragment.station.defaultstation.DefaultStationSetupFragment; +import com.bingce.controlnetwork.fragment.station.heighttraverse.CreateStationForHeightTraverseFragment; +import com.bingce.controlnetwork.fragment.station.line.attached.LineStationAttachedSetupFragment; +import com.bingce.controlnetwork.fragment.station.line.close.LineStationCloseSetupFragment; +import com.bingce.controlnetwork.fragment.station.line.random.LineStationRandomSetupFragment; +import com.bingce.controlnetwork.fragment.station.line.single.LineStationSingleSetupFragment; +import com.bingce.controlnetwork.fragment.station.line.well.LineStationWellDoubleGroundSetupFragment; +import com.bingce.controlnetwork.fragment.station.line.well.LineStationWellDoubleUnderGroundSetupFragment; +import com.bingce.controlnetwork.fragment.station.line.well.LineStationWellSetupFragment; +import com.bingce.controlnetwork.fragment.stationdetail.SingleStationDetailAndEditFragment; +import com.bingce.controlnetwork.fragment.stationsetting.StationSettingHeightTraverseFragment; +import com.bingce.controlnetwork.fragment.stationsetting.StationSettingsFragment; +import com.bingce.controlnetwork.fragment.stationsurvey.StationSurveyorFragment; +import com.bingce.controlnetwork.fragment.stationsurvey.angledistance.MeasureFragment; +import com.bingce.controlnetwork.fragment.stationsurvey.heighttraverse.MeasureHeightTraverseFragment; +import com.bingce.controlnetwork.func.level.fragment.LevelRouteCreateEditFragment; +import com.bingce.controlnetwork.func.level.fragment.LevelSelectExportFragment; +import com.bingce.controlnetwork.func.level.fragment.LevelSurveyFragment; +import com.bingce.controlnetwork.func.level.fragment.ProjectDetailLevelFragment; + +import java.util.HashMap; +import java.util.Map; + +public class FragmentContainer { + private interface IBuilder { + Fragment newInstance(Bundle args); + } + + private static final Map factory = new HashMap<>(); + + static { + factory.put(ProjectDetailHeightTraverseFragment.TAG, ProjectDetailHeightTraverseFragment::newInstance); + factory.put(ProjectDetailTriangleFragment.TAG, ProjectDetailTriangleFragment::newInstance); + factory.put(ProjectToleranceSettingFragment.TAG, ProjectToleranceSettingFragment::newInstance); + factory.put(ToleranceSelectFragment.TAG, ToleranceSelectFragment::newInstance); + factory.put(PointListFragment.TAG, PointListFragment::newInstance); + factory.put(SingleStationDetailAndEditFragment.TAG, SingleStationDetailAndEditFragment::newInstance); + factory.put(DefaultStationSetupFragment.TAG, DefaultStationSetupFragment::newInstance); + factory.put(PickPointFragment.TAG, PickPointFragment::newInstance); + factory.put(StationSurveyorFragment.TAG, StationSurveyorFragment::newInstance); + factory.put(StationSettingsFragment.TAG, StationSettingsFragment::newInstance); + factory.put(ToleranceManageFragment.TAG, ToleranceManageFragment::newInstance); + factory.put(ToleranceDetailFragment.TAG, ToleranceDetailFragment::newInstance); + factory.put(SelectExportSurveyorRecordFragment.TAG, SelectExportSurveyorRecordFragment::newInstance); + factory.put(SelectExportSurveyorRecordWireFileFragment.TAG, SelectExportSurveyorRecordWireFileFragment::newInstance); + factory.put(SurveyorSettingsFragment.TAG, SurveyorSettingsFragment::newInstance); + factory.put(LineStationSingleSetupFragment.TAG, LineStationSingleSetupFragment::newInstance); + factory.put(LineStationAttachedSetupFragment.TAG, LineStationAttachedSetupFragment::newInstance); + factory.put(LineStationCloseSetupFragment.TAG, LineStationCloseSetupFragment::newInstance); + factory.put(LineStationRandomSetupFragment.TAG, LineStationRandomSetupFragment::newInstance); + factory.put(LineStationWellSetupFragment.TAG, LineStationWellSetupFragment::newInstance); + factory.put(LineStationWellDoubleGroundSetupFragment.TAG, LineStationWellDoubleGroundSetupFragment::newInstance); + factory.put(LineStationWellDoubleUnderGroundSetupFragment.TAG, LineStationWellDoubleUnderGroundSetupFragment::newInstance); + factory.put(PrismManageFragment.TAG, PrismManageFragment::newInstance); + factory.put(MeasureFragment.TAG, MeasureFragment::newInstance); + factory.put(CreateStationForHeightTraverseFragment.TAG, CreateStationForHeightTraverseFragment::newInstance); + factory.put(MeasureHeightTraverseFragment.TAG, MeasureHeightTraverseFragment::newInstance); + factory.put(SelectExportHeightTraverseFragment.TAG, SelectExportHeightTraverseFragment::newInstance); + factory.put(StationSettingHeightTraverseFragment.TAG, StationSettingHeightTraverseFragment::newInstance); + factory.put(ProjectDetailLevelFragment.TAG, ProjectDetailLevelFragment::newInstance); + factory.put(LevelSurveyFragment.TAG, LevelSurveyFragment::newInstance); + factory.put(LevelSelectExportFragment.TAG, LevelSelectExportFragment::newInstance); + factory.put(LevelRouteCreateEditFragment.TAG, LevelRouteCreateEditFragment::newInstance); + } + + public static Fragment getFragment(String tag, Bundle bundle) { + IBuilder builder = factory.get(tag); + if (builder == null) { + return null; + } + return builder.newInstance(bundle); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/activity/fragmentcontainer/FragmentContainerActivity.java b/app/src/main/java/com/bingce/controlnetwork/activity/fragmentcontainer/FragmentContainerActivity.java new file mode 100644 index 0000000..7196267 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/activity/fragmentcontainer/FragmentContainerActivity.java @@ -0,0 +1,138 @@ +package com.bingce.controlnetwork.activity.fragmentcontainer; + +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.view.MenuItem; + +import androidx.annotation.Nullable; +import androidx.appcompat.widget.Toolbar; +import androidx.fragment.app.Fragment; + +import org.polaric.colorful.ColorfulActivity; + +import java.util.List; + +import com.bingce.controlnetwork.R; + +public class FragmentContainerActivity extends ColorfulActivity { + private static final String KEY_TAG = "_TAG_"; + private static final String KEY_TITLE_STRING_ID = "__title_res"; + private static final String KEY_TITLE_STRING = "__title__"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //设置view + setContentView(R.layout.activity_fragment_container_layout); + Toolbar mToolbar = findViewById(R.id.toolbar); + setSupportActionBar(mToolbar); + if (getSupportActionBar() != null) + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + //设置fragment + if (savedInstanceState == null) { + Intent intent = getIntent(); + if (intent == null) { + finish(); + return; + } + int title = intent.getIntExtra(KEY_TITLE_STRING_ID, -1); + if (title > 0) { + setTitle(title); + } else { + String string = intent.getStringExtra(KEY_TITLE_STRING); + setTitle(string); + } + String tag = intent.getStringExtra(KEY_TAG); + Bundle bundle = intent.getExtras(); + Fragment fragment = FragmentContainer.getFragment(tag, bundle); + if (fragment == null) { + finish(); + return; + } + getSupportFragmentManager().beginTransaction() + .replace(R.id.container, fragment) + .commitAllowingStateLoss(); + } + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (item.getItemId() == android.R.id.home) { + if (!isCancelBack()) { + finish(); + } + } + return super.onOptionsItemSelected(item); + } + + @Override + public void onBackPressed() { + if (isCancelBack()) { + return; + } + super.onBackPressed(); + } + + private boolean isCancelBack() { + List fragmentList = getSupportFragmentManager() + .getFragments(); + boolean cancelBack = false; + for (Fragment fragment : fragmentList) { + if (fragment instanceof IOnBackFilter) { + if (((IOnBackFilter) fragment).cancelBack()) { + cancelBack = true; + break; + } + } + } + return cancelBack; + } + + public static void start(Context context, String tag, int titleRes, Bundle bundle) { + Intent intent = new Intent(context, FragmentContainerActivity.class); + if (bundle != null) { + intent.putExtras(bundle); + } + intent.putExtra(KEY_TAG, tag); + intent.putExtra(KEY_TITLE_STRING_ID, titleRes); + context.startActivity(intent); + } + + public static void start(Context context, String tag, String title, Bundle bundle) { + Intent intent = new Intent(context, FragmentContainerActivity.class); + if (bundle != null) { + intent.putExtras(bundle); + } + intent.putExtra(KEY_TAG, tag); + intent.putExtra(KEY_TITLE_STRING, title); + context.startActivity(intent); + } + + public static Intent startIntent(Context context, + String tag, + int titleRes, + Bundle bundle) { + Intent intent = new Intent(context, FragmentContainerActivity.class); + if (bundle != null) { + intent.putExtras(bundle); + } + intent.putExtra(KEY_TAG, tag); + intent.putExtra(KEY_TITLE_STRING_ID, titleRes); + return intent; + } + + public static Intent startIntent(Context context, + String tag, + String title, + Bundle bundle) { + Intent intent = new Intent(context, FragmentContainerActivity.class); + if (bundle != null) { + intent.putExtras(bundle); + } + intent.putExtra(KEY_TAG, tag); + intent.putExtra(KEY_TITLE_STRING, title); + return intent; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/activity/fragmentcontainer/FragmentItem.java b/app/src/main/java/com/bingce/controlnetwork/activity/fragmentcontainer/FragmentItem.java new file mode 100644 index 0000000..824ec89 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/activity/fragmentcontainer/FragmentItem.java @@ -0,0 +1,11 @@ +package com.bingce.controlnetwork.activity.fragmentcontainer; + +public class FragmentItem { + public final int titleId; + public final String tag; + + public FragmentItem(int title, String tag) { + titleId = title; + this.tag = tag; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/activity/fragmentcontainer/IOnBackFilter.java b/app/src/main/java/com/bingce/controlnetwork/activity/fragmentcontainer/IOnBackFilter.java new file mode 100644 index 0000000..36dca2d --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/activity/fragmentcontainer/IOnBackFilter.java @@ -0,0 +1,5 @@ +package com.bingce.controlnetwork.activity.fragmentcontainer; + +public interface IOnBackFilter { + boolean cancelBack(); +} diff --git a/app/src/main/java/com/bingce/controlnetwork/activity/user/EditNicknamePasswordActivity.java b/app/src/main/java/com/bingce/controlnetwork/activity/user/EditNicknamePasswordActivity.java new file mode 100644 index 0000000..0e87722 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/activity/user/EditNicknamePasswordActivity.java @@ -0,0 +1,143 @@ +package com.bingce.controlnetwork.activity.user; + +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.text.Editable; +import android.text.InputType; +import android.text.TextWatcher; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.widget.Toolbar; + +import org.polaric.colorful.ColorfulActivity; + +import blankj.utilcode.util.StringUtils; +import blankj.utilcode.util.Utils; +import cn.leancloud.LCUser; + +import com.bingce.controlnetwork.App; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.databinding.ActivityEditUserNicknamePasswordBinding; + +public class EditNicknamePasswordActivity extends ColorfulActivity { + + private ActivityEditUserNicknamePasswordBinding binding; + private boolean isShowPassword01, isShowPassword02; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + binding = ActivityEditUserNicknamePasswordBinding.inflate(getLayoutInflater()); + setContentView(binding.getRoot()); + + Toolbar mToolbar = findViewById(R.id.toolbar); + setSupportActionBar(mToolbar); + if (getSupportActionBar() != null) + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + //隐藏显示按钮01(输入密码) + binding.llPassword01.setOnClickListener(v -> { + if (isShowPassword01) { + // 明文显示密码 + binding.etPassword01.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_NORMAL); + binding.ivPassword01.setImageDrawable(getDrawable(R.drawable.icon_password_open_eyes)); + } else { + // 隐藏密码 + binding.etPassword01.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD); + binding.ivPassword01.setImageDrawable(getDrawable(R.drawable.icon_password_close_eyes)); + } + isShowPassword01 = !isShowPassword01; + }); + + //隐藏显示按钮02(确认密码) + binding.llPassword02.setOnClickListener(v -> { + if (isShowPassword02) { + // 明文显示密码 + binding.etPassword02.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_NORMAL); + binding.ivPassword02.setImageDrawable(getDrawable(R.drawable.icon_password_open_eyes)); + } else { + // 隐藏密码 + binding.etPassword02.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD); + binding.ivPassword02.setImageDrawable(getDrawable(R.drawable.icon_password_close_eyes)); + } + isShowPassword02 = !isShowPassword02; + }); + + binding.etPassword01.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { + + } + + @Override + public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { + + } + + @Override + public void afterTextChanged(Editable editable) { + checkPw(); + } + }); + binding.etPassword02.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { + + } + + @Override + public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { + + } + + @Override + public void afterTextChanged(Editable editable) { + checkPw(); + } + }); + + //完成 + binding.tvComplete.setOnClickListener(v -> { + String nickName = binding.etNickName.getText().toString(); + String password = binding.etPassword01.getText().toString(); + if (LCUser.getCurrentUser() != null) { + LCUser.getCurrentUser().setPassword(password); + LCUser.getCurrentUser().put("nickname", nickName); + LCUser.getCurrentUser().saveInBackground().subscribe(); + ((App) Utils.getApp()).isUserStatusChanged = true; + } + finish(); + }); + } + + private void checkPw() { + String nickName = binding.etNickName.getText().toString(); + String pw1 = binding.etPassword01.getText().toString(); + String pw2 = binding.etPassword02.getText().toString(); + boolean isEmptyNickName = StringUtils.isEmpty(nickName); + boolean isEmptyPw01 = StringUtils.isEmpty(pw1); + boolean isEmptyPw02 = StringUtils.isEmpty(pw2); + if (!isEmptyNickName && !isEmptyPw01 && !isEmptyPw02 && pw1.equals(pw2)) { + binding.tvComplete.setEnabled(true); + binding.tvComplete.setBackground(getDrawable(R.drawable.rectangle_radius_8_theme_green_full)); + } else { + binding.tvComplete.setEnabled(false); + binding.tvComplete.setBackground(getDrawable(R.drawable.rectangle_radius_8_gray_full)); + } + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + if (item.getItemId() == android.R.id.home) { + finish(); + } + return super.onOptionsItemSelected(item); + } + + public static void start(Context context) { + context.startActivity(new Intent(context, EditNicknamePasswordActivity.class)); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/activity/user/InputEmailActivity.java b/app/src/main/java/com/bingce/controlnetwork/activity/user/InputEmailActivity.java new file mode 100644 index 0000000..8c678b9 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/activity/user/InputEmailActivity.java @@ -0,0 +1,107 @@ +package com.bingce.controlnetwork.activity.user; + +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.text.Editable; +import android.text.TextWatcher; + +import androidx.activity.result.ActivityResultLauncher; +import androidx.activity.result.contract.ActivityResultContracts; +import androidx.annotation.Nullable; +import androidx.appcompat.widget.Toolbar; + +import com.bingce.utils.IntentUtil; +import com.bingce.utils.ValidateUtil; + +import org.polaric.colorful.ColorfulActivity; + +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.databinding.ActivityInputEmailBinding; + +public class InputEmailActivity extends ColorfulActivity { + public static final String KEY_EMAIL = "email"; + public static final String KEY_TODO = "todo"; + private ActivityInputEmailBinding binding; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + binding = ActivityInputEmailBinding.inflate(getLayoutInflater()); + setContentView(binding.getRoot()); + + Toolbar mToolbar = findViewById(R.id.toolbar); + setSupportActionBar(mToolbar); + if (getSupportActionBar() != null) getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + getSupportActionBar().setTitle(R.string.email_verify); + if (getEmail() != null) { + binding.etEmail.setText(getEmail()); + binding.etEmail.setEnabled(false); + if (checkEmail()) { + binding.tvNextPage.setEnabled(true); + binding.tvNextPage.setBackground(getDrawable(R.drawable.rectangle_radius_8_theme_green_full)); + } else { + binding.tvNextPage.setEnabled(false); + binding.tvNextPage.setBackground(getDrawable(R.drawable.rectangle_radius_8_gray_full)); + } + } + + binding.etEmail.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { + + } + + @Override + public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { + + } + + @Override + public void afterTextChanged(Editable editable) { + if (checkEmail()) { + binding.tvNextPage.setEnabled(true); + binding.tvNextPage.setBackground(getDrawable(R.drawable.rectangle_radius_8_theme_green_full)); + } else { + binding.tvNextPage.setEnabled(false); + binding.tvNextPage.setBackground(getDrawable(R.drawable.rectangle_radius_8_gray_full)); + } + } + }); + + ActivityResultLauncher verifyCodeLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> { + Intent data = result.getData(); + if (data != null) { + setResult(RESULT_OK, data); + finish(); + } + }); + //下一步 + binding.tvNextPage.setOnClickListener(v -> { + String email = binding.etEmail.getText().toString(); + VerifyEmailCodeActivity.start(this, email, getToDo(), verifyCodeLauncher); + }); + } + + private boolean checkEmail() { + return ValidateUtil.isEmail(binding.etEmail.getText().toString()); + } + + public static void start(Context context, String email, int todo, ActivityResultLauncher launcher) { + Intent intent = new Intent(context, InputEmailActivity.class); + intent.putExtra(KEY_EMAIL, email); + intent.putExtra(KEY_TODO, todo); + launcher.launch(intent); + } + + + private String getEmail() { + return IntentUtil.stringExtra(getIntent(), KEY_EMAIL); + } + + + private int getToDo() { + return IntentUtil.intExtra(getIntent(), KEY_TODO); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/activity/user/InputPhoneNumberActivity.java b/app/src/main/java/com/bingce/controlnetwork/activity/user/InputPhoneNumberActivity.java new file mode 100644 index 0000000..a92c5de --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/activity/user/InputPhoneNumberActivity.java @@ -0,0 +1,93 @@ +package com.bingce.controlnetwork.activity.user; + +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; + +import androidx.activity.result.ActivityResultLauncher; +import androidx.activity.result.contract.ActivityResultContracts; +import androidx.annotation.Nullable; +import androidx.appcompat.widget.Toolbar; + +import com.bingce.utils.IntentUtil; + +import org.polaric.colorful.ColorfulActivity; + +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.databinding.ActivityInputPhoneNumberBinding; + +public class InputPhoneNumberActivity extends ColorfulActivity { + public static final String KEY_PHONE = "phone_number"; + public static final String KEY_EMAIL = "email"; + public static final String KEY_UNION_ID = "unionid"; + public static final String KEY_TODO = "todo"; + private ActivityInputPhoneNumberBinding binding; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + binding = ActivityInputPhoneNumberBinding.inflate(getLayoutInflater()); + setContentView(binding.getRoot()); + + Toolbar mToolbar = findViewById(R.id.toolbar); + setSupportActionBar(mToolbar); + if (getSupportActionBar() != null) getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + getSupportActionBar().setTitle(R.string.mobile_phone_verify); + + binding.ccp.registerCarrierNumberEditText(binding.etPhoneNumber); + binding.ccp.setPhoneNumberValidityChangeListener(isValidNumber -> { + if (isValidNumber) { + binding.tvNextPage.setEnabled(true); + binding.tvNextPage.setBackground(getDrawable(R.drawable.rectangle_radius_8_theme_green_full)); + } else { + binding.tvNextPage.setEnabled(false); + binding.tvNextPage.setBackground(getDrawable(R.drawable.rectangle_radius_8_gray_full)); + } + }); + if (getPhoneNumber() != null) { + binding.etPhoneNumber.setText(getPhoneNumber().replaceFirst("\\+86", "")); + binding.etPhoneNumber.setEnabled(false); + binding.ccp.setCcpClickable(false); + } + + ActivityResultLauncher verifyCodeLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> { + Intent data = result.getData(); + if (data != null && data.hasExtra("isMail") && data.hasExtra("phoneNumberOrEmail")) { + setResult(RESULT_OK, data); + finish(); + } + }); + //下一步 + binding.tvNextPage.setOnClickListener(v -> { + String phoneNumber = binding.ccp.getFullNumberWithPlus(); + VerifySMSCodeActivity.start(this, phoneNumber, getEmail(), getUnionId(), getToDo(), verifyCodeLauncher); + }); + } + + public static void start(Context context, String phoneNumber, String email, String unionid, int todo, ActivityResultLauncher launcher) { + Intent intent = new Intent(context, InputPhoneNumberActivity.class); + intent.putExtra(KEY_PHONE, phoneNumber); + intent.putExtra(KEY_EMAIL, email); + intent.putExtra(KEY_UNION_ID, unionid); + intent.putExtra(KEY_TODO, todo); + launcher.launch(intent); + } + + private String getPhoneNumber() { + return IntentUtil.stringExtra(getIntent(), KEY_PHONE); + } + + + private String getEmail() { + return IntentUtil.stringExtra(getIntent(), KEY_EMAIL); + } + + private String getUnionId() { + return IntentUtil.stringExtra(getIntent(), KEY_UNION_ID); + } + + private int getToDo() { + return IntentUtil.intExtra(getIntent(), KEY_TODO); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/activity/user/LoginActivity.java b/app/src/main/java/com/bingce/controlnetwork/activity/user/LoginActivity.java new file mode 100644 index 0000000..f771c4b --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/activity/user/LoginActivity.java @@ -0,0 +1,579 @@ +package com.bingce.controlnetwork.activity.user; + +import android.app.Activity; +import android.app.ProgressDialog; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.text.Editable; +import android.text.TextWatcher; +import android.view.View; + +import androidx.activity.result.ActivityResultLauncher; +import androidx.activity.result.contract.ActivityResultContracts; +import androidx.annotation.Nullable; + +import com.bingce.AppChannel; +import com.bingce.BaseApp; +import com.bingce.activity.UserCloudFunction; +import com.bingce.controlnetwork.App; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.databinding.ActivityLoginBinding; +import com.bingce.controlnetwork.wxapi.MD5; +import com.bingce.data.sync.utils.LeanCloudUserLoginStateUtils; +import com.bingce.event.WxRespCodeEvent; +import com.bingce.ui.TabEntity; +import com.bingce.utils.ActivityUtils; +import com.bingce.utils.ValidateUtil; +import com.bingce.utils.VipManager; +import com.flyco.tablayout.listener.CustomTabEntity; +import com.flyco.tablayout.listener.OnTabSelectListener; +import com.hbb20.CountryCodePicker; +import com.tencent.mm.opensdk.modelmsg.SendAuth; + +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; +import org.greenrobot.eventbus.ThreadMode; +import org.polaric.colorful.ColorfulActivity; + +import java.util.ArrayList; +import java.util.Random; + +import alibaba.fastjson.JSON; +import alibaba.fastjson.JSONObject; +import blankj.utilcode.util.StringUtils; +import blankj.utilcode.util.ToastUtils; +import blankj.utilcode.util.Utils; +import cn.leancloud.LCException; +import cn.leancloud.LCUser; +import io.reactivex.Observer; +import io.reactivex.disposables.Disposable; + +public class LoginActivity extends ColorfulActivity { + + private ActivityLoginBinding binding; + private final String[] mTitles = new String[]{Utils.getApp().getString(R.string.phone_number), Utils.getApp().getString(R.string.e_mail)}; + private final ArrayList tabEntityList = new ArrayList<>(); + private boolean isLoginPassword = true, isLoginByEmail = false; + + private ProgressDialog progressDialog; + private String wxRespCode; + private String finishTo; + private ActivityResultLauncher signUpOrLoginLauncher; + + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + binding = ActivityLoginBinding.inflate(getLayoutInflater()); + setContentView(binding.getRoot()); + + setSupportActionBar(binding.getRoot().findViewById(R.id.toolbar)); + if (getSupportActionBar() != null) + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + EventBus.getDefault().register(this); + + finishTo = getIntent().getStringExtra("finishTo"); + + //绑定Tab数据 + for (String mTitle : mTitles) { + tabEntityList.add(new TabEntity(mTitle)); + } + binding.tabLoginMode.setTabData(tabEntityList); + + //切换手机号、邮箱 + binding.tabLoginMode.setOnTabSelectListener(new OnTabSelectListener() { + @Override + public void onTabSelect(int position) { + isLoginByEmail = position != 0; + onSelectTabPhoneEmail(); + } + + @Override + public void onTabReselect(int position) { + + } + }); + + //切换验证码、密码 + binding.tvLoginPasswordCode.setOnClickListener(v -> { + onClickBtnPassword(); + }); + + binding.ccp.registerCarrierNumberEditText(binding.etPhoneNumber); + binding.ccp.setPhoneNumberValidityChangeListener(new CountryCodePicker.PhoneNumberValidityChangeListener() { + @Override + public void onValidityChanged(boolean isValidNumber) { + if (isValidNumber) { + binding.tvNextPage.setEnabled(true); + binding.tvNextPage.setBackground(getDrawable(R.drawable.rectangle_radius_8_theme_green_full)); + } else { + binding.tvNextPage.setEnabled(false); + binding.tvNextPage.setBackground(getDrawable(R.drawable.rectangle_radius_8_gray_full)); + } + } + }); + //下一步 + binding.tvNextPage.setOnClickListener(v -> { + if (checkValid()) { + if (isLoginByEmail) { + String email = binding.etEmail.getText().toString().trim(); + if (!isLoginPassword) {//验证码登录 + VerifyEmailCodeActivity.start(this, email, VerifyEmailCodeActivity.TO_SIGNUP_OR_LOGIN_BY_EMAIL, signUpOrLoginLauncher); + } else { + String password = binding.etPassword.getText().toString(); + loginByEmailPassword(email, password); + } + } else { + String phoneNumber = binding.ccp.getFullNumberWithPlus(); + if (!isLoginPassword) {//验证码登录 + VerifySMSCodeActivity.start(this, phoneNumber, null, null, VerifySMSCodeActivity.TO_SIGNUP_OR_LOGIN_BY_PHONE_NUMBER, signUpOrLoginLauncher); + } else { + String password = binding.etPassword.getText().toString(); + if (phoneNumber.startsWith("+86")) { + phoneNumber = phoneNumber.replaceFirst("\\+86", ""); + } + loginByPhonePassword(phoneNumber, password); + } + } + } + }); + + binding.ivWechatLogin.setOnClickListener(v -> { + wxLogin(); + }); + signUpOrLoginLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> { + if (result.getResultCode() == Activity.RESULT_OK) { + Intent data = result.getData(); + if (data != null) { + if (data.hasExtra("sessionToken") && data.hasExtra("newUser")) { + String sessionToken = data.getStringExtra("sessionToken"); + boolean newUser = data.getBooleanExtra("newUser", false); + progressDialog = new ProgressDialog(LoginActivity.this); + progressDialog.setMessage(getString(R.string.logging)); + progressDialog.setCanceledOnTouchOutside(false); + progressDialog.show(); + LCUser.becomeWithSessionTokenInBackground(sessionToken, true).subscribe(new Observer() { + @Override + public void onSubscribe(Disposable d) { + + } + + @Override + public void onNext(LCUser lcUser) { + if (!ActivityUtils.isLiving(LoginActivity.this)) return; + if (progressDialog != null) + progressDialog.dismiss(); + loginSuccess(); + if (newUser) { + EditNicknamePasswordActivity.start(LoginActivity.this); + } + } + + @Override + public void onError(Throwable e) { + ToastUtils.showShort(getString(R.string.error_code) + new LCException(e).getCode()); + } + + @Override + public void onComplete() { + + } + }); + } + } + } + }); + + binding.etPassword.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { + + } + + @Override + public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { + + } + + @Override + public void afterTextChanged(Editable editable) { + checkValid(); + } + }); + } + + public static void start(Context context) { + context.startActivity(new Intent(context, LoginActivity.class)); + } + + public void onSelectTabPhoneEmail() { + binding.etPassword.setText(""); + if (!isLoginByEmail) {//手机号登录 + binding.llPhoneNumber.setVisibility(View.VISIBLE); + binding.llEmail.setVisibility(View.GONE); + binding.etPhoneNumber.setText(""); + if (isLoginPassword) { + binding.signUpHint.setText(R.string.if_you_do_not_have_an_account_you_can_use_a_verification_code_to_sign_up_and_log_in); + } else { + binding.signUpHint.setText(R.string.unsigned_up_mobile_phone_number_will_be_automatically_signed_up_and_logged_in); + } + } else {//邮箱登录 + binding.llPhoneNumber.setVisibility(View.GONE); + binding.llEmail.setVisibility(View.VISIBLE); + binding.etEmail.setText(""); + if (isLoginPassword) { + binding.signUpHint.setText(R.string.if_you_do_not_have_an_account_you_can_use_a_verification_code_to_sign_up_and_log_in); + } else { + binding.signUpHint.setText(R.string.unsigned_up_email_will_be_automatically_signed_up_and_logged_in); + } + } + checkValid(); + } + + public void onClickBtnPassword() { + isLoginPassword = !isLoginPassword; + if (!isLoginPassword) {//现在改为验证码登录 + binding.llPassword.setVisibility(View.GONE); + binding.tvNextPage.setText(R.string.next); + binding.tvLoginPasswordCode.setText(R.string.log_in_with_password); + if (!isLoginByEmail) {//手机号登录 + binding.signUpHint.setText(R.string.unsigned_up_mobile_phone_number_will_be_automatically_signed_up_and_logged_in); + } else { + binding.signUpHint.setText(R.string.unsigned_up_email_will_be_automatically_signed_up_and_logged_in); + } + } else {//现在改为密码登录 + binding.llPassword.setVisibility(View.VISIBLE); + binding.tvNextPage.setText(R.string.log_in); + binding.tvLoginPasswordCode.setText(R.string.log_in_using_verify_code); + binding.signUpHint.setText(R.string.if_you_do_not_have_an_account_you_can_use_a_verification_code_to_sign_up_and_log_in); + } + checkValid(); + } + + public boolean checkValid() { + if (!isLoginPassword) {//现在改为验证码登录 + if (isLoginByEmail) { + if (ValidateUtil.isEmail(binding.etEmail.getText().toString().trim())) { + binding.tvNextPage.setEnabled(true); + binding.tvNextPage.setBackground(getDrawable(R.drawable.rectangle_radius_8_theme_green_full)); + } else { + binding.tvNextPage.setEnabled(false); + binding.tvNextPage.setBackground(getDrawable(R.drawable.rectangle_radius_8_gray_full)); + return false; + } + } else { + if (binding.ccp.isValidFullNumber()) { + binding.tvNextPage.setEnabled(true); + binding.tvNextPage.setBackground(getDrawable(R.drawable.rectangle_radius_8_theme_green_full)); + } else { + binding.tvNextPage.setEnabled(false); + binding.tvNextPage.setBackground(getDrawable(R.drawable.rectangle_radius_8_gray_full)); + return false; + } + } + } else {//现在改为密码登录 + if (isLoginByEmail) { + if (ValidateUtil.isEmail(binding.etEmail.getText().toString().trim()) && !StringUtils.isEmpty(binding.etPassword.getText().toString().trim())) { + binding.tvNextPage.setEnabled(true); + binding.tvNextPage.setBackground(getDrawable(R.drawable.rectangle_radius_8_theme_green_full)); + } else { + binding.tvNextPage.setEnabled(false); + binding.tvNextPage.setBackground(getDrawable(R.drawable.rectangle_radius_8_gray_full)); + return false; + } + } else { + if (binding.ccp.isValidFullNumber() && !StringUtils.isEmpty(binding.etPassword.getText().toString().trim())) { + binding.tvNextPage.setEnabled(true); + binding.tvNextPage.setBackground(getDrawable(R.drawable.rectangle_radius_8_theme_green_full)); + } else { + binding.tvNextPage.setEnabled(false); + binding.tvNextPage.setBackground(getDrawable(R.drawable.rectangle_radius_8_gray_full)); + return false; + } + } + } + return true; + } + + public void wxLogin() { + wxRespCode = null; + if (Utils.getApp() instanceof BaseApp) { + if (((BaseApp) Utils.getApp()).getWxApi() != null) { + if (!((BaseApp) Utils.getApp()).getWxApi().isWXAppInstalled()) { + ToastUtils.showShort(R.string.you_do_not_have_the_wechat_app_installed); + } else { + final SendAuth.Req req = new SendAuth.Req(); + //应用授权作用域,如获取用户个人信息则填写 snsapi_userinfo + req.scope = "snsapi_userinfo"; + //用于保持请求和回调的状态,授权请求后原样带回给第三方。 + //该参数可用于防止 csrf 攻击(跨站请求伪造攻击), + //建议第三方带上该参数,可设置为简单的随机数加 session 进行校验 + req.state = getNonceStr(); + if (((BaseApp) Utils.getApp()).getWxApi() != null) + ((BaseApp) Utils.getApp()).getWxApi().sendReq(req); + } + } + } + } + + //生成随机号,防重发 + private String getNonceStr() { + Random random = new Random(); + return MD5.getMessageDigest((System.currentTimeMillis() + String.valueOf(random.nextInt(10000))).getBytes()); + } + + @Subscribe(threadMode = ThreadMode.MAIN) + public void onMessageEvent(WxRespCodeEvent event) { + wxRespCode = event.getCode(); + } + + @Override + protected void onResume() { + super.onResume(); + if (wxRespCode != null) { + loginByWxCode(); + wxRespCode = null; + } + } + + private void loginByWxCode() { + if (progressDialog != null) + progressDialog.dismiss(); + progressDialog = new ProgressDialog(LoginActivity.this); + progressDialog.setMessage(getString(R.string.logging)); + progressDialog.setCanceledOnTouchOutside(false); + progressDialog.show(); + UserCloudFunction.loginByWxCode(wxRespCode, AppChannel.customChannel, new UserCloudFunction.OnGetSessionTokenListener() { + @Override + public void onSessionTokenGetSuccess(String sessionToken, boolean newUser) { + LCUser.becomeWithSessionTokenInBackground(sessionToken, true).subscribe(new Observer() { + @Override + public void onSubscribe(Disposable d) { + + } + + @Override + public void onNext(LCUser lcUser) { + if (!ActivityUtils.isLiving(LoginActivity.this)) return; + if (progressDialog != null) + progressDialog.dismiss(); + if (newUser) { + EditNicknamePasswordActivity.start(LoginActivity.this); + } + ((App) Utils.getApp()).isUserStatusChanged = true; + setResult(RESULT_OK); + finish(); + } + + @Override + public void onError(Throwable e) { + if (!ActivityUtils.isLiving(LoginActivity.this)) return; + if (progressDialog != null) + progressDialog.dismiss(); + ToastUtils.showShort(getString(R.string.error_code) + new LCException(e).getCode()); + } + + @Override + public void onComplete() { + + } + }); + } + + @Override + public void onSessionTokenGetFailed(int code, String msg, String resp) { + if (!ActivityUtils.isLiving(LoginActivity.this)) return; + if (progressDialog != null) + progressDialog.dismiss(); + if (code == 321 || code == 322) {//321此微信未绑定用户,请使用其他方式登录,322缺少手机号或手机号未验证 + JSONObject jsonObject = JSON.parseObject(resp); + if (jsonObject.containsKey("data")) { + JSONObject data = jsonObject.getJSONObject("data"); + if (data.containsKey("unionid")) { + String unionid = data.getString("unionid"); + InputPhoneNumberActivity.start(LoginActivity.this, null, null, unionid, VerifySMSCodeActivity.TO_SIGNUP_OR_LOGIN_BY_WEIXIN_BIND_PHONE, signUpOrLoginLauncher); + } + } + } else { + ToastUtils.showLong(msg); + } + } + + @Override + public void onSessionTokenGetException(String msg) { + if (!ActivityUtils.isLiving(LoginActivity.this)) return; + if (progressDialog != null) + progressDialog.dismiss(); + ToastUtils.showLong(msg); + } + }); + } + + + private void loginSuccess() { + if (progressDialog != null) + progressDialog.dismiss(); + progressDialog = new ProgressDialog(LoginActivity.this); + progressDialog.setMessage(getString(R.string.logging)); + progressDialog.setCanceledOnTouchOutside(false); + progressDialog.show(); + VipManager.getInstance().controlSdkRefresh(LoginActivity.this, ((App) Utils.getApp()).registerCodeV2, new VipManager.OnSdkRefreshListener() { + @Override + public void onRefreshSuccess() { + if (!StringUtils.isEmpty(finishTo)) { + try { + Intent intent = new Intent(LoginActivity.this, Class.forName(finishTo)); + intent.putExtras(getIntent()); + startActivity(intent); + } catch (ClassNotFoundException | NullPointerException ex) { + ex.printStackTrace(); + } + } + + ((App) Utils.getApp()).isUserStatusChanged = true; + LeanCloudUserLoginStateUtils.onLogIn(); + setResult(RESULT_OK); + finish(); + } + + @Override + public void onRefreshFailed(int errorCode) { + ToastUtils.showShort(getString(R.string.error_code) + ":" + errorCode); + } + }); + } + + private void loginByEmailPassword(String email, String password) { + if (progressDialog != null) + progressDialog.dismiss(); + progressDialog = new ProgressDialog(LoginActivity.this); + progressDialog.setMessage(getString(R.string.logging)); + progressDialog.setCanceledOnTouchOutside(false); + progressDialog.show(); + UserCloudFunction.loginByEmailPassword(email, password, AppChannel.customChannel, new UserCloudFunction.OnGetSessionTokenListener() { + @Override + public void onSessionTokenGetSuccess(String sessionToken, boolean newUser) { + LCUser.becomeWithSessionTokenInBackground(sessionToken, true).subscribe(new Observer() { + @Override + public void onSubscribe(Disposable d) { + + } + + @Override + public void onNext(LCUser lcUser) { + if (!ActivityUtils.isLiving(LoginActivity.this)) return; + if (progressDialog != null) + progressDialog.dismiss(); + loginSuccess(); + if (newUser) { + EditNicknamePasswordActivity.start(LoginActivity.this); + } + } + + @Override + public void onError(Throwable e) { + if (!ActivityUtils.isLiving(LoginActivity.this)) return; + if (progressDialog != null) + progressDialog.dismiss(); + ToastUtils.showShort(getString(R.string.error_code) + new LCException(e).getCode()); + } + + @Override + public void onComplete() { + + } + }); + } + + @Override + public void onSessionTokenGetFailed(int code, String msg, String resp) { + if (!ActivityUtils.isLiving(LoginActivity.this)) return; + if (progressDialog != null) + progressDialog.dismiss(); + if (code == 303) {//缺少手机号或未验证 + InputPhoneNumberActivity.start(LoginActivity.this, null, email, null, VerifySMSCodeActivity.TO_SIGNUP_OR_LOGIN_BY_EMAIL_BIND_PHONE, signUpOrLoginLauncher); + } else if (code == 304) {//邮箱未验证 + InputEmailActivity.start(LoginActivity.this, email, VerifyEmailCodeActivity.TO_SIGNUP_OR_LOGIN_BY_EMAIL, signUpOrLoginLauncher); + } else { + if (msg != null) + ToastUtils.showLong(msg); + } + } + + @Override + public void onSessionTokenGetException(String msg) { + if (!ActivityUtils.isLiving(LoginActivity.this)) return; + if (progressDialog != null) + progressDialog.dismiss(); + ToastUtils.showLong(msg); + } + }); + } + + private void loginByPhonePassword(String phoneNumber, String password) { + if (progressDialog != null) + progressDialog.dismiss(); + progressDialog = new ProgressDialog(LoginActivity.this); + progressDialog.setMessage(getString(R.string.logging)); + progressDialog.setCanceledOnTouchOutside(false); + progressDialog.show(); + UserCloudFunction.loginByPhonePassword(phoneNumber, password, AppChannel.customChannel, new UserCloudFunction.OnGetSessionTokenListener() { + @Override + public void onSessionTokenGetSuccess(String sessionToken, boolean newUser) { + LCUser.becomeWithSessionTokenInBackground(sessionToken, true).subscribe(new Observer() { + @Override + public void onSubscribe(Disposable d) { + + } + + @Override + public void onNext(LCUser lcUser) { + if (!ActivityUtils.isLiving(LoginActivity.this)) return; + if (progressDialog != null) + progressDialog.dismiss(); + loginSuccess(); + if (newUser) { + EditNicknamePasswordActivity.start(LoginActivity.this); + } + } + + @Override + public void onError(Throwable e) { + if (!ActivityUtils.isLiving(LoginActivity.this)) return; + if (progressDialog != null) + progressDialog.dismiss(); + ToastUtils.showShort(getString(R.string.error_code) + new LCException(e).getCode()); + } + + @Override + public void onComplete() { + + } + }); + } + + @Override + public void onSessionTokenGetFailed(int code, String msg, String resp) { + if (!ActivityUtils.isLiving(LoginActivity.this)) return; + if (progressDialog != null) + progressDialog.dismiss(); + if (code == 303) {//手机号未验证 + InputPhoneNumberActivity.start(LoginActivity.this, phoneNumber, null, null, VerifySMSCodeActivity.TO_SIGNUP_OR_LOGIN_BY_PHONE_NUMBER, signUpOrLoginLauncher); + } else { + if (msg != null) + ToastUtils.showLong(msg); + } + } + + @Override + public void onSessionTokenGetException(String msg) { + if (!ActivityUtils.isLiving(LoginActivity.this)) return; + if (progressDialog != null) + progressDialog.dismiss(); + ToastUtils.showLong(msg); + } + }); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/activity/user/OpeningRenewalVipActivity.java b/app/src/main/java/com/bingce/controlnetwork/activity/user/OpeningRenewalVipActivity.java new file mode 100644 index 0000000..b172ff9 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/activity/user/OpeningRenewalVipActivity.java @@ -0,0 +1,534 @@ +package com.bingce.controlnetwork.activity.user; + +import android.content.DialogInterface; +import android.graphics.Bitmap; +import android.graphics.Color; +import android.net.Uri; +import android.os.Bundle; +import android.view.MenuItem; +import android.view.View; +import android.view.View.OnClickListener; +import android.widget.ImageView; +import android.widget.RadioGroup; + +import androidx.annotation.NonNull; +import androidx.appcompat.app.AlertDialog; + +import com.afollestad.materialdialogs.DialogAction; +import com.afollestad.materialdialogs.MaterialDialog; +import com.bingce.controlnetwork.App; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.databinding.ActivityOpeningRenewalBinding; +import com.bingce.data.sync.utils.LeanCloudConfigLoader; +import com.bingce.event.PayOverEvent; +import com.bingce.pay.OrderType; +import com.bingce.pay.WxPayV3; +import com.bingce.surveyor.agentweb.AgentWebActivity; +import com.bingce.utils.ActivityUtils; +import com.bingce.utils.DateUtils; +import com.bingce.utils.StringUtil; +import com.bingce.utils.Util; +import com.bingce.utils.VipManager; +import com.bumptech.glide.Glide; +import com.huawei.hms.hmsscankit.ScanUtil; +import com.huawei.hms.hmsscankit.WriterException; +import com.huawei.hms.ml.scan.HmsBuildBitmapOption; +import com.huawei.hms.ml.scan.HmsScan; + +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; +import org.greenrobot.eventbus.ThreadMode; +import org.polaric.colorful.ColorfulActivity; + +import java.util.Date; + +import blankj.utilcode.util.AppUtils; +import blankj.utilcode.util.ToastUtils; +import blankj.utilcode.util.Utils; +import cn.leancloud.LCUser; + +public class OpeningRenewalVipActivity extends ColorfulActivity { + private int total_fee = -1; + private ImageView qrImageView; + private int queryCount = 0; + private int oneMonthPrice = -1, threeMonthsPrice = -1, oneYearPrice = -1; + private MaterialDialog payingDialog; + private ActivityOpeningRenewalBinding binding; + private String orderType = OrderType.ORDER_TYPE_SURVEYOR_365; + private boolean hasPayResult = false; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + binding = ActivityOpeningRenewalBinding.inflate(getLayoutInflater()); + setContentView(binding.getRoot()); + setSupportActionBar(binding.getRoot().findViewById(R.id.toolbar)); + if (getSupportActionBar() != null) + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + EventBus.getDefault().register(this); + + binding.activityOpeningRenewalTvVersion.setText("V" + AppUtils.getAppVersionName()); + + if (VipManager.getInstance().expireDate != null) { + binding.activityOpeningRenewalTvExpirationDate.setText(getString(R.string.current_expiration_date) + ":" + DateUtils.toFull(VipManager.getInstance().expireDate)); + } else { + binding.activityOpeningRenewalTvExpirationDate.setText(getString(R.string.current_expiration_date) + ":无"); + } + + binding.activityOpeningRenewalRadiogroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(RadioGroup group, int checkedId) { + if (oneMonthPrice <= 0 || threeMonthsPrice <= 0 || oneYearPrice <= 0) { + ToastUtils.showShort("请先联网获取套餐价格"); + return; + } + if (checkedId == binding.activityOpeningRenewalRadiobuttonOneMonth.getId()) { + total_fee = oneMonthPrice; + orderType = OrderType.ORDER_TYPE_SURVEYOR_30; + } else if (checkedId == binding.activityOpeningRenewalRadiobuttonThreeMonths.getId()) { + total_fee = threeMonthsPrice; + orderType = OrderType.ORDER_TYPE_SURVEYOR_90; + } else if (checkedId == binding.activityOpeningRenewalRadiobuttonOneYear.getId()) { + total_fee = oneYearPrice; + orderType = OrderType.ORDER_TYPE_SURVEYOR_365; + } + if (total_fee <= 0) { + binding.activityOpeningRenewalTvTotalFee.setText("联网获取价格"); + } else { + binding.activityOpeningRenewalTvTotalFee.setText(Util.formatDouble2StringDotAuto(total_fee / 100.0) + "元"); + } + } + }); + + if (VipManager.getInstance().checkReg()) { + new AlertDialog.Builder(this) + .setTitle(R.string.hint) + .setMessage("此手机已经绑定激活,请确定是否需要购买会员,绑定激活和购买会员可以二选其一") + .setPositiveButton(R.string.i_know, null) + .show(); + } + + LeanCloudConfigLoader.findInBackground("opening_renewal_fee", instance -> { +// new LCQuery<>("Configuration") +// .whereEqualTo("name", "opening_renewal_fee") +// .limit(1) +// .findInBackground().subscribe(new Observer>() { +// @Override +// public void onSubscribe(Disposable d) { +// +// } +// +// @Override +// public void onNext(List avObjects) { + if (!ActivityUtils.isLiving(OpeningRenewalVipActivity.this)) return; + if (/*avObjects != null && !avObjects.isEmpty() && avObjects.get(0).getString("value") != null*/instance != null && StringUtil.isNotEmpty(instance.value)) { + String value = /*avObjects.get(0).getString("value")*/instance.value; + String value2 = /*avObjects.get(0).getString("value2")*/instance.value2; + String[] valueArr = value.split(","); + String[] value2Arr = value2.split(","); + if (valueArr.length == 3 && value2Arr.length == 3) { + try { + oneMonthPrice = Integer.parseInt(valueArr[0]); + threeMonthsPrice = Integer.parseInt(valueArr[1]); + oneYearPrice = Integer.parseInt(valueArr[2]); + binding.activityOpeningRenewalRadiobuttonOneMonth.setText(value2Arr[0] + " " + oneMonthPrice / 100.0 + "元"); + binding.activityOpeningRenewalRadiobuttonThreeMonths.setText(value2Arr[1] + " " + threeMonthsPrice / 100.0 + "元"); + binding.activityOpeningRenewalRadiobuttonOneYear.setText(value2Arr[2] + " " + oneYearPrice / 100.0 + "元"); + if (binding.activityOpeningRenewalRadiobuttonOneMonth.isChecked()) { + total_fee = oneMonthPrice; + } else if (binding.activityOpeningRenewalRadiobuttonThreeMonths.isChecked()) { + total_fee = threeMonthsPrice; + } else if (binding.activityOpeningRenewalRadiobuttonOneYear.isChecked()) { + total_fee = oneYearPrice; + } + if (total_fee <= 0) { + binding.activityOpeningRenewalTvTotalFee.setText("联网获取价格"); + } else { + binding.activityOpeningRenewalTvTotalFee.setText(Util.formatDouble2StringDotAuto(total_fee / 100.0) + "元"); + } + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + } else { + binding.activityOpeningRenewalTvTotalFee.setText("联网获取价格"); + } +// } +// +// @Override +// public void onError(Throwable e) { +// +// } +// +// @Override +// public void onComplete() { +// +// } + }); + LeanCloudConfigLoader.findInBackground("opening_renewal_activity", instance -> { +// new LCQuery<>("Configuration") +// .whereEqualTo("name", "opening_renewal_activity") +// .limit(1) +// .findInBackground().subscribe(new Observer>() { +// @Override +// public void onSubscribe(Disposable d) { +// +// } +// +// @Override +// public void onNext(List avObjects) { + if (!ActivityUtils.isLiving(OpeningRenewalVipActivity.this)) return; + if (/*avObjects != null && !avObjects.isEmpty() && avObjects.get(0).getString("value") != null*/instance != null && StringUtil.isNotEmpty(instance.value)) { + String activity = /*avObjects.get(0).getString("value")*/instance.value; + binding.activityOpeningRenewalTvActivity.setText(activity); + } +// } +// +// @Override +// public void onError(Throwable e) { +// +// } +// +// @Override +// public void onComplete() { +// +// } + }); + + String adsQueryUrl = "android_opening_renewal_vip_img_ads"; + LeanCloudConfigLoader.findInBackground(adsQueryUrl, instance -> { +// new LCQuery<>("Configuration") +// .whereEqualTo("name", adsQueryUrl) +// .limit(1) +// .findInBackground() +// .subscribe(new Observer>() { +// @Override +// public void onSubscribe(Disposable d) { +// +// } +// +// @Override +// public void onNext(List avObjects) { + if (!ActivityUtils.isLiving(OpeningRenewalVipActivity.this)) return; + if (/*avObjects != null && !avObjects.isEmpty()*/instance != null) { + String adsUrl = /*avObjects.get(0).getString("value")*/instance.value; + if (adsUrl != null) { + binding.activityOpeningRenewalImgAds.setVisibility(View.VISIBLE); + Glide.with(OpeningRenewalVipActivity.this).load(adsUrl).into(binding.activityOpeningRenewalImgAds); + + String actionUrl = /*avObjects.get(0).getString("value2")*/instance.value2; + if (actionUrl != null) { + binding.activityOpeningRenewalImgAds.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { +// Intent intent = new Intent(); +// intent.setClass(Utils.getApp(), AgentWebActivity.class); +// intent.setData(Uri.parse(actionUrl)); +// startActivity(intent); + AgentWebActivity.navigation2( + OpeningRenewalVipActivity.this, + Uri.parse(actionUrl)); + } + }); + } + } + } +// } +// +// @Override +// public void onError(Throwable e) { +// +// } +// +// @Override +// public void onComplete() { +// +// } + }); + + binding.activityOpeningRenewalBtnTaobaoLink.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { +// Intent intent = new Intent(); +// intent.setClass(Utils.getApp(), AgentWebActivity.class); +// intent.putExtra("short_url", "taobaoUrl"); +// startActivity(intent); + AgentWebActivity.navigation2( + OpeningRenewalVipActivity.this, + "taobaoUrl"); + } + }); + binding.activityOpeningRenewalBtnContactCustomerService.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { +// Intent intent = new Intent(); +// intent.setClass(Utils.getApp(), AgentWebActivity.class); +// intent.putExtra("short_url", "android_url_contact_author"); +// startActivity(intent); + AgentWebActivity.navigation2( + OpeningRenewalVipActivity.this, + "android_url_contact_author" + ); + } + }); + + binding.activityOpeningRenewalBtnWepay.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View view) { + if (total_fee <= 0) { + ToastUtils.showShort("请联网获取价格"); + return; + } + binding.activityOpeningRenewalRadiobuttonOneYear.setEnabled(false); + binding.activityOpeningRenewalRadiobuttonOneMonth.setEnabled(false); + binding.activityOpeningRenewalRadiobuttonThreeMonths.setEnabled(false); + showPayListDialog(); + } + }); + + binding.activityOpeningRenewalBtnOpeningRenewalVipTutorial.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { +// Intent intent = new Intent(); +// intent.setClass(Utils.getApp(), AgentWebActivity.class); +// intent.putExtra("short_url", "android_url_opening_renewal_tutorial"); +// startActivity(intent); + AgentWebActivity.navigation2( + OpeningRenewalVipActivity.this, + "android_url_opening_renewal_tutorial" + ); + } + }); + } + + public void showPayListDialog() { + if (LCUser.getCurrentUser() == null) { + ToastUtils.showShort("请重新登录"); + return; + } + if (LCUser.getCurrentUser().getMobilePhoneNumber() == null) { + ToastUtils.showShort("账号绑定的手机号为空,请绑定后再试"); + return; + } + int fee = total_fee <= 0 ? 50000 : total_fee; + nativeOrder(fee);//由于云引擎appid是测量员的,所以无法调用app下单,只能二维码下单 +// new MaterialDialog.Builder(this) +// .title(R.string.choose_wechat_pay_type) +// .items(new String[]{getString(R.string.wechat_direct_pay), getString(R.string.wechat_qr_pay)}) +// .itemsCallback(new MaterialDialog.ListCallback() { +// @Override +// public void onSelection(MaterialDialog dialog, View itemView, int which, CharSequence text) { +// switch (which) { +// case 0: +// appOrder(fee); +// break; +// case 1: +// nativeOrder(fee); +// break; +// } +// binding.activityOpeningRenewalBtnWepay.setEnabled(false); +// } +// }).show(); + } + + /** + * 二维码下单 + * + * @param fee 金额,单位分 + */ + private void nativeOrder(int fee) { + WxPayV3.getInstance().generateNativeVipOrder(this, + LCUser.getCurrentUser().getSessionToken(), + "导线助手会员", + fee, + orderType, + new WxPayV3.nativeOrderGenerateListener() { + @Override + public void onOrderGenerateSuccess(String code_url) { + showQrCode(code_url); + } + + @Override + public void onOrderGenerateFailed(String errorMsg) { + ToastUtils.showLong(errorMsg); + } + }); + } + + /** + * App跳转微信支付,下单 + * + * @param fee 金额,单位分 + */ + private void appOrder(int fee) { + //查询订单是否支付成功 + payingDialog = new MaterialDialog.Builder(OpeningRenewalVipActivity.this) + .title(R.string.hint) + .content("正在支付……稍后请点击\"支付完成\"") + .positiveText(R.string.pay_over) + .onPositive(new MaterialDialog.SingleButtonCallback() { + @Override + public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) { + //查询订单是否支付成功 + queryOrderStatus(); + } + }) + .show(); + + WxPayV3.getInstance().generateAppVipOrder(this, + LCUser.getCurrentUser().getSessionToken(), + "导线助手会员", + fee, + orderType, + new WxPayV3.appOrderGenerateListener() { + @Override + public void onOrderGenerateSuccess() { + hasPayResult = false; + WxPayV3.getInstance().pay(); + } + + @Override + public void onOrderGenerateFailed(String errorMsg) { + ToastUtils.showLong(errorMsg); + } + }); + } + + /** + * 查询订单支付状态 + */ + private void queryOrderStatus() { + binding.activityOpeningRenewalBtnWepay.setEnabled(true); + if (payingDialog != null) + payingDialog.dismiss(); + WxPayV3.getInstance().queryVipOrder(this, new WxPayV3.VipOrderQueryListener() { + @Override + public void onOrderPaySuccess(String orderType, Date paySuccessDate) { + VipManager.getInstance().controlSdkRefresh(OpeningRenewalVipActivity.this, ((App) Utils.getApp()).registerCodeV2, new VipManager.OnSdkRefreshListener() { + @Override + public void onRefreshSuccess() { + binding.activityOpeningRenewalTvExpirationDate.setText(String.format("%s:%s", getString(R.string.current_expiration_date), DateUtils.toFull(VipManager.getInstance().expireDate))); + new AlertDialog.Builder(OpeningRenewalVipActivity.this) + .setTitle(R.string.success) + .setMessage("续费成功,当前到期时间为" + DateUtils.toFull(VipManager.getInstance().expireDate)) + .setPositiveButton(R.string.confirm, null) + .setOnDismissListener(new DialogInterface.OnDismissListener() { + @Override + public void onDismiss(DialogInterface dialog) { + setResult(RESULT_OK); + finish(); + } + }) + .show(); + } + + @Override + public void onRefreshFailed(int errorCode) { + ToastUtils.showShort(getString(R.string.error_code) + ":" + errorCode); + } + }); + } + + @Override + public void onOrderQueryFailed(String errorMsg) { + tryQueryPayResultAgain(getString(R.string.pay_failed), errorMsg); + } + }); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (item.getItemId() == android.R.id.home) { + setResult(RESULT_OK); + finish(); + } + return super.onOptionsItemSelected(item); + } + + @Override + protected void onResume() { + super.onResume(); + if (hasPayResult) { + queryOrderStatus(); + hasPayResult = false; + } + } + + @Subscribe(threadMode = ThreadMode.MAIN) + public void onMessageEvent(PayOverEvent event) { + hasPayResult = true; + } + + /** + * 查询失败后再次显示查询查询 + */ + private void tryQueryPayResultAgain(String title, String message) { + if (!ActivityUtils.isLiving(this)) { + return; + } + new AlertDialog.Builder(OpeningRenewalVipActivity.this) + .setTitle(title) + .setMessage(message) + .setPositiveButton(R.string.query_again, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + if (queryCount >= 5) { + ToastUtils.showLong(R.string.query_times_cannot_bigger_than_five); + return; + } + queryCount++; + //查询订单是否支付成功 + queryOrderStatus(); + } + }) + .setNegativeButton(R.string.cancel, null) + .show(); + } + + /** + * 生成二维码 + */ + public void showQrCode(String code_url) { + MaterialDialog dialog = new MaterialDialog.Builder(this) + .title(R.string.wechat_qr_pay) + .customView(R.layout.dialog_register_pay_qr_code, false) + .positiveText(this.getString(R.string.pay_over)) + .dismissListener(new DialogInterface.OnDismissListener() { + @Override + public void onDismiss(DialogInterface dialogInterface) { + //查询订单是否支付成功 + queryOrderStatus(); + } + }) + .build(); + + qrImageView = dialog.getCustomView().findViewById(R.id.dialog_register_pay_qr_code_imageview); + try { + HmsBuildBitmapOption options = new HmsBuildBitmapOption.Creator() + .setBitmapMargin(1) + .setBitmapColor(Color.BLACK) + .setBitmapBackgroundColor(Color.WHITE) + .create(); + Bitmap resultImage = ScanUtil.buildBitmap(code_url, HmsScan.QRCODE_SCAN_TYPE, 700, 700, options); + qrImageView.setImageBitmap(resultImage); + } catch (WriterException e) { + ToastUtils.showShort("二维码参数错误!"); + } + if (!ActivityUtils.isLiving(this)) { + return; + } + dialog.show(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + EventBus.getDefault().unregister(this); + if (payingDialog != null) { + payingDialog.dismiss(); + payingDialog = null; + } + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/activity/user/RedeemVipActivity.java b/app/src/main/java/com/bingce/controlnetwork/activity/user/RedeemVipActivity.java new file mode 100644 index 0000000..c77c3b9 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/activity/user/RedeemVipActivity.java @@ -0,0 +1,171 @@ +package com.bingce.controlnetwork.activity.user; + +import android.app.ProgressDialog; +import android.content.DialogInterface; +import android.graphics.Color; +import android.os.Bundle; +import android.text.Editable; +import android.text.TextWatcher; +import android.view.MenuItem; +import android.view.View; +import android.view.View.OnClickListener; + +import androidx.appcompat.app.AlertDialog; + +import com.bingce.AppChannel; +import com.bingce.activity.VipCloudFunction; +import com.bingce.controlapphelper.util.HideKeyUtil; +import com.bingce.controlapphelper.util.SettingValueUtil; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.databinding.ActivityRedeemBinding; +import com.bingce.utils.DateUtils; +import com.bingce.utils.VipManager; + +import org.polaric.colorful.ColorfulActivity; + +import java.util.Date; + +import blankj.utilcode.util.AppUtils; +import blankj.utilcode.util.ToastUtils; +import cn.leancloud.LCObject; +import cn.leancloud.LCUser; + +public class RedeemVipActivity extends ColorfulActivity { + private ProgressDialog progressDialog; + private LCObject cashVoucherLCObject; + private ActivityRedeemBinding binding; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + binding = ActivityRedeemBinding.inflate(getLayoutInflater()); + setContentView(binding.getRoot()); + setSupportActionBar(binding.getRoot().findViewById(R.id.toolbar)); + if (getSupportActionBar() != null) + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + initMaterialEditTextColor(); + + binding.activityRedeemTvVersion.setText("V" + AppUtils.getAppVersionName()); + + if (LCUser.getCurrentUser() != null) { + if (VipManager.getInstance().expireDate != null) { + binding.activityRedeemTvExpirationDate.setText(getString(R.string.current_expiration_date) + ":" + DateUtils.toFull(VipManager.getInstance().expireDate)); + } else { + binding.activityRedeemTvExpirationDate.setText(getString(R.string.current_expiration_date) + ":无"); + } + } else { + ToastUtils.showShort(R.string.not_log_in); + finish(); + } + + if (VipManager.getInstance().checkReg()) { + new AlertDialog.Builder(this) + .setTitle(R.string.hint) + .setMessage("此手机已经绑定激活,请确定是否需要购买会员,绑定激活和购买会员可以二选其一") + .setPositiveButton(R.string.i_know, null) + .show(); + } + + binding.activityRedeemMetRedeemCode.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + } + + @Override + public void afterTextChanged(Editable s) { + binding.activityRedeemBtnRedeem.setEnabled(!"".equals(binding.activityRedeemMetRedeemCode.getText().toString().trim())); + } + }); + + binding.activityRedeemBtnRedeem.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + if (LCUser.getCurrentUser() == null) { + ToastUtils.showShort(R.string.not_log_in); + return; + } + HideKeyUtil.hideSoftInput(); + if (binding.activityRedeemMetRedeemCode.getText().toString().trim().length() != 24) { + ToastUtils.showShort(R.string.cash_voucher_code_length_must_be_24); + return; + } + + progressDialog = new ProgressDialog(RedeemVipActivity.this); + progressDialog.setMessage(getString(R.string.please_wait)); + progressDialog.setCanceledOnTouchOutside(false); + progressDialog.show(); + + String cashVoucherCode = binding.activityRedeemMetRedeemCode.getText().toString().trim().toLowerCase(); + VipCloudFunction.redeemVip(LCUser.getCurrentUser().getSessionToken(), cashVoucherCode, AppChannel.customChannel, new VipCloudFunction.OnRedeemVipListener() { + @Override + public void onRedeemSuccess(Date newExpireDate) { + if (progressDialog != null) + progressDialog.dismiss(); + + savePayLog(cashVoucherCode, newExpireDate); + + new AlertDialog.Builder(RedeemVipActivity.this) + .setTitle(R.string.success) + .setMessage("续费成功,当前到期时间为" + DateUtils.toFull(newExpireDate)) + .setPositiveButton(R.string.confirm, null) + .setOnDismissListener(new DialogInterface.OnDismissListener() { + @Override + public void onDismiss(DialogInterface dialog) { + setResult(RESULT_OK); + finish(); + } + }) + .show(); + } + + @Override + public void onRedeemFailed(String errorMsg) { + if (progressDialog != null) + progressDialog.dismiss(); + ToastUtils.showShort(errorMsg); + } + }); + } + }); + } + + private void savePayLog(String cashVoucher, Date newExpireDate) { + final LCObject payLog = new LCObject("PayLog"); + payLog.put("payFor", "兑换会员"); + payLog.put("user", LCUser.getCurrentUser()); + payLog.put("currentExpireDate", newExpireDate); + payLog.put("client", "android"); + payLog.put("channel", "cashVoucher"); + payLog.put("total_fee", "0"); + payLog.put("cash_fee", "0"); + payLog.put("versionCode", AppUtils.getAppVersionCode()); + payLog.put("cashVoucher", cashVoucher); + payLog.saveInBackground().subscribe(); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (item.getItemId() == android.R.id.home) { + finish(); + } + return super.onOptionsItemSelected(item); + } + + private void initMaterialEditTextColor() { + if (SettingValueUtil.isThemeDark()) { + binding.activityRedeemMetRedeemCode.setMetTextColor(Color.WHITE); + + binding.activityRedeemMetRedeemCode.setPrimaryColor(Color.LTGRAY); + + binding.activityRedeemMetRedeemCode.setFocusFraction(1.0f); + + binding.activityRedeemMetRedeemCode.setMetHintTextColor(Color.GRAY); + + binding.activityRedeemMetRedeemCode.setUnderlineColor(Color.GRAY); + } + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/activity/user/RegisterActivity.java b/app/src/main/java/com/bingce/controlnetwork/activity/user/RegisterActivity.java new file mode 100644 index 0000000..abb5dba --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/activity/user/RegisterActivity.java @@ -0,0 +1,488 @@ +package com.bingce.controlnetwork.activity.user; + +import android.Manifest; +import android.app.Activity; +import android.app.ProgressDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.graphics.Bitmap; +import android.graphics.Color; +import android.os.Build; +import android.os.Bundle; +import android.view.MenuItem; +import android.view.View; +import android.view.View.OnClickListener; +import android.widget.Button; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.widget.Toolbar; +import androidx.core.content.ContextCompat; + +import com.afollestad.materialdialogs.DialogAction; +import com.afollestad.materialdialogs.MaterialDialog; +import com.bingce.controlapphelper.util.SettingValueUtil; +import com.bingce.controlnetwork.App; +import com.bingce.controlnetwork.R; +import com.bingce.data.sync.utils.LeanCloudConfigLoader; +import com.bingce.device.enums.SpecialDeviceEnum; +import com.bingce.device.ui.dialog.DialogUtil; +import com.bingce.surveyor.agentweb.AgentWebActivity; +import com.bingce.utils.AppUtil; +import com.bingce.utils.ClipboardUtils; +import com.bingce.utils.PropertiesGet; +import com.bingce.utils.RegisterUtil; +import com.bingce.utils.SdkUtils; +import com.bingce.utils.StringUtil; +import com.bingce.utils.Util; +import com.bingce.utils.VipManager; +import com.hjq.permissions.OnPermissionCallback; +import com.hjq.permissions.Permission; +import com.hjq.permissions.XXPermissions; +import com.huawei.hms.hmsscankit.ScanUtil; +import com.huawei.hms.hmsscankit.WriterException; +import com.huawei.hms.ml.scan.HmsBuildBitmapOption; +import com.huawei.hms.ml.scan.HmsScan; +import com.rengwuxian.materialedittext.MaterialEditText; + +import org.polaric.colorful.ColorfulActivity; + +import java.util.List; +import java.util.Locale; + +import blankj.utilcode.util.AppUtils; +import blankj.utilcode.util.ToastUtils; +import blankj.utilcode.util.Utils; +import cn.leancloud.LCException; +import cn.leancloud.LCObject; +import cn.leancloud.LCQuery; +import cn.leancloud.LCUser; +import io.reactivex.Observer; +import io.reactivex.disposables.Disposable; + +public class RegisterActivity extends ColorfulActivity { + private MaterialEditText met_machine_code, met_activate_code; + private Button mBtnCopy, mBtnActivate, mBtnTaobaoLink, mBtnContactAuthor, mBtnMachineQr, mBtnActivateTutorial; + private TextView mTextViewActivity, mTextViewVersion; + private String mMachineCode = "", mOriginalMachineCode = ""; + private Toolbar mToolbar; + boolean hasAndroidPermission = false; + private ProgressDialog progressDialog; + private ImageView qrImageView; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_activate); + mToolbar = findViewById(R.id.toolbar); + setSupportActionBar(mToolbar); + if (getSupportActionBar() != null) + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + initWidget(); + initMaterialEditTextColor(); + + mTextViewVersion.setText("V" + AppUtils.getAppVersionName()); + + if (!AppUtil.isZh() && SdkUtils.isRegCodeValidate() && !SdkUtils.isIntlCodeValidate()) {//非中文环境需要国际许可码 + DialogUtil.mDismissAlertDialog(this, R.string.hint, R.string.you_need_apply_for_an_international_license_code, R.string.i_know, null, null); + } + + boolean isSpecial = false; + for (SpecialDeviceEnum device : SpecialDeviceEnum.values()) { + if (device.getModel().equals(PropertiesGet.getModel()) + && device.getDevice().equals(PropertiesGet.getDevice()) + && device.getBoard().equals(PropertiesGet.getBoard()) + && device.getBrand().equals(PropertiesGet.getBrand()) + && device.getCpuAbi().equals(PropertiesGet.getCpuAbi()) + && device.getHardware().equals(PropertiesGet.getHardware()) + && device.getManufacturer().equals(PropertiesGet.getManufacturer())) { + isSpecial = true; + break; + } + } + if (!isSpecial && Build.VERSION.SDK_INT >= 29) { + mBtnTaobaoLink.setVisibility(View.GONE); + new AlertDialog.Builder(this) + .setMessage("由于安卓10及以上系统限制App读取硬件信息,原来绑定手机激活的方式已经不可用,如果您之前绑定手机激活过,很遗憾,现在只能刷机降级到安卓9或安卓8重新输入激活才可以。如果您不想刷机,可以购买会员继续使用") + .setPositiveButton(R.string.user_vip_activate, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + if (LCUser.getCurrentUser() == null) { + Intent intent = new Intent(Utils.getApp(), LoginActivity.class); + intent.putExtra("finishTo", UserInfoActivity.class.getName()); + startActivity(intent); + } else { + startActivity(new Intent(RegisterActivity.this, UserInfoActivity.class)); + } + } + }) + .setNeutralButton(R.string.opening_vip_tutorial, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { +// Intent intent = new Intent(); +// intent.setClass(Utils.getApp(), AgentWebActivity.class); +// intent.putExtra("short_url", "android_url_opening_renewal_tutorial"); +// startActivity(intent); + AgentWebActivity.navigation2(RegisterActivity.this, + "android_url_opening_renewal_tutorial"); + } + }) + .setNegativeButton(R.string.cancel, null) + .setOnDismissListener(new DialogInterface.OnDismissListener() { + @Override + public void onDismiss(DialogInterface dialog) { + if (!hasAndroidPermission) + finish(); + } + }).show(); + } else { + int checkStoragePermission = ContextCompat.checkSelfPermission(Utils.getApp(), Manifest.permission.READ_PHONE_STATE); + if (checkStoragePermission != PackageManager.PERMISSION_GRANTED) { + requestPhoneStatePermission(this); + } else { + if ("".equals(RegisterUtil.getOriginalMachineCode()) || "SERIALNUMBERunknown".equals(RegisterUtil.getOriginalMachineCode()) || "SERIALNUMBERnull".equals(RegisterUtil.getOriginalMachineCode())) { + new MaterialDialog.Builder(this) + .title(R.string.hint) + .content("此手机机器码未知,请关闭相关限制软件请重启软件") + .positiveText(R.string.i_know) + .dismissListener(new DialogInterface.OnDismissListener() { + @Override + public void onDismiss(DialogInterface dialog) { + finish(); + } + }).show(); + } + } + } + if (VipManager.getInstance().checkReg()) { + getSupportActionBar().setTitle(R.string.activated); + met_activate_code.setText(((App) Utils.getApp()).registerCodeV2); + mBtnActivate.setEnabled(false); + met_activate_code.setEnabled(false); + mBtnActivate.setText(R.string.activated); + } + + mMachineCode = RegisterUtil.getEncryptMachineCodeInfo(); + mOriginalMachineCode = RegisterUtil.getOriginalMachineCode(); + if (mMachineCode != null) { + met_machine_code.setText(mMachineCode); + } else { + met_machine_code.setText(getString(R.string.get_machine_code_fail)); + } + String queryUrl = "activate_activity_for_control_network"; + LeanCloudConfigLoader.findInBackground(queryUrl, instance -> { +// new LCQuery<>("Configuration") +// .whereEqualTo("name", queryUrl) +// .limit(1) +// .findInBackground() +// .subscribe(new Observer>() { +// @Override +// public void onSubscribe(Disposable d) { +// +// } +// +// @Override +// public void onNext(List avObjects) { + if (isFinishing()) return; + if (/*avObjects != null && !avObjects.isEmpty() && avObjects.get(0).getString("value") != null*/instance != null && StringUtil.isNotEmpty(instance.value)) { + String activity = /*avObjects.get(0).getString("value")*/instance.value; + mTextViewActivity.setText(activity); + } +// } +// +// @Override +// public void onError(Throwable e) { +// +// } +// +// @Override +// public void onComplete() { +// +// } + }); + mBtnCopy.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View arg0) { + if (mMachineCode != null) { + ClipboardUtils.copyText(mMachineCode); + ToastUtils.showShort(R.string.has_copy_to_clipboard); + } else { + ToastUtils.showShort(R.string.get_machine_code_fail); + } + } + }); + mBtnActivate.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View arg0) { + final String registerCode = met_activate_code.getText().toString().trim().toUpperCase(Locale.CHINA).replaceAll(" |\n|\r", ""); + if (mMachineCode == null) { + ToastUtils.showShort(R.string.machine_code_illegal); + return; + } + if ("".equals(met_activate_code.getText().toString().trim())) { + ToastUtils.showShort(R.string.please_input_register_code); + return; + } + if (registerCode.length() != 16) { + ToastUtils.showShort(R.string.register_code_is_16_characters); + return; + } + progressDialog = new ProgressDialog(RegisterActivity.this); + progressDialog.setMessage(getString(R.string.please_wait)); + progressDialog.setCanceledOnTouchOutside(false); + progressDialog.show(); + + new LCQuery<>("DeviceBlacklist") + .whereEqualTo("machineCode", mOriginalMachineCode) + .limit(1) + .findInBackground().subscribe(new Observer>() { + @Override + public void onSubscribe(Disposable d) { + + } + + @Override + public void onNext(List avObjects) { + if (isFinishing()) return; + if (avObjects == null || avObjects.isEmpty()) { + new LCQuery<>("Device") + .whereEqualTo("machineCode", mOriginalMachineCode) + .whereEqualTo("controlRegCode", registerCode) + .limit(1) + .findInBackground().subscribe(new Observer>() { + @Override + public void onSubscribe(Disposable disposable) { + + } + + @Override + public void onNext(List lcObjects) { + if (isFinishing()) return; + if (!lcObjects.isEmpty()) { + if (lcObjects.get(0).getBoolean("activated") && !lcObjects.get(0).getBoolean("converted")) { + ((App) Utils.getApp()).registerCodeV2 = registerCode; + Util.putPreference("registerCodeV2", registerCode); + + VipManager.getInstance().controlSdkRefresh(RegisterActivity.this, ((App) Utils.getApp()).registerCodeV2, new VipManager.OnSdkRefreshListener() { + @Override + public void onRefreshSuccess() { + progressDialog.dismiss(); + getSupportActionBar().setTitle(R.string.activated); + mBtnActivate.setEnabled(false); + met_activate_code.setEnabled(false); + ToastUtils.showShort(R.string.activate_success); + } + + @Override + public void onRefreshFailed(int errorCode) { + progressDialog.dismiss(); + ToastUtils.showShort(getString(R.string.error_code) + ":" + errorCode); + } + }); + //激活次数+1 + lcObjects.get(0).increment("activationTimes"); + lcObjects.get(0).saveInBackground().subscribe(); + } else if (lcObjects.get(0).getBoolean("converted")) { + progressDialog.dismiss(); + ToastUtils.showShort("此设备已经兑换过年会员,无法再绑定手机"); + } else if (!lcObjects.get(0).getBoolean("activated")) { + progressDialog.dismiss(); + ToastUtils.showShort("无法激活,请联系开发人员"); + } else { + progressDialog.dismiss(); + ToastUtils.showShort(R.string.cloud_has_not_register_code); + } + } else { + progressDialog.dismiss(); + ToastUtils.showShort("激活码无效"); + } + } + + @Override + public void onError(Throwable throwable) { + progressDialog.dismiss(); + ToastUtils.showShort(getString(R.string.error_code) + ":" + new LCException(throwable).getCode()); + } + + @Override + public void onComplete() { + + } + }); + } else { + progressDialog.dismiss(); + ToastUtils.showShort(R.string.you_are_in_blacklist); + } + } + + @Override + public void onError(Throwable e) { + progressDialog.dismiss(); + ToastUtils.showShort(getString(R.string.activate_need_to_connect_to_the_internet) + "," + getString(R.string.error_code) + ":" + new LCException(e).getCode()); + } + + @Override + public void onComplete() { + + } + }); + } + }); + mBtnTaobaoLink.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { +// Intent intent = new Intent(); +// intent.setClass(Utils.getApp(), AgentWebActivity.class); +// intent.putExtra("short_url", "taobaoUrl"); +// startActivity(intent); + AgentWebActivity.navigation2(RegisterActivity.this, "taobaoUrl"); + } + }); + mBtnContactAuthor.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { +// Intent intent = new Intent(); +// intent.setClass(Utils.getApp(), AgentWebActivity.class); +// intent.putExtra("short_url", "android_url_contact_author"); +// startActivity(intent); + AgentWebActivity.navigation2(RegisterActivity.this, + "android_url_contact_author"); + } + }); + + mBtnMachineQr.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View view) { + if (!mMachineCode.isEmpty()) + showMachineCodeQr(mMachineCode); + } + }); + + mBtnActivateTutorial.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { +// Intent intent = new Intent(); +// intent.setClass(Utils.getApp(), AgentWebActivity.class); +// intent.putExtra("short_url", "android_url_activate_tutorial"); +// startActivity(intent); + AgentWebActivity.navigation2( + RegisterActivity.this, + "android_url_activate_tutorial"); + } + }); + } + + private void initWidget() { + met_machine_code = findViewById(R.id.activity_activate_met_machine_code); + met_activate_code = findViewById(R.id.activity_activate_met_activate_code); + mBtnCopy = findViewById(R.id.activity_activate_btn_copy); + mBtnActivate = findViewById(R.id.activity_activate_btn_activate); + mBtnTaobaoLink = findViewById(R.id.activity_activate_btn_taobao_link); + mBtnContactAuthor = findViewById(R.id.activity_activate_btn_contact_customer_service); + mBtnMachineQr = findViewById(R.id.activity_activate_btn_machine_code_qr_code); + mBtnActivateTutorial = findViewById(R.id.activity_activate_btn_activate_tutorial); + mTextViewActivity = findViewById(R.id.activity_activate_tv_activity); + mTextViewVersion = findViewById(R.id.activity_activate_tv_version); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (item.getItemId() == android.R.id.home) { + finish(); + } + return super.onOptionsItemSelected(item); + } + + public void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (requestCode == 12) { + if (resultCode == Activity.RESULT_OK) { + met_activate_code.setText(((App) Utils.getApp()).registerCodeV2); + getSupportActionBar().setTitle(R.string.activated); + mBtnActivate.setEnabled(false); + met_activate_code.setEnabled(false); + } + } + } + + private void initMaterialEditTextColor() { + if (SettingValueUtil.isThemeDark()) { + met_machine_code.setMetTextColor(Color.WHITE); + met_activate_code.setMetTextColor(Color.WHITE); + + met_machine_code.setPrimaryColor(Color.LTGRAY); + met_activate_code.setPrimaryColor(Color.LTGRAY); + + met_machine_code.setFocusFraction(1.0f); + met_activate_code.setFocusFraction(1.0f); + + met_machine_code.setMetHintTextColor(Color.GRAY); + met_activate_code.setMetHintTextColor(Color.GRAY); + + met_machine_code.setUnderlineColor(Color.GRAY); + met_activate_code.setUnderlineColor(Color.GRAY); + } + } + + /** + * 生成机器码的二维码 + */ + public void showMachineCodeQr(String mMachineCode) { + MaterialDialog dialog = new MaterialDialog.Builder(this) + .title(R.string.machine_code) + .customView(R.layout.dialog_machine_code_qr_code, false) + .positiveText(this.getString(R.string.close)) + .build(); + + qrImageView = dialog.getCustomView().findViewById(R.id.dialog_machine_code_qr_code_imageview); + try { + HmsBuildBitmapOption options = new HmsBuildBitmapOption.Creator() + .setBitmapMargin(1) + .setBitmapColor(Color.BLACK) + .setBitmapBackgroundColor(Color.WHITE) + .create(); + Bitmap resultImage = ScanUtil.buildBitmap(mMachineCode, HmsScan.QRCODE_SCAN_TYPE, 700, 700, options); + qrImageView.setImageBitmap(resultImage); + } catch (WriterException e) { + ToastUtils.showShort("二维码参数错误!"); + } + dialog.show(); + } + + public static void requestPhoneStatePermission(Context context) { + new MaterialDialog.Builder(context) + .title(R.string.mobile_phone_permissions) + .content(R.string.verify_imei_imsi_code_to_prevent_account_theft) + .canceledOnTouchOutside(false) + .positiveText(R.string.to_allow) + .negativeText(R.string.refuse) + .onPositive(new MaterialDialog.SingleButtonCallback() { + @Override + public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) { + XXPermissions.with(context) + .permission(Permission.READ_PHONE_STATE) + .request(new OnPermissionCallback() { + @Override + public void onGranted(List permissions, boolean all) { + } + + @Override + public void onDenied(List permissions, boolean never) { + if (never) { + ToastUtils.showShort(R.string.manually_enable_the_phone_state_permission_to_bind_hardware_devices); + } else { + ToastUtils.showShort(R.string.please_open_permission_to_activation); + requestPhoneStatePermission(context); + } + } + }); + } + }) + .show(); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/activity/user/UserInfoActivity.java b/app/src/main/java/com/bingce/controlnetwork/activity/user/UserInfoActivity.java new file mode 100644 index 0000000..050b787 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/activity/user/UserInfoActivity.java @@ -0,0 +1,781 @@ +package com.bingce.controlnetwork.activity.user; + +import android.Manifest; +import android.annotation.SuppressLint; +import android.app.ProgressDialog; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.graphics.Bitmap; +import android.graphics.Color; +import android.net.Uri; +import android.os.Bundle; +import android.text.Editable; +import android.text.TextWatcher; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.widget.Button; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.widget.Toolbar; +import androidx.core.app.ActivityCompat; +import androidx.core.content.ContextCompat; + +import com.afollestad.materialdialogs.DialogAction; +import com.afollestad.materialdialogs.MaterialDialog; +import com.afollestad.materialdialogs.internal.MDButton; +import com.bingce.AppChannel; +import com.bingce.controlapphelper.util.SettingValueUtil; +import com.bingce.controlnetwork.App; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.databinding.DialogEditNicknameBinding; +import com.bingce.controlnetwork.ui.WechatImagePicker; +import com.bingce.utils.DateUtils; +import com.bingce.utils.FileUtil; +import com.bingce.utils.LCDeviceUtil; +import com.bingce.utils.ServiceDateUtils; +import com.bingce.utils.ValidateUtil; +import com.bingce.utils.VipManager; +import com.bumptech.glide.Glide; +import com.leon.lib.settingview.LSettingItem; +import com.qingmei2.rximagepicker.core.RxImagePicker; +import com.qingmei2.rximagepicker.entity.Result; +import com.qingmei2.rximagepicker_extension.MimeType; +import com.qingmei2.rximagepicker_extension_wechat.WechatConfigrationBuilder; +import com.qingmei2.rximagepicker_extension_wechat.ui.WechatImagePickerFragment; +import com.yalantis.ucrop.UCrop; + +import org.jetbrains.annotations.NotNull; +import org.polaric.colorful.ColorfulActivity; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.Date; +import java.util.List; + +import blankj.utilcode.util.StringUtils; +import blankj.utilcode.util.ToastUtils; +import blankj.utilcode.util.Utils; +import cn.leancloud.LCFile; +import cn.leancloud.LCObject; +import cn.leancloud.LCQuery; +import cn.leancloud.LCUser; +import de.hdodenhof.circleimageview.CircleImageView; +import id.zelory.compressor.Compressor; +import io.reactivex.Observer; +import io.reactivex.disposables.Disposable; +import io.reactivex.functions.Consumer; + +public class UserInfoActivity extends ColorfulActivity { + private static final String TAG = "UserInfoActivity"; + private static final int REQUEST_CODE_ASK_CAMERA = 166; + private static final int REQUEST_CODE_UPDATE_USER_INFO = 11; + private Toolbar mToolbar; + private CircleImageView avatarImageView; + private TextView tv_nick_name; + private ImageView tv_nick_name_edit; + private MDButton mPositiveAction; + private LSettingItem item_phone, item_email, item_user_level, item_expiration, item_bound_device, item_control_level, item_control_expiration; + private WechatImagePicker rxImagePicker; + private Button btn_log_out, btn_opening_renewal; + private ProgressDialog progressDialog; + private boolean buy = false; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_user_info); + mToolbar = findViewById(R.id.toolbar); + setSupportActionBar(mToolbar); + if (getSupportActionBar() != null) + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + buy = getIntent().getBooleanExtra("buy", false); + + rxImagePicker = RxImagePicker.create(WechatImagePicker.class); + + avatarImageView = findViewById(R.id.activity_user_info_avatar_image); + tv_nick_name = findViewById(R.id.activity_user_info_nick_name); + tv_nick_name_edit = findViewById(R.id.activity_user_info_nick_name_edit); + item_phone = findViewById(R.id.activity_user_info_item_phone); + item_email = findViewById(R.id.activity_user_info_item_email); + item_user_level = findViewById(R.id.activity_user_info_item_user_level); + item_expiration = findViewById(R.id.activity_user_info_item_expiration_date); + item_bound_device = findViewById(R.id.activity_user_info_item_bound_device); + item_control_level = findViewById(R.id.activity_user_info_item_control_level); + item_control_expiration = findViewById(R.id.activity_user_info_item_control_expiration_date); + btn_opening_renewal = findViewById(R.id.activity_user_info_btn_opening_renewal); + btn_log_out = findViewById(R.id.activity_user_info_btn_log_out); + + updateUserInfo(); + + avatarImageView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + showProfileAvatarChangeDialog(); + } + }); + tv_nick_name.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + showEditNicknameDialog(); + } + }); + tv_nick_name_edit.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + showEditNicknameDialog(); + } + }); + item_phone.setOnSettingItemClick(new LSettingItem.onSettingItemClick() { + @Override + public void click(boolean isChecked) { + if (!LCUser.getCurrentUser().isMobilePhoneVerified()) { +// Intent intent = new Intent(Utils.getApp(), MobilePhoneVerifyActivity.class); +// startActivity(intent); + } + } + }); + btn_log_out.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + LCUser.logOut(); + ToastUtils.showShort(R.string.log_out); + VipManager.getInstance().controlSdkRefresh(UserInfoActivity.this, ((App) Utils.getApp()).registerCodeV2, null); + ((App) Utils.getApp()).isUserStatusChanged = true;//返回MainActivity时updateHeaderResult + finish(); + } + }); + btn_opening_renewal.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (AppChannel.customChannel != AppChannel.CUSTOM_CONTROL_PUBLIC) { + new AlertDialog.Builder(UserInfoActivity.this) + .setTitle(R.string.hint) + .setMessage("定制版本无法续费,只能以绑定手机形式使用") + .setPositiveButton(R.string.i_know, null) + .show(); + } else if (LCUser.getCurrentUser().getInt("level") == 0 || LCUser.getCurrentUser().getInt("level") == 1) { + startActivityForResult(new Intent(UserInfoActivity.this, OpeningRenewalVipActivity.class), REQUEST_CODE_UPDATE_USER_INFO); + } else { + ToastUtils.showShort("当前会员模式不支持续费,请联系开发者"); + } + } + }); + + item_bound_device.setOnSettingItemClick(new LSettingItem.onSettingItemClick() { + @Override + public void click(boolean isChecked) { + unbind(); + } + }); + + if (buy) { + btn_opening_renewal.performClick(); + } + } + + private void unbind() { + if (LCUser.getCurrentUser() != null) { + progressDialog = new ProgressDialog(UserInfoActivity.this); + progressDialog.setMessage(getString(R.string.please_wait)); + progressDialog.setCanceledOnTouchOutside(false); + progressDialog.show(); + + ServiceDateUtils.getServerDate(new DateUtils.OnServerDateCallBack() { + @Override + public void get(Date serverDate) { + if (isFinishing()) return; + //查询条件为:查询今年开始时间,查询开年来的解绑次数 + Date startOfAYear = DateUtils.addDayOfMonth(serverDate, -365, false, false); + + LCQuery unbindDeviceQuery = new LCQuery<>("UnbindDevice"); + unbindDeviceQuery.whereEqualTo("user", LCUser.getCurrentUser()); + unbindDeviceQuery.limit(15) + .whereGreaterThan("updatedAt", startOfAYear) + .findInBackground().subscribe(new Observer>() { + @Override + public void onSubscribe(Disposable d) { + + } + + @Override + public void onNext(List avObjects) { + progressDialog.dismiss(); + if (avObjects != null) { + int totalTimes = 0; + if (LCUser.getCurrentUser().getInt("level") == 1) { + totalTimes = 5; + } else if (LCUser.getCurrentUser().getInt("level") == 10) { + totalTimes = 10; + } + final int leftTimes = Math.max(totalTimes - avObjects.size(), 0); + new MaterialDialog.Builder(UserInfoActivity.this) + .title(R.string.unbind_device) + .content(getString(R.string.number_of_untying_opportunities_at_your_membership_level) + ":" + totalTimes + "\n" + + getString(R.string.your_remaining_untying_times_remain) + ":" + leftTimes) + .positiveText(R.string.unbind_device) + .onPositive(new MaterialDialog.SingleButtonCallback() { + @Override + public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) { + if (leftTimes > 0) { + progressDialog = new ProgressDialog(UserInfoActivity.this); + progressDialog.setMessage(getString(R.string.please_wait)); + progressDialog.setCanceledOnTouchOutside(false); + progressDialog.show(); + + LCObject unbindDevice = new LCObject("UnbindDevice"); + unbindDevice.put("user", LCUser.getCurrentUser()); + if (LCUser.getCurrentUser().get("controlBoundDevice") != null) + unbindDevice.put("oldDevice", LCUser.getCurrentUser().get("controlBoundDevice")); + unbindDevice.put("success", true); + unbindDevice.saveInBackground().subscribe(new Observer() { + @Override + public void onSubscribe(Disposable d) { + + } + + @Override + public void onNext(LCObject avObject) { + LCUser.getCurrentUser().remove("controlBoundDevice"); + LCUser.getCurrentUser().saveInBackground().subscribe(new Observer() { + @Override + public void onSubscribe(Disposable d) { + + } + + @Override + public void onNext(LCObject avObject) { + if (VipManager.getInstance().isControlBoundDevice) { + LCUser.logOut(); + VipManager.getInstance().controlSdkRefresh(UserInfoActivity.this, ((App) Utils.getApp()).registerCodeV2, new VipManager.OnSdkRefreshListener() { + @Override + public void onRefreshSuccess() { + progressDialog.dismiss(); + new MaterialDialog.Builder(UserInfoActivity.this) + .title(R.string.unbind_device_success) + .content(R.string.unbind_device_success_next_to_do) + .positiveText(R.string.i_know) + .dismissListener(new DialogInterface.OnDismissListener() { + @Override + public void onDismiss(DialogInterface dialog) { + ((App) Utils.getApp()).isUserStatusChanged = true;//返回MainActivity时updateHeaderResult + finish(); + } + }) + .show(); + } + + @Override + public void onRefreshFailed(int errorCode) { + progressDialog.dismiss(); + } + }); + } else { + LCDeviceUtil.updateDeviceInfo("controlnetwork", ((App) Utils.getApp()).registerCodeV2, new LCDeviceUtil.OnDeviceUpdateListener() { + @Override + public void onUpdateSuccess() { + VipManager.getInstance().controlSdkRefresh(UserInfoActivity.this, ((App) Utils.getApp()).registerCodeV2, new VipManager.OnSdkRefreshListener() { + @Override + public void onRefreshSuccess() { + progressDialog.dismiss(); + item_bound_device.setRightText(VipManager.getInstance().boundName); + ToastUtils.showShort(R.string.unbind_device_success); + } + + @Override + public void onRefreshFailed(int errorCode) { + progressDialog.dismiss(); + ToastUtils.showShort(getString(R.string.error_code) + ":" + errorCode); + } + }); + } + + @Override + public void onUpdateFailed() { + progressDialog.dismiss(); + } + }); + } + } + + @Override + public void onError(Throwable e) { + progressDialog.dismiss(); + } + + @Override + public void onComplete() { + + } + }); + + } + + @Override + public void onError(Throwable e) { + progressDialog.dismiss(); + } + + @Override + public void onComplete() { + + } + }); + } else { + ToastUtils.showLong(R.string.your_remaining_untying_times_remain_is_zero); + } + } + }) + .negativeText(R.string.cancel) + .show(); + } + } + + @Override + public void onError(Throwable e) { + progressDialog.dismiss(); + } + + @Override + public void onComplete() { + + } + }); + } + + @Override + public void error(Throwable throwable) { + progressDialog.dismiss(); + Log.d("error", "unbind_device"); + ToastUtils.showShort(R.string.get_server_date_failed); + } + }); + } else { + ToastUtils.showShort(R.string.you_are_not_vip_no_need_unbind); + } + } + + /** + * 刷新用户信息 + */ + private void updateUserInfo() { + if (LCUser.getCurrentUser() != null) { + if (LCUser.getCurrentUser().getMobilePhoneNumber() != null) + item_phone.setRightText(LCUser.getCurrentUser().getMobilePhoneNumber()); + if (LCUser.getCurrentUser().getEmail() != null) + item_email.setRightText(LCUser.getCurrentUser().getEmail()); + if (VipManager.getInstance().controlBoundName != null) + item_bound_device.setRightText(VipManager.getInstance().controlBoundName); + + fetchNickNameAndAvatar(); + + if (VipManager.getInstance().checkReg()) { + item_user_level.setRightText(getString(R.string.bound_device)); + item_expiration.setVisibility(View.GONE); + } else if (VipManager.getInstance().level > 0) { + item_expiration.setVisibility(View.VISIBLE); + if (VipManager.getInstance().expireDate != null) + item_expiration.setRightText(DateUtils.toFull(VipManager.getInstance().expireDate)); + if (VipManager.getInstance().isInExpireDate) { + switch (VipManager.getInstance().level) { + case 1: + item_user_level.setRightText(getString(R.string.user_level_1)); + break; + case 10: + item_user_level.setRightText(getString(R.string.surveyor_life_vip)); + break; + default: + item_user_level.setRightText(getString(R.string.user_level_unknown)); + } + } else { + item_user_level.setRightText(getString(R.string.vip_expired)); + } + } else { + item_user_level.setRightText(getString(R.string.user_level_0)); + item_expiration.setVisibility(View.GONE); + } + if (VipManager.getInstance().controlLevel > 0) { + item_control_level.setVisibility(View.VISIBLE); + item_control_expiration.setVisibility(View.VISIBLE); + item_control_expiration.setRightText(DateUtils.toFull(VipManager.getInstance().controlExpireDate)); + if (VipManager.getInstance().isControlInExpireDate) { + switch (VipManager.getInstance().controlLevel) { + case 1: + case 2: + item_control_level.setRightText(getString(R.string.user_level_try)); + break; + case 3: + item_control_level.setRightText(getString(R.string.user_level_control_pro)); + break; + } + } else { + item_control_level.setRightText(getString(R.string.vip_expired)); + } + } + } else { + ToastUtils.showShort(R.string.not_log_in); + } + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.menu_activity_user_info, menu); + return super.onCreateOptionsMenu(menu); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + finish(); + break; + case R.id.menu_activity_user_info_redeem_code: + if (AppChannel.customChannel != AppChannel.CUSTOM_CONTROL_PUBLIC) { + new AlertDialog.Builder(UserInfoActivity.this) + .setTitle(R.string.hint) + .setMessage("定制版本无法续费,只能以绑定手机形式使用") + .setPositiveButton(R.string.i_know, null) + .show(); + } else if (LCUser.getCurrentUser().getInt("level") == 0 || LCUser.getCurrentUser().getInt("level") == 1) { + startActivityForResult(new Intent(UserInfoActivity.this, RedeemVipActivity.class), REQUEST_CODE_UPDATE_USER_INFO); + } else { + ToastUtils.showShort("当前会员模式不支持续费,请联系开发者"); + } + break; + } + return super.onOptionsItemSelected(item); + } + + @Override + public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { + if (grantResults.length > 0) { + if (requestCode == REQUEST_CODE_ASK_CAMERA) { + if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { + pickByTake(); + } else { + ToastUtils.showShort(getString(R.string.please_granted_camera_permission)); + } + } else { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + } + } + } + + public void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + switch (requestCode) { + case REQUEST_CODE_UPDATE_USER_INFO: + VipManager.getInstance().controlSdkRefresh(UserInfoActivity.this, ((App) Utils.getApp()).registerCodeV2, new VipManager.OnSdkRefreshListener() { + @Override + public void onRefreshSuccess() { + updateUserInfo(); + } + + @Override + public void onRefreshFailed(int errorCode) { + ToastUtils.showShort(getString(R.string.error_code) + ":" + errorCode); + } + }); + break; + case UCrop.REQUEST_CROP: + final Uri resultUri = UCrop.getOutput(data); + try { + File compressedImage = new Compressor(UserInfoActivity.this) + .setMaxWidth(256) + .setMaxHeight(256) + .setQuality(50) + .setCompressFormat(Bitmap.CompressFormat.JPEG) + .compressToFile(new File(FileUtil.getRealPathFromUri(resultUri))); + + updateProfileAvatar(compressedImage.getAbsolutePath()); + } catch (IOException e) { + e.printStackTrace(); + } + break; + case UCrop.RESULT_ERROR: + final Throwable cropError = UCrop.getError(data); + if (cropError != null) + Log.d("cropError", cropError.getMessage()); + break; + } + } + } + + /** + * 编辑昵称 + */ + public void showEditNicknameDialog() { + if (LCUser.getCurrentUser() == null) { + ToastUtils.showShort(R.string.not_log_in); + return; + } + DialogEditNicknameBinding dialogEditNicknameBinding = DialogEditNicknameBinding.inflate(LayoutInflater.from(this)); + MaterialDialog dialog = new MaterialDialog.Builder(this) + .title(R.string.edit_nickname) + .customView(dialogEditNicknameBinding.getRoot(), false) + .onPositive((dialog1, which) -> { + final String nickname = dialogEditNicknameBinding.metDialogEditNickname.getText().toString(); + LCUser.getCurrentUser().put("nickname", nickname); + LCUser.getCurrentUser().saveInBackground().subscribe(); + ToastUtils.showShort(R.string.edit_nickname_success); + tv_nick_name.setText(nickname); + ((App) Utils.getApp()).isUserStatusChanged = true;//返回MainActivity时updateHeaderResult + }) + .positiveText(getString(R.string.save)) + .negativeText(getString(R.string.cancel)) + .dismissListener(dialog12 -> + dialogEditNicknameBinding.metDialogEditNickname.clearFocus()) + .build(); + mPositiveAction = dialog.getActionButton(DialogAction.POSITIVE); + + if (SettingValueUtil.isThemeDark()) { + dialogEditNicknameBinding.metDialogEditNickname.setMetTextColor(Color.WHITE); + dialogEditNicknameBinding.metDialogEditNickname.setPrimaryColor(Color.LTGRAY); + dialogEditNicknameBinding.metDialogEditNickname.setFocusFraction(1.0f); + dialogEditNicknameBinding.metDialogEditNickname.setMetHintTextColor(Color.GRAY); + dialogEditNicknameBinding.metDialogEditNickname.setUnderlineColor(Color.GRAY); + } + + TextWatcher watcher = new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + } + + @Override + public void afterTextChanged(Editable s) { + String nickname_text = s == null ? "" : s.toString(); + mPositiveAction.setEnabled(ValidateUtil.isNickName(nickname_text)); + } + }; + + dialogEditNicknameBinding.metDialogEditNickname.addTextChangedListener(watcher); + + dialog.show(); + mPositiveAction.setEnabled(false); + } + + /** + * 编辑头像 + */ + private void showProfileAvatarChangeDialog() { + new MaterialDialog.Builder(this) + .title(R.string.change_profile_avatar) + .positiveText(R.string.pick_by_select) + .negativeText(R.string.pick_by_take) + .neutralText(R.string.cancel) + .onPositive(new MaterialDialog.SingleButtonCallback() { + @Override + public void onClick(@NonNull @NotNull MaterialDialog dialog, @NonNull @NotNull DialogAction which) { + pickBySelect(); + } + }) + .onNegative(new MaterialDialog.SingleButtonCallback() { + @Override + public void onClick(@NonNull @NotNull MaterialDialog dialog, @NonNull @NotNull DialogAction which) { + pickByTake(); + } + }) + .show(); + } + + /** + * 相册选择照片 + */ + @SuppressLint("CheckResult") + public void pickBySelect() { + rxImagePicker.openGallery(this, new WechatConfigrationBuilder(MimeType.INSTANCE.ofImage(), false) + .capture(true) + .maxSelectable(1) + .countable(true) + .spanCount(4) + .countable(false) + .build()) + .subscribe(rxImagePickerConsumerOnNext, rxImagePickerConsumerOnError); + } + + /** + * 拍照片 + */ + @SuppressLint("CheckResult") + public void pickByTake() { + if ((PackageManager.PERMISSION_GRANTED != ContextCompat.checkSelfPermission(Utils.getApp(), Manifest.permission.CAMERA))) { + ActivityCompat.requestPermissions(UserInfoActivity.this, new String[]{Manifest.permission.CAMERA}, REQUEST_CODE_ASK_CAMERA); + } else { + rxImagePicker.openCamera(this).subscribe(rxImagePickerConsumerOnNext, rxImagePickerConsumerOnError); + } + } + + Consumer rxImagePickerConsumerOnNext = new Consumer() { + @Override + public void accept(Result result) throws Exception { + boolean originalMode = result.getBooleanExtra(WechatImagePickerFragment.EXTRA_ORIGINAL_IMAGE, false); +// String mimeType = result.getStringExtra(WechatImagePickerFragment.EXTRA_OPTIONAL_MIME_TYPE, ""); + Log.d(TAG, "select image original:" + originalMode + " , uri path: " + FileUtil.getRealPathFromUri(result.getUri())); + UCrop.of(result.getUri(), result.getUri()) + .withAspectRatio(1, 1) + .withMaxResultSize(256, 256) + .start(UserInfoActivity.this); + } + }; + + Consumer rxImagePickerConsumerOnError = new Consumer() { + @Override + public void accept(Throwable throwable) { + ToastUtils.showShort("打开图片失败"); + } + }; + + /** + * 更新云端头像 + * + * @param path + */ + private void updateProfileAvatar(String path) { + try { + final LCFile file = LCFile.withAbsoluteLocalPath("avatar.jpg", path); + if (LCUser.getCurrentUser() != null) { + LCUser.getCurrentUser().put("avatar", file); + LCUser.getCurrentUser().saveInBackground().subscribe(new Observer() { + @Override + public void onSubscribe(Disposable d) { + + } + + @Override + public void onNext(LCObject lcObject) { + Glide.with(UserInfoActivity.this).load(file.getUrl()).into(avatarImageView); + ToastUtils.showShort(R.string.update_avatar_success); + ((App) Utils.getApp()).isUserStatusChanged = true;//返回MainActivity时updateHeaderResult + } + + @Override + public void onError(Throwable e) { + + } + + @Override + public void onComplete() { + + } + }); + } else { + ToastUtils.showShort(R.string.not_log_in); + } + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + } + + private void fetchNickNameAndAvatar() { + if (LCUser.getCurrentUser() != null) { + String nickname = LCUser.getCurrentUser().getString("nickname"); + LCFile avatarFile = LCUser.getCurrentUser().getLCFile("avatar"); + if (!StringUtils.isEmpty(nickname)) { + tv_nick_name.setText(nickname); + if (avatarFile == null) { + avatarImageView.setImageResource(R.mipmap.profile_image); + } else { + Glide.with(UserInfoActivity.this).load(avatarFile.getUrl()).into(avatarImageView); + } + } else { + LCObject userProfile = LCUser.getCurrentUser().getLCObject("profile"); + if (userProfile != null) { + userProfile.fetchInBackground().subscribe(new Observer() { + @Override + public void onSubscribe(Disposable d) { + + } + + @Override + public void onNext(LCObject avObject) { + if (isFinishing()) return; + String nickname = avObject.getString("nickname"); + LCFile avatarFile = avObject.getLCFile("avatar"); + if (!StringUtils.isEmpty(nickname)) { + tv_nick_name.setText(nickname); + if (avatarFile == null) { + avatarImageView.setImageResource(R.mipmap.profile_image); + } else { + Glide.with(UserInfoActivity.this).load(avatarFile.getUrl()).into(avatarImageView); + } + //保存到_User,下次不再查Profile + LCUser.getCurrentUser().put("nickname", nickname); + if (avatarFile != null) + LCUser.getCurrentUser().put("avatar", avatarFile); + LCUser.getCurrentUser().saveInBackground().subscribe(); + } + } + + @Override + public void onError(Throwable e) { + } + + @Override + public void onComplete() { + + } + }); + } else { + new LCQuery<>("Profile") + .whereEqualTo("creatorId", LCUser.getCurrentUser().getObjectId()) + .findInBackground() + .subscribe(new Observer>() { + @Override + public void onSubscribe(Disposable d) { + + } + + @Override + public void onNext(List list) { + if (isFinishing()) return; + if (list != null && !list.isEmpty()) { + String nickname = list.get(0).getString("nickname"); + LCFile avatarFile = list.get(0).getLCFile("avatar"); + if (!StringUtils.isEmpty(nickname)) { + tv_nick_name.setText(nickname); + if (avatarFile == null) { + avatarImageView.setImageResource(R.mipmap.profile_image); + } else { + Glide.with(UserInfoActivity.this).load(avatarFile.getUrl()).into(avatarImageView); + } + + //保存到_User,下次不再查Profile + LCUser.getCurrentUser().put("nickname", nickname); + if (avatarFile != null) + LCUser.getCurrentUser().put("avatar", avatarFile); + LCUser.getCurrentUser().saveInBackground().subscribe(); + } + } + } + + @Override + public void onError(Throwable e) { + + } + + @Override + public void onComplete() { + + } + }); + } + } + } else { + tv_nick_name.setText(getString(R.string.please_log_in_again)); + } + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/activity/user/VerifyEmailCodeActivity.java b/app/src/main/java/com/bingce/controlnetwork/activity/user/VerifyEmailCodeActivity.java new file mode 100644 index 0000000..cb42cf1 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/activity/user/VerifyEmailCodeActivity.java @@ -0,0 +1,234 @@ +package com.bingce.controlnetwork.activity.user; + +import android.app.ProgressDialog; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.text.SpannableString; +import android.text.Spanned; +import android.text.style.TextAppearanceSpan; +import android.view.View; + +import androidx.activity.result.ActivityResultLauncher; +import androidx.annotation.Nullable; +import androidx.appcompat.widget.Toolbar; + +import com.bingce.AppChannel; +import com.bingce.activity.UserCloudFunction; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.databinding.ActivityVerifyCodeBinding; +import com.bingce.utils.ActivityUtils; +import com.bingce.utils.IntentUtil; +import com.bingce.utils.SendCodeCountDownManager; + +import org.polaric.colorful.ColorfulActivity; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import blankj.utilcode.util.ToastUtils; + +public class VerifyEmailCodeActivity extends ColorfulActivity { + + public static final String KEY_EMAIL = "email"; + public static final String KEY_TODO = "todo"; + private static ActivityResultLauncher mLauncher; + + public static final int TO_VERIFY_EMAIL = 0; + public static final int TO_SIGNUP_OR_LOGIN_BY_EMAIL = 1; + + private ActivityVerifyCodeBinding binding; + private ProgressDialog progressDialog; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + binding = ActivityVerifyCodeBinding.inflate(getLayoutInflater()); + setContentView(binding.getRoot()); + + Toolbar mToolbar = findViewById(R.id.toolbar); + setSupportActionBar(mToolbar); + if (getSupportActionBar() != null) getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + getSupportActionBar().setTitle(R.string.verify); + + binding.tvInputHintTitle.setText(R.string.enter_email_verification_code); + + String trip = String.format(getString(R.string.format_enter_verification_code), getEmail()); + binding.tvInputTrip.setText(matcherChangeText(trip, getEmail()));//+前需要转义 + + SendCodeCountDownManager.getInstance().start(this, 60000, 1000, binding.tvSendAuthCode, new SendCodeCountDownManager.OnCountDownListener() { + @Override + public void onSendValid() { + sendCode(); + } + + @Override + public void onSendInvalid() { + + } + }); + binding.tvSendAuthCode.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + SendCodeCountDownManager.getInstance().start(VerifyEmailCodeActivity.this, 60000, 1000, binding.tvSendAuthCode, new SendCodeCountDownManager.OnCountDownListener() { + @Override + public void onSendValid() { + sendCode(); + } + + @Override + public void onSendInvalid() { + + } + }); + } + }); + + binding.etInputAuthCode.setOnInputListener(code -> { + verifyCode(code); + }); + } + + private void sendCode() { + if (getEmail() == null) { + ToastUtils.showShort(R.string.email_address_illegal); + return; + } + UserCloudFunction.sendEmailCode(getEmail(), new UserCloudFunction.OnSendCodeListener() { + @Override + public void onCodeSendSuccess() { + if (progressDialog != null) + progressDialog.dismiss(); + ToastUtils.showShort(R.string.send_success); + } + + @Override + public void onCodeSendFailed(String errorMsg) { + if (progressDialog != null) + progressDialog.dismiss(); + ToastUtils.showLong(errorMsg); + } + }); + } + + private void verifyCode(String code) { + if (progressDialog != null) + progressDialog.dismiss(); + progressDialog = new ProgressDialog(VerifyEmailCodeActivity.this); + progressDialog.setMessage(getString(R.string.logging)); + progressDialog.setCanceledOnTouchOutside(false); + progressDialog.show(); + switch (getToDo()) { + case TO_VERIFY_EMAIL: + if (getEmail() == null) { + ToastUtils.showShort(R.string.email_address_illegal); + if (progressDialog != null) + progressDialog.dismiss(); + return; + } + UserCloudFunction.verifyEmailCode(getEmail(), code, new UserCloudFunction.OnVerifyCodeListener() { + @Override + public void onCodeVerifySuccess() { + if (!ActivityUtils.isLiving(VerifyEmailCodeActivity.this)) return; + if (progressDialog != null) + progressDialog.dismiss(); + + SendCodeCountDownManager.getInstance().resetRemainingTime();//验证成功,重置倒计时,否则跳转到下一个验证页面不会自动发送验证码 + + Intent intent = new Intent(); + intent.putExtra("isMail", true); + intent.putExtra("phoneNumberOrEmail", getEmail()); + setResult(RESULT_OK, intent); + finish(); + } + + @Override + public void onCodeVerifyFailed(String errorMsg) { + if (!ActivityUtils.isLiving(VerifyEmailCodeActivity.this)) return; + if (progressDialog != null) + progressDialog.dismiss(); + ToastUtils.showLong(errorMsg); + } + }); + break; + case TO_SIGNUP_OR_LOGIN_BY_EMAIL: + if (getEmail() == null) { + ToastUtils.showShort(R.string.email_address_illegal); + if (progressDialog != null) + progressDialog.dismiss(); + return; + } + UserCloudFunction.signUpOrLoginByEmail(getEmail(), code, AppChannel.customChannel, + new UserCloudFunction.OnGetSessionTokenListener() { + @Override + public void onSessionTokenGetSuccess(String sessionToken, boolean newUser) { + if (!ActivityUtils.isLiving(VerifyEmailCodeActivity.this)) return; + if (progressDialog != null) + progressDialog.dismiss(); + + SendCodeCountDownManager.getInstance().resetRemainingTime();//验证成功,重置倒计时,否则跳转到下一个验证页面不会自动发送验证码 + + Intent intent = new Intent(); + intent.putExtra("sessionToken", sessionToken); + intent.putExtra("newUser", newUser); + setResult(RESULT_OK, intent); + finish(); + } + + @Override + public void onSessionTokenGetFailed(int code, String msg, String resp) { + if (!ActivityUtils.isLiving(VerifyEmailCodeActivity.this)) return; + if (progressDialog != null) + progressDialog.dismiss(); + + if (code == 303) {//缺少手机号或未验证 + SendCodeCountDownManager.getInstance().resetRemainingTime(); + InputPhoneNumberActivity.start(VerifyEmailCodeActivity.this, null, getEmail(), null, VerifySMSCodeActivity.TO_SIGNUP_OR_LOGIN_BY_EMAIL_BIND_PHONE, mLauncher); + finish(); + } else { + ToastUtils.showLong(msg); + } + } + + @Override + public void onSessionTokenGetException(String msg) { + if (!ActivityUtils.isLiving(VerifyEmailCodeActivity.this)) return; + if (progressDialog != null) + progressDialog.dismiss(); + ToastUtils.showLong(msg); + } + }); + break; + } + } + + + private String getEmail() { + return IntentUtil.stringExtra(getIntent(), KEY_EMAIL); + } + + private int getToDo() { + return IntentUtil.intExtra(getIntent(), KEY_TODO); + } + + public static void start(Context context, String email, int todo, ActivityResultLauncher launcher) { + Intent intent = new Intent(context, VerifyEmailCodeActivity.class); + intent.putExtra(KEY_EMAIL, email); + intent.putExtra(KEY_TODO, todo); + mLauncher = launcher; + launcher.launch(intent); + } + + private SpannableString matcherChangeText(String str, String keyword) { + SpannableString ss = new SpannableString(str); + Pattern pattern = Pattern.compile(keyword); + Matcher matcher = pattern.matcher(ss); + while (matcher.find()) { + int start = matcher.start(); + int end = matcher.end(); + ss.setSpan(new TextAppearanceSpan(this, R.style.style_color_black), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);//new ForegroundColorSpan(color) + } + return ss; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/activity/user/VerifySMSCodeActivity.java b/app/src/main/java/com/bingce/controlnetwork/activity/user/VerifySMSCodeActivity.java new file mode 100644 index 0000000..e05ca85 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/activity/user/VerifySMSCodeActivity.java @@ -0,0 +1,329 @@ +package com.bingce.controlnetwork.activity.user; + +import android.app.ProgressDialog; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.text.SpannableString; +import android.text.Spanned; +import android.text.style.TextAppearanceSpan; +import android.view.View; + +import androidx.activity.result.ActivityResultLauncher; +import androidx.annotation.Nullable; +import androidx.appcompat.widget.Toolbar; + +import com.bingce.AppChannel; +import com.bingce.activity.UserCloudFunction; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.databinding.ActivityVerifyCodeBinding; +import com.bingce.utils.ActivityUtils; +import com.bingce.utils.IntentUtil; +import com.bingce.utils.SendCodeCountDownManager; + +import org.polaric.colorful.ColorfulActivity; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import blankj.utilcode.util.ToastUtils; + +public class VerifySMSCodeActivity extends ColorfulActivity { + public static final String KEY_PHONE = "phone_number"; + public static final String KEY_EMAIL = "email"; + public static final String KEY_UNION_ID = "unionid"; + public static final String KEY_TODO = "todo"; + + public static final int TO_VERIFY_PHONE_NUMBER = 0; + public static final int TO_SIGNUP_OR_LOGIN_BY_PHONE_NUMBER = 1; + public static final int TO_SIGNUP_OR_LOGIN_BY_EMAIL_BIND_PHONE = 2; + public static final int TO_SIGNUP_OR_LOGIN_BY_WEIXIN_BIND_PHONE = 3; + private ActivityVerifyCodeBinding binding; + private ProgressDialog progressDialog; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + binding = ActivityVerifyCodeBinding.inflate(getLayoutInflater()); + setContentView(binding.getRoot()); + + Toolbar mToolbar = findViewById(R.id.toolbar); + setSupportActionBar(mToolbar); + if (getSupportActionBar() != null) getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + getSupportActionBar().setTitle(R.string.verify); + + binding.tvInputHintTitle.setText(R.string.enter_sms_verification_code); + + String phoneOrEmail = getPhoneNumber(); + String trip = String.format(getString(R.string.format_enter_verification_code), phoneOrEmail); + binding.tvInputTrip.setText(matcherChangeText(trip, phoneOrEmail.startsWith("+") ? ("\\" + phoneOrEmail) : phoneOrEmail));//+前需要转义 + + SendCodeCountDownManager.getInstance().start(this, 60000, 1000, binding.tvSendAuthCode, new SendCodeCountDownManager.OnCountDownListener() { + @Override + public void onSendValid() { + sendCode(); + } + + @Override + public void onSendInvalid() { + + } + }); + binding.tvSendAuthCode.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + SendCodeCountDownManager.getInstance().start(VerifySMSCodeActivity.this, 60000, 1000, binding.tvSendAuthCode, new SendCodeCountDownManager.OnCountDownListener() { + @Override + public void onSendValid() { + sendCode(); + } + + @Override + public void onSendInvalid() { + + } + }); + } + }); + + binding.etInputAuthCode.setOnInputListener(code -> { + verifyCode(code); + }); + } + + private void sendCode() { + if (getPhoneNumber() == null) { + ToastUtils.showShort(R.string.phone_number_invalid); + return; + } + UserCloudFunction.sendSMSCode(getPhoneNumber(), new UserCloudFunction.OnSendCodeListener() { + @Override + public void onCodeSendSuccess() { + ToastUtils.showShort(R.string.send_success); + } + + @Override + public void onCodeSendFailed(String errorMsg) { + ToastUtils.showLong(errorMsg); + } + }); + } + + private void verifyCode(String code) { + if (progressDialog != null) + progressDialog.dismiss(); + progressDialog = new ProgressDialog(VerifySMSCodeActivity.this); + progressDialog.setMessage(getString(R.string.logging)); + progressDialog.setCanceledOnTouchOutside(false); + progressDialog.show(); + + switch (getTodo()) { + case TO_VERIFY_PHONE_NUMBER: + if (getPhoneNumber() == null) { + ToastUtils.showShort(R.string.phone_number_invalid); + if (progressDialog != null) + progressDialog.dismiss(); + return; + } + UserCloudFunction.verifySMSCode(getPhoneNumber(), code, new UserCloudFunction.OnVerifyCodeListener() { + @Override + public void onCodeVerifySuccess() { + if (progressDialog != null) + progressDialog.dismiss(); + + SendCodeCountDownManager.getInstance().resetRemainingTime();//验证成功,重置倒计时,否则跳转到下一个验证页面不会自动发送验证码 + + Intent intent = new Intent(); + intent.putExtra("isMail", false); + intent.putExtra("phoneNumberOrEmail", getPhoneNumber()); + setResult(RESULT_OK, intent); + finish(); + } + + @Override + public void onCodeVerifyFailed(String errorMsg) { + if (!ActivityUtils.isLiving(VerifySMSCodeActivity.this)) return; + if (progressDialog != null) + progressDialog.dismiss(); + ToastUtils.showLong(errorMsg); + } + }); + break; + case TO_SIGNUP_OR_LOGIN_BY_PHONE_NUMBER: + if (getPhoneNumber() == null) { + ToastUtils.showShort(R.string.phone_number_invalid); + if (progressDialog != null) + progressDialog.dismiss(); + return; + } + UserCloudFunction.signUpOrLoginByMobilePhone(getPhoneNumber(), code, AppChannel.customChannel, + new UserCloudFunction.OnGetSessionTokenListener() { + @Override + public void onSessionTokenGetSuccess(String sessionToken, boolean newUser) { + if (!ActivityUtils.isLiving(VerifySMSCodeActivity.this)) return; + if (progressDialog != null) + progressDialog.dismiss(); + + SendCodeCountDownManager.getInstance().resetRemainingTime();//验证成功,重置倒计时,否则跳转到下一个验证页面不会自动发送验证码 + + Intent intent = new Intent(); + intent.putExtra("sessionToken", sessionToken); + intent.putExtra("newUser", newUser); + setResult(RESULT_OK, intent); + finish(); + } + + @Override + public void onSessionTokenGetFailed(int code, String msg, String resp) { + if (!ActivityUtils.isLiving(VerifySMSCodeActivity.this)) return; + if (progressDialog != null) + progressDialog.dismiss(); + ToastUtils.showLong(msg); + } + + @Override + public void onSessionTokenGetException(String msg) { + if (!ActivityUtils.isLiving(VerifySMSCodeActivity.this)) return; + if (progressDialog != null) + progressDialog.dismiss(); + ToastUtils.showLong(msg); + } + }); + break; + case TO_SIGNUP_OR_LOGIN_BY_EMAIL_BIND_PHONE: + if (getEmail() == null) { + ToastUtils.showShort(R.string.email_address_illegal); + if (progressDialog != null) + progressDialog.dismiss(); + return; + } + if (getPhoneNumber() == null) { + ToastUtils.showShort(R.string.phone_number_invalid); + if (progressDialog != null) + progressDialog.dismiss(); + return; + } + UserCloudFunction.loginByEmailBindPhone(getEmail(), getPhoneNumber(), code, AppChannel.customChannel, + new UserCloudFunction.OnGetSessionTokenListener() { + @Override + public void onSessionTokenGetSuccess(String sessionToken, boolean newUser) { + if (!ActivityUtils.isLiving(VerifySMSCodeActivity.this)) return; + if (progressDialog != null) + progressDialog.dismiss(); + + SendCodeCountDownManager.getInstance().resetRemainingTime();//验证成功,重置倒计时,否则跳转到下一个验证页面不会自动发送验证码 + + Intent intent = new Intent(); + intent.putExtra("sessionToken", sessionToken); + intent.putExtra("newUser", newUser); + setResult(RESULT_OK, intent); + finish(); + } + + @Override + public void onSessionTokenGetFailed(int code, String msg, String resp) { + if (!ActivityUtils.isLiving(VerifySMSCodeActivity.this)) return; + if (progressDialog != null) + progressDialog.dismiss(); + ToastUtils.showLong(msg); + } + + @Override + public void onSessionTokenGetException(String msg) { + if (!ActivityUtils.isLiving(VerifySMSCodeActivity.this)) return; + if (progressDialog != null) + progressDialog.dismiss(); + ToastUtils.showLong(msg); + } + }); + break; + case TO_SIGNUP_OR_LOGIN_BY_WEIXIN_BIND_PHONE: + if (getUnionId() == null) { + ToastUtils.showShort(R.string.wechat_unionid_invalid); + if (progressDialog != null) + progressDialog.dismiss(); + return; + } + if (getPhoneNumber() == null) { + ToastUtils.showShort(R.string.phone_number_invalid); + if (progressDialog != null) + progressDialog.dismiss(); + return; + } + UserCloudFunction.loginByWxUnionIdBindPhone(getUnionId(), getPhoneNumber(), AppChannel.customChannel, + new UserCloudFunction.OnGetSessionTokenListener() { + @Override + public void onSessionTokenGetSuccess(String sessionToken, boolean newUser) { + if (!ActivityUtils.isLiving(VerifySMSCodeActivity.this)) return; + if (progressDialog != null) + progressDialog.dismiss(); + + SendCodeCountDownManager.getInstance().resetRemainingTime();//验证成功,重置倒计时,否则跳转到下一个验证页面不会自动发送验证码 + + Intent intent = new Intent(); + intent.putExtra("sessionToken", sessionToken); + intent.putExtra("newUser", newUser); + setResult(RESULT_OK, intent); + finish(); + } + + @Override + public void onSessionTokenGetFailed(int code, String msg, String resp) { + if (!ActivityUtils.isLiving(VerifySMSCodeActivity.this)) return; + if (progressDialog != null) + progressDialog.dismiss(); + ToastUtils.showLong(msg); + } + + @Override + public void onSessionTokenGetException(String msg) { + if (!ActivityUtils.isLiving(VerifySMSCodeActivity.this)) return; + if (progressDialog != null) + progressDialog.dismiss(); + ToastUtils.showLong(msg); + } + }); + break; + } + + } + + private String getPhoneNumber() { + return IntentUtil.stringExtra(getIntent(), KEY_PHONE); + } + + private String getEmail() { + return IntentUtil.stringExtra(getIntent(), KEY_EMAIL); + } + + private String getUnionId() { + return IntentUtil.stringExtra(getIntent(), KEY_UNION_ID); + } + + + private int getTodo() { + return IntentUtil.intExtra(getIntent(), KEY_TODO); + } + + public static void start(Context context, String phoneNumber, String email, String unionid, int todo, ActivityResultLauncher launcher) { + Intent intent = new Intent(context, VerifySMSCodeActivity.class); + intent.putExtra(KEY_PHONE, phoneNumber); + intent.putExtra(KEY_EMAIL, email); + intent.putExtra(KEY_UNION_ID, unionid); + intent.putExtra(KEY_TODO, todo); + launcher.launch(intent); + } + + private SpannableString matcherChangeText(String str, String keyword) { + SpannableString ss = new SpannableString(str); + Pattern pattern = Pattern.compile(keyword); + Matcher matcher = pattern.matcher(ss); + while (matcher.find()) { + int start = matcher.start(); + int end = matcher.end(); + ss.setSpan(new TextAppearanceSpan(this, R.style.style_color_black), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);//new ForegroundColorSpan(color) + } + return ss; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/AbstractPointSelectAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/AbstractPointSelectAdapter.java new file mode 100644 index 0000000..cdd0d1e --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/AbstractPointSelectAdapter.java @@ -0,0 +1,176 @@ +package com.bingce.controlnetwork.adapter; + +import android.content.Context; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseExpandableListAdapter; + +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.datasource.database.point.PointRecord; +import com.bingce.controlapphelper.model.PickPointResult; +import com.bingce.controlapphelper.model.ViewItemType; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.ui.vh.GroupParentViewHolder; +import com.bingce.controlnetwork.ui.vh.TextSelectableViewHolder; +import com.bingce.controlnetwork.ui.widget.ViewFactory; + +import java.util.ArrayList; +import java.util.List; + +import blankj.utilcode.util.ToastUtils; + +/* + * 限差详情adapter + * */ +public abstract class AbstractPointSelectAdapter extends BaseExpandableListAdapter { + private final ArrayList selectedId = new ArrayList<>(); + private final ArrayList selectedName = new ArrayList<>(); + private final int maxCount; + private final Context context; + + public AbstractPointSelectAdapter(PickPointResult defaultValue, + int maxCount, + Context context) { + this.maxCount = maxCount; + if (defaultValue != null) { + List ids = defaultValue.getSelectedIds(); + if (ids != null) { + selectedId.addAll(ids); + } + + List names = defaultValue.getSelectedNames(); + if (names != null) { + selectedName.addAll(names); + } + } + this.context = context; + } + + protected Context context() { + return context; + } + + public ArrayList getSelectedId() { + return selectedId; + } + + public ArrayList getSelectedName() { + return selectedName; + } + + public abstract int getGroupCount(); + + public abstract int getChildrenCount(int groupPosition); + + public abstract String getGroup(int groupPosition); + + public abstract PointRecord getChild(int groupPosition, int childPosition); + + @Override + final public long getGroupId(int groupPosition) { + return groupPosition; + } + + @Override + final public long getChildId(int groupPosition, int childPosition) { + return groupPosition * 10000L + childPosition; + } + + @Override + public boolean hasStableIds() { + return true; + } + + protected boolean showGroupArrow() { + return true; + } + + @Override + public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { + GroupParentViewHolder viewHolder = null; + if (convertView == null) { + convertView = ViewFactory.generatorView(parent.getContext(), parent, ViewItemType.groupParent); + viewHolder = new GroupParentViewHolder(convertView); + convertView.setTag(viewHolder); + } else { + viewHolder = (GroupParentViewHolder) convertView.getTag(); + } + if (viewHolder != null) { + String groupName = getGroup(groupPosition); + if (viewHolder.name != null) { + viewHolder.name.setText(groupName); + } + if (viewHolder.expandIcon != null) { + if (showGroupArrow()) { + viewHolder.expandIcon.setImageResource(isExpanded ? R.drawable.ic_arrow_up : R.drawable.ic_arrow_down); + viewHolder.expandIcon.setVisibility(View.VISIBLE); + } else { + viewHolder.expandIcon.setVisibility(View.GONE); + } + } + } + return convertView; + } + + @Override + public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) { + PointRecord record = getChild(groupPosition, childPosition); + RecyclerView.ViewHolder viewHolder = null; + if (convertView == null) { + viewHolder = ViewFactory.generatorViewHolder(parent.getContext(), parent, ViewItemType.textSelectable); + if (viewHolder == null) { + return null; + } + convertView = viewHolder.itemView; + convertView.setTag(viewHolder); + } else { + viewHolder = (RecyclerView.ViewHolder) convertView.getTag(); + } + //更新item内容 + if (viewHolder instanceof TextSelectableViewHolder) { + TextSelectableViewHolder titleWithSubtitleViewHolder = (TextSelectableViewHolder) viewHolder; + titleWithSubtitleViewHolder.name.setText(record.getName()); + if (selectedId.contains(record.getId())) { + titleWithSubtitleViewHolder.status.setVisibility(View.VISIBLE); + } else { + titleWithSubtitleViewHolder.status.setVisibility(View.GONE); + } + } + convertView.setOnClickListener(v -> { + if (!selectedId.contains(record.getId())) { +// if (singlePick) { +// selectedId.clear(); +// selectedName.clear(); +// } +// selectedId.add(record.getId()); +// selectedName.add(record.getName()); + if (maxCount == 1) { + selectedId.clear(); + selectedName.clear(); + selectedId.add(record.getId()); + selectedName.add(record.getName()); + } else if (maxCount < 0) { + selectedId.add(record.getId()); + selectedName.add(record.getName()); + } else if (selectedId.size() >= maxCount) { + ToastUtils.showShort(Tools.getString(R.string.max_select_hint, maxCount)); + } else { + selectedId.add(record.getId()); + selectedName.add(record.getName()); + } + } else { + selectedId.remove(record.getId()); + selectedName.remove(record.getName()); + } + notifyDataSetChanged(); + }); + return convertView; + } + + @Override + public boolean isChildSelectable(int groupPosition, int childPosition) { + return true; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/BaseAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/BaseAdapter.java new file mode 100644 index 0000000..5c2f52c --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/BaseAdapter.java @@ -0,0 +1,57 @@ +package com.bingce.controlnetwork.adapter; + +import android.view.ViewGroup; + +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.model.IUniversalListItem; + +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public abstract class BaseAdapter extends RecyclerView.Adapter { + private final List mValues; + + public BaseAdapter(List items) { + mValues = items; + } + + public void updateData(List list) { + mValues.clear(); + if (list != null && !list.isEmpty()) { + mValues.addAll(list); + } + notifyDataSetChanged(); + } + + protected abstract VH createVH(@NotNull ViewGroup parent, int viewType); + + @Override + public @NotNull + VH onCreateViewHolder(@NotNull ViewGroup parent, int viewType) { + VH viewHolder = createVH(parent, viewType); + assert viewHolder != null; + return viewHolder; + } + + protected T getItem(int position) { + return mValues.get(position); + } + + protected boolean clickEnable(int position) { + return true; + } + + @Override + public int getItemCount() { + if (mValues == null) { + return 0; + } + return mValues.size(); + } + + public interface IOnItemClick> { + void onItemClick(T item); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/BaseIndexPrefixTextWithContextMenuAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/BaseIndexPrefixTextWithContextMenuAdapter.java new file mode 100644 index 0000000..82078e9 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/BaseIndexPrefixTextWithContextMenuAdapter.java @@ -0,0 +1,61 @@ +package com.bingce.controlnetwork.adapter; + +import android.view.ContextMenu; +import android.view.MenuItem; +import android.view.View; +import android.widget.TextView; + +import com.bingce.controlapphelper.model.IUniversalListItem; + +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +import com.bingce.controlnetwork.adapter.contextmenu.IAdapterContextMenu; +import com.bingce.controlnetwork.ui.vh.IndexTextViewHolder; +import com.bingce.controlnetwork.ui.vh.IndexTextWithPrefixViewHolder; + +public abstract class BaseIndexPrefixTextWithContextMenuAdapter> + extends IndexWithTextAndPrefixAdapter + implements View.OnCreateContextMenuListener { + private int currentLongPressIndex = -1; + private final IAdapterContextMenu adapterContextMenu; + + public BaseIndexPrefixTextWithContextMenuAdapter(List items, + IOnItemClick callback, + IAdapterContextMenu adapterContextMenu) { + super(items, callback); + this.adapterContextMenu = adapterContextMenu; + } + + @Override + final public void onBindViewHolder(@NotNull IndexTextViewHolder holder, int position) { + super.onBindViewHolder(holder, position); + holder.itemView.setOnLongClickListener(v -> { + currentLongPressIndex = position; + return false; + }); + holder.itemView.setOnCreateContextMenuListener(this); + if (holder instanceof IndexTextWithPrefixViewHolder) { + onSetPrefix(((IndexTextWithPrefixViewHolder) holder).prefix, getItem(position)); + } + } + + @Override + final public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { + if (adapterContextMenu == null) { + return; + } + menu.clear(); + for (int index = 0; index < adapterContextMenu.menuItemSize(); index++) { + menu.add(0, index, 0, adapterContextMenu.menuItemName(index)); + MenuItem menuItem = menu.getItem(index); + if (menuItem != null) { + menuItem.setOnMenuItemClickListener(item -> + adapterContextMenu.onMenuItemClick(getItem(currentLongPressIndex), item)); + } + } + } + + protected abstract void onSetPrefix(TextView prefixTextView, T item); +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/BaseIndexTextWithContextMenuAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/BaseIndexTextWithContextMenuAdapter.java new file mode 100644 index 0000000..738f542 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/BaseIndexTextWithContextMenuAdapter.java @@ -0,0 +1,54 @@ +package com.bingce.controlnetwork.adapter; + +import android.view.ContextMenu; +import android.view.MenuItem; +import android.view.View; + +import com.bingce.controlapphelper.model.IUniversalListItem; + +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +import com.bingce.controlnetwork.adapter.contextmenu.IAdapterContextMenu; +import com.bingce.controlnetwork.ui.vh.IndexTextViewHolder; + +public class BaseIndexTextWithContextMenuAdapter> + extends IndexWithTextAdapter + implements View.OnCreateContextMenuListener { + private int currentLongPressIndex = -1; + private final IAdapterContextMenu adapterContextMenu; + + public BaseIndexTextWithContextMenuAdapter(List items, + IOnItemClick callback, + IAdapterContextMenu adapterContextMenu) { + super(items, callback); + this.adapterContextMenu = adapterContextMenu; + } + + @Override + final public void onBindViewHolder(@NotNull IndexTextViewHolder holder, int position) { + super.onBindViewHolder(holder, position); + holder.itemView.setOnLongClickListener(v -> { + currentLongPressIndex = position; + return false; + }); + holder.itemView.setOnCreateContextMenuListener(this); + } + + @Override + final public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { + if (adapterContextMenu == null) { + return; + } + menu.clear(); + for (int index = 0; index < adapterContextMenu.menuItemSize(); index++) { + menu.add(0, index, 0, adapterContextMenu.menuItemName(index)); + MenuItem menuItem = menu.getItem(index); + if (menuItem != null) { + menuItem.setOnMenuItemClickListener(item -> + adapterContextMenu.onMenuItemClick(getItem(currentLongPressIndex), item)); + } + } + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/BaseSelectableIndexTextWithContextMenuAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/BaseSelectableIndexTextWithContextMenuAdapter.java new file mode 100644 index 0000000..cabe047 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/BaseSelectableIndexTextWithContextMenuAdapter.java @@ -0,0 +1,55 @@ +package com.bingce.controlnetwork.adapter; + +import android.view.ContextMenu; +import android.view.MenuItem; +import android.view.View; + +import com.bingce.controlapphelper.model.IUniversalListItem; + +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +import com.bingce.controlnetwork.adapter.contextmenu.IAdapterContextMenu; +import com.bingce.controlnetwork.ui.vh.IndexTextViewHolder; + +public class BaseSelectableIndexTextWithContextMenuAdapter> + extends SelectableIndexWithTextAdapter + implements View.OnCreateContextMenuListener { + private int currentLongPressIndex = -1; + private final IAdapterContextMenu adapterContextMenu; + + public BaseSelectableIndexTextWithContextMenuAdapter(String selectedId, + List items, + IOnItemClick callback, + IAdapterContextMenu adapterContextMenu) { + super(selectedId, items, callback); + this.adapterContextMenu = adapterContextMenu; + } + + @Override + final public void onBindViewHolder(@NotNull IndexTextViewHolder holder, int position) { + super.onBindViewHolder(holder, position); + holder.itemView.setOnLongClickListener(v -> { + currentLongPressIndex = position; + return false; + }); + holder.itemView.setOnCreateContextMenuListener(this); + } + + @Override + final public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { + if (adapterContextMenu == null) { + return; + } + menu.clear(); + for (int index = 0; index < adapterContextMenu.menuItemSize(); index++) { + menu.add(0, index, 0, adapterContextMenu.menuItemName(index)); + MenuItem menuItem = menu.getItem(index); + if (menuItem != null) { + menuItem.setOnMenuItemClickListener(item -> + adapterContextMenu.onMenuItemClick(getItem(currentLongPressIndex), item)); + } + } + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/BaseTitleAndSubtitleWithContextMenuAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/BaseTitleAndSubtitleWithContextMenuAdapter.java new file mode 100644 index 0000000..caa98be --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/BaseTitleAndSubtitleWithContextMenuAdapter.java @@ -0,0 +1,51 @@ +package com.bingce.controlnetwork.adapter; + +import android.view.ContextMenu; +import android.view.MenuItem; +import android.view.View; + +import com.bingce.controlapphelper.model.IUniversalListItemWithTitleAndSubtitle; +import com.bingce.controlnetwork.adapter.contextmenu.IAdapterContextMenu; +import com.bingce.controlnetwork.ui.vh.TitleWithSubtitleViewHolder; + +import java.util.List; + +public class BaseTitleAndSubtitleWithContextMenuAdapter> + extends TitleWithSubtitleAdapter + implements View.OnCreateContextMenuListener { + private int currentLongPressIndex = -1; + private final IAdapterContextMenu adapterContextMenu; + + public BaseTitleAndSubtitleWithContextMenuAdapter(List items, + IOnItemClick callback, + IAdapterContextMenu adapterContextMenu) { + super(items, callback); + this.adapterContextMenu = adapterContextMenu; + } + + @Override + final public void onBindViewHolder(TitleWithSubtitleViewHolder holder, int position) { + super.onBindViewHolder(holder, position); + holder.itemView.setOnLongClickListener(v -> { + currentLongPressIndex = position; + return false; + }); + holder.itemView.setOnCreateContextMenuListener(this); + } + + @Override + final public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { + if (adapterContextMenu == null) { + return; + } + menu.clear(); + for (int index = 0; index < adapterContextMenu.menuItemSize(); index++) { + menu.add(0, index, 0, adapterContextMenu.menuItemName(index)); + MenuItem menuItem = menu.getItem(index); + if (menuItem != null) { + menuItem.setOnMenuItemClickListener(item -> + adapterContextMenu.onMenuItemClick(getItem(currentLongPressIndex), item)); + } + } + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/GlobalControlPointSelectAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/GlobalControlPointSelectAdapter.java new file mode 100644 index 0000000..804e4e7 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/GlobalControlPointSelectAdapter.java @@ -0,0 +1,49 @@ +package com.bingce.controlnetwork.adapter; + +import android.content.Context; + +import com.bingce.controlapphelper.datasource.database.point.PointRecord; +import com.bingce.controlapphelper.model.PickPointResult; +import com.bingce.controlnetwork.R; + +import java.util.List; + +/* + * 限差详情adapter + * */ +public class GlobalControlPointSelectAdapter extends AbstractPointSelectAdapter { + private final List pointRecordList; + + public GlobalControlPointSelectAdapter(List pointRecords, + PickPointResult defaultValue, + int maxCount,//boolean singlePick, + Context context) { + super(defaultValue, maxCount, context); + this.pointRecordList = pointRecords; + } + + @Override + public int getGroupCount() { + return 1; + } + + @Override + public int getChildrenCount(int groupPosition) { + return pointRecordList.size(); + } + + @Override + public String getGroup(int groupPosition) { + return context().getString(R.string.global_control_point); + } + + @Override + public PointRecord getChild(int groupPosition, int childPosition) { + return pointRecordList.get(childPosition); + } + + @Override + protected boolean showGroupArrow() { + return false; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/IOnContextItemSelectedCallback.java b/app/src/main/java/com/bingce/controlnetwork/adapter/IOnContextItemSelectedCallback.java new file mode 100644 index 0000000..ebec77c --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/IOnContextItemSelectedCallback.java @@ -0,0 +1,9 @@ +package com.bingce.controlnetwork.adapter; + +import android.view.MenuItem; + +import androidx.annotation.NonNull; + +public interface IOnContextItemSelectedCallback { + void onContextItemSelected(@NonNull MenuItem item); +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/IUpdateListAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/IUpdateListAdapter.java new file mode 100644 index 0000000..f408f72 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/IUpdateListAdapter.java @@ -0,0 +1,9 @@ +package com.bingce.controlnetwork.adapter; + +import com.bingce.controlapphelper.model.IUniversalListItem; + +import java.util.List; + +public interface IUpdateListAdapter> { + void updateData(List list); +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/IndexWithTextAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/IndexWithTextAdapter.java new file mode 100644 index 0000000..25c4c2b --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/IndexWithTextAdapter.java @@ -0,0 +1,88 @@ +package com.bingce.controlnetwork.adapter; + +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.model.IUniversalListItem; +import com.bingce.controlapphelper.model.ViewItemType; + +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +import com.bingce.controlnetwork.ui.vh.IndexTextViewHolder; +import com.bingce.controlnetwork.ui.widget.ViewFactory; + +public class IndexWithTextAdapter> extends BaseAdapter { + private IOnItemClick callback; + private boolean showIndex = true; + + public IndexWithTextAdapter(List items, IOnItemClick callback) { + super(items); + this.callback = callback; + } + + public IndexWithTextAdapter(List items) { + super(items); + this.callback = null; + } + + public void setCallback(IOnItemClick callback) { + this.callback = callback; + } + + protected ViewItemType itemType() { + return ViewItemType.indexWithName; + } + + @Override + final protected IndexTextViewHolder createVH(@NotNull ViewGroup parent, int viewType) { + RecyclerView.ViewHolder viewHolder = ViewFactory.generatorViewHolder(parent.getContext(), parent, itemType()); + if (viewHolder instanceof IndexTextViewHolder) { + return (IndexTextViewHolder) viewHolder; + } + return null; + } + + protected void hideIndex() { + showIndex = false; + notifyDataSetChanged(); + } + + protected void showIndex() { + showIndex = true; + notifyDataSetChanged(); + } + + protected boolean clickEnable(int position) { + return true; + } + + @Override + public void onBindViewHolder(final @NotNull IndexTextViewHolder holder, int position) { + T item = getItem(position); + if (showIndex) { + holder.index.setVisibility(View.VISIBLE); + holder.index.setText(String.valueOf(position + 1)); + } else { + holder.index.setVisibility(View.GONE); + } + onSetName(holder.name, item); + holder.itemView.setOnClickListener(v -> { + if (callback != null && clickEnable(position)) { + callback.onItemClick(item); + } + }); + } + + protected void onSetName(TextView nameTextView, T item) { + nameTextView.setText(item.getName()); + } + + public interface IOnItemClick> { + void onItemClick(T item); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/IndexWithTextAndPrefixAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/IndexWithTextAndPrefixAdapter.java new file mode 100644 index 0000000..953da51 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/IndexWithTextAndPrefixAdapter.java @@ -0,0 +1,20 @@ +package com.bingce.controlnetwork.adapter; + +import com.bingce.controlapphelper.model.IUniversalListItem; +import com.bingce.controlapphelper.model.ViewItemType; + +import java.util.List; + +public class IndexWithTextAndPrefixAdapter> extends IndexWithTextAdapter { + public IndexWithTextAndPrefixAdapter(List items, IOnItemClick callback) { + super(items, callback); + } + + public IndexWithTextAndPrefixAdapter(List items) { + super(items); + } + + protected ViewItemType itemType() { + return ViewItemType.indexWithNameAndPrefix; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/MeasureAngleDistanceAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/MeasureAngleDistanceAdapter.java new file mode 100644 index 0000000..fd11fbb --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/MeasureAngleDistanceAdapter.java @@ -0,0 +1,122 @@ +package com.bingce.controlnetwork.adapter; + +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.model.IAdapter; +import com.bingce.controlapphelper.model.ViewItemType; +import com.bingce.controlapphelper.surveyor.data.CachedDataAloneDistance; +import com.bingce.controlapphelper.surveyor.data.ICachedData; +import com.bingce.controlapphelper.surveyor.data.ICycleRecorder; +import com.bingce.controlapphelper.surveyor.data.IDistanceTypeChangeListener; +import com.bingce.controlapphelper.surveyor.data.IMeasureCache; +import com.bingce.controlapphelper.surveyor.data.ISurveyorData; + +import com.bingce.controlnetwork.ui.vh.SurveyorDataAloneDistanceViewHolder; +import com.bingce.controlnetwork.ui.vh.SurveyorDataViewHolder; +import com.bingce.controlnetwork.ui.widget.ViewFactory; + +/** + * 测量记录adapter + * 井定向-距离 + */ +public class MeasureAngleDistanceAdapter extends RecyclerView.Adapter + implements IAdapter, IDistanceTypeChangeListener { + + public static final String TYPE_ANGLE = "TYPE_ANGLE"; + public static final String TYPE_DISTANCE = "TYPE_DISTANCE"; + + private final IMeasureCache cachedData; + private final ISurveyorData surveyorData; + private final ICycleRecorder cycleRecorder; + private boolean showSlopDistance = true; + private final String stationId; + private final String type;//区分水平还是距离 + + + public MeasureAngleDistanceAdapter( + String stationId, + IMeasureCache cachedData, + ICycleRecorder cycleRecorder, + ISurveyorData surveyorData, + String type) { + this.stationId = stationId; + this.cachedData = cachedData; + this.surveyorData = surveyorData; + this.cycleRecorder = cycleRecorder; + this.type = type; + //注册数据监听 + cachedData.register(this); + } + + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + RecyclerView.ViewHolder vh = null; + switch (type) { + case TYPE_ANGLE: + vh = ViewFactory.generatorViewHolder(parent.getContext(), parent, ViewItemType.surveyorStationPointItem); + break; + case TYPE_DISTANCE: + vh = ViewFactory.generatorViewHolder(parent.getContext(), parent, ViewItemType.aloneDistanceMeasure); + break; + } + assert vh != null; + return vh; + } + + @Override + public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { + if (holder instanceof SurveyorDataAloneDistanceViewHolder) { + SurveyorDataAloneDistanceViewHolder holderDistance = (SurveyorDataAloneDistanceViewHolder) holder; + holderDistance.setup(position, + stationId, + showSlopDistance, + (CachedDataAloneDistance) cachedData, + cycleRecorder, + surveyorData); + } else if (holder instanceof SurveyorDataViewHolder) { + SurveyorDataViewHolder holderHorizontalAngle = (SurveyorDataViewHolder) holder; + holderHorizontalAngle.setup(position, + stationId, + showSlopDistance, + (ICachedData) cachedData, + cycleRecorder, + surveyorData); + } + + holder.itemView.setOnClickListener(v -> { + if (iItemClickListener != null) { + iItemClickListener.click(position); + } + }); + } + + @Override + public int getItemCount() { + return cachedData.pointCount(); + } + + @Override + public void onDataChange() { + notifyDataSetChanged(); + } + + @Override + public void onShowSlopDistance(boolean value) { + this.showSlopDistance = value; + } + + + private IItemClickListener iItemClickListener; + + public void setOnItemClickListener(IItemClickListener iItemClickListener) { + this.iItemClickListener = iItemClickListener; + } + + public interface IItemClickListener { + void click(int position); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/MeasureHeightTraverseAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/MeasureHeightTraverseAdapter.java new file mode 100644 index 0000000..7b9d85a --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/MeasureHeightTraverseAdapter.java @@ -0,0 +1,98 @@ +package com.bingce.controlnetwork.adapter; + +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.model.IAdapter; +import com.bingce.controlapphelper.model.ViewItemType; +import com.bingce.controlapphelper.surveyor.data.ICachedData; +import com.bingce.controlapphelper.surveyor.data.ICycleRecorder; +import com.bingce.controlapphelper.surveyor.data.IDistanceTypeChangeListener; +import com.bingce.controlapphelper.surveyor.data.IMeasureCache; +import com.bingce.controlapphelper.surveyor.data.ISurveyorData; + +import java.util.Objects; + +import com.bingce.controlnetwork.ui.vh.SurveyorDataViewHolderHeightTraverse; +import com.bingce.controlnetwork.ui.widget.ViewFactory; + +/** + * 高程导线数据适配器 + */ +public class MeasureHeightTraverseAdapter extends RecyclerView.Adapter + implements IAdapter, IDistanceTypeChangeListener { + + private final IMeasureCache cachedData; + private final ISurveyorData surveyorData; + private final ICycleRecorder cycleRecorder; + private boolean showSlopDistance = true; + private final String stationId; + private final int typeBackOrFront;//区分后视还是前视 + + + public MeasureHeightTraverseAdapter( + String stationId, + IMeasureCache cachedData, + ICycleRecorder cycleRecorder, + ISurveyorData surveyorData, + int typeBackOrFront) { + this.stationId = stationId; + this.cachedData = cachedData; + this.surveyorData = surveyorData; + this.cycleRecorder = cycleRecorder; + this.typeBackOrFront = typeBackOrFront; + //注册数据监听 + cachedData.register(this); + } + + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + return Objects.requireNonNull(ViewFactory.generatorViewHolder(parent.getContext(), parent, ViewItemType.heightTraverseSurveyor)); + } + + @Override + public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { + SurveyorDataViewHolderHeightTraverse viewHolder = (SurveyorDataViewHolderHeightTraverse) holder; + viewHolder.setup(position, + stationId, + showSlopDistance, + (ICachedData) cachedData, + cycleRecorder, + surveyorData); + + holder.itemView.setOnClickListener(v -> { + if (iItemClickListener != null) { + iItemClickListener.click(position); + } + }); + } + + @Override + public int getItemCount() { + return cachedData.pointCount(); + } + + @Override + public void onDataChange() { + notifyDataSetChanged(); + } + + @Override + public void onShowSlopDistance(boolean value) { + this.showSlopDistance = value; + } + + + private IItemClickListener iItemClickListener; + + public void setOnItemClickListener(IItemClickListener iItemClickListener) { + this.iItemClickListener = iItemClickListener; + } + + public interface IItemClickListener { + void click(int position); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/MultipleSelectableIndexWithTextAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/MultipleSelectableIndexWithTextAdapter.java new file mode 100644 index 0000000..ae6dc00 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/MultipleSelectableIndexWithTextAdapter.java @@ -0,0 +1,71 @@ +package com.bingce.controlnetwork.adapter; + +import android.view.View; +import android.widget.ImageView; + +import com.bingce.controlapphelper.model.IUniversalListItem; +import com.bingce.controlapphelper.model.ViewItemType; + +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +import com.bingce.controlnetwork.ui.vh.IndexTextSelectableViewHolder; +import com.bingce.controlnetwork.ui.vh.IndexTextViewHolder; + +public class MultipleSelectableIndexWithTextAdapter> extends IndexWithTextAdapter { + private final List selectedIds = new ArrayList<>(); + + public MultipleSelectableIndexWithTextAdapter(List selectedIds, + List items, + IOnItemClick callback) { + super(items); + setCallback(item -> { + onItemClicked(item.getId()); + if (callback == null) { + return; + } + callback.onItemClick(item); + }); + this.selectedIds.addAll(selectedIds); + } + + protected void onItemClicked(String id) { + if (selectedIds.contains(id)) { + selectedIds.remove(id); + } else { + selectedIds.add(id); + } + notifyDataSetChanged(); + } + + @Override + protected ViewItemType itemType() { + return ViewItemType.indexWithNameSelectable; + } + + @Override + public void onBindViewHolder(@NotNull IndexTextViewHolder holder, int position) { + super.onBindViewHolder(holder, position); + //设置状态 + T t = getItem(position); + if (t == null) { + return; + } + if (holder instanceof IndexTextSelectableViewHolder) { + ImageView iv = ((IndexTextSelectableViewHolder) holder).status; + if (iv != null) { + if (selectedIds.contains(t.getId())) { + iv.setVisibility(View.VISIBLE); + } else { + iv.setVisibility(View.GONE); + } + } + } + } + + public List selectedIds() { + return selectedIds; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/PointRecordAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/PointRecordAdapter.java new file mode 100644 index 0000000..2bf3fc1 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/PointRecordAdapter.java @@ -0,0 +1,75 @@ +package com.bingce.controlnetwork.adapter; + +import android.content.Context; + +import androidx.annotation.NonNull; +import androidx.fragment.app.FragmentActivity; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.point.PointRecord; +import com.bingce.controlapphelper.util.PointUtil; +import com.bingce.utils.ThreadPoolUtil; + +import java.util.List; + +import blankj.utilcode.util.ToastUtils; + +import com.bingce.controlnetwork.adapter.contextmenu.ContextMenuDeleteEdit; +import com.bingce.controlnetwork.fragment.PointFragment; +import com.bingce.controlnetwork.ui.widget.dialog.LoadingUtil; + +public class PointRecordAdapter extends BaseIndexTextWithContextMenuAdapter { + public PointRecordAdapter(List items, + @NonNull FragmentActivity activity) { + super(items, + item -> editRecord(activity, item), + new ContextMenuDeleteEdit() { + @Override + protected void delete(PointRecord item) { + deletePoint(activity, item); + } + + @Override + protected void edit(PointRecord item) { + editRecord(activity, item); + } + + /** + * 删除点 + * 项目里这个点只要有数据就不能删除 + * + * @param item + */ + private void deletePoint(Context context, PointRecord item) { + LoadingUtil.show(context, null); + + ThreadPoolUtil.execute(() -> { + String msg = PointUtil.getUsedMsg(item.getId()); + if (msg != null) { + ToastUtils.showShort(msg); + dismissLoading(); + return; + } + SurveyorDatabaseFactory + .instance + .getPointDataSource() + .delete(item); + + dismissLoading(); + }); + } + + private void dismissLoading() { + ThreadPoolUtil.executeInMain(LoadingUtil::dismiss); + } + + }); + } + + + private static void editRecord(FragmentActivity activity, PointRecord record) { + PointFragment.edit(activity.getSupportFragmentManager(), + record.projectId, + record.getName(), record.getId(), record.getPointType(), record.getX(), record.getY(), record.getZ()); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/PointSelectAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/PointSelectAdapter.java new file mode 100644 index 0000000..9eec0f0 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/PointSelectAdapter.java @@ -0,0 +1,61 @@ +package com.bingce.controlnetwork.adapter; + +import android.content.Context; + +import com.bingce.controlapphelper.datasource.database.point.PointRecord; +import com.bingce.controlapphelper.model.KnownAndUnknownPoints; +import com.bingce.controlapphelper.model.PickPointResult; +import com.bingce.controlnetwork.R; + +import java.util.List; + +public class PointSelectAdapter extends AbstractPointSelectAdapter { + private final KnownAndUnknownPoints data; + private final List globalPoints; + + public PointSelectAdapter(KnownAndUnknownPoints points, + List globalPoints, + PickPointResult defaultValue, + int maxCount, + Context context) { + super(defaultValue, maxCount, context); + this.data = points; + this.globalPoints = globalPoints; + } + + @Override + public int getGroupCount() { +// return data.groupCount() + 1; + return data.groupCount() ; + } + + @Override + public int getChildrenCount(int groupPosition) { + if (groupPosition >= data.groupCount()) { + if (globalPoints == null) { + return 0; + } + return globalPoints.size(); + } + return data.childrenCount(groupPosition); + } + + @Override + public String getGroup(int groupPosition) { + if (groupPosition >= data.groupCount()) { + return context().getString(R.string.global_control_point); + } + return data.groupName(groupPosition, context()); + } + + @Override + public PointRecord getChild(int groupPosition, int childPosition) { + if (groupPosition >= data.groupCount()) { + if (globalPoints == null) { + return null; + } + return globalPoints.get(childPosition); + } + return data.child(groupPosition, childPosition); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/PrismMagegeAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/PrismMagegeAdapter.java new file mode 100644 index 0000000..74f418d --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/PrismMagegeAdapter.java @@ -0,0 +1,94 @@ +package com.bingce.controlnetwork.adapter; + +import android.view.ContextMenu; +import android.view.LayoutInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; + +import com.bingce.controlapphelper.datasource.database.prism.PrismRecord; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.adapter.contextmenu.IAdapterContextMenu; +import com.bingce.controlnetwork.ui.vh.PrismManageViewHolder; + +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public class PrismMagegeAdapter extends BaseAdapter + implements View.OnCreateContextMenuListener { + private IOnItemClick callback; + + private int currentLongPressIndex = -1; + + private final IAdapterContextMenu adapterContextMenu; + + public PrismMagegeAdapter(List items, IOnItemClick callback, IAdapterContextMenu adapterContextMenu) { + super(items); + this.callback = callback; + this.adapterContextMenu = adapterContextMenu; + } + + public void setCallback(IOnItemClick callback) { + this.callback = callback; + } + + @Override + final protected PrismManageViewHolder createVH(@NotNull ViewGroup parent, int viewType) { + View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_prism_manager, parent, false); + PrismManageViewHolder prismManageViewHolder = new PrismManageViewHolder(itemView); + return prismManageViewHolder; + } + + protected boolean clickEnable(int position) { + return true; + } + + @Override + public void onBindViewHolder(final @NotNull PrismManageViewHolder holder, int position) { + //长按出菜单 + holder.itemView.setOnLongClickListener(v -> { + currentLongPressIndex = position; + return false; + }); + holder.itemView.setOnCreateContextMenuListener(this); + + PrismRecord item = getItem(position); + + holder.tvName.setText(item.getShowPrismTypeName()); + holder.tvType.setText(item.prismTypeLarge); + + //绝对常数 + holder.tvConstant.setText(item.prismTypeConstant); + + holder.itemView.setOnClickListener(v -> { + if (callback != null && clickEnable(position)) { + callback.onItemClick(item); + } + }); + } + + public interface IOnItemClick { + void onItemClick(T item); + } + + @Override + final public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { + if (adapterContextMenu == null) { + return; + } + PrismRecord currentItem = getItem(currentLongPressIndex); + if (currentItem.modify == PrismRecord.MODIFY_DEFAULT) { + return; + } + menu.clear(); + for (int index = 0; index < adapterContextMenu.menuItemSize(); index++) { + menu.add(0, index, 0, adapterContextMenu.menuItemName(index)); + MenuItem menuItem = menu.getItem(index); + if (menuItem != null) { + menuItem.setOnMenuItemClickListener(menuItemBack -> + adapterContextMenu.onMenuItemClick(currentItem, menuItemBack)); + } + } + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/ProjectListAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/ProjectListAdapter.java new file mode 100644 index 0000000..33c0f1c --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/ProjectListAdapter.java @@ -0,0 +1,28 @@ +package com.bingce.controlnetwork.adapter; + +import android.content.Context; + +import androidx.annotation.NonNull; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; + +import com.bingce.controlapphelper.datasource.database.project.ProjectRecord; +import com.bingce.controlapphelper.util.IUIRunner; + +import java.util.ArrayList; + +import com.bingce.controlnetwork.adapter.contextmenu.ProjectAdapterContextMenu; + +public class ProjectListAdapter extends BaseIndexTextWithContextMenuAdapter + implements IUpdateListAdapter { + + public ProjectListAdapter(IOnItemClick callback, + @NonNull Context context, + @NonNull IUIRunner iuiRunner, + @NonNull LifecycleOwner lifecycleOwner, + @NonNull FragmentManager fragmentManager) { + super(new ArrayList<>(), + callback, + new ProjectAdapterContextMenu(context, iuiRunner, lifecycleOwner, fragmentManager)); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/ReSurveyorCycleAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/ReSurveyorCycleAdapter.java new file mode 100644 index 0000000..180f5fe --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/ReSurveyorCycleAdapter.java @@ -0,0 +1,56 @@ +package com.bingce.controlnetwork.adapter; + +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; + +import com.bingce.controlapphelper.model.UniversalListItem; +import com.bingce.controlapphelper.model.ViewItemType; + +import java.util.List; + +import com.bingce.controlnetwork.ui.vh.IndexTextSelectableViewHolder; +import com.bingce.controlnetwork.ui.widget.ViewFactory; + +public class ReSurveyorCycleAdapter extends BaseAdapter, IndexTextSelectableViewHolder> { + + private final List> dataList; + private final ICallBack callBack; + + private int selectPosition = -1; + + public ReSurveyorCycleAdapter(List> dataList, ICallBack callBack) { + super(dataList); + this.dataList = dataList; + this.callBack = callBack; + } + + @Override + protected IndexTextSelectableViewHolder createVH(@NonNull ViewGroup parent, int viewType) { + return (IndexTextSelectableViewHolder) ViewFactory.generatorViewHolder(parent.getContext(), parent, ViewItemType.indexWithNameSelectable); + } + + @Override + public void onBindViewHolder(@NonNull IndexTextSelectableViewHolder holder, int position) { + holder.index.setVisibility(View.GONE); + holder.name.setText(dataList.get(position).getName()); + + if (position == selectPosition) { + holder.status.setVisibility(View.VISIBLE); + } else { + holder.status.setVisibility(View.GONE); + } + + holder.itemView.setOnClickListener(v -> { + selectPosition = holder.getAbsoluteAdapterPosition(); + notifyItemRangeChanged(0, dataList.size()); + callBack.back(selectPosition); + }); + } + + public interface ICallBack { + void back(int cycleIndex); + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/ResurveyorPointsAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/ResurveyorPointsAdapter.java new file mode 100644 index 0000000..c22efe4 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/ResurveyorPointsAdapter.java @@ -0,0 +1,61 @@ +package com.bingce.controlnetwork.adapter; + +import android.content.Context; + +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; + +import com.bingce.controlapphelper.model.UniversalListItem; +import com.bingce.controlapphelper.model.ViewItemType; + +import java.util.List; + +import blankj.utilcode.util.ToastUtils; + +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.fragment.TipsFragment; + +public class ResurveyorPointsAdapter extends MultipleSelectableIndexWithTextAdapter { + private final FragmentManager fragmentManager; + private final LifecycleOwner lifecycleOwner; + private final Context context; + + public ResurveyorPointsAdapter(List selectedIds, + List items, + Context context, + FragmentManager fragmentManager, + LifecycleOwner lifecycleOwner) { + super(selectedIds, items, null); + this.fragmentManager = fragmentManager; + this.lifecycleOwner = lifecycleOwner; + this.context = context; + } + + @Override + protected void onItemClicked(String id) { + //判断上限数据 + if (!selectedIds().contains(id)) { + if (selectedIds().size() + 1 > getItemCount() / 3) { + TipsFragment.tipsOnly(fragmentManager, lifecycleOwner, context, + context.getString(R.string.tips_resurveyor_count_exceed_1_3)); + return; + } + } + if (getItem(0) != null && getItem(0).getId().equals(id)) { + ToastUtils.showShort(R.string.tips_resurveyor_must_select_0_point); + return; + } + super.onItemClicked(id); + } + + public static class Item extends UniversalListItem { + public Item(String name, String id) { + super(name, id, null); + } + + @Override + public ViewItemType getType() { + return null; + } + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/SelectableIndexWithTextAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/SelectableIndexWithTextAdapter.java new file mode 100644 index 0000000..7f920f9 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/SelectableIndexWithTextAdapter.java @@ -0,0 +1,99 @@ +package com.bingce.controlnetwork.adapter; + +import android.view.View; +import android.widget.ImageView; + +import com.bingce.controlapphelper.model.IUniversalListItem; +import com.bingce.controlapphelper.model.ViewItemType; + +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +import com.bingce.controlnetwork.ui.vh.IndexTextSelectableViewHolder; +import com.bingce.controlnetwork.ui.vh.IndexTextViewHolder; + +public class SelectableIndexWithTextAdapter> extends IndexWithTextAdapter { + private String selectedId; + private final List enableList = new ArrayList<>(); + + public SelectableIndexWithTextAdapter(String selectedId, List items, List enableIndex, IOnItemClick callback) { + super(items); + setCallback(item -> { + updateCurrentSelectedId(item.getId()); + if (callback == null) { + return; + } + callback.onItemClick(item); + }); + if (enableIndex != null) { + enableList.addAll(enableIndex); + } + this.selectedId = selectedId; + } + + public SelectableIndexWithTextAdapter(String selectedId, List items, IOnItemClick callback) { + this(selectedId, items, null, callback); + } + + protected void updateCurrentSelectedId(String id) { + selectedId = id; + notifyDataSetChanged(); + } + + // @Override +// protected RecyclerView.ViewHolder createVH(@NotNull ViewGroup parent, int viewType) { +// return ViewFactory.generatorViewHolder(parent.getContext(), parent, ViewFactory.ItemType.indexWithNameSelectable); +// } + @Override + protected ViewItemType itemType() { + return ViewItemType.indexWithNameSelectable; + } + + @Override + protected boolean clickEnable(int position) { + if (enableList.isEmpty() || enableList.contains(String.valueOf(position))) { + return super.clickEnable(position); + } + return false; + } + + @Override + public void onBindViewHolder(@NotNull IndexTextViewHolder holder, int position) { + super.onBindViewHolder(holder, position); + //设置状态 + T t = getItem(position); + if (t == null) { + return; + } + if (holder instanceof IndexTextSelectableViewHolder) { + ImageView iv = ((IndexTextSelectableViewHolder) holder).status; + if (iv != null) { + if (t.getId().equals(selectedId)) { + iv.setVisibility(View.VISIBLE); + } else { + iv.setVisibility(View.GONE); + } + } + + if (!enableList.isEmpty()) { + if (enableList.contains(String.valueOf(position))) { + ((IndexTextSelectableViewHolder) holder).mask.setVisibility(View.GONE); + ((IndexTextSelectableViewHolder) holder).item.setAlpha(1f); + } else { + ((IndexTextSelectableViewHolder) holder).mask.setVisibility(View.VISIBLE); + ((IndexTextSelectableViewHolder) holder).item.setAlpha(.5f); + } + } + } + } + + protected String currentSelectedItemId() { + return selectedId; + } + + protected boolean isItemSelected(int index) { + return currentSelectedItemId().equals(getItem(index).getId()); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/SpinnerAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/SpinnerAdapter.java new file mode 100644 index 0000000..c3a5219 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/SpinnerAdapter.java @@ -0,0 +1,83 @@ +package com.bingce.controlnetwork.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; +import android.widget.TextView; + +import java.util.ArrayList; +import java.util.List; + +import com.bingce.controlnetwork.R; + +public class SpinnerAdapter extends BaseAdapter { + + private final Context context; + + private final List lists; + + + public SpinnerAdapter(Context context, List list) { + this.context = context; + this.lists = new ArrayList<>(); + lists.addAll(list); + } + + @Override + public int getCount() { + return lists.size(); + } + + @Override + public String getItem(int position) { + return lists.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + convertView = getConvertView(convertView, parent); + ViewHodler viewHodler = (ViewHodler) convertView.getTag(); + viewHodler.textView.setText(getItem(position)); + return convertView; + } + + @Override + public View getDropDownView(int position, View convertView, ViewGroup parent) { + convertView = getConvertView(convertView, parent); + ViewHodler viewHodler = (ViewHodler) convertView.getTag(); + viewHodler.imageView.setVisibility(position == 0 ? View.VISIBLE : View.GONE); + viewHodler.textView.setText(getItem(position)); + return convertView; + } + + + private View getConvertView(View convertView, ViewGroup parent) { + if (convertView == null) { + ViewHodler viewHodler = new ViewHodler(); + convertView = LayoutInflater.from(context).inflate(R.layout.item_spinner_content, parent, false); + viewHodler.textView = convertView.findViewById(R.id.tv); + viewHodler.imageView = convertView.findViewById(R.id.ivArrow); + convertView.setTag(viewHodler); + } + return convertView; + } + + private class ViewHodler { + public TextView textView; + public ImageView imageView; + } + + public void setLists(List lists) { + this.lists.clear(); + this.lists.addAll(lists); + notifyDataSetChanged(); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/SurveyorPeriodAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/SurveyorPeriodAdapter.java new file mode 100644 index 0000000..a581d91 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/SurveyorPeriodAdapter.java @@ -0,0 +1,32 @@ +package com.bingce.controlnetwork.adapter; + +import android.os.Bundle; + +import androidx.fragment.app.DialogFragment; + +import com.bingce.controlapphelper.datasource.database.surveyorcycle.SurveyorPeriodRecord; + +import java.util.ArrayList; + +import com.bingce.controlnetwork.adapter.contextmenu.SurveyorPeriodAdapterContextMenu; +import com.bingce.controlnetwork.fragment.BottomSheetSurveyorPeriodFragment; + +public class SurveyorPeriodAdapter extends BaseSelectableIndexTextWithContextMenuAdapter { + public SurveyorPeriodAdapter(String selectedId, DialogFragment fragment) { + super(selectedId, + new ArrayList<>(), + item -> { + Bundle args = new Bundle(); + args.putString(BottomSheetSurveyorPeriodFragment.KEY_RESULT_ID, item.getValue()); + args.putString(BottomSheetSurveyorPeriodFragment.KEY_RESULT_NAME, item.getName()); + fragment.getParentFragmentManager().setFragmentResult(BottomSheetSurveyorPeriodFragment.KEY_REQUEST_TIME, args); + fragment.dismiss(); + }, + new SurveyorPeriodAdapterContextMenu(fragment.getContext(), selectedId, + fragment.getViewLifecycleOwner(), fragment.getChildFragmentManager())); + } + + public void changeCurrentSelect(String id) { + updateCurrentSelectedId(id); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/SurveyorStationListAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/SurveyorStationListAdapter.java new file mode 100644 index 0000000..6c026c6 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/SurveyorStationListAdapter.java @@ -0,0 +1,287 @@ +package com.bingce.controlnetwork.adapter; + + +import static com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord.isLineStation; + +import android.content.Context; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.WorkerThread; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; +import androidx.lifecycle.LiveData; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.line.LineRecord; +import com.bingce.controlapphelper.datasource.database.point.PointRecord; +import com.bingce.controlapphelper.datasource.database.surveyorrecord.ISurveyorRecordDataSource; +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord; +import com.bingce.controlapphelper.util.IUIRunner; +import com.bingce.controlapphelper.util.StationUtil; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.adapter.contextmenu.ContextMenuEdit; +import com.bingce.controlnetwork.fragment.TipsFragment; +import com.bingce.controlnetwork.fragment.TipsWith2OptionFragment; +import com.bingce.controlnetwork.fragment.stationdetail.SingleStationDetailAndEditFragment; +import com.bingce.controlnetwork.util.SurveyorStationUtil; +import com.bingce.utils.ThreadPoolUtil; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class SurveyorStationListAdapter extends BaseIndexPrefixTextWithContextMenuAdapter { + private final LifecycleOwner lifecycleOwner; + + public SurveyorStationListAdapter(List items, + @NonNull FragmentManager fragmentManager, + @NonNull LifecycleOwner lifecycleOwner, + @NonNull IUIRunner iuiRunner, + Context context, + IOnItemClick itemClick, + boolean editAble) { + super(items, itemClick, + contextMenu(fragmentManager, lifecycleOwner, iuiRunner, context, editAble)); + this.lifecycleOwner = lifecycleOwner; + } + + @Override + protected void onSetName(TextView nameTextView, SurveyorStationRecord item) { + String pointId = item.getItems().get(0).getPointId(); + nameTextView.setText(cachedId2Name.get(pointId)); + + if (item.getItems() == null || item.getItems().isEmpty()) { + return; + } + //停止原livedata订阅 + Object tag = nameTextView.getTag(); + LiveData pointRecordLiveData; + if (tag instanceof LiveData) { + pointRecordLiveData = (LiveData) tag; + pointRecordLiveData.removeObservers(lifecycleOwner); + } + //创建新订阅 + pointRecordLiveData = SurveyorDatabaseFactory + .instance + .getPointDataSource() + .findById(pointId); + nameTextView.setTag(pointRecordLiveData); + + //监听 + pointRecordLiveData.observe(lifecycleOwner, pointRecord -> { + if (pointRecord == null) { + return; + } + nameTextView.setText(pointRecord.getName()); + cachedId2Name.put(pointRecord.id, pointRecord.getName()); + }); + } + + @Override + protected void onSetPrefix(TextView prefixTextView, SurveyorStationRecord item) { + String lineId = item.getLineId(); + if (cachedId2LineName.containsKey(lineId)) { + prefixTextView.setText(cachedId2LineName.get(lineId)); + } else { + prefixTextView.setText(StationUtil.mulCycleAngleStationPrefix()); + } + + if (lineId == null || lineId.isEmpty()) { + return; + } + //停止原livedata订阅 + Object tag = prefixTextView.getTag(); + LiveData lineRecordLiveData; + if (tag instanceof LiveData) { + lineRecordLiveData = (LiveData) tag; + lineRecordLiveData.removeObservers(lifecycleOwner); + } + //创建新订阅 + lineRecordLiveData = SurveyorDatabaseFactory + .instance + .getLineRecordDatabase() + .liveData(lineId); + prefixTextView.setTag(lineRecordLiveData); + + //监听 + lineRecordLiveData.observe(lifecycleOwner, lineRecord -> { + if (lineRecord == null) { + return; + } + prefixTextView.setText(lineRecord.name + "-"); + cachedId2LineName.put(lineRecord.id, lineRecord.name); + cachedId2LineType.put(lineRecord.id, lineRecord.type); + }); + } + + private static final Map cachedId2Name = new HashMap<>(); + private static final Map cachedId2LineName = new HashMap<>(); + private static final Map cachedId2LineType = new HashMap<>(); + + private static ContextMenuEdit contextMenu( + @NonNull FragmentManager fragmentManager, + @NonNull LifecycleOwner lifecycleOwner, + @NonNull IUIRunner iuiRunner, + Context context, + boolean editAble) { + if (!editAble) { + return null; + } + return new ContextMenuEdit() { + @Override + protected void edit(SurveyorStationRecord item) { + if (SurveyorStationRecord.isLineWell(cachedId2LineType.get(item.getLineId()))) { + TipsWith2OptionFragment.tips(fragmentManager, lifecycleOwner, + context.getString(R.string.button_edit_station), + context.getString(R.string.button_delete_station), + context.getString(R.string.tips_select_default_station_operator_well), + new TipsWith2OptionFragment.SimpleCallback() { + @Override + public void onConfirm() { + SurveyorStationUtil.editLine(context, item.getLineId()); + } + + @Override + public void onCancel() { + try2DeleteLine(item.getLineId(), context, fragmentManager, lifecycleOwner, iuiRunner); + } + }); + return; + } + + + //检测是否属于导线测量 + if (isLineStation(item.getLineId())) { + String lineId = item.getLineId(); + TipsWith2OptionFragment.tips(fragmentManager, lifecycleOwner, + context.getString(R.string.button_edit_line), + context.getString(R.string.button_delete_line), + context.getString(R.string.tips_forbid_delete_station_because_batch), + new TipsWith2OptionFragment.SimpleCallback() { + @Override + public void onConfirm() { + try2EditLine(lineId, context, fragmentManager, lifecycleOwner, iuiRunner); + } + + @Override + public void onCancel() { + try2DeleteLine(lineId, context, fragmentManager, lifecycleOwner, iuiRunner); + } + }); + } else { + TipsWith2OptionFragment.tips(fragmentManager, lifecycleOwner, + context.getString(R.string.button_edit_station), + context.getString(R.string.button_delete_station), + context.getString(R.string.tips_select_default_station_operator), + new TipsWith2OptionFragment.SimpleCallback() { + @Override + public void onConfirm() { + ThreadPoolUtil.execute(() -> { + String stationName = StationUtil.getStationName(item); + String lineType = StationUtil.getLineTypeFromStation(item); + SingleStationDetailAndEditFragment.start(context, item.getId(), stationName, item.getProjectId(), lineType); + }); + } + + @Override + public void onCancel() { + String stationId = item.getId(); + try2DeleteStation(stationId, context, fragmentManager, lifecycleOwner, iuiRunner); + } + }); + } + } + }; + } + + @WorkerThread + private static boolean isStationHasData(String stationId) { + ISurveyorRecordDataSource surveyorRecordDataSource = + SurveyorDatabaseFactory.instance.getSurveyorRecordDataSource(); + return surveyorRecordDataSource.recordCount(stationId) > 0; + } + + @WorkerThread + private static boolean isLineHasData(String lineId) { + boolean lineHasData = Tools.isLineHasData(lineId); +// ISurveyorStationDataSource stationDataSource = +// SurveyorDatabaseFactory.instance.getSurveyorStation(); +// List stationRecordList = stationDataSource.getDataListByLine(lineId); +// if (stationRecordList == null || stationRecordList.isEmpty()) { +// return false; +// } +// ISurveyorRecordDataSource surveyorRecordDataSource = +// SurveyorDatabaseFactory.instance.getSurveyorRecordDataSource(); +// boolean hasData = false; +// for (SurveyorStationRecord stationRecord : stationRecordList) { +// if (stationRecord == null) { +// continue; +// } +// if (surveyorRecordDataSource.recordCount(stationRecord.getId()) <= 0) { +// continue; +// } +// hasData = true; +// break; +// } + return lineHasData; + } + + public static void try2DeleteLine(String lineId, Context context, + FragmentManager fragmentManager, LifecycleOwner lifecycleOwner, + @NonNull IUIRunner iuiRunner) { + ThreadPoolUtil.execute(() -> { + if (isLineHasData(lineId)) { + iuiRunner.runOnUI(() -> TipsFragment.cancelAbleTips(fragmentManager, lifecycleOwner, context, + context.getString(R.string.tips_is_sure_to_delete_line_with_record), + 4, + () -> SurveyorDatabaseFactory + .instance + .getSurveyorStation() + .deleteByLineId(lineId))); + } else { + SurveyorDatabaseFactory + .instance + .getSurveyorStation() + .deleteByLineId(lineId); + } + }); + } + + public static void try2EditLine(String lineId, Context context, + FragmentManager fragmentManager, LifecycleOwner lifecycleOwner, + @NonNull IUIRunner iuiRunner) { + ThreadPoolUtil.execute(() -> { + if (isLineHasData(lineId)) { + iuiRunner.runOnUI(() -> TipsFragment.cancelAbleTips(fragmentManager, lifecycleOwner, context, + context.getString(R.string.tips_is_sure_to_edit_line_with_record), + 4, + () -> SurveyorStationUtil.editLine(context, lineId))); + } else { + SurveyorStationUtil.editLine(context, lineId); + } + }); + } + + public static void try2DeleteStation(String stationId, Context context, + FragmentManager fragmentManager, LifecycleOwner lifecycleOwner, + @NonNull IUIRunner iuiRunner) { + ThreadPoolUtil.execute(() -> { + if (isStationHasData(stationId)) { + iuiRunner.runOnUI(() -> TipsFragment.cancelAbleTips(fragmentManager, lifecycleOwner, context, + context.getString(R.string.tips_is_sure_to_delete_station_with_record), + 4, + () -> SurveyorDatabaseFactory + .instance + .getSurveyorStation() + .deleteById(stationId))); + } else { + SurveyorDatabaseFactory + .instance + .getSurveyorStation() + .deleteById(stationId); + } + }); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/SurveyorStationRecordsAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/SurveyorStationRecordsAdapter.java new file mode 100644 index 0000000..61ff774 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/SurveyorStationRecordsAdapter.java @@ -0,0 +1,77 @@ +package com.bingce.controlnetwork.adapter; + +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.model.IAdapter; +import com.bingce.controlapphelper.model.ViewItemType; +import com.bingce.controlapphelper.surveyor.data.ICachedData; +import com.bingce.controlapphelper.surveyor.data.ICycleRecorder; +import com.bingce.controlapphelper.surveyor.data.IDistanceTypeChangeListener; +import com.bingce.controlapphelper.surveyor.data.ISurveyorData; + +import org.jetbrains.annotations.NotNull; + +import com.bingce.controlnetwork.ui.vh.SurveyorDataViewHolder; +import com.bingce.controlnetwork.ui.widget.ViewFactory; + +/* + * 测量记录adapter + * */ +public class SurveyorStationRecordsAdapter extends RecyclerView.Adapter + implements IAdapter, IDistanceTypeChangeListener { + private final ICachedData cachedData; + private final ISurveyorData surveyorData; + private final ICycleRecorder cycleRecorder; + private boolean showSlopDistance = true; + private final String stationId; + + public SurveyorStationRecordsAdapter( + String stationId, + ICachedData cachedData, + ICycleRecorder cycleRecorder, + ISurveyorData surveyorData) { + this.stationId = stationId; + this.cachedData = cachedData; + this.surveyorData = surveyorData; + this.cycleRecorder = cycleRecorder; + //注册数据监听 + cachedData.register(this); + } + + @NonNull + @NotNull + @Override + public SurveyorDataViewHolder onCreateViewHolder(@NonNull @NotNull ViewGroup parent, int viewType) { + RecyclerView.ViewHolder vh = ViewFactory.generatorViewHolder(parent.getContext(), parent, ViewItemType.surveyorStationPointItem); + assert vh != null; + return (SurveyorDataViewHolder) vh; + } + + @Override + public void onBindViewHolder(@NonNull @NotNull SurveyorDataViewHolder holder, int position) { + holder.setup(position, + stationId, + showSlopDistance, + cachedData, + cycleRecorder, + surveyorData); + } + + @Override + public int getItemCount() { + return cachedData.pointCount(); + } + + @Override + public void onDataChange() { + notifyItemRangeChanged(0, getItemCount()); + } + + @Override + public void onShowSlopDistance(boolean value) { + this.showSlopDistance = value; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/TitleWithSubtitleAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/TitleWithSubtitleAdapter.java new file mode 100644 index 0000000..caac1da --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/TitleWithSubtitleAdapter.java @@ -0,0 +1,76 @@ +package com.bingce.controlnetwork.adapter; + +import android.view.ViewGroup; + +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.model.IUniversalListItemWithTitleAndSubtitle; +import com.bingce.controlapphelper.model.ViewItemType; +import com.bingce.controlnetwork.ui.vh.TitleWithSubtitleViewHolder; +import com.bingce.controlnetwork.ui.widget.ViewFactory; + +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public class TitleWithSubtitleAdapter> + extends RecyclerView.Adapter { + + private final List mValues; + private final TitleWithSubtitleAdapter.IOnItemClick callback; + + public TitleWithSubtitleAdapter(List items, TitleWithSubtitleAdapter.IOnItemClick callback) { + mValues = items; + this.callback = callback; + } + + public void updateData(List list) { + if (mValues != null) { + mValues.clear(); + } + if (list != null) { + mValues.addAll(list); + } + notifyDataSetChanged(); + } + + protected RecyclerView.ViewHolder createVH(@NotNull ViewGroup parent, int viewType) { + return ViewFactory.generatorViewHolder(parent.getContext(), parent, ViewItemType.titleWithSubtitle); + } + + @Override + public @NotNull + TitleWithSubtitleViewHolder onCreateViewHolder(@NotNull ViewGroup parent, int viewType) { + RecyclerView.ViewHolder viewHolder = createVH(parent, viewType); + assert viewHolder != null; + return (TitleWithSubtitleViewHolder) viewHolder; + } + + protected T getItem(int position) { + return mValues.get(position); + } + + @Override + public void onBindViewHolder(final TitleWithSubtitleViewHolder holder, int position) { + T item = getItem(position); + holder.title.setText(item.getTitle()); + holder.subTitle.setText(item.getSubtitle()); + holder.itemView.setOnClickListener(v -> { + if (callback != null) { + callback.onItemClick(item); + } + }); + } + + @Override + public int getItemCount() { + if (mValues == null) { + return 0; + } + return mValues.size(); + } + + public interface IOnItemClick> { + void onItemClick(T item); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/ToleranceDetailAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/ToleranceDetailAdapter.java new file mode 100644 index 0000000..0cadcab --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/ToleranceDetailAdapter.java @@ -0,0 +1,136 @@ +package com.bingce.controlnetwork.adapter; + +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseExpandableListAdapter; + +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.interfacee.IProjectTolerance; +import com.bingce.controlapphelper.model.ProjectTolerance; +import com.bingce.controlapphelper.model.UniversalListItem; +import com.bingce.controlapphelper.model.ViewItemType; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.ui.vh.GroupParentViewHolder; +import com.bingce.controlnetwork.ui.vh.KeyBoolViewHolder; +import com.bingce.controlnetwork.ui.vh.KeyValueViewHolder; +import com.bingce.controlnetwork.ui.widget.ViewFactory; + +import java.util.Arrays; +import java.util.List; + +/* + * 限差详情adapter + * */ +public class ToleranceDetailAdapter extends BaseExpandableListAdapter { + private IProjectTolerance data; + private static final List childTypes = + Arrays.asList( + ViewItemType.nameWithBool, + ViewItemType.nameWithText); + + public ToleranceDetailAdapter(IProjectTolerance limit) { + data = limit; + } + + public void updateData(IProjectTolerance limit) { + this.data = limit; + notifyDataSetChanged(); + } + + @Override + public int getGroupCount() { + return data.groupCount(); + } + + @Override + public int getChildrenCount(int groupPosition) { + return data.childrenCount(groupPosition); + } + + @Override + public String getGroup(int groupPosition) { + return data.groupName(groupPosition); + } + + @Override + public UniversalListItem getChild(int groupPosition, int childPosition) { + return data.child(groupPosition, childPosition); + } + + @Override + public long getGroupId(int groupPosition) { + return groupPosition; + } + + @Override + public long getChildId(int groupPosition, int childPosition) { + return groupPosition * 10L + childPosition; + } + + @Override + public boolean hasStableIds() { + return true; + } + + @Override + public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { + GroupParentViewHolder viewHolder = null; + if (convertView == null) { + convertView = ViewFactory.generatorView(parent.getContext(), parent, ViewItemType.groupParent); + viewHolder = new GroupParentViewHolder(convertView); + convertView.setTag(viewHolder); + } else { + viewHolder = (GroupParentViewHolder) convertView.getTag(); + } + if (viewHolder != null) { + String groupName = getGroup(groupPosition); + if (viewHolder.name != null) { + viewHolder.name.setText(groupName); + } + if (viewHolder.expandIcon != null) { + viewHolder.expandIcon.setImageResource(isExpanded ? R.drawable.ic_arrow_up : R.drawable.ic_arrow_down); + } + } + return convertView; + } + + @Override + public int getChildTypeCount() { + return childTypes.size(); + } + + @Override + public int getChildType(int groupPosition, int childPosition) { + return childTypes.indexOf(getChild(groupPosition, childPosition).getType()); + } + + @Override + public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) { + UniversalListItem item = getChild(groupPosition, childPosition); + RecyclerView.ViewHolder viewHolder = null; + if (convertView == null) { + viewHolder = ViewFactory.generatorViewHolder(parent.getContext(), parent, item.getType()); + convertView = viewHolder.itemView; + convertView.setTag(viewHolder); + } else { + viewHolder = (RecyclerView.ViewHolder) convertView.getTag(); + } + if (viewHolder instanceof KeyValueViewHolder) { + KeyValueViewHolder kvHolder = (KeyValueViewHolder) viewHolder; + kvHolder.key.setText(item.getName()); + kvHolder.value.setText(item.getValue().toString()); + } else if (viewHolder instanceof KeyBoolViewHolder) { + KeyBoolViewHolder kvHolder = (KeyBoolViewHolder) viewHolder; + kvHolder.key.setText(item.getName()); + kvHolder.checkBox.setChecked((Boolean) item.getValue()); + } + return convertView; + } + + @Override + public boolean isChildSelectable(int groupPosition, int childPosition) { + return true; + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/contextmenu/ContextMenuDelete.java b/app/src/main/java/com/bingce/controlnetwork/adapter/contextmenu/ContextMenuDelete.java new file mode 100644 index 0000000..9a8331d --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/contextmenu/ContextMenuDelete.java @@ -0,0 +1,28 @@ +package com.bingce.controlnetwork.adapter.contextmenu; + +import android.view.MenuItem; + +import com.bingce.controlnetwork.R; + +public abstract class ContextMenuDelete implements IAdapterContextMenu { + @Override + public int menuItemSize() { + return 1; + } + + @Override + public int menuItemName(int index) { + return R.string.menu_delete; + } + + @Override + final public boolean onMenuItemClick(T item, MenuItem menuItem) { + if (menuItem.getItemId() == 0) { + delete(item); + return true; + } + return false; + } + + protected abstract void delete(T item); +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/contextmenu/ContextMenuDeleteEdit.java b/app/src/main/java/com/bingce/controlnetwork/adapter/contextmenu/ContextMenuDeleteEdit.java new file mode 100644 index 0000000..74d807f --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/contextmenu/ContextMenuDeleteEdit.java @@ -0,0 +1,37 @@ +package com.bingce.controlnetwork.adapter.contextmenu; + +import android.view.MenuItem; + +import com.bingce.controlnetwork.R; + +public abstract class ContextMenuDeleteEdit implements IAdapterContextMenu { + @Override + final public int menuItemSize() { + return 2; + } + + @Override + final public int menuItemName(int index) { + if (index == 0) { + return R.string.menu_delete; + } + return R.string.menu_edit; + } + + @Override + final public boolean onMenuItemClick(T item, MenuItem menuItem) { + if (menuItem.getItemId() == 0) { + delete(item); + return true; + } + if (menuItem.getItemId() == 1) { + edit(item); + return true; + } + return false; + } + + protected abstract void delete(T item); + + protected abstract void edit(T item); +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/contextmenu/ContextMenuEdit.java b/app/src/main/java/com/bingce/controlnetwork/adapter/contextmenu/ContextMenuEdit.java new file mode 100644 index 0000000..dab433c --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/contextmenu/ContextMenuEdit.java @@ -0,0 +1,28 @@ +package com.bingce.controlnetwork.adapter.contextmenu; + +import android.view.MenuItem; + +import com.bingce.controlnetwork.R; + +public abstract class ContextMenuEdit implements IAdapterContextMenu { + @Override + public int menuItemSize() { + return 1; + } + + @Override + public int menuItemName(int index) { + return R.string.menu_edit; + } + + @Override + final public boolean onMenuItemClick(T item, MenuItem menuItem) { + if (menuItem.getItemId() == 0) { + edit(item); + return true; + } + return false; + } + + protected abstract void edit(T item); +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/contextmenu/IAdapterContextMenu.java b/app/src/main/java/com/bingce/controlnetwork/adapter/contextmenu/IAdapterContextMenu.java new file mode 100644 index 0000000..4754b32 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/contextmenu/IAdapterContextMenu.java @@ -0,0 +1,14 @@ +package com.bingce.controlnetwork.adapter.contextmenu; + +import android.view.MenuItem; + +import androidx.annotation.StringRes; + +public interface IAdapterContextMenu { + int menuItemSize(); + + @StringRes + int menuItemName(int index); + + boolean onMenuItemClick(T item, MenuItem menuItem); +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/contextmenu/ProjectAdapterContextMenu.java b/app/src/main/java/com/bingce/controlnetwork/adapter/contextmenu/ProjectAdapterContextMenu.java new file mode 100644 index 0000000..bcb5494 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/contextmenu/ProjectAdapterContextMenu.java @@ -0,0 +1,49 @@ +package com.bingce.controlnetwork.adapter.contextmenu; + +import android.content.Context; + +import androidx.annotation.NonNull; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; + +import com.bingce.controlapphelper.ProjectHelper; +import com.bingce.controlapphelper.datasource.database.project.ProjectRecord; +import com.bingce.controlapphelper.util.IUIRunner; + +import com.bingce.controlnetwork.fragment.projectedit.AbstractProjectEditFragment; + +public class ProjectAdapterContextMenu extends ContextMenuDeleteEdit { + private @NonNull + final FragmentManager fragmentManager; + private @NonNull + final Context context; + private final @NonNull + IUIRunner iuiRunner; + private final @NonNull + LifecycleOwner lifecycleOwner; + + private final ProjectHelper projectHelper; + + public ProjectAdapterContextMenu( + @NonNull Context context, + @NonNull IUIRunner iuiRunner, + @NonNull LifecycleOwner lifecycleOwner, + @NonNull FragmentManager fragmentManager) { + this.fragmentManager = fragmentManager; + this.context = context; + this.iuiRunner = iuiRunner; + this.lifecycleOwner = lifecycleOwner; + projectHelper = new ProjectHelper(lifecycleOwner.getLifecycle()); + } + + @Override + protected void delete(ProjectRecord item) { + projectHelper.deleteProject(fragmentManager, lifecycleOwner, context, item); + } + + @Override + protected void edit(ProjectRecord item) { + AbstractProjectEditFragment.editProject(fragmentManager, context, item.getId(), item.getProjectTypeFault(), + item.getToleranceId(), item.getProjectName()); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/contextmenu/SurveyorPeriodAdapterContextMenu.java b/app/src/main/java/com/bingce/controlnetwork/adapter/contextmenu/SurveyorPeriodAdapterContextMenu.java new file mode 100644 index 0000000..441b054 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/contextmenu/SurveyorPeriodAdapterContextMenu.java @@ -0,0 +1,84 @@ +package com.bingce.controlnetwork.adapter.contextmenu; + +import android.content.Context; + +import androidx.annotation.NonNull; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.config.ConfigConstants; +import com.bingce.controlapphelper.datasource.database.config.ConfigRecord; +import com.bingce.controlapphelper.datasource.database.config.IConfigDataSource; +import com.bingce.controlapphelper.datasource.database.surveyorcycle.SurveyorPeriodRecord; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.fragment.StringInputFragment; +import com.bingce.utils.ThreadPoolUtil; + +import blankj.utilcode.util.ToastUtils; + +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.fragment.StringInputFragment; + +public class SurveyorPeriodAdapterContextMenu extends ContextMenuDeleteEdit { + private @NonNull + final LifecycleOwner lifecycleOwner; + private @NonNull + final FragmentManager fragmentManager; + private final String selectedId; + private final Context context; + + public SurveyorPeriodAdapterContextMenu(Context context, String selectedId, + @NonNull LifecycleOwner lifecycleOwner, + @NonNull FragmentManager fragmentManager) { + this.context = context; + this.selectedId = selectedId; + this.lifecycleOwner = lifecycleOwner; + this.fragmentManager = fragmentManager; + } + + @Override + protected void delete(SurveyorPeriodRecord item) { + String id = item.getId(); + if (selectedId.equals(id)) { + ToastUtils.showShort(Tools.getString(R.string.current_period_selected_not_delete)); + } else { + SurveyorDatabaseFactory + .instance + .getSurveyorPeriod() + .deleteById(id); + //检测是否需要修改默认测期 + ThreadPoolUtil.execute(new Runnable() { + @Override + public void run() { + IConfigDataSource configDataSource = + SurveyorDatabaseFactory + .instance.getConfigDataSource(); + ConfigRecord configRecord = configDataSource.getByKeySync(ConfigConstants.KEY_DEFAULT_PERIOD_ID); + if (configRecord != null && id.equals(configRecord.getConfigValue())) { + configDataSource.set(ConfigConstants.KEY_DEFAULT_PERIOD_ID, selectedId); + } + } + }); + } + } + + @Override + protected void edit(SurveyorPeriodRecord item) { + StringInputFragment + .input( + fragmentManager, + Tools.getString(R.string.modify_period_name), + item.getName(), + lifecycleOwner, + string -> { + if (string != null && !string.isEmpty()) { + item.setName(string); + SurveyorDatabaseFactory + .instance + .getSurveyorPeriod() + .saveRecord(item); + } + }); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/stationdetail/BaseStationDetailAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/stationdetail/BaseStationDetailAdapter.java new file mode 100644 index 0000000..bd0419e --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/stationdetail/BaseStationDetailAdapter.java @@ -0,0 +1,227 @@ +package com.bingce.controlnetwork.adapter.stationdetail; + +import android.text.TextUtils; +import android.view.View; + +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.datasource.database.surveyorstation.model.SurveyorPoint; +import com.bingce.controlapphelper.model.PickPointResult; +import com.bingce.controlapphelper.model.StationDetailItem; +import com.bingce.controlapphelper.model.ViewItemType; +import com.bingce.controlnetwork.ui.vh.DraggableTextViewHolder; +import com.bingce.controlnetwork.ui.vh.StationGroupItemViewHolder; +import com.bingce.controlnetwork.ui.widget.recyclerview.AbstractDraggableRecycleViewAdapter; + +import java.util.ArrayList; +import java.util.List; + +public abstract class BaseStationDetailAdapter extends AbstractDraggableRecycleViewAdapter { + private final boolean adjustable; + private final IOnSelectPointDelegate selectPointCallback; + + protected BaseStationDetailAdapter(IOnSelectPointDelegate selectPointCallback, + List items, + boolean adjustable) { + super(items); + this.adjustable = adjustable; + this.selectPointCallback = selectPointCallback; + } + + public void setStationPoint(String id, String name) { + StationDetailItem item = getItem(1); + if (item != null) { + if (StationDetailItem.ITEM_TYPE_STATION_ITEM.equals(item.getType())) { + setItem(1, new StationDetailItem( + name, StationDetailItem.ITEM_TYPE_STATION_ITEM, id)); + notifyItemChanged(1); + } else { + StationDetailItem newInstance = new StationDetailItem( + name, StationDetailItem.ITEM_TYPE_STATION_ITEM, id); + insert(1, newInstance); + notifyItemInserted(1); + } + } + } + + public void setSurveyorPoint(List ids, List names) { + List items = new ArrayList<>(); + for (int index = 0; index < ids.size(); index++) { + StationDetailItem item = new StationDetailItem( + names.get(index), StationDetailItem.ITEM_TYPE_POINT_ITEM, ids.get(index)); + items.add(item); + } + if (items == null || items.isEmpty()) { + return; + } + for (int i = getItemCount() - 1; i >= 0; i--) { + StationDetailItem item = getItem(i); + if (TextUtils.equals(item.getType(), StationDetailItem.ITEM_TYPE_POINT_ITEM)) { + remove(item); + } + } + insertAll(items); + notifyDataSetChanged(); + } + + private StationDetailItem getStationItem() { + StationDetailItem o = getItem(1); + if (o != null && StationDetailItem.ITEM_TYPE_STATION_ITEM.equals(o.getType())) { + return o; + } + return null; + } + + @Override + protected void bindItem(StationDetailItem item, RecyclerView.ViewHolder viewHolder) { + if (viewHolder instanceof DraggableTextViewHolder) { + DraggableTextViewHolder draggableTextViewHolder = (DraggableTextViewHolder) viewHolder; + DraggableTextViewHolder.update(draggableTextViewHolder, item, adjustable); + } else if (viewHolder instanceof StationGroupItemViewHolder) { + StationGroupItemViewHolder surveyorStationSetupGroupParentViewHolder = ((StationGroupItemViewHolder) viewHolder); + StationGroupItemViewHolder.update( + surveyorStationSetupGroupParentViewHolder, + item, + adjustable, + (itemType, surveyorStationSetupGroupParentViewHolder1) -> { + if (StationDetailItem.ITEM_TYPE_STATION_GROUP.equals(item.getType())) { + View.OnClickListener listener = v -> { + if (selectPointCallback != null) { + //收集信息 + PickPointResult pickPointResult = new PickPointResult(); + StationDetailItem stationItem = getStationItem(); + if (stationItem != null) { + pickPointResult.getSelectedIds().add(stationItem.getOriginalPointId()); + pickPointResult.getSelectedNames().add(stationItem.getName()); + } + ArrayList filters = new ArrayList<>(); + for (int index = 2; index < getItemCount(); index++) { + StationDetailItem obj = getItem(index); + if (obj == null) { + continue; + } + if (StationDetailItem.ITEM_TYPE_POINT_ITEM.equals(obj.getType())) { + filters.add(obj.getOriginalPointId()); + } + } + selectPointCallback.onSelectStationPoint(pickPointResult, filters); + } + }; + surveyorStationSetupGroupParentViewHolder1.pick.setOnClickListener(listener); + surveyorStationSetupGroupParentViewHolder1.switchView.setOnClickListener(listener); + StationDetailItem stationItem = getStationItem(); + if (stationItem != null) { + surveyorStationSetupGroupParentViewHolder1.pick.setVisibility(View.INVISIBLE); + surveyorStationSetupGroupParentViewHolder1.switchView.setVisibility(View.VISIBLE); + } else { + surveyorStationSetupGroupParentViewHolder1.pick.setVisibility(View.VISIBLE); + surveyorStationSetupGroupParentViewHolder1.switchView.setVisibility(View.INVISIBLE); + } + } else if (StationDetailItem.ITEM_TYPE_POINT_GROUP.equals(item.getType())) { + surveyorStationSetupGroupParentViewHolder1.pick.setOnClickListener(v -> { + if (selectPointCallback != null) { + //收集信息 + PickPointResult pickPointResult = new PickPointResult(); + for (int index = 2; index < getItemCount(); index++) { + StationDetailItem o = getItem(index); + if (o == null) { + continue; + } + if (StationDetailItem.ITEM_TYPE_POINT_ITEM.equals(o.getType())) { + pickPointResult.getSelectedIds().add(o.getOriginalPointId()); + pickPointResult.getSelectedNames().add(o.getName()); + } + } + String filterId = ""; + StationDetailItem filter = getStationItem(); + if (filter != null) { + filterId = filter.getOriginalPointId(); + } + ArrayList filters = new ArrayList<>(); + if (!filterId.isEmpty()) { + filters.add(filterId); + } + selectPointCallback.onSelectSurveyorPoint(pickPointResult, filters); + } + }); + } + }); + } + } + + @Override + public int getItemViewType(int position) { + StationDetailItem item = getItem(position); + if (item == null) { + return -1; + } + if (StationDetailItem.ITEM_TYPE_POINT_GROUP.equals(item.getType()) || + StationDetailItem.ITEM_TYPE_STATION_GROUP.equals(item.getType())) { + return ViewItemType.surveyorStationCreateStationGroupItem.ordinal(); + } + return super.getItemViewType(position); + } + + @Override + public boolean isItemSwipeAble(int position) { + StationDetailItem item = getItem(position); + if (!adjustable || item == null) { + return false; + } + return !StationDetailItem.ITEM_TYPE_STATION_GROUP.equals(item.getType()) && + !StationDetailItem.ITEM_TYPE_POINT_GROUP.equals(item.getType()) && + !StationDetailItem.ITEM_TYPE_STATION_ITEM.equals(item.getType()); + } + + @Override + public boolean isItemDragAble(int position) { + StationDetailItem item = getItem(position); + if (!adjustable || item == null) { + return false; + } + return !StationDetailItem.ITEM_TYPE_STATION_ITEM.equals(item.getType()) && + !StationDetailItem.ITEM_TYPE_STATION_GROUP.equals(item.getType()) && + !StationDetailItem.ITEM_TYPE_POINT_GROUP.equals(item.getType()); + } + + public List collectData() { + List stationItems = new ArrayList<>(); + for (int index = 0; index < getItemCount(); index++) { + StationDetailItem item = getItem(index); + if (item == null) { + continue; + } + if (StationDetailItem.ITEM_TYPE_STATION_ITEM.equals(item.getType())) { + SurveyorPoint stationItem = new SurveyorPoint(); + stationItem.setOriginalPointId(item.getOriginalPointId()); + stationItem.setType(SurveyorPoint.TYPE_STATION); + stationItems.add(stationItem); + } else if (StationDetailItem.ITEM_TYPE_POINT_ITEM.equals(item.getType())) { + SurveyorPoint stationItem = new SurveyorPoint(); + stationItem.setOriginalPointId(item.getOriginalPointId()); + stationItem.setType(SurveyorPoint.TYPE_POINT); + stationItems.add(stationItem); + } + } + return stationItems; + } + + public int surveyorPointSize() { + int size = getItemCount(); + int count = 0; + for (int index = 0; index < size; index++) { + StationDetailItem item = getItem(index); + if (item == null || !StationDetailItem.ITEM_TYPE_POINT_ITEM.equals(item.getType())) { + continue; + } + count++; + } + return count; + } + + public interface IOnSelectPointDelegate { + void onSelectStationPoint(PickPointResult pickPointResult, ArrayList filters); + + void onSelectSurveyorPoint(PickPointResult pickPointResult, ArrayList filters); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/stationdetail/EditableStationDetailAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/stationdetail/EditableStationDetailAdapter.java new file mode 100644 index 0000000..746dff6 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/stationdetail/EditableStationDetailAdapter.java @@ -0,0 +1,11 @@ +package com.bingce.controlnetwork.adapter.stationdetail; + +import com.bingce.controlapphelper.model.StationDetailItem; + +import java.util.List; + +public class EditableStationDetailAdapter extends BaseStationDetailAdapter { + public EditableStationDetailAdapter(IOnSelectPointDelegate selectPointCallback, List items) { + super(selectPointCallback, items, true); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/stationdetail/NoEditableStationDetailAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/stationdetail/NoEditableStationDetailAdapter.java new file mode 100644 index 0000000..b79df48 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/stationdetail/NoEditableStationDetailAdapter.java @@ -0,0 +1,11 @@ +package com.bingce.controlnetwork.adapter.stationdetail; + +import com.bingce.controlapphelper.model.StationDetailItem; + +import java.util.List; + +public class NoEditableStationDetailAdapter extends BaseStationDetailAdapter { + public NoEditableStationDetailAdapter(List items) { + super(null, items, false); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/stationdetail/StationCreateLineKnownUnknownKnownAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/stationdetail/StationCreateLineKnownUnknownKnownAdapter.java new file mode 100644 index 0000000..bdea324 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/stationdetail/StationCreateLineKnownUnknownKnownAdapter.java @@ -0,0 +1,354 @@ +package com.bingce.controlnetwork.adapter.stationdetail; + +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.model.PickPointResult; +import com.bingce.controlapphelper.model.StationDetailItem; +import com.bingce.controlapphelper.model.ViewItemType; +import com.bingce.controlnetwork.ui.vh.DraggableTextViewHolder; +import com.bingce.controlnetwork.ui.vh.StationGroupItemViewHolder; +import com.bingce.controlnetwork.ui.widget.recyclerview.AbstractDraggableRecycleViewAdapter; + +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +/** + * (复合、无定向)导线创建 known1-unknown-known2格式 + */ +public class StationCreateLineKnownUnknownKnownAdapter extends AbstractDraggableRecycleViewAdapter { + private final IOnSelectPointDelegate selectPointCallback; + + public StationCreateLineKnownUnknownKnownAdapter(IOnSelectPointDelegate selectPointCallback, + List items) { + super(items); + this.selectPointCallback = selectPointCallback; + } + + public void setKnownPoints1(List ids, List names) { + if (ids == null || names == null || ids.size() != names.size()) { + return; + } + //先移除之前known point + List knownItems = knownItems1(); + for (StationDetailItem item : knownItems) { + remove(item); + } + //添加新的known point + for (int index = 0; index < ids.size(); index++) { + insert( + 1 + index, + new StationDetailItem( + names.get(index), + StationDetailItem.ITEM_TYPE_KNOWN_POINT_ITEM1, + ids.get(index))); + } + //通知变化 + if (knownItems.size() == ids.size()) { + notifyItemRangeChanged(1, ids.size()); + } else { + notifyItemRangeChanged(1, getItemCount() - 1); + } + } + + public void setUnknownPoints(List ids, List names) { + if (ids == null || names == null || ids.size() != names.size()) { + return; + } + //先移除之前unknown point + List unknowns = unknownItems(); + for (StationDetailItem item : unknowns) { + remove(item); + } + //搜索unknown-group索引 + int targetIndex = -1; + for (int index = 0; index < getItemCount(); index++) { + StationDetailItem obj = getItem(index); + if (obj != null && StationDetailItem.ITEM_TYPE_UN_KNOWN_POINT_GROUP.equals(obj.getType())) { + targetIndex = index; + break; + } + } + if (targetIndex >= 0) { + //添加新的unknown point + for (int index = 0; index < ids.size(); index++) { + insert( + targetIndex + 1 + index, + new StationDetailItem( + names.get(index), + StationDetailItem.ITEM_TYPE_UN_KNOWN_POINT_ITEM, + ids.get(index))); + } + } + //通知变化 + if (unknowns.size() == ids.size()) { + notifyItemRangeChanged(targetIndex + 1, ids.size()); + } else { + notifyItemRangeChanged(targetIndex + 1, getItemCount() - 1); + } + } + + public void setKnownPoints2(List ids, List names) { + if (ids == null || names == null || ids.size() != names.size()) { + return; + } + //搜索known-group2索引 + int targetIndex = -1; + for (int index = 0; index < getItemCount(); index++) { + StationDetailItem obj = getItem(index); + if (obj != null && StationDetailItem.ITEM_TYPE_KNOWN_POINT_GROUP2.equals(obj.getType())) { + targetIndex = index; + break; + } + } + List items = new ArrayList<>(); + for (int index = 0; index < ids.size(); index++) { + StationDetailItem item = new StationDetailItem( + names.get(index), StationDetailItem.ITEM_TYPE_KNOWN_POINT_ITEM2, ids.get(index)); + items.add(item); + } + if (targetIndex > 0) { + replace(targetIndex + 1, items); + notifyItemRangeChanged(targetIndex + 1, items.size()); + } + } + + public List knownItems1() { + List items = new ArrayList<>(); + for (int index = 1; index < getItemCount(); index++) { + StationDetailItem obj = getItem(index); + if (obj == null || !StationDetailItem.ITEM_TYPE_KNOWN_POINT_ITEM1.equals(obj.getType())) { + break; + } + items.add(obj); + } + return items; + } + + public List unknownItems() { + List items = new ArrayList<>(); + for (int index = 1; index < getItemCount(); index++) { + StationDetailItem obj = getItem(index); + if (obj == null || !StationDetailItem.ITEM_TYPE_UN_KNOWN_POINT_ITEM.equals(obj.getType())) { + continue; + } + items.add(obj); + } + return items; + } + + public List knownItems2() { + List items = new ArrayList<>(); + int targetIndex = -1; + for (int index = getItemCount() - 1; index >= 0; index--) { + StationDetailItem obj = getItem(index); + if (obj != null && StationDetailItem.ITEM_TYPE_KNOWN_POINT_GROUP2.equals(obj.getType())) { + targetIndex = index; + break; + } + } + if (targetIndex < 0) { + return items; + } + for (int index = targetIndex + 1; index < getItemCount(); index++) { + StationDetailItem obj = getItem(index); + if (obj == null || !StationDetailItem.ITEM_TYPE_KNOWN_POINT_ITEM2.equals(obj.getType())) { + break; + } + items.add(obj); + } + return items; + } + + @Override + protected void bindItem(StationDetailItem item, RecyclerView.ViewHolder viewHolder) { + if (viewHolder instanceof DraggableTextViewHolder) { + DraggableTextViewHolder draggableTextViewHolder = (DraggableTextViewHolder) viewHolder; + DraggableTextViewHolder.update(draggableTextViewHolder, item, true); + } else if (viewHolder instanceof StationGroupItemViewHolder) { + StationGroupItemViewHolder surveyorStationSetupGroupParentViewHolder = ((StationGroupItemViewHolder) viewHolder); + StationGroupItemViewHolder.update( + surveyorStationSetupGroupParentViewHolder, + item, + true, + (itemType, surveyorStationSetupGroupParentViewHolder1) -> { + if (StationDetailItem.ITEM_TYPE_KNOWN_POINT_GROUP1.equals(item.getType())) { + View.OnClickListener listener = v -> { + if (selectPointCallback != null) { + //收集信息 + PickPointResult pickPointResult = new PickPointResult(); + for (StationDetailItem obj : knownItems1()) { + pickPointResult.getSelectedIds().add(obj.getOriginalPointId()); + pickPointResult.getSelectedNames().add(obj.getName()); + } + ArrayList filters = new ArrayList<>(); + for (StationDetailItem obj : unknownItems()) { + if (obj == null) { + continue; + } + filters.add(obj.getOriginalPointId()); + } + for (StationDetailItem obj : knownItems2()) { + if (obj == null) { + continue; + } + filters.add(obj.getOriginalPointId()); + } + selectPointCallback.onSelectKnownPoint1(pickPointResult, filters); + } + }; + surveyorStationSetupGroupParentViewHolder1.pick.setOnClickListener(listener); + surveyorStationSetupGroupParentViewHolder1.switchView.setOnClickListener(listener); + + List knownItems = knownItems1(); + if (knownItems.isEmpty()) { + surveyorStationSetupGroupParentViewHolder1.pick.setVisibility(View.VISIBLE); + surveyorStationSetupGroupParentViewHolder1.switchView.setVisibility(View.INVISIBLE); + } else { + surveyorStationSetupGroupParentViewHolder1.pick.setVisibility(View.INVISIBLE); + surveyorStationSetupGroupParentViewHolder1.switchView.setVisibility(View.VISIBLE); + } + } else if (StationDetailItem.ITEM_TYPE_UN_KNOWN_POINT_GROUP.equals(item.getType())) { + surveyorStationSetupGroupParentViewHolder1.pick.setOnClickListener(v -> { + if (selectPointCallback != null) { + //收集信息 + PickPointResult pickPointResult = new PickPointResult(); + for (int index = 2; index < getItemCount(); index++) { + StationDetailItem o = getItem(index); + if (o == null) { + continue; + } + if (StationDetailItem.ITEM_TYPE_UN_KNOWN_POINT_ITEM.equals(o.getType())) { + pickPointResult.getSelectedIds().add(o.getOriginalPointId()); + pickPointResult.getSelectedNames().add(o.getName()); + } + } + ArrayList filters = new ArrayList<>(); + for (StationDetailItem obj : knownItems1()) { + if (obj == null) { + continue; + } + filters.add(obj.getOriginalPointId()); + } + for (StationDetailItem obj : knownItems2()) { + if (obj == null) { + continue; + } + filters.add(obj.getOriginalPointId()); + } + selectPointCallback.onSelectUnknownPoint(pickPointResult, filters); + } + }); + } else if (StationDetailItem.ITEM_TYPE_KNOWN_POINT_GROUP2.equals(item.getType())) { + View.OnClickListener listener = v -> { + if (selectPointCallback != null) { + //收集信息 + PickPointResult pickPointResult = new PickPointResult(); + for (StationDetailItem obj : knownItems2()) { + pickPointResult.getSelectedIds().add(obj.getOriginalPointId()); + pickPointResult.getSelectedNames().add(obj.getName()); + } + ArrayList filters = new ArrayList<>(); + for (StationDetailItem obj : knownItems1()) { + if (obj == null) { + continue; + } + filters.add(obj.getOriginalPointId()); + } + for (StationDetailItem obj : unknownItems()) { + if (obj == null) { + continue; + } + filters.add(obj.getOriginalPointId()); + } + selectPointCallback.onSelectKnownPoint2(pickPointResult, filters); + } + }; + surveyorStationSetupGroupParentViewHolder1.pick.setOnClickListener(listener); + surveyorStationSetupGroupParentViewHolder1.switchView.setOnClickListener(listener); + + List knownItems = knownItems2(); + if (knownItems.isEmpty()) { + surveyorStationSetupGroupParentViewHolder1.pick.setVisibility(View.VISIBLE); + surveyorStationSetupGroupParentViewHolder1.switchView.setVisibility(View.INVISIBLE); + } else { + surveyorStationSetupGroupParentViewHolder1.pick.setVisibility(View.INVISIBLE); + surveyorStationSetupGroupParentViewHolder1.switchView.setVisibility(View.VISIBLE); + } + } + }); + } + } + + private static final int ITEM_TYPE_KNOWN_POINT1 = 11; + private static final int ITEM_TYPE_UNKNOWN_POINT = ITEM_TYPE_KNOWN_POINT1 + 1; + private static final int ITEM_TYPE_KNOWN_POINT2 = ITEM_TYPE_UNKNOWN_POINT + 1; + + @Override + public int getItemViewType(int position) { + StationDetailItem item = getItem(position); + if (item == null) { + return -1; + } + if (StationDetailItem.ITEM_TYPE_KNOWN_POINT_GROUP1.equals(item.getType()) || + StationDetailItem.ITEM_TYPE_UN_KNOWN_POINT_GROUP.equals(item.getType()) || + StationDetailItem.ITEM_TYPE_KNOWN_POINT_GROUP2.equals(item.getType())) { + return ViewItemType.surveyorStationCreateStationGroupItem.ordinal(); + } + if (StationDetailItem.ITEM_TYPE_KNOWN_POINT_ITEM1.equals(item.getType())) { + return ITEM_TYPE_KNOWN_POINT1; + } + if (StationDetailItem.ITEM_TYPE_UN_KNOWN_POINT_ITEM.equals(item.getType())) { + return ITEM_TYPE_UNKNOWN_POINT; + } + if (StationDetailItem.ITEM_TYPE_KNOWN_POINT_ITEM2.equals(item.getType())) { + return ITEM_TYPE_KNOWN_POINT2; + } + return super.getItemViewType(position); + } + + @NonNull + @NotNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull @NotNull ViewGroup parent, int viewType) { + if (ITEM_TYPE_KNOWN_POINT1 == viewType || ITEM_TYPE_UNKNOWN_POINT == viewType || ITEM_TYPE_KNOWN_POINT2 == viewType) { + return super.onCreateViewHolder(parent, ViewItemType.draggableItem.ordinal()); + } + return super.onCreateViewHolder(parent, viewType); + } + + @Override + public boolean isItemSwipeAble(int position) { + StationDetailItem item = getItem(position); + if (item == null) { + return false; + } + return !StationDetailItem.ITEM_TYPE_KNOWN_POINT_GROUP1.equals(item.getType()) && + !StationDetailItem.ITEM_TYPE_UN_KNOWN_POINT_GROUP.equals(item.getType()) && + !StationDetailItem.ITEM_TYPE_KNOWN_POINT_GROUP2.equals(item.getType()); + } + + @Override + public boolean isItemDragAble(int position) { + StationDetailItem item = getItem(position); + if (item == null) { + return false; + } + return !StationDetailItem.ITEM_TYPE_KNOWN_POINT_GROUP1.equals(item.getType()) && + !StationDetailItem.ITEM_TYPE_UN_KNOWN_POINT_GROUP.equals(item.getType()) && + !StationDetailItem.ITEM_TYPE_KNOWN_POINT_GROUP2.equals(item.getType()); + } + + public interface IOnSelectPointDelegate { + void onSelectKnownPoint1(PickPointResult pickPointResult, ArrayList filters); + + void onSelectUnknownPoint(PickPointResult pickPointResult, ArrayList filters); + + void onSelectKnownPoint2(PickPointResult pickPointResult, ArrayList filters); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/stationdetail/StationCreateLineSingleAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/stationdetail/StationCreateLineSingleAdapter.java new file mode 100644 index 0000000..3d057a8 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/stationdetail/StationCreateLineSingleAdapter.java @@ -0,0 +1,238 @@ +package com.bingce.controlnetwork.adapter.stationdetail; + +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.model.PickPointResult; +import com.bingce.controlapphelper.model.StationDetailItem; +import com.bingce.controlapphelper.model.ViewItemType; +import com.bingce.controlnetwork.ui.vh.DraggableTextViewHolder; +import com.bingce.controlnetwork.ui.vh.StationGroupItemViewHolder; +import com.bingce.controlnetwork.ui.widget.recyclerview.AbstractDraggableRecycleViewAdapter; + +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +/** + * 支导线创建 + */ +public class StationCreateLineSingleAdapter extends AbstractDraggableRecycleViewAdapter { + private final IOnSelectPointDelegate selectPointCallback; + + public StationCreateLineSingleAdapter(IOnSelectPointDelegate selectPointCallback, + List items) { + super(items); + this.selectPointCallback = selectPointCallback; + } + + public void setKnownPoints(List ids, List names) { + if (ids == null || names == null || ids.size() != names.size()) { + return; + } + //先移除之前known point + List knownItems = knownItems(); + for (StationDetailItem item : knownItems) { + remove(item); + } + //添加新的known point + for (int index = 0; index < ids.size(); index++) { + insert( + 1 + index, + new StationDetailItem( + names.get(index), + StationDetailItem.ITEM_TYPE_KNOWN_POINT_ITEM, + ids.get(index))); + } + //通知变化 + if (knownItems.size() == ids.size()) { + notifyItemRangeChanged(1, ids.size()); + } else { + notifyItemRangeChanged(1, getItemCount() - 1); + } + } + + public void setUnknownPoints(List ids, List names) { + List items = new ArrayList<>(); + for (int index = 0; index < ids.size(); index++) { + StationDetailItem item = new StationDetailItem( + names.get(index), StationDetailItem.ITEM_TYPE_UN_KNOWN_POINT_ITEM, ids.get(index)); + items.add(item); + } + + int index = -1; + for (int i = 0; i < getItemCount(); i++) { + StationDetailItem item = getItem(i); + if (item == null || !StationDetailItem.ITEM_TYPE_UN_KNOWN_POINT_GROUP.equals(item.getType())) { + continue; + } + index = i; + break; + } + if (index > 0) { + replace(index + 1, items); + notifyItemRangeChanged(index + 1, items.size()); + } + } + + public List knownItems() { + List items = new ArrayList<>(); + for (int index = 1; index < getItemCount(); index++) { + StationDetailItem obj = getItem(index); + if (obj == null || !StationDetailItem.ITEM_TYPE_KNOWN_POINT_ITEM.equals(obj.getType())) { + break; + } + items.add(obj); + } + return items; + } + + public List unknownItems() { + List items = new ArrayList<>(); + for (int index = 1; index < getItemCount(); index++) { + StationDetailItem obj = getItem(index); + if (obj == null || !StationDetailItem.ITEM_TYPE_UN_KNOWN_POINT_ITEM.equals(obj.getType())) { + continue; + } + items.add(obj); + } + return items; + } + + @Override + protected void bindItem(StationDetailItem item, RecyclerView.ViewHolder viewHolder) { + if (viewHolder instanceof DraggableTextViewHolder) { + DraggableTextViewHolder draggableTextViewHolder = (DraggableTextViewHolder) viewHolder; + DraggableTextViewHolder.update(draggableTextViewHolder, item, true); + } else if (viewHolder instanceof StationGroupItemViewHolder) { + StationGroupItemViewHolder surveyorStationSetupGroupParentViewHolder = ((StationGroupItemViewHolder) viewHolder); + StationGroupItemViewHolder.update( + surveyorStationSetupGroupParentViewHolder, + item, + true, + (itemType, surveyorStationSetupGroupParentViewHolder1) -> { + if (StationDetailItem.ITEM_TYPE_KNOWN_POINT_GROUP.equals(item.getType())) { + View.OnClickListener listener = v -> { + if (selectPointCallback != null) { + //收集信息 + PickPointResult pickPointResult = new PickPointResult(); + for (StationDetailItem obj : knownItems()) { + pickPointResult.getSelectedIds().add(obj.getOriginalPointId()); + pickPointResult.getSelectedNames().add(obj.getName()); + } + ArrayList filters = new ArrayList<>(); + for (int index = 2; index < getItemCount(); index++) { + StationDetailItem obj = getItem(index); + if (obj == null) { + continue; + } + if (StationDetailItem.ITEM_TYPE_UN_KNOWN_POINT_ITEM.equals(obj.getType())) { + filters.add(obj.getOriginalPointId()); + } + } + selectPointCallback.onSelectKnownPoint(pickPointResult, filters); + } + }; + surveyorStationSetupGroupParentViewHolder1.pick.setOnClickListener(listener); + surveyorStationSetupGroupParentViewHolder1.switchView.setOnClickListener(listener); + + List knownItems = knownItems(); + if (knownItems.isEmpty()) { + surveyorStationSetupGroupParentViewHolder1.pick.setVisibility(View.VISIBLE); + surveyorStationSetupGroupParentViewHolder1.switchView.setVisibility(View.INVISIBLE); + } else { + surveyorStationSetupGroupParentViewHolder1.pick.setVisibility(View.INVISIBLE); + surveyorStationSetupGroupParentViewHolder1.switchView.setVisibility(View.VISIBLE); + } + } else if (StationDetailItem.ITEM_TYPE_UN_KNOWN_POINT_GROUP.equals(item.getType())) { + surveyorStationSetupGroupParentViewHolder1.pick.setOnClickListener(v -> { + if (selectPointCallback != null) { + //收集信息 + PickPointResult pickPointResult = new PickPointResult(); + for (int index = 2; index < getItemCount(); index++) { + StationDetailItem o = getItem(index); + if (o == null) { + continue; + } + if (StationDetailItem.ITEM_TYPE_UN_KNOWN_POINT_ITEM.equals(o.getType())) { + pickPointResult.getSelectedIds().add(o.getOriginalPointId()); + pickPointResult.getSelectedNames().add(o.getName()); + } + } + ArrayList filters = new ArrayList<>(); + for (StationDetailItem obj : knownItems()) { + if (obj == null) { + continue; + } + filters.add(obj.getOriginalPointId()); + } + selectPointCallback.onSelectUnknownPoint(pickPointResult, filters); + } + }); + } + }); + } + } + + private static final int ITEM_TYPE_KNOWN_POINT = 11; + private static final int ITEM_TYPE_UNKNOWN_POINT = ITEM_TYPE_KNOWN_POINT + 1; + + @Override + public int getItemViewType(int position) { + StationDetailItem item = getItem(position); + if (item == null) { + return -1; + } + if (StationDetailItem.ITEM_TYPE_KNOWN_POINT_GROUP.equals(item.getType()) || + StationDetailItem.ITEM_TYPE_UN_KNOWN_POINT_GROUP.equals(item.getType())) { + return ViewItemType.surveyorStationCreateStationGroupItem.ordinal(); + } + if (StationDetailItem.ITEM_TYPE_KNOWN_POINT_ITEM.equals(item.getType())) { + return ITEM_TYPE_KNOWN_POINT; + } + if (StationDetailItem.ITEM_TYPE_UN_KNOWN_POINT_ITEM.equals(item.getType())) { + return ITEM_TYPE_UNKNOWN_POINT; + } + return super.getItemViewType(position); + } + + @NonNull + @NotNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull @NotNull ViewGroup parent, int viewType) { + if (ITEM_TYPE_KNOWN_POINT == viewType || ITEM_TYPE_UNKNOWN_POINT == viewType) { + return super.onCreateViewHolder(parent, ViewItemType.draggableItem.ordinal()); + } + return super.onCreateViewHolder(parent, viewType); + } + + @Override + public boolean isItemSwipeAble(int position) { + StationDetailItem item = getItem(position); + if (item == null) { + return false; + } + return !StationDetailItem.ITEM_TYPE_KNOWN_POINT_GROUP.equals(item.getType()) && + !StationDetailItem.ITEM_TYPE_UN_KNOWN_POINT_GROUP.equals(item.getType()); + } + + @Override + public boolean isItemDragAble(int position) { + StationDetailItem item = getItem(position); + if (item == null) { + return false; + } + return !StationDetailItem.ITEM_TYPE_KNOWN_POINT_GROUP.equals(item.getType()) && + !StationDetailItem.ITEM_TYPE_UN_KNOWN_POINT_GROUP.equals(item.getType()); + } + + public interface IOnSelectPointDelegate { + void onSelectKnownPoint(PickPointResult pickPointResult, ArrayList filters); + + void onSelectUnknownPoint(PickPointResult pickPointResult, ArrayList filters); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/stationdetail/StationCreateLineWellAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/stationdetail/StationCreateLineWellAdapter.java new file mode 100644 index 0000000..a6cbffa --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/stationdetail/StationCreateLineWellAdapter.java @@ -0,0 +1,301 @@ +package com.bingce.controlnetwork.adapter.stationdetail; + +import android.text.TextUtils; +import android.view.View; + +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.model.PickPointResult; +import com.bingce.controlapphelper.model.StationDetailItem; +import com.bingce.controlapphelper.model.ViewItemType; +import com.bingce.controlnetwork.ui.vh.ItemWellViewHolder; +import com.bingce.controlnetwork.ui.vh.StationGroupItemViewHolder; +import com.bingce.controlnetwork.ui.widget.recyclerview.AbstractDraggableRecycleViewAdapter; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 一井定向-创建站选点的适配器 + */ +public class StationCreateLineWellAdapter extends AbstractDraggableRecycleViewAdapter { + private final IOnSelectPointDelegate selectPointCallback; + + private final Map groupPositionMap = new HashMap<>(); + private final Map lastSelectMap = new HashMap<>(); + + public StationCreateLineWellAdapter(IOnSelectPointDelegate selectPointCallback, + List items) { + super(items); + for (int i = 0; i < items.size(); i++) { + groupPositionMap.put(items.get(i).getType(), i); + } + this.selectPointCallback = selectPointCallback; + } + + /** + * 设置地面连接方向点数据 + */ + public void setGroundLinkPoints(PickPointResult pickPointResult) { + setPointsData(pickPointResult, StationDetailItem.ITEM_TYPE_WELL_GROUP_GROUND_LINK, + StationDetailItem.ITEM_TYPE_WELL_GROUP_GROUND_LINK + StationDetailItem._DATA); + } + + private void setPointsData(PickPointResult pickPointResult, String groupType, String dataType) { + if (pickPointResult == null || pickPointResult.getSelectedIds() == null + || pickPointResult.getSelectedNames() == null + || pickPointResult.getSelectedIds().size() != pickPointResult.getSelectedNames().size()) { + return; + } + //记录选择的 + lastSelectMap.put(groupType, pickPointResult); + + List pointsOld = getPointsFromType(dataType); + removeAll(pointsOld); + + List newList = new ArrayList<>(); + for (int index = 0; index < pickPointResult.getSelectedIds().size(); index++) { + newList.add(new StationDetailItem( + pickPointResult.getSelectedNames().get(index), + dataType, + pickPointResult.getSelectedIds().get(index))); + } + + int insertPosition = groupPositionMap.get(groupType); + insertForWell(insertPosition + 1, newList); + + updateGroupPositionMap(); + + notifyItemRangeChanged(0, getItemCount()); + + } + + /** + * 更新group的基准位置 + */ + private void updateGroupPositionMap() { + for (int i = 0; i < getItemCount(); i++) { + String type = getItem(i).getType(); + if (type.equals(StationDetailItem.ITEM_TYPE_WELL_GROUP_GROUND_LINK) + || type.equals(StationDetailItem.ITEM_TYPE_WELL_GROUP_GROUND_SIDE) + || type.equals(StationDetailItem.ITEM_TYPE_WELL_GROUP_STEEL_WIRE) + || type.equals(StationDetailItem.ITEM_TYPE_WELL_GROUP_UNDERGROUND_SIDE) + || type.equals(StationDetailItem.ITEM_TYPE_WELL_GROUP_UNDERGROUND_LINK)) { + groupPositionMap.put(type, i); + } + } + } + + /** + * 设置地面近井点数据 + */ + public void setGroundSidePoints(PickPointResult pickPointResult) { + setPointsData(pickPointResult, StationDetailItem.ITEM_TYPE_WELL_GROUP_GROUND_SIDE, + StationDetailItem.ITEM_TYPE_WELL_GROUP_GROUND_SIDE + StationDetailItem._DATA); + } + + /** + * 设置钢丝点数据 + */ + public void setSteelWirePoints(PickPointResult pickPointResult) { + setPointsData(pickPointResult, StationDetailItem.ITEM_TYPE_WELL_GROUP_STEEL_WIRE, + StationDetailItem.ITEM_TYPE_WELL_GROUP_STEEL_WIRE + StationDetailItem._DATA); + } + + /** + * 设置地下近井点数据 + */ + public void setUndergroudSidePoints(PickPointResult pickPointResult) { + setPointsData(pickPointResult, StationDetailItem.ITEM_TYPE_WELL_GROUP_UNDERGROUND_SIDE, + StationDetailItem.ITEM_TYPE_WELL_GROUP_UNDERGROUND_SIDE + StationDetailItem._DATA); + } + + /** + * 设置地下连接方向点数据 + */ + public void setUndergroudLinkPoints(PickPointResult pickPointResult) { + setPointsData(pickPointResult, StationDetailItem.ITEM_TYPE_WELL_GROUP_UNDERGROUND_LINK, + StationDetailItem.ITEM_TYPE_WELL_GROUP_UNDERGROUND_LINK + StationDetailItem._DATA); + } + + + public List getPointsFromType(String dataType) { + List items = new ArrayList<>(); + for (int index = 1; index < getItemCount(); index++) { + StationDetailItem obj = getItem(index); + if (obj == null || !dataType.equals(obj.getType())) { + continue; + } + + if (dataType.contains(StationDetailItem.ITEM_TYPE_WELL_GROUP_STEEL_WIRE)) { + obj.setWellSteel(true); + } + + items.add(obj); + } + return items; + } + + @Override + protected void bindItem(StationDetailItem item, RecyclerView.ViewHolder viewHolder) { + if (viewHolder instanceof ItemWellViewHolder) { + ItemWellViewHolder itemWellViewHolder = (ItemWellViewHolder) viewHolder; + ItemWellViewHolder.update(itemWellViewHolder, item, true, (itemType, itemWellViewHolderBack) -> { +// itemWellViewHolder.switchCompat.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { +// @Override +// public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { +// item.setWellSteel(isChecked); +// if (selectPointCallback != null) { +// selectPointCallback.onSelectOnlyMeasureHorAngle(isChecked); +// } +// } +// }); + }); + } else if (viewHolder instanceof StationGroupItemViewHolder) { + StationGroupItemViewHolder stationGroupItemViewHolder = ((StationGroupItemViewHolder) viewHolder); + + StationGroupItemViewHolder.update( + stationGroupItemViewHolder, + item, + true, + (itemType, stationGroupItemViewHolderBack) -> { + stationGroupItemViewHolder.pick.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + backToData(itemType, stationGroupItemViewHolderBack); + } + }); + }); + } + } + + @Override + public int getItemViewType(int position) { + StationDetailItem item = getItem(position); + if (item == null) { + return -1; + } + if (StationDetailItem.ITEM_TYPE_WELL_GROUP_GROUND_LINK.equals(item.getType()) || + StationDetailItem.ITEM_TYPE_WELL_GROUP_GROUND_SIDE.equals(item.getType()) || + StationDetailItem.ITEM_TYPE_WELL_GROUP_STEEL_WIRE.equals(item.getType()) || + StationDetailItem.ITEM_TYPE_WELL_GROUP_UNDERGROUND_SIDE.equals(item.getType()) || + StationDetailItem.ITEM_TYPE_WELL_GROUP_UNDERGROUND_LINK.equals(item.getType())) { + return ViewItemType.surveyorStationCreateStationGroupItem.ordinal(); + } else { + return ViewItemType.wellItem.ordinal(); + } + } + + @Override + public boolean isItemSwipeAble(int position) { + StationDetailItem item = getItem(position); + if (item == null) { + return false; + } + return !StationDetailItem.ITEM_TYPE_WELL_GROUP_GROUND_LINK.equals(item.getType()) && + !StationDetailItem.ITEM_TYPE_WELL_GROUP_GROUND_SIDE.equals(item.getType()) && + !StationDetailItem.ITEM_TYPE_WELL_GROUP_STEEL_WIRE.equals(item.getType()) + && !StationDetailItem.ITEM_TYPE_WELL_GROUP_UNDERGROUND_SIDE.equals(item.getType()) + && !StationDetailItem.ITEM_TYPE_WELL_GROUP_UNDERGROUND_LINK.equals(item.getType()); + } + + @Override + public boolean isItemDragAble(int position) { + StationDetailItem item = getItem(position); + if (item == null) { + return false; + } + return !StationDetailItem.ITEM_TYPE_WELL_GROUP_GROUND_LINK.equals(item.getType()) && + !StationDetailItem.ITEM_TYPE_WELL_GROUP_GROUND_SIDE.equals(item.getType()) && + !StationDetailItem.ITEM_TYPE_WELL_GROUP_STEEL_WIRE.equals(item.getType()) + && !StationDetailItem.ITEM_TYPE_WELL_GROUP_UNDERGROUND_SIDE.equals(item.getType()) + && !StationDetailItem.ITEM_TYPE_WELL_GROUP_UNDERGROUND_LINK.equals(item.getType()); + } + + + public void removeItemForLastSelect(int adapterPosition) { + StationDetailItem item = getItem(adapterPosition); + assert item != null; + String groupType = item.getType().replaceAll(StationDetailItem._DATA, ""); + PickPointResult pickPointResult = lastSelectMap.get(groupType); + if (pickPointResult != null && !pickPointResult.getSelectedIds().isEmpty()) { + int index = pickPointResult.getSelectedIds().indexOf(item.getOriginalPointId()); + pickPointResult.getSelectedIds().remove(index); + pickPointResult.getSelectedNames().remove(index); + } else { + lastSelectMap.remove(groupType); + } + updateGroupPositionMap(); +// 原先只有这一句 lastSelectMap.put(item.getType().replaceAll(StationDetailItem._DATA, ""), null); + } + + public interface IOnSelectPointDelegate { + void onSelectGroundLink(PickPointResult pickPointResult, List filters); + + void onSelectGroundSide(PickPointResult pickPointResult, List filters); + + void onSelectSteelWire(PickPointResult pickPointResult, List filters); + + void onSelectUndergroundSide(PickPointResult pickPointResult, List filters); + + void onSelectUndergroundLink(PickPointResult pickPointResult, List filters); + +// void onSelectOnlyMeasureHorAngle(boolean measureHorAngle); + } + + /** + * 返回数据给上一级 + * + * @param itemType + * @param holder + */ + private void backToData(String itemType, StationGroupItemViewHolder holder) { + if (selectPointCallback == null) { + return; + } + + PickPointResult pickPointResult = lastSelectMap.get(itemType); + + List filterIds = getFilterIds(pickPointResult); + + switch (itemType) { + case StationDetailItem.ITEM_TYPE_WELL_GROUP_GROUND_LINK: + selectPointCallback.onSelectGroundLink(pickPointResult, filterIds); + break; + case StationDetailItem.ITEM_TYPE_WELL_GROUP_GROUND_SIDE: + selectPointCallback.onSelectGroundSide(pickPointResult, filterIds); + break; + case StationDetailItem.ITEM_TYPE_WELL_GROUP_STEEL_WIRE: + selectPointCallback.onSelectSteelWire(pickPointResult, filterIds); + break; + case StationDetailItem.ITEM_TYPE_WELL_GROUP_UNDERGROUND_SIDE: + selectPointCallback.onSelectUndergroundSide(pickPointResult, filterIds); + break; + case StationDetailItem.ITEM_TYPE_WELL_GROUP_UNDERGROUND_LINK: + selectPointCallback.onSelectUndergroundLink(pickPointResult, filterIds); + break; + } + } + + private List getFilterIds(PickPointResult pickPointResult) { + List filterIds = new ArrayList<>(); + for (int i = 0; i < getItemCount(); i++) { + StationDetailItem item = getItem(i); + String pointId = item.getOriginalPointId(); + + if (!TextUtils.isEmpty(pointId)) { + if (pickPointResult == null) { + filterIds.add(pointId); + } else { + if (!pickPointResult.getSelectedIds().contains(pointId)) { + filterIds.add(pointId); + } + } + } + } + return filterIds; + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/stationdetail/StationCreateLineWellDoubleGroundAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/stationdetail/StationCreateLineWellDoubleGroundAdapter.java new file mode 100644 index 0000000..9cfea74 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/stationdetail/StationCreateLineWellDoubleGroundAdapter.java @@ -0,0 +1,296 @@ +package com.bingce.controlnetwork.adapter.stationdetail; + +import android.text.TextUtils; +import android.view.View; + +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.model.PickPointResult; +import com.bingce.controlapphelper.model.StationDetailItem; +import com.bingce.controlapphelper.model.ViewItemType; +import com.bingce.controlnetwork.ui.vh.ItemWellViewHolder; +import com.bingce.controlnetwork.ui.vh.StationGroupItemViewHolder; +import com.bingce.controlnetwork.ui.widget.recyclerview.AbstractDraggableRecycleViewAdapter; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 二井定向-地上-创建站选点的适配器 + */ +public class StationCreateLineWellDoubleGroundAdapter extends AbstractDraggableRecycleViewAdapter { + private final IOnSelectPointDelegate selectPointCallback; + + private final Map groupPositionMap = new HashMap<>(); + private final Map lastSelectMap = new HashMap<>(); + + public StationCreateLineWellDoubleGroundAdapter(IOnSelectPointDelegate selectPointCallback, + List items) { + super(items); + for (int i = 0; i < items.size(); i++) { + groupPositionMap.put(items.get(i).getType(), i); + } + this.selectPointCallback = selectPointCallback; + } + + private void setPointsData(PickPointResult pickPointResult, String groupType, String dataType) { + if (pickPointResult == null || pickPointResult.getSelectedIds() == null + || pickPointResult.getSelectedNames() == null + || pickPointResult.getSelectedIds().size() != pickPointResult.getSelectedNames().size()) { + return; + } + //记录选择的 + lastSelectMap.put(groupType, pickPointResult); + + List pointsOld = getPointsFromType(dataType); + removeAll(pointsOld); + + List newList = new ArrayList<>(); + for (int index = 0; index < pickPointResult.getSelectedIds().size(); index++) { + newList.add(new StationDetailItem( + pickPointResult.getSelectedNames().get(index), + dataType, + pickPointResult.getSelectedIds().get(index))); + } + + int insertPosition = groupPositionMap.get(groupType); + insertForWell(insertPosition + 1, newList); + + updateGroupPositionMap(); + + notifyItemRangeChanged(0, getItemCount()); + + } + + /** + * 更新group的基准位置 + */ + private void updateGroupPositionMap() { + for (int i = 0; i < getItemCount(); i++) { + String type = getItem(i).getType(); + if (type.equals(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_LEFT) + || type.equals(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_MIDDLE) + || type.equals(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_RIGHT) + || type.equals(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_A) + || type.equals(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_B)) { + groupPositionMap.put(type, i); + } + } + } + + /** + * 设置地面连接点 左 + */ + public void setGroundLinkLeftPoints(PickPointResult pickPointResult) { + setPointsData(pickPointResult, StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_LEFT, + StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_LEFT + StationDetailItem._DATA); + } + + /** + * 设置地面连接点 右 + */ + public void setGroundLinkRightPoints(PickPointResult pickPointResult) { + setPointsData(pickPointResult, StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_RIGHT, + StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_RIGHT + StationDetailItem._DATA); + } + + /** + * 设置地面连接点 中 + */ + public void setGroundLinkMiddlePoints(PickPointResult pickPointResult) { + setPointsData(pickPointResult, StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_MIDDLE, + StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_MIDDLE + StationDetailItem._DATA); + } + + /** + * 设置地面近井点 A + */ + public void setGroundSideAPoints(PickPointResult pickPointResult) { + setPointsData(pickPointResult, StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_A, + StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_A + StationDetailItem._DATA); + } + + + /** + * 设置地面近井点 B + */ + public void setGroundSideBPoints(PickPointResult pickPointResult) { + setPointsData(pickPointResult, StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_B, + StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_B + StationDetailItem._DATA); + } + + + public List getPointsFromType(String dataType) { + List items = new ArrayList<>(); + for (int index = 1; index < getItemCount(); index++) { + StationDetailItem obj = getItem(index); + if (obj == null || !dataType.equals(obj.getType())) { + continue; + } + items.add(obj); + } + return items; + } + + @Override + protected void bindItem(StationDetailItem item, RecyclerView.ViewHolder viewHolder) { + if (viewHolder instanceof ItemWellViewHolder) { + ItemWellViewHolder itemWellViewHolder = (ItemWellViewHolder) viewHolder; + ItemWellViewHolder.update(itemWellViewHolder, item, true, (itemType, itemWellViewHolderBack) -> { +// itemWellViewHolder.switchCompat.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { +// @Override +// public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { +// item.setWellSteel(isChecked); +// if (selectPointCallback!=null) { +// selectPointCallback.onSelectOnlyMeasureHorAngle(isChecked); +// } +// } +// }); + }); + } else if (viewHolder instanceof StationGroupItemViewHolder) { + StationGroupItemViewHolder stationGroupItemViewHolder = ((StationGroupItemViewHolder) viewHolder); + + StationGroupItemViewHolder.update( + stationGroupItemViewHolder, + item, + true, + (itemType, stationGroupItemViewHolderBack) -> { + stationGroupItemViewHolder.pick.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + backToData(itemType, stationGroupItemViewHolderBack); + } + }); + }); + } + } + + @Override + public int getItemViewType(int position) { + StationDetailItem item = getItem(position); + if (item == null) { + return -1; + } + if (StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_LEFT.equals(item.getType()) || + StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_MIDDLE.equals(item.getType()) || + StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_RIGHT.equals(item.getType()) || + StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_A.equals(item.getType()) || + StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_B.equals(item.getType())) { + return ViewItemType.surveyorStationCreateStationGroupItem.ordinal(); + } else { + return ViewItemType.wellItem.ordinal(); + } + } + + @Override + public boolean isItemSwipeAble(int position) { + StationDetailItem item = getItem(position); + if (item == null) { + return false; + } + return !StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_LEFT.equals(item.getType()) && + !StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_MIDDLE.equals(item.getType()) && + !StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_RIGHT.equals(item.getType()) + && !StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_A.equals(item.getType()) + && !StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_B.equals(item.getType()); + } + + @Override + public boolean isItemDragAble(int position) { + StationDetailItem item = getItem(position); + if (item == null) { + return false; + } + return !StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_LEFT.equals(item.getType()) && + !StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_MIDDLE.equals(item.getType()) && + !StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_RIGHT.equals(item.getType()) + && !StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_A.equals(item.getType()) + && !StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_B.equals(item.getType()); + } + + public void removeItemForLastSelect(int adapterPosition) { + StationDetailItem item = getItem(adapterPosition); + assert item != null; + String groupType = item.getType().replaceAll(StationDetailItem._DATA, ""); + PickPointResult pickPointResult = lastSelectMap.get(groupType); + if (pickPointResult != null && !pickPointResult.getSelectedIds().isEmpty()) { + int index = pickPointResult.getSelectedIds().indexOf(item.getOriginalPointId()); + pickPointResult.getSelectedIds().remove(index); + pickPointResult.getSelectedNames().remove(index); + } else { + lastSelectMap.remove(groupType); + } + updateGroupPositionMap(); + } + + public interface IOnSelectPointDelegate { + void onSelectGroundLinkLeft(PickPointResult pickPointResult, List filters); + + void onSelectGroundLinkRight(PickPointResult pickPointResult, List filters); + + void onSelectGroundLinkMiddle(PickPointResult pickPointResult, List filters); + + void onSelectGroundSideA(PickPointResult pickPointResult, List filters); + + void onSelectGroundSideB(PickPointResult pickPointResult, List filters); + + void onSelectOnlyMeasureHorAngle(boolean measureHorAngle); + + } + + /** + * 返回数据给上一级 + * + * @param itemType + * @param holder + */ + private void backToData(String itemType, StationGroupItemViewHolder holder) { + if (selectPointCallback == null) { + return; + } + + PickPointResult pickPointResult = lastSelectMap.get(itemType); + + List filterIds = getFilterIds(pickPointResult); + + switch (itemType) { + case StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_LEFT: + selectPointCallback.onSelectGroundLinkLeft(pickPointResult, filterIds); + break; + case StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_MIDDLE: + selectPointCallback.onSelectGroundLinkMiddle(pickPointResult, filterIds); + break; + case StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_RIGHT: + selectPointCallback.onSelectGroundLinkRight(pickPointResult, filterIds); + break; + case StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_A: + selectPointCallback.onSelectGroundSideA(pickPointResult, filterIds); + break; + case StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_B: + selectPointCallback.onSelectGroundSideB(pickPointResult, filterIds); + break; + } + } + + private List getFilterIds(PickPointResult pickPointResult) { + List filterIds = new ArrayList<>(); + for (int i = 0; i < getItemCount(); i++) { + StationDetailItem item = getItem(i); + String pointId = item.getOriginalPointId(); + + if (!TextUtils.isEmpty(pointId)) { + if (pickPointResult == null) { + filterIds.add(pointId); + } else { + if (!pickPointResult.getSelectedIds().contains(pointId)) { + filterIds.add(pointId); + } + } + } + } + return filterIds; + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/adapter/stationdetail/StationCreateLineWellDoubleUnderGroundAdapter.java b/app/src/main/java/com/bingce/controlnetwork/adapter/stationdetail/StationCreateLineWellDoubleUnderGroundAdapter.java new file mode 100644 index 0000000..68a8174 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/adapter/stationdetail/StationCreateLineWellDoubleUnderGroundAdapter.java @@ -0,0 +1,331 @@ +package com.bingce.controlnetwork.adapter.stationdetail; + +import android.os.Handler; +import android.text.TextUtils; +import android.view.View; + +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.model.PickPointResult; +import com.bingce.controlapphelper.model.StationDetailItem; +import com.bingce.controlapphelper.model.ViewItemType; +import com.bingce.controlnetwork.ui.vh.ItemWellViewHolder; +import com.bingce.controlnetwork.ui.vh.StationGroupItemViewHolder; +import com.bingce.controlnetwork.ui.widget.recyclerview.AbstractDraggableRecycleViewAdapter; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 二井定向-地下-创建站选点的适配器 + */ +public class StationCreateLineWellDoubleUnderGroundAdapter extends AbstractDraggableRecycleViewAdapter { + private final IOnSelectPointDelegate selectPointCallback; + + private final Map groupPositionMap = new HashMap<>(); + private final Map lastSelectMap = new HashMap<>(); + + public StationCreateLineWellDoubleUnderGroundAdapter(IOnSelectPointDelegate selectPointCallback, + List items) { + super(items); + for (int i = 0; i < items.size(); i++) { + groupPositionMap.put(items.get(i).getType(), i); + } + this.selectPointCallback = selectPointCallback; + } + + private void setPointsData(PickPointResult pickPointResult, String groupType, String dataType) { + if (pickPointResult == null || pickPointResult.getSelectedIds() == null + || pickPointResult.getSelectedNames() == null + || pickPointResult.getSelectedIds().size() != pickPointResult.getSelectedNames().size()) { + return; + } + //记录选择的 + lastSelectMap.put(groupType, pickPointResult); + + List pointsOld = getPointsFromType(dataType); + removeAll(pointsOld); + + List newList = new ArrayList<>(); + for (int index = 0; index < pickPointResult.getSelectedIds().size(); index++) { + newList.add(new StationDetailItem( + pickPointResult.getSelectedNames().get(index), + dataType, + pickPointResult.getSelectedIds().get(index))); + } + + int insertPosition = groupPositionMap.get(groupType); + insertForWell(insertPosition + 1, newList); + updateGroupPositionMap(); + notifyItemRangeChanged(0, getItemCount()); + } + + /** + * 更新group的基准位置 + */ + private void updateGroupPositionMap() { + for (int i = 0; i < getItemCount(); i++) { + String type = getItem(i).getType(); + if (type.equals(StationDetailItem.TYPE_WELL_DOUBLE_STEEL_A) + || type.equals(StationDetailItem.TYPE_WELL_DOUBLE_STEEL_B) + || type.equals(StationDetailItem.TYPE_WELL_DOUBLE_UNDERGROUND_LINK) + || type.equals(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_LEFT) + || type.equals(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_RIGHT) + || type.equals(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_A) + || type.equals(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_B)) { + groupPositionMap.put(type, i); + } + } + } + + /** + * 设置地面连接点 左 + */ + public void setGroundLinkLeftPoints(PickPointResult pickPointResult) { + setPointsData(pickPointResult, StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_LEFT, + StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_LEFT + StationDetailItem._DATA); + } + + /** + * 设置地面连接点 右 + */ + public void setGroundLinkRightPoints(PickPointResult pickPointResult) { + setPointsData(pickPointResult, StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_RIGHT, + StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_RIGHT + StationDetailItem._DATA); + } + + /** + * 设置地面近井点 A + */ + public void setGroundSideAPoints(PickPointResult pickPointResult) { + setPointsData(pickPointResult, StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_A, + StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_A + StationDetailItem._DATA); + } + + + /** + * 设置地面近井点 B + */ + public void setGroundSideBPoints(PickPointResult pickPointResult) { + setPointsData(pickPointResult, StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_B, + StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_B + StationDetailItem._DATA); + } + + /** + * 设置钢丝A + */ + public void setSteelAPoints(PickPointResult pickPointResult) { + setPointsData(pickPointResult, StationDetailItem.TYPE_WELL_DOUBLE_STEEL_A, + StationDetailItem.TYPE_WELL_DOUBLE_STEEL_A + StationDetailItem._DATA); + } + + /** + * 设置钢丝B + */ + public void setSteelBPoints(PickPointResult pickPointResult) { + setPointsData(pickPointResult, StationDetailItem.TYPE_WELL_DOUBLE_STEEL_B, + StationDetailItem.TYPE_WELL_DOUBLE_STEEL_B + StationDetailItem._DATA); + } + + /** + * 设置地下连接方向 + */ + public void setUnderGroundLinkPoints(PickPointResult pickPointResult) { + setPointsData(pickPointResult, StationDetailItem.TYPE_WELL_DOUBLE_UNDERGROUND_LINK, + StationDetailItem.TYPE_WELL_DOUBLE_UNDERGROUND_LINK + StationDetailItem._DATA); + } + + + public List getPointsFromType(String dataType) { + List items = new ArrayList<>(); + for (int index = 1; index < getItemCount(); index++) { + StationDetailItem obj = getItem(index); + if (obj == null || !dataType.equals(obj.getType())) { + continue; + } + + if (dataType.contains(StationDetailItem.ITEM_TYPE_WELL_GROUP_STEEL_WIRE)) { + //注意是contains + obj.setWellSteel(true); + } + + items.add(obj); + } + return items; + } + + @Override + protected void bindItem(StationDetailItem item, RecyclerView.ViewHolder viewHolder) { + if (viewHolder instanceof ItemWellViewHolder) { + ItemWellViewHolder itemWellViewHolder = (ItemWellViewHolder) viewHolder; + ItemWellViewHolder.update(itemWellViewHolder, item, true, (itemType, itemWellViewHolderBack) -> { +// itemWellViewHolder.switchCompat.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { +// @Override +// public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { +// item.setWellSteel(isChecked); +// if (selectPointCallback != null) { +// selectPointCallback.onSelectOnlyMeasureHorAngle(isChecked); +// } +// } +// }); + }); + } else if (viewHolder instanceof StationGroupItemViewHolder) { + StationGroupItemViewHolder stationGroupItemViewHolder = ((StationGroupItemViewHolder) viewHolder); + + StationGroupItemViewHolder.update( + stationGroupItemViewHolder, + item, + true, + (itemType, stationGroupItemViewHolderBack) -> { + stationGroupItemViewHolder.pick.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + backToData(itemType, stationGroupItemViewHolderBack); + } + }); + }); + } + } + + @Override + public int getItemViewType(int position) { + StationDetailItem item = getItem(position); + if (item == null) { + return -1; + } + if (StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_LEFT.equals(item.getType()) || + StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_RIGHT.equals(item.getType()) || + StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_A.equals(item.getType()) || + StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_B.equals(item.getType()) || + StationDetailItem.TYPE_WELL_DOUBLE_STEEL_A.equals(item.getType()) || + StationDetailItem.TYPE_WELL_DOUBLE_STEEL_B.equals(item.getType()) || + StationDetailItem.TYPE_WELL_DOUBLE_UNDERGROUND_LINK.equals(item.getType()) + ) { + return ViewItemType.surveyorStationCreateStationGroupItem.ordinal(); + } else { + return ViewItemType.wellItem.ordinal(); + } + } + + @Override + public boolean isItemSwipeAble(int position) { + return isItemSwipeAbleOrItemDragAble(position); + } + + @Override + public boolean isItemDragAble(int position) { + return isItemSwipeAbleOrItemDragAble(position); + } + + private boolean isItemSwipeAbleOrItemDragAble(int position) { + StationDetailItem item = getItem(position); + if (item == null) { + return false; + } + return !StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_LEFT.equals(item.getType()) + && !StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_RIGHT.equals(item.getType()) + && !StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_A.equals(item.getType()) + && !StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_B.equals(item.getType()) + && !StationDetailItem.TYPE_WELL_DOUBLE_STEEL_A.equals(item.getType()) + && !StationDetailItem.TYPE_WELL_DOUBLE_STEEL_B.equals(item.getType()) + && !StationDetailItem.TYPE_WELL_DOUBLE_UNDERGROUND_LINK.equals(item.getType()); + } + + public void removeItemForLastSelect(int adapterPosition) { + StationDetailItem item = getItem(adapterPosition); + assert item != null; + String groupType = item.getType().replaceAll(StationDetailItem._DATA, ""); + PickPointResult pickPointResult = lastSelectMap.get(groupType); + if (pickPointResult != null && !pickPointResult.getSelectedIds().isEmpty()) { + int index = pickPointResult.getSelectedIds().indexOf(item.getOriginalPointId()); + pickPointResult.getSelectedIds().remove(index); + pickPointResult.getSelectedNames().remove(index); + } else { + lastSelectMap.remove(groupType); + } + //延迟更新groupType的位置 + new Handler().postDelayed(() -> updateGroupPositionMap(), 300); + } + + public interface IOnSelectPointDelegate { + void onSelectGroundLinkLeft(PickPointResult pickPointResult, List filters); + + void onSelectGroundLinkRight(PickPointResult pickPointResult, List filters); + + void onSelectGroundSideA(PickPointResult pickPointResult, List filters); + + void onSelectGroundSideB(PickPointResult pickPointResult, List filters); + + void onSelectSteelA(PickPointResult pickPointResult, List filters); + + void onSelectSteelB(PickPointResult pickPointResult, List filters); + + void onSelectUnderGroundLink(PickPointResult pickPointResult, List filters); + + void onSelectOnlyMeasureHorAngle(boolean measureHorAngle); + + } + + /** + * 返回数据给上一级 + * + * @param itemType + * @param holder + */ + private void backToData(String itemType, StationGroupItemViewHolder holder) { + if (selectPointCallback == null) { + return; + } + + PickPointResult pickPointResult = lastSelectMap.get(itemType); + + List filterIds = getFilterIds(pickPointResult); + + switch (itemType) { + case StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_LEFT: + selectPointCallback.onSelectGroundLinkLeft(pickPointResult, filterIds); + break; + case StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_RIGHT: + selectPointCallback.onSelectGroundLinkRight(pickPointResult, filterIds); + break; + case StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_A: + selectPointCallback.onSelectGroundSideA(pickPointResult, filterIds); + break; + case StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_B: + selectPointCallback.onSelectGroundSideB(pickPointResult, filterIds); + break; + + case StationDetailItem.TYPE_WELL_DOUBLE_STEEL_A: + selectPointCallback.onSelectSteelA(pickPointResult, filterIds); + break; + case StationDetailItem.TYPE_WELL_DOUBLE_STEEL_B: + selectPointCallback.onSelectSteelB(pickPointResult, filterIds); + break; + case StationDetailItem.TYPE_WELL_DOUBLE_UNDERGROUND_LINK: + selectPointCallback.onSelectUnderGroundLink(pickPointResult, filterIds); + break; + } + } + + private List getFilterIds(PickPointResult pickPointResult) { + List filterIds = new ArrayList<>(); + for (int i = 0; i < getItemCount(); i++) { + StationDetailItem item = getItem(i); + String pointId = item.getOriginalPointId(); + + if (!TextUtils.isEmpty(pointId)) { + if (pickPointResult == null) { + filterIds.add(pointId); + } else { + if (!pickPointResult.getSelectedIds().contains(pointId)) { + filterIds.add(pointId); + } + } + } + } + return filterIds; + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/bean/MainUserBean.java b/app/src/main/java/com/bingce/controlnetwork/bean/MainUserBean.java new file mode 100644 index 0000000..1311f4b --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/bean/MainUserBean.java @@ -0,0 +1,13 @@ +package com.bingce.controlnetwork.bean; + +public class MainUserBean { + public String userName; + public String nickName; + public String avator; + + public MainUserBean(String userName, String nickName, String avator) { + this.userName = userName; + this.nickName = nickName; + this.avator = avator; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/controller/Expression.java b/app/src/main/java/com/bingce/controlnetwork/controller/Expression.java new file mode 100644 index 0000000..d67d350 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/controller/Expression.java @@ -0,0 +1,1008 @@ +/* + * Copyright 2012 Udo Klimaschewski + * + * http://UdoJava.com/ + * http://about.me/udo.klimaschewski + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ +package com.bingce.controlnetwork.controller; + +import java.math.BigDecimal; +import java.math.MathContext; +import java.math.RoundingMode; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Stack; + +/** + *

EvalEx - Java Expression Evaluator

+ *

+ *

Introduction

+ * EvalEx is a handy expression evaluator for Java, that allows to evaluate simple mathematical and boolean expressions. + *
+ * Key Features: + *
    + *
  • Uses BigDecimal for calculation and result
  • + *
  • Single class implementation, very compact
  • + *
  • No dependencies to external libraries
  • + *
  • Precision and rounding mode can be set
  • + *
  • Supports variables
  • + *
  • Standard boolean and mathematical operators
  • + *
  • Standard basic mathematical and boolean functions
  • + *
  • Custom functions and operators can be added at runtime
  • + *
+ *
+ *

Examples

+ *
+ *  BigDecimal result = null;
+ *
+ *  Expression expression = new Expression("1+1/3");
+ *  result = expression.eval():
+ *  expression.setPrecision(2);
+ *  result = expression.eval():
+ *
+ *  result = new Expression("(3.4 + -4.1)/2").eval();
+ *
+ *  result = new Expression("SQRT(a^2 + b^2").with("a","2.4").and("b","9.253").eval();
+ *
+ *  BigDecimal a = new BigDecimal("2.4");
+ *  BigDecimal b = new BigDecimal("9.235");
+ *  result = new Expression("SQRT(a^2 + b^2").with("a",a).and("b",b).eval();
+ *
+ *  result = new Expression("2.4/PI").setPrecision(128).setRoundingMode(RoundingMode.UP).eval();
+ *
+ *  result = new Expression("random() > 0.5").eval();
+ *
+ *  result = new Expression("not(x<7 || sqrt(max(x,9)) <= 3))").with("x","22.9").eval();
+ * 
+ *
+ *

Supported Operators

+ * + * + * + * + * + * + * + * + * + *
Mathematical Operators
OperatorDescription
+Additive operator
-Subtraction operator
*Multiplication operator
/Division operator
%Remainder operator (Modulo)
^Power operator
+ *
+ * + * + * + * + * + * + * + * + * + * + * + * + * + *
Boolean Operators*
OperatorDescription
=Equals
==Equals
!=Not equals
<>Not equals
<Less than
<=Less than or equal to
>Greater than
>=Greater than or equal to
&&Boolean and
||Boolean or
+ * *Boolean operators result always in a BigDecimal value of 1 or 0 (zero). Any non-zero value is treated as a _true_ value. Boolean _not_ is implemented by a function. + *
+ *

Supported Functions

+ * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Function*Description
NOT(expression)Boolean negation, 1 (means true) if the expression is not zero
RANDOM()Produces a random number between 0 and 1
MIN(e1,e2)Returns the smaller of both expressions
MAX(e1,e2)Returns the bigger of both expressions
ABS(expression)Returns the absolute (non-negative) value of the expression
ROUND(expression,precision)Rounds a value to a certain number of digits, uses the current rounding mode
LOG(expression)Returns the natural logarithm (base e) of an expression
SQRT(expression)Returns the square root of an expression
SIN(expression)Returns the trigonometric sine of an angle (in degrees)
COS(expression)Returns the trigonometric cosine of an angle (in degrees)
TAN(expression)Returns the trigonometric tangens of an angle (in degrees)
SINH(expression)Returns the hyperbolic sine of a value
COSH(expression)Returns the hyperbolic cosine of a value
TANH(expression)Returns the hyperbolic tangens of a value
RAD(expression)Converts an angle measured in degrees to an approximately equivalent angle measured in radians
DEG(expression)Converts an angle measured in radians to an approximately equivalent angle measured in degrees
+ * *Functions names are case insensitive. + *
+ *

Supported Constants

+ * + * + * + *
ConstantDescription
PIThe value of PI, exact to 100 digits
+ *

+ *

Add Custom Operators

+ *

+ * Custom operators can be added easily, simply create an instance of `Expression.Operator` and add it to the expression. + * Parameters are the operator string, its precedence and if it is left associative. The operators `eval()` method will be called with the BigDecimal values of the operands. + * All existing operators can also be overridden. + *
+ * For example, add an operator `x >> n`, that moves the decimal point of _x_ _n_ digits to the right: + *

+ *

+ * Expression e = new Expression("2.1234 >> 2");
+ *
+ * e.addOperator(e.new Operator(">>", 30, true) {
+ *     {@literal @}Override
+ *     public BigDecimal eval(BigDecimal v1, BigDecimal v2) {
+ *         return v1.movePointRight(v2.toBigInteger().intValue());
+ *     }
+ * });
+ *
+ * e.eval(); // returns 212.34
+ * 
+ *
+ *

Add Custom Functions

+ *

+ * Adding custom functions is as easy as adding custom operators. Create an instance of `Expression.Function`and add it to the expression. + * Parameters are the function name and the count of required parameters. The functions `eval()` method will be called with a list of the BigDecimal parameters. + * All existing functions can also be overridden. + *
+ * For example, add a function `average(a,b,c)`, that will calculate the average value of a, b and c: + *
+ *

+ * Expression e = new Expression("2 * average(12,4,8)");
+ *
+ * e.addFunction(e.new Function("average", 3) {
+ *     {@literal @}Override
+ *     public BigDecimal eval(List parameters) {
+ *         BigDecimal sum = parameters.get(0).add(parameters.get(1)).add(parameters.get(2));
+ *         return sum.divide(new BigDecimal(3));
+ *     }
+ * });
+ *
+ * e.eval(); // returns 16
+ * 
+ * The software is licensed under the MIT Open Source license (see LICENSE file). + *
+ *
    + *
  • The *power of* operator (^) implementation was copied from [Stack Overflow](http://stackoverflow.com/questions/3579779/how-to-do-a-fractional-power-on-bigdecimal-in-java) Thanks to Gene Marin
  • + *
  • The SQRT() function implementation was taken from the book [The Java Programmers Guide To numerical Computing](http://www.amazon.de/Java-Number-Cruncher-Programmers-Numerical/dp/0130460419) (Ronald Mak, 2002)
  • + *
+ * + * @author Udo Klimaschewski (http://about.me/udo.klimaschewski) + */ +public class Expression { + + /** + * Definition of PI as a constant, can be used in expressions as variable. + */ + public static final BigDecimal PI = new BigDecimal( + "3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679"); + + /** + * The {@link MathContext} to use for calculations. + */ + private MathContext mc = MathContext.DECIMAL32; + + /** + * The original infix expression. + */ + private String expression = null; + + /** + * The cached RPN (Reverse Polish Notation) of the expression. + */ + private List rpn = null; + + /** + * All defined operators with name and implementation. + */ + private final Map operators = new HashMap(); + + /** + * All defined functions with name and implementation. + */ + private final Map functions = new HashMap(); + + /** + * All defined variables with name and value. + */ + private final Map variables = new HashMap(); + + /** + * What character to use for decimal separators. + */ + private final char decimalSeparator = '.'; + + /** + * What character to use for minus sign (negative values). + */ + private final char minusSign = '-'; + + /** + * The expression evaluators exception class. + */ + public class ExpressionException extends RuntimeException { + private static final long serialVersionUID = 1118142866870779047L; + + public ExpressionException(String message) { + super(message); + } + } + + /** + * Abstract definition of a supported expression function. A function is + * defined by a name, the number of parameters and the actual processing + * implementation. + */ + public abstract class Function { + /** + * Name of this function. + */ + private final String name; + /** + * Number of parameters expected for this function. + */ + private final int numParams; + + /** + * Creates a new function with given name and parameter count. + * + * @param name The name of the function. + * @param numParams The number of parameters for this function. + */ + public Function(String name, int numParams) { + this.name = name.toUpperCase(); + this.numParams = numParams; + } + + public String getName() { + return name; + } + + public int getNumParams() { + return numParams; + } + + /** + * Implementation for this function. + * + * @param parameters Parameters will be passed by the expression evaluator as a + * {@link List} of {@link BigDecimal} values. + * @return The function must return a new {@link BigDecimal} value as a + * computing result. + */ + public abstract BigDecimal eval(List parameters); + } + + /** + * Abstract definition of a supported operator. An operator is defined by + * its name (pattern), precedence and if it is left- or right associative. + */ + public abstract class Operator { + /** + * This operators name (pattern). + */ + private final String oper; + /** + * Operators precedence. + */ + private final int precedence; + /** + * Operator is left associative. + */ + private final boolean leftAssoc; + + /** + * Creates a new operator. + * + * @param oper The operator name (pattern). + * @param precedence The operators precedence. + * @param leftAssoc true if the operator is left associative, + * else false. + */ + public Operator(String oper, int precedence, boolean leftAssoc) { + this.oper = oper; + this.precedence = precedence; + this.leftAssoc = leftAssoc; + } + + public String getOper() { + return oper; + } + + public int getPrecedence() { + return precedence; + } + + public boolean isLeftAssoc() { + return leftAssoc; + } + + /** + * Implementation for this operator. + * + * @param v1 Operand 1. + * @param v2 Operand 2. + * @return The result of the operation. + */ + public abstract BigDecimal eval(BigDecimal v1, BigDecimal v2); + } + + /** + * Expression tokenizer that allows to iterate over a {@link String} + * expression token by token. Blank characters will be skipped. + */ + private class Tokenizer implements Iterator { + + /** + * Actual position in expression string. + */ + private int pos = 0; + /** + * The original input expression. + */ + private final String input; + /** + * The previous token or null if none. + */ + private String previousToken; + + /** + * Creates a new tokenizer for an expression. + * + * @param input The expression string. + */ + public Tokenizer(String input) { + this.input = input; + } + + @Override + public boolean hasNext() { + return (pos < input.length()); + } + + /** + * Peek at the next character, without advancing the iterator. + * + * @return The next character or character 0, if at end of string. + */ + private char peekNextChar() { + if (pos < (input.length() - 1)) { + return input.charAt(pos + 1); + } else { + return 0; + } + } + + @Override + public String next() { + StringBuilder token = new StringBuilder(); + if (pos >= input.length()) { + return previousToken = null; + } + char ch = input.charAt(pos); + while (Character.isWhitespace(ch) && pos < input.length()) { + ch = input.charAt(++pos); + } + if (Character.isDigit(ch)) { + while ((Character.isDigit(ch) || ch == decimalSeparator) + && (pos < input.length())) { + token.append(input.charAt(pos++)); + ch = pos == input.length() ? 0 : input.charAt(pos); + } + } else if (ch == minusSign + && Character.isDigit(peekNextChar()) + && ("(".equals(previousToken) || ",".equals(previousToken) + || previousToken == null || operators + .containsKey(previousToken))) { + token.append(minusSign); + pos++; + token.append(next()); + } else if (Character.isLetter(ch)) { + while ((Character.isLetter(ch) || Character.isDigit(ch) || (ch == '_')) && (pos < input.length())) { + token.append(input.charAt(pos++)); + ch = pos == input.length() ? 0 : input.charAt(pos); + } + } else if (ch == '(' || ch == ')' || ch == ',') { + token.append(ch); + pos++; + } else { + while (!Character.isLetter(ch) && !Character.isDigit(ch) + && !Character.isWhitespace(ch) && ch != '(' + && ch != ')' && ch != ',' && (pos < input.length())) { + token.append(input.charAt(pos)); + pos++; + ch = pos == input.length() ? 0 : input.charAt(pos); + if (ch == minusSign) { + break; + } + } + if (!operators.containsKey(token.toString())) { + throw new ExpressionException("Unknown operator '" + token + + "' at position " + (pos - token.length() + 1)); + } + } + return previousToken = token.toString(); + } + + @Override + public void remove() { + throw new ExpressionException("remove() not supported"); + } + + } + + /** + * Creates a new expression instance from an expression string. + * + * @param expression The expression. E.g. "2.4*sin(3)/(2-4)" or + * "sin(y)>0 & max(z, 3)>3" + */ + public Expression(String expression) { + this.expression = expression; + addOperator(new Operator("+", 20, true) { + @Override + public BigDecimal eval(BigDecimal v1, BigDecimal v2) { + return v1.add(v2, mc); + } + }); + addOperator(new Operator("-", 20, true) { + @Override + public BigDecimal eval(BigDecimal v1, BigDecimal v2) { + return v1.subtract(v2, mc); + } + }); + addOperator(new Operator("*", 30, true) { + @Override + public BigDecimal eval(BigDecimal v1, BigDecimal v2) { + return v1.multiply(v2, mc); + } + }); + /*addOperator(new Operator("/", 30, true) { + @Override + public BigDecimal eval(BigDecimal v1, BigDecimal v2) { + return v1.divide(v2, mc); + } + });*/ + addOperator(new Operator("%", 30, true) { + @Override + public BigDecimal eval(BigDecimal v1, BigDecimal v2) { + return v1.remainder(v2, mc); + } + }); + addOperator(new Operator("^", 40, false) { + @Override + public BigDecimal eval(BigDecimal v1, BigDecimal v2) { + /*- + * Thanks to Gene Marin: + * http://stackoverflow.com/questions/3579779/how-to-do-a-fractional-power-on-bigdecimal-in-java + */ + int signOf2 = v2.signum(); + double dn1 = v1.doubleValue(); + v2 = v2.multiply(new BigDecimal(signOf2)); // n2 is now positive + BigDecimal remainderOf2 = v2.remainder(BigDecimal.ONE); + BigDecimal n2IntPart = v2.subtract(remainderOf2); + BigDecimal intPow = v1.pow(n2IntPart.intValueExact(), mc); + BigDecimal doublePow = BigDecimal.valueOf(Math.pow(dn1, + remainderOf2.doubleValue())); + + BigDecimal result = intPow.multiply(doublePow, mc); + if (signOf2 == -1) { + result = BigDecimal.ONE.divide(result, mc.getPrecision(), + RoundingMode.HALF_UP); + } + return result; + } + }); + addOperator(new Operator("&&", 4, false) { + @Override + public BigDecimal eval(BigDecimal v1, BigDecimal v2) { + boolean b1 = !v1.equals(BigDecimal.ZERO); + boolean b2 = !v2.equals(BigDecimal.ZERO); + return b1 && b2 ? BigDecimal.ONE : BigDecimal.ZERO; + } + }); + + addOperator(new Operator("||", 2, false) { + @Override + public BigDecimal eval(BigDecimal v1, BigDecimal v2) { + boolean b1 = !v1.equals(BigDecimal.ZERO); + boolean b2 = !v2.equals(BigDecimal.ZERO); + return b1 || b2 ? BigDecimal.ONE : BigDecimal.ZERO; + } + }); + + addOperator(new Operator(">", 10, false) { + @Override + public BigDecimal eval(BigDecimal v1, BigDecimal v2) { + return v1.compareTo(v2) == 1 ? BigDecimal.ONE : BigDecimal.ZERO; + } + }); + + addOperator(new Operator(">=", 10, false) { + @Override + public BigDecimal eval(BigDecimal v1, BigDecimal v2) { + return v1.compareTo(v2) >= 0 ? BigDecimal.ONE : BigDecimal.ZERO; + } + }); + + addOperator(new Operator("<", 10, false) { + @Override + public BigDecimal eval(BigDecimal v1, BigDecimal v2) { + return v1.compareTo(v2) == -1 ? BigDecimal.ONE + : BigDecimal.ZERO; + } + }); + + addOperator(new Operator("<=", 10, false) { + @Override + public BigDecimal eval(BigDecimal v1, BigDecimal v2) { + return v1.compareTo(v2) <= 0 ? BigDecimal.ONE : BigDecimal.ZERO; + } + }); + + addOperator(new Operator("=", 7, false) { + @Override + public BigDecimal eval(BigDecimal v1, BigDecimal v2) { + return v1.compareTo(v2) == 0 ? BigDecimal.ONE : BigDecimal.ZERO; + } + }); + addOperator(new Operator("==", 7, false) { + @Override + public BigDecimal eval(BigDecimal v1, BigDecimal v2) { + return operators.get("=").eval(v1, v2); + } + }); + + addOperator(new Operator("!=", 7, false) { + @Override + public BigDecimal eval(BigDecimal v1, BigDecimal v2) { + return v1.compareTo(v2) != 0 ? BigDecimal.ONE : BigDecimal.ZERO; + } + }); + addOperator(new Operator("<>", 7, false) { + @Override + public BigDecimal eval(BigDecimal v1, BigDecimal v2) { + return operators.get("!=").eval(v1, v2); + } + }); + + addFunction(new Function("NOT", 1) { + @Override + public BigDecimal eval(List parameters) { + boolean zero = parameters.get(0).compareTo(BigDecimal.ZERO) == 0; + return zero ? BigDecimal.ONE : BigDecimal.ZERO; + } + }); + + addFunction(new Function("RANDOM", 0) { + @Override + public BigDecimal eval(List parameters) { + double d = Math.random(); + return new BigDecimal(d, mc); + } + }); + /*addFunction(new Function("SIN", 1) { + @Override + public BigDecimal eval(List parameters) { + double d = Math.sin(Math.toRadians(parameters.get(0) + .doubleValue())); + return new BigDecimal(d, mc); + } + }); + addFunction(new Function("COS", 1) { + @Override + public BigDecimal eval(List parameters) { + double d = Math.cos(Math.toRadians(parameters.get(0) + .doubleValue())); + return new BigDecimal(d, mc); + } + }); + addFunction(new Function("TAN", 1) { + @Override + public BigDecimal eval(List parameters) { + double d = Math.tan(Math.toRadians(parameters.get(0) + .doubleValue())); + return new BigDecimal(d, mc); + } + });*/ + addFunction(new Function("SINH", 1) { + @Override + public BigDecimal eval(List parameters) { + double d = Math.sinh(parameters.get(0).doubleValue()); + return new BigDecimal(d, mc); + } + }); + addFunction(new Function("COSH", 1) { + @Override + public BigDecimal eval(List parameters) { + double d = Math.cosh(parameters.get(0).doubleValue()); + return new BigDecimal(d, mc); + } + }); + addFunction(new Function("TANH", 1) { + @Override + public BigDecimal eval(List parameters) { + double d = Math.tanh(parameters.get(0).doubleValue()); + return new BigDecimal(d, mc); + } + }); + addFunction(new Function("RAD", 1) { + @Override + public BigDecimal eval(List parameters) { + double d = Math.toRadians(parameters.get(0).doubleValue()); + return new BigDecimal(d, mc); + } + }); + addFunction(new Function("DEG", 1) { + @Override + public BigDecimal eval(List parameters) { + double d = Math.toDegrees(parameters.get(0).doubleValue()); + return new BigDecimal(d, mc); + } + }); + addFunction(new Function("MAX", 2) { + @Override + public BigDecimal eval(List parameters) { + BigDecimal v1 = parameters.get(0); + BigDecimal v2 = parameters.get(1); + return v1.compareTo(v2) > 0 ? v1 : v2; + } + }); + addFunction(new Function("MIN", 2) { + @Override + public BigDecimal eval(List parameters) { + BigDecimal v1 = parameters.get(0); + BigDecimal v2 = parameters.get(1); + return v1.compareTo(v2) < 0 ? v1 : v2; + } + }); + addFunction(new Function("ABS", 1) { + @Override + public BigDecimal eval(List parameters) { + return parameters.get(0).abs(mc); + } + }); + addFunction(new Function("LOG", 1) { + @Override + public BigDecimal eval(List parameters) { + double d = Math.log(parameters.get(0).doubleValue()); + return new BigDecimal(d, mc); + } + }); + addFunction(new Function("ROUND", 2) { + @Override + public BigDecimal eval(List parameters) { + BigDecimal toRound = parameters.get(1); + int precision = parameters.get(0).intValue(); + return toRound.setScale(precision, mc.getRoundingMode()); + } + }); + /*addFunction(new Function("SQRT", 1) { + @Override + public BigDecimal eval(List parameters) { + /* + * From The Java Programmers Guide To numerical Computing + * (Ronald Mak, 2003) + */ + /*BigDecimal x = parameters.get(0); + if (x.compareTo(BigDecimal.ZERO) == 0) { + return new BigDecimal(0); + } + if (x.signum() < 0) { + throw new ExpressionException( + "Argument to SQRT() function must not be negative"); + } + BigInteger n = x.movePointRight(mc.getPrecision() << 1) + .toBigInteger(); + + int bits = (n.bitLength() + 1) >> 1; + BigInteger ix = n.shiftRight(bits); + BigInteger ixPrev; + + do { + ixPrev = ix; + ix = ix.add(n.divide(ix)).shiftRight(1); + // Give other threads a chance to work; + Thread.yield(); + } while (ix.compareTo(ixPrev) != 0); + + return new BigDecimal(ix, mc.getPrecision()); + } + });*/ + + variables.put("PI", PI); + + } + + /** + * Is the string a number? + * + * @param st The string. + * @return true, if the input string is a number. + */ + private boolean isNumber(String st) { + if (st.charAt(0) == minusSign && st.length() == 1) + return false; + for (char ch : st.toCharArray()) { + if (!Character.isDigit(ch) && ch != minusSign + && ch != decimalSeparator) + return false; + } + return true; + } + + /** + * Implementation of the Shunting Yard algorithm to transform an + * infix expression to a RPN expression. + * + * @param expression The input expression in infx. + * @return A RPN representation of the expression, with each token as a list + * member. + */ + private List shuntingYard(String expression) { + List outputQueue = new ArrayList(); + Stack stack = new Stack(); + + Tokenizer tokenizer = new Tokenizer(expression); + + String lastFunction = null; + while (tokenizer.hasNext()) { + String token = tokenizer.next(); + if (isNumber(token)) { + outputQueue.add(token); + } else if (variables.containsKey(token)) { + outputQueue.add(variables.get(token).toPlainString()); + } else if (functions.containsKey(token.toUpperCase())) { + stack.push(token); + lastFunction = token; + } else if (Character.isLetter(token.charAt(0))) { + stack.push(token); + } else if (",".equals(token)) { + while (!stack.isEmpty() && !"(".equals(stack.peek())) { + outputQueue.add(stack.pop()); + } + if (stack.isEmpty()) { + throw new ExpressionException("Parse error for function '" + + lastFunction + "'"); + } + } else if (operators.containsKey(token)) { + Operator o1 = operators.get(token); + String token2 = stack.isEmpty() ? null : stack.peek(); + while (operators.containsKey(token2) + && ((o1.isLeftAssoc() && o1.getPrecedence() <= operators + .get(token2).getPrecedence()) || (o1 + .getPrecedence() < operators.get(token2) + .getPrecedence()))) { + outputQueue.add(stack.pop()); + token2 = stack.isEmpty() ? null : stack.peek(); + } + stack.push(token); + } else if ("(".equals(token)) { + stack.push(token); + } else if (")".equals(token)) { + while (!stack.isEmpty() && !"(".equals(stack.peek())) { + outputQueue.add(stack.pop()); + } + if (stack.isEmpty()) { + throw new RuntimeException("Mismatched parentheses"); + } + stack.pop(); + if (!stack.isEmpty() + && functions.containsKey(stack.peek().toUpperCase())) { + outputQueue.add(stack.pop()); + } + } + } + while (!stack.isEmpty()) { + String element = stack.pop(); + if ("(".equals(element) || ")".equals(element)) { + throw new RuntimeException("Mismatched parentheses"); + } + if (!operators.containsKey(element)) { + throw new RuntimeException("Unknown operator or function: " + + element); + } + outputQueue.add(element); + } + return outputQueue; + } + + /** + * Evaluates the expression. + * + * @return The result of the expression. + */ + public BigDecimal eval() { + + Stack stack = new Stack(); + + for (String token : getRPN()) { + if (operators.containsKey(token)) { + BigDecimal v1 = stack.pop(); + BigDecimal v2 = stack.pop(); + stack.push(operators.get(token).eval(v2, v1)); + } else if (functions.containsKey(token.toUpperCase())) { + Function f = functions.get(token.toUpperCase()); + ArrayList p = new ArrayList( + f.getNumParams()); + for (int i = 0; i < f.numParams; i++) { + p.add(stack.pop()); + } + BigDecimal fResult = f.eval(p); + stack.push(fResult); + } else { + stack.push(new BigDecimal(token, mc)); + } + } + return stack.pop().stripTrailingZeros(); + } + + /** + * Sets the precision for expression evaluation. + * + * @param precision The new precision. + * @return The expression, allows to chain methods. + */ + public Expression setPrecision(int precision) { + this.mc = new MathContext(precision); + return this; + } + + /** + * Sets the rounding mode for expression evaluation. + * + * @param roundingMode The new rounding mode. + * @return The expression, allows to chain methods. + */ + public Expression setRoundingMode(RoundingMode roundingMode) { + this.mc = new MathContext(mc.getPrecision(), roundingMode); + return this; + } + + /** + * Adds an operator to the list of supported operators. + * + * @param operator The operator to add. + * @return The previous operator with that name, or null if + * there was none. + */ + public Operator addOperator(Operator operator) { + return operators.put(operator.getOper(), operator); + } + + /** + * Adds a function to the list of supported functions + * + * @param function The function to add. + * @return The previous operator with that name, or null if + * there was none. + */ + public Function addFunction(Function function) { + return functions.put(function.getName(), function); + } + + /** + * Sets a variable value. + * + * @param variable The variable name. + * @param value The variable value. + * @return The expression, allows to chain methods. + */ + public Expression setVariable(String variable, BigDecimal value) { + variables.put(variable, value); + return this; + } + + /** + * Sets a variable value. + * + * @param variable The variable to set. + * @param value The variable value. + * @return The expression, allows to chain methods. + */ + public Expression setVariable(String variable, String value) { + variables.put(variable, new BigDecimal(value)); + return this; + } + + /** + * Sets a variable value. + * + * @param variable The variable to set. + * @param value The variable value. + * @return The expression, allows to chain methods. + */ + public Expression with(String variable, BigDecimal value) { + return setVariable(variable, value); + } + + /** + * Sets a variable value. + * + * @param variable The variable to set. + * @param value The variable value. + * @return The expression, allows to chain methods. + */ + public Expression and(String variable, String value) { + return setVariable(variable, value); + } + + /** + * Sets a variable value. + * + * @param variable The variable to set. + * @param value The variable value. + * @return The expression, allows to chain methods. + */ + public Expression and(String variable, BigDecimal value) { + return setVariable(variable, value); + } + + /** + * Sets a variable value. + * + * @param variable The variable to set. + * @param value The variable value. + * @return The expression, allows to chain methods. + */ + public Expression with(String variable, String value) { + return setVariable(variable, value); + } + + /** + * Get an iterator for this expression, allows iterating over an expression + * token by token. + * + * @return A new iterator instance for this expression. + */ + public Iterator getExpressionTokenizer() { + return new Tokenizer(this.expression); + } + + /** + * Cached access to the RPN notation of this expression, ensures only one + * calculation of the RPN per expression instance. If no cached instance + * exists, a new one will be created and put to the cache. + * + * @return The cached RPN instance. + */ + private List getRPN() { + if (rpn == null) { + rpn = shuntingYard(this.expression); + } + return rpn; + } + + /** + * Get a string representation of the RPN (Reverse Polish Notation) for this + * expression. + * + * @return A string with the RPN representation for this expression. + */ + public String toRPN() { + String result = ""; + for (String st : getRPN()) { + result = "".equals(result) ? result : result + " "; + result += st; + //System.out.println("Watch out this is only possible with api 9+"); + } + return result; + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/controller/KeyEventAction.java b/app/src/main/java/com/bingce/controlnetwork/controller/KeyEventAction.java new file mode 100644 index 0000000..c36e96b --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/controller/KeyEventAction.java @@ -0,0 +1,12 @@ +package com.bingce.controlnetwork.controller; + +public class KeyEventAction { + public final static String NONE = "0"; + public final static String CAL = "1"; + public final static String SURVEY = "2"; + public final static String RECORD = "3"; + public final static String LAST = "4"; + public final static String NEXT = "5"; + public final static String SURVEY_NO_SEND = "6"; + public final static String SURVEY_AND_RECORD = "7"; +} diff --git a/app/src/main/java/com/bingce/controlnetwork/event/RefreshEvent.java b/app/src/main/java/com/bingce/controlnetwork/event/RefreshEvent.java new file mode 100644 index 0000000..b8204fc --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/event/RefreshEvent.java @@ -0,0 +1,21 @@ +package com.bingce.controlnetwork.event; + +public class RefreshEvent { + public static final int REFRESH_BY_LEVEL_I_DETECTION_SETTING_UPDATE = 3; + + private int type; + private T data; + + public RefreshEvent(int type, T data) { + this.type = type; + this.data = data; + } + + public int getType() { + return type; + } + + public T getData() { + return data; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/event/RefreshToleranceTotailEvent.java b/app/src/main/java/com/bingce/controlnetwork/event/RefreshToleranceTotailEvent.java new file mode 100644 index 0000000..b55964f --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/event/RefreshToleranceTotailEvent.java @@ -0,0 +1,4 @@ +package com.bingce.controlnetwork.event; + +public class RefreshToleranceTotailEvent { +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/AbstractFullScreenDialogFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/AbstractFullScreenDialogFragment.java new file mode 100644 index 0000000..dd9c790 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/AbstractFullScreenDialogFragment.java @@ -0,0 +1,125 @@ +package com.bingce.controlnetwork.fragment; + +import android.graphics.drawable.ColorDrawable; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.Window; +import android.view.WindowManager; +import android.widget.FrameLayout; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatDialogFragment; + +import com.bingce.utils.SoftKeyUtils; + +import com.bingce.controlnetwork.R; + +public abstract class AbstractFullScreenDialogFragment extends AppCompatDialogFragment { + + private View viewSpace; + private View confirm; + + @Nullable + @Override + final public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE); + View contentView = inflater.inflate(R.layout.fragment_fullscreen_dialog_layout, container, false); + FrameLayout contentContainer = contentView.findViewById(R.id.content_container); + contentView.setOnClickListener(v -> { + if (quitWhenTouchBg()) { + doDismiss(); + } else { + hideSoft(); + } + }); + + if (getArguments() != null) { + TextView title = contentView.findViewById(R.id.title); + if (title != null) { + String string = getArguments().getString(KEY_TITLE_NAME); + if (string == null || string.isEmpty()) { + title.setVisibility(View.GONE); + } else { + title.setText(string); + } + } + TextView subTitle = contentView.findViewById(R.id.sub_title); + if (subTitle != null) { + String string = getArguments().getString(KEY_SUB_TITLE_NAME); + if (string == null || string.isEmpty()) { + subTitle.setVisibility(View.GONE); + } else { + subTitle.setText(string); + } + } + } + + View cancel = contentView.findViewById(R.id.cancel_button); + if (cancel != null) { + cancel.setOnClickListener(v -> onCancel()); + } + viewSpace = contentView.findViewById(R.id.viewSpace); + confirm = contentView.findViewById(R.id.confirm_button); + if (confirm != null) { + confirm.setOnClickListener(v -> { + hideSoft(); + onConfirm(); + }); + } + + contentContainer.addView(createContentView(inflater, contentContainer, savedInstanceState)); + return contentView; + } + + protected void onCancel() { + doDismiss(); + } + + protected void onConfirm() { + dismiss(); + } + + protected abstract View createContentView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState); + + private void doDismiss() { + hideSoft(); + dismiss(); + } + + private void hideSoft() { + SoftKeyUtils.hideSoftKey(); + } + + protected boolean quitWhenTouchBg() { + return true; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + getDialog().getWindow().setBackgroundDrawable(new ColorDrawable(0x33000000)); + getDialog().getWindow().setLayout( + WindowManager.LayoutParams.MATCH_PARENT, + WindowManager.LayoutParams.MATCH_PARENT); + } + + protected AbstractFullScreenDialogFragment() { + } + + private static final String KEY_SUB_TITLE_NAME = "__ATTRIBUTE__NAME__"; + private static final String KEY_TITLE_NAME = "__GROUP__NAME__"; + + protected static void setArgs(Bundle args, String title, String subTitle) { + args.putString(KEY_SUB_TITLE_NAME, subTitle); + args.putString(KEY_TITLE_NAME, title); + } + + protected void setHideConfirm() { + viewSpace.setVisibility(View.GONE); + confirm.setVisibility(View.GONE); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/AbstractHierarchicalListFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/AbstractHierarchicalListFragment.java new file mode 100644 index 0000000..fc8333b --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/AbstractHierarchicalListFragment.java @@ -0,0 +1,211 @@ +package com.bingce.controlnetwork.fragment; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.animation.Animation; +import android.view.animation.AnimationUtils; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.model.IUniversalListItem; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.adapter.IndexWithTextAdapter; + +import org.jetbrains.annotations.NotNull; + +public abstract class AbstractHierarchicalListFragment extends Fragment { + private View layout1; + private View layout2; + private View back1; + private View back2; + private TextView title1; + private TextView title2; + private RecyclerView recyclerView1; + private RecyclerView recyclerView2; + private boolean is1Layout = true;//通知当前显示的是layout1还是layout2 + private int currentListIndex = 0;//当前显示的list在所有集合中的index + private final IndexWithTextAdapter.IOnItemClick> callback = item -> onItemClicked(currentListIndex, item); + + @Nullable + @org.jetbrains.annotations.Nullable + @Override + public View onCreateView(@NonNull @NotNull LayoutInflater inflater, @Nullable @org.jetbrains.annotations.Nullable ViewGroup container, @Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) { + View root = inflater.inflate(R.layout.fragment_hierarchical_list_layout, container, false); + + layout1 = root.findViewById(R.id.layout1); + if (layout1 != null) { + recyclerView1 = layout1.findViewById(R.id.list1); + } + back1 = root.findViewById(R.id.back1); + if (back1 != null) { + back1.setOnClickListener(v -> onBackClicked(currentListIndex)); + } + title1 = root.findViewById(R.id.title1); + + layout2 = root.findViewById(R.id.layout2); + if (layout2 != null) { + recyclerView2 = layout2.findViewById(R.id.list2); + } + back2 = root.findViewById(R.id.back2); + if (back2 != null) { + back2.setOnClickListener(v -> onBackClicked(currentListIndex)); + } + title2 = root.findViewById(R.id.title2); + + //初始化 + if (layout2 != null) { + layout2.setVisibility(View.GONE); + } + //加载list1 + setupList(0, title1, recyclerView1, callback); + return root; + } + + //执行back + final protected void back2(int listIndex) { + currentListIndex = listIndex; + is1Layout = !is1Layout; + + updateButtonVisibility(); + + doSwitch(layout1, layout2, title1, title2, recyclerView1, recyclerView2, this, + callback, + is1Layout, listIndex, false); + } + + //执行forward + final protected void forward2(int listIndex) { + currentListIndex = listIndex; + is1Layout = !is1Layout; + + updateButtonVisibility(); + + doSwitch(layout1, layout2, title1, title2, recyclerView1, recyclerView2, this, + callback, + is1Layout, listIndex, true); + } + + private void updateButtonVisibility() { + if (is1Layout && back1 != null) { + back1.setVisibility(!isFirstIndex(currentListIndex) ? View.VISIBLE : View.GONE); + } else if (!is1Layout && back2 != null) { + back2.setVisibility(!isFirstIndex(currentListIndex) ? View.VISIBLE : View.GONE); + } + } + + protected boolean isFirstIndex(int index) { + return index == 0; + } + + protected int preIndexOf(int index) { + return index - 1; + } + + final boolean doBack() { + if (currentListIndex > 0) { + back2(preIndexOf(currentListIndex)); + return true; + } + return false; + } + + private static void doSwitch(View layout1, View layout2, TextView title1, TextView title2, + RecyclerView recyclerView1, + RecyclerView recyclerView2, + AbstractHierarchicalListFragment fragment, + final IndexWithTextAdapter.IOnItemClick> callback, + boolean targetLayoutIsLayout1, + int listIndex, + boolean moveForward) { + //先更新界面,再执行动画 + View currentLayout = layout1; + View targetLayout = layout1; + TextView targetTitle = title1; + RecyclerView targetRecycleView = recyclerView1; + + if (targetLayoutIsLayout1) { + currentLayout = layout2; + } else { + targetLayout = layout2; + targetTitle = title2; + targetRecycleView = recyclerView2; + } + + //先设置数据 + fragment.setupList(listIndex, targetTitle, targetRecycleView, callback); + + //执行动画 + Animation outAnimation = AnimationUtils.loadAnimation(fragment.getContext(), + moveForward ? R.anim.slide_out_left : R.anim.slide_out_right); + outAnimation.setFillAfter(true); + View finalCurrentLayout = currentLayout; + outAnimation.setAnimationListener(new Animation.AnimationListener() { + @Override + public void onAnimationStart(Animation animation) { + } + + @Override + public void onAnimationEnd(Animation animation) { + finalCurrentLayout.clearAnimation(); + finalCurrentLayout.setVisibility(View.GONE); + } + + @Override + public void onAnimationRepeat(Animation animation) { + + } + }); + + Animation inAnimation = AnimationUtils.loadAnimation(fragment.getContext(), + moveForward ? R.anim.slide_in_right : R.anim.slide_in_left); + inAnimation.setFillAfter(true); + targetLayout.setVisibility(View.VISIBLE); + + currentLayout.startAnimation(outAnimation); + targetLayout.startAnimation(inAnimation); + } + + //通知child,通知list的item被点击,下一步执行 forward或结束加载 + protected abstract void onItemClicked(int currentListIndex, IUniversalListItem item); + + //通知child,准备back,用于加载数据 + protected abstract void onBackClicked(int currentListIndex); + + //通知child,加载相应list的数据 + protected abstract void setupList(int listIndex, TextView title, RecyclerView recyclerView, + final IndexWithTextAdapter.IOnItemClick> callback); + + protected static class Item implements IUniversalListItem { + private final String name; + private final String id; + + Item(String name, String id) { + this.name = name; + this.id = id; + } + + @Override + public String getName() { + return name; + } + + @Override + public String getId() { + return id; + } + + @Override + public String getValue() { + return id; + } + } + + protected AbstractHierarchicalListFragment() { + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/AbstractProjectToleranceFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/AbstractProjectToleranceFragment.java new file mode 100644 index 0000000..e55b8ea --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/AbstractProjectToleranceFragment.java @@ -0,0 +1,163 @@ +package com.bingce.controlnetwork.fragment; + +import android.content.Context; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.WorkerThread; +import androidx.fragment.app.Fragment; + +import com.bingce.controlapphelper.datasource.database.tolerance.detail.IToleranceDetail; +import com.bingce.controlapphelper.datasource.database.tolerance.group.ToleranceGroupRecord; +import com.bingce.controlapphelper.datasource.database.tolerance.level.ToleranceLevelRecord; +import com.bingce.controlapphelper.datasource.database.tolerance.load.IToleranceOperate; +import com.bingce.controlapphelper.datasource.database.tolerance.load.ToleranceLoadUtil; +import com.bingce.controlapphelper.model.BundleConstants; +import com.bingce.controlapphelper.util.ToleranceUtil; +import com.bingce.controlnetwork.fragment.base.BaseFragment; +import com.bingce.controlnetwork.ui.ViewUtil; +import com.bingce.controlnetwork.ui.widget.TextItemWithMore; +import com.bingce.controlnetwork.util.tolerance.ToleranceOperateUtil; +import com.bingce.utils.IOnSingleGetCallback; +import com.bingce.utils.ThreadPoolUtil; + +import com.bingce.controlnetwork.R; + +/* + * 项目限差详情,包含'LimitDetailFragment'+选择模板 + * */ +public abstract class AbstractProjectToleranceFragment extends BaseFragment { + private String currentToleranceDetailRecordId; + + protected String projectType; + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + if (getArguments() != null) { + projectType = getArguments().getString(BundleConstants.KEY_PROJECT_TYPE); + } + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.fragment_project_limit_detail_layout, container, false); + //设置限差模板选择事件 + registerSelectTemplateCallback(view, () -> ThreadPoolUtil.execute(this::onSelectToleranceTemplateClick)); + //设置详情 + onCreateView(view); + return view; + } + + /** + * 获取新建项目时的默认限差 + * + * @param projectType + */ + protected IToleranceDetail getNewDefaultTolerance(String projectType) { + return ToleranceLoadUtil.getToleranceLoad(projectType).getNewDefaultTolerance(projectType); + } + + protected abstract void onCreateView(View view); + + protected void setCurrentToleranceName(View view, IToleranceDetail toleranceRecord) { + View tv = view.findViewById(R.id.setting_index); + ThreadPoolUtil.execute(() -> { + if (toleranceRecord == null) return; + IToleranceOperate operate = ToleranceOperateUtil.getOperate(toleranceRecord.getId()); + if (operate == null) return; + ToleranceGroupRecord group = operate.getGroup(toleranceRecord); + ToleranceLevelRecord level = operate.getLevel(toleranceRecord); + String name = ToleranceUtil.completedToleranceName(group, level, toleranceRecord); + runOnUI(() -> { + if (tv instanceof TextItemWithMore) { + ((TextItemWithMore) tv).setDescribeText(name); + } + }); + }); + } + + protected void registerSelectTemplateCallback(View view, Runnable runnable) { + ViewUtil.setOnClick(view.findViewById(R.id.setting_index), v -> runnable.run()); + } + + /** + * 限差模板的点击后逻辑 + */ + @WorkerThread + protected void onSelectToleranceTemplateClick() { + IToleranceOperate operate = ToleranceOperateUtil.getOperate(currentToleranceDetailRecordId); + if (operate == null) return; + IToleranceDetail toleranceDetailRecordTj = operate.getIToleranceDetail(currentToleranceDetailRecordId); + if (toleranceDetailRecordTj == null) { + return; + } + + ThreadPoolUtil.executeInMain(() -> + SelectToleranceBottomSheetFragment.select( + getChildFragmentManager(), + getViewLifecycleOwner(), + projectType, + toleranceDetailRecordTj.getGroupId(), + toleranceDetailRecordTj.getLevelId(), + toleranceDetailRecordTj.getId(), + toleranceId -> ThreadPoolUtil.execute(() -> { + //根据toleranceId查找缓存数据 + IToleranceDetail instance = operate.getIToleranceDetail(toleranceId); + //更新页面数据 + updateToleranceDetail(getView(), instance); + //新增 + //这里增加存入数据库 已备杀死app后能获取到限差数据 + operate.saveToleranceDetail(instance); + }) + )); + } + + protected void onCurrentToleranceChanged(String toleranceId) { + currentToleranceDetailRecordId = toleranceId; + } + + protected void newToleranceDetailFragment(Bundle args, IOnSingleGetCallback callback) { + if (callback != null) { + callback.onGet(ToleranceDetailFragment.newInstance(args, false)); + } + } + + @WorkerThread + protected void updateToleranceDetail(View view, IToleranceDetail tolerance) { + if (tolerance == null) { + return; + } + onCurrentToleranceChanged(tolerance.getId()); + runOnUI(() -> { + //设置限差名称 + setCurrentToleranceName(view, tolerance); + //设置限差详情 + Fragment detailFragment = + getParentFragmentManager().findFragmentByTag(AbstractProjectToleranceFragment.class.getName()); + if (detailFragment == null) { + Bundle args = new Bundle(); + if (getArguments() != null) { + args.putString(BundleConstants.KEY_TOLERANCE_ID, tolerance.getId()); + } + newToleranceDetailFragment(args, detailFragmentInstance -> getParentFragmentManager() + .beginTransaction() + .replace(R.id.fragment_container, detailFragmentInstance, AbstractProjectToleranceFragment.class.getName()) + .commit()); + } else { + if (detailFragment instanceof ToleranceDetailFragment) { + ((ToleranceDetailFragment) detailFragment).switchTolerance(tolerance.getId()); + } + } + }); + } + + protected String currentTolerance() { + return currentToleranceDetailRecordId; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/AbstractRecyclerViewFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/AbstractRecyclerViewFragment.java new file mode 100644 index 0000000..b749465 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/AbstractRecyclerViewFragment.java @@ -0,0 +1,33 @@ +package com.bingce.controlnetwork.fragment; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlnetwork.R; + +public abstract class AbstractRecyclerViewFragment extends Fragment { + protected abstract void refreshRecyclerView(RecyclerView recyclerView); + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.fragment_single_list_layout, container, false); + + // Set the adapter + if (view instanceof RecyclerView) { + RecyclerView recyclerView = (RecyclerView) view; + refreshRecyclerView(recyclerView); + } + + setHasOptionsMenu(true); + + return view; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/BaseBottomSheetDialogFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/BaseBottomSheetDialogFragment.java new file mode 100644 index 0000000..8dc5454 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/BaseBottomSheetDialogFragment.java @@ -0,0 +1,12 @@ +package com.bingce.controlnetwork.fragment; + +import com.google.android.material.bottomsheet.BottomSheetDialogFragment; + +public class BaseBottomSheetDialogFragment extends BottomSheetDialogFragment { + final protected void runOnUI(Runnable runnable) { + if (getActivity() == null) { + return; + } + getActivity().runOnUiThread(runnable); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/BottomSheetSelectListFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/BottomSheetSelectListFragment.java new file mode 100644 index 0000000..4eed9fa --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/BottomSheetSelectListFragment.java @@ -0,0 +1,141 @@ +package com.bingce.controlnetwork.fragment; + +import android.content.Context; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.model.UniversalListItem; +import com.bingce.controlapphelper.model.ViewItemType; +import com.bingce.controlnetwork.adapter.SelectableIndexWithTextAdapter; +import com.google.android.material.bottomsheet.BottomSheetDialogFragment; + +import java.util.ArrayList; +import java.util.List; + +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.adapter.SelectableIndexWithTextAdapter; + +/** + * 弹框,用于选择限差模板 + */ +public class BottomSheetSelectListFragment extends BottomSheetDialogFragment { + public static final String TAG = BottomSheetSelectListFragment.class.getName(); + + private BottomSheetSelectListFragment() { + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.fragment_bottom_popup_list_select_layout, + container, false); + // Set the adapter + Context context = view.getContext(); + RecyclerView recyclerView = view.findViewById(R.id.list); + recyclerView.setLayoutManager(new LinearLayoutManager(context)); + + String targetId = null; + List items = new ArrayList<>(); + List indexes = null; + if (getArguments() != null) { + List strings = getArguments().getStringArrayList(KEY_ITEMS); + indexes = getArguments().getStringArrayList(KEY_ENABLE_INDEX); + int defaultIndex = getArguments().getInt(KEY_DEFAULT_ID, -1); + if (strings != null) { + for (int index = 0; index < strings.size(); index++) { + String string = strings.get(index); + Item item = new Item(); + item.setId(String.valueOf(index)); + item.setName(string); + items.add(item); + } + if (defaultIndex < 0 || defaultIndex >= strings.size()) { + if (!items.isEmpty()) { + targetId = items.get(0).getId(); + } + } else { + targetId = items.get(defaultIndex).getId(); + } + } + } + + SelectableIndexWithTextAdapter adapter = + new SelectableIndexWithTextAdapter<>( + targetId, + items, + indexes, + item -> { + Bundle args = new Bundle(); + String id = item.getId(); + int index = Integer.parseInt(id); + args.putInt(KEY_INDEX, index); + args.putString(KEY_STRING, item.getName()); + getParentFragmentManager().setFragmentResult(KEY_REQUEST_SELECT, args); + dismiss(); + }); + recyclerView.setAdapter(adapter); + return view; + } + + private static final String KEY_ITEMS = "__ITEMS__"; + private static final String KEY_INDEX = "__INDEX__"; + private static final String KEY_ENABLE_INDEX = "__ENABLE_INDEX__"; + private static final String KEY_DEFAULT_ID = "__defaultId__"; + private static final String KEY_STRING = "__STRING__"; + private static final String KEY_REQUEST_SELECT = "__SELECT__"; + + public static void showSelect(FragmentManager fragmentManager, + @NonNull LifecycleOwner lifecycleOwner, + int defaultIndex, + ArrayList items, + ArrayList enableIndexes, + IOnSelectCallback callback) { + if (callback == null) { + return; + } + Bundle args = new Bundle(); + args.putStringArrayList(KEY_ITEMS, items); + if (enableIndexes != null && !enableIndexes.isEmpty()) { + args.putStringArrayList(KEY_ENABLE_INDEX, enableIndexes); + } + args.putInt(KEY_DEFAULT_ID, defaultIndex); + BottomSheetSelectListFragment fragment = new BottomSheetSelectListFragment(); + fragment.setArguments(args); + fragmentManager + .setFragmentResultListener(KEY_REQUEST_SELECT, + lifecycleOwner, + (requestKey, result) -> { + if (KEY_REQUEST_SELECT.equals(requestKey)) { + callback.onSelected(result.getInt(KEY_INDEX), result.getString(KEY_STRING)); + } + }); + fragment.show(fragmentManager, TAG); + } + +// public static void showSelect(FragmentManager fragmentManager, +// @NonNull LifecycleOwner lifecycleOwner, +// int defaultIndex, +// ArrayList items, +// IOnSelectCallback callback) { +// showSelect(fragmentManager, lifecycleOwner, defaultIndex, items, null, callback); +// } + + public interface IOnSelectCallback { + void onSelected(int index, String string); + } + + private static class Item extends UniversalListItem { + @Override + public ViewItemType getType() { + return null; + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/BottomSheetSurveyorPeriodFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/BottomSheetSurveyorPeriodFragment.java new file mode 100644 index 0000000..97d3a2a --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/BottomSheetSurveyorPeriodFragment.java @@ -0,0 +1,320 @@ +package com.bingce.controlnetwork.fragment; + +import android.content.Context; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.config.ConfigOperate; +import com.bingce.controlapphelper.datasource.database.line.ILineRecordDataSource; +import com.bingce.controlapphelper.datasource.database.line.LineRecord; +import com.bingce.controlapphelper.datasource.database.surveyorcycle.ISurveyorPeriodDataSource; +import com.bingce.controlapphelper.datasource.database.surveyorcycle.SurveyorPeriodRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.ISurveyorStationDataSource; +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord; +import com.bingce.controlapphelper.model.BundleConstants; +import com.bingce.controlapphelper.util.IUIRunner; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.adapter.SurveyorPeriodAdapter; +import com.bingce.controlnetwork.ui.ViewUtil; +import com.bingce.controlnetwork.util.DefaultNameUtil; +import com.bingce.utils.ThreadPoolUtil; +import com.google.android.material.bottomsheet.BottomSheetDialogFragment; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import blankj.utilcode.util.ToastUtils; + + +/** + * 弹框,用于选择测期 + */ +public class BottomSheetSurveyorPeriodFragment extends BottomSheetDialogFragment implements IUIRunner { + private static final String KEY_TIME_ID = "__TIME_ID"; + public static final String KEY_REQUEST_TIME = "KEY_REQUEST_TIME_ID"; + public static final String KEY_RESULT_NAME = "KEY_RESULT_NAME"; + public static final String KEY_RESULT_ID = "___result__id"; + private SurveyorPeriodAdapter adapter = null; + + private BottomSheetSurveyorPeriodFragment() { + } + + public static void pick(@NonNull FragmentManager fragmentManager, + @NonNull LifecycleOwner lifecycleOwner, + String projectId, String currentCycleId, ICallback callback) { + fragmentManager + .setFragmentResultListener( + KEY_REQUEST_TIME, + lifecycleOwner, + (requestKey, result) -> { + if (KEY_REQUEST_TIME.equals(requestKey)) { + callback.onSelect(result.getString(KEY_RESULT_ID), result.getString(KEY_RESULT_NAME)); + } + }); + BottomSheetDialogFragment fragment = new BottomSheetSurveyorPeriodFragment(); + Bundle args = new Bundle(); + args.putString(KEY_TIME_ID, currentCycleId); + args.putString(BundleConstants.KEY_PROJECT_ID, projectId); + fragment.setArguments(args); + fragment.show(fragmentManager, "time_index"); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.fragment_surveryor_station_number_list, container, false); + RecyclerView recyclerView = view.findViewById(R.id.list); + recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); + String projectId = ""; + String currentCycleId = ""; + if (getArguments() != null) { + projectId = getArguments().getString(BundleConstants.KEY_PROJECT_ID); + currentCycleId = getArguments().getString(KEY_TIME_ID); + } + + adapter = new SurveyorPeriodAdapter(currentCycleId, this); + recyclerView.setAdapter(adapter); + + Helper helper = new Helper(adapter, recyclerView, + view.findViewById(R.id.loading), view.findViewById(R.id.empty_tips), getViewLifecycleOwner()); + + helper.refresh(projectId); + + String finalProjectId = projectId; + ViewUtil.setOnClick( + view.findViewById(R.id.new_item), + v -> createNewCycle(getContext(), getParentFragmentManager(), getChildFragmentManager(), getViewLifecycleOwner(), + adapter, this, finalProjectId)); + return view; + } + + private static void createNewCycle(@Nullable Context context, FragmentManager parentManager, FragmentManager manager, LifecycleOwner lifecycleOwner, + SurveyorPeriodAdapter adapter, IUIRunner runner, String finalProjectId) { + if (context == null) { + return; + } + StringInputFragment.input(manager, + context.getString(R.string.tips_input_new_cycle_name), + DefaultNameUtil.getDefaultPeriodName(), + lifecycleOwner, + string -> { + if (string == null || string.isEmpty()) { + ToastUtils.showShort(R.string.tips_cycle_name_cannt_empty); + } else { + SurveyorPeriodRecord record = + new SurveyorPeriodRecord(finalProjectId, string); + SurveyorDatabaseFactory.instance + .getSurveyorPeriod() + .saveRecord(record); + if (adapter != null) { + adapter.changeCurrentSelect(record.id); + } + //自动切换到新测回 + Bundle args = new Bundle(); + args.putString(BottomSheetSurveyorPeriodFragment.KEY_RESULT_ID, record.getId()); + args.putString(BottomSheetSurveyorPeriodFragment.KEY_RESULT_NAME, record.getName()); + parentManager.setFragmentResult(BottomSheetSurveyorPeriodFragment.KEY_REQUEST_TIME, args); + //询问是否从其他已有测期复制测站列表 + tryCopyStationFromOther(context, manager, lifecycleOwner, record, runner, finalProjectId); + //更新默认测回和测期 + ConfigOperate.changeDefaultProjectAndCycle(finalProjectId, record.id); + + } + }); + } + + private static void tryCopyStationFromOther( + @Nullable Context context, FragmentManager manager, LifecycleOwner lifecycleOwner, + SurveyorPeriodRecord record, IUIRunner runner, String finalProjectId) { + //检测其他测期是否有测站 + ThreadPoolUtil.execute(() -> { + ISurveyorPeriodDataSource surveyorCycleDataSource = + SurveyorDatabaseFactory.instance + .getSurveyorPeriod(); + List cycleRecords = surveyorCycleDataSource.getDataListSyncByProjectId(finalProjectId); + if (cycleRecords == null || cycleRecords.isEmpty()) { + return; + } + List cycleRecordWithStation = new ArrayList<>(); + ISurveyorStationDataSource stationDataSource = + SurveyorDatabaseFactory.instance.getSurveyorStation(); + for (SurveyorPeriodRecord cycleRecord : cycleRecords) { + if (cycleRecord == null) { + continue; + } + + List stationRecordList = stationDataSource.getDataList(finalProjectId, cycleRecord.getId()); + if (stationRecordList == null || stationRecordList.isEmpty()) { + continue; + } + + cycleRecordWithStation.add(cycleRecord); + } + + if (cycleRecordWithStation.isEmpty()) { + return; + } + + ArrayList cycleNameList = new ArrayList<>(); + List cycleIdList = new ArrayList<>(); + for (SurveyorPeriodRecord cycleRecord : cycleRecordWithStation) { + if (cycleRecord == null) { + continue; + } + cycleNameList.add(cycleRecord.getName()); + cycleIdList.add(cycleRecord.getId()); + } + //当前其他测期已有测站,则提示是否拷贝 + runner.runOnUI(() -> { + if (context == null) { + return; + } + TipsWith2OptionFragment.tips(manager, + lifecycleOwner, + context.getString(R.string.confirm_button_copy_station_list), + context.getString(R.string.cancel_button_create_empty_cycle), + context.getString(R.string.tips_should_copy_station_list_from_other_cycle), + new TipsWith2OptionFragment.SimpleCallback() { + @Override + public void onConfirm() { + copyStationListFromOther(context, manager, lifecycleOwner, cycleNameList, cycleIdList, record); + } + }); + }); + }); + } + + private static void copyStationListFromOther( + Context context, FragmentManager manager, LifecycleOwner lifecycleOwner, + ArrayList cycleNameList, List surveyorPeriodIdList, + SurveyorPeriodRecord surveyorPeriodRecord) { + if (surveyorPeriodRecord == null) { + return; + } + ListDialogFragment.showList( + manager, context.getString(R.string.tips_select_cycle_to_copy), + cycleNameList, lifecycleOwner, (index, value) -> { + String surveyorPeriodId = surveyorPeriodIdList.get(index); + String surveyorPeriodRecordId = surveyorPeriodRecord.getId(); + String projectId = surveyorPeriodRecord.getProjectId(); + ISurveyorStationDataSource stationDataSource = + SurveyorDatabaseFactory.instance.getSurveyorStation(); + ILineRecordDataSource lineRecordDataSource = + SurveyorDatabaseFactory.instance.getLineRecordDatabase(); + ThreadPoolUtil.execute(() -> { + List stationRecordList = + stationDataSource.getDataList(projectId, surveyorPeriodId); + if (stationRecordList == null || stationRecordList.isEmpty()) { + return; + } + String lastLineId = "";//当前遍历到的要拷贝的导线id + String newLineId = "";//新建的导线id + List newStations = new ArrayList<>(); + List newLines = new ArrayList<>(); + long date = (new Date()).getTime(); + for (SurveyorStationRecord surveyorStationRecord : stationRecordList) { + if (surveyorStationRecord == null) { + continue; + } + if (surveyorStationRecord.isMulAngleStation()) { + lastLineId = LineRecord.TYPE_MUL_ANGLE; + newLineId = LineRecord.TYPE_MUL_ANGLE; + } else if (SurveyorStationRecord.isLineStation(surveyorStationRecord.getLineId())) { + //拷贝导线 + if (!lastLineId.equals(surveyorStationRecord.getLineId())) { + lastLineId = surveyorStationRecord.getLineId(); + //执行创建导线以及相应测站的逻辑 + LineRecord lineRecord = lineRecordDataSource.findById(lastLineId); + if (lineRecord == null) { + continue; + } + LineRecord newLine = LineRecord.copy(lineRecord, surveyorPeriodRecordId, date++); + newLines.add(newLine); + newLineId = newLine.id; + } + } + //拷贝测站 + newStations.add( + SurveyorStationRecord.copy( + surveyorStationRecord, surveyorPeriodRecordId, newLineId, date++)); + } + //存储测站 + stationDataSource.save(newStations); + //存储导线 + lineRecordDataSource.save(newLines); + }); + }); + } + + public void runOnUI(Runnable runnable) { + if (getActivity() == null) { + return; + } + getActivity().runOnUiThread(runnable); + } + + public interface ICallback { + void onSelect(String id, String name); + } + + public static class Helper { + private final SurveyorPeriodAdapter adapter; + private final View loadingView; + private final View emptyView; + private final RecyclerView recyclerView; + private final LifecycleOwner lifecycleOwner; + + Helper(SurveyorPeriodAdapter adapter, + RecyclerView recyclerView, + View loadingView, + View emptyView, + LifecycleOwner lifecycleOwner) { + this.loadingView = loadingView; + this.emptyView = emptyView; + this.adapter = adapter; + this.recyclerView = recyclerView; + this.lifecycleOwner = lifecycleOwner; + } + + private void update(List projectRecords) { + adapter.updateData(projectRecords); + } + + public void refresh(String projectId) { + ISurveyorPeriodDataSource surveyorCycleDataSource = + SurveyorDatabaseFactory.instance.getSurveyorPeriod(); + surveyorCycleDataSource.getLiveDataListByProjectId(projectId) + .observe(lifecycleOwner, + records -> { + //隐藏loading + if (loadingView != null) { + loadingView.setVisibility(View.GONE); + } + if (records == null || records.isEmpty()) { + if (emptyView != null) { + emptyView.setVisibility(View.VISIBLE); + } + recyclerView.setVisibility(View.GONE); + } else { + //刷新adapter + if (emptyView != null) { + emptyView.setVisibility(View.GONE); + } + recyclerView.setVisibility(View.VISIBLE); + update(records); + } + }); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/ComponentStationSurveyorDataListFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/ComponentStationSurveyorDataListFragment.java new file mode 100644 index 0000000..9c897d9 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/ComponentStationSurveyorDataListFragment.java @@ -0,0 +1,377 @@ +package com.bingce.controlnetwork.fragment; + +import android.content.Context; +import android.os.Bundle; +import android.text.TextUtils; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.WorkerThread; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.project.ProjectRecord; +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord; +import com.bingce.controlapphelper.datasource.database.tolerance.detail.ToleranceDetailRecord; +import com.bingce.controlapphelper.surveyor.data.CachedData; +import com.bingce.controlapphelper.surveyor.data.ICachedData; +import com.bingce.controlapphelper.surveyor.data.IDistanceTypeChangeListener; +import com.bingce.controlapphelper.surveyor.data.SurveyorData; +import com.bingce.controlapphelper.surveyor.state.ISurveyState; +import com.bingce.controlapphelper.surveyor.surveyor.RequestSurveyorParamAuto; +import com.bingce.controlapphelper.util.DigitalUtil; +import com.bingce.controlapphelper.util.IUIRunner; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.adapter.SurveyorStationRecordsAdapter; +import com.bingce.controlnetwork.fragment.base.BaseFragment; +import com.bingce.controlnetwork.surveyor.state.IScrollDelegate; +import com.bingce.controlnetwork.surveyor.state.angledistance.StateManager; +import com.bingce.totalstation.TotalStation; +import com.bingce.utils.ThreadPoolUtil; + +import blankj.utilcode.util.ToastUtils; + +/** + * 测站某个测期的测量数据列表 + */ +public class ComponentStationSurveyorDataListFragment extends BaseFragment + implements IDistanceTypeChangeListener, ISurveyState { + private SurveyorStationRecordsAdapter adapter = null; + private StateManager stateManager; + private RecyclerView recyclerView; + private IDistanceTypeChangeListener cachedDataListener = null; + private IDistanceTypeChangeListener surveyedDataListener = null; + private ISurveyState surveyState; + + private String stationId() { + if (getArguments() == null) { + return null; + } + return getArguments().getString(KEY_STATION_ID); + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, + @Nullable ViewGroup container, + @Nullable Bundle savedInstanceState) { + View view = inflater.inflate( + R.layout.fragment_project_surveyor_station_point_list_layout, + container, + false); + String stationId = stationId(); + recyclerView = view.findViewById(R.id.recycler_view); + if (stationId != null) { + //收集信息 + collectData(stationId, + getContext(), + getChildFragmentManager(), + getViewLifecycleOwner(), + this::runOnUI, + index -> { + if (index >= 0 && adapter != null && index < adapter.getItemCount()) { + recyclerView.scrollToPosition(index); + } + }, + new ICollectCacheCallback() { + @Override + public void onFailure() { + } + + @Override + public void onSuccess( + boolean showSlopDistance, + ICachedData cachedData, + SurveyorData surveyorData, + StateManager stateManager) { + onCollectStationData(showSlopDistance, cachedData, surveyorData, stateManager); + surveyState = stateManager; + } + }); + } + + return view; + } + + @WorkerThread + private void onCollectStationData( + boolean showSlopDistance, + ICachedData cachedData, + SurveyorData surveyorData, + StateManager stateManager) { + this.stateManager = stateManager; + cachedDataListener = cachedData; + surveyedDataListener = surveyorData; + + //测量数据收集完毕后,就可以更新UI了 + runOnUI(() -> { + //刷新UI + if (adapter == null) { + adapter = new SurveyorStationRecordsAdapter(stationId(), cachedData, surveyorData, surveyorData); + adapter.onShowSlopDistance(showSlopDistance); + if (recyclerView != null) { + recyclerView.setAdapter(adapter); + //滚动到当前目标点 + int currentItemIndex = surveyorData.currentIndex(); + if (currentItemIndex >= 0 && currentItemIndex < adapter.getItemCount()) { + recyclerView.scrollToPosition(currentItemIndex); + } + } + } + +// //监听测站数据 +// //监听「平距」「斜距」切换,更新UI显示 +// SurveyorDatabaseFactory +// .instance +// .getSurveyorStation() +// .getLiveDataRecord(stationId()) +// .observe(getViewLifecycleOwner(), +// surveyorStationRecord -> onShowSlopDistance(surveyorStationRecord.isShowSlopDistance())); + }); + } + + /** + * 收集测站信息 + */ + private static void collectData( + String stationId, + Context context, + FragmentManager fragmentManager, + LifecycleOwner lifecycleOwner, + IUIRunner runner, + IScrollDelegate scrollDelegate, + ICollectCacheCallback callback) { + if (callback == null) { + return; + } + boolean isSupportAutoMode = TotalStation.getInstance().isSupportMotor(); + ThreadPoolUtil.execute(() -> { + //读取当前测站的当前测回--很重要 + SurveyorScheduleRecord scheduleRecord = + SurveyorDatabaseFactory + .instance + .getScheduleDataSource() + .findScheduleSync(SurveyorScheduleConstants.getCurrentCycleKey(stationId, null)); + int defaultCycle = scheduleRecord == null ? 0 : + DigitalUtil.valueOfIntString(scheduleRecord.getStatue(), 0); + //加载测站信息 + SurveyorStationRecord surveyorStationRecord = + SurveyorDatabaseFactory + .instance + .getSurveyorStation() + .getRecordSync(stationId); + //加载对应项目 + ProjectRecord projectRecord = SurveyorDatabaseFactory + .instance + .getProjectDataSource() + .getRecord(surveyorStationRecord.getProjectId()); + if (projectRecord == null) { + callback.onFailure(); + return; + } + //加载对应限差 + ToleranceDetailRecord toleranceRecord = SurveyorDatabaseFactory + .instance + .getToleranceDetailDataSource() + .getRecordSync(projectRecord.getToleranceId()); + if (toleranceRecord == null) { + callback.onFailure(); + return; + } + //创建缓存数据 + CachedData cachedData = + CachedData.newInstance(surveyorStationRecord.isAutoClose(), + surveyorStationRecord.isLeftAndRightSurveyor(), + stationId, toleranceRecord); + if (cachedData == null) { + callback.onFailure(); + return; + } + //是否显示斜距? + cachedData.onShowSlopDistance(surveyorStationRecord.isShowSlopDistance()); + if (cachedData.pointCount() <= 0) { + callback.onFailure(); + return; + } + //创建stateManager实例 + SurveyorData surveyorDataSource = new SurveyorData(toleranceRecord.getSurveyorCount()); + surveyorDataSource.onShowSlopDistance(surveyorStationRecord.isShowSlopDistance()); + RequestSurveyorParamAuto requestSurveyorParamAuto = new RequestSurveyorParamAuto(stationId, cachedData); + + StateManager stateManager = StateManager.newInstance( + isSupportAutoMode, + requestSurveyorParamAuto, + surveyorStationRecord, + context, + fragmentManager, + lifecycleOwner, + toleranceRecord, + surveyorDataSource, + surveyorDataSource, + cachedData, + scrollDelegate, + runner); + //fragment创建后立即计算当前cycle的测量状态 + runner.runOnUI(() -> stateManager.calScheduleWhenEnterSurveyFragment(defaultCycle)); + callback.onSuccess(surveyorStationRecord.isShowSlopDistance(), cachedData, surveyorDataSource, stateManager); + }); + } + + @Override + public void onResume() { + super.onResume(); + if (stateManager != null) { + stateManager.resume(); + } + } + + @Override + public void onPause() { + super.onPause(); + if (stateManager != null) { + stateManager.quite(); + } + } + + private interface ICollectCacheCallback { + void onFailure(); + + void onSuccess(boolean showSlopDistance, ICachedData cachedData, SurveyorData surveyorData, StateManager stateManager); + } + + public void doSurveyor() { + if (stateManager == null) { + return; + } + stateManager.doSurveyor(); + } + + public void autoSurvey() { + if (stateManager == null) { + return; + } + stateManager.doAutoSurveyor(); + } + + public void switchCycle(int cycleIndex) { + if (stateManager == null) { + return; + } + stateManager.switch2Cycle(cycleIndex); + } + + public void deleteCurrentStationSurveyorData() { + if (stateManager == null) { + return; + } + stateManager.deleteCurrentStationSurveyorData(); + } + + public void deleteByStationAndPeriod(int cycleIndex) { + if (stateManager == null) { + return; + } + stateManager.deleteCurrentStationSurveyorData(cycleIndex); + } + + /** + * 测站检测 + */ + public void stationCheck() { + if (stateManager == null) { + return; + } + stateManager.stationCheck(); + } + + /** + * 测站平差 + */ + public void stationAdjust() { + if (stateManager == null) { + return; + } + stateManager.stationAdjust(StationDataAdjustDialogFragment.TYPE_ANGLE_DISTANCE); + } + + /** + * 测站检测平差 + */ + public void stationCheckAdjust() { + ThreadPoolUtil.execute(() -> { + SurveyorScheduleRecord scheduleRecord = SurveyorDatabaseFactory.instance.getScheduleDataSource() + .findScheduleSync(SurveyorScheduleConstants.getAllCycleScheduleKey(stationId(), null)); + if (scheduleRecord == null || SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED.equals(scheduleRecord.getStatue())) { + ToastUtils.showShort("请完成测站测量"); + return; + } + if (SurveyorScheduleConstants.STATUE_VALUE_CHECKED.equals(scheduleRecord.getStatue())) { + //经过检测 + stateManager.stationAdjustOnly(StationDataAdjustDialogFragment.TYPE_ANGLE_DISTANCE); + } else if (SurveyorScheduleConstants.STATUE_VALUE_COMPLETED.equals(scheduleRecord.getStatue())) { + //完成测量 + String error = stateManager.stationCheckOnly(); + if (!TextUtils.isEmpty(error)) { + TipsFragment.tipsOnly(getChildFragmentManager(), getViewLifecycleOwner(), requireContext(), error); + return; + } + stateManager.stationAdjustOnly(StationDataAdjustDialogFragment.TYPE_ANGLE_DISTANCE); + } + }); + } + + public void goBack() { + if (stateManager == null) { + return; + } + stateManager.moveBack(); + } + + @Override + public void onShowSlopDistance(boolean value) { + if (cachedDataListener != null) { + cachedDataListener.onShowSlopDistance(value); + } + if (surveyedDataListener != null) { + surveyedDataListener.onShowSlopDistance(value); + } + if (adapter != null) { + adapter.onShowSlopDistance(value); + adapter.notifyItemRangeChanged(0, adapter.getItemCount()); + } + } + + @Override + public boolean isSurveying() { + if (surveyState != null) { + return surveyState.isSurveying(); + } + return false; + } + + @Override + public boolean isAutoSurveying() { + if (surveyState != null) { + return surveyState.isAutoSurveying(); + } + return false; + } + + private static final String KEY_STATION_ID = "__station_id"; + public static final String TAG = ComponentStationSurveyorDataListFragment.class.getName(); + + public static ComponentStationSurveyorDataListFragment newInstance(String stationId) { + ComponentStationSurveyorDataListFragment fragment = new ComponentStationSurveyorDataListFragment(); + Bundle bundle = new Bundle(); + bundle.putString(KEY_STATION_ID, stationId); + fragment.setArguments(bundle); + return fragment; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/ComponentSurveyorStationListFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/ComponentSurveyorStationListFragment.java new file mode 100644 index 0000000..39726ae --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/ComponentSurveyorStationListFragment.java @@ -0,0 +1,144 @@ +package com.bingce.controlnetwork.fragment; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.lifecycle.LiveData; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.datasource.database.ProjectType; +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord; +import com.bingce.controlapphelper.model.BundleConstants; +import com.bingce.controlapphelper.util.StationUtil; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.adapter.SurveyorStationListAdapter; +import com.bingce.controlnetwork.fragment.base.BaseFragment; +import com.bingce.controlnetwork.fragment.stationdetail.SingleStationDetailAndEditFragment; +import com.bingce.controlnetwork.fragment.stationsurvey.StationSurveyorFragment; +import com.bingce.controlnetwork.fragment.stationsurvey.angledistance.MeasureFragment; +import com.bingce.utils.ThreadPoolUtil; + +import java.util.List; + +/** + * 测站列表(项目和测量共用) + */ +public class ComponentSurveyorStationListFragment extends BaseFragment { + public static final String TAG = "cn.liuyanbing.surveyor.fragment.dummy__SurveyorStationListFragment___"; + private SurveyorStationListAdapter adapter; + private RecyclerView recyclerView; + + private LiveData> stationLiveData; + + /** + * 去测量或者详情页面 + */ + private void goStationMeasureOrDetail(SurveyorStationRecord item, boolean detailOrSurveyorFinal) { + String stationId = item.getId(); + ThreadPoolUtil.execute(() -> { + SurveyorStationRecord stationRecord = SurveyorDatabaseFactory + .instance + .getSurveyorStation() + .getRecordSync(stationId); + if (stationRecord == null || stationRecord.getItems() == null || stationRecord.getItems().isEmpty()) { + return; + } + + String lineTypeFromStation = StationUtil.getLineTypeFromStation(stationRecord); + + //站的名称 导线+点名 + String stationName = StationUtil.getStationName(stationRecord); + + if (detailOrSurveyorFinal) { + SingleStationDetailAndEditFragment.start(getContext(), stationId, stationName, item.getProjectId(), null); + } else { + //StationSurveyorFragment原始测量页 + if (ProjectType.isConnection(item.projectType)) { + MeasureFragment.start(getContext(), stationId, stationName); + } else { + StationSurveyorFragment.start(getContext(), stationId, stationName); + } + } + }); + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.fragment_list_layout, container, false); + if (view instanceof RecyclerView) { + recyclerView = (RecyclerView) view; + if (getArguments() != null) { + update(getArguments().getString(BundleConstants.KEY_PROJECT_ID), + getArguments().getString(KEY_TIME_INDEX)); + } + } + return view; + } + + /** + * 根据项目id和测期id获取测站记录 + * + * @param projectId + * @param periodId + */ + public void update(String projectId, String periodId) { + if (stationLiveData != null) { + stationLiveData.removeObservers(this); + } + + stationLiveData = SurveyorDatabaseFactory + .instance + .getSurveyorStation().getLiveDataList(projectId, periodId); + + stationLiveData.observe(getViewLifecycleOwner(), this::updateUi); + } + + private void updateUi(List dataList) { + runOnUI(() -> { + if (adapter == null) { + boolean detailOrSurveyor = false; + if (getArguments() != null) { + detailOrSurveyor = getArguments().getBoolean(KEY_DETAIL_OR_SURVEYOR, false); + } + boolean detailOrSurveyorFinal = detailOrSurveyor; + adapter = new SurveyorStationListAdapter(dataList, + getChildFragmentManager(), + getViewLifecycleOwner(), + runnable -> { + if (getActivity() != null) { + getActivity().runOnUiThread(runnable); + } + }, + getContext(), + item -> goStationMeasureOrDetail(item, detailOrSurveyorFinal), + detailOrSurveyor); + recyclerView.setAdapter(adapter); + } else { + adapter.updateData(dataList); + } + }); + } + + private static final String KEY_TIME_INDEX = "___time_index__"; + private static final String KEY_DETAIL_OR_SURVEYOR = "___editable___";//标识点击item进入测量界面还是测站详情 + + public static ComponentSurveyorStationListFragment newInstance(String projectId, String surveyorPeriodId, boolean isDetail) { + ComponentSurveyorStationListFragment fragment = new ComponentSurveyorStationListFragment(); + Bundle bundle = new Bundle(); + bundle.putString(BundleConstants.KEY_PROJECT_ID, projectId); + bundle.putString(KEY_TIME_INDEX, surveyorPeriodId); + bundle.putBoolean(KEY_DETAIL_OR_SURVEYOR, isDetail); + fragment.setArguments(bundle); + return fragment; + } + + public static ComponentSurveyorStationListFragment newInstance(String projectId, String surveyorPeriodId) { + return newInstance(projectId, surveyorPeriodId, true); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/ComponentSwitchStationListFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/ComponentSwitchStationListFragment.java new file mode 100644 index 0000000..258a09b --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/ComponentSwitchStationListFragment.java @@ -0,0 +1,148 @@ +package com.bingce.controlnetwork.fragment; + +import android.os.Bundle; +import android.widget.TextView; + +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.project.ProjectRecord; +import com.bingce.controlapphelper.datasource.database.surveyorcycle.SurveyorPeriodRecord; +import com.bingce.controlapphelper.model.IUniversalListItem; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.adapter.IndexWithTextAdapter; +import com.bingce.controlnetwork.adapter.SelectableIndexWithTextAdapter; +import com.bingce.utils.ThreadPoolUtil; + +import org.greenrobot.eventbus.EventBus; + +import java.util.ArrayList; +import java.util.List; + +import blankj.utilcode.util.ToastUtils; + +/** + * 选择项目和测期的组件 + */ +public class ComponentSwitchStationListFragment extends AbstractHierarchicalListFragment { + private static final int INDEX_PROJECT_LIST = 0; + private static final int INDEX_CYCLE_LIST = 1; + private String projectId = ""; + private String projectName = ""; + private SelectableIndexWithTextAdapter> projectAdapter; + private SelectableIndexWithTextAdapter> periodAdapter; + + @Override + protected void onItemClicked(int currentListIndex, IUniversalListItem item) { + if (INDEX_PROJECT_LIST == currentListIndex) { + projectId = item.getId(); + projectName = item.getName(); + forward2(INDEX_CYCLE_LIST); + } else { + SelectProjectAndSurveyorCycleFragment.SelectedResult result = + new SelectProjectAndSurveyorCycleFragment.SelectedResult(projectId, projectName, item.getId(), item.getName()); + EventBus.getDefault().post(result); + } + } + + @Override + protected void onBackClicked(int currentListIndex) { + if (INDEX_CYCLE_LIST == currentListIndex) { + back2(INDEX_PROJECT_LIST); + } else { + //结束 + ToastUtils.showShort(R.string.cannot_go_back); + } + } + + @Override + protected void setupList(int listIndex, TextView title, RecyclerView recyclerView, + IndexWithTextAdapter.IOnItemClick> callback) { + if (INDEX_PROJECT_LIST == listIndex) { + //加载 + if (title != null) { + title.setText(Tools.getString(R.string.please_select_an_project)); + } + ThreadPoolUtil.execute(() -> { + List projectRecords = SurveyorDatabaseFactory + .instance + .getProjectDataSource() + .getDataList(); + String selectedProject = ""; + if (getArguments() != null) { + selectedProject = getArguments().getString(KEY_PROJECT_ID); + } + List> items = new ArrayList<>(); + int targetIndex = 0; + for (int index = 0; index < projectRecords.size(); index++) { + ProjectRecord projectRecord = projectRecords.get(index); + Item item = new Item(projectRecord.getName(), projectRecord.getId()); + items.add(item); + if (selectedProject.equals(item.getId())) { + targetIndex = index; + } + } + int finalTargetIndex = targetIndex; + String finalSelectedProject = selectedProject; + ThreadPoolUtil.executeInMain(() -> { + if (projectAdapter == null) { + projectAdapter = new SelectableIndexWithTextAdapter<>(finalSelectedProject, items, callback); + recyclerView.setAdapter(projectAdapter); + } else { + projectAdapter.updateData(items); + } + recyclerView.scrollToPosition(finalTargetIndex); + }); + }); + } else if (INDEX_CYCLE_LIST == listIndex) { + //加载 + if (title != null) { + title.setText(Tools.getString(R.string.please_select_an_period)); + } + ThreadPoolUtil.execute(() -> { + List periodRecords = SurveyorDatabaseFactory.instance + .getSurveyorPeriod().getDataListSyncByProjectId(projectId); + List> items = new ArrayList<>(); + String selectedPeriodId = ""; + if (getArguments() != null) { + selectedPeriodId = getArguments().getString(KEY_CYCLE_ID); + } + int targetIndex = 0; + for (int index = 0; index < periodRecords.size(); index++) { + SurveyorPeriodRecord surveyorPeriodRecord = periodRecords.get(index); + Item item = new Item(surveyorPeriodRecord.getName(), surveyorPeriodRecord.getId()); + items.add(item); + if (selectedPeriodId.equals(item.getId())) { + targetIndex = index; + } + } + int finalTargetIndex = targetIndex; + if (periodAdapter == null) { + periodAdapter = new SelectableIndexWithTextAdapter<>(selectedPeriodId, items, callback); + ThreadPoolUtil.executeInMain(() -> { + recyclerView.setAdapter(periodAdapter); + recyclerView.scrollToPosition(finalTargetIndex); + }); + } else { + ThreadPoolUtil.executeInMain(() -> { + periodAdapter.updateData(items); + recyclerView.scrollToPosition(finalTargetIndex); + }); + } + }); + } + } + + private static final String KEY_PROJECT_ID = "___project_id"; + private static final String KEY_CYCLE_ID = "__cycle_id"; + + public static ComponentSwitchStationListFragment newInstance(String projectId, String cycleId) { + ComponentSwitchStationListFragment fragment = new ComponentSwitchStationListFragment(); + Bundle args = new Bundle(); + args.putString(KEY_PROJECT_ID, projectId); + args.putString(KEY_CYCLE_ID, cycleId); + fragment.setArguments(args); + return fragment; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/ComponentSwitchToleranceFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/ComponentSwitchToleranceFragment.java new file mode 100644 index 0000000..e833c46 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/ComponentSwitchToleranceFragment.java @@ -0,0 +1,251 @@ +package com.bingce.controlnetwork.fragment; + +import android.content.Context; +import android.os.Bundle; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.tolerance.detail.IToleranceDetail; +import com.bingce.controlapphelper.datasource.database.tolerance.detail.IToleranceDetailDataSource; +import com.bingce.controlapphelper.datasource.database.tolerance.group.ToleranceGroupConstants; +import com.bingce.controlapphelper.datasource.database.tolerance.group.ToleranceGroupRecord; +import com.bingce.controlapphelper.datasource.database.tolerance.level.ToleranceLevelRecord; +import com.bingce.controlapphelper.datasource.database.tolerance.load.ToleranceLoadUtil; +import com.bingce.controlapphelper.model.IUniversalListItem; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.adapter.IndexWithTextAdapter; +import com.bingce.controlnetwork.adapter.SelectableIndexWithTextAdapter; +import com.bingce.utils.ThreadPoolUtil; + +import org.greenrobot.eventbus.EventBus; + +import java.util.ArrayList; +import java.util.List; + +import blankj.utilcode.util.ToastUtils; + + +/** + * 选择限差模板的内容 + */ +public class ComponentSwitchToleranceFragment extends AbstractHierarchicalListFragment { + private static final int INDEX_GROUP = 0; + private static final int INDEX_LEVEL = 1; + private static final int INDEX_TOLERANCE = 2; + private String projectType = ""; + private String groupId = ""; + private String levelId = ""; + private String toleranceId = ""; + private SelectableIndexWithTextAdapter> adapterGroup = null; + private SelectableIndexWithTextAdapter> adapterLevel = null; + private SelectableIndexWithTextAdapter> adapterDetail = null; + + @Override + protected void onItemClicked(int currentListIndex, IUniversalListItem item) { + if (INDEX_GROUP == currentListIndex) { + groupId = item.getId(); + //检测目标group是否有level,如果没有直接进入detail + List levelRecordList = ToleranceLoadUtil.getToleranceLoad(projectType).levelListOf(projectType, groupId); + if (levelRecordList.isEmpty()) { + levelId = ""; + forward2(INDEX_TOLERANCE); + } else { + forward2(INDEX_LEVEL); + } + } else if (INDEX_LEVEL == currentListIndex) { + levelId = item.getId(); + forward2(INDEX_TOLERANCE); + } else { + callBackData(item.getId()); + } + } + + private void callBackData(String id) { + SelectedToleranceEvent result = new SelectedToleranceEvent(id); + EventBus.getDefault().post(result); + } + + @Override + protected int preIndexOf(int index) { + if (INDEX_TOLERANCE == index) { + if (levelId == null || levelId.isEmpty()) { + return INDEX_GROUP; + } else { + return INDEX_LEVEL; + } + } + return super.preIndexOf(index); + } + + @Override + protected void onBackClicked(int currentListIndex) { + if (INDEX_TOLERANCE == currentListIndex) { + if (levelId == null || levelId.isEmpty()) { + back2(INDEX_GROUP); + } else { + back2(INDEX_LEVEL); + } + } else if (INDEX_LEVEL == currentListIndex) { + back2(INDEX_GROUP); + } else { + ToastUtils.showShort(R.string.cannot_go_back); + } + } + + @Override + protected void setupList(int listIndex, TextView title, RecyclerView recyclerView, + final IndexWithTextAdapter.IOnItemClick> callback) { + if (INDEX_GROUP == listIndex) { + if (title != null) { + title.setText(R.string.tips_please_select_tolerance_group); + } + List toleranceGroupRecords = ToleranceLoadUtil.getToleranceLoad(projectType).getGroupFromType(projectType); + List> items = new ArrayList<>(); + int targetIndex = 0; + IUniversalListItem customGroup = null; + int index = -1; + for (ToleranceGroupRecord toleranceGroupRecord : toleranceGroupRecords) { + if (toleranceGroupRecord.isDeleted()) { + continue; + } + if (ToleranceGroupConstants.VALUE_CUSTOM_GROUP.equals(toleranceGroupRecord.getId())) { + customGroup = toleranceGroupRecord; + continue; + } + index++; + items.add(toleranceGroupRecord); + if (groupId.equals(toleranceGroupRecord.getId())) { + targetIndex = index; + } + } + //添加自定义分组 + if (customGroup != null) { + items.add(customGroup); + if (groupId.equals(customGroup.getId())) { + targetIndex = items.size() - 1; + } + } + if (adapterGroup == null) { + adapterGroup = new SelectableIndexWithTextAdapter<>(groupId, items, callback); + } else { + adapterGroup.updateData(items); + } + recyclerView.setAdapter(adapterGroup); + recyclerView.scrollToPosition(targetIndex); + } else if (INDEX_LEVEL == listIndex) { + if (title != null) { + title.setText(R.string.tips_please_select_tolerance_level); + } + List toleranceLevelRecords = ToleranceLoadUtil.getToleranceLoad(projectType).levelListOf(projectType, groupId); + List> items = new ArrayList<>(); + int targetIndex = 0; + for (int index = 0; index < toleranceLevelRecords.size(); index++) { + ToleranceLevelRecord toleranceLevelRecord = toleranceLevelRecords.get(index); + items.add(toleranceLevelRecord); + if (levelId != null && levelId.equals(toleranceLevelRecord.getId())) { + targetIndex = index; + } + } + if (adapterLevel == null) { + adapterLevel = new SelectableIndexWithTextAdapter<>(levelId, items, callback); + } else { + adapterLevel.updateData(items); + } + recyclerView.setAdapter(adapterLevel); + recyclerView.scrollToPosition(targetIndex); + } else if (INDEX_TOLERANCE == listIndex) { + ThreadPoolUtil.execute(() -> { + IToleranceDetailDataSource toleranceDetailDataSource = + SurveyorDatabaseFactory.instance.getToleranceDetailDataSource(); + List toleranceDetailList; + int titleRes = R.string.tips_please_select_instrument_precision; + if (levelId == null || levelId.isEmpty()) {//自定义模板 + toleranceDetailList = ToleranceLoadUtil.getToleranceLoad(projectType).getDetailListByGroup(groupId); + //选择模板 + titleRes = R.string.tips_please_select_custom_tolerance; + } else { + toleranceDetailList = ToleranceLoadUtil.getToleranceLoad(projectType).detailListOfLevel(projectType, levelId); + } + + if (!ToleranceGroupConstants.VALUE_CUSTOM_GROUP.equals(groupId) && + toleranceDetailList != null && toleranceDetailList.size() == 1) { + callBackData(toleranceDetailList.get(0).getId()); + return; + } + + + int finalTitleRes = titleRes; + runOnUI(() -> { + if (title != null) { + title.setText(finalTitleRes); + } + }); + List> items = new ArrayList<>(); + int targetIndex = 0; + for (int index = 0; index < toleranceDetailList.size(); index++) { + IToleranceDetail toleranceDetailRecordTj = toleranceDetailList.get(index); + items.add((IUniversalListItem) toleranceDetailRecordTj); + if (toleranceId.equals(toleranceDetailRecordTj.getId())) { + targetIndex = index; + } + } + int finalTargetIndex = targetIndex; + runOnUI(() -> { + if (adapterDetail == null) { + adapterDetail = new SelectableIndexWithTextAdapter<>(toleranceId, items, callback); + } else { + adapterDetail.updateData(items); + } + recyclerView.setAdapter(adapterDetail); + recyclerView.scrollToPosition(finalTargetIndex); + }); + }); + } + } + + private void runOnUI(Runnable runnable) { + if (getActivity() == null) { + return; + } + getActivity().runOnUiThread(runnable); + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + if (getArguments() != null) { + projectType = getArguments().getString(KEY_PROJECT_TYPE); + groupId = getArguments().getString(KEY_GROUP); + levelId = getArguments().getString(KEY_LEVEL); + toleranceId = getArguments().getString(KEY_TOLERANCE); + } + } + + private static final String KEY_PROJECT_TYPE = "___PROJECT_TYPE___"; + private static final String KEY_GROUP = "___GROUP___"; + private static final String KEY_LEVEL = "___LEVEL___"; + private static final String KEY_TOLERANCE = "___PRECISION__"; + + public static ComponentSwitchToleranceFragment newInstance(String projectType, + String groupId, String levelId, String toleranceId) { + ComponentSwitchToleranceFragment fragment = new ComponentSwitchToleranceFragment(); + Bundle args = new Bundle(); + args.putString(KEY_PROJECT_TYPE, projectType); + args.putString(KEY_GROUP, groupId); + args.putString(KEY_LEVEL, levelId); + args.putString(KEY_TOLERANCE, toleranceId); + fragment.setArguments(args); + return fragment; + } + + public static class SelectedToleranceEvent { + public final String toleranceId; + + public SelectedToleranceEvent(String toleranceId) { + this.toleranceId = toleranceId; + } + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/ConfigFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/ConfigFragment.java new file mode 100644 index 0000000..4466902 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/ConfigFragment.java @@ -0,0 +1,93 @@ +package com.bingce.controlnetwork.fragment; + +import android.graphics.Color; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import com.bingce.controlapphelper.util.SettingValueUtil; +import com.wedcel.dragexpandgrid.model.DargChildInfo; +import com.wedcel.dragexpandgrid.model.DragIconInfo; +import com.wedcel.dragexpandgrid.view.CustomAboveView; +import com.wedcel.dragexpandgrid.view.CustomGroup; + +import java.util.ArrayList; + +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.ui.widget.NoScrollView; +import com.bingce.controlnetwork.util.config.ConfigsSetConfigs; + +/** + * 主页面-管理 + */ +public class ConfigFragment extends Fragment { + private CustomGroup mCustomGroup; + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + View rootView = inflater.inflate(R.layout.fragment_config, container, false); + mCustomGroup = rootView.findViewById(R.id.fragment_config_custom_group); + NoScrollView mScrollView = rootView.findViewById(R.id.fragment_config_custom_group_scrollview); + + if (SettingValueUtil.isThemeDark()) { + mScrollView.setBackgroundColor(Color.DKGRAY); + mCustomGroup.setNameTextColor(Color.WHITE); + } + return rootView; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + mCustomGroup.setHasMoreIcon(false); + + ArrayList iconInfoList = new ArrayList<>(); + ConfigsSetConfigs.getInstance().foreach(item -> iconInfoList.add( + new DragIconInfo( + item.getId(), + getString(item.getTitle()), + item.getIcon(), + item.getCategory(), + false, + new ArrayList<>()))); + mCustomGroup.initIconInfo(iconInfoList); + + mCustomGroup.setCustomViewClickListener(new CustomAboveView.CustomAboveViewClickListener() { + @Override + public void onSingleClicked(DragIconInfo iconInfo) { + if (iconInfo == null) { + return; + } + ConfigsSetConfigs.getInstance().onItemClick(iconInfo.getId(), ConfigFragment.this); + } + + @Override + public void onChildClicked(DargChildInfo childInfo) { + } + }); +// mCustomGroup.setEditModelListener(new CustomGroup.InfoEditModelListener() { +// @Override +// public void onModelChanged(boolean isEditModel) { +// if (getActivity() instanceof MainActivity) { +//// ((MainActivity) getActivity()).getViewPager().setNoScroll(isEditModel); +// } +// mScrollView.setNoScroll(isEditModel); +// } +// }); + } + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + } + + public CustomGroup getCustomGroup() { + return mCustomGroup; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/EmptyFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/EmptyFragment.java new file mode 100644 index 0000000..9ee70d0 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/EmptyFragment.java @@ -0,0 +1,10 @@ +package com.bingce.controlnetwork.fragment; + +import com.bingce.controlnetwork.fragment.base.BaseFragment; + +/** + * Empty + */ +public class EmptyFragment extends BaseFragment { + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/FullLoadingFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/FullLoadingFragment.java new file mode 100644 index 0000000..6d6b02a --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/FullLoadingFragment.java @@ -0,0 +1,83 @@ +package com.bingce.controlnetwork.fragment; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.Window; +import android.view.WindowManager; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatDialogFragment; +import androidx.fragment.app.DialogFragment; +import androidx.fragment.app.FragmentManager; + +import org.jetbrains.annotations.NotNull; + +import com.bingce.controlnetwork.R; + +public final class FullLoadingFragment extends AppCompatDialogFragment { + @Nullable + @org.jetbrains.annotations.Nullable + @Override + public View onCreateView(@NonNull @NotNull LayoutInflater inflater, @Nullable @org.jetbrains.annotations.Nullable ViewGroup container, @Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) { + View rootView = inflater.inflate(R.layout.fragment_full_loading_layout, container, false); + if (getArguments() != null) { + String msg = getArguments().getString(KEY_MSG); + if (msg != null && !msg.isEmpty()) { + TextView tips = rootView.findViewById(R.id.tips); + if (tips != null) { + tips.setText(msg); + } + } + } + return rootView; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + if (getDialog() != null) { + final Window window = getDialog().getWindow(); + + window.setWindowAnimations(R.style.animate_full_dialog); + window.setBackgroundDrawable(null); + + WindowManager.LayoutParams params = window.getAttributes(); + params.width = ViewGroup.LayoutParams.MATCH_PARENT; + params.height = ViewGroup.LayoutParams.MATCH_PARENT; + window.setAttributes(params); + } + } + + @Override + public void onResume() { + super.onResume(); + if (getDialog() == null) { + return; + } + getDialog().setOnKeyListener((dialog, keyCode, event) -> { + // pass on to be processed as normal + return keyCode == android.view.KeyEvent.KEYCODE_BACK; // pretend we've processed it + }); + } + + private static final String KEY_MSG = "__KEY_MSG__"; + + public static DialogFragment showLoading(FragmentManager fragmentManager) { + return showLoading(fragmentManager, null); + } + + public static DialogFragment showLoading(FragmentManager fragmentManager, String msg) { + DialogFragment fragment = new FullLoadingFragment(); + if (msg != null && !msg.isEmpty()) { + Bundle args = new Bundle(); + args.putString(KEY_MSG, msg); + fragment.setArguments(args); + } + fragment.show(fragmentManager, FullLoadingFragment.class.getName()); + return fragment; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/ListDialogFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/ListDialogFragment.java new file mode 100644 index 0000000..cab9e36 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/ListDialogFragment.java @@ -0,0 +1,173 @@ +package com.bingce.controlnetwork.fragment; + +import android.graphics.drawable.ColorDrawable; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.Window; +import android.view.WindowManager; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.DialogFragment; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; +import androidx.recyclerview.widget.RecyclerView; + +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +import com.bingce.controlnetwork.R; + +public class ListDialogFragment extends DialogFragment { + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + if (getDialog() == null) { + return; + } + Window window = getDialog().getWindow(); + window.setBackgroundDrawable(new ColorDrawable(0x00000000)); + window.setLayout( + WindowManager.LayoutParams.MATCH_PARENT, + WindowManager.LayoutParams.WRAP_CONTENT); + } + + @Nullable + @org.jetbrains.annotations.Nullable + @Override + public View onCreateView(@NonNull @NotNull LayoutInflater inflater, @Nullable @org.jetbrains.annotations.Nullable ViewGroup container, @Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) { + View rootView = inflater.inflate(R.layout.fragment_station_select_point_datasource_layout, container, false); + RecyclerView recyclerView = rootView.findViewById(R.id.list); + if (recyclerView != null && getArguments() != null) { + List list = getArguments().getStringArrayList(KEY_LIST); + _Adapter adapter = new _Adapter(list, (index, value) -> { + Bundle args = new Bundle(); + args.putInt(KEY_INDEX, index); + args.putString(KEY_RESULT, value); + getParentFragmentManager().setFragmentResult(TAG, args); + dismiss(); + }); + recyclerView.setAdapter(adapter); + } + TextView title = rootView.findViewById(R.id.title); + if (title != null && getArguments() != null) { + String string = getArguments().getString(KEY_TITLE); + if (string != null && string.isEmpty()) { + title.setText(string); + } + } + return rootView; + } + + private static class _VH extends RecyclerView.ViewHolder { + final TextView textView; + + public _VH(@NonNull @NotNull View itemView) { + super(itemView); + if (itemView instanceof TextView) { + textView = (TextView) itemView; + } else { + textView = null; + } + } + } + + private static class _Adapter extends RecyclerView.Adapter<_VH> { + private final List list; + private final IResultCallback resultCallback; + + _Adapter(List list, IResultCallback resultCallback) { + this.list = list; + this.resultCallback = resultCallback; + } + + @NonNull + @NotNull + @Override + public _VH onCreateViewHolder(@NonNull @NotNull ViewGroup parent, int viewType) { + View rootView = LayoutInflater.from(parent.getContext()) + .inflate(android.R.layout.simple_list_item_1, parent, false); + return new _VH(rootView); + } + + @Override + public void onBindViewHolder(@NonNull @NotNull ListDialogFragment._VH holder, int position) { + String value = list.get(position); + if (holder.textView != null) { + holder.textView.setText(value); + holder.textView.setOnClickListener(v -> { + if (resultCallback != null) { + resultCallback.onResult(position, value); + } + }); + } + } + + @Override + public int getItemCount() { + return list == null ? 0 : list.size(); + } + } + + public interface IResultCallback { + void onResult(int index, String value); + } + + private static final String TAG = ListDialogFragment.class.getName(); + private static final String KEY_INDEX = "key_index"; + private static final String KEY_RESULT = "key value"; + private static final String KEY_LIST = "key list"; + private static final String KEY_TITLE = "KEY TITLE"; + + public static void showList(FragmentManager fragmentManager, + ArrayList list, + @NonNull LifecycleOwner lifecycleOwner, + IResultCallback callback) { +// DialogFragment fragment = new ListDialogFragment(); +// +// Bundle args = new Bundle(); +// args.putStringArrayList(KEY_LIST, list); +// fragment.setArguments(args); +// +// fragmentManager +// .setFragmentResultListener( +// TAG, +// lifecycleOwner, +// (requestKey, result) -> { +// if (TAG.equals(requestKey)) { +// callback.onResult(result.getInt(KEY_INDEX, -1), result.getString(KEY_RESULT)); +// } +// }); +// fragment.show(fragmentManager, TAG); + showList(fragmentManager, null, list, lifecycleOwner, callback); + } + + public static void showList(FragmentManager fragmentManager, + String title, + ArrayList list, + @NonNull LifecycleOwner lifecycleOwner, + IResultCallback callback) { + DialogFragment fragment = new ListDialogFragment(); + + Bundle args = new Bundle(); + args.putStringArrayList(KEY_LIST, list); + args.putString(KEY_TITLE, title); + fragment.setArguments(args); + + fragmentManager + .setFragmentResultListener( + TAG, + lifecycleOwner, + (requestKey, result) -> { + if (TAG.equals(requestKey)) { + callback.onResult(result.getInt(KEY_INDEX, -1), result.getString(KEY_RESULT)); + } + }); + fragment.show(fragmentManager, TAG); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/MainSurveyFragment.kt b/app/src/main/java/com/bingce/controlnetwork/fragment/MainSurveyFragment.kt new file mode 100644 index 0000000..883bbf1 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/MainSurveyFragment.kt @@ -0,0 +1,373 @@ +package com.bingce.controlnetwork.fragment + +import android.os.Bundle +import android.text.TextUtils +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import androidx.fragment.app.viewModels +import com.bingce.controlapphelper.datasource.database.ProjectType +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory +import com.bingce.controlapphelper.datasource.database.config.ConfigConstants +import com.bingce.controlapphelper.datasource.database.leveling.LevelingDbFactory +import com.bingce.controlapphelper.datasource.database.leveling.route.LevelRouteRecord +import com.bingce.controlapphelper.datasource.database.project.ProjectRecord +import com.bingce.controlapphelper.datasource.database.route.RouteRecord +import com.bingce.controlapphelper.datasource.database.surveyorcycle.SurveyorPeriodRecord +import com.bingce.controlapphelper.util.Tools +import com.bingce.controlnetwork.R +import com.bingce.controlnetwork.databinding.FragmentProjectSurveyorStationListLayoutBinding +import com.bingce.controlnetwork.fragment.base.BaseFragment +import com.bingce.controlnetwork.fragment.bottompage.BottomBean +import com.bingce.controlnetwork.fragment.bottompage.BottomPageFragment +import com.bingce.controlnetwork.fragment.bottompage.IData +import com.bingce.controlnetwork.func.level.fragment.LevelSurveyorHomeFragment +import com.bingce.controlnetwork.newui.stationlist.StationListFragment +import com.bingce.controlnetwork.newui.stationlist.StationListVm +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.MainScope +import kotlinx.coroutines.cancel +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + +/** + * 测量首页 + */ +class MainSurveyFragment : BaseFragment() { + + private val mBinding get() = _binding!! + + private var _binding: FragmentProjectSurveyorStationListLayoutBinding? = null + + private val scope = MainScope() + + //筛选项目的项目类型 + private var selectProjectType: String? = null + + private val stationListVm by viewModels() + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + _binding = + FragmentProjectSurveyorStationListLayoutBinding.inflate(inflater, container, false) + return mBinding.root + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + scope.cancel() + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + SurveyorDatabaseFactory.instance + .configDataSource + .getLiveDataByKey(ConfigConstants.KEY_DEFAULT_PROJECT_ID) + .observe(viewLifecycleOwner) { configRecord -> + refreshUi(configRecord?.configValue) + } + + initListener() + } + + private fun initListener() { + mBinding.title.setOnClickListener { + BottomPageFragment.showBottom( + childFragmentManager, viewLifecycleOwner, + selectData, + object : BottomPageFragment.CallBack { + override fun back(selectData: List) { + scope.launch { + val title = getFilterTitle( + selectData[0].name, + selectData[1].name + ) + if (ProjectType.isHeightTraverse(selectProjectType)) { + switchContent( + title, + SurveyorRouteStationFragment.newInstance( + selectData[0].id, + selectData[1].id + ) + ) + } else if (ProjectType.isLevel(selectProjectType)) { + switchContent( + title, + LevelSurveyorHomeFragment.newInstance( + selectData[0].id, + selectData[1].id, + false + ) + ) + } else { + stationListVm.setArgument(selectData[0].id, selectData[1].id) + switchContent( + title, + StationListFragment() + ) + } + } + } + }) + } + } + + private val selectData = object : IData { + override suspend fun getData(bottomBean: BottomBean?): List { + val dataList: MutableList = ArrayList() + + if (bottomBean == null) { + //一级数据 + val projectRecords = SurveyorDatabaseFactory.instance + .projectDataSource + .dataList + for (projectRecord in projectRecords) { + dataList.add( + BottomBean( + projectRecord.getId(), projectRecord.getProjectName(), + 0 + ) + ) + } + } else { + if (bottomBean.pageIndex == 0) { + //二级数据 + val projectRecord = + SurveyorDatabaseFactory.instance.projectDataSource.getRecord(bottomBean.id) + selectProjectType = projectRecord.getProjectType() + if (ProjectType.isHeightTraverse(selectProjectType)) { + val routeList = SurveyorDatabaseFactory.instance.getRouteDataSource() + .getByProjectId(bottomBean.id) + for (routeRecord in routeList) { + dataList.add( + BottomBean( + routeRecord.getId(), routeRecord.name, + 1, tag = selectProjectType + ) + ) + } + } else if (ProjectType.isLevel(selectProjectType)) { + val routeList = LevelingDbFactory.instance.levelDataSource + .getByProjectId(bottomBean.id) + for (routeRecord in routeList) { + dataList.add( + BottomBean( + routeRecord.getId(), routeRecord.name, + 1, tag = selectProjectType + ) + ) + } + } else { + val periodRecords = SurveyorDatabaseFactory.instance + .surveyorPeriod.getDataListSyncByProjectId(bottomBean.id) + for (periodItem in periodRecords) { + dataList.add( + BottomBean( + periodItem.getId(), periodItem.getName(), + 1, tag = selectProjectType + ) + ) + } + } + } + } + + return dataList + } + + override fun getTitle(pageIndex: Int): String { + return if (pageIndex == 0) { + Tools.getString(R.string.please_select_an_project) + } else if (selectProjectType != null && pageIndex == 1) { + if (ProjectType.isHeightTraverse(selectProjectType) + || ProjectType.isLevel(selectProjectType) + ) { + Tools.getString(R.string.please_select_an_route) + } else { + Tools.getString(R.string.please_select_an_period) + } + } else { + "" + } + } + } + + /** + * 刷新页面 + */ + private fun refreshUi(projectId: String?) { + scope.launch { + val projectRecord = getProjectRecord(projectId) + if (projectRecord == null) { + switchContent(null, null) + return@launch + } + val projectType = projectRecord.getProjectType() + if (ProjectType.isHeightTraverse(projectType)) { + loadHeightTraverseData(projectRecord) + } else if (ProjectType.isLevel(projectType)) { + loadLevelData(projectRecord) + } else { + loadNotHeightTraverseData(projectRecord) + } + } + } + + /** + * 加载三角导线和联系测量数据 + */ + private suspend fun loadNotHeightTraverseData(projectRecord: ProjectRecord) { + val cycleRecord = getPeriodRecord(projectRecord.getId()) + + val fragment = + if (cycleRecord == null) + EmptyFragment() + else { + stationListVm.setArgument(projectRecord.getId(), cycleRecord.getId()) + StationListFragment() + +// ComponentSurveyorStationListFragment.newInstance( +// projectRecord.getId(), +// cycleRecord.getId(), +// false +// ) + } + switchContent( + getFilterTitle(projectRecord.getProjectName(), cycleRecord?.getName()), + fragment + ) + } + + + /** + * 加载高程导线数据 + */ + private suspend fun loadHeightTraverseData(projectRecord: ProjectRecord) { + val routeRecord = getRouteRecord(projectRecord.getId()) + + val fragment = + if (routeRecord == null) + EmptyFragment() + else SurveyorRouteStationFragment.newInstance( + projectRecord.getId(), + routeRecord.getId() + ) + + switchContent( + getFilterTitle(projectRecord.getProjectName(), routeRecord?.routeName), + fragment + ) + } + + private suspend fun loadLevelData(projectRecord: ProjectRecord) { + val routeRecord = getLevelRouteRecord(projectRecord.getId()) + val fragment = + if (routeRecord == null) + EmptyFragment() + else LevelSurveyorHomeFragment.newInstance( + projectRecord.getId(), + routeRecord.getId(), + false + ) + + switchContent( + getFilterTitle(projectRecord.getProjectName(), routeRecord?.routeName), + fragment + ) + } + + private fun getFilterTitle(projectName: String, secondName: String?): String { + val suffix = if (secondName == null) "" else " > $secondName" + return projectName + suffix + } + + private suspend fun switchContent(title: String?, fragment: Fragment?) { + withContext(Dispatchers.Main) { + setFilterTitle(title) + val targetFragment = fragment ?: EmptyFragment() + childFragmentManager + .beginTransaction() + .replace(R.id.fragment_container, targetFragment, null) + .commit() + } + } + + private fun setFilterTitle(title: String?) { + if (TextUtils.isEmpty(title)) { + mBinding.title.visibility = View.INVISIBLE + } else { + mBinding.title.visibility = View.VISIBLE + mBinding.titleView.text = title + } + } + + private suspend fun getProjectRecord(projectId: String?): ProjectRecord? { + return withContext(Dispatchers.IO) { + val projectRecord = + SurveyorDatabaseFactory.instance.projectDataSource.getRecord(projectId) + if (projectRecord != null) { + return@withContext projectRecord + } + SurveyorDatabaseFactory.instance.projectDataSource.defaultRecordSync + } + } + + private suspend fun getPeriodRecord( + projectId: String, + ): SurveyorPeriodRecord? { + return withContext(Dispatchers.IO) { + val defaultPeriodId = SurveyorDatabaseFactory.instance + .configDataSource.getByKeySync(ConfigConstants.KEY_DEFAULT_PERIOD_ID)?.configValue + val periodRecord = + SurveyorDatabaseFactory.instance.surveyorPeriod.getByIdAndProjectId( + defaultPeriodId, + projectId + ) + if (periodRecord != null) { + return@withContext periodRecord + } + SurveyorDatabaseFactory.instance.surveyorPeriod.getDefaultSync(projectId) + } + } + + private suspend fun getRouteRecord( + projectId: String, + ): RouteRecord? { + return withContext(Dispatchers.IO) { + val defaultRouteId = SurveyorDatabaseFactory.instance + .configDataSource.getByKeySync(ConfigConstants.KEY_DEFAULT_ROUTE_ID)?.configValue + val routeRecord = + SurveyorDatabaseFactory.instance.getRouteDataSource() + .getByIdAndProjectId(defaultRouteId, projectId) + if (routeRecord != null) { + return@withContext routeRecord + } + SurveyorDatabaseFactory.instance.getRouteDataSource() + .getDefault(projectId) + } + } + + private suspend fun getLevelRouteRecord( + projectId: String, + ): LevelRouteRecord? { + return withContext(Dispatchers.IO) { + val defaultRouteId = SurveyorDatabaseFactory.instance + .configDataSource.getByKeySync(ConfigConstants.KEY_DEFAULT_ROUTE_ID)?.configValue + val routeRecord = + LevelingDbFactory.instance.levelDataSource + .getByIdSync(defaultRouteId) + if (routeRecord != null) { + return@withContext routeRecord + } + LevelingDbFactory.instance.levelDataSource + .getDefault(projectId) + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/PickPointFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/PickPointFragment.java new file mode 100644 index 0000000..6fb2bd0 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/PickPointFragment.java @@ -0,0 +1,239 @@ +package com.bingce.controlnetwork.fragment; + +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ExpandableListView; + +import androidx.activity.result.ActivityResultLauncher; +import androidx.activity.result.contract.ActivityResultContracts; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.point.IPointDataSource; +import com.bingce.controlapphelper.datasource.database.point.PointRecord; +import com.bingce.controlapphelper.model.BundleConstants; +import com.bingce.controlapphelper.model.KnownAndUnknownPoints; +import com.bingce.controlapphelper.model.PickPointResult; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.activity.fragmentcontainer.FragmentContainerActivity; +import com.bingce.controlnetwork.adapter.AbstractPointSelectAdapter; +import com.bingce.controlnetwork.adapter.PointSelectAdapter; +import com.bingce.controlnetwork.fragment.base.BaseFragment; +import com.bingce.utils.ThreadPoolUtil; + +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + + +public class PickPointFragment extends BaseFragment { + public static final String TAG = PickPointFragment.class.getName(); + AbstractPointSelectAdapter adapter; + + @Nullable + @Override + public View onCreateView(@NonNull @NotNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + //读取数据类型 + int maxCount = -1; + if (getArguments() != null) { + maxCount = getArguments().getInt(KEY_MAX_COUNT, -1); + } + View view = inflater.inflate(R.layout.fragment_pick_point_bottom_sheet_layout, container, false); + if (view instanceof ExpandableListView) { + ExpandableListView expandableListView = (ExpandableListView) view; + String projectId = getArguments().getString(BundleConstants.KEY_PROJECT_ID); + List filterId = getArguments().getStringArrayList(KEY_FILTER); + PickPointResult pickPointResult = getArguments().getParcelable(BundleConstants.KEY_RESULT); + + int finalMaxCount1 = maxCount; + ThreadPoolUtil.execute(() -> { + IPointDataSource pointDataSource = + SurveyorDatabaseFactory.instance.getPointDataSource(); + //去掉全局控制点 +// List globalControlPoints = pointDataSource +// .getListByProjectId(PointRecordTj.GLOBAL_CONTROL_POINT_PROJECT_ID, PointRecordTj.TYPE_GLOBAL_POINT); + + KnownAndUnknownPoints knownAndUnknownPoints = + KnownAndUnknownPoints.loadData(false, filterId, projectId); + + List filterName = new ArrayList<>(); + if (filterId != null) { + for (String id : filterId) { + PointRecord record = pointDataSource.findByIdSync(id); + if (record == null) { + continue; + } + filterName.add(record.getName()); + } + } + + //过滤全局控制点 + List others = new ArrayList<>(); + //去掉全局控制点 +// for (PointRecordTj pointRecord : globalControlPoints) { +// if ((filterId != null && filterId.contains(pointRecord.getId())) || +// filterName.contains(pointRecord.getName()) || +// knownAndUnknownPoints.containsKnownPoint(pointRecord)) { +// continue; +// } +// others.add(pointRecord); +// } + adapter = new PointSelectAdapter(knownAndUnknownPoints, others, + pickPointResult, + finalMaxCount1, getContext()); + runOnUI(() -> { + expandableListView.setAdapter(adapter); + int groupCount = adapter.getGroupCount(); + for (int index = 0; index < groupCount; index++) { + expandableListView.expandGroup(index); + } + }); + }); +// String pointType = getArguments().getString(KEY_POINT_TYPE); +// if (PointRecord.TYPE_KNOWN_POINT.equals(pointType)) { +// KnownAndUnknownPoints.loadKnownData(filterId, projectId, instance -> runOnUI(() -> { +// adapter = new KnownAndUnknownPointSelectAdapter(instance, pickPointResult, +// finalMaxCount1, getContext()); +// expandableListView.setAdapter(adapter); +// int groupCount = adapter.getGroupCount(); +// for (int index = 0; index < groupCount; index++) { +// expandableListView.expandGroup(index); +// } +// })); +// } else { +// KnownAndUnknownPoints.loadKnownAndUnknownData(filterId, projectId, instance -> runOnUI(() -> { +// adapter = new KnownAndUnknownPointSelectAdapter(instance, pickPointResult, +// finalMaxCount1, getContext()); +// expandableListView.setAdapter(adapter); +// int groupCount = adapter.getGroupCount(); +// for (int index = 0; index < groupCount; index++) { +// expandableListView.expandGroup(index); +// } +// })); +// } + } + setHasOptionsMenu(true); + return view; + } + + @Override + public void onCreateOptionsMenu(@NonNull @NotNull Menu menu, @NonNull @NotNull MenuInflater inflater) { + inflater.inflate(R.menu.menu_confirm, menu); + super.onCreateOptionsMenu(menu, inflater); + } + + @Override + public boolean onOptionsItemSelected(@NonNull @NotNull MenuItem item) { + if (item.getItemId() == R.id.menu_confirm) { + Intent intent = new Intent(); + PickPointResult pickPointResult = new PickPointResult(); + pickPointResult.setSelectedIds(adapter.getSelectedId()); + pickPointResult.setSelectedNames(adapter.getSelectedName()); + intent.putExtra(BundleConstants.KEY_RESULT, pickPointResult); + if (getArguments() != null) { + intent.putExtra(KEY_TYPE, getArguments().getString(KEY_TYPE)); + } + Activity activity = getActivity(); + if (activity != null) { + activity.setResult(Activity.RESULT_OK, intent); + activity.finish(); + } + } + return super.onOptionsItemSelected(item); + } + + public static final String KEY_TYPE = "__TYPE"; + private static final String KEY_FILTER = "__filter__id"; + private static final String KEY_MAX_COUNT = "__key__max_count"; + private static final String KEY_POINT_TYPE = "__point_type"; + + public static PickPointFragment newInstance(Bundle args) { + PickPointFragment pickPointFragment = new PickPointFragment(); + pickPointFragment.setArguments(args); + return pickPointFragment; + } + + public static ActivityResultLauncher createActivityLauncher(Fragment fragment, IOnSelectCallback selectCallback) { + return fragment.registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> { + if (result != null && Activity.RESULT_OK == result.getResultCode()) { + Intent intent = result.getData(); + if (intent != null) { + PickPointResult pickPointResult = intent.getParcelableExtra(BundleConstants.KEY_RESULT); + String type = intent.getStringExtra(KEY_TYPE); + selectCallback.onSelect(type, pickPointResult); + } + } + }); + } + + public static void pickKnownPoint( Context context, + String type, + int maxCount, + String title, + ArrayList filterPointId, String projectId, + PickPointResult result, ActivityResultLauncher launcher) { + pickPoint( context, + type, maxCount, title, filterPointId, projectId, result, launcher); + } + + public static void pickKnownAndUnknownPoint(Context context, + String type, + int maxCount, + String title, + List filterPointId, String projectId, + PickPointResult result, ActivityResultLauncher launcher) { + pickPoint(context, + type, maxCount, title, filterPointId, projectId, result, launcher); + } + + public static void pickPoint(Context context, + String type, + int maxCount, + String title, + List filterPointId, String projectId, + PickPointResult result, ActivityResultLauncher launcher) { +// ArrayList list = new ArrayList<>(); +// list.add(context.getString(R.string.global_control_point)); +// if (knownOnly) { +// list.add(context.getString(R.string.project_known_point)); +// } else { +// list.add(context.getString(R.string.project_known_unknown_point)); +// } +// ListDialogFragment.showList(fragmentManager, list, lifecycleOwner, (index, value) -> { + if (launcher == null) { + return; + } + Bundle args = new Bundle(); +// if (index == 0) { +// args.putString(BundleConstants.KEY_PROJECT_ID, PointRecord.GLOBAL_CONTROL_POINT_PROJECT_ID); +// } else { + args.putString(BundleConstants.KEY_PROJECT_ID, projectId); +// } +// if (knownOnly) { +// args.putString(KEY_POINT_TYPE, PointRecord.TYPE_KNOWN_POINT); +// } + args.putString(KEY_TYPE, type); + args.putInt(KEY_MAX_COUNT, maxCount); + args.putStringArrayList(KEY_FILTER, (ArrayList) filterPointId); + args.putParcelable(BundleConstants.KEY_RESULT, result); + launcher.launch(FragmentContainerActivity.startIntent(context, TAG, title, args)); +// }); + } + + public interface IOnSelectCallback { + void onSelect(String type, PickPointResult result); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/PointFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/PointFragment.java new file mode 100644 index 0000000..2b3fa73 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/PointFragment.java @@ -0,0 +1,362 @@ +package com.bingce.controlnetwork.fragment; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.WorkerThread; +import androidx.fragment.app.DialogFragment; +import androidx.fragment.app.FragmentManager; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.point.PointRecord; +import com.bingce.controlapphelper.util.PointUtil; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.databinding.FragmentPointLayoutBinding; +import com.bingce.utils.SoftKeyUtils; +import com.bingce.utils.ThreadPoolUtil; +import com.rengwuxian.materialedittext.MaterialEditText; + +import org.jetbrains.annotations.NotNull; + +import java.util.Locale; + +import blankj.utilcode.util.ToastUtils; + +/** + * 新建或编辑点 + */ +public class PointFragment extends DialogFragment { + + private FragmentPointLayoutBinding mBinding; + + private PointFragment() { + } + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setStyle(STYLE_NORMAL, R.style.Dialog_FullScreen); + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + mBinding = null; + } + + @Nullable + @Override + public View onCreateView(@NonNull @NotNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + mBinding = FragmentPointLayoutBinding.inflate(inflater, container, false); + return mBinding.getRoot(); + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initListener(); + initData(); + } + + private void initListener() { + + mBinding.getRoot().setOnClickListener(v -> dismissPointFragment()); + + mBinding.cancel.setOnClickListener(v -> dismissPointFragment()); + + mBinding.next.setOnClickListener(v -> checkSave(isCanSave -> { + if (!isCanSave) return; + saveCurrnetPoint(); + startNextPointPre(); + })); + + mBinding.confirm.setOnClickListener(v -> checkSave(isCanSave -> { + if (!isCanSave) return; + saveCurrnetPoint(); + dismissPointFragment(); + })); + + } + + private void startNextPointPre() { + runOnUI(() -> { + //编号+1 + String indexString = string(mBinding.number); + int index = 1; + try { + index = Integer.parseInt(indexString) + 1; + } catch (Exception ignored) { + ignored.printStackTrace(); + } + mBinding.number.setText(String.format(Locale.getDefault(), "%03d", index)); + clearXYZ(mBinding.pointX, mBinding.pointY, mBinding.pointZ); + }); + } + + @WorkerThread + private void saveCurrnetPoint() { + String pointName = pointName(mBinding.prefix, mBinding.number, mBinding.suffix); + + double x = doubleValue(mBinding.pointX); + double y = doubleValue(mBinding.pointY); + double z = doubleValue(mBinding.pointZ); + + if (isEdit()) { + String pointId = getPointId(); + PointRecord pointRecord = SurveyorDatabaseFactory.instance.getPointDataSource().findByIdSync(pointId); + pointRecord.name = pointName; + pointRecord.x = x; + pointRecord.y = y; + pointRecord.z = z; + pointRecord.code = ""; + pointRecord.remarks = ""; + SurveyorDatabaseFactory.instance.getPointDataSource().update(pointRecord); + } else { + PointRecord pointRecord = PointRecord.point( + getProjectId(), getPointType(), pointName, "", x, y, z, "", -1); + SurveyorDatabaseFactory + .instance + .getPointDataSource() + .saveSync(pointRecord); + } + } + + /** + * 初始化编辑数据 + */ + private void initData() { + boolean isEdit = isEdit(); + + mBinding.title.setText(isEdit ? R.string.edit_point : R.string.new_point); + + if (isEdit) { + mBinding.number.setVisibility(View.GONE); + mBinding.suffix.setVisibility(View.GONE); + mBinding.next.setVisibility(View.GONE); + + setString(mBinding.prefix, getArguments(), KEY_POINT_NAME); + String label = getString(R.string.point_name); + mBinding.prefix.setFloatingLabelText(label); + mBinding.prefix.setHint(label); + + setDouble(mBinding.pointX, getArguments(), KEY_POINT_X); + setDouble(mBinding.pointY, getArguments(), KEY_POINT_Y); + setDouble(mBinding.pointZ, getArguments(), KEY_POINT_Z); + } + } + + private void runOnUI(Runnable runnable) { + if (getActivity() != null) { + getActivity().runOnUiThread(runnable); + } + } + + private void clearXYZ(MaterialEditText x, MaterialEditText y, MaterialEditText z) { + if (x != null) { + x.setText(null); + } + if (y != null) { + y.setText(null); + } + if (z != null) { + z.setText(null); + } + } + + private String string(MaterialEditText editText) { + if (editText == null || editText.getText() == null) { + return ""; + } + return editText.getText().toString(); + } + + private double doubleValue(MaterialEditText editText) { + String string = string(editText); + if (string.isEmpty()) { + return 0; + } + return Double.parseDouble(string); + } + + private void setString(MaterialEditText editText, Bundle args, String key) { + if (editText == null || args == null) { + return; + } + editText.setText(args.getString(key)); + } + + private void setDouble(MaterialEditText editText, Bundle args, String key) { + if (editText == null || args == null) { + return; + } + editText.setText(String.valueOf(args.getDouble(key))); + } + + private String pointName(final MaterialEditText prefix, + final MaterialEditText numberCome, + final MaterialEditText suffix) { + String number = string(numberCome); + if (number.isEmpty()) { + return string(prefix) + string(suffix); + } + long value = 0; + try { + value = Long.parseLong(number); + } catch (NumberFormatException ignored) { + + } + String result = String.format(Locale.getDefault(), "%s%03d%s", string(prefix), value, string(suffix)); + return result.replace(",", ""); + } + + private boolean checkXYValidate(MaterialEditText x, MaterialEditText y) { + return x != null && y != null && + x.getText() != null && y.getText() != null && + !x.getText().toString().isEmpty() && !y.getText().toString().isEmpty(); + } + + private static final String KEY_PROJECT_ID = "___project__id"; + private static final String KEY_POINT_TYPE = "___point_type__"; + private static final String KEY_POINT_NAME = "___point_name__"; + private static final String KEY_POINT_ID = "___point_id"; + private static final String KEY_POINT_X = "___point_x"; + private static final String KEY_POINT_Y = "___point_y"; + private static final String KEY_POINT_Z = "__point_z"; + + private static final String KEY_TYPE = "_TYPE_"; + private static final String VALUE_NEW = "___new___"; + private static final String VALUE_EDIT = "___edit___"; + + + public static void start(FragmentManager fragmentManager, + String projectId, + String pointType) { + Bundle args = new Bundle(); + args.putString(KEY_PROJECT_ID, projectId); + args.putString(KEY_POINT_TYPE, pointType); + show(fragmentManager, args); + } + + + public static void edit(FragmentManager fragmentManager, + String projectId, + String pointName, + String pointId, + String pointType, + double x, + double y, + double z) { + Bundle args = new Bundle(); + args.putString(KEY_PROJECT_ID, projectId); + args.putString(KEY_POINT_NAME, pointName); + args.putString(KEY_POINT_ID, pointId); + args.putString(KEY_POINT_TYPE, pointType); + + args.putDouble(KEY_POINT_X, x); + args.putDouble(KEY_POINT_Y, y); + args.putDouble(KEY_POINT_Z, z); + args.putString(KEY_TYPE, VALUE_EDIT); + + show(fragmentManager, args); + } + + + private static void show(FragmentManager fragmentManager, + Bundle args) { + PointFragment fragment = new PointFragment(); + if (args != null) { + fragment.setArguments(args); + } + fragment.show(fragmentManager, PointFragment.class.getName()); + } + + public interface ICallback { + void onGet(String pointName, double x, double y, double z); + } + + private void showPointSameNameDialogHint() { + ThreadPoolUtil.executeInMain(() -> { + //点名重复,提示 + TipsFragment.tipsOnly( + getChildFragmentManager(), + getViewLifecycleOwner(), + requireContext(), + Tools.getString(R.string.same_project_ponit_point_cannot_repeate)); + }); + } + + private boolean isEdit() { + if (getArguments() != null) { + return VALUE_EDIT.equals(getArguments().getString(KEY_TYPE, VALUE_NEW)); + } + return false; + } + + private String getProjectId() { + if (getArguments() != null) { + return getArguments().getString(KEY_PROJECT_ID); + } + return null; + } + + private String getPointId() { + if (getArguments() != null) { + return getArguments().getString(KEY_POINT_ID); + } + return null; + } + + private String getPointType() { + if (getArguments() != null) { + return getArguments().getString(KEY_POINT_TYPE); + } + return null; + } + + private boolean isKnownPoint(String pointType) { + return PointRecord.TYPE_KNOWN_POINT.equals(pointType) || PointRecord.TYPE_GLOBAL_POINT.equals(pointType); + } + + private void checkSave(ICallBackSave callBackSave) { + String pointName = pointName(mBinding.prefix, mBinding.number, mBinding.suffix);//string(prefix) + string(number) + string(suffix); + if (pointName.isEmpty()) { + ToastUtils.showShort(R.string.point_name_cannot_be_empty); + callBackSave.result(false); + return; + } + + if (isKnownPoint(getPointType()) && !checkXYValidate(mBinding.pointX, mBinding.pointY)) { + ToastUtils.showShort(R.string.error_tips_known_point_x_y_cannt_be_empty); + callBackSave.result(false); + return; + } + + ThreadPoolUtil.execute(() -> { + boolean sameName = PointUtil.isSameName(getProjectId(), pointName, getPointId()); + if (sameName) { + showPointSameNameDialogHint(); + callBackSave.result(false); + return; + } + callBackSave.result(true); + }); + } + + private void dismissPointFragment() { + runOnUI(() -> { + SoftKeyUtils.hideSoftKey(); + dismiss(); + }); + } + + private interface ICallBackSave { + void result(boolean isCanSave); + } + + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/PointListFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/PointListFragment.java new file mode 100644 index 0000000..d3c81ac --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/PointListFragment.java @@ -0,0 +1,279 @@ +package com.bingce.controlnetwork.fragment; + +import android.content.Context; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.WorkerThread; + +import com.bingce.controlapphelper.datasource.database.ProjectType; +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.point.PointRecord; +import com.bingce.controlapphelper.model.BundleConstants; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlapphelper.util.importpoint.ImportPointsUtil; +import com.bingce.controlapphelper.widget.swiperecyclerview.widget.DefaultItemDecoration; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.activity.fragmentcontainer.FragmentContainerActivity; +import com.bingce.controlnetwork.databinding.NewFragmentPointListBinding; +import com.bingce.controlnetwork.newui.adapter.PointListAdapter; +import com.bingce.controlnetwork.newui.base.BaseFragmentBinding; +import com.bingce.controlnetwork.newui.createeditpoint.CreateEditPointActvity; +import com.bingce.controlnetwork.newui.widget.swipemenu.SwipeMenuEditDelete; +import com.bingce.controlnetwork.util.DialogUtil; +import com.bingce.coordlib.model.Blh; +import com.bingce.coordlib.model.Coordinate; +import com.bingce.coordlib.model.CoordinateSystem; +import com.bingce.utils.ThreadPoolUtil; + +import java.util.Collections; +import java.util.List; + +import blankj.utilcode.util.ToastUtils; + + +/** + * 点列表 + */ +public class PointListFragment extends BaseFragmentBinding { + public static final String TAG = PointListFragment.class.getName(); + private final static String KEY_TYPE = "___KEY___"; + + // private PointRecordAdapter adapter; + private PointListAdapter adapter; + @NonNull + private final ImportPointsUtil importPointsUtil; + + /** + * 去未知点列表 + * + * @param projectId + * @param context + */ + public static void go2UnknownPointList(String projectId, String projectType, Context context) { + Bundle bundle = new Bundle(); + bundle.putString(KEY_TYPE, PointRecord.TYPE_UNKNOWN_POINT); + bundle.putString(BundleConstants.KEY_PROJECT_ID, projectId); + bundle.putString(BundleConstants.KEY_PROJECT_TYPE, projectType); + FragmentContainerActivity.start(context, TAG, R.string.project_unknown_points, bundle); + } + + /** + * 去已知点列表 + * + * @param projectId + * @param context + */ + public static void go2KnownPointList(String projectId, String projectType, Context context) { + Bundle bundle = new Bundle(); + bundle.putString(KEY_TYPE, PointRecord.TYPE_KNOWN_POINT); + bundle.putString(BundleConstants.KEY_PROJECT_ID, projectId); + bundle.putString(BundleConstants.KEY_PROJECT_TYPE, projectType); + FragmentContainerActivity.start(context, TAG, R.string.project_known_points, bundle); + } + + /** + * 去全局控制点 + * + * @param context + */ + public static void go2GlobalPointList(Context context) { + Bundle bundle = new Bundle(); + bundle.putString(KEY_TYPE, PointRecord.TYPE_GLOBAL_POINT); + bundle.putString(BundleConstants.KEY_PROJECT_ID, PointRecord.GLOBAL_CONTROL_POINT_PROJECT_ID); + FragmentContainerActivity.start(context, TAG, R.string.global_control_point, bundle); + } + + public static PointListFragment newInstance(Bundle bundle) { + PointListFragment fragment = new PointListFragment(); + fragment.setArguments(bundle); + return fragment; + } + + public PointListFragment() { + importPointsUtil = new ImportPointsUtil(this); + } + + /** + * 更新点列表 + * + * @param pointRecords + */ + private void updateData(List pointRecords) { + //排序 + Collections.sort(pointRecords, (o1, o2) -> { + if (o1.getCreateDate().before(o2.getCreateDate())) { + return -1; + } else if (o1.getCreateDate().after(o2.getCreateDate())) { + return 1; + } + if (o1.getOrderIndex() < o2.getOrderIndex()) { + return -1; + } else if (o1.getOrderIndex() > o2.getOrderIndex()) { + return 1; + } + return 0; + }); + + adapter.refreshData(pointRecords); + } + + @Override + public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { + inflater.inflate(R.menu.menu_import_and_clear, menu); + super.onCreateOptionsMenu(menu, inflater); + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + int id = item.getItemId(); + if (getArguments() == null) { + return super.onOptionsItemSelected(item); + } + String pointType = getPonitType(); + String projectId = getProjectId(); + if (id == R.id.menu_item_import) { + //导入点 + importPoints(pointType, projectId); + } else if (id == R.id.menu_item_clear) { + //清空点 + clearPoints(pointType, projectId); + } + return super.onOptionsItemSelected(item); + } + + private String getPonitType() { + return requireArguments().getString(KEY_TYPE, PointRecord.TYPE_GLOBAL_POINT); + } + + private String getProjectId() { + return requireArguments().getString(BundleConstants.KEY_PROJECT_ID); + } + + private String getProjectType() { + return requireArguments().getString(BundleConstants.KEY_PROJECT_TYPE); + } + + /** + * 创建点 + */ + private void createPoints(String pointType, String projectId, String projectType) { + goCreateEditPointActvity(projectId, projectType, pointType, null); + } + + private void goCreateEditPointActvity(String projectId, String projectType, String pointType, PointRecord bean) { + CreateEditPointActvity.launch(requireContext(), projectId, projectType, + pointType, bean); + } + + /** + * 清空点 + */ + private void clearPoints(String pointType, String projectId) { + DialogUtil.showConfirmCountDownDialog(getChildFragmentManager(), getViewLifecycleOwner(), + getString(R.string.tips_ready_2_clear_all_known_point), + Tools.getString(R.string.confirm), () -> SurveyorDatabaseFactory + .instance + .getPointDataSource() + .clearByProjectId(projectId, pointType)); + } + + /** + * 导入点 + */ + private void importPoints(String pointType, String projectId) { + importPointsUtil.showImportDialog(projectId, pointType); + } + + @Override + protected NewFragmentPointListBinding getViewBinding(@NonNull LayoutInflater inflater, @Nullable ViewGroup container) { + return NewFragmentPointListBinding.inflate(inflater, container, false); + } + + @Override + protected void initView() { + setHasOptionsMenu(true); + initAapter(); + initListener(); + } + + private void initListener() { + mBinding.tvNewPoint.setOnClickListener((v) -> { + //新建点 + if (getArguments() == null) { + return; + } + createPoints(getPonitType(), getProjectId(), getProjectType()); + }); + } + + private void initAapter() { + mBinding.ilSwipeList.swipeRecyclerView.addItemDecoration(new DefaultItemDecoration(Tools.getColor(R.color.transparent), 1, 1)); + mBinding.ilSwipeList.swipeRecyclerView.setSwipeMenuCreator(new SwipeMenuEditDelete(requireContext())); + mBinding.ilSwipeList.swipeRecyclerView.setOnItemMenuClickListener((menuBridge, adapterPosition) -> { + menuBridge.closeMenu(); + dealMenuClick(menuBridge.getPosition(), adapter.getBean(adapterPosition)); + }); + adapter = new PointListAdapter(requireContext()); + adapter.setProjectType(getProjectType()); + mBinding.ilSwipeList.swipeRecyclerView.setAdapter(adapter); + } + + /** + * @param menuPostion 编辑或删除的position + * @param bean 数据模型 + */ + private void dealMenuClick(int menuPostion, PointRecord bean) { + if (SwipeMenuEditDelete.isEditMenu(menuPostion)) { + startEdit(bean); + } else if (SwipeMenuEditDelete.isDeleteMenu(menuPostion)) { + startDelete(bean); + } + } + + private void startDelete(PointRecord bean) { + SurveyorDatabaseFactory + .instance + .getPointDataSource() + .delete(bean); + } + + private void startEdit(PointRecord bean) { + goCreateEditPointActvity(getProjectId(), getProjectType(), getPonitType(), bean); + } + + + @Override + protected void initData() { + if (getArguments() == null) { + return; + } + String pointType = getArguments().getString(KEY_TYPE, PointRecord.TYPE_GLOBAL_POINT); + String projectId = getArguments().getString(BundleConstants.KEY_PROJECT_ID); + + String projectType = getProjectType(); + ThreadPoolUtil.execute(() -> { + //是否是平面坐标 + boolean isPlatCoordinate = true; + if (ProjectType.isHeightTraverse(projectType)) { + isPlatCoordinate = false; + } + adapter.setIsPlatCoordinate(isPlatCoordinate); + getData(projectId, pointType); + }); + } + + private void getData(String projectId, String pointType) { + ThreadPoolUtil.executeInMain(() -> SurveyorDatabaseFactory + .instance + .getPointDataSource() + .getLiveDataListByProject(projectId, pointType) + .observe(getViewLifecycleOwner(), this::updateData)); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/PrismManageFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/PrismManageFragment.java new file mode 100644 index 0000000..d398962 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/PrismManageFragment.java @@ -0,0 +1,159 @@ +package com.bingce.controlnetwork.fragment; + +import android.content.Context; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.prism.IPrismManagerDataSource; +import com.bingce.controlapphelper.datasource.database.prism.PrismConstants; +import com.bingce.controlapphelper.datasource.database.prism.PrismRecord; +import com.bingce.controlnetwork.adapter.PrismMagegeAdapter; +import com.bingce.utils.ThreadPoolUtil; + +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.activity.fragmentcontainer.FragmentContainerActivity; +import com.bingce.controlnetwork.adapter.PrismMagegeAdapter; +import com.bingce.controlnetwork.adapter.contextmenu.ContextMenuDeleteEdit; +import com.bingce.controlnetwork.fragment.base.BaseFragment; + +/** + * 棱镜管理 + */ +public class PrismManageFragment extends BaseFragment { + + public static final String TAG = PrismManageFragment.class.getName(); + private PrismMagegeAdapter adapter = null; + private RecyclerView recyclerView; + + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + + } + + @Nullable + @org.jetbrains.annotations.Nullable + @Override + public View onCreateView(@NonNull @NotNull LayoutInflater inflater, @Nullable @org.jetbrains.annotations.Nullable ViewGroup container, @Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) { + View rootView = inflater.inflate(R.layout.fragment_prism_manager, container, false); + recyclerView = rootView.findViewById(R.id.list); + View createButton = rootView.findViewById(R.id.create_new); + if (createButton != null) { + createButton.setOnClickListener(this::createCustom); + } + return rootView; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initData(); + } + + private void initData() { + IPrismManagerDataSource prismManagerDataSource = SurveyorDatabaseFactory.instance.getPrismManagerDataSource(); + prismManagerDataSource.getAllRecordLiveData().observe(getViewLifecycleOwner(), prismRecords -> { + if (prismRecords == null) return; + if (adapter == null) { + adapter = new _Adapter( + prismRecords, + item -> { + + }); + recyclerView.setAdapter(adapter); + } else { + adapter.updateData(prismRecords); + } + + + }); + + + } + + /** + * 创建自定义 + * + * @param view + */ + private void createCustom(View view) { + PrismManagerCreateCustomFragment.create(getChildFragmentManager(), getViewLifecycleOwner(), (nameBefore, name, typeLarge, constant) -> { + //选择完的结果 + ThreadPoolUtil.execute(() -> { + PrismRecord record = PrismRecord.createRecord(name, PrismConstants.TYPE_USER, constant, PrismRecord.MODIFY_ALLOW, typeLarge); + SurveyorDatabaseFactory.instance.getPrismManagerDataSource().saveRecord(record); + }); + }); + } + + private void editCustom(PrismRecord item) { + PrismManagerCreateCustomFragment.edit(getChildFragmentManager(), + getViewLifecycleOwner(), + item.prismTypeName, item.prismTypeLarge, item.prismTypeConstant, + (nameBefore, name, typeLarge, constant) -> ThreadPoolUtil.execute(() -> { + IPrismManagerDataSource prismManagerDataSource = SurveyorDatabaseFactory.instance.getPrismManagerDataSource(); + PrismRecord record = prismManagerDataSource.getPrismTypeNameSync(nameBefore); + if (record != null) { + record.prismTypeName = name; + record.prismType = PrismConstants.TYPE_USER; + record.prismTypeConstant = constant; + record.prismTypeLarge = typeLarge; + prismManagerDataSource.update(record); + } + })); + } + + private class _Adapter extends PrismMagegeAdapter { + public _Adapter( + List records, + IOnItemClick callback) { + super(records == null ? new ArrayList<>() : records, + callback, + new ContextMenuDeleteEdit() { + @Override + protected void delete(PrismRecord item) { + ThreadPoolUtil.execute(() -> { + IPrismManagerDataSource prismManagerDataSource = SurveyorDatabaseFactory.instance.getPrismManagerDataSource(); + prismManagerDataSource.delete(item); + }); + } + + @Override + protected void edit(PrismRecord item) { + editCustom(item); + } + }); + } + + + } + + /** + * 启动方法 + * + * @param context + */ + public static void start(Context context) { + Bundle bundle = new Bundle(); + FragmentContainerActivity.start(context, TAG, R.string.prism_manager, bundle); + } + + public static PrismManageFragment newInstance(Bundle bundle) { + PrismManageFragment fragment = new PrismManageFragment(); + fragment.setArguments(bundle); + return fragment; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/PrismManagerCreateCustomFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/PrismManagerCreateCustomFragment.java new file mode 100644 index 0000000..52db430 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/PrismManagerCreateCustomFragment.java @@ -0,0 +1,277 @@ +package com.bingce.controlnetwork.fragment; + +import android.os.Bundle; +import android.text.TextUtils; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; +import android.widget.Button; +import android.widget.Spinner; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.DialogFragment; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.prism.IPrismManagerDataSource; +import com.bingce.controlapphelper.datasource.database.prism.PrismConstants; +import com.bingce.controlapphelper.datasource.database.prism.PrismRecord; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.utils.SoftKeyUtils; +import com.bingce.utils.ThreadPoolUtil; +import com.rengwuxian.materialedittext.MaterialEditText; + +import org.jetbrains.annotations.NotNull; + +import java.util.Arrays; +import java.util.List; + +import blankj.utilcode.util.ToastUtils; + +/** + * 新建自定义棱镜类型 + */ +public class PrismManagerCreateCustomFragment extends DialogFragment { + + private final String[] spinnerData = {PrismConstants.TYPE_PRISM_LARGE, PrismConstants.TYPE_TAPE_LARGE}; + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setStyle(STYLE_NORMAL, R.style.Dialog_FullScreen); + } + + @Nullable + @org.jetbrains.annotations.Nullable + @Override + public View onCreateView(@NonNull @NotNull LayoutInflater inflater, @Nullable @org.jetbrains.annotations.Nullable ViewGroup container, @Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) { + View contentView = inflater.inflate(R.layout.fragment_prism_manager_create_custom, container, false); + if (contentView != null) { + contentView.setOnClickListener(v -> { + SoftKeyUtils.hideSoftKey(); + dismiss(); + }); + String type = VALUE_NEW; + String prismTypeName = ""; + String prismTypeType = ""; + String prismTypeConstant = ""; + if (getArguments() != null) { + type = getArguments().getString(KEY_TYPE, VALUE_NEW); + prismTypeName = getArguments().getString(KEY_PRISM_TYPE_NAME); + prismTypeType = getArguments().getString(KEY_PRISM_TYPE_LARGE); + prismTypeConstant = getArguments().getString(KEY_PRISM_TYPE_CONSTANT); + } + //设置标题 + TextView title = contentView.findViewById(R.id.title); + if (title != null) { + if (VALUE_NEW.equals(type)) { + title.setText(Tools.getString(R.string.text_create_new_surveyor_station)); + } else if (VALUE_EDIT.equals(type)) { + title.setText(Tools.getString(R.string.menu_edit)); + } + } + + MaterialEditText etName = contentView.findViewById(R.id.etName); + Spinner spinner = contentView.findViewById(R.id.spinner); + MaterialEditText etContant = contentView.findViewById(R.id.etContant); + + List spinnerDataList = Arrays.asList(spinnerData); + spinner.setAdapter(new ArrayAdapter<>(getContext(), android.R.layout.simple_list_item_1, spinnerDataList)); + + //编辑的时候重新赋值 + if (VALUE_EDIT.equals(type)) { + //设置值 + etName.setText(prismTypeName); + if (!TextUtils.isEmpty(prismTypeName)) { + etName.setSelection(prismTypeName.length()); + } + etContant.setText(prismTypeConstant); + spinner.setSelection(spinnerDataList.indexOf(prismTypeType)); + } + + IPrismManagerDataSource prismManagerDataSource = SurveyorDatabaseFactory.instance.getPrismManagerDataSource(); + + Button confirm = contentView.findViewById(R.id.confirm); + if (confirm != null) { + String finalPrismTypeNameBefore = prismTypeName; + String finalType = type; + confirm.setOnClickListener(v -> { + String name = string(etName); + if (name.isEmpty()) { + ToastUtils.showShort(R.string.name_is_required); + return; + } + String constant = string(etContant); + if (constant.isEmpty()) { + ToastUtils.showShort(R.string.absolute_constants_cannot_be_empty); + return; + } + double constantD = Double.parseDouble(constant); + if (constantD > 0) { + ToastUtils.showShort(R.string.absolute_constants_must_be_negative); + return; + } + + String selectedItem = (String) spinner.getSelectedItem(); + + //检测名称是否重复 + ThreadPoolUtil.execute(() -> { + PrismRecord prismRecord = prismManagerDataSource.getPrismTypeNameSync(name); + + if (VALUE_NEW.equals(finalType)) { + if (prismRecord != null) { + //点名重复,提示 + TipsFragment.tipsOnly( + getChildFragmentManager(), + getViewLifecycleOwner(), + getContext(), + Tools.getString(R.string.custom_name_cannot_be_repeated)); + return; + } + } + + //1.新建没有重名 + //2.编辑 + runOnUI(() -> { + onCallback(finalPrismTypeNameBefore, name, selectedItem, constant, getParentFragmentManager()); + SoftKeyUtils.hideSoftKey(); + dismiss(); + }); + + + }); + }); + } + Button cancel = contentView.findViewById(R.id.cancel); + if (cancel != null) { + cancel.setOnClickListener(v -> { + SoftKeyUtils.hideSoftKey(); + dismiss(); + }); + } + + } + return contentView; + } + + private void runOnUI(Runnable runnable) { + if (getActivity() != null) { + getActivity().runOnUiThread(runnable); + } + } + + private PrismManagerCreateCustomFragment() { + } + + private static void onCallback( + final String nameBefore, + final String name, + final String type, + final String constant, + final FragmentManager fragmentManager) { + Bundle args = new Bundle(); + + args.putString(KEY_PRISM_TYPE_NAME_BEFORE, nameBefore); + args.putString(KEY_PRISM_TYPE_NAME, name); + args.putString(KEY_PRISM_TYPE_LARGE, type); + args.putString(KEY_PRISM_TYPE_CONSTANT, constant); + + fragmentManager.setFragmentResult(KEY_REQUEST_INPUT, args); + } + + private static String string(MaterialEditText editText) { + if (editText == null || editText.getText() == null) { + return ""; + } + return editText.getText().toString().trim(); + } + + private static double doubleValue(MaterialEditText editText) { + String string = string(editText); + if (string.isEmpty()) { + return 0; + } + return Double.parseDouble(string); + } + + private static void setString(MaterialEditText editText, Bundle args, String key) { + if (editText == null || args == null) { + return; + } + editText.setText(args.getString(key)); + } + + + private static final String KEY_PRISM_TYPE_NAME = "KEY_PRISM_TYPE_NAME"; + private static final String KEY_PRISM_TYPE_NAME_BEFORE = "KEY_PRISM_TYPE_NAME_BEFORE"; + private static final String KEY_PRISM_TYPE_LARGE = "KEY_PRISM_TYPE_LARGE"; + private static final String KEY_PRISM_TYPE_CONSTANT = "KEY_PRISM_TYPE_CONSTANT"; + + private static final String KEY_TYPE = "KEY_TYPE"; + private static final String VALUE_NEW = "___new___"; + private static final String VALUE_EDIT = "___edit___"; + + private static final String KEY_REQUEST_INPUT = "___request__code___"; + + public static void create(FragmentManager fragmentManager, + LifecycleOwner lifecycleOwner, + @Nullable ICallback callback) { + Bundle args = new Bundle(); + show(fragmentManager, lifecycleOwner, args, callback); + } + + + public static void edit(FragmentManager fragmentManager, + LifecycleOwner lifecycleOwner, + String prismTypeName, + String prismTypeLarge, + String prismTypeConstant, + @Nullable ICallback callback) { + Bundle args = new Bundle(); + args.putString(KEY_PRISM_TYPE_NAME, prismTypeName); + args.putString(KEY_PRISM_TYPE_LARGE, prismTypeLarge); + args.putString(KEY_PRISM_TYPE_CONSTANT, prismTypeConstant); + args.putString(KEY_TYPE, VALUE_EDIT); + + show(fragmentManager, lifecycleOwner, args, callback); + } + + + private static void show(FragmentManager fragmentManager, + LifecycleOwner lifecycleOwner, + @Nullable Bundle args, + @Nullable ICallback callback) { + PrismManagerCreateCustomFragment fragment = new PrismManagerCreateCustomFragment(); + if (args != null) { + fragment.setArguments(args); + } + fragmentManager + .setFragmentResultListener( + KEY_REQUEST_INPUT, + lifecycleOwner, + (key, result) -> { + if (KEY_REQUEST_INPUT.equals(key)) { + if (callback == null) { + return; + } + callback.onGet( + result.getString(KEY_PRISM_TYPE_NAME_BEFORE, ""), + result.getString(KEY_PRISM_TYPE_NAME, ""), + result.getString(KEY_PRISM_TYPE_LARGE, ""), + result.getString(KEY_PRISM_TYPE_CONSTANT, "") + ); + } + }); + fragment.show(fragmentManager, PrismManagerCreateCustomFragment.class.getName()); + } + + public interface ICallback { + void onGet(String nameBefore, String name, String typeLarge, String constant); + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/ProjectListFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/ProjectListFragment.java new file mode 100644 index 0000000..a4a992a --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/ProjectListFragment.java @@ -0,0 +1,274 @@ +package com.bingce.controlnetwork.fragment; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.WorkerThread; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.datasource.database.ProjectType; +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.config.ConfigConstants; +import com.bingce.controlapphelper.datasource.database.config.ConfigRecord; +import com.bingce.controlapphelper.datasource.database.config.IConfigDataSource; +import com.bingce.controlapphelper.datasource.database.project.IProjectDataSource; +import com.bingce.controlapphelper.datasource.database.project.ProjectRecord; +import com.bingce.controlapphelper.datasource.database.surveyorcycle.ISurveyorPeriodDataSource; +import com.bingce.controlapphelper.datasource.database.surveyorcycle.SurveyorPeriodRecord; +import com.bingce.controlapphelper.datasource.database.tolerance.detail.IToleranceDetail; +import com.bingce.controlapphelper.datasource.database.tolerance.group.ToleranceGroupRecord; +import com.bingce.controlapphelper.datasource.database.tolerance.level.ToleranceLevelRecord; +import com.bingce.controlapphelper.datasource.database.tolerance.load.IToleranceOperate; +import com.bingce.controlapphelper.util.SurveyorRecordUtil; +import com.bingce.controlapphelper.util.ToleranceUtil; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.adapter.contextmenu.ContextMenuDeleteEdit; +import com.bingce.controlnetwork.fragment.base.BaseFragment; +import com.bingce.controlnetwork.fragment.projectdetail.ProjectDetailFragment; +import com.bingce.controlnetwork.fragment.projectedit.AbstractProjectEditFragment; +import com.bingce.controlnetwork.func.level.fragment.ProjectDetailLevelFragment; +import com.bingce.controlnetwork.newui.adapter.ProjectListAdapter; +import com.bingce.controlnetwork.newui.projectedit.ProjectCreateEditActivity; +import com.bingce.controlnetwork.newui.widget.selectitem.BaseSelectItemFragment; +import com.bingce.controlnetwork.newui.widget.selectitem.HorDividerDecoration; +import com.bingce.controlnetwork.newui.widget.selectitem.SelectProjectTypeFragment; +import com.bingce.controlnetwork.util.DialogUtil; +import com.bingce.controlnetwork.util.tolerance.ToleranceOperateUtil; +import com.bingce.surveyor.agentweb.AgentWebActivity; +import com.bingce.utils.ThreadPoolUtil; + +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +import jp.wasabeef.recyclerview.animators.FadeInLeftAnimator; + +/** + * 主页面-项目 + */ +public class ProjectListFragment extends BaseFragment { + private ProjectListAdapter projectListAdapter; + private RecyclerView recyclerView; + private View createNewProject; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.fragment_project_list, container, false); + recyclerView = view.findViewById(R.id.recycler_view_project_list); + createNewProject = view.findViewById(R.id.create_new); + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initView(); + initListener(); + initObserver(); + } + + private void initAdapter() { + recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); + recyclerView.setItemAnimator(new FadeInLeftAnimator()); + recyclerView.addItemDecoration(new HorDividerDecoration(requireContext())); + + projectListAdapter = new ProjectListAdapter(requireContext()); + projectListAdapter.setAdapterContextMenu(new ContextMenuDeleteEdit() { + @Override + protected void delete(ProjectRecord item) { + startDeleteProject(item); + } + + @Override + protected void edit(ProjectRecord item) { + startEditProject(item); + } + }); + projectListAdapter.setOnItemClickListener(this::goProjectDetail); + recyclerView.setAdapter(projectListAdapter); + } + + private void initListener() { + //新建项目 + createNewProject.setOnClickListener(v -> { + //选择项目类型 + BaseSelectItemFragment.select(new SelectProjectTypeFragment(), + getChildFragmentManager(), + getViewLifecycleOwner(), + value -> goCreateOrEditProject(value, null)); + }); + } + + /** + * 去新建项目或编辑项目 + */ + private void goCreateOrEditProject(String projctType, ProjectRecord projectRecord) { + if (ProjectType.isLevel(projctType)) { + String projectId = null; + if (projectRecord != null) { + projectId = projectRecord.getId(); + } + ProjectCreateEditActivity.launch(requireContext(), projctType, projectId); + } else { + if (projectRecord == null) { + AbstractProjectEditFragment.createProject(getChildFragmentManager(), requireContext(), projctType); + } else { + AbstractProjectEditFragment.editProject(getChildFragmentManager(), requireContext(), + projectRecord.getId(), projctType, projectRecord.getToleranceId(), projectRecord.getProjectName()); + } + } + } + + private void initObserver() { + SurveyorDatabaseFactory + .instance + .getProjectDataSource() + .getLiveDataList() + .observe(getViewLifecycleOwner(), this::addToleranceNameToProject); + } + + + private void addToleranceNameToProject(List projectRecords) { + ThreadPoolUtil.execute(() -> { + for (ProjectRecord record : projectRecords) { + String toleName = null; + IToleranceOperate operate = ToleranceOperateUtil.getOperate(record.getToleranceId()); + if (operate != null) { + IToleranceDetail iToleranceDetail = operate.getIToleranceDetail(record.getToleranceId()); + if (iToleranceDetail != null) { + ToleranceGroupRecord group = operate.getGroup(iToleranceDetail); + ToleranceLevelRecord level1 = operate.getLevel(iToleranceDetail); + toleName = ToleranceUtil.completedToleranceName(group, level1, iToleranceDetail); + } + } + record.toleranceName = toleName; + } + refreshAdapter(projectRecords); + }); + } + + private void refreshAdapter(List projectRecords) { + ThreadPoolUtil.executeInMain(() -> { + if (projectListAdapter != null) { + projectListAdapter.refreshData(projectRecords); + } + }); + } + + private void initView() { + initAdapter(); + } + + /** + * 进入项目详情 + */ + private void goProjectDetail(ProjectRecord item) { + if (ProjectType.isLevel(item.projectType)) { + ProjectDetailLevelFragment.start(requireContext(), item.projectType, item.getId(), item.getName()); + } else { + ProjectDetailFragment.start(requireContext(), + item.projectType, + item.getId(), + item.getName()); + } + } + + @Override + public void onCreateOptionsMenu(@NotNull Menu menu, @NotNull MenuInflater inflater) { + super.onCreateOptionsMenu(menu, inflater); + inflater.inflate(R.menu.menu_activity_project_list, menu); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (item.getItemId() == R.id.menu_activity_project_list_help) { + AgentWebActivity.navigation2(getContext(), "android_url_activity_project_list_help"); + } + return super.onOptionsItemSelected(item); + } + + private void startEditProject(ProjectRecord item) { + goCreateOrEditProject(item.projectType, item); + } + + private void startDeleteProject(ProjectRecord item) { + //删除的时候判断是否需要更新默认项目 + ThreadPoolUtil.execute(() -> { + //检测是否有测量数据 + if (SurveyorRecordUtil.isProjectSurveyor(item.getId())) { + //弹框提示 + runOnUI(() -> TipsFragment.cancelAbleTips( + getChildFragmentManager(), + getViewLifecycleOwner(), + requireContext(), + "要删除的项目存在测量数据,是否确认删除?", + 4, + () -> ThreadPoolUtil.execute(() -> doDelete(item)))); + } else { + ThreadPoolUtil.executeInMain(() -> { + DialogUtil.showConfirmDialog(getChildFragmentManager(), getViewLifecycleOwner(), "您确定要删除该项目吗?", + Tools.getString(R.string.confirm), () -> { + ThreadPoolUtil.execute(() -> { + doDelete(item); + }); + }); + }); + } + }); + } + + @WorkerThread + private void doDelete(ProjectRecord item) { + IProjectDataSource projectDataSource = SurveyorDatabaseFactory.instance.getProjectDataSource(); + IConfigDataSource configDataSource = SurveyorDatabaseFactory.instance.getConfigDataSource(); + + ConfigRecord defaultProject = configDataSource.getByKeySync(ConfigConstants.KEY_DEFAULT_PROJECT_ID); + + boolean needChangeDefaultProjectId = false; + if (defaultProject == null || defaultProject.getConfigValue().equals(item.getId())) { + needChangeDefaultProjectId = true; + } + + //先删除项目及关联 + projectDataSource.delete(item); + + if (needChangeDefaultProjectId) { + String projectId = ""; + String periodId = ""; + List projectRecords = projectDataSource.getDataList(); + if (projectRecords != null) { + ISurveyorPeriodDataSource surveyorPeriodDataSource = SurveyorDatabaseFactory.instance.getSurveyorPeriod(); + for (ProjectRecord projectRecord : projectRecords) { + if (projectRecord == null) { + continue; + } + List surveyorPeriodRecordList = surveyorPeriodDataSource.getDataListSyncByProjectId(projectRecord.getId()); + for (SurveyorPeriodRecord surveyorPeriodRecord : surveyorPeriodRecordList) { + if (surveyorPeriodRecord == null) { + continue; + } + periodId = surveyorPeriodRecord.getId(); + break; + } + if (!periodId.isEmpty()) { + projectId = projectRecord.getId(); + break; + } + } + } + configDataSource.set(ConfigConstants.KEY_DEFAULT_PROJECT_ID, projectId); + configDataSource.set(ConfigConstants.KEY_DEFAULT_PERIOD_ID, periodId); + } + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/ProjectToleranceSettingFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/ProjectToleranceSettingFragment.java new file mode 100644 index 0000000..6365e70 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/ProjectToleranceSettingFragment.java @@ -0,0 +1,107 @@ +package com.bingce.controlnetwork.fragment; + +import android.content.Context; +import android.os.Bundle; +import android.view.View; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.project.IProjectDataSource; +import com.bingce.controlapphelper.datasource.database.project.ProjectRecord; +import com.bingce.controlapphelper.datasource.database.tolerance.detail.IToleranceDetailDataSource; +import com.bingce.controlapphelper.datasource.database.tolerance.detail.ToleranceDetailRecord; +import com.bingce.controlapphelper.model.BundleConstants; +import com.bingce.controlapphelper.util.SurveyorRecordUtil; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.activity.fragmentcontainer.FragmentContainerActivity; +import com.bingce.utils.ThreadPoolUtil; + +import blankj.utilcode.util.ToastUtils; + +/* + * 项目限差详情,包含'LimitDetailFragment'+选择模板 + * */ +public class ProjectToleranceSettingFragment extends AbstractProjectToleranceFragment { + public static final int title = R.string.project_limite_detail; + public static final String TAG = ProjectToleranceSettingFragment.class.getName(); + + @Override + protected void onCurrentToleranceChanged(String toleranceId) { + super.onCurrentToleranceChanged(toleranceId); + if (getArguments() == null) { + return; + } + String projectId = getArguments().getString(BundleConstants.KEY_PROJECT_ID); + ThreadPoolUtil.execute(() -> { + IProjectDataSource projectDataSource = + SurveyorDatabaseFactory.instance.getProjectDataSource(); + ProjectRecord projectRecord = projectDataSource.getRecord(projectId); + projectRecord.setToleranceId(toleranceId); + projectDataSource.saveRecordSync(projectRecord); + }); + } + + @Override + protected void onCreateView(View view) { + //读取当前项目配置的限差方案,并设置限差界面 + if (getArguments() == null) { + return; + } + String projectId = getArguments().getString(BundleConstants.KEY_PROJECT_ID); + ThreadPoolUtil.execute(() -> { + IProjectDataSource projectDataSource = SurveyorDatabaseFactory + .instance + .getProjectDataSource(); + ProjectRecord projectRecord = projectDataSource.getRecord(projectId); + if (projectRecord == null) { + return; + } + String projectToleranceId = projectRecord.getToleranceId(); + //读取'限差方案'名称 + IToleranceDetailDataSource toleranceDataSource = SurveyorDatabaseFactory + .instance + .getToleranceDetailDataSource(); + ToleranceDetailRecord instance = toleranceDataSource.getRecordSync(projectToleranceId); + //设置限差详情 + if (instance == null) { + //修改项目限差配置 + toleranceDataSource.getDefaultRecord(defaultRecord -> { + projectRecord.setToleranceId(defaultRecord.getId()); + projectDataSource.saveRecordSync(projectRecord); + updateToleranceDetail(view, defaultRecord); + }); + } else { + updateToleranceDetail(view, instance); + } + }); + } + + @Override + protected void onSelectToleranceTemplateClick() { + //读取当前项目配置的限差方案,并设置限差界面 + if (getArguments() == null) { + return; + } + String projectId = getArguments().getString(BundleConstants.KEY_PROJECT_ID); + //判断当前project是否存在已经测量的station + ThreadPoolUtil.execute(() -> { + if (SurveyorRecordUtil.isProjectSurveyor(projectId)) { + ToastUtils.showShort(R.string.tips_tolerance_cannt_modify); + } else { + ProjectToleranceSettingFragment.super.onSelectToleranceTemplateClick(); + } + }); + } + + public static void start(Context context, String projectId, String projectType) { + Bundle bundle = new Bundle(); + bundle.putString(BundleConstants.KEY_PROJECT_ID, projectId); + bundle.putString(BundleConstants.KEY_PROJECT_TYPE, projectType); + FragmentContainerActivity.start(context, TAG, title, bundle); + } + + public static ProjectToleranceSettingFragment newInstance(Bundle bundle) { + ProjectToleranceSettingFragment fragment = new ProjectToleranceSettingFragment(); + fragment.setArguments(bundle); + return fragment; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/SelectExportHeightTraverseFragment.kt b/app/src/main/java/com/bingce/controlnetwork/fragment/SelectExportHeightTraverseFragment.kt new file mode 100644 index 0000000..5cc7222 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/SelectExportHeightTraverseFragment.kt @@ -0,0 +1,270 @@ +package com.bingce.controlnetwork.fragment + +import android.content.Context +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.annotation.MainThread +import androidx.fragment.app.DialogFragment +import blankj.utilcode.util.ToastUtils +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory +import com.bingce.controlapphelper.util.CheckStorageUtil +import com.bingce.controlapphelper.util.StationUtil.getStationName +import com.bingce.controlapphelper.util.StationUtil.getStationPointName +import com.bingce.controlapphelper.util.StationUtil.isStationCanExportForHeightTraverse +import com.bingce.controlapphelper.util.Tools +import com.bingce.controlnetwork.BuildConfig +import com.bingce.controlnetwork.R +import com.bingce.controlnetwork.activity.fragmentcontainer.FragmentContainerActivity +import com.bingce.controlnetwork.databinding.FragmentSelectExportSurveyorLayoutBinding +import com.bingce.controlnetwork.fragment.base.BaseFragment +import com.bingce.controlnetwork.surveyor.method.ExportUtilsPla +import com.bingce.controlnetwork.ui.widget.treeview.TreeNode +import com.bingce.controlnetwork.ui.widget.treeview.TreeView +import com.bingce.controlnetwork.ui.widget.treeview.custom.MyNodeViewFactory +import com.bingce.file.FileOperator +import com.bingce.utils.ThreadPoolUtil +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.MainScope +import kotlinx.coroutines.cancel +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import java.io.File + + +class SelectExportHeightTraverseFragment : BaseFragment() { + + private var _binding: FragmentSelectExportSurveyorLayoutBinding? = null + val mBinding get() = _binding!! + + private val mainScope = MainScope() + + val root: TreeNode = TreeNode.root() + + private val treeView: TreeView by lazy { + TreeView(root, requireContext(), MyNodeViewFactory()) + } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + _binding = FragmentSelectExportSurveyorLayoutBinding.inflate(inflater, container, false) + return mBinding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + mBinding.export.isEnabled = true + + mBinding.export.setOnClickListener { + if (ExportUtilsPla.isCanExport()) { + requestStoragePermission() + } + } + + initData() + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + mainScope.cancel() + } + + private fun initData() { + mainScope.launch { + withContext(Dispatchers.IO) { + buildNodeTree() + } + treeView.setup(mBinding.list) + mBinding.list.visibility = View.VISIBLE + mBinding.loading.visibility = View.GONE + } + } + + private suspend fun buildNodeTree() { + val projectDataSource = SurveyorDatabaseFactory.instance.projectDataSource + val projectRecordList = projectDataSource.dataList + + for (projectRecord in projectRecordList) { + //遍历项目 + //一级数据 + val projectNode = + TreeNode(TreeNode.Value(projectRecord.projectName, projectRecord.id), 0) + + val routeList = SurveyorDatabaseFactory.instance.getRouteDataSource() + .getByProjectId(projectRecord.getId()) + + var projectHasData = false + + for (routeRecord in routeList) { + //遍历路线 + //二级数据 + val periodNode = + TreeNode(TreeNode.Value(routeRecord.name, routeRecord.id), 1) + + val stationList = + SurveyorDatabaseFactory.instance.surveyorStation.getByProjectRoute( + projectRecord.getId(), + routeRecord.getId() + ) + + var routeHasData = false + + for (stationRecord in stationList) { + //遍历测站 + if (stationRecord == null) { + continue + } + + val exportItem = ExportUtilsPla.ExportItem( + projectRecord.getProjectName(), projectRecord.getId(), + projectRecord.projectType, + routeRecord.getId(), routeRecord.name, + stationRecord.getId(), + getStationName(stationRecord), + getStationPointName(stationRecord) + ) + + //三级数据 + val stationNode = TreeNode( + TreeNode.Value(exportItem, stationRecord.getId()), + 2 + ) + //添加三级数据 + periodNode.addChild(stationNode) + + val stationCanExport = isStationCanExportForHeightTraverse(stationRecord) + stationNode.isEnable = stationCanExport + if (stationCanExport) { + projectHasData = true + routeHasData = true + } + } + + //添加二级数据 + periodNode.isEnable = routeHasData + projectNode.addChild(periodNode) + + } + + projectNode.isEnable = projectHasData + //添加一级数据 + root.addChild(projectNode) + } + + } + + companion object { + @JvmField + val TAG: String = SelectExportHeightTraverseFragment::class.java.name + + @JvmStatic + fun newInstance(args: Bundle?): SelectExportHeightTraverseFragment { + val fragment = SelectExportHeightTraverseFragment() + fragment.arguments = args + return fragment + } + + @JvmStatic + fun start(context: Context) { + FragmentContainerActivity.start( + context, + TAG, + R.string.export_height_traverse, + null + ) + } + + } + + + private fun requestStoragePermission() { + CheckStorageUtil.check(context) { exportHasPermission() } + } + + private fun exportHasPermission() { + val dialogFragment: DialogFragment = FullLoadingFragment.showLoading(childFragmentManager) + doExport(root, requireContext(), object : ICallback { + override fun onFailureInMainThread(msg: String?) { + dialogFragment.dismiss() + ToastUtils.showShort(R.string.tips_please_select_exported_data) + } + + override fun onSuccessInMainThread(zip: File) { + if (dialogFragment.isVisible) { + dialogFragment.dismiss() + } + TipsWith2OptionFragment.tipsCannotCancel( + childFragmentManager, viewLifecycleOwner, + getString(R.string.share), + getString(R.string.cancel), + getString(R.string.export_successful), + object : TipsWith2OptionFragment.SimpleCallback() { + override fun onConfirm() { + FileOperator.shareFile(context, zip, BuildConfig.APPLICATION_ID) + } + }) + } + }) + } + + private interface ICallback { + fun onFailureInMainThread(msg: String?) + fun onSuccessInMainThread(zip: File) + } + + @MainThread + private fun doExport( + root: TreeNode, + context: Context, + callback: ICallback + ) { + ThreadPoolUtil.execute { + + //层遍历node树,找到所有被选中的station + val exportItem: MutableList = + ArrayList() + val nodeList: MutableList = + ArrayList() + nodeList.add(root) + while (!nodeList.isEmpty()) { + val first = nodeList.removeAt(0) + if (first.isEnable && first.isSelected && first.value + .value is ExportUtilsPla.ExportItem + ) { + exportItem.add(first.value.value as ExportUtilsPla.ExportItem) + } + nodeList.addAll(first.children) + } + if (exportItem.isEmpty()) { + if (callback != null) { + ThreadPoolUtil.executeInMain { + callback.onFailureInMainThread( + context.getString( + R.string.error_tips_please_select_exported_station + ) + ) + } + } + return@execute + } + + //执行导出 + val zip = ExportUtilsPla.doExportHeightTraverse(context, exportItem) + //提示导出成功 + ThreadPoolUtil.executeInMain { + if (zip == null) { + callback.onFailureInMainThread(Tools.getString(R.string.export_failure)) + } else { + callback.onSuccessInMainThread(zip) + } + } + } + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/SelectExportSurveyorRecordFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/SelectExportSurveyorRecordFragment.java new file mode 100644 index 0000000..4e0fe0e --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/SelectExportSurveyorRecordFragment.java @@ -0,0 +1,247 @@ +package com.bingce.controlnetwork.fragment; + +import android.content.Context; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.MainThread; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.WorkerThread; +import androidx.fragment.app.DialogFragment; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.project.IProjectDataSource; +import com.bingce.controlapphelper.datasource.database.project.ProjectRecord; +import com.bingce.controlapphelper.datasource.database.surveyorcycle.ISurveyorPeriodDataSource; +import com.bingce.controlapphelper.datasource.database.surveyorcycle.SurveyorPeriodRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.ISurveyorStationDataSource; +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord; +import com.bingce.controlapphelper.surveyor.method.ExportUtils; +import com.bingce.controlapphelper.util.CheckStorageUtil; +import com.bingce.controlapphelper.util.StationUtil; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.BuildConfig; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.activity.fragmentcontainer.FragmentContainerActivity; +import com.bingce.controlnetwork.fragment.base.BaseFragment; +import com.bingce.controlnetwork.newui.configfragment.SelectExportType; +import com.bingce.controlnetwork.surveyor.method.ExportUtilsPla; +import com.bingce.controlnetwork.ui.widget.treeview.TreeNode; +import com.bingce.controlnetwork.ui.widget.treeview.TreeView; +import com.bingce.controlnetwork.ui.widget.treeview.custom.MyNodeViewFactory; +import com.bingce.file.FileOperator; +import com.bingce.utils.ThreadPoolUtil; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +import blankj.utilcode.util.ToastUtils; + +/** + * 观测数据导出(基于选择的站的点数据导出) + */ +public class SelectExportSurveyorRecordFragment extends BaseFragment { + public static final String TAG = SelectExportSurveyorRecordFragment.class.getName(); + private TreeNode root; + private TreeView treeView; + private boolean isOpen = false; + + public static final String KEY_DATA = "key_data"; + private ArrayList selectExportTypeList; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + root = TreeNode.root(); + if (getContext() != null) { + treeView = new TreeView(root, getContext(), new MyNodeViewFactory()); + } + View rootView = inflater.inflate(R.layout.fragment_select_export_surveyor_layout, container, false); + View exportBtn = rootView.findViewById(R.id.export); + exportBtn.setEnabled(true); + + exportBtn.setOnClickListener(v -> { + if (ExportUtilsPla.isCanExport()) { + requestStoragePermission(); + } + }); + + ThreadPoolUtil.execute(() -> { + buildNodeTree(root); + ThreadPoolUtil.executeInMain(() -> { + RecyclerView list = rootView.findViewById(R.id.list); + treeView.setup(list); + list.setVisibility(View.VISIBLE); + View loading = rootView.findViewById(R.id.loading); + loading.setVisibility(View.GONE); + }); + }); + return rootView; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + selectExportTypeList = getSelectExportTypeList(); + } + + @MainThread + private void doExport(TreeNode root, + Context context, + ICallback callback) { + ThreadPoolUtil.execute(() -> { + //层遍历node树,找到所有被选中的station + List exportItem = new ArrayList<>(); + List nodeList = new ArrayList<>(); + nodeList.add(root); + while (!nodeList.isEmpty()) { + TreeNode first = nodeList.remove(0); + if (first.isEnable() && first.isSelected() && first.getValue().getValue() instanceof ExportUtils.ExportItem) { + exportItem.add((ExportUtilsPla.ExportItem) first.getValue().getValue()); + } + nodeList.addAll(first.getChildren()); + } + if (exportItem.isEmpty()) { + if (callback != null) { + ThreadPoolUtil.executeInMain(() -> callback.onFailureInMainThread(context.getString(R.string.error_tips_please_select_exported_station))); + } + return; + } + + //执行导出 + File zip = ExportUtilsPla.doExport(context, exportItem, selectExportTypeList); + //提示导出成功 + if (callback != null) { + ThreadPoolUtil.executeInMain(() -> { + if (zip == null) { + callback.onFailureInMainThread(Tools.getString(R.string.export_failure)); + } else { + callback.onSuccessInMainThread(zip); + } + }); + } + }); + } + + private interface ICallback { + void onFailureInMainThread(String msg); + + void onSuccessInMainThread(File zip); + } + + /** + * 根据 + *

+ * (项目->测期->测站) + *

+ * 三级结构,构建node树 + *

+ * 检测每个测站数据是否正常记录,如果没有则将其设置为不可选中状态 + * + * @param root node树的根节点 + */ + @WorkerThread + private static void buildNodeTree(TreeNode root) { + IProjectDataSource projectDataSource = SurveyorDatabaseFactory.instance.getProjectDataSource(); + List projectRecordList = projectDataSource.getDataList(); + for (ProjectRecord projectRecord : projectRecordList) {//遍历项目 + TreeNode projectNode = + new TreeNode(new TreeNode.Value(projectRecord.projectName, projectRecord.id), 0); + ISurveyorPeriodDataSource surveyorPeriodDataSource = SurveyorDatabaseFactory.instance.getSurveyorPeriod(); + List surveyorPeriodRecordList = surveyorPeriodDataSource.getDataListSyncByProjectId(projectRecord.getId()); + + boolean projectHasData = false; + for (SurveyorPeriodRecord periodRecord : surveyorPeriodRecordList) {//遍历测期 + TreeNode periodNode = new TreeNode(new TreeNode.Value(periodRecord.getName(), periodRecord.id), 1); + ISurveyorStationDataSource surveyorStationDataSource = SurveyorDatabaseFactory.instance.getSurveyorStation(); + List stationRecordList = surveyorStationDataSource.getDataList(projectRecord.getId(), periodRecord.getId()); + + boolean periodHasData = false; + for (SurveyorStationRecord stationRecord : stationRecordList) {//遍历测站 + if (stationRecord == null) { + continue; + } + ExportUtils.ExportItem exportItem = + new ExportUtils.ExportItem(projectRecord.getProjectName(), projectRecord.getId(), + projectRecord.projectType, + periodRecord.getId(), periodRecord.getName(), + stationRecord.getId(), + StationUtil.getStationName(stationRecord), + StationUtil.getStationPointName(stationRecord)); + TreeNode stationNode = new TreeNode(new TreeNode.Value(exportItem, stationRecord.getId()), + 2); + periodNode.addChild(stationNode); + + boolean stationCanExport = StationUtil.isStationCanExport(stationRecord); + stationNode.setEnable(stationCanExport); + if (stationCanExport) { + projectHasData = true; + periodHasData = true; + } + } + + periodNode.setEnable(periodHasData); + projectNode.addChild(periodNode); + } + + projectNode.setEnable(projectHasData); + root.addChild(projectNode); + } + } + + public static SelectExportSurveyorRecordFragment newInstance(Bundle args) { + SelectExportSurveyorRecordFragment fragment = new SelectExportSurveyorRecordFragment(); + fragment.setArguments(args); + return fragment; + } + + public static void start(Context context, Bundle bundle) { + FragmentContainerActivity.start(context, TAG, R.string.export, bundle); + } + + public void requestStoragePermission() { + CheckStorageUtil.check(getContext(), this::exportHasPermission); + } + + private void exportHasPermission() { + DialogFragment dialogFragment = FullLoadingFragment.showLoading(getChildFragmentManager()); + doExport(root, getContext(), new ICallback() { + @Override + public void onFailureInMainThread(String msg) { + dialogFragment.dismiss(); + ToastUtils.showShort(R.string.tips_please_select_exported_data); + } + + @Override + public void onSuccessInMainThread(File zip) { + if (dialogFragment.isVisible()) { + dialogFragment.dismiss(); + } + TipsWith2OptionFragment.tipsCannotCancel(getChildFragmentManager(), getViewLifecycleOwner(), + getString(R.string.share), + getString(R.string.cancel), + getString(R.string.export_successful), + new TipsWith2OptionFragment.SimpleCallback() { + @Override + public void onConfirm() { + FileOperator.shareFile(getContext(), zip, BuildConfig.APPLICATION_ID); + } + }); + } + }); + } + + private ArrayList getSelectExportTypeList() { + Bundle arguments = getArguments(); + if (arguments != null) { + return arguments.getParcelableArrayList(KEY_DATA); + } + return null; + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/SelectExportSurveyorRecordWireFileFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/SelectExportSurveyorRecordWireFileFragment.java new file mode 100644 index 0000000..922c62f --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/SelectExportSurveyorRecordWireFileFragment.java @@ -0,0 +1,295 @@ +package com.bingce.controlnetwork.fragment; + +import android.content.Context; +import android.os.Bundle; +import android.os.Environment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.MainThread; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.WorkerThread; +import androidx.fragment.app.DialogFragment; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.line.LineRecord; +import com.bingce.controlapphelper.datasource.database.project.IProjectDataSource; +import com.bingce.controlapphelper.datasource.database.project.ProjectRecord; +import com.bingce.controlapphelper.datasource.database.schedule.ISurveyorScheduleDataSource; +import com.bingce.controlapphelper.datasource.database.surveyorcycle.ISurveyorPeriodDataSource; +import com.bingce.controlapphelper.datasource.database.surveyorcycle.SurveyorPeriodRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.ISurveyorStationDataSource; +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord; +import com.bingce.controlapphelper.surveyor.method.ExportUtils; +import com.bingce.controlapphelper.util.CheckStorageUtil; +import com.bingce.controlapphelper.util.StationUtil; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.BuildConfig; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.activity.fragmentcontainer.FragmentContainerActivity; +import com.bingce.controlnetwork.fragment.base.BaseFragment; +import com.bingce.controlnetwork.surveyor.method.ExportUtilsPla; +import com.bingce.controlnetwork.ui.widget.treeview.TreeNode; +import com.bingce.controlnetwork.ui.widget.treeview.TreeView; +import com.bingce.controlnetwork.ui.widget.treeview.custom.MyNodeViewFactory; +import com.bingce.file.FileOperator; +import com.bingce.utils.ThreadPoolUtil; +import com.bingce.zip.ZipUtil; + +import java.io.File; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; + +import blankj.utilcode.util.FileUtils; +import blankj.utilcode.util.ToastUtils; + +/** + * 导线文件导出(基于选择的导线数据导出) + */ +public class SelectExportSurveyorRecordWireFileFragment extends BaseFragment { + public static final String TAG = SelectExportSurveyorRecordWireFileFragment.class.getName(); + private TreeNode root; + private TreeView treeView; + private boolean isOpen = false; + private Date currentDate, expireDate; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + root = TreeNode.root(); + if (getContext() != null) { + treeView = new TreeView(root, getContext(), new MyNodeViewFactory()); + } + View rootView = inflater.inflate(R.layout.fragment_select_export_surveyor_layout, container, false); + View exportBtn = rootView.findViewById(R.id.export); + exportBtn.setEnabled(true); + exportBtn.setOnClickListener(v -> { + if (ExportUtilsPla.isCanExport()) { + requestStoragePermission(); + } + }); + + ThreadPoolUtil.execute(() -> { + buildNodeTree(root); + ThreadPoolUtil.executeInMain(() -> { + RecyclerView list = rootView.findViewById(R.id.list); + treeView.setup(list); + list.setVisibility(View.VISIBLE); + View loading = rootView.findViewById(R.id.loading); + loading.setVisibility(View.GONE); + }); + }); + return rootView; + } + + @MainThread + private static void doExport(TreeNode root, + Context context, + ICallback callback) { + ThreadPoolUtil.execute(() -> { + //层遍历node树,找到所有被选中的station + List exportItem = new ArrayList<>(); + List nodeList = new ArrayList<>(); + nodeList.add(root); + while (!nodeList.isEmpty()) { + TreeNode first = nodeList.remove(0); + if (first.isEnable() && first.isSelected() && first.getValue().getValue() instanceof ExportUtils.ExportItem) { + exportItem.add((ExportUtils.ExportItem) first.getValue().getValue()); + } + nodeList.addAll(first.getChildren()); + } + if (exportItem.isEmpty()) { + if (callback != null) { + ThreadPoolUtil.executeInMain(() -> callback.onFailureInMainThread(context.getString(R.string.error_tips_please_select_exported_station))); + } + return; + } + + //获取测站测期的完整数据列表 +// List exportCompleteLoopList = getExportProjectPeridList(root); + + //执行导出 + String exportFolder = "导线助手导出文件" + File.separator + "导线文件导出"; + List files = ExportUtils.doExportWire(context, exportItem, exportFolder); + + //将文件存储到一个zip中 + String absolutePath = Environment.getExternalStorageDirectory().getAbsolutePath(); +// File appSharedFolder = PathManager.appDocumentFolder(); + Date date = new Date(); + SimpleDateFormat format = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss", Locale.getDefault()); + String dateString = format.format(date); + File zip = new File(absolutePath, exportFolder + File.separator + dateString + ".zip"); + if (!ZipUtil.zip(zip, files)) { + zip = null; + } + //存储成功,删除zip文件 + for (File file : files) { + if (file == null) { + continue; + } + FileUtils.delete(file); + } + + //提示导出成功 + if (callback != null) { + File finalZip = zip; + ThreadPoolUtil.executeInMain(() -> { + if (finalZip == null) { + callback.onFailureInMainThread(Tools.getString(R.string.export_failure)); + } else { + callback.onSuccessInMainThread(finalZip); + } + }); + } + }); + } + + private interface ICallback { + void onFailureInMainThread(String msg); + + void onSuccessInMainThread(File zip); + } + + /** + * 根据 + *

+ * (项目->测期->测站) + *

+ * 三级结构,构建node树 + *

+ * 检测每个测站数据是否正常记录,如果没有则将其设置为不可选中状态 + * + * @param root node树的根节点 + */ + @WorkerThread + private static void buildNodeTree(TreeNode root) { + IProjectDataSource projectDataSource = SurveyorDatabaseFactory.instance.getProjectDataSource(); + List projectRecordList = projectDataSource.getDataList(); + //遍历项目 + for (ProjectRecord projectRecord : projectRecordList) { + //创建项目节点 + TreeNode projectNode = + new TreeNode(new TreeNode.Value(projectRecord.projectName, projectRecord.id), 0); + ISurveyorPeriodDataSource surveyorPeriodDataSource = SurveyorDatabaseFactory.instance.getSurveyorPeriod(); + List surveyorPeriodRecordList = surveyorPeriodDataSource.getDataListSyncByProjectId(projectRecord.getId()); + boolean projectHasData = false; + //遍历测期 + for (SurveyorPeriodRecord periodRecord : surveyorPeriodRecordList) { + //创建测期节点 + TreeNode periodNode = new TreeNode(new TreeNode.Value(periodRecord.getName(), periodRecord.id), 1); + ISurveyorStationDataSource surveyorStationDataSource = SurveyorDatabaseFactory.instance.getSurveyorStation(); + List stationRecordList = surveyorStationDataSource.getDataList(projectRecord.getId(), periodRecord.getId()); + ISurveyorScheduleDataSource surveyorScheduleDataSource = SurveyorDatabaseFactory.instance.getScheduleDataSource(); + + boolean periodHasData = false; + //遍历测站 + if (stationRecordList == null || stationRecordList.isEmpty()) { + continue; + } + + //初始化导线数据map + Map lineMap = new HashMap<>(); + for (SurveyorStationRecord stationRecord : stationRecordList) { + if (stationRecord == null) { + continue; + } + String lineId = stationRecord.getLineId(); + LineRecord lineRecord = SurveyorDatabaseFactory.instance.getLineRecordDatabase().findById(lineId); + if (lineRecord == null) { + continue; + } + if (LineRecord.TYPE_MUL_ANGLE.equals(StationUtil.getLineTypeFromStation(stationRecord))) { + //排除多测回测角 + continue; + } + if (lineMap.containsKey(lineId)) { + LineRecord lineRecordAlready = lineMap.get(lineId); + if (lineRecordAlready != null && lineRecordAlready.isCanSelected) { + lineRecordAlready.isCanSelected = StationUtil.isStationCanExport(stationRecord); + } + } else { + lineRecord.isCanSelected = StationUtil.isStationCanExport(stationRecord); + lineMap.put(lineId, lineRecord); + } + } + + //添加第三节点 导线 + for (LineRecord lineRecord : lineMap.values()) { + ExportUtils.ExportItem exportItem = + new ExportUtils.ExportItem(projectRecord.getProjectName(), projectRecord.getId(), + projectRecord.projectType, + periodRecord.getId(), periodRecord.getName(), + lineRecord.id, + lineRecord.name, + ""); + TreeNode lineNode = new TreeNode(new TreeNode.Value(exportItem, lineRecord.id), + 2); + + lineNode.setEnable(lineRecord.isCanSelected); + periodNode.addChild(lineNode); + + if (lineRecord.isCanSelected) { + projectHasData = true; + periodHasData = true; + } + } + + periodNode.setEnable(periodHasData); + projectNode.addChild(periodNode); + } + + projectNode.setEnable(projectHasData); + root.addChild(projectNode); + } + } + + public static SelectExportSurveyorRecordWireFileFragment newInstance(Bundle args) { + SelectExportSurveyorRecordWireFileFragment fragment = new SelectExportSurveyorRecordWireFileFragment(); + fragment.setArguments(args); + return fragment; + } + + public static void start(Context context) { + FragmentContainerActivity.start(context, TAG, R.string.export_wire_file, null); + } + + public void requestStoragePermission() { + CheckStorageUtil.check(getContext(), this::exportHasPermission); + } + + private void exportHasPermission() { + DialogFragment dialogFragment = FullLoadingFragment.showLoading(getChildFragmentManager()); + doExport(root, getContext(), new SelectExportSurveyorRecordWireFileFragment.ICallback() { + @Override + public void onFailureInMainThread(String msg) { + dialogFragment.dismiss(); + ToastUtils.showShort(R.string.tips_please_select_exported_data); + } + + @Override + public void onSuccessInMainThread(File zip) { + if (dialogFragment.isVisible()) { + dialogFragment.dismiss(); + } + TipsWith2OptionFragment.tipsCannotCancel(getChildFragmentManager(), getViewLifecycleOwner(), + getString(R.string.share), + getString(R.string.cancel), + getString(R.string.export_successful), + new TipsWith2OptionFragment.SimpleCallback() { + @Override + public void onConfirm() { + FileOperator.shareFile(getContext(), zip, BuildConfig.APPLICATION_ID); + } + }); + } + }); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/SelectProjectAndSurveyorCycleFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/SelectProjectAndSurveyorCycleFragment.java new file mode 100644 index 0000000..f2ace7d --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/SelectProjectAndSurveyorCycleFragment.java @@ -0,0 +1,163 @@ +package com.bingce.controlnetwork.fragment; + +import android.content.DialogInterface; +import android.os.Bundle; +import android.view.Gravity; +import android.view.KeyEvent; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.Window; +import android.view.WindowManager; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.DialogFragment; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; + +import com.bingce.controlapphelper.model.BundleConstants; +import com.bingce.controlnetwork.R; + +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; +import org.greenrobot.eventbus.ThreadMode; +import org.jetbrains.annotations.NotNull; + +/** + * 弹框,先选项目,再选测期 + */ +public class SelectProjectAndSurveyorCycleFragment extends DialogFragment { + public static final String TAG = SelectProjectAndSurveyorCycleFragment.class.getName(); + private ComponentSwitchStationListFragment componentSwitchStationListFragment; + + private SelectProjectAndSurveyorCycleFragment() { + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View view = inflater + .inflate(R.layout.fragment_single_framelayout_layout, + container, + false); + String currentProjectId = ""; + String cycleId = ""; + if (getArguments() != null) { + currentProjectId = getArguments().getString(BundleConstants.KEY_PROJECT_ID); + cycleId = getArguments().getString(BundleConstants.KEY_PERIOD_ID); + } + + componentSwitchStationListFragment = + ComponentSwitchStationListFragment.newInstance(currentProjectId, cycleId); + + getChildFragmentManager() + .beginTransaction() + .replace(R.id.container, componentSwitchStationListFragment) + .commit(); + + view.setOnClickListener(v -> dismiss()); + return view; + } + + @Override + public void onViewCreated(@NonNull @NotNull View view, @Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + + if (getDialog() != null) { + final Window window = getDialog().getWindow(); + + window.setWindowAnimations(R.style.animate_dialog); + window.setBackgroundDrawable(null); + + WindowManager.LayoutParams params = window.getAttributes(); + params.gravity = Gravity.BOTTOM; + params.width = ViewGroup.LayoutParams.MATCH_PARENT; + params.height = ViewGroup.LayoutParams.WRAP_CONTENT; + window.setAttributes(params); + } + } + + @Override + public void onStart() { + super.onStart(); + EventBus.getDefault().register(this); + getDialog().setOnKeyListener(new DialogInterface.OnKeyListener() { + @Override + public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) { + if ((keyCode == android.view.KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP)) { + if (!componentSwitchStationListFragment.doBack()) { + dismiss(); + } + return true; + } + return false; + } + }); + } + + @Override + public void onStop() { + super.onStop(); + EventBus.getDefault().unregister(this); + } + + @Subscribe(threadMode = ThreadMode.MAIN) + public void onMessageEvent(SelectedResult event) { + Bundle args = new Bundle(); + args.putString(BundleConstants.KEY_PROJECT_ID, event.projectId); + args.putString(BundleConstants.KEY_PROJECT_NAME, event.projectName); + args.putString(BundleConstants.KEY_PERIOD_ID, event.cycleId); + args.putString(BundleConstants.KEY_PERIOD_NAME, event.cycleName); + getParentFragmentManager() + .setFragmentResult(KEY_REQUEST_SELECT, args); + dismiss(); + } + + private static final String KEY_REQUEST_SELECT = "__SELECT__"; + + public static void select(FragmentManager fragmentManager, + @NonNull LifecycleOwner lifecycleOwner, + String defaultProjectId, + String defaultToleranceId, + IOnSelectCallback callback) { + Bundle args = new Bundle(); + args.putString(BundleConstants.KEY_PROJECT_ID, defaultProjectId); + args.putString(BundleConstants.KEY_PERIOD_ID, defaultToleranceId); + SelectProjectAndSurveyorCycleFragment fragment = new SelectProjectAndSurveyorCycleFragment(); + fragment.setArguments(args); + fragmentManager + .setFragmentResultListener( + KEY_REQUEST_SELECT, + lifecycleOwner, + (requestKey, result) -> { + if (KEY_REQUEST_SELECT.equals(requestKey)) { + callback.onSurveyorCycleSelected( + result.getString(BundleConstants.KEY_PROJECT_ID), + result.getString(BundleConstants.KEY_PROJECT_NAME), + result.getString(BundleConstants.KEY_PERIOD_ID), + result.getString(BundleConstants.KEY_PERIOD_NAME)); + } + }); + fragment.show(fragmentManager, TAG); + } + + public interface IOnSelectCallback { + void onSurveyorCycleSelected(String projectId, String projectName, String cycleId, String cycleName); + } + + public static class SelectedResult { + public final String projectId; + public final String projectName; + public final String cycleId; + public final String cycleName; + + public SelectedResult(String projectId, String projectName, + String cycleId, String cycleName) { + this.projectId = projectId; + this.projectName = projectName; + this.cycleId = cycleId; + this.cycleName = cycleName; + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/SelectReSurveyorCycleFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/SelectReSurveyorCycleFragment.java new file mode 100644 index 0000000..34653b5 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/SelectReSurveyorCycleFragment.java @@ -0,0 +1,139 @@ +package com.bingce.controlnetwork.fragment; + +import android.app.Dialog; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; + +import com.bingce.controlapphelper.model.UniversalListItem; +import com.bingce.controlapphelper.model.ViewItemType; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.adapter.ReSurveyorCycleAdapter; +import com.bingce.controlnetwork.databinding.FragmentResurveryorLayoutCycleBinding; +import com.google.android.material.bottomsheet.BottomSheetDialogFragment; + +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +import blankj.utilcode.util.ToastUtils; + +import com.bingce.controlnetwork.adapter.ReSurveyorCycleAdapter; + +/** + * 高程导线 + * 选择要重测的测回 + */ +public class SelectReSurveyorCycleFragment extends BaseBottomSheetDialogFragment { + private FragmentResurveryorLayoutCycleBinding mBinding; + + private int resultCycleIndex = -1; + + @Nullable + @Override + public View onCreateView(@NonNull @NotNull LayoutInflater inflater, + @Nullable ViewGroup container, + @Nullable Bundle savedInstanceState) { + mBinding = FragmentResurveryorLayoutCycleBinding.inflate(inflater, container, false); + + List> items = new ArrayList<>(); + + if (getArguments() != null) { + int cycleCount = getArguments().getInt(KEY_CYCLE_COUNT, 0); + for (int i = 0; i < cycleCount; i++) { + UniversalListItem item = new UniversalListItem() { + @Override + public ViewItemType getType() { + return ViewItemType.indexWithName; + } + }; + item.setName(Tools.getString(R.string.test_n_cycle, (i + 1))); + items.add(item); + } + } + + ReSurveyorCycleAdapter adapter = new ReSurveyorCycleAdapter(items, cycleIndex -> { + resultCycleIndex = cycleIndex; + }); + mBinding.list.setAdapter(adapter); + + mBinding.confirm.setOnClickListener(v -> { + if (resultCycleIndex == -1) { + ToastUtils.showShort(R.string.please_select_retest_cycle); + return; + } + Bundle args = new Bundle(); + args.putInt(KEY_RESULT_CYCLE, resultCycleIndex); + getParentFragmentManager().setFragmentResult(KEY_REQUEST_TIME, args); + dismiss(); + }); + + return mBinding.getRoot(); + } + + + @Override + public void onDestroyView() { + super.onDestroyView(); + mBinding = null; + } + + public static final String KEY_REQUEST_TIME = "KEY_REQUEST_TIME_ID"; + + + private static final String KEY_CYCLE_COUNT = "__cycle_count__ "; + private static final String KEY_RESULT_CYCLE = "__result_cycle__ "; + + private SelectReSurveyorCycleFragment() { + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + Dialog dialog = getDialog(); + if (dialog == null) { + return; + } + dialog.setOnDismissListener(dialogInterface -> { + Bundle args = new Bundle(); + getParentFragmentManager().setFragmentResult(KEY_REQUEST_TIME, args); + dismiss(); + }); + } + + public static void start(@NonNull FragmentManager fragmentManager, + @NonNull LifecycleOwner lifecycleOwner, + int cycleCount, + ISelectedCallback callback) { + if (callback == null) { + return; + } + fragmentManager + .setFragmentResultListener( + KEY_REQUEST_TIME, + lifecycleOwner, + (requestKey, result) -> { + if (KEY_REQUEST_TIME.equals(requestKey)) { + int targetCycleIndex = result.getInt(KEY_RESULT_CYCLE, -1); + callback.onSelected(targetCycleIndex); + } + }); + BottomSheetDialogFragment fragment = new SelectReSurveyorCycleFragment(); + Bundle args = new Bundle(); + args.putInt(KEY_CYCLE_COUNT, cycleCount); + fragment.setArguments(args); + fragment.show(fragmentManager, SelectReSurveyorCycleFragment.class.getName()); + } + + public interface ISelectedCallback { + void onSelected(int cycleIndex); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/SelectReSurveyorPointFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/SelectReSurveyorPointFragment.java new file mode 100644 index 0000000..ccc6f80 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/SelectReSurveyorPointFragment.java @@ -0,0 +1,176 @@ +package com.bingce.controlnetwork.fragment; + +import android.app.Dialog; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.util.SurveyorCycleUtil; +import com.bingce.controlnetwork.adapter.ResurveyorPointsAdapter; +import com.google.android.material.bottomsheet.BottomSheetDialogFragment; + +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.adapter.ResurveyorPointsAdapter; + +/** + * 选择要补测的方向 + */ +public class SelectReSurveyorPointFragment extends BaseBottomSheetDialogFragment { + private int cycleIndex = -1; + + @Nullable + @Override + public View onCreateView(@NonNull @NotNull LayoutInflater inflater, + @Nullable ViewGroup container, + @Nullable Bundle savedInstanceState) { + View rootView = inflater.inflate(R.layout.fragment_resurveryor_layout, container, false); + + RecyclerView recyclerView = rootView.findViewById(R.id.list); + if (recyclerView != null && getArguments() != null) { + int cycleCount = getArguments().getInt(KEY_CYCLE_COUNT); + boolean showLeftOrRight = getArguments().getBoolean(KEY_SHOW_LEFT_RIGHT, false); + if (cycleCount > 0) { + cycleIndex = 0; + View layoutCycle = rootView.findViewById(R.id.layout_cycle); + if (layoutCycle != null) { + layoutCycle.setVisibility(View.VISIBLE); + TextView cycleText = rootView.findViewById(R.id.cycle_text); + layoutCycle.setOnClickListener(v -> { + ArrayList cycleList = SurveyorCycleUtil.cycleStrings(cycleCount, showLeftOrRight); + runOnUI(() -> BottomSheetSelectListFragment.showSelect( + getChildFragmentManager(), + getViewLifecycleOwner(), + cycleIndex, + cycleList, + null,//不再限制测期 + (index, string) -> { + cycleIndex = index; + if (cycleText != null) { + cycleText.setText(string); + } + })); + }); + } + } + + //默认添加0方向 + List allPointIds = getArguments().getStringArrayList(KEY_ALL_POINT_IDS); + List allPointNames = getArguments().getStringArrayList(KEY_ALL_POINT_NAMES); + + List items = new ArrayList<>(); + for (int index = 0; index < allPointIds.size(); index++) { + ResurveyorPointsAdapter.Item item = + new ResurveyorPointsAdapter.Item(allPointNames.get(index), allPointIds.get(index)); + items.add(item); + } + ResurveyorPointsAdapter adapter = new ResurveyorPointsAdapter( + Collections.singletonList(allPointIds.get(0)), + items, + getContext(), + getChildFragmentManager(), + getViewLifecycleOwner()); + recyclerView.setAdapter(adapter); + + Button confirm = rootView.findViewById(R.id.confirm); + if (confirm != null) { + confirm.setOnClickListener(v -> { + Bundle args = new Bundle(); + List ids = adapter.selectedIds(); + ArrayList results = new ArrayList<>(ids); + args.putStringArrayList(KEY_SELECTED_POINT_IDS, results); + args.putInt(KEY_CYCLE_INDEX, cycleIndex); + getParentFragmentManager().setFragmentResult(KEY_REQUEST_TIME, args); + dismiss(); + }); + } + } + + return rootView; + } + + public static final String KEY_REQUEST_TIME = "KEY_REQUEST_TIME_ID"; + private static final String KEY_ALL_POINT_IDS = "__all_point_ids "; + private static final String KEY_ALL_POINT_NAMES = "__all_point_names "; + private static final String KEY_SELECTED_POINT_IDS = "__selected_point_ids "; + + private static final String KEY_CYCLE_COUNT = "__cycle_count__ "; + private static final String KEY_SHOW_LEFT_RIGHT = "__show_left_or_right__"; + private static final String KEY_CYCLE_INDEX = "__cycle_INDEX__ "; + + private SelectReSurveyorPointFragment() { + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + Dialog dialog = getDialog(); + if (dialog == null) { + return; + } + dialog.setOnDismissListener(dialogInterface -> { + Bundle args = new Bundle(); + getParentFragmentManager().setFragmentResult(KEY_REQUEST_TIME, args); + dismiss(); + }); + } + + public static void pick(@NonNull FragmentManager fragmentManager, + @NonNull LifecycleOwner lifecycleOwner, + boolean showLeftOrRight, + ArrayList allPointIds, + ArrayList allPointNames, + ISelectedCallback callback) { + pick(fragmentManager, lifecycleOwner, -1, showLeftOrRight, + allPointIds, allPointNames, callback); + } + + public static void pick(@NonNull FragmentManager fragmentManager, + @NonNull LifecycleOwner lifecycleOwner, + int cycleCount, + boolean showLeftOrRight, + ArrayList allPointIds, + ArrayList allPointNames, + ISelectedCallback callback) { + if (callback == null) { + return; + } + fragmentManager + .setFragmentResultListener( + KEY_REQUEST_TIME, + lifecycleOwner, + (requestKey, result) -> { + if (KEY_REQUEST_TIME.equals(requestKey)) { + List selectedIds = result.getStringArrayList(KEY_SELECTED_POINT_IDS); + int targetCycleIndex = result.getInt(KEY_CYCLE_INDEX, -1); + callback.onSelected(targetCycleIndex, selectedIds); + } + }); + BottomSheetDialogFragment fragment = new SelectReSurveyorPointFragment(); + Bundle args = new Bundle(); + args.putStringArrayList(KEY_ALL_POINT_IDS, allPointIds); + args.putStringArrayList(KEY_ALL_POINT_NAMES, allPointNames); + args.putBoolean(KEY_SHOW_LEFT_RIGHT, showLeftOrRight); + args.putInt(KEY_CYCLE_COUNT, cycleCount); + fragment.setArguments(args); + fragment.show(fragmentManager, SelectReSurveyorPointFragment.class.getName()); + } + + public interface ISelectedCallback { + void onSelected(int cycleIndex, List pointIds); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/SelectSurveyorStationTypeFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/SelectSurveyorStationTypeFragment.java new file mode 100644 index 0000000..0fa0925 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/SelectSurveyorStationTypeFragment.java @@ -0,0 +1,176 @@ +package com.bingce.controlnetwork.fragment; + +import android.content.Context; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.WindowManager; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; + +import com.bingce.controlapphelper.datasource.database.ProjectType; +import com.google.android.material.bottomsheet.BottomSheetDialogFragment; + +import com.bingce.controlnetwork.R; + +/** + * 选择站的类型(闭合导线,直导线等) + */ +public class SelectSurveyorStationTypeFragment extends BottomSheetDialogFragment { + public static final String TAG = SelectProjectAndSurveyorCycleFragment.class.getName(); + //上个页面传过来的 + private String projectType; + + private final int[] needHideIdsTriangle = { + R.id.wire_well_double, R.id.wire_well + }; + private final int[] needHideIdsConnection = { + R.id.default_type, R.id.wire_zhi, R.id.wire_fuhe, R.id.wire_close, + R.id.wire_random + }; + private final int[] needHideIdsHeightTraverse = { + R.id.default_type, R.id.wire_zhi, R.id.wire_fuhe, R.id.wire_close, + R.id.wire_random, R.id.wire_well_double, R.id.wire_well + }; + + private SelectSurveyorStationTypeFragment() { + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + if (getArguments() != null) { + projectType = getArguments().getString(KEY_PROJECT_TYPE); + } + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View view = inflater + .inflate( + R.layout.fragment_bottom_popup_surveyor_station_type_select_layout, + container, + false); + initListener(view); + initShowOrHideView(view); + return view; + } + + private void initShowOrHideView(View view) { + ProjectType.getTarget(projectType, (projectTypeBack) -> { + if (projectTypeBack == ProjectType.TRIANGLE) { + hideViews(view, needHideIdsTriangle); + } else if (projectTypeBack == ProjectType.CONNECTION) { + hideViews(view, needHideIdsConnection); + } else if (projectTypeBack == ProjectType.HEIGHT_TRAVERSE) { + hideViews(view, needHideIdsHeightTraverse); + } + return null; + }); + } + + private void hideViews(View view, int[] ids) { + for (int i = 0; i < ids.length; i++) { + View currentView = view.findViewById(ids[i]); + currentView.setVisibility(View.GONE); + } + } + + private void initListener(View view) { + View.OnClickListener onClickListener = v -> { + if (v == null) { + dismiss(); + return; + } + int id = v.getId(); + String type = TYPE_DEFAULT; + if (id == R.id.wire_zhi) { + type = TYPE_LINE_SINGLE; + } else if (id == R.id.wire_fuhe) { + type = TYPE_LINE_ATTACH; + } else if (id == R.id.wire_close) { + type = TYPE_LINE_CLOSE; + } else if (id == R.id.wire_random) { + type = TYPE_LINE_RANDOM; + } else if (id == R.id.wire_well) { + type = TYPE_WELL_WIRE; + } else if (id == R.id.wire_well_double) { + type = TYPE_WELL_WIRE_DOUBLE; + } + Bundle args = new Bundle(); + args.putString(KEY_RESULT_TYPE, type); + getParentFragmentManager().setFragmentResult(KEY_REQUEST_SELECT, args); + dismiss(); + }; + + setOnClickListener(view, R.id.default_type, onClickListener); + setOnClickListener(view, R.id.wire_zhi, onClickListener); + setOnClickListener(view, R.id.wire_fuhe, onClickListener); + setOnClickListener(view, R.id.wire_close, onClickListener); + setOnClickListener(view, R.id.wire_random, onClickListener); + setOnClickListener(view, R.id.wire_well, onClickListener); + setOnClickListener(view, R.id.wire_well_double, onClickListener); + setOnClickListener(view, R.id.cancel, v -> dismiss()); + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + if (getDialog() == null) { + return; + } + getDialog().getWindow().setLayout( + WindowManager.LayoutParams.MATCH_PARENT, + WindowManager.LayoutParams.WRAP_CONTENT); + } + + private static void setOnClickListener(View root, int id, View.OnClickListener onClickListener) { + View view = root.findViewById(id); + if (view != null) { + view.setOnClickListener(onClickListener); + } + } + + private static final String KEY_PROJECT_TYPE = "__KEY_PROJECT_TYPE__"; + + private static final String KEY_REQUEST_SELECT = "__SELECT__"; + private static final String KEY_RESULT_TYPE = "__KEY_RESULT_TYPE__"; + + public static final String TYPE_DEFAULT = "__default__";//多测回测角 + public static final String TYPE_LINE_SINGLE = "__line_single";//支导线 + public static final String TYPE_LINE_ATTACH = "__line_attach";//附合导线 + public static final String TYPE_LINE_CLOSE = "__line_close";//闭合导线 + public static final String TYPE_LINE_RANDOM = "__line_random";//无定向导线 + public static final String TYPE_WELL_WIRE = "__well_wire";//井定向 + public static final String TYPE_WELL_WIRE_DOUBLE = "__well_wire_double";//二井定向 + + public static void select(FragmentManager fragmentManager, + @NonNull LifecycleOwner lifecycleOwner, + String projectType, + IOnSelectCallback callback) { + SelectSurveyorStationTypeFragment fragment = new SelectSurveyorStationTypeFragment(); + Bundle bundle = new Bundle(); + bundle.putString(KEY_PROJECT_TYPE, projectType); + fragment.setArguments(bundle); + fragmentManager + .setFragmentResultListener( + KEY_REQUEST_SELECT, + lifecycleOwner, + (requestKey, result) -> { + if (KEY_REQUEST_SELECT.equals(requestKey)) { + callback.onSurveyorCycleSelected(result.getString(KEY_RESULT_TYPE)); + } + }); + fragment.show(fragmentManager, TAG); + } + + + public interface IOnSelectCallback { + void onSurveyorCycleSelected(String type); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/SelectSurveyorStationTypeWellSubFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/SelectSurveyorStationTypeWellSubFragment.java new file mode 100644 index 0000000..f9524bc --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/SelectSurveyorStationTypeWellSubFragment.java @@ -0,0 +1,103 @@ +package com.bingce.controlnetwork.fragment; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.WindowManager; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; + +import com.google.android.material.bottomsheet.BottomSheetDialogFragment; + +import com.bingce.controlnetwork.R; + +/** + * 选择二井定向-地上还是地下 + */ +public class SelectSurveyorStationTypeWellSubFragment extends BottomSheetDialogFragment { + public static final String TAG = SelectProjectAndSurveyorCycleFragment.class.getName(); + + private SelectSurveyorStationTypeWellSubFragment() { + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View view = inflater + .inflate( + R.layout.fragment_bottom_popup_surveyor_station_type_select_layout_well_sub, + container, + false); + View.OnClickListener onClickListener = v -> { + if (v == null) { + dismiss(); + return; + } + int id = v.getId(); + String type = TYPE_GROUND; + if (id == R.id.wire_ground) { + type = TYPE_GROUND; + } else if (id == R.id.wire_underground) { + type = TYPE_UNDERGROUND; + } + Bundle args = new Bundle(); + args.putString(KEY_TYPE, type); + getParentFragmentManager().setFragmentResult(KEY_REQUEST_SELECT, args); + dismiss(); + }; + + setOnClickListener(view, R.id.wire_ground, onClickListener); + setOnClickListener(view, R.id.wire_underground, onClickListener); + setOnClickListener(view, R.id.cancel, v -> dismiss()); + + return view; + } + + private static void setOnClickListener(View root, int id, View.OnClickListener onClickListener) { + View view = root.findViewById(id); + if (view != null) { + view.setOnClickListener(onClickListener); + } + } + + private static final String KEY_REQUEST_SELECT = "__SELECT__"; + private static final String KEY_TYPE = "__SELECT_TYPE__"; + + public static final String TYPE_GROUND = "type_ground";//二井定向地上 + public static final String TYPE_UNDERGROUND = "type_underground";//二井定向地下 + + public static void select(FragmentManager fragmentManager, + @NonNull LifecycleOwner lifecycleOwner, + IOnSelectCallback callback) { + SelectSurveyorStationTypeWellSubFragment fragment = new SelectSurveyorStationTypeWellSubFragment(); + fragmentManager + .setFragmentResultListener( + KEY_REQUEST_SELECT, + lifecycleOwner, + (requestKey, result) -> { + if (KEY_REQUEST_SELECT.equals(requestKey)) { + callback.onSurveyorCycleSelected(result.getString(KEY_TYPE)); + } + }); + fragment.show(fragmentManager, TAG); + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + if (getDialog() == null) { + return; + } + getDialog().getWindow().setLayout( + WindowManager.LayoutParams.MATCH_PARENT, + WindowManager.LayoutParams.WRAP_CONTENT); + } + + public interface IOnSelectCallback { + void onSurveyorCycleSelected(String type); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/SelectToleranceBottomSheetFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/SelectToleranceBottomSheetFragment.java new file mode 100644 index 0000000..5af4a8b --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/SelectToleranceBottomSheetFragment.java @@ -0,0 +1,156 @@ +package com.bingce.controlnetwork.fragment; + +import android.os.Bundle; +import android.view.Gravity; +import android.view.KeyEvent; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.Window; +import android.view.WindowManager; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.DialogFragment; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; + +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; +import org.greenrobot.eventbus.ThreadMode; +import org.jetbrains.annotations.NotNull; + +import com.bingce.controlnetwork.R; + +/** + * 限差选择框(限差设置-限差模板点击后的操作) + */ +public class SelectToleranceBottomSheetFragment extends DialogFragment { + public static final String TAG = SelectToleranceBottomSheetFragment.class.getName(); + private ComponentSwitchToleranceFragment componentSwitchToleranceFragment; + + private SelectToleranceBottomSheetFragment() { + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View view = inflater + .inflate(R.layout.fragment_tolerance_select_framelayout_layout, + container, + false); + String projectType = ""; + String groupId = ""; + String levelId = ""; + String toleranceId = ""; + if (getArguments() != null) { + projectType = getArguments().getString(KEY_PROJECT_TYPE); + groupId = getArguments().getString(KEY_GROUP_ID); + levelId = getArguments().getString(KEY_LEVEL_ID); + toleranceId = getArguments().getString(KEY_TOLERANCE_ID); + } + + componentSwitchToleranceFragment = + ComponentSwitchToleranceFragment.newInstance(projectType, groupId, levelId, toleranceId); + + getChildFragmentManager() + .beginTransaction() + .replace(R.id.container, componentSwitchToleranceFragment) + .commit(); + + View toleranceManager = view.findViewById(R.id.btn_tolerance_manager); + if (toleranceManager != null) { + String finalProjectType = projectType; + toleranceManager.setOnClickListener(v -> ToleranceManageFragment.start(getContext(), finalProjectType)); + } + + view.setOnClickListener(v -> dismiss()); + return view; + } + + @Override + public void onViewCreated(@NonNull @NotNull View view, @Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + + if (getDialog() != null) { + final Window window = getDialog().getWindow(); + + window.setWindowAnimations(R.style.animate_dialog); + window.setBackgroundDrawable(null); + + WindowManager.LayoutParams params = window.getAttributes(); + params.gravity = Gravity.BOTTOM; + params.width = ViewGroup.LayoutParams.MATCH_PARENT; + params.height = ViewGroup.LayoutParams.WRAP_CONTENT; + window.setAttributes(params); + } + } + + @Override + public void onStart() { + super.onStart(); + EventBus.getDefault().register(this); + getDialog().setOnKeyListener((dialog, keyCode, event) -> { + if ((keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP)) { + if (!componentSwitchToleranceFragment.doBack()) { + dismiss(); + } + return true; + } + return false; + }); + } + + @Override + public void onStop() { + super.onStop(); + EventBus.getDefault().unregister(this); + } + + @Subscribe(threadMode = ThreadMode.MAIN) + public void onMessageEvent(ComponentSwitchToleranceFragment.SelectedToleranceEvent event) { + Bundle args = new Bundle(); + args.putString(KEY_TOLERANCE_ID, event.toleranceId); + getParentFragmentManager().setFragmentResult(KEY_REQUEST_SELECT, args); + dismiss(); + } + + private static final String KEY_REQUEST_SELECT = "__SELECT__"; + private static final String KEY_PROJECT_TYPE = "___project__type"; + private static final String KEY_GROUP_ID = "___group__id"; + private static final String KEY_LEVEL_ID = "____level__id"; + private static final String KEY_TOLERANCE_ID = "____tolerance__id"; + + public static void select(FragmentManager fragmentManager, + @NonNull LifecycleOwner lifecycleOwner, + String projectType, + String defaultGroupId, + String defaultLevelId, + String defaultToleranceId, + IOnSelectCallback callback) { + Bundle args = new Bundle(); + args.putString(KEY_PROJECT_TYPE, projectType); + args.putString(KEY_GROUP_ID, defaultGroupId); + args.putString(KEY_LEVEL_ID, defaultLevelId); + args.putString(KEY_TOLERANCE_ID, defaultToleranceId); + + SelectToleranceBottomSheetFragment fragment = new SelectToleranceBottomSheetFragment(); + fragment.setArguments(args); + + fragmentManager + .setFragmentResultListener( + KEY_REQUEST_SELECT, + lifecycleOwner, + (requestKey, result) -> { + if (KEY_REQUEST_SELECT.equals(requestKey)) { + callback.onToleranceSelected( + result.getString(KEY_TOLERANCE_ID)); + } + }); + fragment.show(fragmentManager, TAG); + } + + public interface IOnSelectCallback { + void onToleranceSelected(String toleranceId); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/SelectToleranceTemplateBottomSheetFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/SelectToleranceTemplateBottomSheetFragment.java new file mode 100644 index 0000000..ad345da --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/SelectToleranceTemplateBottomSheetFragment.java @@ -0,0 +1,144 @@ +package com.bingce.controlnetwork.fragment; + +import android.content.Context; +import android.os.Bundle; +import android.view.Gravity; +import android.view.KeyEvent; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.Window; +import android.view.WindowManager; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.DialogFragment; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; + +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; +import org.greenrobot.eventbus.ThreadMode; +import org.jetbrains.annotations.NotNull; + +import com.bingce.controlnetwork.R; + +/** + * 选择限差参考模板(自定义限差管理点击+后的操作) + */ +public class SelectToleranceTemplateBottomSheetFragment extends DialogFragment { + public static final String TAG = SelectToleranceTemplateBottomSheetFragment.class.getName(); + private ComponentSwitchToleranceFragment componentSwitchToleranceFragment; + + private String projectType; + + private SelectToleranceTemplateBottomSheetFragment() { + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + if (getArguments() != null) { + projectType = getArguments().getString(KEY_PROJECT_TYPE, ""); + } + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View view = inflater + .inflate(R.layout.fragment_tolerance_template_select_layout, + container, + false); + + componentSwitchToleranceFragment = + ComponentSwitchToleranceFragment.newInstance(projectType, "", "", ""); + + getChildFragmentManager() + .beginTransaction() + .replace(R.id.container, componentSwitchToleranceFragment) + .commit(); + + view.setOnClickListener(v -> dismiss()); + return view; + } + + @Override + public void onViewCreated(@NonNull @NotNull View view, @Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + + if (getDialog() != null) { + final Window window = getDialog().getWindow(); + + window.setWindowAnimations(R.style.animate_dialog); + window.setBackgroundDrawable(null); + + WindowManager.LayoutParams params = window.getAttributes(); + params.gravity = Gravity.BOTTOM; + params.width = ViewGroup.LayoutParams.MATCH_PARENT; + params.height = ViewGroup.LayoutParams.WRAP_CONTENT; + window.setAttributes(params); + } + } + + @Override + public void onStart() { + super.onStart(); + EventBus.getDefault().register(this); + getDialog().setOnKeyListener((dialog, keyCode, event) -> { + if ((keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP)) { + if (!componentSwitchToleranceFragment.doBack()) { + dismiss(); + } + return true; + } + return false; + }); + } + + @Override + public void onStop() { + super.onStop(); + EventBus.getDefault().unregister(this); + } + + @Subscribe(threadMode = ThreadMode.MAIN) + public void onMessageEvent(ComponentSwitchToleranceFragment.SelectedToleranceEvent event) { + Bundle args = new Bundle(); + args.putString(KEY_TOLERANCE_ID, event.toleranceId); + getParentFragmentManager().setFragmentResult(KEY_REQUEST_SELECT, args); + dismiss(); + } + + private static final String KEY_REQUEST_SELECT = "__SELECT__"; + private static final String KEY_TOLERANCE_ID = "___key__tolerance__id"; + private static final String KEY_PROJECT_TYPE = "KEY_PROJECT_TYPE"; + + public static void select(FragmentManager fragmentManager, + @NonNull LifecycleOwner lifecycleOwner, + String projectType, + IOnSelectCallback callback) { + SelectToleranceTemplateBottomSheetFragment fragment = + new SelectToleranceTemplateBottomSheetFragment(); + + Bundle bundle = new Bundle(); + bundle.putString(KEY_PROJECT_TYPE, projectType); + fragment.setArguments(bundle); + + fragmentManager + .setFragmentResultListener( + KEY_REQUEST_SELECT, + lifecycleOwner, + (requestKey, result) -> { + if (KEY_REQUEST_SELECT.equals(requestKey)) { + callback.onToleranceSelected( + result.getString(KEY_TOLERANCE_ID)); + } + }); + fragment.show(fragmentManager, TAG); + } + + public interface IOnSelectCallback { + void onToleranceSelected(String toleranceId); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/ServiceFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/ServiceFragment.java new file mode 100644 index 0000000..1ce6514 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/ServiceFragment.java @@ -0,0 +1,108 @@ +package com.bingce.controlnetwork.fragment; + +import android.os.Bundle; +import android.view.View; +import android.webkit.JavascriptInterface; + +import androidx.annotation.Nullable; + +import com.bingce.data.sync.utils.LeanCloudConfigLoader; +import com.bingce.surveyor.agentweb.AgentWebFragment; +import com.bingce.surveyor.agentweb.FragmentKeyDown; +import com.bingce.surveyor.agentweb.sonic.SonicImpl; +import com.bingce.surveyor.constant.ServicePageUrl; +import com.bingce.utils.StringUtil; +import com.just.agentweb.MiddlewareWebClientBase; + + +/** + * 主页面-服务 + */ +public class ServiceFragment extends AgentWebFragment implements FragmentKeyDown { + public static final String TAG = "ServiceFragment"; + public final String offlineUrl = "file:///android_asset/service_default.html"; + private SonicImpl mSonicImpl; + + @Override + public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { + // 1. 首先创建SonicImpl + mSonicImpl = new SonicImpl(offlineUrl, this.getContext()); + // 2. 调用 onCreateSession + mSonicImpl.onCreateSession(); + //3. 创建AgentWeb ,注意创建AgentWeb的时候应该使用加入SonicWebViewClient中间件 + super.onViewCreated(view, savedInstanceState); // 创建 AgentWeb 注意的 go("") 传入的 mUrl 应该null 或者"" + //4. 注入 JavaScriptInterface + if (mAgentWeb != null) { + //注入对象 + mAgentWeb.getJsInterfaceHolder().addJavaObject("android", this); + } + //5. 最后绑定AgentWeb + mSonicImpl.bindAgentWeb(mAgentWeb); + + refresh(); + } + + //在步骤3的时候应该传入给AgentWeb + @Override + public MiddlewareWebClientBase getMiddlewareWebClient() { + return mSonicImpl.createSonicClientMiddleWare(); + } + + //getUrl 应该为null + @Override + public String getUrl() { + return null; + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + //销毁SonicSession + if (mSonicImpl != null) { + mSonicImpl.destrory(); + } + } + + @JavascriptInterface + public void refresh() { + String queryUrl = "android_url_service_for_control"; + LeanCloudConfigLoader.findInBackground(queryUrl, instance -> { +// new LCQuery<>("Configuration") +// .whereEqualTo("name", queryUrl) +// .limit(1) +// .findInBackground().subscribe(new Observer>() { +// @Override +// public void onSubscribe(Disposable d) { +// +// } +// +// @Override +// public void onNext(List avObjects) { + if (/*avObjects != null && !avObjects.isEmpty() && avObjects.get(0).getString("value") != null*/instance != null && StringUtil.isNotEmpty(instance.value)) { +// ((App) Utils.getApp()).servicePageUrl = /*avObjects.get(0).getString("value")*/instance.value; + ServicePageUrl.url = instance.value; + mAgentWeb.getUrlLoader().loadUrl(ServicePageUrl.url); + } +// } +// +// @Override +// public void onError(Throwable e) { +// +// } +// +// @Override +// public void onComplete() { +// +// } + }); + } + + @Override + public void onResume() { + super.onResume(); +// Activity activity = getActivity(); +// if (activity instanceof MainActivity) { +// ((MainActivity) activity).setCurrentTab(2); +// } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/StationDataAdjustDialogFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/StationDataAdjustDialogFragment.java new file mode 100644 index 0000000..24fced5 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/StationDataAdjustDialogFragment.java @@ -0,0 +1,183 @@ +package com.bingce.controlnetwork.fragment; + +import android.content.Context; +import android.graphics.drawable.ColorDrawable; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.Window; +import android.view.WindowManager; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.DialogFragment; +import androidx.fragment.app.FragmentManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.model.ViewItemType; +import com.bingce.controlapphelper.surveyor.method.RadianMethod; +import com.bingce.controlapphelper.surveyor.method.SurveyorAdjustMethod; +import com.bingce.controlapphelper.util.SettingValueUtil; +import com.bingce.controlnetwork.adapter.BaseAdapter; +import com.bingce.utils.Util; + +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.ui.vh.StationAdjustItemViewHolder; +import com.bingce.controlnetwork.ui.widget.ViewFactory; + +public class StationDataAdjustDialogFragment extends DialogFragment { + public static final String KEY_SHOW_TYPE = "__key_show_type"; + private static final String KEY_LIST = "__key_list"; + private static final String KEY_IS_SHOW_SLOP_DISTANCE = "__key_show_slop"; + + //key_type对应的常量 + public static final String TYPE_ANGLE_DISTANCE = "TYPE_ANGLE_DISTANCE";//水平角,垂直角,距离 + public static final String TYPE_ANGLE_VER_AND_DISTANCE = "TYPE_ANGLE_VER_AND_DISTANCE";//垂直角,距离 + public static final String TYPE_ALONE_DISTANCE = "TYPE_ALONE_DISTANCE";//距离 + + + private String showType; + + private StationDataAdjustDialogFragment() { + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + Bundle arguments = getArguments(); + if (arguments != null) { + showType = arguments.getString(KEY_SHOW_TYPE); + } + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + if (getDialog() == null) { + return; + } + Window window = getDialog().getWindow(); + window.setBackgroundDrawable(new ColorDrawable(0x00000000)); + window.setLayout( + WindowManager.LayoutParams.MATCH_PARENT, + WindowManager.LayoutParams.WRAP_CONTENT); + } + + @Nullable + @org.jetbrains.annotations.Nullable + @Override + public View onCreateView(@NonNull @NotNull LayoutInflater inflater, @Nullable @org.jetbrains.annotations.Nullable ViewGroup container, @Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) { + View rootView = inflater.inflate(R.layout.fragment_station_data_adjust_dialog_layout, container, false); + if (getArguments() != null) { + ArrayList items = getArguments().getParcelableArrayList(KEY_LIST); + boolean isShowSlop = getArguments().getBoolean(KEY_IS_SHOW_SLOP_DISTANCE, true); + RecyclerView recyclerView = rootView.findViewById(R.id.list); + TextView distanceTitle = rootView.findViewById(R.id.distance_angle_title); + if (recyclerView != null) { + _Adapter adapter = new _Adapter(items); + recyclerView.setAdapter(adapter); + if (distanceTitle != null) { + distanceTitle.setText(isShowSlop ? R.string.distance_slope : R.string.distance_horizontal); + } + } + + initShowView(rootView.findViewById(R.id.hor_angle_title), + rootView.findViewById(R.id.ver_angle_title), + rootView.findViewById(R.id.distance_angle_title)); + + } + return rootView; + } + + + private void initShowView(View horView, View verView, View disView) { + if (showType == null) return; + switch (showType) { + case TYPE_ALONE_DISTANCE: + horView.setVisibility(View.GONE); + verView.setVisibility(View.GONE); + disView.setVisibility(View.VISIBLE); + break; + case TYPE_ANGLE_VER_AND_DISTANCE: + horView.setVisibility(View.GONE); + verView.setVisibility(View.VISIBLE); + disView.setVisibility(View.VISIBLE); + break; + case TYPE_ANGLE_DISTANCE: + default: + horView.setVisibility(View.VISIBLE); + verView.setVisibility(View.VISIBLE); + disView.setVisibility(View.VISIBLE); + break; + } + } + + + private class _Adapter extends BaseAdapter { + + public _Adapter(List items) { + super(items); + } + + @Override + protected StationAdjustItemViewHolder createVH(@NotNull ViewGroup parent, int viewType) { + RecyclerView.ViewHolder viewHolder = ViewFactory.generatorViewHolder(parent.getContext(), parent, ViewItemType.stationAdjust); + if (viewHolder instanceof StationAdjustItemViewHolder) { + return (StationAdjustItemViewHolder) viewHolder; + } + return null; + } + + @Override + public void onBindViewHolder(@NonNull @NotNull StationAdjustItemViewHolder holder, int position) { + SurveyorAdjustMethod.Item item = getItem(position); + + initShowView(holder.horAngle, holder.verAngle, holder.distance); + + setText(holder.pointName, item.getPointName()); + setText(holder.horAngle, formatAngle(item.getHorAngle())); + setText(holder.verAngle, formatAngle(item.getVerAngle())); + setText(holder.distance, formatDistance(item.getDistance())); + } + + + private void setText(TextView textView, String string) { + if (textView != null) { + textView.setText(string); + } + } + + private String formatAngle(double angle) { + if (angle < 0) { + return ""; + } + return RadianMethod.dmsStringOf(angle); + } + + private String formatDistance(double distance) { + if (distance < 0) { + return ""; + } + return Util.formatDouble2String(distance, SettingValueUtil.getLengthDecimalPoint()); + } + } + + public static void showDialog(String type, ArrayList finalItemList, + Boolean isShowSlopDistance, + FragmentManager fragmentManager) { + StationDataAdjustDialogFragment dialogFragment = new StationDataAdjustDialogFragment(); + Bundle args = new Bundle(); + args.putString(KEY_SHOW_TYPE, type); + args.putParcelableArrayList(KEY_LIST, finalItemList); + args.putBoolean(KEY_IS_SHOW_SLOP_DISTANCE, isShowSlopDistance); + dialogFragment.setArguments(args); + dialogFragment.show(fragmentManager, StationDataAdjustDialogFragment.class.getName()); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/StringInputFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/StringInputFragment.java new file mode 100644 index 0000000..620fa02 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/StringInputFragment.java @@ -0,0 +1,88 @@ +package com.bingce.controlnetwork.fragment; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; + +import com.rengwuxian.materialedittext.MaterialEditText; + +import blankj.utilcode.util.ToastUtils; + +import com.bingce.controlnetwork.R; + +public class StringInputFragment extends AbstractFullScreenDialogFragment { + @Override + protected View createContentView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.content_string_input_layout, container, false); + MaterialEditText editText = view.findViewById(R.id.editor); + if (editText != null && getArguments() != null) { + editText.setText(getArguments().getString(KEY_DEFAULT_STRING)); + } + return view; + } + + @Override + protected void onConfirm() { + Bundle args = new Bundle(); + if (getView() != null) { + MaterialEditText editText = getView().findViewById(R.id.editor); + if (editText.getText() != null) { + String string = editText.getText().toString(); + if (string.isEmpty()) { + ToastUtils.showShort(R.string.string_no_empty); + return; + } + args.putString(KEY_STRING_RESULT, string); + } + } + getParentFragmentManager() + .setFragmentResult(KEY_REQUEST_INPUT, args); + super.onConfirm(); + } + + private static final String TAG = StringInputFragment.class.getName(); + private static final String KEY_REQUEST_INPUT = StringInputFragment.class.getName() + "_REQUEST"; + private static final String KEY_STRING_RESULT = StringInputFragment.class.getName() + "_result"; + private static final String KEY_DEFAULT_STRING = StringInputFragment.class.getName() + "__DEFAULT_STRING"; + + public static void input(FragmentManager fragmentManager, + String title, + @NonNull LifecycleOwner lifecycleOwner, + IInputCallback callback) { + input(fragmentManager, title, null, lifecycleOwner, callback); + } + + public static void input(FragmentManager fragmentManager, + String title, + String defaultString, + @NonNull LifecycleOwner lifecycleOwner, + IInputCallback callback) { + Bundle args = new Bundle(); + StringInputFragment fragment = new StringInputFragment(); + fragment.setArguments(args); + if (defaultString != null) { + args.putString(KEY_DEFAULT_STRING, defaultString); + } + setArgs(args, title, null); + fragmentManager + .setFragmentResultListener( + KEY_REQUEST_INPUT, + lifecycleOwner, + (requestKey, result) -> { + if (KEY_REQUEST_INPUT.equals(requestKey)) { + callback.onGetInput(result.getString(KEY_STRING_RESULT)); + } + }); + fragment.show(fragmentManager, TAG); + } + + public interface IInputCallback { + void onGetInput(String string); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/SurveyorRouteStationFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/SurveyorRouteStationFragment.java new file mode 100644 index 0000000..b80faba --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/SurveyorRouteStationFragment.java @@ -0,0 +1,200 @@ +package com.bingce.controlnetwork.fragment; + +import android.os.Bundle; +import android.text.TextUtils; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.lifecycle.LiveData; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.route.RouteRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.model.SurveyorPoint; +import com.bingce.controlapphelper.model.BundleConstants; +import com.bingce.controlapphelper.util.ScheduleUtil; +import com.bingce.controlapphelper.util.StationUtil; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.adapter.SurveyorStationListAdapter; +import com.bingce.controlnetwork.databinding.FragmentSurveyorRouteStationBinding; +import com.bingce.controlnetwork.fragment.base.BaseFragment; +import com.bingce.controlnetwork.fragment.station.heighttraverse.CreateStationForHeightTraverseFragment; +import com.bingce.controlnetwork.fragment.stationsurvey.heighttraverse.MeasureHeightTraverseFragment; +import com.bingce.utils.ThreadPoolUtil; + +import java.util.List; + +import blankj.utilcode.util.ToastUtils; + +/** + * 高程导线 测量页-项目路线下的测站列表和新增测站 + */ +public class SurveyorRouteStationFragment extends BaseFragment { + public static final String TAG = SurveyorRouteStationFragment.class.getName(); + private SurveyorStationListAdapter adapter; + private FragmentSurveyorRouteStationBinding mBinding; + + private static final String KEY_DETAIL_OR_SURVEYOR = "___editable___";//标识点击item进入测量界面还是测站详情 + + public static SurveyorRouteStationFragment newInstance(String projectId, String routeId) { + return newInstance(projectId, routeId, true); + } + + public static SurveyorRouteStationFragment newInstance(String projectId, String routeId, boolean detailOrSurveyor) { + SurveyorRouteStationFragment fragment = new SurveyorRouteStationFragment(); + Bundle bundle = new Bundle(); + bundle.putString(BundleConstants.KEY_PROJECT_ID, projectId); + bundle.putString(BundleConstants.KEY_ROUTE_ID, routeId); + bundle.putBoolean(KEY_DETAIL_OR_SURVEYOR, detailOrSurveyor); + fragment.setArguments(bundle); + return fragment; + } + + /** + * 去测量或者详情页面 + */ + private void goStationMeasureOrDetail(SurveyorStationRecord item) { + String stationId = item.getId(); + ThreadPoolUtil.execute(() -> { + SurveyorStationRecord stationRecord = SurveyorDatabaseFactory + .instance + .getSurveyorStation() + .getRecordSync(stationId); + if (stationRecord == null || stationRecord.getItems() == null || stationRecord.getItems().isEmpty()) { + return; + } + + //站的名称 导线+点名 + String stationName = StationUtil.getStationName(stationRecord); + + MeasureHeightTraverseFragment.start(requireContext(), stationId, stationName); + }); + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + mBinding = FragmentSurveyorRouteStationBinding.inflate(inflater, container, false); + return mBinding.getRoot(); + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + mBinding = null; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initView(); + initListener(); + initData(); + } + + private void initView() { + mBinding.btnCreateStation.setVisibility(getRouteId() == null ? View.GONE : View.VISIBLE); + } + + private void initListener() { + mBinding.btnCreateStation.setOnClickListener(v -> checkCreateStation(checkSuccess -> { + if (!checkSuccess) return; + CreateStationForHeightTraverseFragment.start(requireContext(), getProjectId(), getRouteId()); + })); + } + + private void checkCreateStation(ICallBackCheckStation callBackCheckStation) { + ThreadPoolUtil.execute(() -> { + String projectId = getProjectId(); + String routeId = getRouteId(); + if (projectId == null || routeId == null) { + ToastUtils.showShort(R.string.parameter_exception); + callBackCheckStation.result(false); + return; + } + RouteRecord routeRecord = SurveyorDatabaseFactory.instance.getRouteDataSource().getByIdSync(routeId); + if (routeRecord == null) { + ToastUtils.showShort(R.string.route_record_exception); + callBackCheckStation.result(false); + return; + } + + //判断上一个测站是否通过检测 + SurveyorStationRecord stationLatest = SurveyorDatabaseFactory.instance.getSurveyorStation().getByProjectRouteLatest(projectId, routeId); + if (stationLatest != null && stationLatest.items != null && stationLatest.items.size() > 0) { + String stationNameNotFinish = ScheduleUtil.INSTANCE.getStationNameNotFinishForHeightTraverse(stationLatest); + if (!TextUtils.isEmpty(stationNameNotFinish)) { + ToastUtils.showShort(Tools.getString(R.string.station_failed_test, stationNameNotFinish)); + callBackCheckStation.result(false); + return; + } + } + + SurveyorStationRecord stationRecord = SurveyorDatabaseFactory.instance.getSurveyorStation().getByProjectRouteLatest(projectId, routeId); + if (stationRecord != null && stationRecord.items != null) { + for (SurveyorPoint surveyorPoint : stationRecord.items) { + if (surveyorPoint.getOriginalPointId().equals(routeRecord.getEndPointId())) { + ToastUtils.showShort(R.string.route_begin_end_been_created); + callBackCheckStation.result(false); + return; + } + } + } + + callBackCheckStation.result(true); + }); + } + + private void initData() { + if (getArguments() != null) { + update(getProjectId(), getRouteId()); + } + } + + private String getProjectId() { + if (getArguments() != null) { + return getArguments().getString(BundleConstants.KEY_PROJECT_ID); + } + return null; + } + + private String getRouteId() { + if (getArguments() != null) { + return getArguments().getString(BundleConstants.KEY_ROUTE_ID); + } + return null; + } + + /** + * 根据项目id和路线id获取测站记录 + */ + public void update(String projectId, String routeId) { + LiveData> liveData = SurveyorDatabaseFactory.instance.getSurveyorStation().getByProjectRouteLiveData(projectId, routeId); + liveData.observe(getViewLifecycleOwner(), this::updateUi); + } + + private void updateUi(List stationList) { + if (adapter == null) { + adapter = new SurveyorStationListAdapter(stationList, + getChildFragmentManager(), + getViewLifecycleOwner(), + this::runOnUI, + getContext(), + this::goStationMeasureOrDetail, + true); + mBinding.recyclerView.setAdapter(adapter); + } else { + adapter.updateData(stationList); + } + } + + private interface ICallBackCheckStation { + void result(boolean checkSuccess); + } + + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/SurveyorSettingsFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/SurveyorSettingsFragment.java new file mode 100644 index 0000000..15ddfd9 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/SurveyorSettingsFragment.java @@ -0,0 +1,98 @@ +package com.bingce.controlnetwork.fragment; + +import android.content.Context; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; +import androidx.preference.PreferenceFragmentCompat; +import androidx.preference.SwitchPreferenceCompat; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.surveyorstation.ISurveyorStationDataSource; +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord; +import com.bingce.controlapphelper.model.BundleConstants; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.activity.fragmentcontainer.FragmentContainerActivity; +import com.bingce.utils.ThreadPoolUtil; + +import org.jetbrains.annotations.NotNull; + +public class SurveyorSettingsFragment extends Fragment { + public static final String TAG = SurveyorSettingsFragment.class.getName(); + + @Nullable + @org.jetbrains.annotations.Nullable + @Override + public View onCreateView(@NonNull @NotNull LayoutInflater inflater, @Nullable @org.jetbrains.annotations.Nullable ViewGroup container, @Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) { + View rootView = inflater.inflate(R.layout.fragment_fragment_container_layout, container, false); + _SettingsFragment fragment = new _SettingsFragment(); + fragment.setArguments(getArguments()); + getChildFragmentManager() + .beginTransaction() + .add(R.id.container, fragment) + .commit(); + return rootView; + } + + public static class _SettingsFragment extends PreferenceFragmentCompat { + @Override + public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { + addPreferencesFromResource(R.xml.surveyor_settings_prefs); + + SwitchPreferenceCompat distanceType = findPreference("surveyor_settings_key_distance_type"); + if (getArguments() != null) { + String stationId = getArguments().getString(BundleConstants.KEY_SURVEYOR_STATION_ID); + ThreadPoolUtil.execute(() -> { + ISurveyorStationDataSource stationDataSource = + SurveyorDatabaseFactory.instance.getSurveyorStation(); + SurveyorStationRecord stationRecord = stationDataSource.getRecordSync(stationId); + if (stationRecord == null) { + return; + } + runOnUI(() -> { + if (distanceType != null) { + distanceType.setChecked(stationRecord.isShowSlopDistance()); + distanceType.setOnPreferenceChangeListener((preference, newValue) -> { + if (newValue instanceof Boolean) { +// Log.d("___distance_type", newValue.toString()); + stationRecord.setShowSlopDistance((boolean) newValue); + stationDataSource.save(stationRecord); + } + return true; + }); + } + }); + }); + } + } + + private void runOnUI(Runnable action) { + if (getActivity() != null) { + getActivity().runOnUiThread(action); + } + } + } + +// public static void show(FragmentManager fragmentManager) { +// DialogFragment dialogFragment = new SurveyorSettingDialogFragment(); +// dialogFragment.show(fragmentManager, SurveyorSettingDialogFragment.class.getName()); +// } + + public static void start(Context context, String surveyorStationId, String surveyorStationName) { + Bundle bundle = new Bundle(); + bundle.putString(BundleConstants.KEY_SURVEYOR_STATION_ID, surveyorStationId); + bundle.putString(BundleConstants.KEY_SURVEYOR_STATION_NAME, surveyorStationName); + FragmentContainerActivity.start(context, TAG, surveyorStationName, bundle); + } + + public static SurveyorSettingsFragment newInstance(Bundle bundle) { + SurveyorSettingsFragment fragment = new SurveyorSettingsFragment(); + fragment.setArguments(bundle); + return fragment; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/TipsFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/TipsFragment.java new file mode 100644 index 0000000..c27b0a3 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/TipsFragment.java @@ -0,0 +1,177 @@ +package com.bingce.controlnetwork.fragment; + +import android.content.Context; +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.os.Message; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.WindowManager; +import android.widget.Button; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatDialogFragment; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; + +import com.bingce.controlnetwork.R; + +public class TipsFragment extends AppCompatDialogFragment { + private final Handler mainHandler = new Handler(Looper.getMainLooper()) { + @Override + public void handleMessage(@NonNull Message msg) { + View contentView = getView(); + if (contentView == null) { + return; + } + Button confirm = contentView.findViewById(R.id.confirm_button); + int countDown = (Integer) msg.obj - 1; + if (countDown <= 0) { + confirm.setEnabled(true); + confirm.setText(R.string.confirm); + } else { + confirm.setEnabled(false); + confirm.setText(String.valueOf(countDown)); + Message message = Message.obtain(); + message.obj = countDown; + mainHandler.sendMessageDelayed(message, 1000); + } + } + }; + + private TipsFragment() { + super(); + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View contentView = inflater.inflate(R.layout.fragment_tips_layout, container, false); + Button confirm = contentView.findViewById(R.id.confirm_button); + if (getArguments() != null) { + TextView tvTitle = contentView.findViewById(R.id.title); + if (tvTitle != null) { + tvTitle.setText(getArguments().getString(KEY_TITLE)); + } + TextView tvTips = contentView.findViewById(R.id.content); + if (tvTips != null) { + tvTips.setText(getArguments().getString(KEY_CONTENT)); + } + int countDown = getArguments().getInt(KEY_COUNT_DOWN, -1); + if (countDown > 0) { + confirm.setEnabled(false); + confirm.setText(String.valueOf(countDown)); + Message message = Message.obtain(); + message.obj = countDown; + mainHandler.sendMessageDelayed(message, 1000); + } + } + + if (confirm != null) { + confirm.setOnClickListener(v -> { + //这里主动dismiss不会收到回调 + Bundle args = new Bundle(); + args.putBoolean(KEY_QUIT_CANCEL, false); + getParentFragmentManager().setFragmentResult(getTag(), args); + dismiss(); + }); + } + return contentView; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + if (getDialog() == null) { + return; + } + if (getArguments() != null) { + boolean cancelAble = getArguments().getBoolean(KEY_CANCEL_ABLE, true); + if (!cancelAble) { + getDialog().setCancelable(false); + } + } + getDialog().getWindow().setLayout( + WindowManager.LayoutParams.MATCH_PARENT, + WindowManager.LayoutParams.WRAP_CONTENT); + } + + private static final String KEY_TITLE = "__TITLE"; + private static final String KEY_CONTENT = "___CONTENT"; + private static final String KEY_COUNT_DOWN = "__COUNT_DOWN"; + private static final String KEY_CANCEL_ABLE = "__cancel__able"; + private static final String KEY_QUIT_CANCEL = "__key_quit_cancel__"; + + public static void noCancelAbleTips(@NonNull FragmentManager fragmentManager, + @NonNull LifecycleOwner lifecycleOwner, + Context context, + String content, + int countdown, + IConfirmCallback callback) { + baseTips(fragmentManager, lifecycleOwner, context.getString(R.string.notice), content, countdown, false, false, callback); + } + + public static void cancelAbleTips(@NonNull FragmentManager fragmentManager, + @NonNull LifecycleOwner lifecycleOwner, + Context context, + String content, + int countdown, + IConfirmCallback callback) { + baseTips(fragmentManager, lifecycleOwner, context.getString(R.string.notice), content, countdown, true, true, callback); + } + + public static void tipsOnly(@NonNull FragmentManager fragmentManager, + @NonNull LifecycleOwner lifecycleOwner, + Context context, + String content) { + baseTips(fragmentManager, lifecycleOwner, context.getString(R.string.notice), content, + -1, true, false, null); + } + + private static void baseTips( + @NonNull FragmentManager fragmentManager, + @NonNull LifecycleOwner lifecycleOwner, + String title, + String content, + int countdown, + boolean cancelAble, + boolean filterCancel, + IConfirmCallback callback) { + Bundle args = new Bundle(); + TipsFragment fragment = new TipsFragment(); + fragment.setArguments(args); + args.putString(KEY_TITLE, title); + args.putString(KEY_CONTENT, content); + args.putInt(KEY_COUNT_DOWN, countdown); + args.putBoolean(KEY_CANCEL_ABLE, cancelAble); + + String tag = String.valueOf(System.currentTimeMillis()); + + fragmentManager + .setFragmentResultListener( + tag, + lifecycleOwner, + (requestKey, result) -> { + if (callback != null) { + if (tag.equals(requestKey)) { + boolean isCancel = result.getBoolean(KEY_QUIT_CANCEL, true); + if (!isCancel || !filterCancel) { + callback.onConfirm(); + } + } + } + }); + + fragment.show(fragmentManager, tag); + + + } + + public interface IConfirmCallback { + void onConfirm(); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/TipsWith2OptionFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/TipsWith2OptionFragment.java new file mode 100644 index 0000000..c0ed8e4 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/TipsWith2OptionFragment.java @@ -0,0 +1,452 @@ +package com.bingce.controlnetwork.fragment; + +import android.app.Dialog; +import android.content.DialogInterface; +import android.graphics.Color; +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.os.Message; +import android.text.TextUtils; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.Window; +import android.view.WindowManager; +import android.widget.Button; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatDialogFragment; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.Lifecycle; +import androidx.lifecycle.LifecycleOwner; + +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.databinding.FragmentTipsWith2OptionLayoutBinding; + +public class TipsWith2OptionFragment extends AppCompatDialogFragment { + + private static TipsWith2OptionFragment currentFragmet;//为了全局消失使用 + + private static final int COUNT_DOWN_TIME = 5;//如果有倒计时,默认是5秒 + + //key 返回的是确实还是取消... + private static final String KEY_CALL_BACK_CODE = "KEY_CALL_BACK_CODE"; + private static final int CALL_BACK_CODE_CONFIRM = 1; + private static final int CALL_BACK_CODE_CANCEL = 2; + private static final int CALL_BACK_CODE_OPTION = 3; + private static final int CALL_BACK_CODE_IGNORE = 4; + + private static final String KEY_TITLE = "__TITLE"; + private static final String KEY_CONTENT = "___CONTENT"; + private static final String KEY_CONFIRM_BUTTON = "_confirm_button"; + private static final String KEY_CANCEL_BUTTON = "_cancel_button"; + private static final String KEY_OPTION_BUTTON = "_option_button"; + private static final String KEY_CANCELABLE = "__cancelable"; + private static final String KEY_AUTO_DISMISS = "__auto_dismiss";//点击按钮后是否可以自动关闭 + private static final String KEY_COUNT_DOWN = "__COUNT_DOWN"; + + private int callBackCode; + + + private final Handler mainHandler = new Handler(Looper.getMainLooper()) { + @Override + public void handleMessage(@NonNull Message msg) { + View contentView = getView(); + if (contentView == null) { + return; + } + Button confirm = contentView.findViewById(R.id.confirm_button); + int countDown = (Integer) msg.obj - 1; + if (countDown <= 0) { + confirm.setEnabled(true); + confirm.setText(R.string.confirm); + confirm.setTextColor(Color.BLACK); + } else { + confirm.setEnabled(false); + confirm.setText(String.valueOf(countDown)); + Message message = Message.obtain(); + message.obj = countDown; + mainHandler.sendMessageDelayed(message, 1000); + } + } + }; + private FragmentTipsWith2OptionLayoutBinding mBinding; + + public static void hardTips(@NonNull FragmentManager fragmentManager, + @NonNull LifecycleOwner lifecycleOwner, + String content, + IOperatorCallback callback) { + Bundle build = new Argument().content(content).cancelable(false).build(); + init(fragmentManager, lifecycleOwner, callback, build); + } + + + public static void tips(@NonNull FragmentManager fragmentManager, + @NonNull LifecycleOwner lifecycleOwner, + Argument argument, + IOperatorCallback callback) { + Bundle build = argument.build(); + init(fragmentManager, lifecycleOwner, callback, build); + } + + public static void dismissNowMe() { + if (currentFragmet != null && currentFragmet.getLifecycle().getCurrentState() == Lifecycle.State.RESUMED) { + currentFragmet.dismissAllowingStateLoss(); + currentFragmet = null; + } + } + + public static void tips(@NonNull FragmentManager fragmentManager, + @NonNull LifecycleOwner lifecycleOwner, + String confirmButton, + String cancelButton, + String optionButton, + String content, + IOperatorCallback callback) { + Bundle build = new Argument().confirmText(confirmButton).cancelText(cancelButton).optionText(optionButton).content(content).build(); + init(fragmentManager, lifecycleOwner, callback, build); + } + + public static void tips(@NonNull FragmentManager fragmentManager, + @NonNull LifecycleOwner lifecycleOwner, + String confirmButton, + String cancelButton, + String content, + IOperatorCallback callback) { + Bundle build = new Argument().confirmText(confirmButton).cancelText(cancelButton) + .content(content).build(); + init(fragmentManager, lifecycleOwner, callback, build); + } + + public static void tipsCountDownTime(@NonNull FragmentManager fragmentManager, + @NonNull LifecycleOwner lifecycleOwner, + String confirmButton, + String cancelButton, + String optionButton, + String content, + IOperatorCallback callback) { + Bundle build = new Argument().confirmText(confirmButton).cancelText(cancelButton).optionText(optionButton) + .content(content).countDownTime(COUNT_DOWN_TIME).build(); + init(fragmentManager, lifecycleOwner, callback, build); + } + + + public static void tipsCannotCancel(@NonNull FragmentManager fragmentManager, + @NonNull LifecycleOwner lifecycleOwner, + String confirmButton, + String cancelButton, + String content, + IOperatorCallback callback) { + Bundle build = new Argument().confirmText(confirmButton).cancelText(cancelButton) + .content(content).cancelable(false).build(); + init(fragmentManager, lifecycleOwner, callback, build); + } + + @Override + public void onStart() { + super.onStart(); + Dialog dialog = getDialog(); + if (dialog != null) { + dialog.setCancelable(isCancelableOwn()); + + Window window = dialog.getWindow(); + if (window != null) { + window.setLayout( + WindowManager.LayoutParams.MATCH_PARENT, + WindowManager.LayoutParams.WRAP_CONTENT); + } + } + } + + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + currentFragmet = this; + + mBinding = FragmentTipsWith2OptionLayoutBinding.inflate(inflater, container, false); + initData(); + initClickListener(); + initCountDownTime(); + + return mBinding.getRoot(); + } + + + @Override + public void onDestroyView() { + super.onDestroyView(); + mBinding = null; + currentFragmet = null; + } + + + private void initData() { + mBinding.title.setText(getTitle()); + mBinding.content.setText(getContent()); + mBinding.cancelButton.setText(getCancelText()); + String optionText = getOptionText(); + if (TextUtils.isEmpty(optionText)) { + mBinding.optionButton.setVisibility(View.GONE); + } else { + mBinding.optionButton.setVisibility(View.VISIBLE); + mBinding.optionButton.setText(optionText); + } + mBinding.confirmButton.setText(getConfirmText()); + } + + private void initCountDownTime() { + int countDownTime = getCountDownTime(); + if (countDownTime > 0) { + mBinding.confirmButton.setEnabled(false); + mBinding.confirmButton.setText(String.valueOf(countDownTime)); + mBinding.confirmButton.setTextColor(Color.RED); + Message message = Message.obtain(); + message.obj = countDownTime; + mainHandler.sendMessageDelayed(message, 1000); + } + } + + private void initClickListener() { + mBinding.confirmButton.setOnClickListener(view -> { + callBackCode = CALL_BACK_CODE_CONFIRM; + setResultForBtnClick(); + }); + mBinding.cancelButton.setOnClickListener(view -> { + callBackCode = CALL_BACK_CODE_CANCEL; + setResultForBtnClick(); + }); + mBinding.optionButton.setOnClickListener(view -> { + callBackCode = CALL_BACK_CODE_OPTION; + setResultForBtnClick(); + }); + } + + @Override + public void onDismiss(@NonNull DialogInterface dialog) { + setResultForIgnore(); + super.onDismiss(dialog); + } + + private void setResultForIgnore() { + if (isCallBackCodeConfirm() || isCallBackCodeCancel() + || isCallBackCodeOption()) { + return; + } + callBackCode = CALL_BACK_CODE_IGNORE; + setResult(); + } + + private void setResultForBtnClick() { + setResult(); + + if (isAutoDismiss() || !isCallBackCodeConfirm()) { + dismissAllowingStateLoss(); + } + } + + private boolean isCallBackCodeCancel() { + return callBackCode == CALL_BACK_CODE_CANCEL; + } + + private boolean isCallBackCodeConfirm() { + return callBackCode == CALL_BACK_CODE_CONFIRM; + } + + private boolean isCallBackCodeOption() { + return callBackCode == CALL_BACK_CODE_OPTION; + } + + private void setResult() { + Bundle bundle = new Bundle(); + bundle.putInt(KEY_CALL_BACK_CODE, callBackCode); + getParentFragmentManager().setFragmentResult(getTag(), bundle); + } + + private static void init(FragmentManager fragmentManager, LifecycleOwner lifecycleOwner, + IOperatorCallback callback, Bundle bundle) { + TipsWith2OptionFragment fragment = new TipsWith2OptionFragment(); + fragment.setArguments(bundle); + fragment.setCancelable(true); + + String tag = String.valueOf(System.currentTimeMillis()); + + fragmentManager + .setFragmentResultListener( + tag, + lifecycleOwner, + (requestKey, result) -> { + if (callback != null) { + if (fragment.getTag().equals(requestKey)) { + int type = result.getInt(KEY_CALL_BACK_CODE, -1); + if (CALL_BACK_CODE_CONFIRM == type) { + callback.onConfirm(); + } else if (CALL_BACK_CODE_OPTION == type) { + callback.onOption(); + } else if (CALL_BACK_CODE_CANCEL == type) { + callback.onCancel(); + } else if (CALL_BACK_CODE_IGNORE == type) { + callback.onIgnore(); + } + } + } + }); + fragment.show(fragmentManager, tag); + } + + public boolean isAutoDismiss() { + assert getArguments() != null; + return getArguments().getBoolean(KEY_AUTO_DISMISS, true); + } + + public boolean isCancelableOwn() { + assert getArguments() != null; + return getArguments().getBoolean(KEY_CANCELABLE, true); + } + + public String getTitle() { + assert getArguments() != null; + return getArguments().getString(KEY_TITLE, Tools.getString(R.string.notice)); + } + + public String getConfirmText() { + assert getArguments() != null; + return getArguments().getString(KEY_CONFIRM_BUTTON, Tools.getString(R.string.confirm)); + } + + public String getCancelText() { + assert getArguments() != null; + return getArguments().getString(KEY_CANCEL_BUTTON, Tools.getString(R.string.cancel)); + } + + public String getOptionText() { + assert getArguments() != null; + return getArguments().getString(KEY_OPTION_BUTTON, ""); + } + + public String getContent() { + assert getArguments() != null; + return getArguments().getString(KEY_CONTENT, ""); + } + + public int getCountDownTime() { + assert getArguments() != null; + return getArguments().getInt(KEY_COUNT_DOWN, 0); + } + + public static class Argument { + private Boolean cancelable;//是否可以取消 + private Boolean autoDismiss; + private String title; + private String confirmText; + private String cancelText; + private String optionText; + private String content; + private Integer countDownTime; + + public Argument() { + } + + public Argument autoDismiss(boolean autoDismiss) { + this.autoDismiss = autoDismiss; + return this; + } + + public Argument cancelable(boolean cancelable) { + this.cancelable = cancelable; + return this; + } + + public Argument title(String title) { + this.title = title; + return this; + } + + public Argument confirmText(String confirmText) { + this.confirmText = confirmText; + return this; + } + + public Argument cancelText(String cancelText) { + this.cancelText = cancelText; + return this; + } + + public Argument optionText(String optionText) { + this.optionText = optionText; + return this; + } + + public Argument content(String content) { + this.content = content; + return this; + } + + public Argument countDownTime(int countDownTime) { + this.countDownTime = countDownTime; + return this; + } + + public Bundle build() { + Bundle bundle = new Bundle(); + putValue(bundle, KEY_TITLE, title); + putValue(bundle, KEY_CONTENT, content); + putValue(bundle, KEY_CONFIRM_BUTTON, confirmText); + putValue(bundle, KEY_CANCEL_BUTTON, cancelText); + putValue(bundle, KEY_OPTION_BUTTON, optionText); + putValue(bundle, KEY_CANCELABLE, cancelable); + putValue(bundle, KEY_AUTO_DISMISS, autoDismiss); + putValue(bundle, KEY_COUNT_DOWN, countDownTime); + return bundle; + } + + private void putValue(Bundle bundle, String key, Object value) { + if (value != null) { + if (value instanceof Boolean) { + bundle.putBoolean(key, (Boolean) value); + } else if (value instanceof String) { + bundle.putString(key, (String) value); + } else if (value instanceof Integer) { + bundle.putInt(key, (Integer) value); + } + } + } + + } + + public interface IOperatorCallback { + void onConfirm(); + + void onOption(); + + void onCancel(); + + void onIgnore(); + } + + public static class SimpleCallback implements IOperatorCallback { + + @Override + public void onConfirm() { + + } + + @Override + public void onOption() { + + } + + @Override + public void onCancel() { + + } + + @Override + public void onIgnore() { + + } + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/ToleranceAttributeEditFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/ToleranceAttributeEditFragment.java new file mode 100644 index 0000000..67f10db --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/ToleranceAttributeEditFragment.java @@ -0,0 +1,188 @@ +package com.bingce.controlnetwork.fragment; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.widget.SwitchCompat; +import androidx.fragment.app.FragmentManager; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.tolerance.detail.ToleranceDetailRecord; +import com.bingce.controlapphelper.model.BundleConstants; +import com.bingce.controlapphelper.model.ProjectTolerance; +import com.bingce.controlapphelper.model.ToleranceAttributesType; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.event.RefreshToleranceTotailEvent; +import com.bingce.utils.ThreadPoolUtil; +import com.rengwuxian.materialedittext.MaterialEditText; + +import org.greenrobot.eventbus.EventBus; + +public class ToleranceAttributeEditFragment extends AbstractFullScreenDialogFragment { + + @Override + protected View createContentView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View contentView = inflater.inflate(R.layout.content_tolerance_attribute_editor_layout, container, false); + if (getArguments() != null) { + ThreadPoolUtil.execute(() -> { + String toleranceId = getArguments().getString(BundleConstants.KEY_TOLERANCE_ID); + ToleranceDetailRecord record = SurveyorDatabaseFactory + .instance + .getToleranceDetailDataSource() + .getRecordSync(toleranceId); + if (record == null) { + return; + } + ProjectTolerance projectTolerance = new ProjectTolerance(record); + int attributeIndex = getArguments().getInt(KEY_ATTRIBUTE_INDEX, -1); + if (attributeIndex < 0) { + return; + } + ToleranceAttributesType type = ToleranceAttributesType.values()[attributeIndex]; + MaterialEditText editor = contentView.findViewById(R.id.editor); + SwitchCompat switchCompat = contentView.findViewById(R.id.switch_control); + View integerView = contentView.findViewById(R.id.integerValue); + if (projectTolerance.isBoolValue(type)) { + if (editor != null) { + integerView.setVisibility(View.GONE); + } + if (integerView != null) { + integerView.setVisibility(View.GONE); + } + if (switchCompat != null) { + switchCompat.setVisibility(View.VISIBLE); + switchCompat.setChecked(projectTolerance.getBoolAttribute(type)); + } + } else if (projectTolerance.isDoubleValue(type)) { + if (editor != null) { + editor.setVisibility(View.VISIBLE); + String value = String.valueOf(projectTolerance.getDoubleAttribute(type)); + editor.setText(value); + editor.setHint(value); + } + if (switchCompat != null) { + switchCompat.setVisibility(View.GONE); + } + if (integerView != null) { + integerView.setVisibility(View.GONE); + } + } else if (projectTolerance.isIntegerValue(type)) { + if (editor != null) { + editor.setVisibility(View.GONE); + } + if (switchCompat != null) { + switchCompat.setVisibility(View.GONE); + } + if (integerView != null) { + integerView.setVisibility(View.VISIBLE); + String value = String.valueOf(projectTolerance.getIntegerAttribute(type)); + TextView countView = integerView.findViewById(R.id.count); + countView.setText(value); + View left = integerView.findViewById(R.id.left); + View right = integerView.findViewById(R.id.right); + if (left != null) { + if (Integer.parseInt(value) <= 1) { + left.setEnabled(false); + } + left.setOnClickListener(v -> { + int count = Integer.parseInt(countView.getText().toString()); + countView.setText(String.valueOf(count - 1)); + if (count - 1 <= 1) {//禁止减小 + left.setEnabled(false); + } + //减小后增大变为可用 + if (right != null) { + right.setEnabled(true); + } + }); + } + if (right != null) { + right.setOnClickListener(v -> { + int count = Integer.parseInt(countView.getText().toString()); + countView.setText(String.valueOf(count + 1)); + //增大后减小变为可用 + if (left != null) { + left.setEnabled(true); + } + if (type == ToleranceAttributesType.singleSurveyor && count + 1 >= 2) { + right.setEnabled(false); + } + }); + } + } + } + }); + } + return contentView; + } + + @Override + protected void onConfirm() { + ThreadPoolUtil.execute(() -> { + if (getArguments() == null || getView() == null) { + return; + } + String toleranceId = getArguments().getString(BundleConstants.KEY_TOLERANCE_ID); + ToleranceDetailRecord record = SurveyorDatabaseFactory + .instance + .getToleranceDetailDataSource() + .getRecordSync(toleranceId); + if (record == null) { + return; + } + ProjectTolerance projectTolerance = new ProjectTolerance(record); + int attributeIndex = getArguments().getInt(KEY_ATTRIBUTE_INDEX, -1); + if (attributeIndex < 0) { + return; + } + MaterialEditText editor = getView().findViewById(R.id.editor); + SwitchCompat switchCompat = getView().findViewById(R.id.switch_control); + TextView count = getView().findViewById(R.id.count); + ToleranceAttributesType type = ToleranceAttributesType.values()[attributeIndex]; + if (projectTolerance.isBoolValue(type)) { + projectTolerance.setBoolAttribute(type, switchCompat.isChecked()); + } else if (projectTolerance.isDoubleValue(type)) { + String string = editor.getText().toString(); + if (string.isEmpty()) { + dismiss(); + return; + } + projectTolerance.setDoubleAttribute(type, Double.parseDouble(string)); + } else if (projectTolerance.isIntegerValue(type)) { + String string = count.getText().toString(); + if (string.isEmpty()) { + dismiss(); + return; + } + projectTolerance.setIntegerAttribute(type, Integer.parseInt(string)); + } + //存储数据 + projectTolerance.save2DataSource(() -> { + EventBus.getDefault().post(new RefreshToleranceTotailEvent()); + dismissAllowingStateLoss(); + }); + + }); + } + + private static final String KEY_ATTRIBUTE_INDEX = "__attribute_index___"; + + public static void editAndSave(String toleranceId, + ToleranceAttributesType attributesType, + String groupTitle, + String title, + FragmentManager fragmentManager) { + ToleranceAttributeEditFragment fragment = new ToleranceAttributeEditFragment(); + Bundle args = new Bundle(); + args.putInt(KEY_ATTRIBUTE_INDEX, attributesType.ordinal()); + args.putString(BundleConstants.KEY_TOLERANCE_ID, toleranceId); + setArgs(args, groupTitle, title); + fragment.setArguments(args); + fragment.show(fragmentManager, ToleranceAttributeEditFragment.class.getName()); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/ToleranceDetailFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/ToleranceDetailFragment.java new file mode 100644 index 0000000..d8989e9 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/ToleranceDetailFragment.java @@ -0,0 +1,179 @@ +package com.bingce.controlnetwork.fragment; + +import android.content.Context; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ExpandableListView; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; + +import com.bingce.controlapphelper.datasource.database.leveling.tolerance.LevelingToleranceDetail; +import com.bingce.controlapphelper.datasource.database.tolerance.detail.IToleranceDetail; +import com.bingce.controlapphelper.datasource.database.tolerance.detail.ToleranceDetailRecord; +import com.bingce.controlapphelper.datasource.database.tolerance.load.IToleranceOperate; +import com.bingce.controlapphelper.interfacee.IProjectTolerance; +import com.bingce.controlapphelper.model.BundleConstants; +import com.bingce.controlapphelper.model.ProjectTolerance; +import com.bingce.controlapphelper.model.tolerance.ProjectToleranceLeveling; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.activity.fragmentcontainer.FragmentContainerActivity; +import com.bingce.controlnetwork.adapter.ToleranceDetailAdapter; +import com.bingce.controlnetwork.event.RefreshToleranceTotailEvent; +import com.bingce.controlnetwork.util.tolerance.ToleranceOperateUtil; +import com.bingce.utils.ThreadPoolUtil; + +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; +import org.greenrobot.eventbus.ThreadMode; + + +/** + * 限差详情页 + */ +public class ToleranceDetailFragment extends Fragment { + public static final String TAG = ToleranceDetailFragment.class.getName(); + private String currentToleranceId; + private ToleranceDetailAdapter adapter; + + private ExpandableListView expandableListView; + + @Subscribe(threadMode = ThreadMode.MAIN) + public void refresh(RefreshToleranceTotailEvent event) { + refreshUi(); + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + if (getArguments() != null) { + currentToleranceId = getArguments().getString(BundleConstants.KEY_TOLERANCE_ID); + } + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + EventBus.getDefault().register(this); + View view = inflater.inflate(R.layout.fragment_limit_detail_list, container, false); + expandableListView = view.findViewById(R.id.list); + refreshUi(); + return view; + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + EventBus.getDefault().unregister(this); + } + + public void switchTolerance(String id) { + currentToleranceId = id; + refreshUi(); + } + + private void refreshUi() { + IToleranceOperate operate = ToleranceOperateUtil.getOperate(currentToleranceId); + if (operate == null) { + return; + } + ThreadPoolUtil.execute(() -> { + IToleranceDetail iToleranceDetail = operate.getIToleranceDetail(currentToleranceId); + ThreadPoolUtil.executeInMain(() -> { + if (iToleranceDetail != null) { + if (iToleranceDetail instanceof LevelingToleranceDetail) { + updateTolerance(expandableListView, new ProjectToleranceLeveling((LevelingToleranceDetail) iToleranceDetail)); + } else if (iToleranceDetail instanceof ToleranceDetailRecord) { + updateTolerance(expandableListView, new ProjectTolerance((ToleranceDetailRecord) iToleranceDetail)); + } + } + }); + }); + + } + + /** + * 填充数据 + * + * @param expandableListView + * @param projectTolerance + */ + private void updateTolerance(ExpandableListView expandableListView, IProjectTolerance projectTolerance) { + if (!currentToleranceId.equals(projectTolerance.id())) { + return; + } + boolean editable = projectTolerance.isWritable(); + //填充adapter + if (adapter == null) { + adapter = new ToleranceDetailAdapter(projectTolerance); + expandableListView.setAdapter(adapter); + expandAllItemView(expandableListView, projectTolerance); + } else { + adapter.updateData(projectTolerance); + expandAllItemView(expandableListView, projectTolerance); + } + //设置点击事件 + expandableListView.setOnChildClickListener((parent, v, groupPosition, childPosition, viewId) -> { + boolean forbidModify = false; + if (getArguments() != null) { + forbidModify = getArguments().getBoolean(KEY_FORBID_MODIFY, false); + } + if (editable && !forbidModify) {//执行编辑 + ToleranceAttributeEditFragment + .editAndSave(currentToleranceId, + projectTolerance.attributesType(groupPosition, childPosition), + projectTolerance.attributesName(groupPosition, childPosition), + projectTolerance.groupName(groupPosition), + getChildFragmentManager()); + } else if (forbidModify) { + TipsFragment.tipsOnly(getChildFragmentManager(), + getViewLifecycleOwner(), + getContext(), + getString(R.string.tips_tolerance_cannt_modify_because_has_surveyed)); + } else { + TipsFragment.tipsOnly(getChildFragmentManager(), + getViewLifecycleOwner(), + getContext(), + getString(R.string.tips_tolerance_template_cannt_delete)); + } + return true; + }); + } + + /** + * 全部展开 + * + * @param expandableListView + * @param projectTolerance + */ + private void expandAllItemView(ExpandableListView expandableListView, IProjectTolerance projectTolerance) { + int groupCount = projectTolerance.groupCount(); + for (int index = 0; index < groupCount; index++) { + expandableListView.expandGroup(index); + } + } + + private static final String KEY_FORBID_MODIFY = "__forbid_modify"; + + public static ToleranceDetailFragment newInstance(Bundle args, boolean forbidModify) { + ToleranceDetailFragment fragment = new ToleranceDetailFragment(); + args.putBoolean(KEY_FORBID_MODIFY, forbidModify); + fragment.setArguments(args); + return fragment; + } + + public static ToleranceDetailFragment newInstance(Bundle args) { + ToleranceDetailFragment fragment = new ToleranceDetailFragment(); + fragment.setArguments(args); + return fragment; + } + + public static void start(Context context, String toleranceId, boolean forbidModify) { + Bundle args = new Bundle(); + args.putBoolean(KEY_FORBID_MODIFY, forbidModify); + args.putString(BundleConstants.KEY_TOLERANCE_ID, toleranceId); + FragmentContainerActivity.start(context, TAG, "限差设置", args); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/ToleranceManageFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/ToleranceManageFragment.java new file mode 100644 index 0000000..336c84f --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/ToleranceManageFragment.java @@ -0,0 +1,231 @@ +package com.bingce.controlnetwork.fragment; + +import android.content.Context; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.project.IProjectDataSource; +import com.bingce.controlapphelper.datasource.database.project.ProjectRecord; +import com.bingce.controlapphelper.datasource.database.tolerance.detail.IToleranceDetailDataSource; +import com.bingce.controlapphelper.datasource.database.tolerance.detail.ToleranceDetailRecord; +import com.bingce.controlapphelper.datasource.database.tolerance.group.ToleranceGroupRecord; +import com.bingce.controlapphelper.datasource.database.tolerance.level.ToleranceLevelRecord; +import com.bingce.controlapphelper.datasource.database.tolerance.load.ToleranceLoadUtil; +import com.bingce.controlapphelper.model.BundleConstants; +import com.bingce.controlapphelper.surveyor.method.ToleranceMethodKt; +import com.bingce.controlapphelper.util.SurveyorRecordUtil; +import com.bingce.controlapphelper.util.ToleranceUtil; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.activity.fragmentcontainer.FragmentContainerActivity; +import com.bingce.controlnetwork.adapter.BaseIndexTextWithContextMenuAdapter; +import com.bingce.controlnetwork.adapter.IUpdateListAdapter; +import com.bingce.controlnetwork.adapter.contextmenu.ContextMenuDeleteEdit; +import com.bingce.controlnetwork.fragment.base.BaseFragment; +import com.bingce.utils.ThreadPoolUtil; + +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +import blankj.utilcode.util.ToastUtils; + +/** + * 自定义限差管理 + */ +public class ToleranceManageFragment extends BaseFragment { + public static final String TAG = ToleranceManageFragment.class.getName(); + private BaseIndexTextWithContextMenuAdapter adapter = null; + + private String projectType; + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + if (getArguments() != null) { + projectType = getArguments().getString(BundleConstants.KEY_PROJECT_TYPE); + } + } + + @Nullable + @org.jetbrains.annotations.Nullable + @Override + public View onCreateView(@NonNull @NotNull LayoutInflater inflater, @Nullable @org.jetbrains.annotations.Nullable ViewGroup container, @Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) { + View rootView = inflater.inflate(R.layout.fragment_tolerance_manager_layout, container, false); + + RecyclerView recyclerView = rootView.findViewById(R.id.list); + IToleranceDetailDataSource toleranceDetailDataSource = + SurveyorDatabaseFactory.instance.getToleranceDetailDataSource(); + toleranceDetailDataSource + .getCustomLiveDataListByGroup() + .observe(getViewLifecycleOwner(), + toleranceDetailRecords -> { + if (adapter == null) { + adapter = new _Adapter( + getChildFragmentManager(), + getViewLifecycleOwner(), + getContext(), + toleranceDetailRecords, + this::clickToleranceItem); + recyclerView.setAdapter(adapter); + } else { + adapter.updateData(toleranceDetailRecords); + } + }); + + View createButton = rootView.findViewById(R.id.create_new); + if (createButton != null) { + createButton.setOnClickListener(this::showSelectedToleranceDlg); + } + return rootView; + } + + /** + * 点击限差进行编辑 + * + * @param item + */ + private void clickToleranceItem(ToleranceDetailRecord item) { + ThreadPoolUtil.execute(() -> { + IProjectDataSource projectDataSource = SurveyorDatabaseFactory + .instance.getProjectDataSource(); + List projectRecordList = projectDataSource + .getDataListByToleranceId(item.getId()); + boolean hasSurveyed = false; + for (ProjectRecord projectRecord : projectRecordList) { + if (SurveyorRecordUtil.isProjectSurveyor(projectRecord.getId())) { + hasSurveyed = true; + break; + } + } + boolean finalHasSurveyed = hasSurveyed; + runOnUI(() -> ToleranceDetailFragment.start(getContext(), item.getId(), finalHasSurveyed)); + }); + } + + + private void showSelectedToleranceDlg(View view) { + SelectToleranceTemplateBottomSheetFragment.select( + getChildFragmentManager(), + getViewLifecycleOwner(), + projectType, + toleranceId -> onSelectedTolerance( + getChildFragmentManager(), + getViewLifecycleOwner(), + getContext(), + toleranceId)); + } + + private static void onSelectedTolerance(FragmentManager fragmentManager, + LifecycleOwner lifecycleOwner, + Context context, + String toleranceId) { + //查询 限差 名称 + IToleranceDetailDataSource toleranceDetailDataSource = + SurveyorDatabaseFactory.instance.getToleranceDetailDataSource(); + ThreadPoolUtil.execute(() -> { + //先检测预置模板 + ToleranceDetailRecord toleranceDetailRecord = (ToleranceDetailRecord) ToleranceLoadUtil.getTriangleToleranceLoad().detailOf(toleranceId); + if (toleranceDetailRecord == null) { + toleranceDetailRecord = toleranceDetailDataSource.getRecordSync(toleranceId); + } + if (toleranceDetailRecord == null) { + return; + } + + //查询限差完整名称 + ToleranceGroupRecord toleranceGroupRecord = ToleranceLoadUtil.getTriangleToleranceLoad().groupOf(toleranceDetailRecord.getGroupId()); + ToleranceLevelRecord toleranceLevelRecord = ToleranceLoadUtil.getTriangleToleranceLoad().levelOf(toleranceDetailRecord.getLevelId()); + if (toleranceGroupRecord == null) { + ToastUtils.showShort(R.string.error_tips_tolerance_template_read_failure); + return; + } + ToleranceDetailRecord finalToleranceDetailRecord = toleranceDetailRecord; + ThreadPoolUtil.executeInMain(() -> StringInputFragment + .input( + fragmentManager, + context.getString(R.string.tips_please_input_new_tolerance_name), + ToleranceUtil.completedToleranceName(toleranceGroupRecord, toleranceLevelRecord, finalToleranceDetailRecord), + lifecycleOwner, + string -> { + if (string == null || string.isEmpty()) { + ToastUtils.showShort(R.string.string_no_empty); + return; + } + gotoEditNewTolerance(context, finalToleranceDetailRecord, string); + } + )); + }); + } + + private static void gotoEditNewTolerance(Context context, ToleranceDetailRecord template, String name) { + ToleranceDetailRecord newInstance = template.convertCustomRecord(template); + newInstance.singleSurveyor = template.singleSurveyor; + newInstance.setName(name); + SurveyorDatabaseFactory + .instance + .getToleranceDetailDataSource() + .saveWithCallback(newInstance, () -> ToleranceDetailFragment.start(context, newInstance.getId(), false)); + } + + private static class _Adapter extends BaseIndexTextWithContextMenuAdapter + implements IUpdateListAdapter { + public _Adapter( + FragmentManager fragmentManager, + LifecycleOwner lifecycleOwner, + Context context, + List records, + IOnItemClick callback) { + super(records == null ? new ArrayList<>() : records, callback, new ContextMenuDeleteEdit() { + @Override + protected void delete(ToleranceDetailRecord item) { + //检测是否有project使用了当前限差方案 + ThreadPoolUtil.execute(() -> { + long count = SurveyorDatabaseFactory + .instance + .getProjectDataSource() + .recordCountWithTolerance(item.getId()); + if (count <= 0) { + IToleranceDetailDataSource toleranceDetailDataSource = + SurveyorDatabaseFactory.instance.getToleranceDetailDataSource(); + toleranceDetailDataSource.delete(item); + } else { + ThreadPoolUtil.executeInMain(() -> Toast + .makeText(context, R.string.tips_tolerance_cannt_delete_because_of_used, Toast.LENGTH_SHORT) + .show()); + } + }); + } + + @Override + protected void edit(ToleranceDetailRecord item) { + ToleranceMethodKt.changeToleranceName( + fragmentManager, lifecycleOwner, item); + } + }); + } + } + + public static void start(Context context, String projectType) { + Bundle bundle = new Bundle(); + bundle.putString(BundleConstants.KEY_PROJECT_TYPE, projectType); + FragmentContainerActivity.start(context, TAG, R.string.name_custom_telorance_manager, bundle); + } + + public static ToleranceManageFragment newInstance(Bundle bundle) { + ToleranceManageFragment fragment = new ToleranceManageFragment(); + fragment.setArguments(bundle); + return fragment; + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/ToleranceSelectFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/ToleranceSelectFragment.java new file mode 100644 index 0000000..cc78629 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/ToleranceSelectFragment.java @@ -0,0 +1,109 @@ +package com.bingce.controlnetwork.fragment; + +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.text.TextUtils; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; + +import androidx.activity.result.ActivityResultLauncher; +import androidx.activity.result.contract.ActivityResultContracts; +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; + +import com.bingce.controlapphelper.datasource.database.tolerance.detail.IToleranceDetail; +import com.bingce.controlapphelper.datasource.database.tolerance.load.IToleranceOperate; +import com.bingce.controlapphelper.model.BundleConstants; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.activity.fragmentcontainer.FragmentContainerActivity; +import com.bingce.controlnetwork.util.tolerance.ToleranceOperateUtil; +import com.bingce.utils.ThreadPoolUtil; + +public class ToleranceSelectFragment extends AbstractProjectToleranceFragment { + public static final String TAG = ToleranceSelectFragment.class.getName(); + + @Override + protected void onCreateView(View view) { + String toleranceId = null; + if (getArguments() != null) { + toleranceId = getArguments().getString(BundleConstants.KEY_TOLERANCE_ID); + } + initData(view, toleranceId); + setHasOptionsMenu(true); + } + + private void initData(View view, String toleranceId) { + if (TextUtils.isEmpty(toleranceId)) { + IToleranceDetail firstDefaultTolerance = getNewDefaultTolerance(projectType); + updateToleranceDetail(view, firstDefaultTolerance); + } else { + ThreadPoolUtil.execute(() -> { + IToleranceOperate operate = ToleranceOperateUtil.getOperate(toleranceId); + if (operate != null) { + IToleranceDetail iToleranceDetail = operate.getIToleranceDetail(toleranceId); + updateToleranceDetail(view, iToleranceDetail); + } + }); + } + } + + @Override + public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { + inflater.inflate(R.menu.tolerance_select_menu, menu); + super.onCreateOptionsMenu(menu, inflater); + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + if (item.getItemId() == R.id.confirm_button) { + Intent intent = new Intent(); + intent.putExtra(BundleConstants.KEY_TOLERANCE_ID, currentTolerance()); + Activity activity = getActivity(); + if (activity != null) { + activity.setResult(Activity.RESULT_OK, intent); + activity.finish(); + } + } + return super.onOptionsItemSelected(item); + } + + public static void start(Context context, String toleranceId, String projectType, + ActivityResultLauncher launcher) { + if (launcher == null) { + return; + } + Bundle args = new Bundle(); + args.putString(BundleConstants.KEY_TOLERANCE_ID, toleranceId); + args.putString(BundleConstants.KEY_PROJECT_TYPE, projectType); + launcher.launch(FragmentContainerActivity.startIntent(context, TAG, R.string.select_tolerance, args)); + } + + public static ActivityResultLauncher createActivityLauncher(Fragment fragment, ISelectCallback selectCallback) { + return fragment.registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> { + if (result != null && Activity.RESULT_OK == result.getResultCode()) { + Intent intent = result.getData(); + if (intent != null) { + String id = intent.getStringExtra(BundleConstants.KEY_TOLERANCE_ID); + selectCallback.onSelectTolerance(id); + return; + } + } +// selectCallback.onSelectTolerance(null); + }); + } + + public static ToleranceSelectFragment newInstance(Bundle bundle) { + ToleranceSelectFragment fragment = new ToleranceSelectFragment(); + fragment.setArguments(bundle); + return fragment; + } + + public interface ISelectCallback { + void onSelectTolerance(String id); + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/base/BaseFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/base/BaseFragment.java new file mode 100644 index 0000000..5c94c4f --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/base/BaseFragment.java @@ -0,0 +1,32 @@ +package com.bingce.controlnetwork.fragment.base; + +import android.view.View; + +import androidx.annotation.IdRes; +import androidx.fragment.app.Fragment; +import androidx.lifecycle.Lifecycle; + +import com.bingce.controlapphelper.util.IUIRunner; + +public class BaseFragment extends Fragment implements IUIRunner { + public void runOnUI(Runnable runnable) { + if (getActivity() == null) { + return; + } + getActivity().runOnUiThread(runnable); + } + + final protected T findViewById(@IdRes int id) { + if (getActivity() == null) { + return null; + } + return getActivity().findViewById(id); + } + + final protected void setCreatedData(Runnable runnable) { + if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.CREATED)) { + runnable.run(); + } + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/base/BaseLazyFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/base/BaseLazyFragment.java new file mode 100644 index 0000000..ee4d84d --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/base/BaseLazyFragment.java @@ -0,0 +1,87 @@ +package com.bingce.controlnetwork.fragment.base; + +import android.os.Bundle; +import android.view.View; + +import androidx.annotation.IdRes; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; +import androidx.lifecycle.Lifecycle; + +public abstract class BaseLazyFragment extends Fragment { + + /** + * 是否执行懒加载 + */ + private boolean isLoaded = false; + + /** + * 当前Fragment是否对用户可见 + */ + private boolean isVisibleToUser = false; + + /** + * view是否已经创建 + */ + private boolean onViewCreated = false; + + final protected void runOnUI(Runnable runnable) { + if (getActivity() == null) { + return; + } + getActivity().runOnUiThread(runnable); + } + + final protected T findViewById(@IdRes int id) { + if (getActivity() == null) { + return null; + } + return getActivity().findViewById(id); + } + + final protected void setCreatedData(Runnable runnable) { + if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.CREATED)) { + runnable.run(); + } + } + + + @Override + public void setUserVisibleHint(boolean isVisibleToUser) { + super.setUserVisibleHint(isVisibleToUser); + this.isVisibleToUser = isVisibleToUser; + judgeLoadData(); + } + + @Override + public void onHiddenChanged(boolean hidden) { + super.onHiddenChanged(hidden); + isVisibleToUser = !hidden; + } + + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + onViewCreated = true; + judgeLoadData(); + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + isLoaded = false; + isVisibleToUser = false; + onViewCreated = false; + } + + private void judgeLoadData() { + if (!isLoaded && isVisibleToUser && onViewCreated) { + loadData(); + isLoaded = true; + } + } + + protected abstract void loadData(); +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/bottompage/BottomBean.kt b/app/src/main/java/com/bingce/controlnetwork/fragment/bottompage/BottomBean.kt new file mode 100644 index 0000000..e2ff1ce --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/bottompage/BottomBean.kt @@ -0,0 +1,15 @@ +package com.bingce.controlnetwork.fragment.bottompage + +import android.os.Parcelable +import androidx.annotation.Keep +import kotlinx.android.parcel.Parcelize + +@Keep +@Parcelize +data class BottomBean( + val id: String, + val name: String, + val pageIndex: Int, + val isSelect: Boolean = false, + val tag: String? = null +) : Parcelable diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/bottompage/BottomPageAdapter.kt b/app/src/main/java/com/bingce/controlnetwork/fragment/bottompage/BottomPageAdapter.kt new file mode 100644 index 0000000..badb59d --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/bottompage/BottomPageAdapter.kt @@ -0,0 +1,42 @@ +package com.bingce.controlnetwork.fragment.bottompage + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.bingce.controlapphelper.util.FastClickUtil +import com.bingce.controlnetwork.adapter.BaseAdapter +import com.bingce.controlnetwork.databinding.ListItemIndexTextSelectableLayoutBinding + +class BottomPageAdapter(val context: Context, private val dataList: List, callBack: CallBack) : + BaseAdapter(dataList) { + + private val callBack: CallBack + + init { + this.callBack = callBack + } + + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + val bean = dataList[position] + holder.mBinding.index.text = (position + 1).toString() + holder.mBinding.text.text = bean.name + holder.mBinding.status.visibility = if (bean.isSelect) View.VISIBLE else View.GONE + + holder.mBinding.root.setOnClickListener { + FastClickUtil.click { + callBack.back(bean) + } + } + } + + override fun createVH(parent: ViewGroup, viewType: Int): ViewHolder { + val binding = ListItemIndexTextSelectableLayoutBinding.inflate(LayoutInflater.from(context), parent, false) + return ViewHolder(binding) + } + + interface CallBack { + fun back(bottomBean: BottomBean) + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/bottompage/BottomPageContentFragment.kt b/app/src/main/java/com/bingce/controlnetwork/fragment/bottompage/BottomPageContentFragment.kt new file mode 100644 index 0000000..aa40fea --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/bottompage/BottomPageContentFragment.kt @@ -0,0 +1,99 @@ +package com.bingce.controlnetwork.fragment.bottompage + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import androidx.fragment.app.viewModels +import com.bingce.controlnetwork.databinding.FragmentBottomPageContentBinding +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.MainScope +import kotlinx.coroutines.cancel +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + +class BottomPageContentFragment(private val dataList: List) : Fragment() { + private var _binding: FragmentBottomPageContentBinding? = null + val mBinding get() = _binding!! + + private val viewModel: BottomSwitchVm by viewModels({ requireParentFragment() }) + + private val mainScope = MainScope() + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + _binding = FragmentBottomPageContentBinding.inflate(inflater, container, false) + return mBinding.root + } + + override fun onDestroyView() { + super.onDestroyView() + mainScope.cancel() + _binding = null + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + initView() + } + + override fun onHiddenChanged(hidden: Boolean) { + super.onHiddenChanged(hidden) + if (!hidden) { + refreshTitleVisiable() + } + } + + private fun initView() { + mBinding.back.setOnClickListener { + viewModel.selectList.removeLast() + getBottomPageFragment()?.removeFragment() + } + + val adapter = + BottomPageAdapter(requireContext(), dataList, object : BottomPageAdapter.CallBack { + override fun back(bottomBean: BottomBean) { + itemClick(bottomBean) + } + }) + mBinding.recyclerView.adapter = adapter + + mBinding.title.text = getBottomPageFragment()?.getTitle(this) + refreshTitleVisiable() + } + + private fun itemClick(bottomBean: BottomBean) { + mainScope.launch { + val dataNext = withContext(Dispatchers.IO) { + getBottomPageFragment()?.getDataNext(bottomBean) + } + viewModel.selectList.add(bottomBean) + if (dataNext.isNullOrEmpty()) { + getBottomPageFragment()?.setResultData() + } else { + getBottomPageFragment()?.addFragment(dataNext, true) + } + } + } + + private fun getBottomPageFragment(): BottomPageFragment? { + return parentFragment as? BottomPageFragment + } + + private fun refreshTitleVisiable() { + parentFragmentManager.fragments.let { + if (it.size <= 1) { + mBinding.back.visibility = View.GONE + } else { + mBinding.back.visibility = View.VISIBLE + } + } + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/bottompage/BottomPageFragment.kt b/app/src/main/java/com/bingce/controlnetwork/fragment/bottompage/BottomPageFragment.kt new file mode 100644 index 0000000..d102353 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/bottompage/BottomPageFragment.kt @@ -0,0 +1,157 @@ +package com.bingce.controlnetwork.fragment.bottompage + +import android.os.Bundle +import android.view.Gravity +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.DialogFragment +import androidx.fragment.app.FragmentManager +import androidx.fragment.app.FragmentTransaction +import androidx.fragment.app.setFragmentResult +import androidx.fragment.app.viewModels +import androidx.lifecycle.LifecycleOwner +import blankj.utilcode.util.ToastUtils +import com.bingce.controlapphelper.model.BundleConstants +import com.bingce.controlapphelper.util.GsonUtil +import com.bingce.controlnetwork.R +import com.bingce.controlnetwork.databinding.FragmentSingleFramelayoutLayoutBinding +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.MainScope +import kotlinx.coroutines.cancel +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + +class BottomPageFragment(val data: IData) : DialogFragment() { + + private val mainScope = MainScope() + + private var _binding: FragmentSingleFramelayoutLayoutBinding? = null + val mBinding get() = _binding!! + + private val viewModel: BottomSwitchVm by viewModels() + + companion object { + @JvmStatic + fun showBottom( + fragmentManager: FragmentManager, + lifecycleOwner: LifecycleOwner, + data: IData, + callBack: CallBack + ) { + val bottomPageFragment = BottomPageFragment(data) + val tag = System.currentTimeMillis().toString() + + fragmentManager.setFragmentResultListener( + tag, + lifecycleOwner + ) { requestKey: String, bundle: Bundle -> + bottomPageFragment.dismiss() + if (requestKey == tag) { + bundle.getString(BundleConstants.KEY_SELECT_LIST)?.let { it -> + GsonUtil.toAny>(it)?.let juadge@{ + if (it.size < 2) { + ToastUtils.showShort(R.string.no_data) + return@juadge + } + callBack.back(it) + } + } + } + } + bottomPageFragment.show(fragmentManager, tag) + } + } + + + override fun onStart() { + super.onStart() + dialog?.window?.run { + setWindowAnimations(R.style.animate_dialog) + setBackgroundDrawable(null) + val params = attributes + params.gravity = Gravity.BOTTOM + params.width = ViewGroup.LayoutParams.MATCH_PARENT + params.height = ViewGroup.LayoutParams.WRAP_CONTENT + attributes = params + } + + } + + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + _binding = FragmentSingleFramelayoutLayoutBinding.inflate(inflater, container, false) + return mBinding.root + } + + override fun onDestroyView() { + super.onDestroyView() + mainScope.cancel() + _binding = null + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + mainScope.launch { + val firstPageData = withContext(Dispatchers.IO) { + data.getData(null) + } + firstPageData?.let { + addFragment(it, false) + } + } + } + + fun addFragment(dataNext: List, isNeedAnim: Boolean) { + addOrDeleteFragment(isNeedAnim) { + val contentFragment = BottomPageContentFragment(dataNext) + add(R.id.container, contentFragment) + } + } + + fun removeFragment() { + childFragmentManager.fragments.last()?.let { + addOrDeleteFragment { + remove(it) + } + } + } + + fun setResultData() { + val toJson = GsonUtil.toJson(viewModel.selectList) + val bundle = Bundle() + bundle.putString(BundleConstants.KEY_SELECT_LIST, toJson) + setFragmentResult(tag!!, bundle) + } + + suspend fun getDataNext(currentData: BottomBean): List? { + return data.getData(currentData) + } + + fun getTitle(bottomPageContentFragment: BottomPageContentFragment): String { + return data.getTitle(childFragmentManager.fragments.indexOf(bottomPageContentFragment)) + } + + private fun addOrDeleteFragment( + isNeedAnim: Boolean = true, + block: FragmentTransaction.() -> Unit + ) { + val transaction = childFragmentManager + .beginTransaction() + if (isNeedAnim) { + transaction.setCustomAnimations(R.anim.slide_in_right, R.anim.slide_out_right) + } + block(transaction) + transaction.commit() + } + + interface CallBack { + fun back(selectData: List) + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/bottompage/BottomSwitchVm.kt b/app/src/main/java/com/bingce/controlnetwork/fragment/bottompage/BottomSwitchVm.kt new file mode 100644 index 0000000..35c7013 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/bottompage/BottomSwitchVm.kt @@ -0,0 +1,8 @@ +package com.bingce.controlnetwork.fragment.bottompage + +import androidx.lifecycle.ViewModel + +class BottomSwitchVm : ViewModel() { + // val dataList = mutableListOf() + val selectList = mutableListOf() +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/bottompage/IData.kt b/app/src/main/java/com/bingce/controlnetwork/fragment/bottompage/IData.kt new file mode 100644 index 0000000..4eeafa1 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/bottompage/IData.kt @@ -0,0 +1,7 @@ +package com.bingce.controlnetwork.fragment.bottompage + +interface IData { + suspend fun getData(bottomBean: BottomBean?): List? + + fun getTitle(pageIndex: Int): String +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/bottompage/ViewHolder.kt b/app/src/main/java/com/bingce/controlnetwork/fragment/bottompage/ViewHolder.kt new file mode 100644 index 0000000..1e1c155 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/bottompage/ViewHolder.kt @@ -0,0 +1,6 @@ +package com.bingce.controlnetwork.fragment.bottompage + +import androidx.recyclerview.widget.RecyclerView +import com.bingce.controlnetwork.databinding.ListItemIndexTextSelectableLayoutBinding + +class ViewHolder(val mBinding: ListItemIndexTextSelectableLayoutBinding) : RecyclerView.ViewHolder(mBinding.root) \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/heighttraverse/CreateOrEditRouteDialog.java b/app/src/main/java/com/bingce/controlnetwork/fragment/heighttraverse/CreateOrEditRouteDialog.java new file mode 100644 index 0000000..41c2bb9 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/heighttraverse/CreateOrEditRouteDialog.java @@ -0,0 +1,447 @@ +package com.bingce.controlnetwork.fragment.heighttraverse; + +import android.content.Intent; +import android.os.Bundle; +import android.text.TextUtils; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.WindowManager; + +import androidx.activity.result.ActivityResultLauncher; +import androidx.annotation.IdRes; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.WorkerThread; +import androidx.fragment.app.DialogFragment; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.point.PointRecord; +import com.bingce.controlapphelper.datasource.database.route.RouteRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord; +import com.bingce.controlapphelper.model.PickPointResult; +import com.bingce.controlapphelper.util.CheckLocationUtil; +import com.bingce.controlapphelper.util.GetLocationUtil; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.databinding.DialogCreateRouteBinding; +import com.bingce.controlnetwork.fragment.PickPointFragment; +import com.bingce.controlnetwork.fragment.TipsFragment; +import com.bingce.utils.ThreadPoolUtil; +import com.rengwuxian.materialedittext.MaterialEditText; + +import java.util.ArrayList; +import java.util.List; + +import blankj.utilcode.util.ToastUtils; + +public class CreateOrEditRouteDialog extends DialogFragment { + private PickPointResult pickPointResultStart; + private PickPointResult pickPointResultEnd; + + //选择起点还是终点的标志 + private static final String SELECT_START_TAG = "SELECT_START_TAG"; + private static final String SELECT_END_TAG = "SELECT_END_TAG"; + + private static final String KEY_PROJECT_ID = "KEY_PROJECT_ID"; + private static final String KEY_ROUTE_ID = "KEY_ROUTE_ID"; + + private static final String KEY_ROUTE_NAME = "KEY_ROUTE_NAME"; + private static final String KEY_START_POINT_ID = "KEY_START_POINT_ID"; + private static final String KEY_END_POINT_ID = "KEY_END_POINT_ID"; + + private DialogCreateRouteBinding mBinding; + private GetLocationUtil getLocationUtil; + + public static void start(String projectId, String routeId, FragmentManager fragmentManager, + @NonNull LifecycleOwner lifecycleOwner, + CallBack callback) { + Bundle args = new Bundle(); + args.putString(KEY_PROJECT_ID, projectId); + args.putString(KEY_ROUTE_ID, routeId); + showFragment(args, fragmentManager, lifecycleOwner, callback); + } + + + private static void showFragment(Bundle args, FragmentManager fragmentManager, LifecycleOwner lifecycleOwner, CallBack callback) { + String tag = String.valueOf(System.currentTimeMillis()); + CreateOrEditRouteDialog fragment = new CreateOrEditRouteDialog(); + fragment.setArguments(args); + fragmentManager + .setFragmentResultListener( + tag, + lifecycleOwner, + (requestKey, resultBundle) -> { + if (tag.equals(requestKey)) { + callback.result( + resultBundle.getString(KEY_ROUTE_NAME), + resultBundle.getString(KEY_START_POINT_ID), + resultBundle.getString(KEY_END_POINT_ID) + ); + } + }); + fragment.show(fragmentManager, tag); + } + + private final ActivityResultLauncher defaultStationLauncher = PickPointFragment.createActivityLauncher(this, (type, pickPointResult) -> { + if (SELECT_START_TAG.equals(type)) { + pickPointResultStart = pickPointResult; + } else if (SELECT_END_TAG.equals(type)) { + pickPointResultEnd = pickPointResult; + } + if (pickPointResult == null || isListEmpty(pickPointResult.getSelectedIds()) || isListEmpty(pickPointResult.getSelectedNames()) + || pickPointResult.getSelectedNames().size() != pickPointResult.getSelectedIds().size()) { + ToastUtils.showShort(R.string.abnormal_point_selection); + return; + } + setEtData(type); + }); + + private void setEtData(String type) { + if (SELECT_START_TAG.equals(type)) { + setEtDataSingle(mBinding.ilStart.etPoint, mBinding.ilStart.etHeight, + mBinding.ilStart.etB, mBinding.ilStart.etL, pickPointResultStart.getSelectedIds().get(0)); + } else if (SELECT_END_TAG.equals(type)) { + setEtDataSingle(mBinding.ilEnd.etPoint, mBinding.ilEnd.etHeight, + mBinding.ilEnd.etB, mBinding.ilEnd.etL, + pickPointResultEnd.getSelectedIds().get(0)); + } + } + + private void setEtDataSingle(MaterialEditText etPointName, MaterialEditText etPointHeight, + MaterialEditText etB, MaterialEditText etL, + String pointId) { + ThreadPoolUtil.execute(() -> { + PointRecord pointRecord = SurveyorDatabaseFactory.instance.getPointDataSource().findByIdSync(pointId); + ThreadPoolUtil.executeInMain(() -> { + etPointName.setText(pointRecord.getName()); + etPointHeight.setText(doubleToString(pointRecord.getZ())); + + if (pointRecord.getLatitude() != 0 && pointRecord.getLongitude() != 0) { + etB.setText(doubleToString(pointRecord.getLatitude())); + etL.setText(doubleToString(pointRecord.getLongitude())); + } else { + etB.setText(""); + etL.setText(""); + } + }); + }); + } + + private boolean isListEmpty(List list) { + return list == null || list.isEmpty(); + } + + private MaterialEditText getEtPoint(@IdRes int id) { + View view = getView(); + assert view != null; + return view.findViewById(id); + } + + @Override + public void onStart() { + super.onStart(); +// getDialog().getWindow().setBackgroundDrawable(new ColorDrawable(0x33000000)); + getDialog().getWindow().setLayout( + WindowManager.LayoutParams.MATCH_PARENT, + WindowManager.LayoutParams.MATCH_PARENT); + } + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getLocationUtil = new GetLocationUtil(); + getLifecycle().addObserver(getLocationUtil); + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + mBinding = DialogCreateRouteBinding.inflate(inflater, container, false); + initView(); + initListener(); + initData(); + return mBinding.getRoot(); + } + + private void initView() { + mBinding.ilStart.llCoord.setVisibility(View.VISIBLE); + mBinding.ilEnd.llCoord.setVisibility(View.VISIBLE); + } + + + @Override + public void onDestroyView() { + super.onDestroyView(); + mBinding = null; + } + + private void initData() { + String routeId = getRouteId(); + if (routeId != null) { + ThreadPoolUtil.execute(() -> { + RouteRecord routeRecord = SurveyorDatabaseFactory.instance.getRouteDataSource().getByIdSync(routeId); + if (routeRecord != null) { + PointRecord startPointRecord = SurveyorDatabaseFactory.instance.getPointDataSource().findByIdSync(routeRecord.getStartPointId()); + PointRecord endPointRecord = SurveyorDatabaseFactory.instance.getPointDataSource().findByIdSync(routeRecord.getEndPointId()); + setPickPointResultForEdit(SELECT_START_TAG, startPointRecord.getId(), startPointRecord.getName()); + setPickPointResultForEdit(SELECT_END_TAG, endPointRecord.getId(), endPointRecord.getName()); + + ThreadPoolUtil.executeInMain(() -> { + setEtData(SELECT_START_TAG); + setEtData(SELECT_END_TAG); + }); + } + }); + } + } + + private void setPickPointResultForEdit(String type, String id, String name) { + if (type.equals(SELECT_START_TAG)) { + pickPointResultStart = getPickPointResultFromIdName(id, name); + } else { + pickPointResultEnd = getPickPointResultFromIdName(id, name); + } + } + + private PickPointResult getPickPointResultFromIdName(String id, String name) { + List ids = new ArrayList<>(); + List names = new ArrayList<>(); + ids.add(id); + names.add(name); + PickPointResult pickPointResult = new PickPointResult(); + pickPointResult.setSelectedIds(ids); + pickPointResult.setSelectedNames(names); + return pickPointResult; + } + + private void initListener() { + mBinding.tvSelectStartPoint.setOnClickListener(v -> selectPoint(SELECT_START_TAG)); + mBinding.tvSelectEndPoint.setOnClickListener(v -> selectPoint(SELECT_END_TAG)); + + mBinding.btnCancel.setOnClickListener((v) -> dismissAllowingStateLoss()); + + mBinding.btnConfirm.setOnClickListener((v) -> { + checkConfirm(); + }); + + mBinding.ivGetLocationStartPoint.setOnClickListener(v -> { + getLocation(result -> { + setLocation(mBinding.ilStart.etB, mBinding.ilStart.etL, result); + }); + }); + mBinding.ivGetLocationEndPoint.setOnClickListener(v -> { + getLocation(result -> { + setLocation(mBinding.ilEnd.etB, mBinding.ilEnd.etL, result); + }); + }); + } + + private void getLocation(GetLocationUtil.IResultListener resultListener) { + CheckLocationUtil.check(requireContext(), () -> { + getLocationUtil.getResult(resultListener); + }); + } + + private void setLocation(MaterialEditText etB, MaterialEditText etL, GetLocationUtil.Result result) { + if (result != null) { + etB.setText(result.getLatitude()); + etL.setText(result.getLongitude()); + } + } + + private void checkConfirm() { + ThreadPoolUtil.execute(() -> { + + String startPointName = mBinding.ilStart.etPoint.getText().toString().trim(); + if (TextUtils.isEmpty(startPointName)) { + ToastUtils.showShort(R.string.please_enter_or_select_a_starting_point); + return; + } + + String endPointName = mBinding.ilEnd.etPoint.getText().toString().trim(); + if (TextUtils.isEmpty(endPointName)) { + ToastUtils.showShort(R.string.please_enter_or_select_a_destination); + return; + } + + //取消起点终点重复的限制 +// if (startPointName.equals(endPointName)) { +// ToastUtils.showShort(R.string.duplicate_start_and_end_names); +// return; +// } + + boolean canEdit = checkCanEdit(); + if (!canEdit) { + ToastUtils.showShort(R.string.route_has_data_not_edit_hint); + return; + } + + String startHeight = mBinding.ilStart.etHeight.getText().toString().trim(); + String startB = mBinding.ilStart.etB.getText().toString().trim(); + String startL = mBinding.ilStart.etL.getText().toString().trim(); + String endHeight = mBinding.ilEnd.etHeight.getText().toString().trim(); + String endB = mBinding.ilEnd.etB.getText().toString().trim(); + String endL = mBinding.ilEnd.etL.getText().toString().trim(); + + PointRecord startPoint; + PointRecord endPoint; + + String projectId = getProjectId(); + startPoint = SurveyorDatabaseFactory.instance.getPointDataSource().findByNameSync(startPointName, projectId); + endPoint = SurveyorDatabaseFactory.instance.getPointDataSource().findByNameSync(endPointName, projectId); + + if (startPoint == null) { + startPoint = createPoint(startPointName, startHeight, startB, startL); + } else { + editPoint(startPoint, startPointName, startHeight, startB, startL); + } + + if (endPoint == null) { + endPoint = createPoint(endPointName, endHeight, endB, endL); + } else { + editPoint(endPoint, endPointName, endHeight, endB, endL); + } + + //存数据库 + SurveyorDatabaseFactory.instance.getPointDataSource().saveSync(startPoint); + SurveyorDatabaseFactory.instance.getPointDataSource().saveSync(endPoint); + + setResultToPage(startPoint.getId(), endPoint.getId(), + startPoint.getName() + "-" + endPoint.getName()); + }); + } + + @WorkerThread + private boolean checkCanEdit() { + //路线有数据时候不能编辑 + String routeId = getRouteId(); + if (routeId == null) { + return true; + } + RouteRecord routeRecord = SurveyorDatabaseFactory.instance.getRouteDataSource().getByIdSync(getRouteId()); + if (routeRecord != null) { + List stationList = SurveyorDatabaseFactory.instance.getSurveyorStation().getByProjectRoute(getProjectId(), getRouteId()); + if (stationList != null && !stationList.isEmpty()) { + for (SurveyorStationRecord stationRecord : stationList) { + long recordCount = SurveyorDatabaseFactory.instance.getSurveyorRecordDataSource().recordCount(stationRecord.getId()); + if (recordCount > 0) { + return false; + } + } + } + } + return true; + } + + @WorkerThread + private PointRecord createPoint(String pointName, String height, String b, String l) { + return createPointRecord(pointName, height, b, l); + } + + @WorkerThread + private void editPoint(PointRecord pointRecord, String pointNameEdit, String height, String b, String l) { + pointRecord.setName(pointNameEdit); + pointRecord.setZ(stringToDouble(height)); + pointRecord.setLatitude(stringToDouble(b)); + pointRecord.setLongitude(stringToDouble(l)); + } + + private void setResultToPage(String startPointId, String endPointId, String routeName) { + if (getActivity() != null) { + getActivity().runOnUiThread(() -> { + Bundle resultBundle = new Bundle(); + resultBundle.putString(KEY_START_POINT_ID, startPointId); + resultBundle.putString(KEY_END_POINT_ID, endPointId); + resultBundle.putString(KEY_ROUTE_NAME, routeName); + getParentFragmentManager() + .setFragmentResult(getTag(), resultBundle); + dismissAllowingStateLoss(); + }); + } + } + + private PointRecord createPointRecord(String pointText, String height, String b, String l) { + String pointType; + if (isKnownPoint(height)) { + pointType = PointRecord.TYPE_KNOWN_POINT; + } else { + pointType = PointRecord.TYPE_UNKNOWN_POINT; + } + double h = stringToDouble(height); + PointRecord point = PointRecord.point(getProjectId(), pointType, pointText, "", 0, 0, h, "", -1); + point.setLatitude(stringToDouble(b)); + point.setLongitude(stringToDouble(l)); + return point; + } + + private boolean isKnownPoint(String height) { + double heightD = stringToDouble(height); + return heightD != 0; + } + + private double stringToDouble(String value) { + if (TextUtils.isEmpty(value)) { + return 0; + } + return Double.parseDouble(value); + } + + private String doubleToString(double value) { + return String.valueOf(value); + } + + private void tipsOnly(String msg) { + if (getActivity() != null) { + getActivity().runOnUiThread(() -> TipsFragment.tipsOnly( + getChildFragmentManager(), + getViewLifecycleOwner(), + requireContext(), + msg)); + } + } + + private void selectPoint(String type) { + String title = null; + PickPointResult pickPointResultSelected = null; + List filderIds = null; + if (SELECT_START_TAG.equals(type)) { + pickPointResultSelected = pickPointResultStart; +// filderIds = pickPointResultEnd != null ? pickPointResultEnd.getSelectedIds() : null; + title = Tools.getString(R.string.choose_starting_point); + } else if (SELECT_END_TAG.equals(type)) { + pickPointResultSelected = pickPointResultEnd; +// filderIds = pickPointResultStart != null ? pickPointResultStart.getSelectedIds() : null; + title = Tools.getString(R.string.select_end_point); + } + PickPointFragment.pickPoint( + getContext(), + type, + 1, + title, + filderIds,//filderIds取消起点和终点的限制 + getProjectId(), pickPointResultSelected, defaultStationLauncher); + } + + public interface CallBack { + void result(String routeName, String startPointId, String endPointId); + } + + private String getProjectId() { + if (getArguments() != null) { + return getArguments().getString(KEY_PROJECT_ID); + } + return null; + } + + private String getRouteId() { + if (getArguments() != null) { + return getArguments().getString(KEY_ROUTE_ID); + } + return null; + } + + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/heighttraverse/adapter/RouteListAdapter.java b/app/src/main/java/com/bingce/controlnetwork/fragment/heighttraverse/adapter/RouteListAdapter.java new file mode 100644 index 0000000..9e883ba --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/heighttraverse/adapter/RouteListAdapter.java @@ -0,0 +1,18 @@ +package com.bingce.controlnetwork.fragment.heighttraverse.adapter; + +import java.util.List; + +import com.bingce.controlnetwork.adapter.BaseIndexTextWithContextMenuAdapter; +import com.bingce.controlnetwork.adapter.contextmenu.ContextMenuDelete; +import com.bingce.controlapphelper.datasource.database.route.RouteRecord; +import com.bingce.controlnetwork.adapter.BaseIndexTextWithContextMenuAdapter; +import com.bingce.controlnetwork.adapter.contextmenu.ContextMenuDelete; + +public class RouteListAdapter extends BaseIndexTextWithContextMenuAdapter { + + public RouteListAdapter(List dataList, IOnItemClick callback + , ContextMenuDelete contextMenuDeleteEdit) { + super(dataList, callback, contextMenuDeleteEdit); + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/heighttraverse/viewmodel/HeightCreateOrEditVm.kt b/app/src/main/java/com/bingce/controlnetwork/fragment/heighttraverse/viewmodel/HeightCreateOrEditVm.kt new file mode 100644 index 0000000..d0fc265 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/heighttraverse/viewmodel/HeightCreateOrEditVm.kt @@ -0,0 +1,62 @@ +package com.bingce.controlnetwork.fragment.heighttraverse.viewmodel + +import androidx.fragment.app.FragmentManager +import androidx.lifecycle.LifecycleOwner +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.bingce.controlnetwork.fragment.heighttraverse.CreateOrEditRouteDialog +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory +import com.bingce.controlapphelper.datasource.database.config.ConfigConstants +import com.bingce.controlapphelper.datasource.database.route.RouteRecord +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch + +class HeightCreateOrEditVm : ViewModel() { + + fun showCreateOrEditDialog( + projectId: String, + routeId: String?, + childFragmentManager: FragmentManager, + viewLifecycleOwner: LifecycleOwner + ) { + CreateOrEditRouteDialog.start( + projectId, routeId, childFragmentManager, viewLifecycleOwner + ) { routeName, startPointId, endPointId -> + saveOrUpdateRecord(projectId, routeName, routeId, startPointId, endPointId) + } + } + + /** + * 存路线的同时存默认项目 + */ + private fun saveOrUpdateRecord( + projectId: String, + routeName: String, + routeId: String?, + startPointId: String, + endPointId: String + ) { + viewModelScope.launch(Dispatchers.IO) { + if (routeId != null) { + val routeRecord = + SurveyorDatabaseFactory.instance.getRouteDataSource().getById(routeId) + routeRecord?.let { + it.routeName = routeName + it.startPointId = startPointId + it.endPointId = endPointId + SurveyorDatabaseFactory.instance.getRouteDataSource().update(it) + } + } else { + val routeRecord = + RouteRecord.createRouteRecord(projectId, routeName, startPointId, endPointId) + SurveyorDatabaseFactory.instance.getRouteDataSource().saveRecord(routeRecord) + //存默认的项目id + SurveyorDatabaseFactory.instance.configDataSource.setSync( + ConfigConstants.KEY_DEFAULT_PROJECT_ID, + projectId + ) + } + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/projectdetail/ProjectDetailFragment.kt b/app/src/main/java/com/bingce/controlnetwork/fragment/projectdetail/ProjectDetailFragment.kt new file mode 100644 index 0000000..622aeea --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/projectdetail/ProjectDetailFragment.kt @@ -0,0 +1,161 @@ +package com.bingce.controlnetwork.fragment.projectdetail + + +import android.content.Context +import android.os.Bundle +import android.view.LayoutInflater +import android.view.Menu +import android.view.MenuInflater +import android.view.MenuItem +import android.view.View +import android.view.ViewGroup +import androidx.annotation.WorkerThread +import androidx.fragment.app.Fragment +import androidx.lifecycle.lifecycleScope +import blankj.utilcode.util.ToastUtils +import com.bingce.controlapphelper.datasource.database.ProjectType +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory +import com.bingce.controlapphelper.event.SwitchPageEvent +import com.bingce.controlapphelper.model.BundleConstants +import com.bingce.controlnetwork.R +import com.bingce.controlnetwork.activity.fragmentcontainer.FragmentContainerActivity +import com.bingce.controlnetwork.databinding.FragmentProjectDetailListLayoutBinding +import com.bingce.controlnetwork.fragment.PointListFragment +import com.bingce.controlnetwork.fragment.ProjectToleranceSettingFragment +import com.bingce.controlnetwork.fragment.base.BaseFragment +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import org.greenrobot.eventbus.EventBus + + +abstract class ProjectDetailFragment : BaseFragment() { + + companion object { + @JvmStatic + fun start(context: Context, projectType: String?, projectId: String, projectName: String?) { + val bundle = Bundle() + bundle.putString(BundleConstants.KEY_PROJECT_ID, projectId) + bundle.putString(BundleConstants.KEY_PROJECT_TYPE, projectType) + val tag = if (projectType == ProjectType.HEIGHT_TRAVERSE.flag) { + ProjectDetailHeightTraverseFragment.TAG + } else { + ProjectDetailTriangleFragment.TAG + } + FragmentContainerActivity.start(context, tag, projectName, bundle) + } + } + + private var _binding: FragmentProjectDetailListLayoutBinding? = null + val mBinding get() = _binding!! + + private val configDataSource = SurveyorDatabaseFactory.instance.configDataSource + + protected val projectId: String by lazy { + requireArguments().getString(BundleConstants.KEY_PROJECT_ID)!! + } + + protected val projectType: String? by lazy { + requireArguments().getString(BundleConstants.KEY_PROJECT_TYPE) + } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + _binding = FragmentProjectDetailListLayoutBinding.inflate(inflater, container, false) + initView() + setHasOptionsMenu(true) + return mBinding.root + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } + + protected abstract fun getContentFragment(): Fragment + + @WorkerThread + protected abstract fun saveDefaultProjectAndSoOn(): String? + + protected abstract fun clickCreateStation() + + private fun initView() { + //设置开始测量 + mBinding.ilBtn.btnOne.text = getString(R.string.new_surveyor_station) + mBinding.ilBtn.btnTwo.text = getString(R.string.start_surveyor) + + childFragmentManager + .beginTransaction() + .replace(R.id.fragment_container, getContentFragment(), "__station_list") + .commit() + //已知点 + initKnownPoint() + //未知点 + initUnKnownPoint() + //去测量页面 + initGoMeasurePage() + //新建测站 + initCreateStation() + } + + private fun initCreateStation() = + mBinding.ilBtn.btnOne.setOnClickListener { v -> clickCreateStation() } + + private fun initGoMeasurePage() { + mBinding.ilBtn.btnTwo.setOnClickListener { view -> + lifecycleScope.launch(Dispatchers.IO) { + val msg = saveDefaultProjectAndSoOn() + if (!msg.isNullOrEmpty()) { + ToastUtils.showShort(msg) + return@launch + } + EventBus.getDefault().post( + SwitchPageEvent( + SwitchPageEvent.TYPE_SWITCH_TO_MEASURE_PAGE_AND_DATA, + null + ) + ) + val activity = activity + activity?.finish() + } + } + } + + private fun initUnKnownPoint() { + mBinding.unknownPointList.setOnClickListener { view -> + PointListFragment.go2UnknownPointList( + projectId, + projectType, + context + ) + } + } + + private fun initKnownPoint() { + mBinding.knownPointList.setOnClickListener { view -> + PointListFragment.go2KnownPointList( + projectId, + projectType, + context + ) + } + } + + override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { + inflater.inflate(R.menu.project_detail_fragment_menu, menu) + super.onCreateOptionsMenu(menu, inflater) + } + + override fun onOptionsItemSelected(item: MenuItem): Boolean { + if (item.itemId == R.id.project_parameter_setting) { + //设置参数点击事件 + ProjectToleranceSettingFragment.start(context, projectId, projectType) + return true + } + return super.onOptionsItemSelected(item) + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/projectdetail/ProjectDetailHeightTraverseFragment.kt b/app/src/main/java/com/bingce/controlnetwork/fragment/projectdetail/ProjectDetailHeightTraverseFragment.kt new file mode 100644 index 0000000..d427cc1 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/projectdetail/ProjectDetailHeightTraverseFragment.kt @@ -0,0 +1,71 @@ +package com.bingce.controlnetwork.fragment.projectdetail + +import android.os.Bundle +import android.view.View +import androidx.fragment.app.Fragment +import androidx.fragment.app.viewModels +import com.bingce.controlapphelper.datasource.database.SurveyorDataBase +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory +import com.bingce.controlapphelper.datasource.database.config.ConfigConstants +import com.bingce.controlapphelper.util.Tools +import com.bingce.controlnetwork.R +import com.bingce.controlnetwork.fragment.heighttraverse.viewmodel.HeightCreateOrEditVm +import com.bingce.controlnetwork.fragment.projectdetail.content.RouteFragment + +class ProjectDetailHeightTraverseFragment : ProjectDetailFragment() { + + private lateinit var routeFragment: RouteFragment + + private val heightCreateOrEditVm: HeightCreateOrEditVm by viewModels() + + companion object { + @JvmField + val TAG = ProjectDetailHeightTraverseFragment::class.simpleName + + @JvmStatic + fun newInstance(bundle: Bundle): ProjectDetailHeightTraverseFragment { + val fragment = ProjectDetailHeightTraverseFragment() + fragment.arguments = bundle + return fragment + } + } + + override fun getContentFragment(): Fragment { + routeFragment = RouteFragment.newInstance(projectId) + return routeFragment + } + + override fun saveDefaultProjectAndSoOn(): String? { + val routeId = + routeFragment.getSurveyorRouteId() ?: return Tools.getString(R.string.no_route_yet) + SurveyorDataBase.getInstance().runInTransaction { + SurveyorDatabaseFactory.instance.configDataSource.setSync( + ConfigConstants.KEY_DEFAULT_PROJECT_ID, + projectId + ) + + SurveyorDatabaseFactory.instance.configDataSource.setSync( + ConfigConstants.KEY_DEFAULT_ROUTE_ID, + routeId + ) + } + return null + } + + override fun clickCreateStation() { + heightCreateOrEditVm.showCreateOrEditDialog( + projectId, + routeId = null, + childFragmentManager, + viewLifecycleOwner + ) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + mBinding.tvCycleTitle.text = getString(R.string.route) + mBinding.ilBtn.btnOne.text = getString(R.string.create_new_route) + mBinding.ivCycleArrow.visibility = View.GONE + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/projectdetail/ProjectDetailTriangleFragment.kt b/app/src/main/java/com/bingce/controlnetwork/fragment/projectdetail/ProjectDetailTriangleFragment.kt new file mode 100644 index 0000000..594d640 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/projectdetail/ProjectDetailTriangleFragment.kt @@ -0,0 +1,197 @@ +package com.bingce.controlnetwork.fragment.projectdetail + +import android.os.Bundle +import android.view.View +import androidx.fragment.app.Fragment +import androidx.fragment.app.viewModels +import com.bingce.controlapphelper.datasource.database.SurveyorDataBase +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory +import com.bingce.controlapphelper.datasource.database.config.ConfigConstants +import com.bingce.controlapphelper.datasource.database.surveyorcycle.SurveyorPeriodRecord +import com.bingce.controlnetwork.fragment.BottomSheetSurveyorPeriodFragment +import com.bingce.controlnetwork.fragment.SelectSurveyorStationTypeFragment +import com.bingce.controlnetwork.fragment.SelectSurveyorStationTypeWellSubFragment +import com.bingce.controlnetwork.fragment.station.defaultstation.DefaultStationSetupFragment +import com.bingce.controlnetwork.fragment.station.line.attached.LineStationAttachedSetupFragment +import com.bingce.controlnetwork.fragment.station.line.close.LineStationCloseSetupFragment +import com.bingce.controlnetwork.fragment.station.line.random.LineStationRandomSetupFragment +import com.bingce.controlnetwork.fragment.station.line.single.LineStationSingleSetupFragment +import com.bingce.controlnetwork.fragment.station.line.well.LineStationWellDoubleGroundSetupFragment +import com.bingce.controlnetwork.fragment.station.line.well.LineStationWellDoubleUnderGroundSetupFragment +import com.bingce.controlnetwork.fragment.station.line.well.LineStationWellSetupFragment +import com.bingce.controlnetwork.newui.stationlist.StationListFragment +import com.bingce.controlnetwork.newui.stationlist.StationListVm + +class ProjectDetailTriangleFragment : ProjectDetailFragment() { + + private var currentPeriodId: String = "" + + private var contentFragment: StationListFragment? = null + + private val stationListVm by viewModels() + + companion object { + @JvmField + val TAG = ProjectDetailTriangleFragment::class.simpleName + + @JvmStatic + fun newInstance(bundle: Bundle): ProjectDetailTriangleFragment { + val fragment = ProjectDetailTriangleFragment() + fragment.arguments = bundle + return fragment + } + + } + + override fun getContentFragment(): Fragment { + //测站列表 + contentFragment = StationListFragment() + return contentFragment!! + } + + override fun saveDefaultProjectAndSoOn(): String? { + SurveyorDataBase.getInstance().runInTransaction { + SurveyorDatabaseFactory.instance.configDataSource.setSync( + ConfigConstants.KEY_DEFAULT_PROJECT_ID, + projectId + ) + SurveyorDatabaseFactory.instance.configDataSource.setSync( + ConfigConstants.KEY_DEFAULT_PERIOD_ID, + currentPeriodId + ) + } + return null + } + + override fun clickCreateStation() { + SelectSurveyorStationTypeFragment + .select( + childFragmentManager, + viewLifecycleOwner, + projectType + ) { type: String -> + if (SelectSurveyorStationTypeFragment.TYPE_DEFAULT == type) { + DefaultStationSetupFragment.start(context, projectId, currentPeriodId) + } else if (SelectSurveyorStationTypeFragment.TYPE_LINE_SINGLE == type) { + //支导线 + LineStationSingleSetupFragment.startCreate( + context, + projectId, + currentPeriodId + ) + } else if (SelectSurveyorStationTypeFragment.TYPE_LINE_ATTACH == type) { + //附合导线 + LineStationAttachedSetupFragment.startCreate( + context, + projectId, + currentPeriodId + ) + } else if (SelectSurveyorStationTypeFragment.TYPE_LINE_CLOSE == type) { + LineStationCloseSetupFragment.startCreateCloseLine( + context, + projectId, + currentPeriodId + ) + } else if (SelectSurveyorStationTypeFragment.TYPE_LINE_RANDOM == type) { + LineStationRandomSetupFragment.startCreate( + context, + projectId, + currentPeriodId + ) + } else if (SelectSurveyorStationTypeFragment.TYPE_WELL_WIRE == type) { + //一井定向 + LineStationWellSetupFragment.startCreate( + context, + projectId, + currentPeriodId + ) + } else if (SelectSurveyorStationTypeFragment.TYPE_WELL_WIRE_DOUBLE == type) { + //二井定向 + selectWellDoubleType() + } + } + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + stationListVm.isCanEditDelete = true + initListener() + initData() + } + + private fun initListener() { + initSwithCycle() + } + + private fun initSwithCycle() { + mBinding.cycleLayout.setOnClickListener { + //切换测期 + BottomSheetSurveyorPeriodFragment.pick( + childFragmentManager, + viewLifecycleOwner, + projectId, + currentPeriodId + ) { id: String, name: String -> + setCreatedData { + currentPeriodId = id + mBinding.orderText.text = name + updateStationList(projectId, currentPeriodId) + } + } + } + } + + private fun initData() { + //获取默认测期,刷新页面 + SurveyorDatabaseFactory.instance + .surveyorPeriod + .getDefault( + projectId + ) { instance: SurveyorPeriodRecord -> + setCreatedData { + currentPeriodId = instance.value + runOnUI { + //设置测期名称 + mBinding.orderText.text = instance.name + //设置测站列表 + updateStationList(projectId, instance.id) + } + } + } + } + + private fun updateStationList(projectId: String, periodId: String) { + if (contentFragment == null) { + return + } + stationListVm.setArgument(projectId, periodId) + contentFragment!!.refreshUi() + } + + /** + * 选择二井定向地上还是地下的弹框 + */ + private fun selectWellDoubleType() { + SelectSurveyorStationTypeWellSubFragment + .select( + childFragmentManager, + viewLifecycleOwner + ) { type: String -> + if (SelectSurveyorStationTypeWellSubFragment.TYPE_GROUND == type) { + LineStationWellDoubleGroundSetupFragment.startCreate( + context, + projectId, + currentPeriodId + ) + } else if (SelectSurveyorStationTypeWellSubFragment.TYPE_UNDERGROUND == type) { + LineStationWellDoubleUnderGroundSetupFragment.startCreate( + context, + projectId, + currentPeriodId + ) + } + } + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/projectdetail/content/RouteFragment.kt b/app/src/main/java/com/bingce/controlnetwork/fragment/projectdetail/content/RouteFragment.kt new file mode 100644 index 0000000..5fcd3db --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/projectdetail/content/RouteFragment.kt @@ -0,0 +1,185 @@ +package com.bingce.controlnetwork.fragment.projectdetail.content + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.viewModels +import androidx.lifecycle.lifecycleScope +import androidx.room.withTransaction +import com.bingce.controlnetwork.adapter.contextmenu.ContextMenuDelete +import com.bingce.controlnetwork.fragment.TipsFragment +import com.bingce.controlnetwork.fragment.base.BaseFragment +import com.bingce.controlnetwork.fragment.heighttraverse.adapter.RouteListAdapter +import com.bingce.controlnetwork.fragment.heighttraverse.viewmodel.HeightCreateOrEditVm +import com.bingce.controlapphelper.datasource.database.SurveyorDataBase +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory +import com.bingce.controlapphelper.datasource.database.route.RouteRecord +import com.bingce.controlapphelper.model.BundleConstants +import com.bingce.controlapphelper.util.PointUtil +import com.bingce.controlnetwork.R +import com.bingce.controlnetwork.databinding.FragmentListLayoutBinding +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + +class RouteFragment : BaseFragment() { + + private val heightCreateOrEditVm: HeightCreateOrEditVm by viewModels() + + private var _binding: FragmentListLayoutBinding? = null + val mBinding get() = _binding!! + + private val dataList = mutableListOf() + + val adapter: RouteListAdapter by lazy { + RouteListAdapter(dataList, + { + //路线item点击 + doLookAndEditRoute(it) + }, + object : ContextMenuDelete() { + override fun delete(item: RouteRecord) { + doDelete(item) + } + }) + } + + private fun doLookAndEditRoute(item: RouteRecord) { + heightCreateOrEditVm.showCreateOrEditDialog( + getProjectId()!!, + routeId = item.getId(), + childFragmentManager, + viewLifecycleOwner + ) + } + + private fun doDelete(item: RouteRecord) { + lifecycleScope.launch(Dispatchers.IO) { + + val stationList = SurveyorDatabaseFactory.instance.surveyorStation.getByProjectRoute( + item.projectId, + item.getId() + ) + + var hasData = false + for (stationItem in stationList) { + val recordCount = + SurveyorDatabaseFactory.instance.surveyorRecordDataSource.recordCount( + stationItem.getId() + ) + if (recordCount > 0) { + hasData = true + break + } + } + + if (hasData) { + withContext(Dispatchers.Main) { + TipsFragment.cancelAbleTips( + childFragmentManager, viewLifecycleOwner, context, + getString(R.string.tips_is_sure_to_delete_route_with_record), + 4 + ) { + deleteDatabase(item) + } + } + } else { + deleteDatabase(item) + } + } + } + + private fun deleteDatabase(routeRecord: RouteRecord) { + lifecycleScope.launch(Dispatchers.IO) { + SurveyorDataBase.getInstance().withTransaction { + val stationList = + SurveyorDatabaseFactory.instance.surveyorStation.getByProjectRoute( + routeRecord.projectId, + routeRecord.getId() + ) + + //删除路线 + SurveyorDatabaseFactory.instance.getRouteDataSource().delete(routeRecord) + //删除测站 + SurveyorDatabaseFactory.instance.surveyorStation.deleteByRouteId(routeRecord.getId()) + + if (PointUtil.isCanDeleteHeightTraverseAutoCreatePoint(routeRecord.startPointId)) { + SurveyorDatabaseFactory.instance.pointDataSource.deleteById(routeRecord.startPointId) + } + + if (PointUtil.isCanDeleteHeightTraverseAutoCreatePoint(routeRecord.endPointId)) { + SurveyorDatabaseFactory.instance.pointDataSource.deleteById(routeRecord.endPointId) + } + + for (stationItem in stationList) { + if (stationItem.items != null) { + for (surveyorPoint in stationItem.items) { + if (PointUtil.isCanDeleteHeightTraverseAutoCreatePoint(surveyorPoint.originalPointId)) { + //删除点 + SurveyorDatabaseFactory.instance.pointDataSource.deleteById( + surveyorPoint.originalPointId + ) + } + + } + } + } + + } + } + } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + _binding = FragmentListLayoutBinding.inflate(inflater, container, false) + return mBinding.root + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + mBinding.list.adapter = adapter + + getProjectId()?.let { it -> + SurveyorDatabaseFactory.instance.getRouteDataSource().getListLiveData(it) + .observe(viewLifecycleOwner) { + adapter.updateData(it) + } + } + } + + + fun getProjectId() = arguments?.getString(BundleConstants.KEY_PROJECT_ID) + + + companion object { + fun newInstance(projectId: String): RouteFragment { + val bundle = Bundle() + bundle.putString(BundleConstants.KEY_PROJECT_ID, projectId) + val routeFragment = RouteFragment() + routeFragment.arguments = bundle + return routeFragment + } + } + + /** + * 获取即将要测量的路线id + */ + fun getSurveyorRouteId(): String? { + if (dataList.isNotEmpty()) { + return dataList.last().getId() + } + return null + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/projectedit/AbstractProjectEditFragment.kt b/app/src/main/java/com/bingce/controlnetwork/fragment/projectedit/AbstractProjectEditFragment.kt new file mode 100644 index 0000000..12685c4 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/projectedit/AbstractProjectEditFragment.kt @@ -0,0 +1,310 @@ +package com.bingce.controlnetwork.fragment.projectedit + +import android.content.Context +import android.content.Intent +import android.os.Bundle +import android.text.TextUtils +import android.view.View +import androidx.activity.result.ActivityResultLauncher +import androidx.fragment.app.DialogFragment +import androidx.fragment.app.Fragment +import androidx.fragment.app.FragmentManager +import androidx.room.withTransaction +import blankj.utilcode.util.ToastUtils +import com.bingce.controlapphelper.datasource.database.ProjectType +import com.bingce.controlapphelper.datasource.database.SurveyorDataBase +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory +import com.bingce.controlapphelper.datasource.database.config.ConfigConstants +import com.bingce.controlapphelper.datasource.database.project.ProjectRecord +import com.bingce.controlapphelper.datasource.database.surveyorcycle.SurveyorPeriodRecord +import com.bingce.controlapphelper.datasource.database.tolerance.load.ToleranceLoadUtil +import com.bingce.controlnetwork.R +import com.bingce.controlnetwork.fragment.AbstractFullScreenDialogFragment +import com.bingce.controlnetwork.fragment.ToleranceSelectFragment +import com.bingce.controlnetwork.ui.widget.dialog.LoadingUtilKt +import com.bingce.controlnetwork.util.DefaultNameUtil +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.MainScope +import kotlinx.coroutines.cancel +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + +abstract class AbstractProjectEditFragment : AbstractFullScreenDialogFragment() { + companion object { + + const val KEY_PROJECT_ID = "___project__id" + const val KEY_PROJECT_TYPE = "___project__type" + const val KEY_PROJECT_NAME = "___project___name___" + const val KEY_TOLERANCE_ID = "___tolerance_id" + + @JvmStatic + fun editProject( + fragmentManager: FragmentManager, + context: Context, + projectId: String, projectType: String?, toleranceId: String?, projectName: String? + ) { + newInstance( + context, projectId, projectType, + toleranceId, projectName + ).show(fragmentManager, "_edit_project_fragment") + } + + @JvmStatic + fun createProject( + fragmentManager: FragmentManager, + context: Context, + projectType: String? + ) { + newInstance(context, null, projectType, null, null) + .show(fragmentManager, "__create_project_fragment__") + } + + private fun newInstance( + context: Context, projectId: String?, projectType: String?, + toleranceId: String?, projectName: String? + ): DialogFragment { + val fragment = + if (projectType == ProjectType.HEIGHT_TRAVERSE.flag) ProjectEditHeightTraverseFragment() + else ProjectEditTriangleFragment() + + val args = Bundle() + if (projectId.isNullOrEmpty()) { + setArgs(args, context.getString(R.string.title_create_new_project), null) + args.putString(KEY_PROJECT_TYPE, projectType) + } else { + setArgs(args, context.getString(R.string.title_edit_project), null) + args.putString(KEY_PROJECT_ID, projectId) + args.putString(KEY_PROJECT_TYPE, projectType) + args.putString(KEY_TOLERANCE_ID, toleranceId) + args.putString(KEY_PROJECT_NAME, projectName) + } + fragment.arguments = args + return fragment + } + + } + + + protected val scope = MainScope() + + private lateinit var selectedToleranceId: String + + private lateinit var selectToleranceLauncher: ActivityResultLauncher + + + protected fun initSelectToleranceLauncher(fragment: Fragment) { + selectToleranceLauncher = ToleranceSelectFragment.createActivityLauncher( + fragment + ) { + updateToleranceData(it) + } + } + + + fun getProjectId() = arguments?.getString(KEY_PROJECT_ID) + fun getProjectType() = arguments?.getString(KEY_PROJECT_TYPE) + fun getProjectName() = arguments?.getString(KEY_PROJECT_NAME) + fun getToleranceId() = arguments?.getString(KEY_TOLERANCE_ID) + + override fun onDestroyView() { + super.onDestroyView() + scope.cancel() + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + initView() + initData() + } + + protected open fun initView() { + getToleranceBtn().setOnClickListener { + selectTolerance() + } + } + + protected abstract fun getCurrentProjectName(): String + abstract fun getShowSlopSwitch(): Boolean + abstract fun setToleranceName(name: String) + abstract fun setProjectName(name: String) + abstract fun setShowSlopSwitch(isChecked: Boolean) + abstract fun getToleranceBtn(): View + + //存其他的数据,如果是高程导线存自己的配置信息,没有自己的数据就空实现即可 + abstract suspend fun saveOtherRecord(projectId: String) + + + private fun updateToleranceData(toleranceId: String?) { + toleranceId?.let { + scope.launch { + val toleranceDetailRecord = withContext(Dispatchers.IO) { + SurveyorDatabaseFactory.instance + .toleranceDetailDataSource + .getRecordSync(toleranceId) + } + toleranceDetailRecord?.let { + val tjToleranceLoad = ToleranceLoadUtil.getTriangleToleranceLoad() + val groupRecord = tjToleranceLoad.groupOf(it.groupId) + val levelRecord = tjToleranceLoad.levelOf(it.levelId) + + val lineName = if (levelRecord?.name == null) "" else "-${levelRecord.name}" + + setToleranceName("${groupRecord?.name ?: ""}${lineName}-${it.name}") + + selectedToleranceId = toleranceId + } + } + } + } + + protected open fun initData() { + initToleranceData() + //设置项目名称 + setProjectName(getProjectName() ?: "")//DefaultNameUtil.getDefaultProjectName() + updateShowSlopData(getProjectId()) + } + + /** + * 初始化限差数据 + */ + private fun initToleranceData() { + val projectType = getProjectType() + + val newDefaultTolerance = ToleranceLoadUtil.getTriangleToleranceLoad().getNewDefaultTolerance(projectType) + val toleranceId = + getToleranceId() ?: newDefaultTolerance?.id + updateToleranceData(toleranceId) + } + + private fun updateShowSlopData(projectId: String?) { + if (projectId == null) { + val checked = when (getProjectType()) { + ProjectType.TRIANGLE.flag -> true + ProjectType.CONNECTION.flag -> false + else -> true + } + setShowSlopSwitch(checked) + } else { + scope.launch { + val projectRecord = withContext(Dispatchers.IO) { + SurveyorDatabaseFactory.instance + .projectDataSource + .getRecord(projectId) + } + projectRecord?.let { + setShowSlopSwitch(it.isShowSlopDistance) + } + } + } + } + + private fun selectTolerance() { + //选择限差 + ToleranceSelectFragment.start( + context, + getToleranceId(), + getProjectType(), + selectToleranceLauncher + ) + } + + private fun checkBase(): Boolean { + val projectName = getCurrentProjectName() + if (TextUtils.isEmpty(projectName)) { + ToastUtils.showShort(R.string.tips_need_select_input_project_name) + return false + } + + if (!::selectedToleranceId.isInitialized || TextUtils.isEmpty(selectedToleranceId)) { + ToastUtils.showShort(R.string.tips_need_select_project_tolerance) + return false + } + return true + } + + override fun onConfirm() { + if (!checkBase()) return + saveRecord() + } + + private fun saveRecord() { + scope.launch { + LoadingUtilKt.show(requireContext(), null) + + //开始事务 + SurveyorDataBase.getInstance().withTransaction { + if (isEdit()) { + savaRecordEdit(getCurrentProjectName(), getShowSlopSwitch()) + } else { + val projectRecord = ProjectRecord(getCurrentProjectName()) + projectRecord.projectType = getProjectType() + projectRecord.setToleranceId(selectedToleranceId) + projectRecord.isShowSlopDistance = getShowSlopSwitch() + savaRecordNew(projectRecord) + } + } + + LoadingUtilKt.dismiss() + + super.onConfirm() + } + } + + private suspend fun savaRecordNew(projectRecord: ProjectRecord) { + //存储 + SurveyorDatabaseFactory.instance + .projectDataSource + .saveRecordSync(projectRecord) + + if (ProjectType.HEIGHT_TRAVERSE.flag != projectRecord.getProjectType()) { + //非高程导线 + //创建默认测期 + val surveyorPeriodRecord = + SurveyorPeriodRecord(projectRecord.getId(), DefaultNameUtil.getDefaultPeriodName()) + SurveyorDatabaseFactory.instance + .surveyorPeriod + .saveRecordSync(surveyorPeriodRecord) + + //创建新项目的时候存默认的测期 + SurveyorDatabaseFactory.instance.configDataSource.setSync( + ConfigConstants.KEY_DEFAULT_PERIOD_ID, + surveyorPeriodRecord.getId() + ) + } else { + //创建高程导线时候清空默认路线 + SurveyorDatabaseFactory.instance.configDataSource.setSync( + ConfigConstants.KEY_DEFAULT_ROUTE_ID, + null + ) + } + + //创建新项目的时候存默认的项目,无论是否是高程导线 + SurveyorDatabaseFactory.instance.configDataSource.setSync( + ConfigConstants.KEY_DEFAULT_PROJECT_ID, + projectRecord.getId() + ) + + saveOtherRecord(projectRecord.getId()) + } + + private suspend fun savaRecordEdit(currentProjectName: String, showSlopSwitch: Boolean) { + val projectRecord = SurveyorDatabaseFactory.instance + .projectDataSource + .getRecord(getProjectId()) + + projectRecord.setProjectName(currentProjectName) + projectRecord.setToleranceId(selectedToleranceId) + projectRecord.isShowSlopDistance = showSlopSwitch + + //存储 + SurveyorDatabaseFactory.instance + .projectDataSource + .saveRecordSync(projectRecord) + + saveOtherRecord(getProjectId()!!) + } + + protected fun isEdit() = getProjectId() != null + + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/projectedit/ProjectEditHeightTraverseFragment.kt b/app/src/main/java/com/bingce/controlnetwork/fragment/projectedit/ProjectEditHeightTraverseFragment.kt new file mode 100644 index 0000000..65e7ad3 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/projectedit/ProjectEditHeightTraverseFragment.kt @@ -0,0 +1,239 @@ +package com.bingce.controlnetwork.fragment.projectedit + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ArrayAdapter +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory +import com.bingce.controlapphelper.datasource.database.heighttraverse.config.model.EveryWay +import com.bingce.controlapphelper.datasource.database.heighttraverse.config.model.HeighTraverseConfigRecord +import com.bingce.controlapphelper.datasource.database.heighttraverse.config.model.SeparateWay +import com.bingce.controlapphelper.datasource.database.heighttraverse.config.model.StationLayout +import com.bingce.controlnetwork.R +import com.bingce.controlnetwork.databinding.FragmentProjectEditHeightTraverseBinding +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + +/** + * 高程导线新建编辑 + */ +class ProjectEditHeightTraverseFragment : AbstractProjectEditFragment() { + + private val stationLayoutList = listOf( + "隔点设站,设站一次", + "隔点设站,设站两次", + "每点设站,单向观测", + "每点设站,对向观测", + ) + + companion object { +// const val POSITION_SEPARATION = 0//隔点设站的index + + const val POSITION_SEPARATE_SET_UP_ONCE = 0 + const val POSITION_SEPARATE_SET_UP_TWICE = 1 + const val POSITION_EVERY_SINGLE_MEASURE = 2 + const val POSITION_EVERY_OPPOSITE_MEASURE = 3 + } + + init { + initSelectToleranceLauncher(this) + } + + private var _binding: FragmentProjectEditHeightTraverseBinding? = null + private val mBinding get() = _binding!! + + override fun createContentView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + _binding = FragmentProjectEditHeightTraverseBinding.inflate(inflater, container, false) + return mBinding.root + } + + override fun initView() { + super.initView() + + mBinding.spinner.setAdapter( + ArrayAdapter( + requireContext(), + R.layout.item_spinner_text, + stationLayoutList + ) + ) +// mBinding.dtlStationMode.observeIndexChange { fromIndex, toIndex, reselect, fromUser -> +// if (toIndex == POSITION_SEPARATION) { +// //隔点设站 +// mBinding.everyMeasureModeParent.visibility = View.GONE +// mBinding.separationMeasureModeParent.visibility = View.VISIBLE +// } else { +// //每点设站 +// mBinding.everyMeasureModeParent.visibility = View.VISIBLE +// mBinding.separationMeasureModeParent.visibility = View.GONE +// } +// } + } + + override fun initData() { + super.initData() + getProjectId()?.let { + scope.launch { + setEditClickEnable(it) + setStationLayoutData(it) + } + } + } + + /** + *设置布局方式数据 + */ + private suspend fun setStationLayoutData(projectId: String) { + val record = withContext(Dispatchers.IO) { + getRecord(projectId) + } + record?.let { + val stationLayoutSpinnerPos = if (it.stationLayout == StationLayout.SEPARATE) { + if (it.separateWay == SeparateWay.SET_UP_ONCE) { + POSITION_SEPARATE_SET_UP_ONCE + } else { + POSITION_SEPARATE_SET_UP_TWICE + } + } else { + if (it.everyWay == EveryWay.SINGLE_MEASURE) { + POSITION_EVERY_SINGLE_MEASURE + } else { + POSITION_EVERY_OPPOSITE_MEASURE + } + } + mBinding.spinner.setSelection(stationLayoutSpinnerPos) +// mBinding.dtlStationMode.onPageSelected(it.stationLayout.ordinal) +// it.separateWay?.ordinal?.let { +// mBinding.dtlSeparationMeasureMode.onPageSelected(it) +// } +// it.everyWay?.ordinal?.let { +// mBinding.dtlEveryMeasureMode.onPageSelected(it) +// } + } + } + + /** + * 当项目中新建测站了就不能编辑了布置方式了 + */ + private suspend fun setEditClickEnable(projectId: String) { + withContext(Dispatchers.IO) { + val countByProjectId = + SurveyorDatabaseFactory.instance.surveyorStation.getCountByProjectId(projectId) + + if (countByProjectId != 0) { +// mBinding.dtlStationMode.itemEnableSelector = false +// mBinding.dtlSeparationMeasureMode.itemEnableSelector = false +// mBinding.dtlEveryMeasureMode.itemEnableSelector = false + mBinding.spinner.isEnabled = false + } + } + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } + + + override fun getCurrentProjectName(): String { + return mBinding.il.editor.text.toString().trim() + } + + override fun setToleranceName(name: String) { + mBinding.il.selectTolerance.text = name + } + + override fun setProjectName(name: String) { + mBinding.il.editor.setText(name) + } + + override fun setShowSlopSwitch(isChecked: Boolean) { + mBinding.il.showSlopSwitch.isChecked = isChecked + } + + override fun getToleranceBtn(): View { + return mBinding.il.selectTolerance + } + + override suspend fun saveOtherRecord(projectId: String) { + var record = getRecord(projectId) + if (record == null) { + record = HeighTraverseConfigRecord.newInstance( + projectId, getStationLayout(), + getSeparateWay(), + getEveryWay() + ) + } else { + record.stationLayout = getStationLayout() + record.separateWay = getSeparateWay() + record.everyWay = getEveryWay() + } + SurveyorDatabaseFactory.instance.getHeightTraverseConfigDataSource().saveRecord(record) + } + + private suspend fun getRecord(projectId: String): HeighTraverseConfigRecord? { + val heightTraverseConfigDataSource = + SurveyorDatabaseFactory.instance.getHeightTraverseConfigDataSource() + return heightTraverseConfigDataSource.getRecordByProjectId(projectId) + } + +// private fun getStationLayout() = when (mBinding.dtlStationMode.currentItemIndex) { +// POSITION_SEPARATION -> { +// StationLayout.SEPARATE +// } +// +// else -> StationLayout.EVERY +// } +// +// private fun getSeparateWay() = getSeparateOrEveryWay(mBinding.dtlSeparationMeasureMode) { +// SeparateWay.values()[it] +// } +// +// private fun getEveryWay() = getSeparateOrEveryWay(mBinding.dtlEveryMeasureMode) { +// EveryWay.values()[it] +// } + + private fun getStationLayout() = when (mBinding.spinner.selectedItemPosition) { + POSITION_SEPARATE_SET_UP_ONCE, POSITION_SEPARATE_SET_UP_TWICE -> { + StationLayout.SEPARATE + } + + else -> StationLayout.EVERY + } + + private fun getSeparateWay() = when (mBinding.spinner.selectedItemPosition) { + POSITION_SEPARATE_SET_UP_ONCE -> { + SeparateWay.SET_UP_ONCE + } + + POSITION_SEPARATE_SET_UP_TWICE -> { + SeparateWay.SET_UP_TWICE + } + + else -> null + } + + private fun getEveryWay() = when (mBinding.spinner.selectedItemPosition) { + POSITION_EVERY_SINGLE_MEASURE -> { + EveryWay.SINGLE_MEASURE + } + + POSITION_EVERY_OPPOSITE_MEASURE -> { + EveryWay.OPPOSITE_MEASURE + } + + else -> null + } + + + override fun getShowSlopSwitch(): Boolean { + return mBinding.il.showSlopSwitch.isChecked + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/projectedit/ProjectEditTriangleFragment.kt b/app/src/main/java/com/bingce/controlnetwork/fragment/projectedit/ProjectEditTriangleFragment.kt new file mode 100644 index 0000000..378ad93 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/projectedit/ProjectEditTriangleFragment.kt @@ -0,0 +1,74 @@ +package com.bingce.controlnetwork.fragment.projectedit + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory +import com.bingce.controlapphelper.datasource.database.config.IConfigDataSource +import com.bingce.controlnetwork.databinding.FragmentProjectEditTriangleBinding + +/** + * 三角测量和联系测量共用 + */ +class ProjectEditTriangleFragment : AbstractProjectEditFragment() { + + init { + initSelectToleranceLauncher(this) + } + + private var _binding: FragmentProjectEditTriangleBinding? = null + + private val mBinding get() = _binding!! + + + val configDataSource: IConfigDataSource = SurveyorDatabaseFactory.instance.configDataSource + + override fun createContentView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + _binding = FragmentProjectEditTriangleBinding.inflate(inflater, container, false) + return mBinding.root + } + + override fun quitWhenTouchBg(): Boolean { + return true + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } + + override fun getCurrentProjectName(): String { + return mBinding.il.editor.text.toString().trim() + } + + override fun setToleranceName(name: String) { + mBinding.il.selectTolerance.text = name + } + + override fun setProjectName(name: String) { + mBinding.il.editor.setText(name) + } + + override fun setShowSlopSwitch(isChecked: Boolean) { + mBinding.il.showSlopSwitch.isChecked = isChecked + } + + override fun getToleranceBtn(): View { + return mBinding.il.selectTolerance + } + + override suspend fun saveOtherRecord(projectId: String) { + //暂无使用 + } + + override fun getShowSlopSwitch(): Boolean { + return mBinding.il.showSlopSwitch.isChecked + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/station/AbstractStationFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/station/AbstractStationFragment.java new file mode 100644 index 0000000..5359839 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/station/AbstractStationFragment.java @@ -0,0 +1,112 @@ +package com.bingce.controlnetwork.fragment.station; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.widget.SwitchCompat; +import androidx.fragment.app.Fragment; + +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.activity.fragmentcontainer.IOnBackFilter; +import com.bingce.controlnetwork.fragment.TipsFragment; +import com.bingce.controlnetwork.fragment.TipsWith2OptionFragment; +import com.bingce.controlnetwork.fragment.base.BaseFragment; +import com.bingce.controlnetwork.newui.widget.switchtext.SwitchWithText; + +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public abstract class AbstractStationFragment extends BaseFragment implements IOnBackFilter { + + /** + * 错误提示-已经存在重复测期测站 + * + * @param duplicateStationName + */ + protected void tipsError(String duplicateStationName) { + runOnUI(() -> { + if (getContext() == null) { + return; + } + TipsFragment.tipsOnly( + getChildFragmentManager(), + getViewLifecycleOwner(), + getContext(), + duplicateStationError(duplicateStationName)); + }); + } + + protected String duplicateStationError(String duplicateStationName) { + return Tools.getString(R.string.already_exist_station_period, duplicateStationName); + } + + protected abstract int layoutRes(); + + @Nullable + @Override + public View onCreateView(@NonNull @NotNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + return inflater.inflate(layoutRes(), container, false); + } + + protected static boolean warningDataLosing(@NonNull Fragment fragment) { + TipsWith2OptionFragment + .tips( + fragment.getChildFragmentManager(), + fragment.getViewLifecycleOwner(), + fragment.getString(R.string.exit), + fragment.getString(R.string.cancel), + fragment.getString(R.string.tips_station_data_will_lose), + new TipsWith2OptionFragment.SimpleCallback() { + @Override + public void onConfirm() { + if (fragment.getActivity() != null) { + fragment.getActivity().finish(); + } + } + } + ); + return true; + } + + protected static boolean switchIsChecked(View view, int id) { + if (view == null) { + return false; + } + View view1 = view.findViewById(id); + if (view1 != null) { + if (view1 instanceof SwitchWithText) { + SwitchWithText switchCompat = (SwitchWithText) view1; + return switchCompat.isChecked(); + } + if (view1 instanceof SwitchCompat) { + SwitchCompat switchCompat = (SwitchCompat) view1; + return switchCompat.isChecked(); + } + } + return false; + } + + protected boolean needLeftRightSurveyor() { + return switchIsChecked(getView(), R.id.left_right_switch); + } + + protected void updateLeftRightMark(View view, boolean need) { + if (view == null) { + return; + } + SwitchWithText switchCompat = view.findViewById(R.id.left_right_switch); + if (switchCompat != null) { + switchCompat.setChecked(need); + } + } + + protected static boolean isListEmpty(List stationItems) { + return stationItems != null && !stationItems.isEmpty(); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/station/defaultstation/AbstractSingleStationPointListFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/station/defaultstation/AbstractSingleStationPointListFragment.java new file mode 100644 index 0000000..7a381a0 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/station/defaultstation/AbstractSingleStationPointListFragment.java @@ -0,0 +1,201 @@ +package com.bingce.controlnetwork.fragment.station.defaultstation; + +import android.content.Intent; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.activity.result.ActivityResultLauncher; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.model.SurveyorPoint; +import com.bingce.controlapphelper.model.BundleConstants; +import com.bingce.controlapphelper.model.PickPointResult; +import com.bingce.controlapphelper.model.StationDetailItem; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.adapter.stationdetail.BaseStationDetailAdapter; +import com.bingce.controlnetwork.adapter.stationdetail.EditableStationDetailAdapter; +import com.bingce.controlnetwork.adapter.stationdetail.NoEditableStationDetailAdapter; +import com.bingce.controlnetwork.fragment.PickPointFragment; +import com.bingce.controlnetwork.fragment.station.AbstractStationFragment; +import com.bingce.controlnetwork.ui.widget.recyclerview.SwipeDraggableRecyclerViewUtil; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import blankj.utilcode.util.ToastUtils; + +public abstract class AbstractSingleStationPointListFragment extends AbstractStationFragment + implements BaseStationDetailAdapter.IOnSelectPointDelegate, + SwipeDraggableRecyclerViewUtil.IStationPointOperatorListener { + private static final String TYPE_SURVEYOR_STATION = "___station_points"; + private static final String TYPE_SURVEYOR_POINT = "___surveyor_points"; + private BaseStationDetailAdapter defaultStationDetailAdapter; + private final ActivityResultLauncher defaultStationLauncher = PickPointFragment.createActivityLauncher(this, (type, pickPointResult) -> { + if (pickPointResult.getSelectedIds().isEmpty() || pickPointResult.getSelectedNames().isEmpty()) { + return; + } + if (TYPE_SURVEYOR_STATION.equals(type)) { + //检测数据是否正常 + if (pickPointResult.getSelectedIds().get(0) == null || + pickPointResult.getSelectedNames().get(0) == null) { + showStationPointError(); + return; + } + defaultStationDetailAdapter.setStationPoint( + pickPointResult.getSelectedIds().get(0), + pickPointResult.getSelectedNames().get(0)); + } else if (TYPE_SURVEYOR_POINT.equals(type)) { + //检测数据是否正常 + if (pickPointResult.getSelectedIds().size() != pickPointResult.getSelectedNames().size() || + pickPointResult.getSelectedIds().size() < 2) { + showPointCountError(); + return; + } + defaultStationDetailAdapter.setSurveyorPoint( + pickPointResult.getSelectedIds(), + pickPointResult.getSelectedNames()); + } + onItemChanged(); + }); + + protected abstract void prepareAdapterData(IDataCallback callback); + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = super.onCreateView(inflater, container, savedInstanceState); + if (view == null) { + return null; + } + RecyclerView recyclerView = view.findViewById(R.id.recycler_view); + if (recyclerView != null) { + prepareAdapterData((editAble, items) -> { + if (getContext() == null) { + return; + } + if (editAble) { + defaultStationDetailAdapter = new EditableStationDetailAdapter( + AbstractSingleStationPointListFragment.this, + items); + } else { + defaultStationDetailAdapter = new NoEditableStationDetailAdapter(items); + } + runOnUI(() -> { + recyclerView.setAdapter(defaultStationDetailAdapter); + SwipeDraggableRecyclerViewUtil.setup(defaultStationDetailAdapter, + recyclerView, + getChildFragmentManager(), + getViewLifecycleOwner(), + this, + getContext()); + }); + }); + } + setHasOptionsMenu(true); + return view; + } + + protected final List collectDataItems() { + if (defaultStationDetailAdapter == null) { + return null; + } + return defaultStationDetailAdapter.collectData(); + } + + /** + * 将数据库存储的测站点列表和显示的顺序保持一致 + * + * @param surveyorStationRecord + */ + protected final void sortStationPoint(SurveyorStationRecord surveyorStationRecord) { + List currentItems = collectDataItems(); + if (currentItems == null) { + return; + } + //对现有数据进行排序 + Map map = new HashMap<>(); + for (SurveyorPoint item : surveyorStationRecord.getItems()) { + map.put(item.getPointId(), item); + } + for (int index = 0; index < currentItems.size(); index++) { + SurveyorPoint item = currentItems.get(index); + if (item == null) { + continue; + } + SurveyorPoint find = map.get(item.getPointId()); + if (find == null) { + continue; + } + currentItems.set(index, find); + } + surveyorStationRecord.setItems(currentItems); + } + + @Override + public void onSelectStationPoint(PickPointResult pickPointResult, ArrayList filters) { + if (getArguments() == null || getContext() == null) { + return; + } + String projectId = getArguments().getString(BundleConstants.KEY_PROJECT_ID); + PickPointFragment.pickPoint( + getContext(), + TYPE_SURVEYOR_STATION, + 1, + getContext().getString(R.string.select_station_point), + filters, + projectId, pickPointResult, defaultStationLauncher); + } + + @Override + public void onSelectSurveyorPoint(PickPointResult pickPointResult, ArrayList filters) { + if (getArguments() == null || getContext() == null) { + return; + } + String projectId = getArguments().getString(BundleConstants.KEY_PROJECT_ID); + PickPointFragment.pickPoint( + getContext(), + TYPE_SURVEYOR_POINT, + -1, + getContext().getString(R.string.select_surveyor_point), + filters, + projectId, pickPointResult, defaultStationLauncher); + } + + @Override + public void onItemRemoved(int adapterPosition) { + onItemChanged(); + } + + @Override + public void onItemDragCompleted() { + onItemChanged(); + } + + /** + * 测站数据发生了变化--测点被删除、测点被修改、测站被修改、测点被拖拽 + */ + protected abstract void onItemChanged(); + + protected int surveyorPointSize() { + return defaultStationDetailAdapter.surveyorPointSize(); + } + + private void showPointCountError() { + ToastUtils.showShort(R.string.tips_surveyor_point_must_more_than_2); + } + + private void showStationPointError() { + ToastUtils.showShort(R.string.tips_please_select_station_point); + } + + public interface IDataCallback { + void onGetAdapterData(boolean editAble, List items); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/station/defaultstation/ComponentSingleStationPointListFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/station/defaultstation/ComponentSingleStationPointListFragment.java new file mode 100644 index 0000000..c56a024 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/station/defaultstation/ComponentSingleStationPointListFragment.java @@ -0,0 +1,177 @@ +package com.bingce.controlnetwork.fragment.station.defaultstation; + +import android.os.Bundle; + +import androidx.annotation.WorkerThread; +import androidx.lifecycle.ViewModelProvider; + +import com.bingce.controlapphelper.datasource.database.ProjectType; +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.point.IPointDataSource; +import com.bingce.controlapphelper.datasource.database.point.PointRecord; +import com.bingce.controlapphelper.datasource.database.project.ProjectRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.ISurveyorStationDataSource; +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.model.SurveyorPoint; +import com.bingce.controlapphelper.model.BundleConstants; +import com.bingce.controlapphelper.model.StationDetailItem; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.fragment.stationdetail.StationDetailViewModel; +import com.bingce.utils.ThreadPoolUtil; + +import java.util.ArrayList; +import java.util.List; + +public class ComponentSingleStationPointListFragment extends AbstractSingleStationPointListFragment { + + @Override + protected int layoutRes() { + return R.layout.fragment_surveyor_station_point_list_layout; + } + + @Override + protected void prepareAdapterData(IDataCallback callback) { + if (getArguments() == null) { + return; + } + String stationId = getArguments().getString(KEY_STATION_ID); + IPointDataSource pointDataSource = SurveyorDatabaseFactory + .instance + .getPointDataSource(); + ThreadPoolUtil.execute(() -> { + if (getContext() == null) { + return; + } + //1.读取测站数据 + SurveyorStationRecord surveyorStationRecord = + SurveyorDatabaseFactory.instance.getSurveyorStation().getRecordSync(stationId); + List items = surveyorStationRecord.getItems(); + //2.提取测站点和测点 + List pointIdsWithoutStation = new ArrayList<>(); + List pointNamesWithoutStation = new ArrayList<>(); + String stationPointId = null; + String stationPointName = null; + for (SurveyorPoint item : items) { + if (item == null) { + continue; + } + if (SurveyorPoint.TYPE_STATION.equals(item.getType())) { + stationPointId = item.getPointId(); + PointRecord pointRecord = pointDataSource.findByIdSync(stationPointId); + if (pointRecord != null) { + stationPointName = pointRecord.getName(); + } + } else if (SurveyorPoint.TYPE_POINT.equals(item.getType())) { + pointIdsWithoutStation.add(item.getPointId()); + PointRecord pointRecord = pointDataSource.findByIdSync(item.getPointId()); + if (pointRecord != null) { + pointNamesWithoutStation.add(pointRecord.getName()); + } + } + } + //3.为adapter创建数据源 + List itemList = new ArrayList<>(); + //添加测站title item + itemList.add( + new StationDetailItem( + getContext().getString(R.string.select_station_point), + StationDetailItem.ITEM_TYPE_STATION_GROUP, + null)); + if (stationPointId != null && stationPointName != null) { + //添加测站点 + StationDetailItem item = + new StationDetailItem( + stationPointName, + StationDetailItem.ITEM_TYPE_STATION_ITEM, + stationPointId); + itemList.add(item); + } + //添加测点title item + itemList.add( + new StationDetailItem( + getContext().getString(R.string.select_surveyor_point), + StationDetailItem.ITEM_TYPE_POINT_GROUP, + null)); + for (int index = 0; index < pointIdsWithoutStation.size(); index++) { + String id = pointIdsWithoutStation.get(index); + String name = pointNamesWithoutStation.get(index); + if (id == null || name == null) { + continue; + } + //添加测点 + StationDetailItem item = + new StationDetailItem( + name, + StationDetailItem.ITEM_TYPE_POINT_ITEM, + id); + itemList.add(item); + } + //4.回调 + callback.onGetAdapterData(isCanEditSurveyorPoint(surveyorStationRecord), itemList); + + runOnUI(() -> updateLeftRightMark(getView(), surveyorStationRecord.leftAndRightSurveyor)); + }); + } + + @Override + protected void onItemChanged() { + if (getArguments() == null) { + return; + } + String stationId = getArguments().getString(KEY_STATION_ID); + ThreadPoolUtil.execute(() -> { + if (getContext() == null) { + return; + } + ISurveyorStationDataSource stationDataSource = SurveyorDatabaseFactory.instance.getSurveyorStation(); + //1.读取测站数据 + SurveyorStationRecord currentRecord = stationDataSource.getRecordSync(stationId); + if (currentRecord == null) { + return; + } + //2.排序测站列表 + sortStationPoint(currentRecord); + //3.存储测站record + stationDataSource.saveSync(currentRecord); + //4.更新测点数量 + runOnUI(() -> { + if (getActivity() == null) { + return; + } + }); + }); + } + + @Override + public boolean cancelBack() { + return false; + } + + private static final String KEY_STATION_ID = "__station_id"; + public static final String TAG = ComponentSingleStationPointListFragment.class.getName(); + + public static ComponentSingleStationPointListFragment newInstance(String stationId, String projectId) { + ComponentSingleStationPointListFragment fragment = new ComponentSingleStationPointListFragment(); + Bundle bundle = new Bundle(); + bundle.putString(KEY_STATION_ID, stationId); + bundle.putString(BundleConstants.KEY_PROJECT_ID, projectId); + fragment.setArguments(bundle); + return fragment; + } + + @WorkerThread + private boolean isCanEditSurveyorPoint(SurveyorStationRecord stationRecord) { + ProjectRecord projectRecord = SurveyorDatabaseFactory.instance.getProjectDataSource().getRecord(stationRecord.getProjectId()); + if (projectRecord.getProjectType() == null || projectRecord.getProjectType().equals(ProjectType.TRIANGLE.getFlag())) { + if (!SurveyorStationRecord.isLineStation(stationRecord.getLineId())) { + long surveyorRecordCount = + SurveyorDatabaseFactory + .instance + .getSurveyorRecordDataSource() + .recordCount(stationRecord.getId()); + return surveyorRecordCount <= 0; + } + } + return false; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/station/defaultstation/DefaultStationSetupFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/station/defaultstation/DefaultStationSetupFragment.java new file mode 100644 index 0000000..424e32f --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/station/defaultstation/DefaultStationSetupFragment.java @@ -0,0 +1,229 @@ +package com.bingce.controlnetwork.fragment.station.defaultstation; + +import android.content.Context; +import android.os.Bundle; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; + +import androidx.annotation.NonNull; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.point.IPointDataSource; +import com.bingce.controlapphelper.datasource.database.point.PointRecord; +import com.bingce.controlapphelper.datasource.database.project.ProjectRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.ISurveyorStationDataSource; +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.model.SurveyorPoint; +import com.bingce.controlapphelper.model.BundleConstants; +import com.bingce.controlapphelper.model.StationDetailItem; +import com.bingce.controlapphelper.util.PointUtil; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.activity.fragmentcontainer.FragmentContainerActivity; +import com.bingce.controlnetwork.newui.widget.switchtext.SwitchWithText; +import com.bingce.utils.ThreadPoolUtil; + +import java.util.Arrays; +import java.util.List; + +public class DefaultStationSetupFragment extends AbstractSingleStationPointListFragment { + public static final String TAG = DefaultStationSetupFragment.class.getName(); + private MenuItem confirmItem; + + private boolean lastConfirmEnable = false; + + @Override + protected int layoutRes() { + return R.layout.fragment_default_surveyor_station_setup_layout; + } + + @Override + protected void prepareAdapterData(IDataCallback callback) { + if (callback == null || getContext() == null) { + return; + } + List itemList = Arrays.asList( + new StationDetailItem( + getContext().getString(R.string.select_station_point), + StationDetailItem.ITEM_TYPE_STATION_GROUP, + null), + new StationDetailItem( + getContext().getString(R.string.select_surveyor_point), + StationDetailItem.ITEM_TYPE_POINT_GROUP, + null)); + callback.onGetAdapterData(true, itemList); + } + + @Override + public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { + inflater.inflate(R.menu.menu_confirm, menu); + confirmItem = menu.findItem(R.id.menu_confirm); + if (confirmItem != null) { + confirmItem.setEnabled(lastConfirmEnable); + } + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + if (R.id.menu_confirm == item.getItemId()) { + //收集信息,并创建站点记录 + List stationItems = collectDataItems(); + if (stationItems == null || getArguments() == null) { + return super.onOptionsItemSelected(item); + } + String projectId = getArguments().getString(BundleConstants.KEY_PROJECT_ID); + String periodId = getArguments().getString(BundleConstants.KEY_PERIOD_ID); + ThreadPoolUtil.execute(() -> { + //找到站的点id + String stationPointId = ""; + for (SurveyorPoint stationItem : stationItems) { + if (SurveyorPoint.TYPE_STATION.equals(stationItem.getType())) { + stationPointId = stationItem.getPointId(); + break; + } + } + String name = checkValidate(stationPointId, projectId, periodId); + if (name != null && !name.isEmpty()) { + tipsError(name); + return; + } + //先对stationItems点作处理 + //处理方式就是,如果这里面有点是global_control,将其拷贝到project known_point中 + //并使用拷贝的pointId替换stationItems里面的id + PointUtil.globalToProjectControlPoint(stationItems, projectId); + + IPointDataSource pointDataSource = + SurveyorDatabaseFactory.instance.getPointDataSource(); + PointRecord pointRecord = pointDataSource.findByIdSync(stationPointId); + if (pointRecord == null) { + return; + } + ProjectRecord projectRecord = SurveyorDatabaseFactory + .instance + .getProjectDataSource() + .getRecord(projectId); + boolean showSlopDistance = true; + if (projectRecord != null) { + showSlopDistance = projectRecord.isShowSlopDistance(); + } + SurveyorStationRecord stationRecord = SurveyorStationRecord.mulAngle(projectId, periodId); + stationRecord.setItems(stationItems); + if (stationItems.size() > 4) { + stationRecord.setAutoClose(true); + } + //检测左右角 + stationRecord.setLeftAndRightSurveyor(needLeftRightSurveyor()); + + stationRecord.setShowSlopDistance(showSlopDistance); + + SurveyorDatabaseFactory + .instance + .getSurveyorStation() + .saveSync(stationRecord); + + + runOnUI(() -> { + if (getActivity() != null) { + getActivity().finish(); + } + }); + }); + } + return super.onOptionsItemSelected(item); + } + + protected static String checkValidate(String stationPointId, String projectId, String periodId) { + //检测该测期下是否有同名测站 + ISurveyorStationDataSource stationDataSource = SurveyorDatabaseFactory + .instance + .getSurveyorStation(); + List stationRecordList = + stationDataSource.getDataList(projectId, periodId); + if (stationRecordList != null) {//遍历当前已有测站,检测是否有同名测站 + for (SurveyorStationRecord record : stationRecordList) { + List items = record.getItems(); + if (items != null) {//检测测站名是否相同 + for (SurveyorPoint stationItem : items) { + if (SurveyorPoint.TYPE_STATION.equals(stationItem.getType())) { + if (stationItem.getPointId().equals(stationPointId)) { + PointRecord pointRecord = SurveyorDatabaseFactory + .instance + .getPointDataSource() + .findByIdSync(stationItem.getOriginalPointId()); + if (pointRecord != null) { + return pointRecord.getName(); + } + return ""; + } + break; + } + } + } + } + } + return null; + } + + protected boolean isCurrentDataValidate() { + List stationItems = collectDataItems(); + if (stationItems == null || stationItems.size() < 3) { + return false; + } else { + //检测是否有station item + for (SurveyorPoint item : stationItems) { + if (item == null) { + continue; + } + if (SurveyorPoint.TYPE_STATION.equals(item.getType())) { + return true; + } + } + } + return false; + } + + @Override + protected void onItemChanged() { + if (confirmItem != null) {//设置menuItem enable + boolean confirmEnable = isCurrentDataValidate(); + confirmItem.setEnabled(confirmEnable); + lastConfirmEnable = confirmEnable; + } + //检测左右角是否 + SwitchWithText leftAndRightSwitch = findViewById(R.id.left_right_switch); + if (leftAndRightSwitch != null) { + int pointSize = surveyorPointSize(); + if (pointSize == 2) { + leftAndRightSwitch.setVisibility(View.VISIBLE); + } else { + leftAndRightSwitch.setChecked(false); + leftAndRightSwitch.setVisibility(View.GONE); + } + } + } + + @Override + public boolean cancelBack() { + List items = collectDataItems(); + if (isListEmpty(items)) { + return warningDataLosing(this); + } + return false; + } + + public static final int title = R.string.new_surveyor_station; + + public static void start(Context context, String projectId, String period) { + Bundle bundle = new Bundle(); + bundle.putString(BundleConstants.KEY_PROJECT_ID, projectId); + bundle.putString(BundleConstants.KEY_PERIOD_ID, period); + FragmentContainerActivity.start(context, TAG, title, bundle); + } + + public static DefaultStationSetupFragment newInstance(Bundle bundle) { + DefaultStationSetupFragment fragment = new DefaultStationSetupFragment(); + fragment.setArguments(bundle); + return fragment; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/station/defaultstation/SingleStationDetailAndEditContentFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/station/defaultstation/SingleStationDetailAndEditContentFragment.java new file mode 100644 index 0000000..0116ad2 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/station/defaultstation/SingleStationDetailAndEditContentFragment.java @@ -0,0 +1,195 @@ +package com.bingce.controlnetwork.fragment.station.defaultstation; + + +import static com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord.isLineStation; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.lifecycle.ViewModelProvider; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.point.IPointDataSource; +import com.bingce.controlapphelper.datasource.database.point.PointRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.ISurveyorStationDataSource; +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.model.SurveyorPoint; +import com.bingce.controlapphelper.model.BundleConstants; +import com.bingce.controlapphelper.model.StationDetailItem; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.fragment.stationdetail.StationDetailViewModel; +import com.bingce.utils.ThreadPoolUtil; + +import java.util.ArrayList; +import java.util.List; + + +public class SingleStationDetailAndEditContentFragment extends AbstractSingleStationPointListFragment { + + private StationDetailViewModel viewModel; + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + viewModel = new ViewModelProvider(requireActivity()).get(StationDetailViewModel.class); + } + + @Override + protected int layoutRes() { + return R.layout.item_recycler_view_layout; + } + + @Override + protected void prepareAdapterData(IDataCallback callback) { + if (getArguments() == null) { + return; + } + String stationId = getArguments().getString(KEY_STATION_ID); + IPointDataSource pointDataSource = SurveyorDatabaseFactory + .instance + .getPointDataSource(); + ThreadPoolUtil.execute(() -> { + if (getContext() == null) { + return; + } + //1.读取测站数据 + SurveyorStationRecord surveyorStationRecord = + SurveyorDatabaseFactory.instance.getSurveyorStation().getRecordSync(stationId); + List items = surveyorStationRecord.getItems(); + //2.提取测站点和测点 + List pointIdsWithoutStation = new ArrayList<>(); + List pointNamesWithoutStation = new ArrayList<>(); + String stationPointId = null; + String stationPointName = null; + for (SurveyorPoint item : items) { + if (item == null) { + continue; + } + if (SurveyorPoint.TYPE_STATION.equals(item.getType())) { + stationPointId = item.getPointId(); + PointRecord pointRecord = pointDataSource.findByIdSync(stationPointId); + if (pointRecord != null) { + stationPointName = pointRecord.getName(); + } + } else if (SurveyorPoint.TYPE_POINT.equals(item.getType())) { + pointIdsWithoutStation.add(item.getPointId()); + PointRecord pointRecord = pointDataSource.findByIdSync(item.getPointId()); + if (pointRecord != null) { + pointNamesWithoutStation.add(pointRecord.getName()); + } + } + } + //3.为adapter创建数据源 + List itemList = new ArrayList<>(); + //添加测站title item + itemList.add( + new StationDetailItem( + getContext().getString(R.string.select_station_point), + StationDetailItem.ITEM_TYPE_STATION_GROUP, + null)); + if (stationPointId != null && stationPointName != null) { + //添加测站点 + StationDetailItem item = + new StationDetailItem( + stationPointName, + StationDetailItem.ITEM_TYPE_STATION_ITEM, + stationPointId); + itemList.add(item); + } + //添加测点title item + itemList.add( + new StationDetailItem( + getContext().getString(R.string.select_surveyor_point), + StationDetailItem.ITEM_TYPE_POINT_GROUP, + null)); + for (int index = 0; index < pointIdsWithoutStation.size(); index++) { + String id = pointIdsWithoutStation.get(index); + String name = pointNamesWithoutStation.get(index); + if (id == null || name == null) { + continue; + } + //添加测点 + StationDetailItem item = + new StationDetailItem( + name, + StationDetailItem.ITEM_TYPE_POINT_ITEM, + id); + itemList.add(item); + } + //4.回调 + boolean editAble; + if (isLineStation(surveyorStationRecord.getLineId())) { + editAble = false; + } else { + //检测记录数量,如果为0,则可编辑,否则不可编辑 + long surveyorRecordCount = + SurveyorDatabaseFactory + .instance + .getSurveyorRecordDataSource() + .recordCount(surveyorStationRecord.getId()); + editAble = surveyorRecordCount <= 0; + } + callback.onGetAdapterData(editAble, itemList); + + runOnUI(() -> { + viewModel.setLeftOrRight(surveyorStationRecord.isLeftAndRightSurveyor()); + updateSurverPointCount(); + }); + }); + } + + @Override + protected void onItemChanged() { + if (getArguments() == null) { + return; + } + String stationId = getArguments().getString(KEY_STATION_ID); + ThreadPoolUtil.execute(() -> { + if (getContext() == null) { + return; + } + ISurveyorStationDataSource stationDataSource = SurveyorDatabaseFactory.instance.getSurveyorStation(); + //1.读取测站数据 + SurveyorStationRecord currentRecord = stationDataSource.getRecordSync(stationId); + if (currentRecord == null) { + return; + } + //2.排序测站列表 + sortStationPoint(currentRecord); + //3.存储测站record + stationDataSource.saveSync(currentRecord); + //4.更新测点数量 + runOnUI(() -> { + if (getActivity() == null) { + return; + } + updateSurverPointCount(); + }); + }); + } + + @Override + public boolean cancelBack() { + return false; + } + + private static final String KEY_STATION_ID = "__station_id"; + public static final String TAG = SingleStationDetailAndEditContentFragment.class.getName(); + + public static SingleStationDetailAndEditContentFragment newInstance(String stationId, String projectId) { + SingleStationDetailAndEditContentFragment fragment = new SingleStationDetailAndEditContentFragment(); + Bundle bundle = new Bundle(); + bundle.putString(KEY_STATION_ID, stationId); + bundle.putString(BundleConstants.KEY_PROJECT_ID, projectId); + fragment.setArguments(bundle); + return fragment; + } + + private void updateSurverPointCount() { + viewModel.setRefreshUi(); + } + + public int getSurveyorPointSize() { + return surveyorPointSize(); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/station/heighttraverse/AbstructSetupStationHeightTraverseFragment.kt b/app/src/main/java/com/bingce/controlnetwork/fragment/station/heighttraverse/AbstructSetupStationHeightTraverseFragment.kt new file mode 100644 index 0000000..33ace4c --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/station/heighttraverse/AbstructSetupStationHeightTraverseFragment.kt @@ -0,0 +1,181 @@ +package com.bingce.controlnetwork.fragment.station.heighttraverse + +import android.os.Bundle +import android.view.View +import androidx.annotation.WorkerThread +import androidx.fragment.app.Fragment +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory +import com.bingce.controlapphelper.datasource.database.point.PointRecord +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord +import com.bingce.controlapphelper.util.RegExUtil +import com.bingce.controlapphelper.util.Tools +import com.bingce.controlnetwork.R +import com.bingce.utils.DateUtils +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.MainScope +import kotlinx.coroutines.cancel +import kotlinx.coroutines.launch +import java.util.Date + +abstract class AbstructSetupStationHeightTraverseFragment : Fragment() { + + val prefixStation: String = Tools.getString(R.string.transfer) + val prefixJianXie: String = Tools.getString(R.string.break_point) + val prefixTransfer: String = Tools.getString(R.string.turn_point) + + private val mainScope = MainScope() + + abstract fun doConfirm() + abstract fun isCheckedJianXiePoint(): Boolean + abstract fun isCheckedEndPoint(): Boolean + abstract fun getFrontPointHeight(): String + + abstract suspend fun getBackPoint(): PointRecord + abstract suspend fun getFrontPoint(): PointRecord + abstract suspend fun getStationPoint(): PointRecord? + abstract fun initView() + abstract fun initListener() + abstract fun initData() + + fun launch(block: suspend CoroutineScope.() -> Unit) { + mainScope.launch(Dispatchers.IO) { + block.invoke(this) + } + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + initView() + initListener() + initData() + } + + override fun onDestroyView() { + super.onDestroyView() + mainScope.cancel() + } + + fun getProjectId(): String { + val createStationForHeightTraverseFragment = + parentFragment as CreateStationForHeightTraverseFragment + return createStationForHeightTraverseFragment.getProjectId() + } + + fun getRouteId(): String { + val createStationForHeightTraverseFragment = + parentFragment as CreateStationForHeightTraverseFragment + return createStationForHeightTraverseFragment.getRouteId() + } + + fun createStationRecordNoSurveyorPoints( + projectId: String, + projectType: String, + relationStationId: String? + ): SurveyorStationRecord { + val stationRecord = SurveyorStationRecord() + stationRecord.id = DateUtils.genRandomTimeId() + stationRecord.projectId = projectId + stationRecord.projectType = projectType + stationRecord.showSlopDistance = true + stationRecord.createDate = Date() + stationRecord.routeId = getRouteId() + stationRecord.items = mutableListOf() + stationRecord.relationStationId = relationStationId + return stationRecord + } + + protected fun finish() { + requireActivity().finish() + } + + @WorkerThread + protected fun savePoint( + pointName: String, + pointTypeHeightTraverse: String?, + projectId: String, + height: String? + ): String { +// var pointRecord = +// SurveyorDatabaseFactory.instance.pointDataSource.findByNameSync( +// pointName, +// projectId +// ) +// if (pointRecord == null) { +// pointRecord = PointRecord.point( +// getProjectId(), +// PointRecord.TYPE_UNKNOWN_POINT, +// pointName, +// "", +// 0.0, +// 0.0, +// stringToDouble(height), +// "", +// -1 +// ) +// pointRecord.pointTypeHeightTraverse = pointTypeHeightTraverse +// SurveyorDatabaseFactory.instance.pointDataSource.saveSync(pointRecord) +// } else { +// pointRecord.setZ(stringToDouble(height)) +// SurveyorDatabaseFactory.instance.pointDataSource.update(pointRecord) +// } + + val pointRecord = PointRecord.point( + projectId, + PointRecord.TYPE_UNKNOWN_POINT, + pointName, + "", + 0.0, + 0.0, + stringToDouble(height), + "", + -1 + ) + pointRecord.pointTypeHeightTraverse = pointTypeHeightTraverse + SurveyorDatabaseFactory.instance.pointDataSource.saveSync(pointRecord) + + return pointRecord.getId() + } + + @WorkerThread + protected fun saveFrontPoint(projectId: String, frontName: String): String { + var frontPointTypeHeightTraverse: String? = null + if (isCheckedJianXiePoint()) { + frontPointTypeHeightTraverse = + PointRecord.TYPE_HEIGHT_TRAVERSE_INTERVAL + } else if (isCheckedEndPoint()) { + //终点 + } else { + frontPointTypeHeightTraverse = + PointRecord.TYPE_HEIGHT_TRAVERSE_TRANSFER + } + + val frontHeight = getFrontPointHeight() + + return savePoint(frontName, frontPointTypeHeightTraverse, projectId, frontHeight) + } + + fun doubleToString(value: Double) = value.toString() + fun stringToDouble(value: String?): Double { + if (value.isNullOrEmpty()) { + return 0.0 + } + return value.toDouble() + } + + @WorkerThread + protected fun getNewIndexFromTwoPointId(pointId1: String, pointId2: String): PointRecord { + val point1 = + SurveyorDatabaseFactory.instance.pointDataSource.findByIdSync(pointId1) + val point2 = + SurveyorDatabaseFactory.instance.pointDataSource.findByIdSync(pointId2) + val index1 = RegExUtil.getIndexFromName(point1.getName()) + val index2 = RegExUtil.getIndexFromName(point2.getName()) + if (index1 >= index2) { + return point1 + } + return point2 + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/station/heighttraverse/CreateStationForHeightTraverseFragment.kt b/app/src/main/java/com/bingce/controlnetwork/fragment/station/heighttraverse/CreateStationForHeightTraverseFragment.kt new file mode 100644 index 0000000..bf62a2c --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/station/heighttraverse/CreateStationForHeightTraverseFragment.kt @@ -0,0 +1,176 @@ +package com.bingce.controlnetwork.fragment.station.heighttraverse + +import android.content.Context +import android.os.Bundle +import android.view.LayoutInflater +import android.view.Menu +import android.view.MenuInflater +import android.view.MenuItem +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory +import com.bingce.controlapphelper.datasource.database.heighttraverse.config.model.EveryWay +import com.bingce.controlapphelper.datasource.database.heighttraverse.config.model.SeparateWay +import com.bingce.controlapphelper.datasource.database.heighttraverse.config.model.StationLayout +import com.bingce.controlapphelper.model.BundleConstants +import com.bingce.controlapphelper.util.Tools +import com.bingce.controlnetwork.R +import com.bingce.controlnetwork.activity.fragmentcontainer.FragmentContainerActivity +import com.bingce.controlnetwork.databinding.FragmentCreateStationForHeightTraverseBinding +import kotlinx.coroutines.MainScope +import kotlinx.coroutines.launch + +/** + * 高程导线 新建测站 + */ +class CreateStationForHeightTraverseFragment : Fragment() { + + private lateinit var confirmItem: MenuItem + + private var _binding: FragmentCreateStationForHeightTraverseBinding? = null + val mBinding get() = _binding!! + private val mainScope = MainScope() + + private var currentFragment: AbstructSetupStationHeightTraverseFragment? = null + + + companion object { + @JvmField + val TAG: String = CreateStationForHeightTraverseFragment::class.java.name + + @JvmStatic + fun newInstance(args: Bundle?): Fragment { + val fragment: Fragment = CreateStationForHeightTraverseFragment() + fragment.arguments = args + return fragment + } + + @JvmStatic + fun start(context: Context, projectId: String?, routeId: String?) { + val bundle = Bundle() + bundle.putString(BundleConstants.KEY_PROJECT_ID, projectId) + bundle.putString(BundleConstants.KEY_ROUTE_ID, routeId) + FragmentContainerActivity.start( + context, + TAG, + R.string.new_surveyor_station,//新建测站 + bundle + ) + } + + } + + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + setHasOptionsMenu(true) + _binding = + FragmentCreateStationForHeightTraverseBinding.inflate(inflater, container, false) + return mBinding.root + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } + + override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { + inflater.inflate(R.menu.menu_confirm, menu) + confirmItem = menu.findItem(R.id.menu_confirm) + super.onCreateOptionsMenu(menu, inflater) + } + + override fun onOptionsItemSelected(item: MenuItem): Boolean { + if (R.id.menu_confirm == item.itemId) { + currentFragment?.doConfirm() + } + return super.onOptionsItemSelected(item) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + init() + } + + private fun init() { + mainScope.launch { + val configRecord = + SurveyorDatabaseFactory.instance.getHeightTraverseConfigDataSource() + .getRecordByProjectId(getProjectId()) + configRecord?.let { + + val stringBuilder = StringBuilder() + stringBuilder.append(Tools.getString(R.string.note_current_station_is)) + + if (it.stationLayout == StationLayout.SEPARATE) { + + if (it.separateWay == SeparateWay.SET_UP_ONCE) { + stringBuilder.append(Tools.getString(R.string.set_up_station_is_seperate_once)) + + replaceFragment( + SeparatSetupStationFragment.newInstance( + SeparatSetupStationFragment.TYPE_ONCE + ) + ) + } else if (it.separateWay == SeparateWay.SET_UP_TWICE) { + stringBuilder.append(Tools.getString(R.string.set_up_station_is_seperate_twice)) + + replaceFragment( + SeparatSetupStationFragment.newInstance( + SeparatSetupStationFragment.TYPE_TWICE + ) + ) + } + } else if (it.stationLayout == StationLayout.EVERY) { + + if (it.everyWay == EveryWay.SINGLE_MEASURE) { + stringBuilder.append(Tools.getString(R.string.set_up_station_is_each_one_way)) + + replaceFragment( + EverySetUpStationFragment.newInstance( + EverySetUpStationFragment.TYPE_ONE_WAY + ) + ) + } else if (it.everyWay == EveryWay.OPPOSITE_MEASURE) { + stringBuilder.append(Tools.getString(R.string.set_up_station_is_each_opposite)) + + replaceFragment( + EverySetUpStationFragment.newInstance( + EverySetUpStationFragment.TYPE_TWO_WAY + ) + ) + } + } + + setTvHint(stringBuilder.toString()) + } + } + + + } + + private fun setTvHint(text: String) { + mBinding.tvHint.text = text + } + + fun getProjectId(): String { + return requireArguments().getString(BundleConstants.KEY_PROJECT_ID)!! + } + + fun getRouteId(): String { + return requireArguments().getString(BundleConstants.KEY_ROUTE_ID)!! + } + + private fun replaceFragment(fragment: AbstructSetupStationHeightTraverseFragment) { + currentFragment = fragment + + val beginTransaction = childFragmentManager.beginTransaction() + beginTransaction.replace(R.id.fl_container, fragment) + beginTransaction.commit() + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/station/heighttraverse/EverySetUpStationFragment.kt b/app/src/main/java/com/bingce/controlnetwork/fragment/station/heighttraverse/EverySetUpStationFragment.kt new file mode 100644 index 0000000..994d027 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/station/heighttraverse/EverySetUpStationFragment.kt @@ -0,0 +1,313 @@ +package com.bingce.controlnetwork.fragment.station.heighttraverse + +import android.os.Bundle +import android.text.TextUtils +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.annotation.WorkerThread +import androidx.room.withTransaction +import blankj.utilcode.util.ToastUtils +import com.bingce.controlapphelper.datasource.database.SurveyorDataBase +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory +import com.bingce.controlapphelper.datasource.database.heighttraverse.config.model.EveryWay +import com.bingce.controlapphelper.datasource.database.point.PointRecord +import com.bingce.controlapphelper.datasource.database.surveyorstation.model.SurveyorPoint +import com.bingce.controlapphelper.util.RegExUtil +import com.bingce.controlapphelper.util.Tools +import com.bingce.controlnetwork.R +import com.bingce.controlnetwork.databinding.FragmentHeightTraverseEverySetupStationBinding +import com.bingce.utils.DateUtils +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext + +/** + * 每点设站 创建测站 + */ +class EverySetUpStationFragment : AbstructSetupStationHeightTraverseFragment() { + + private val mBinding get() = _binding!! + + private var _binding: FragmentHeightTraverseEverySetupStationBinding? = null + + private lateinit var backPoint: PointRecord + private var isFirstStation = false + + companion object { + private const val KEY_TYPE = "KEY_TYPE" + const val TYPE_ONE_WAY = 1 + const val TYPE_TWO_WAY = 2 + + @JvmStatic + fun newInstance(type: Int): EverySetUpStationFragment { + val fragment = EverySetUpStationFragment() + val bundle = Bundle() + bundle.putInt(KEY_TYPE, type) + fragment.arguments = bundle + return fragment + } + } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + _binding = + FragmentHeightTraverseEverySetupStationBinding.inflate(inflater, container, false) + return mBinding.root + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } + + override fun initView() { + mBinding.ilBackTitle.tvTitle.text = Tools.getString(R.string.back_station) + mBinding.ilFrontTitle.tvTitle.text = Tools.getString(R.string.front_station) + //说明信息 + mBinding.ilDesc.tvDesc.text = getString(R.string.staton_setup_every_height_traverse_hint) + //前视打开设置间歇点和终点 + mBinding.ilFrontTitle.llCb.visibility = View.VISIBLE + //设置不可点击 + mBinding.ilBack.etPoint.isFocusable = false + mBinding.ilBack.etHeight.isFocusable = false + mBinding.ilFront.etPoint.isFocusable = false + } + + override fun initListener() { + var isClickCheckBox = false + mBinding.ilFrontTitle.cbJianXie.setOnCheckedChangeListener { buttonView, isChecked -> + if (isClickCheckBox) return@setOnCheckedChangeListener + isClickCheckBox = true + mBinding.ilFrontTitle.cbEnd.isChecked = false + refreshFrontUi() + isClickCheckBox = false + } + mBinding.ilFrontTitle.cbEnd.setOnCheckedChangeListener { buttonView, isChecked -> + if (isClickCheckBox) return@setOnCheckedChangeListener + isClickCheckBox = true + mBinding.ilFrontTitle.cbJianXie.isChecked = false + refreshFrontUi() + isClickCheckBox = false + } + } + + override fun initData() { + launch { + backPoint = getBackPoint() + val frontPoint = getFrontPoint() + withContext(Dispatchers.Main) { + setUi(backPoint, frontPoint) + } + } + } + + private fun setUi(back: PointRecord, front: PointRecord) { + setUiBack(back) + setUiFront(front) + } + + private fun setUiBack(pointRecord: PointRecord) { + mBinding.ilBack.etPoint.setText(pointRecord.getName()) + mBinding.ilBack.etHeight.setText(doubleToString(pointRecord.getZ())) + } + + private fun setUiFront(pointRecord: PointRecord) { + mBinding.ilFront.etPoint.setText(pointRecord.getName()) + mBinding.ilFront.etHeight.setText(doubleToString(pointRecord.getZ())) + } + + + private fun refreshFrontUi() { + launch { + val frontPoint = getFrontPoint() + withContext(Dispatchers.Main) { + setUiFront(frontPoint) + } + } + } + + override suspend fun getBackPoint(): PointRecord { + val projectId = getProjectId() + val routeId = getRouteId() + + val stationLatest = + SurveyorDatabaseFactory.instance.surveyorStation.getByProjectRouteLatest( + projectId, + routeId + ) + + if (stationLatest?.items != null && stationLatest.items.size >= 2) { + val pointRecord: PointRecord = + if (!TextUtils.isEmpty(stationLatest.relationStationId)) { + //对向观测 + getNewIndexFromTwoPointId( + stationLatest.items[0].originalPointId, + stationLatest.items[1].originalPointId + ) + } else { + val pointId = stationLatest.items[1].originalPointId + SurveyorDatabaseFactory.instance.pointDataSource.findByIdSync(pointId) + } + isFirstStation = false + return pointRecord + } + + isFirstStation = true + val routeRecord = SurveyorDatabaseFactory.instance.getRouteDataSource().getById(routeId) + return SurveyorDatabaseFactory.instance.pointDataSource.findByIdSync(routeRecord?.startPointId) + } + + override suspend fun getFrontPoint(): PointRecord { + var frontIndexNew = 1 + if (!isFirstStation) { + val index = RegExUtil.getIndexFromName(backPoint.getName()) + if (index != -1) { + frontIndexNew = index + 1 + } + } + +// val projectId = getProjectId() + val routeId = getRouteId() + + val routeRecord = SurveyorDatabaseFactory.instance.getRouteDataSource().getById(routeId) + + if (mBinding.ilFrontTitle.cbEnd.isChecked) { + return SurveyorDatabaseFactory.instance.pointDataSource.findByIdSync(routeRecord?.endPointId) + } else if (mBinding.ilFrontTitle.cbJianXie.isChecked) { +// val intervalPoint = +// SurveyorDatabaseFactory.instance.pointDataSource.findByPointTypeForHeightTraverseLatest( +// projectId, PointRecord.TYPE_HEIGHT_TRAVERSE_INTERVAL +// ) +// val intervalRecord = PointRecord() +// if (intervalPoint == null) { +// intervalRecord.name = "$prefixJianXie${1}" +// } else { +// val index = RegExUtil.getIndexFromName(intervalPoint.getName()) +// intervalRecord.name = "$prefixJianXie${index + 1}" +// } +// return intervalRecord + val intervalRecord = PointRecord() + intervalRecord.name = "$prefixJianXie${frontIndexNew}" + return intervalRecord + } else { +// val transferPoint = +// SurveyorDatabaseFactory.instance.pointDataSource.findByPointTypeForHeightTraverseLatest( +// projectId, PointRecord.TYPE_HEIGHT_TRAVERSE_TRANSFER +// ) +// val transferRecord = PointRecord() +// if (transferPoint == null) { +// transferRecord.name = "$prefixTransfer${1}" +// } else { +// val index = RegExUtil.getIndexFromName(transferPoint.getName()) +// transferRecord.name = "$prefixTransfer${index + 1}" +// } +// return transferRecord + + val transferRecord = PointRecord() + transferRecord.name = "$prefixTransfer${frontIndexNew}" + return transferRecord + } + } + + override suspend fun getStationPoint(): PointRecord? { + return null + } + + + override fun doConfirm() { + val backName = mBinding.ilBack.etPoint.text.toString().trim() + val frontName = mBinding.ilFront.etPoint.text.toString().trim() + + if (TextUtils.isEmpty(backName)) { + ToastUtils.showShort("backName is empty") + return + } + if (TextUtils.isEmpty(frontName)) { + ToastUtils.showShort("frontName is empty") + return + } + + launch { + val projectId = getProjectId() + val projectRecord = + SurveyorDatabaseFactory.instance.projectDataSource.getRecord(projectId) + + val heightTraverseConfig = + SurveyorDatabaseFactory.instance.getHeightTraverseConfigDataSource() + .getRecordByProjectId(projectId) + + val isTwiceSetup = heightTraverseConfig?.everyWay == EveryWay.OPPOSITE_MEASURE + + SurveyorDataBase.getInstance().withTransaction { + val frontSetupId = saveFrontPoint(projectId, frontName) + + val relationStationId = if (isTwiceSetup) DateUtils.genRandomTimeId() else null + + saveStationRecord( + projectId, + projectRecord.getProjectType(), + backPoint.getId(), + frontSetupId, + relationStationId + ) + + if (isTwiceSetup) { + saveStationRecord( + projectId, + projectRecord.getProjectType(), + frontSetupId, + backPoint.getId(), + relationStationId + ) + } + withContext(Dispatchers.Main) { + finish() + } + } + + } + + } + + override fun isCheckedJianXiePoint(): Boolean { + return mBinding.ilFrontTitle.cbJianXie.isChecked + } + + override fun isCheckedEndPoint(): Boolean { + return mBinding.ilFrontTitle.cbEnd.isChecked + } + + override fun getFrontPointHeight(): String { + return mBinding.ilFront.etHeight.text.toString().trim() + } + + @WorkerThread + private fun saveStationRecord( + projectId: String, + projectType: String, + stationPointId: String, + surveyorPointId: String, + relationStationId: String? + ) { + val stationRecord = + createStationRecordNoSurveyorPoints(projectId, projectType, relationStationId) + stationRecord.items.add( + SurveyorPoint.newInstance( + stationPointId, + SurveyorPoint.TYPE_STATION + ) + ) + stationRecord.items.add( + SurveyorPoint.newInstance( + surveyorPointId, + SurveyorPoint.TYPE_POINT + ) + ) + SurveyorDatabaseFactory.instance.surveyorStation.saveSync(stationRecord) + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/station/heighttraverse/SeparatSetupStationFragment.kt b/app/src/main/java/com/bingce/controlnetwork/fragment/station/heighttraverse/SeparatSetupStationFragment.kt new file mode 100644 index 0000000..26c0596 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/station/heighttraverse/SeparatSetupStationFragment.kt @@ -0,0 +1,428 @@ +package com.bingce.controlnetwork.fragment.station.heighttraverse + +import android.os.Bundle +import android.text.TextUtils +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.annotation.WorkerThread +import androidx.room.withTransaction +import blankj.utilcode.util.ToastUtils +import com.bingce.controlapphelper.datasource.database.SurveyorDataBase +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory +import com.bingce.controlapphelper.datasource.database.heighttraverse.config.model.SeparateWay +import com.bingce.controlapphelper.datasource.database.point.PointRecord +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord +import com.bingce.controlapphelper.datasource.database.surveyorstation.model.SurveyorPoint +import com.bingce.controlapphelper.util.RegExUtil +import com.bingce.controlapphelper.util.Tools +import com.bingce.controlnetwork.R +import com.bingce.controlnetwork.databinding.FragmentHeightTraverseSeperateSetupStationBinding +import com.bingce.utils.DateUtils +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext + +/** + * 隔点设站 创建测站 + */ +class SeparatSetupStationFragment : AbstructSetupStationHeightTraverseFragment() { + private val mBinding get() = _binding!! + private var _binding: FragmentHeightTraverseSeperateSetupStationBinding? = null + + private lateinit var backPoint: PointRecord + private var isFirstStation = false + + companion object { + private const val KEY_TYPE = "KEY_TYPE" + const val TYPE_ONCE = 1 + const val TYPE_TWICE = 2 + + @JvmStatic + fun newInstance(type: Int): SeparatSetupStationFragment { + val separatSetupStationFragment = SeparatSetupStationFragment() + val bundle = Bundle() + bundle.putInt(KEY_TYPE, type) + separatSetupStationFragment.arguments = bundle + return separatSetupStationFragment + } + } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + _binding = + FragmentHeightTraverseSeperateSetupStationBinding.inflate(inflater, container, false) + return mBinding.root + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } + + override fun initView() { + mBinding.ilBackTitle.tvTitle.text = Tools.getString(R.string.rearview) + mBinding.ilStationTitle.tvTitle.text = Tools.getString(R.string.measure_station) + mBinding.ilFrontTitle.tvTitle.text = Tools.getString(R.string.forward_view) + //说明信息 + mBinding.ilDesc.tvDesc.text = getString(R.string.staton_setup_separate_height_traverse_hint) + //前视打开设置间歇点和终点 + mBinding.ilFrontTitle.llCb.visibility = View.VISIBLE + //设置不可点击 + mBinding.ilBack.etPoint.isFocusable = false + mBinding.ilBack.etHeight.isFocusable = false + mBinding.ilStation.etPoint.isFocusable = false + mBinding.ilFront.etPoint.isFocusable = false + } + + override fun initListener() { + var isClickCheckBox = false + mBinding.ilFrontTitle.cbJianXie.setOnCheckedChangeListener { buttonView, isChecked -> + if (isClickCheckBox) return@setOnCheckedChangeListener + isClickCheckBox = true + mBinding.ilFrontTitle.cbEnd.isChecked = false + refreshFrontUi() + isClickCheckBox = false + } + mBinding.ilFrontTitle.cbEnd.setOnCheckedChangeListener { buttonView, isChecked -> + if (isClickCheckBox) return@setOnCheckedChangeListener + isClickCheckBox = true + mBinding.ilFrontTitle.cbJianXie.isChecked = false + refreshFrontUi() + isClickCheckBox = false + } + } + + override fun initData() { + launch { + backPoint = getBackPoint() + val frontPoint = getFrontPoint() + val stationPoint = getStationPoint() + + withContext(Dispatchers.Main) { + setUi(backPoint, stationPoint, frontPoint) + } + } + } + + private fun setUi(back: PointRecord, station: PointRecord, front: PointRecord) { + setUiBack(back) + setUiStation(station) + setUiFront(front) + } + + private fun setUiFront(pointRecord: PointRecord) { + mBinding.ilFront.etPoint.setText(pointRecord.getName()) + mBinding.ilFront.etHeight.setText(doubleToString(pointRecord.getZ())) + } + + private fun setUiBack(pointRecord: PointRecord) { + mBinding.ilBack.etPoint.setText(pointRecord.getName()) + mBinding.ilBack.etHeight.setText(doubleToString(pointRecord.getZ())) + } + + private fun setUiStation(pointRecord: PointRecord) { + mBinding.ilStation.etPoint.setText(pointRecord.getName()) + mBinding.ilStation.etHeight.setText(doubleToString(pointRecord.getZ())) + } + + + private fun refreshFrontUi() { + launch { + val frontPoint = getFrontPoint() + withContext(Dispatchers.Main) { + setUiFront(frontPoint) + } + } + } + + override fun doConfirm() { + + val backName = mBinding.ilBack.etPoint.text.toString().trim() + val stationName = mBinding.ilStation.etPoint.text.toString().trim() + val frontName = mBinding.ilFront.etPoint.text.toString().trim() + + if (TextUtils.isEmpty(backName)) { + ToastUtils.showShort("backName is empty") + return + } + if (TextUtils.isEmpty(stationName)) { + ToastUtils.showShort("stationName is empty") + return + } + if (TextUtils.isEmpty(frontName)) { + ToastUtils.showShort("frontName is empty") + return + } + + launch { + val projectId = getProjectId() + val projectRecord = + SurveyorDatabaseFactory.instance.projectDataSource.getRecord(projectId) + + val configRecord = + SurveyorDatabaseFactory.instance.getHeightTraverseConfigDataSource() + .getRecordByProjectId(getProjectId()) + + val isTwiceSetup = configRecord?.separateWay == SeparateWay.SET_UP_TWICE + + SurveyorDataBase.getInstance().withTransaction { + + val stationSetupIdList = + saveStationPoint(projectId, stationName, isTwiceSetup) + + val frontSetupId = saveFrontPoint(projectId, frontName) + + val relationStationId = if (isTwiceSetup) DateUtils.genRandomTimeId() else null + + for (stationPointId in stationSetupIdList) { + val stationRecord = + createStationRecordNoSurveyorPoints( + projectId, + projectRecord.getProjectType(), + relationStationId + ) + + stationRecord.items.add( + SurveyorPoint.newInstance( + stationPointId, + SurveyorPoint.TYPE_STATION + ) + ) + stationRecord.items.add( + SurveyorPoint.newInstance( + backPoint.getId(), + SurveyorPoint.TYPE_POINT + ) + ) + stationRecord.items.add( + SurveyorPoint.newInstance( + frontSetupId, + SurveyorPoint.TYPE_POINT + ) + ) + SurveyorDatabaseFactory.instance.surveyorStation.saveSync(stationRecord) + } + + withContext(Dispatchers.Main) { + finish() + } + } + + } + } + + override fun isCheckedJianXiePoint(): Boolean { + return mBinding.ilFrontTitle.cbJianXie.isChecked + } + + override fun isCheckedEndPoint(): Boolean { + return mBinding.ilFrontTitle.cbEnd.isChecked + } + + override fun getFrontPointHeight(): String { + return mBinding.ilFront.etHeight.text.toString().trim() + } + + override suspend fun getBackPoint(): PointRecord { + val projectId = getProjectId() + val routeId = getRouteId() + +// val stationLatest = +// SurveyorDatabaseFactory.instance.surveyorStation.getByProjectRouteLatest( +// projectId, +// routeId +// ) +// +// if (stationLatest?.items != null && stationLatest.items.size >= 3) { +// val surveyorPoint = stationLatest.items[2] +// return SurveyorDatabaseFactory.instance.pointDataSource.findByIdSync(surveyorPoint.originalPointId) +// } + + val stationList = + SurveyorDatabaseFactory.instance.surveyorStation.getByProjectRouteLastTwo( + projectId, + routeId + ) + val newestPointRecord = getNewestPointRecord(stationList, 2) + if (newestPointRecord != null) { + isFirstStation = false + return newestPointRecord + } + + isFirstStation = true + val routeRecord = SurveyorDatabaseFactory.instance.getRouteDataSource().getById(routeId) + return SurveyorDatabaseFactory.instance.pointDataSource.findByIdSync(routeRecord?.startPointId) + } + + override suspend fun getFrontPoint(): PointRecord { +// val projectId = getProjectId() + val routeId = getRouteId() + + var frontIndexNew = 1 + if (!isFirstStation) { + val index = RegExUtil.getIndexFromName(backPoint.getName()) + if (index != -1) { + frontIndexNew = index + 1 + } + } + + val routeRecord = SurveyorDatabaseFactory.instance.getRouteDataSource().getById(routeId) + + if (mBinding.ilFrontTitle.cbEnd.isChecked) { + return SurveyorDatabaseFactory.instance.pointDataSource.findByIdSync(routeRecord?.endPointId) + } else if (mBinding.ilFrontTitle.cbJianXie.isChecked) { +// val intervalPoint = +// SurveyorDatabaseFactory.instance.pointDataSource.findByPointTypeForHeightTraverseLatest( +// projectId, PointRecord.TYPE_HEIGHT_TRAVERSE_INTERVAL +// ) +// +// val intervalRecord = PointRecord() +// if (intervalPoint == null) { +// intervalRecord.name = "$prefixJianXie${1}" +// } else { +// val index = RegExUtil.getIndexFromName(intervalPoint.getName()) +// intervalRecord.name = "$prefixJianXie${index + 1}" +// } +// return intervalRecord + val intervalRecord = PointRecord() + intervalRecord.name = "$prefixJianXie${frontIndexNew}" + return intervalRecord + } else { +// val transferPoint = +// SurveyorDatabaseFactory.instance.pointDataSource.findByPointTypeForHeightTraverseLatest( +// projectId, PointRecord.TYPE_HEIGHT_TRAVERSE_TRANSFER +// ) +// +// val transferRecord = PointRecord() +// if (transferPoint == null) { +// transferRecord.name = "$prefixTransfer${1}" +// } else { +// val index = RegExUtil.getIndexFromName(transferPoint.getName()) +// transferRecord.name = "$prefixTransfer${index + 1}" +// } +// return transferRecord + val transferRecord = PointRecord() + transferRecord.name = "$prefixTransfer$frontIndexNew" + return transferRecord + } + } + + override suspend fun getStationPoint(): PointRecord { + val projectId = getProjectId() + val routeId = getRouteId() + val stationList = + SurveyorDatabaseFactory.instance.surveyorStation.getByProjectRouteLastTwo( + projectId, + routeId + ) + + var index = 1 + val newestPointRecord = getNewestPointRecord(stationList, 0) + if (newestPointRecord != null) { + val indexFromName = RegExUtil.getIndexFromName(newestPointRecord.name) + if (indexFromName != -1) { + index = indexFromName + 1 + } + } + val stationRecord = PointRecord() + stationRecord.name = "$prefixStation${index}" + return stationRecord +// val stationPoint = +// SurveyorDatabaseFactory.instance.pointDataSource.findByPointTypeForHeightTraverseLatest( +// projectId, PointRecord.TYPE_HEIGHT_TRAVERSE_STATION_TRANSFER +// ) +// val stationRecord = PointRecord() +// if (stationPoint == null) { +// stationRecord.name = "$prefixStation${1}" +// } else { +// val index = RegExUtil.getIndexFromName(stationPoint.getName()) +// stationRecord.name = "$prefixStation${index+1}" +// } +// return stationRecord + } + + + /** + * 存储测站点并返回测站id + * + * return 新建测站的ids + */ + @WorkerThread + private fun saveStationPoint( + projectId: String, + stationNameShow: String, + isTwiceSetup: Boolean + ): List { + + val stationHeight = mBinding.ilStation.etHeight.text.toString().trim() + + val index = RegExUtil.getIndexFromName(stationNameShow) + val stationIdList = mutableListOf() + + val pointTypeHeightTraverse = PointRecord.TYPE_HEIGHT_TRAVERSE_STATION_TRANSFER + + if (isTwiceSetup) { + stationIdList.add( + savePoint( + "$prefixStation${index}${Tools.getString(R.string._left)}", + pointTypeHeightTraverse, + projectId, + stationHeight + ) + ) + stationIdList.add( + savePoint( + "$prefixStation${index}${Tools.getString(R.string._right)}", + pointTypeHeightTraverse, + projectId, + stationHeight + ) + ) + } else { + stationIdList.add( + savePoint( + "$prefixStation${index}", + pointTypeHeightTraverse, + projectId, + stationHeight + ) + ) + } + + return stationIdList + } + + /** + * type 0 站点,1 后视 2 前视 + */ + @WorkerThread + private fun getNewestPointRecord( + stationList: List, + type: Int + ): PointRecord? { + var pointRecord: PointRecord? = null + for (item in stationList) { + if (item.items != null && item.items.size >= 3) { + val surveyorPoint = item.items[type] + val everyPointRecord = + SurveyorDatabaseFactory.instance.pointDataSource.findByIdSync(surveyorPoint.originalPointId) + val indexFromName = RegExUtil.getIndexFromName(everyPointRecord?.name ?: "") + if (indexFromName != -1) { + if (pointRecord == null) pointRecord = everyPointRecord + if (pointRecord != null) { + val indexLast = RegExUtil.getIndexFromName(pointRecord.name) + if (indexFromName > indexLast) { + pointRecord = everyPointRecord + } + } + } + } + } + return pointRecord + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/AbstractLineStationKnownUnknownKnownSetupFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/AbstractLineStationKnownUnknownKnownSetupFragment.java new file mode 100644 index 0000000..2826426 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/AbstractLineStationKnownUnknownKnownSetupFragment.java @@ -0,0 +1,247 @@ +package com.bingce.controlnetwork.fragment.station.line; + +import android.content.Intent; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; + +import androidx.activity.result.ActivityResultLauncher; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.model.BundleConstants; +import com.bingce.controlapphelper.model.PickPointResult; +import com.bingce.controlapphelper.model.StationDetailItem; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.adapter.stationdetail.StationCreateLineKnownUnknownKnownAdapter; +import com.bingce.controlnetwork.fragment.PickPointFragment; +import com.bingce.controlnetwork.ui.widget.recyclerview.SwipeDraggableRecyclerViewUtil; +import com.bingce.utils.IOnListGetCallback; + +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +import blankj.utilcode.util.ToastUtils; + +public abstract class AbstractLineStationKnownUnknownKnownSetupFragment extends AbstractLineStationSetupFragment + implements StationCreateLineKnownUnknownKnownAdapter.IOnSelectPointDelegate, + SwipeDraggableRecyclerViewUtil.IStationPointOperatorListener { + private static final String TYPE_KNOWN_POINT1 = "___known_points1"; + private static final String TYPE_UNKNOWN_POINT = "___unknown_points"; + private static final String TYPE_KNOWN_POINT2 = "___known_points2"; + private StationCreateLineKnownUnknownKnownAdapter stationCreateLineAttachAdapter; + private final ActivityResultLauncher activityResultLauncher = PickPointFragment.createActivityLauncher(this, (type, pickPointResult) -> { + if (pickPointResult.getSelectedIds().isEmpty() || pickPointResult.getSelectedNames().isEmpty()) { + return; + } + if (TYPE_KNOWN_POINT1.equals(type)) { + //检测数据是否正常 + if (pickPointResult.getSelectedIds().size() != pickPointResult.getSelectedIds().size() || + pickPointResult.getSelectedIds().size() != knownItemMinCount()) { + showKnownPointError(); + return; + } + stationCreateLineAttachAdapter.setKnownPoints1( + pickPointResult.getSelectedIds(), + pickPointResult.getSelectedNames()); + } else if (TYPE_UNKNOWN_POINT.equals(type)) { + //检测数据是否正常 + if (pickPointResult.getSelectedIds().size() != pickPointResult.getSelectedIds().size() || + pickPointResult.getSelectedIds().isEmpty()) { + showUnknownPointError(); + return; + } + stationCreateLineAttachAdapter.setUnknownPoints( + pickPointResult.getSelectedIds(), + pickPointResult.getSelectedNames()); + } else if (TYPE_KNOWN_POINT2.equals(type)) { + //检测数据是否正常 + if (pickPointResult.getSelectedIds().size() != pickPointResult.getSelectedIds().size() || + pickPointResult.getSelectedIds().size() != knownItemMinCount()) { + showKnownPointError(); + return; + } + stationCreateLineAttachAdapter.setKnownPoints2( + pickPointResult.getSelectedIds(), + pickPointResult.getSelectedNames()); + } + onItemChanged(); + }); + private MenuItem confirmItem; + + protected abstract int selectKnownPointTitle(); + + protected abstract int knownItemMinCount(); + + protected abstract void defaultItems(IOnListGetCallback callback); + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = super.onCreateView(inflater, container, savedInstanceState); + if (view == null) { + return null; + } + RecyclerView recyclerView = view.findViewById(R.id.recycler_view); + if (recyclerView != null) { + defaultItems(instance -> runOnUI(() -> { + stationCreateLineAttachAdapter = new StationCreateLineKnownUnknownKnownAdapter( + AbstractLineStationKnownUnknownKnownSetupFragment.this, instance); + recyclerView.setAdapter(stationCreateLineAttachAdapter); + SwipeDraggableRecyclerViewUtil.setup(stationCreateLineAttachAdapter, + recyclerView, + getChildFragmentManager(), + getViewLifecycleOwner(), + AbstractLineStationKnownUnknownKnownSetupFragment.this, + getContext()); + })); + } + setHasOptionsMenu(true); + return view; + } + + @Override + public void onSelectKnownPoint1(PickPointResult pickPointResult, ArrayList filters) { + if (getArguments() == null || getContext() == null) { + return; + } + String projectId = projectId();//getArguments().getString(BundleConstants.KEY_PROJECT_ID); + PickPointFragment.pickPoint( + getContext(), + TYPE_KNOWN_POINT1, + knownItemMinCount(), + getString(R.string.title_pick_known_point), + filters, + projectId, pickPointResult, activityResultLauncher); + } + + @Override + public void onSelectUnknownPoint(PickPointResult pickPointResult, ArrayList filters) { + if (getArguments() == null || getContext() == null) { + return; + } + String projectId = projectId();//getArguments().getString(BundleConstants.KEY_PROJECT_ID); + PickPointFragment.pickPoint( + getContext(), + TYPE_UNKNOWN_POINT, + -1, + getString(R.string.title_pick_unknown_point), + filters, + projectId, pickPointResult, activityResultLauncher); + } + + @Override + public void onSelectKnownPoint2(PickPointResult pickPointResult, ArrayList filters) { + if (getArguments() == null || getContext() == null) { + return; + } + String projectId = projectId();//getArguments().getString(BundleConstants.KEY_PROJECT_ID); + PickPointFragment.pickPoint( + getContext(), + TYPE_KNOWN_POINT2, + knownItemMinCount(), + getString(R.string.title_pick_known_point), + filters, + projectId, pickPointResult, activityResultLauncher); + } + + @Override + public void onItemRemoved(int adapterPosition) { + onItemChanged(); + } + + @Override + public void onItemDragCompleted() { + onItemChanged(); + } + + /** + * 测站数据发生了变化--测点被删除、测点被修改、测站被修改、测点被拖拽 + */ + protected void onItemChanged() { + //检测数据是否合法 + List knownItems1 = stationCreateLineAttachAdapter.knownItems1(); + List unknownItems = stationCreateLineAttachAdapter.unknownItems(); + List knownItems2 = stationCreateLineAttachAdapter.knownItems2(); + if (confirmItem != null) { + confirmItem.setEnabled(!(knownItems1.size() < knownItemMinCount() || + unknownItems.isEmpty() || + knownItems2.size() < knownItemMinCount())); + } + } + + private void showUnknownPointError() { + ToastUtils.showShort(R.string.tips_unknown_point_must_not_empty); + } + + protected abstract int knownPointCountError(); + + private void showKnownPointError() { + ToastUtils.showShort(knownPointCountError()); + } + + @Override + public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { + inflater.inflate(R.menu.menu_confirm, menu); + confirmItem = menu.findItem(R.id.menu_confirm); + if (confirmItem != null) { + confirmItem.setEnabled(false); + } + super.onCreateOptionsMenu(menu, inflater); + } + + @Override + public boolean onOptionsItemSelected(@NonNull @NotNull MenuItem item) { + if (R.id.menu_confirm == item.getItemId()) { + if (getArguments() == null) { + return super.onOptionsItemSelected(item); + } + requestLineName(string -> { + String projectId = projectId();//getArguments().getString(BundleConstants.KEY_PROJECT_ID); + String periodId = getArguments().getString(BundleConstants.KEY_PERIOD_ID); + if (getCurrentBatch() != null) { + projectId = getCurrentBatch().projectId; + periodId = getCurrentBatch().cycleId; + } + //1.收集所有点信息 + List knownItems1 = stationCreateLineAttachAdapter.knownItems1(); + List unknownItems = stationCreateLineAttachAdapter.unknownItems(); + List knownItems2 = stationCreateLineAttachAdapter.knownItems2(); + //2.建站 + setup(projectId, periodId, string, knownItems1, unknownItems, knownItems2, () -> { + if (getActivity() != null) { + getActivity().finish(); + } + }); + }); + } + return super.onOptionsItemSelected(item); + } + + @Override + public boolean cancelBack() { + List knownItems1 = stationCreateLineAttachAdapter.knownItems1(); + List unknownItems = stationCreateLineAttachAdapter.unknownItems(); + List knownItems2 = stationCreateLineAttachAdapter.knownItems2(); + if (isListEmpty(knownItems1) || + isListEmpty(unknownItems) || + isListEmpty(knownItems2)) { + return warningDataLosing(this); + } + return false; + } + + protected abstract void setup(String projectId, String periodId, + String lineName, + List knownItems1, + List unknownItems, + List knownItems2, + Runnable callback); +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/AbstractLineStationKnownUnknownSetupFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/AbstractLineStationKnownUnknownSetupFragment.java new file mode 100644 index 0000000..2543acb --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/AbstractLineStationKnownUnknownSetupFragment.java @@ -0,0 +1,249 @@ +package com.bingce.controlnetwork.fragment.station.line; + +import android.content.Intent; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; + +import androidx.activity.result.ActivityResultLauncher; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.model.BundleConstants; +import com.bingce.controlapphelper.model.PickPointResult; +import com.bingce.controlapphelper.model.StationDetailItem; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.adapter.stationdetail.StationCreateLineSingleAdapter; +import com.bingce.controlnetwork.fragment.PickPointFragment; +import com.bingce.controlnetwork.ui.widget.recyclerview.SwipeDraggableRecyclerViewUtil; +import com.bingce.utils.IOnListGetCallback; + +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +import blankj.utilcode.util.ToastUtils; + +public abstract class AbstractLineStationKnownUnknownSetupFragment extends AbstractLineStationSetupFragment + implements StationCreateLineSingleAdapter.IOnSelectPointDelegate, + SwipeDraggableRecyclerViewUtil.IStationPointOperatorListener { + private static final String TYPE_KNOWN_POINT = "___known_points"; + private static final String TYPE_UNKNOWN_POINT = "___unknown_points"; + private StationCreateLineSingleAdapter stationCreateLineSingleAdapter; + private final ActivityResultLauncher activityResultLauncher = PickPointFragment.createActivityLauncher(this, (type, pickPointResult) -> { + if (pickPointResult.getSelectedIds().isEmpty() || pickPointResult.getSelectedNames().isEmpty()) { + return; + } + if (TYPE_KNOWN_POINT.equals(type)) { + //检测数据是否正常 + if (pickPointResult.getSelectedIds().size() != pickPointResult.getSelectedIds().size() || + pickPointResult.getSelectedIds().size() < knownItemMinCount()) { + showKnownPointError(); + return; + } + stationCreateLineSingleAdapter.setKnownPoints( + pickPointResult.getSelectedIds(), + pickPointResult.getSelectedNames()); + } else if (TYPE_UNKNOWN_POINT.equals(type)) { + //检测数据是否正常 + if (pickPointResult.getSelectedIds().size() != pickPointResult.getSelectedIds().size() || + pickPointResult.getSelectedIds().size() < unknownItemMinCount()) { + showUnknownPointError(); + return; + } + stationCreateLineSingleAdapter.setUnknownPoints( + pickPointResult.getSelectedIds(), + pickPointResult.getSelectedNames()); + } + onItemChanged(); + }); + private MenuItem confirmItem; + + protected abstract int knownItemMinCount(); + + protected abstract int knownGroupTitle(); + + protected abstract int knownPointCountError(); + + protected abstract int unknownItemMinCount(); + + protected abstract int unknownGroupTitle(); + + protected abstract int unknownPointCountError(); + + protected abstract void defaultItems(IOnListGetCallback callback); + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = super.onCreateView(inflater, container, savedInstanceState); + if (view == null) { + return null; + } + RecyclerView recyclerView = view.findViewById(R.id.recycler_view); + if (recyclerView != null) { + defaultItems(instance -> runOnUI(() -> { + stationCreateLineSingleAdapter = new StationCreateLineSingleAdapter( + AbstractLineStationKnownUnknownSetupFragment.this, instance); + recyclerView.setAdapter(stationCreateLineSingleAdapter); + SwipeDraggableRecyclerViewUtil.setup(stationCreateLineSingleAdapter, + recyclerView, + getChildFragmentManager(), + getViewLifecycleOwner(), + AbstractLineStationKnownUnknownSetupFragment.this, + getContext()); + })); + } + setHasOptionsMenu(true); + return view; + } + + @Override + public void onSelectKnownPoint(PickPointResult pickPointResult, ArrayList filters) { + if (getArguments() == null || getContext() == null) { + return; + } + String projectId = projectId();//getArguments().getString(BundleConstants.KEY_PROJECT_ID); + PickPointFragment.pickPoint( + getContext(), + TYPE_KNOWN_POINT, + knownItemMinCount(), + getString(R.string.title_pick_known_point), + filters, + projectId, pickPointResult, activityResultLauncher); + } + + @Override + public void onSelectUnknownPoint(PickPointResult pickPointResult, ArrayList filters) { + if (getArguments() == null || getContext() == null) { + return; + } + String projectId = projectId();//getArguments().getString(BundleConstants.KEY_PROJECT_ID); + PickPointFragment.pickPoint( + getContext(), + TYPE_UNKNOWN_POINT, + -1, + getString(R.string.title_pick_unknown_point), + filters, + projectId, pickPointResult, activityResultLauncher); + } + + @Override + public void onItemRemoved(int adapterPosition) { + onItemChanged(); + } + + @Override + public void onItemDragCompleted() { + onItemChanged(); + } + + /** + * 测站数据发生了变化--测点被删除、测点被修改、测站被修改、测点被拖拽 + */ + protected void onItemChanged() { + //检测数据是否合法 + List knownItems = knownItems(); + List unknownItems = unknownItems(); + if (confirmItem != null) { + confirmItem.setEnabled(!(knownItems.size() < knownItemMinCount() || unknownItems.isEmpty())); + } + } + + private void showUnknownPointError() { + ToastUtils.showShort(unknownPointCountError()); + } + + private void showKnownPointError() { + ToastUtils.showShort(knownPointCountError()); + } + + @Override + public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { + inflater.inflate(R.menu.menu_confirm, menu); + confirmItem = menu.findItem(R.id.menu_confirm); + if (confirmItem != null) { + confirmItem.setEnabled(false); + } + super.onCreateOptionsMenu(menu, inflater); + } + + @Override + public boolean onOptionsItemSelected(@NonNull @NotNull MenuItem item) { + if (R.id.menu_confirm == item.getItemId()) { + if (getArguments() == null) { + return super.onOptionsItemSelected(item); + } + //1.收集所有点信息 + List knownItems = knownItems(); + List unknownItems = unknownItems(); + //2.循环创建测站 + if (knownItems.size() != knownItemMinCount()) { + //当已知点不满足最少点的个数时提示 + showKnownPointError(); + return super.onOptionsItemSelected(item); + } + if (unknownItems.size() < unknownItemMinCount()) { + //当未知点不满足最少点的个数时提示 + showUnknownPointError(); + return super.onOptionsItemSelected(item); + } + //设置导线的名称(弹框设置名称) + requestLineName(lineName -> { + String projectId = projectId();//getArguments().getString(BundleConstants.KEY_PROJECT_ID); + String periodId = getArguments().getString(BundleConstants.KEY_PERIOD_ID); + if (getCurrentBatch() != null) { + projectId = getCurrentBatch().projectId; + periodId = getCurrentBatch().cycleId; + } + setup(projectId, periodId, lineName, knownItems, unknownItems, () -> { + if (getActivity() != null) { + getActivity().finish(); + } + }); + }); + } + return super.onOptionsItemSelected(item); + } + + @Override + public boolean cancelBack() { + List knownItems = knownItems(); + List unknownItems = unknownItems(); + if (isListEmpty(knownItems) || + isListEmpty(unknownItems)) { + return warningDataLosing(this); + } + return false; + } + + /** + * 设置导线 + * + * @param projectId + * @param periodId + * @param lineName + * @param knownItems + * @param unknownItems + * @param runnable + */ + protected abstract void setup(String projectId, String periodId, + String lineName, + List knownItems, + List unknownItems, + Runnable runnable); + + protected List knownItems() { + return stationCreateLineSingleAdapter.knownItems(); + } + + protected List unknownItems() { + return stationCreateLineSingleAdapter.unknownItems(); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/AbstractLineStationSetupFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/AbstractLineStationSetupFragment.java new file mode 100644 index 0000000..d41096f --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/AbstractLineStationSetupFragment.java @@ -0,0 +1,109 @@ +package com.bingce.controlnetwork.fragment.station.line; + +import android.os.Bundle; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.line.LineRecord; +import com.bingce.controlapphelper.datasource.database.project.ProjectRecord; +import com.bingce.controlapphelper.model.BundleConstants; +import com.bingce.controlapphelper.model.StationDetailItem; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.fragment.StringInputFragment; +import com.bingce.controlnetwork.fragment.station.AbstractStationFragment; +import com.bingce.controlnetwork.newui.widget.switchtext.SwitchWithText; +import com.bingce.controlnetwork.util.SurveyorStationUtil; +import com.bingce.utils.IOnListGetCallback; +import com.bingce.utils.ThreadPoolUtil; + +import org.jetbrains.annotations.NotNull; + +public abstract class AbstractLineStationSetupFragment extends AbstractStationFragment { + private LineRecord currentBatch; + private ProjectRecord projectRecord; + + @Override + protected int layoutRes() { + return R.layout.fragment_line_surveyor_station_setup_layout; + } + + @Override + protected String duplicateStationError(String duplicateStationName) { + return Tools.getString(R.string.station_already_exist_same_name, duplicateStationName); + } + + @Override + public void onViewCreated(@NonNull @NotNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + setLeftRightEnable(initLeftRightMeasure()); + //读取projectRecord + ThreadPoolUtil.execute(() -> { + if (getArguments() == null) { + return; + } + String projectId = getArguments().getString(BundleConstants.KEY_PROJECT_ID); + projectRecord = + SurveyorDatabaseFactory + .instance + .getProjectDataSource() + .getRecord(projectId); + }); + } + + private void setLeftRightEnable(boolean isEnable) { + //显示左右角开关 + View view = getView(); + if (view != null) { + SwitchWithText switchCompat = view.findViewById(R.id.left_right_switch); + if (switchCompat != null) { + switchCompat.setEnabled(isEnable); + } + } + } + + + protected String projectId() { + return projectRecord == null ? null : projectRecord.getId(); + } + + protected ProjectRecord currentProject() { + return projectRecord; + } + + protected void loadBatchRecord(String batchId, IOnListGetCallback callback) { + SurveyorStationUtil.getBatchItemList(batchId, lineRecord -> { + if (lineRecord == null) { + return; + } + callback.onGet(lineRecord.items); + currentBatch = lineRecord; + }); + } + + private String lineName() { + if (currentBatch != null) { + return currentBatch.name; + } + return defaultLineName(); + } + + protected LineRecord getCurrentBatch() { + return currentBatch; + } + + protected abstract boolean initLeftRightMeasure(); + + protected abstract String defaultLineName(); + + final protected void requestLineName(StringInputFragment.IInputCallback callback) { + StringInputFragment.input(getChildFragmentManager(), + getString(R.string.tips_please_input_line_name), + lineName(), + getViewLifecycleOwner(), + callback); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/AbstractLineStationWellDoubleGroundSetupFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/AbstractLineStationWellDoubleGroundSetupFragment.java new file mode 100644 index 0000000..9c6f0dd --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/AbstractLineStationWellDoubleGroundSetupFragment.java @@ -0,0 +1,333 @@ +package com.bingce.controlnetwork.fragment.station.line; + +import android.content.Intent; +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; + +import androidx.activity.result.ActivityResultLauncher; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.datasource.database.line.LineRecord; +import com.bingce.controlapphelper.model.BundleConstants; +import com.bingce.controlapphelper.model.PickPointResult; +import com.bingce.controlapphelper.model.StationDetailItem; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.adapter.stationdetail.StationCreateLineWellDoubleGroundAdapter; +import com.bingce.controlnetwork.fragment.PickPointFragment; +import com.bingce.controlnetwork.ui.widget.recyclerview.SwipeDraggableRecyclerViewUtil; +import com.bingce.controlnetwork.util.SurveyorStationUtil; +import com.bingce.utils.IOnListGetCallback; + +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +import blankj.utilcode.util.ToastUtils; + +/** + * 二井定向地上父类 + */ +public abstract class AbstractLineStationWellDoubleGroundSetupFragment extends AbstractLineStationSetupFragment + implements StationCreateLineWellDoubleGroundAdapter.IOnSelectPointDelegate, + SwipeDraggableRecyclerViewUtil.IStationPointOperatorListener { + + public static final String LINE_NAME = Tools.getString(R.string.erjing_directional_above_ground); + + private MenuItem confirmItem; + //选择到的点 + private List groundLinkLeftDataList; + private List groundLinkMiddleDataList; + private List groundLinkRightDataList; + private List groundSideADataList; + private List groundSideBDataList; + + private StationCreateLineWellDoubleGroundAdapter mAdapter; + + private final Handler handler = new Handler(Looper.getMainLooper()); + + private final ActivityResultLauncher activityResultLauncher = PickPointFragment.createActivityLauncher(this, (type, pickPointResult) -> { + if (pickPointResult.getSelectedIds().isEmpty() || pickPointResult.getSelectedNames().isEmpty()) { + return; + } + if (StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_LEFT.equals(type)) { + //检测数据是否正常 + if (pickPointResult.getSelectedIds().size() < groundLinkLeftMinCount()) { + showErrorMsg(Tools.getString(R.string.well_a_ground_connection_hint)); + return; + } + mAdapter.setGroundLinkLeftPoints(pickPointResult); + } else if (StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_A.equals(type)) { + //检测数据是否正常 + if (pickPointResult.getSelectedIds().size() < groundSideAMinCount()) { + showErrorMsg(Tools.getString(R.string.well_a_surface_near_well_hint)); + return; + } + mAdapter.setGroundSideAPoints(pickPointResult); + } else if (StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_B.equals(type)) { + //检测数据是否正常 + if (pickPointResult.getSelectedIds().size() < groundSideBMinCount()) { + showErrorMsg(Tools.getString(R.string.well_b_surface_near_well_hint)); + return; + } + mAdapter.setGroundSideBPoints(pickPointResult); + } else if (StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_RIGHT.equals(type)) { + if (pickPointResult.getSelectedIds().size() < groundLinkRightMinCount()) { + showErrorMsg(Tools.getString(R.string.well_b_ground_connection_hint)); + return; + } + mAdapter.setGroundLinkRightPoints(pickPointResult); + } else if (StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_MIDDLE.equals(type)) { + mAdapter.setGroundLinkMiddlePoints(pickPointResult); + } + onItemChanged(); + }); + + protected abstract int groundLinkLeftMinCount(); + + protected abstract int groundSideAMinCount(); + + protected abstract int groundLinkMiddleMinCount(); + + protected abstract int groundSideBMinCount(); + + protected abstract int groundLinkRightMinCount(); + + protected abstract void defaultItems(IOnListGetCallback callback); + + protected List getAdapterDataList() { + List items = null; + if (mAdapter != null) { + items = mAdapter.getItems(); + } + return items; + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = super.onCreateView(inflater, container, savedInstanceState); + if (view == null) { + return null; + } + RecyclerView recyclerView = view.findViewById(R.id.recycler_view); + if (recyclerView != null) { + defaultItems(stationDetailItemList -> runOnUI(() -> { + mAdapter = new StationCreateLineWellDoubleGroundAdapter( + AbstractLineStationWellDoubleGroundSetupFragment.this, stationDetailItemList); + + recyclerView.setAdapter(mAdapter); + SwipeDraggableRecyclerViewUtil.setup(mAdapter, + recyclerView, + getChildFragmentManager(), + getViewLifecycleOwner(), + AbstractLineStationWellDoubleGroundSetupFragment.this, + getContext()); + + refreshFiveDataList(); + + })); + } + setHasOptionsMenu(true); + return view; + } + + @Override + public void onViewCreated(@NonNull @NotNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); +// initAutoCloseView(); + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (handler != null) + handler.removeCallbacksAndMessages(null); + } + + protected void goSelectPoint(String type, int maxCount, String title, List filters, PickPointResult pickPointResult) { + if (getArguments() == null || getContext() == null) { + return; + } + String projectId = projectId();//getArguments().getString(BundleConstants.KEY_PROJECT_ID); + PickPointFragment.pickPoint( + getContext(), + type, + maxCount, + title, + filters, + projectId, pickPointResult, activityResultLauncher); + } + + @Override + public void onSelectGroundLinkLeft(PickPointResult pickPointResult, List filters) { + goSelectPoint(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_LEFT, + groundLinkLeftMinCount() + 1, Tools.getString(R.string.well_a_ground_connection_direction_point), + filters, pickPointResult); + } + + @Override + public void onSelectGroundLinkRight(PickPointResult pickPointResult, List filters) { + goSelectPoint(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_RIGHT, + groundLinkRightMinCount() + 1, Tools.getString(R.string.well_b_ground_connection_direction_point), + filters, pickPointResult); + } + + @Override + public void onSelectGroundLinkMiddle(PickPointResult pickPointResult, List filters) { + goSelectPoint(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_MIDDLE, + Integer.MAX_VALUE, Tools.getString(R.string.ground_connection_point), filters, pickPointResult); + } + + @Override + public void onSelectGroundSideA(PickPointResult pickPointResult, List filters) { + goSelectPoint(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_A, + 1, Tools.getString(R.string.well_a_surface_near_well_point), filters, pickPointResult); + } + + @Override + public void onSelectGroundSideB(PickPointResult pickPointResult, List filters) { + goSelectPoint(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_B, + 1, Tools.getString(R.string.well_b_surface_near_well_point), filters, pickPointResult); + } + + @Override + public void onSelectOnlyMeasureHorAngle(boolean measureHorAngle) { + LineRecord currentBatch = getCurrentBatch(); + SurveyorStationUtil.updateLineRecord(currentBatch); + SurveyorStationUtil.updateStationPointsMeasureHorAag(currentBatch); + } + + @Override + public void onItemRemoved(int adapterPosition) { + mAdapter.removeItemForLastSelect(adapterPosition); + onItemChanged(); + } + + @Override + public void onItemDragCompleted() { + onItemChanged(); + } + + /** + * 测站数据发生了变化--测点被删除、测点被修改、测站被修改、测点被拖拽 + */ + private void onItemChanged() { + handler.postDelayed(() -> { + refreshFiveDataList(); + //检测数据是否合法 + if (confirmItem != null) { + confirmItem.setEnabled(!(groundLinkLeftDataList.size() < groundLinkLeftMinCount() || + groundLinkMiddleDataList.size() < groundLinkMiddleMinCount() || + groundLinkRightDataList.size() < groundLinkRightMinCount() || + groundSideADataList.size() < groundSideAMinCount() || + groundSideBDataList.size() < groundSideBMinCount() + )); + } + }, 80); + } + + private void refreshFiveDataList() { + groundLinkLeftDataList = mAdapter.getPointsFromType(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_LEFT + StationDetailItem._DATA); + groundLinkMiddleDataList = mAdapter.getPointsFromType(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_MIDDLE + StationDetailItem._DATA); + groundLinkRightDataList = mAdapter.getPointsFromType(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_RIGHT + StationDetailItem._DATA); + groundSideADataList = mAdapter.getPointsFromType(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_A + StationDetailItem._DATA); + groundSideBDataList = mAdapter.getPointsFromType(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_B + StationDetailItem._DATA); + } + + protected void showErrorMsgForWell(String type) { + switch (type) { + case StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_LEFT: + showErrorMsg(Tools.getString(R.string.well_a_ground_connection_hint)); + break; + case StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_MIDDLE: + //中间点是可选 + break; + case StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_RIGHT: + showErrorMsg(Tools.getString(R.string.well_b_ground_connection_hint)); + break; + case StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_A: + showErrorMsg(Tools.getString(R.string.well_a_surface_near_well_hint)); + break; + case StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_B: + showErrorMsg(Tools.getString(R.string.well_b_surface_near_well_hint)); + break; + default: + break; + } + } + + private void showErrorMsg(String msg) { + ToastUtils.showShort(msg); + } + + @Override + public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { + inflater.inflate(R.menu.menu_confirm, menu); + confirmItem = menu.findItem(R.id.menu_confirm); + if (confirmItem != null) { + confirmItem.setEnabled(false); + } + super.onCreateOptionsMenu(menu, inflater); + } + + @Override + public boolean onOptionsItemSelected(@NonNull @NotNull MenuItem item) { + // TODO: 2022/6/15 + if (R.id.menu_confirm == item.getItemId()) { + if (getArguments() == null) { + return super.onOptionsItemSelected(item); + } +// //设置导线的弹框 +// requestLineName(string -> { +// //建站 +// }); + + String projectId = projectId();//getArguments().getString(BundleConstants.KEY_PROJECT_ID); + String periodId = getArguments().getString(BundleConstants.KEY_PERIOD_ID); + if (getCurrentBatch() != null) { + projectId = getCurrentBatch().projectId; + periodId = getCurrentBatch().cycleId; + } + setup(projectId, periodId, LINE_NAME, groundLinkLeftDataList, groundLinkMiddleDataList, groundLinkRightDataList, groundSideBDataList, groundSideADataList, () -> { + if (getActivity() != null) { + getActivity().finish(); + } + }); + } + return super.onOptionsItemSelected(item); + } + + @Override + public boolean cancelBack() { + // TODO: 2022/6/15 +// List knownItems1 = mAdapter.getGroundLinkPoints(); +// List unknownItems = mAdapter.unknownItems(); +// List knownItems2 = mAdapter.knownItems2(); +// if (isListEmpty(knownItems1) || +// isListEmpty(unknownItems) || +// isListEmpty(knownItems2)) { +// return warningDataLosing(this); +// } + return false; + } + + protected abstract void setup(String projectId, String periodId, + String lineName, + List groundLinkLeftDataList, + List groundLinkMiddleDataList, + List groundLinkRightDataList, + List groundSideBDataList, + List groundSideADataList, + Runnable callback); + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/AbstractLineStationWellDoubleUnderGroundSetupFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/AbstractLineStationWellDoubleUnderGroundSetupFragment.java new file mode 100644 index 0000000..cf33e4c --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/AbstractLineStationWellDoubleUnderGroundSetupFragment.java @@ -0,0 +1,422 @@ +package com.bingce.controlnetwork.fragment.station.line; + +import android.content.Intent; +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; + +import androidx.activity.result.ActivityResultLauncher; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.datasource.database.line.LineRecord; +import com.bingce.controlapphelper.model.BundleConstants; +import com.bingce.controlapphelper.model.PickPointResult; +import com.bingce.controlapphelper.model.StationDetailItem; +import com.bingce.controlapphelper.util.RegExUtil; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.adapter.stationdetail.StationCreateLineWellDoubleUnderGroundAdapter; +import com.bingce.controlnetwork.fragment.PickPointFragment; +import com.bingce.controlnetwork.ui.widget.recyclerview.SwipeDraggableRecyclerViewUtil; +import com.bingce.controlnetwork.util.SurveyorStationUtil; +import com.bingce.utils.IOnListGetCallback; + +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +import blankj.utilcode.util.ToastUtils; + +/** + * 一井定向的父类 + */ +public abstract class AbstractLineStationWellDoubleUnderGroundSetupFragment extends AbstractLineStationSetupFragment + implements StationCreateLineWellDoubleUnderGroundAdapter.IOnSelectPointDelegate, + SwipeDraggableRecyclerViewUtil.IStationPointOperatorListener { + + public static final String LINE_NAME = Tools.getString(R.string.second_well_directional_underground); + + private final Handler handler = new Handler(Looper.getMainLooper()); + + private MenuItem confirmItem; + //选择到的点 + private List groundLinkLeftDataList; + private List groundSideADataList; + private List steelADataList; + private List underGroundLinkDataList; + private List steeBDataList; + private List groundSideBDataList; + private List groundLinkRightDataList; + + private StationCreateLineWellDoubleUnderGroundAdapter mAdapter; + + private final ActivityResultLauncher activityResultLauncher = PickPointFragment.createActivityLauncher(this, (type, pickPointResult) -> { + if (pickPointResult.getSelectedIds().isEmpty() || pickPointResult.getSelectedNames().isEmpty()) { + return; + } + if (StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_LEFT.equals(type)) { + //检测数据是否正常 + if (pickPointResult.getSelectedIds().size() < groundLinkLeftMinCount()) { + showErrorMsg(Tools.getString(R.string.well_a_ground_connection_hint)); + return; + } + mAdapter.setGroundLinkLeftPoints(pickPointResult); + } else if (StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_A.equals(type)) { + //检测数据是否正常 + if (pickPointResult.getSelectedIds().size() < groundSideAMinCount()) { + showErrorMsg(Tools.getString(R.string.well_a_surface_near_well_hint)); + return; + } + mAdapter.setGroundSideAPoints(pickPointResult); + } else if (StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_B.equals(type)) { + //检测数据是否正常 + if (pickPointResult.getSelectedIds().size() < groundSideBMinCount()) { + showErrorMsg(Tools.getString(R.string.well_b_surface_near_well_hint)); + return; + } + mAdapter.setGroundSideBPoints(pickPointResult); + } else if (StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_RIGHT.equals(type)) { + if (pickPointResult.getSelectedIds().size() < groundLinkRightMinCount()) { + showErrorMsg(Tools.getString(R.string.well_b_ground_connection_hint)); + return; + } + mAdapter.setGroundLinkRightPoints(pickPointResult); + } else if (StationDetailItem.TYPE_WELL_DOUBLE_STEEL_A.equals(type)) { + //检测数据是否正常 + if (pickPointResult.getSelectedIds().size() < groundSideAMinCount()) { + showErrorMsg(Tools.getString(R.string.please_select_well_a_wire)); + return; + } + mAdapter.setSteelAPoints(pickPointResult); + } else if (StationDetailItem.TYPE_WELL_DOUBLE_STEEL_B.equals(type)) { + //检测数据是否正常 + if (pickPointResult.getSelectedIds().size() < groundSideBMinCount()) { + showErrorMsg(Tools.getString(R.string.please_select_well_b_wire)); + return; + } + mAdapter.setSteelBPoints(pickPointResult); + } else if (StationDetailItem.TYPE_WELL_DOUBLE_UNDERGROUND_LINK.equals(type)) { + //检测数据是否正常 + if (pickPointResult.getSelectedIds().size() < underGroundLinkMinCount()) { + showErrorMsg(Tools.getString(R.string.underground_connection_point_min_hint)); + return; + } + mAdapter.setUnderGroundLinkPoints(pickPointResult); + } + onItemChanged(); + }); + + protected abstract int groundLinkLeftMinCount(); + + protected abstract int groundSideAMinCount(); + + protected abstract int steelAMinCount(); + + protected abstract int underGroundLinkMinCount(); + + protected abstract int steelBMinCount(); + + protected abstract int groundSideBMinCount(); + + protected abstract int groundLinkRightMinCount(); + + protected abstract void defaultItems(IOnListGetCallback callback); + + protected List getAdapterDataList() { + List items = null; + if (mAdapter != null) { + items = mAdapter.getItems(); + } + return items; + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = super.onCreateView(inflater, container, savedInstanceState); + if (view == null) { + return null; + } + RecyclerView recyclerView = view.findViewById(R.id.recycler_view); + if (recyclerView != null) { + defaultItems(stationDetailItemList -> runOnUI(() -> { + mAdapter = new StationCreateLineWellDoubleUnderGroundAdapter( + AbstractLineStationWellDoubleUnderGroundSetupFragment.this, stationDetailItemList); + + recyclerView.setAdapter(mAdapter); + SwipeDraggableRecyclerViewUtil.setup(mAdapter, + recyclerView, + getChildFragmentManager(), + getViewLifecycleOwner(), + AbstractLineStationWellDoubleUnderGroundSetupFragment.this, + getContext()); + + refreshFiveDataList(); + + })); + } + setHasOptionsMenu(true); + return view; + } + + @Override + public void onViewCreated(@NonNull @NotNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); +// initAutoCloseView(); + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (handler != null) + handler.removeCallbacksAndMessages(null); + } + + protected void goSelectPoint(String type, int maxCount, String title, List filters, PickPointResult pickPointResult) { + if (getArguments() == null || getContext() == null) { + return; + } + String projectId = projectId();//getArguments().getString(BundleConstants.KEY_PROJECT_ID); + PickPointFragment.pickPoint( + getContext(), + type, + maxCount, + title, + filters, + projectId, pickPointResult, activityResultLauncher); + } + + @Override + public void onSelectGroundLinkLeft(PickPointResult pickPointResult, List filters) { + goSelectPoint(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_LEFT, + groundLinkLeftMinCount() + 1, Tools.getString(R.string.well_a_surface_connection_point), + filters, pickPointResult); + } + + @Override + public void onSelectGroundLinkRight(PickPointResult pickPointResult, List filters) { + goSelectPoint(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_RIGHT, + groundLinkRightMinCount() + 1, Tools.getString(R.string.well_b_surface_connection_point), + filters, pickPointResult); + } + + @Override + public void onSelectGroundSideA(PickPointResult pickPointResult, List filters) { + goSelectPoint(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_A, + 1, Tools.getString(R.string.well_a_surface_near_well_point), filters, pickPointResult); + } + + @Override + public void onSelectGroundSideB(PickPointResult pickPointResult, List filters) { + goSelectPoint(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_B, + 1, Tools.getString(R.string.well_b_surface_near_well_point), filters, pickPointResult); + } + + @Override + public void onSelectSteelA(PickPointResult pickPointResult, List filters) { +// goSelectPoint(StationDetailItem.TYPE_WELL_DOUBLE_STEEL_A, +// steelAMinCount() + 1, "A井钢丝", filters, pickPointResult); + addSteelOnCurrentPage(StationDetailItem.TYPE_WELL_DOUBLE_STEEL_A, steelAMinCount() + 1); + } + + @Override + public void onSelectSteelB(PickPointResult pickPointResult, List filters) { +// goSelectPoint(StationDetailItem.TYPE_WELL_DOUBLE_STEEL_B, +// steelBMinCount() + 1, "B井钢丝", filters, pickPointResult); + addSteelOnCurrentPage(StationDetailItem.TYPE_WELL_DOUBLE_STEEL_B, steelBMinCount() + 1); + } + + @Override + public void onSelectUnderGroundLink(PickPointResult pickPointResult, List filters) { + goSelectPoint(StationDetailItem.TYPE_WELL_DOUBLE_UNDERGROUND_LINK, + Integer.MAX_VALUE, Tools.getString(R.string.underground_connection_point), filters, pickPointResult); + } + + @Override + public void onSelectOnlyMeasureHorAngle(boolean measureHorAngle) { + LineRecord currentBatch = getCurrentBatch(); + SurveyorStationUtil.updateLineRecord(currentBatch); + SurveyorStationUtil.updateStationPointsMeasureHorAag(currentBatch); + } + + + private void addSteelOnCurrentPage(String groupType, int steelMaxCount) { + List pointsFromType = mAdapter.getPointsFromType(groupType + StationDetailItem._DATA); + PickPointResult lastSteelPickPoint = PickPointResult.create(); + int newName = 1; + if (pointsFromType != null && !pointsFromType.isEmpty()) { + PickPointResult.initPicPointResultData(lastSteelPickPoint, pointsFromType); + //获取新的钢丝的索引 + StationDetailItem stationDetailItem = pointsFromType.get(pointsFromType.size() - 1); + String num = RegExUtil.findNum(stationDetailItem.getName()); + assert num != null; + newName = Integer.parseInt(num) + 1; + } + if (lastSteelPickPoint.getSelectedIds().size() >= steelMaxCount) { + ToastUtils.showShort(R.string.steel_max_hint, steelMaxCount); + return; + } + if (StationDetailItem.TYPE_WELL_DOUBLE_STEEL_A.equals(groupType)) { + PickPointResult.createPointResultNewData(lastSteelPickPoint, Tools.getString(R.string.wire_a) + newName); + mAdapter.setSteelAPoints(lastSteelPickPoint); + } else if (StationDetailItem.TYPE_WELL_DOUBLE_STEEL_B.equals(groupType)) { + PickPointResult.createPointResultNewData(lastSteelPickPoint, Tools.getString(R.string.wire_b) + newName); + mAdapter.setSteelBPoints(lastSteelPickPoint); + } + onItemChanged(); + } + + + @Override + public void onItemRemoved(int adapterPosition) { + mAdapter.removeItemForLastSelect(adapterPosition); + onItemChanged(); + } + + @Override + public void onItemDragCompleted() { + onItemChanged(); + } + + /** + * 测站数据发生了变化--测点被删除、测点被修改、测站被修改、测点被拖拽 + */ + private void onItemChanged() { + handler.postDelayed(() -> { + refreshFiveDataList(); + //检测数据是否合法 + if (confirmItem != null) { + confirmItem.setEnabled(!(groundLinkLeftDataList.size() < groundLinkLeftMinCount() || + groundSideADataList.size() < groundSideAMinCount() || + steelADataList.size() < steelAMinCount() || + underGroundLinkDataList.size() < underGroundLinkMinCount() || + steeBDataList.size() < steelBMinCount() || + groundSideBDataList.size() < groundSideBMinCount() || + groundLinkRightDataList.size() < groundLinkRightMinCount() + )); + } + }, 80); + } + + private void refreshFiveDataList() { + String _data = StationDetailItem._DATA; + groundLinkLeftDataList = mAdapter.getPointsFromType(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_LEFT + _data); + groundSideADataList = mAdapter.getPointsFromType(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_A + _data); + steelADataList = mAdapter.getPointsFromType(StationDetailItem.TYPE_WELL_DOUBLE_STEEL_A + _data); + underGroundLinkDataList = mAdapter.getPointsFromType(StationDetailItem.TYPE_WELL_DOUBLE_UNDERGROUND_LINK + _data); + steeBDataList = mAdapter.getPointsFromType(StationDetailItem.TYPE_WELL_DOUBLE_STEEL_B + _data); + groundSideBDataList = mAdapter.getPointsFromType(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_B + _data); + groundLinkRightDataList = mAdapter.getPointsFromType(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_RIGHT + _data); + } + + protected void showErrorMsgForWell(String type) { + switch (type) { + case StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_LEFT: + showErrorMsg(Tools.getString(R.string.well_a_ground_connection_hint)); + break; + case StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_RIGHT: + showErrorMsg(Tools.getString(R.string.well_b_ground_connection_hint)); + break; + case StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_A: + showErrorMsg(Tools.getString(R.string.well_a_surface_near_well_hint)); + break; + case StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_B: + showErrorMsg(Tools.getString(R.string.well_b_surface_near_well_hint)); + break; + case StationDetailItem.TYPE_WELL_DOUBLE_STEEL_A: + showErrorMsg(Tools.getString(R.string.please_select_well_a_wire)); + break; + case StationDetailItem.TYPE_WELL_DOUBLE_STEEL_B: + showErrorMsg(Tools.getString(R.string.please_select_well_b_wire)); + break; + case StationDetailItem.TYPE_WELL_DOUBLE_UNDERGROUND_LINK: + showErrorMsg(Tools.getString(R.string.please_select_an_underground_connection_point)); + break; + default: + break; + } + } + + private void showErrorMsg(String msg) { + ToastUtils.showShort(msg); + } + + @Override + public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { + inflater.inflate(R.menu.menu_confirm, menu); + confirmItem = menu.findItem(R.id.menu_confirm); + if (confirmItem != null) { + confirmItem.setEnabled(false); + } + super.onCreateOptionsMenu(menu, inflater); + } + + @Override + public boolean onOptionsItemSelected(@NonNull @NotNull MenuItem item) { + // TODO: 2022/6/15 + if (R.id.menu_confirm == item.getItemId()) { + if (getArguments() == null) { + return super.onOptionsItemSelected(item); + } +// //设置导线的弹框 +// requestLineName(string -> { +// //建站 +// }); + + String projectId = projectId();//getArguments().getString(BundleConstants.KEY_PROJECT_ID); + String periodId = getArguments().getString(BundleConstants.KEY_PERIOD_ID); + if (getCurrentBatch() != null) { + projectId = getCurrentBatch().projectId; + periodId = getCurrentBatch().cycleId; + } + + setup(projectId, periodId, LINE_NAME, + groundLinkLeftDataList, + groundSideADataList, + steelADataList, + underGroundLinkDataList, + steeBDataList, + groundSideBDataList, + groundLinkRightDataList, () -> { + if (getActivity() != null) { + getActivity().finish(); + } + }); + } + return super.onOptionsItemSelected(item); + } + + @Override + public boolean cancelBack() { + // TODO: 2022/6/15 +// List knownItems1 = mAdapter.getGroundLinkPoints(); +// List unknownItems = mAdapter.unknownItems(); +// List knownItems2 = mAdapter.knownItems2(); +// if (isListEmpty(knownItems1) || +// isListEmpty(unknownItems) || +// isListEmpty(knownItems2)) { +// return warningDataLosing(this); +// } + return false; + } + + protected abstract void setup(String projectId, String periodId, + String lineName, + List groundLinkLeftDataList, + List groundSideADataList, + List steelADataList, + List underGroundLinkDataList, + List steeBDataList, + List groundSideBDataList, + List groundLinkRightDataList, + Runnable callback); + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/AbstractLineStationWellSetupFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/AbstractLineStationWellSetupFragment.java new file mode 100644 index 0000000..4d98d41 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/AbstractLineStationWellSetupFragment.java @@ -0,0 +1,421 @@ +package com.bingce.controlnetwork.fragment.station.line; + +import android.content.Intent; +import android.os.Bundle; +import android.os.Handler; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; + +import androidx.activity.result.ActivityResultLauncher; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationConstants; +import com.bingce.controlapphelper.model.BundleConstants; +import com.bingce.controlapphelper.model.PickPointResult; +import com.bingce.controlapphelper.model.StationDetailItem; +import com.bingce.controlapphelper.util.RegExUtil; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.adapter.stationdetail.StationCreateLineWellAdapter; +import com.bingce.controlnetwork.fragment.PickPointFragment; +import com.bingce.controlnetwork.ui.widget.recyclerview.SwipeDraggableRecyclerViewUtil; +import com.bingce.utils.IOnListGetCallback; + +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +import blankj.utilcode.util.ToastUtils; + +/** + * 一井定向的父类 + */ +public abstract class AbstractLineStationWellSetupFragment extends AbstractLineStationSetupFragment + implements StationCreateLineWellAdapter.IOnSelectPointDelegate, + SwipeDraggableRecyclerViewUtil.IStationPointOperatorListener { + + public static final String LINE_NAME = Tools.getString(R.string.one_well_orientation); + + private MenuItem confirmItem; + //选择到的点 + private List groundLinkDataList; + private List groundSideDataList; + private List steelWireDataList; + private List ungroundSideDataList; + private List ungroundLinkDataList; + + private StationCreateLineWellAdapter mAdapter; + + + private final Handler handler = new Handler(); + + private final ActivityResultLauncher activityResultLauncher = PickPointFragment.createActivityLauncher(this, (type, pickPointResult) -> { + if (pickPointResult.getSelectedIds().isEmpty() || pickPointResult.getSelectedNames().isEmpty()) { + return; + } + if (StationDetailItem.ITEM_TYPE_WELL_GROUP_GROUND_LINK.equals(type)) { + //检测数据是否正常 + if (pickPointResult.getSelectedIds().size() < groundLinkMinCount()) { + showErrorMsg(Tools.getString(R.string.underground_connection_min_hint)); + return; + } + mAdapter.setGroundLinkPoints(pickPointResult); + } else if (StationDetailItem.ITEM_TYPE_WELL_GROUP_GROUND_SIDE.equals(type)) { + //检测数据是否正常 + if (pickPointResult.getSelectedIds().size() < groundSideMinCount()) { + showErrorMsg(Tools.getString(R.string.please_select_the_surface_near_well_point)); + return; + } + mAdapter.setGroundSidePoints(pickPointResult); + } else if (StationDetailItem.ITEM_TYPE_WELL_GROUP_STEEL_WIRE.equals(type)) { + //检测数据是否正常 + if (pickPointResult.getSelectedIds().size() < steelWireMinCount()) { + showErrorMsg(Tools.getString(R.string.wire_at_least_two_points)); + return; + } + mAdapter.setSteelWirePoints(pickPointResult); + } else if (StationDetailItem.ITEM_TYPE_WELL_GROUP_UNDERGROUND_SIDE.equals(type)) { + if (pickPointResult.getSelectedIds().size() < undergroundSideMinCount()) { + showErrorMsg(Tools.getString(R.string.please_select_the_underground_near_well_point)); + return; + } + mAdapter.setUndergroudSidePoints(pickPointResult); + } else if (StationDetailItem.ITEM_TYPE_WELL_GROUP_UNDERGROUND_LINK.equals(type)) { + if (pickPointResult.getSelectedIds().size() < undergroundLinkMinCount()) { + showErrorMsg(Tools.getString(R.string.underground_connection_direction_min_hint)); + return; + } + mAdapter.setUndergroudLinkPoints(pickPointResult); + } + onItemChanged(); + }); + + protected abstract int groundLinkMinCount(); + + protected abstract int groundSideMinCount(); + + protected abstract int steelWireMinCount(); + + protected abstract int undergroundSideMinCount(); + + protected abstract int undergroundLinkMinCount(); + + protected abstract void defaultItems(IOnListGetCallback callback); + + protected List getAdapterDataList() { + List items = null; + if (mAdapter != null) { + items = mAdapter.getItems(); + } + return items; + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = super.onCreateView(inflater, container, savedInstanceState); + if (view == null) { + return null; + } + RecyclerView recyclerView = view.findViewById(R.id.recycler_view); + if (recyclerView != null) { + defaultItems(stationDetailItemList -> runOnUI(() -> { + mAdapter = new StationCreateLineWellAdapter( + AbstractLineStationWellSetupFragment.this, stationDetailItemList); + + recyclerView.setAdapter(mAdapter); + SwipeDraggableRecyclerViewUtil.setup(mAdapter, + recyclerView, + getChildFragmentManager(), + getViewLifecycleOwner(), + AbstractLineStationWellSetupFragment.this, + getContext()); + + refreshFiveDataList(); +// refreshAutoCloseView(); + + })); + } + setHasOptionsMenu(true); + return view; + } + + @Override + public void onViewCreated(@NonNull @NotNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); +// initAutoCloseView(); + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (handler != null) + handler.removeCallbacksAndMessages(null); + } + + + @Override + public void onSelectGroundLink(PickPointResult pickPointResult, List filters) { + goSelectPoint(StationDetailItem.ITEM_TYPE_WELL_GROUP_GROUND_LINK, + groundLinkMinCount() + 1, Tools.getString(R.string.select_the_ground_connection_direction_point), filters, pickPointResult); + } + + protected void goSelectPoint(String type, int maxCount, String title, List filters, PickPointResult pickPointResult) { + if (getArguments() == null || getContext() == null) { + return; + } + String projectId = projectId();//getArguments().getString(BundleConstants.KEY_PROJECT_ID); + PickPointFragment.pickPoint( + getContext(), + type, + maxCount, + title, + filters, + projectId, pickPointResult, activityResultLauncher); + } + + + @Override + public void onSelectGroundSide(PickPointResult pickPointResult, List filters) { + goSelectPoint(StationDetailItem.ITEM_TYPE_WELL_GROUP_GROUND_SIDE, + 1, Tools.getString(R.string.select_surface_near_well_point), filters, pickPointResult); + } + + @Override + public void onSelectSteelWire(PickPointResult pickPointResult, List filters) { +// goSelectPoint(StationDetailItem.ITEM_TYPE_WELL_GROUP_STEEL_WIRE, +// steelWireMinCount() + 1, "选择钢丝点", filters, pickPointResult); + PickPointResult lastSteelPickPoint = PickPointResult.create(); + int newName = 1; + List pointsFromType = mAdapter.getPointsFromType(StationDetailItem.ITEM_TYPE_WELL_GROUP_STEEL_WIRE + StationDetailItem._DATA); + if (pointsFromType != null && !pointsFromType.isEmpty()) { + PickPointResult.initPicPointResultData(lastSteelPickPoint, pointsFromType); + //获取新的钢丝的索引 + StationDetailItem stationDetailItem = pointsFromType.get(pointsFromType.size() - 1); + String num = RegExUtil.findNum(stationDetailItem.getName()); + assert num != null; + newName = Integer.parseInt(num) + 1; + } + + if (lastSteelPickPoint.getSelectedIds().size() >= steelWireMinCount() + 1) { + ToastUtils.showShort(R.string.steel_max_hint, (steelWireMinCount() + 1)); + return; + } + + PickPointResult.createPointResultNewData(lastSteelPickPoint, Tools.getString(R.string.wire) + newName); + mAdapter.setSteelWirePoints(lastSteelPickPoint); + + onItemChanged(); + } + + @Override + public void onSelectUndergroundLink(PickPointResult pickPointResult, List filters) { + goSelectPoint(StationDetailItem.ITEM_TYPE_WELL_GROUP_UNDERGROUND_LINK, + undergroundLinkMinCount() + 1, Tools.getString(R.string.select_underground_connection_direction_point), filters, pickPointResult); + } + + @Override + public void onSelectUndergroundSide(PickPointResult pickPointResult, List filters) { + goSelectPoint(StationDetailItem.ITEM_TYPE_WELL_GROUP_UNDERGROUND_SIDE, + 1, Tools.getString(R.string.select_underground_near_well_point), filters, pickPointResult); + } + +// @Override +// public void onSelectOnlyMeasureHorAngle(boolean measureHorAngle) { +// LineRecord currentBatch = getCurrentBatch(); +// SurveyorStationUtil.updateLineRecord(currentBatch); +// SurveyorStationUtil.updateStationPointsMeasureHorAag(currentBatch); +// } + + @Override + public void onItemRemoved(int adapterPosition) { + mAdapter.removeItemForLastSelect(adapterPosition); + onItemChanged(); + } + + @Override + public void onItemDragCompleted() { + onItemChanged(); + } + + /** + * 测站数据发生了变化--测点被删除、测点被修改、测站被修改、测点被拖拽 + */ + private void onItemChanged() { + handler.postDelayed(() -> { + refreshFiveDataList(); + //检测数据是否合法 + if (confirmItem != null) { + confirmItem.setEnabled(!(groundLinkDataList.size() < groundLinkMinCount() || + groundSideDataList.size() < groundSideMinCount() || + steelWireDataList.size() < steelWireMinCount() || + ungroundSideDataList.size() < undergroundSideMinCount() || + ungroundLinkDataList.size() < undergroundLinkMinCount() + )); + } +// refreshAutoCloseView(); + }, 80); + } + + private void refreshFiveDataList() { + String _data = StationDetailItem._DATA; + groundLinkDataList = mAdapter.getPointsFromType(StationDetailItem.ITEM_TYPE_WELL_GROUP_GROUND_LINK + _data); + groundSideDataList = mAdapter.getPointsFromType(StationDetailItem.ITEM_TYPE_WELL_GROUP_GROUND_SIDE + _data); + steelWireDataList = mAdapter.getPointsFromType(StationDetailItem.ITEM_TYPE_WELL_GROUP_STEEL_WIRE + _data); + ungroundSideDataList = mAdapter.getPointsFromType(StationDetailItem.ITEM_TYPE_WELL_GROUP_UNDERGROUND_SIDE + _data); + ungroundLinkDataList = mAdapter.getPointsFromType(StationDetailItem.ITEM_TYPE_WELL_GROUP_UNDERGROUND_LINK + _data); + } + +// private void refreshAutoCloseView() { +// if (isCanSetAutoCloseCheck()) { +// setAutoCloseCheckEnable(true, true); +// } else { +// setAutoCloseCheckEnable(false, false); +// } +// } + + private boolean isCanSetAutoCloseCheck() { + if (groundLinkDataList == null || steelWireDataList == null || ungroundLinkDataList == null) { + return false; + } + int groundLinkSize = groundLinkDataList.size(); + int steelWireSize = steelWireDataList.size(); + int ungroundLinkSize = ungroundLinkDataList.size(); + return groundLinkSize + steelWireSize >= SurveyorStationConstants.AUTO_CLOSE_NUM_INCLUDE_STATION + || ungroundLinkSize + steelWireSize >= SurveyorStationConstants.AUTO_CLOSE_NUM_INCLUDE_STATION; + } + + + protected void showErrorMsgForWell(String type) { + switch (type) { + case StationDetailItem.ITEM_TYPE_WELL_GROUP_GROUND_LINK: + showErrorMsg(Tools.getString(R.string.underground_connection_min_hint)); + break; + case StationDetailItem.ITEM_TYPE_WELL_GROUP_GROUND_SIDE: + showErrorMsg(Tools.getString(R.string.please_select_the_surface_near_well_point)); + break; + case StationDetailItem.ITEM_TYPE_WELL_GROUP_STEEL_WIRE: + showErrorMsg(Tools.getString(R.string.wire_at_least_two_points)); + break; + case StationDetailItem.ITEM_TYPE_WELL_GROUP_UNDERGROUND_SIDE: + showErrorMsg(Tools.getString(R.string.please_select_the_underground_near_well_point)); + break; + case StationDetailItem.ITEM_TYPE_WELL_GROUP_UNDERGROUND_LINK: + showErrorMsg(Tools.getString(R.string.underground_connection_direction_min_hint)); + break; + default: + break; + } + } + + private void showErrorMsg(String msg) { + ToastUtils.showShort(msg); + } + + @Override + public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { + inflater.inflate(R.menu.menu_confirm, menu); + confirmItem = menu.findItem(R.id.menu_confirm); + if (confirmItem != null) { + confirmItem.setEnabled(false); + } + super.onCreateOptionsMenu(menu, inflater); + } + + @Override + public boolean onOptionsItemSelected(@NonNull @NotNull MenuItem item) { + // TODO: 2022/6/15 + if (R.id.menu_confirm == item.getItemId()) { + if (getArguments() == null) { + return super.onOptionsItemSelected(item); + } +// //设置导线的弹框 +// requestLineName(string -> { +// //建站 +// }); + + String projectId = projectId();//getArguments().getString(BundleConstants.KEY_PROJECT_ID); + String periodId = getArguments().getString(BundleConstants.KEY_PERIOD_ID); + if (getCurrentBatch() != null) { + projectId = getCurrentBatch().projectId; + periodId = getCurrentBatch().cycleId; + } + setup(projectId, periodId, LINE_NAME, groundLinkDataList, groundSideDataList, steelWireDataList, ungroundLinkDataList, ungroundSideDataList, () -> { + if (getActivity() != null) { + getActivity().finish(); + } + }); + } + return super.onOptionsItemSelected(item); + } + + @Override + public boolean cancelBack() { + // TODO: 2022/6/15 +// List knownItems1 = mAdapter.getGroundLinkPoints(); +// List unknownItems = mAdapter.unknownItems(); +// List knownItems2 = mAdapter.knownItems2(); +// if (isListEmpty(knownItems1) || +// isListEmpty(unknownItems) || +// isListEmpty(knownItems2)) { +// return warningDataLosing(this); +// } + return false; + } + + protected abstract void setup(String projectId, String cycleId, + String lineName, + List groundLinkDataList, + List groundSideDataList, + List steelWireDataList, + List ungroundLinkDataList, + List ungroundSideDataList, + Runnable callback); + + +// private SwitchCompat getAutoCloseView() { +// if (getView() != null) { +// return getView().findViewById(R.id.auto_close_switch); +// } +// return null; +// } +// +// private void setAutoCloseCheckEnable(boolean isCheck, boolean isEnable) { +// SwitchCompat autoCloseView = getAutoCloseView(); +// if (autoCloseView != null) { +// autoCloseView.setChecked(isCheck); +// autoCloseView.setEnabled(isEnable); +// } +// } +// +// /** +// * 默认是自动闭合的 +// * +// * @return +// */ +// protected boolean isAutoClose() { +// SwitchCompat autoCloseView = getAutoCloseView(); +// if (autoCloseView != null) { +// return autoCloseView.isChecked(); +// } +// return true; +// } +// +// private void initAutoCloseView() { +// SwitchCompat autoCloseView = getAutoCloseView(); +// if (autoCloseView != null) { +// autoCloseView.setOnCheckedChangeListener((buttonView, isChecked) -> { +// if (isCanSetAutoCloseCheck()) { +// setAutoCloseCheckEnable(isChecked, true); +// } +// }); +// } +// } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/attached/LineStationAttachedSetupFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/attached/LineStationAttachedSetupFragment.java new file mode 100644 index 0000000..53521bb --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/attached/LineStationAttachedSetupFragment.java @@ -0,0 +1,280 @@ +package com.bingce.controlnetwork.fragment.station.line.attached; + +import android.content.Context; +import android.os.Bundle; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.line.ILineRecordDataSource; +import com.bingce.controlapphelper.datasource.database.line.LineRecord; +import com.bingce.controlapphelper.datasource.database.point.PointRecord; +import com.bingce.controlapphelper.datasource.database.project.ProjectRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.ISurveyorStationDataSource; +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.model.SurveyorPoint; +import com.bingce.controlapphelper.model.BundleConstants; +import com.bingce.controlapphelper.model.StationDetailItem; +import com.bingce.controlapphelper.util.PointUtil; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.activity.fragmentcontainer.FragmentContainerActivity; +import com.bingce.controlnetwork.fragment.station.line.AbstractLineStationKnownUnknownKnownSetupFragment; +import com.bingce.utils.IOnListGetCallback; +import com.bingce.utils.ThreadPoolUtil; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.List; + +import blankj.utilcode.util.ToastUtils; + +/** + * 新建附合导线 + */ +public class LineStationAttachedSetupFragment extends AbstractLineStationKnownUnknownKnownSetupFragment { + + @Override + protected int knownItemMinCount() { + return 2; + } + + @Override + protected void defaultItems(IOnListGetCallback callback) { + if (callback == null || getArguments() == null) { + return; + } + String batchId = getArguments().getString(BundleConstants.KEY_LINE_ID); + if (batchId == null || batchId.isEmpty()) { + callback.onGet(Arrays.asList( + new StationDetailItem( + getString(selectKnownPointTitle()), + StationDetailItem.ITEM_TYPE_KNOWN_POINT_GROUP1, + null), + new StationDetailItem( + getString(R.string.select_1_unknown_point), + StationDetailItem.ITEM_TYPE_UN_KNOWN_POINT_GROUP, + null), + new StationDetailItem( + getString(selectKnownPointTitle()), + StationDetailItem.ITEM_TYPE_KNOWN_POINT_GROUP2, + null))); + } else { + loadBatchRecord(batchId, callback); + } + } + + @Override + protected int selectKnownPointTitle() { + return R.string.select_2_known_point; + } + + @Override + protected int knownPointCountError() { + return R.string.tips_known_point_must_more_than_2; + } + + @Override + protected boolean initLeftRightMeasure() { + return true; + } + + @Override + protected String defaultLineName() { + return getString(R.string.wire_fuhe); + } + + @Override + protected void setup(String projectId, String periodId, + String lineName, + List knownItems1, + List unknownItems, + List knownItems2, + Runnable runnable) { + //判断数据是否准确 + if (knownItems1.size() != knownItemMinCount()) { + ToastUtils.showShort(knownPointCountError()); + return; + } + if (unknownItems.isEmpty()) { + ToastUtils.showShort(R.string.tips_unknown_point_must_not_empty); + return; + } + if (knownItems2.size() != knownItemMinCount()) { + ToastUtils.showShort(knownPointCountError()); + return; + } + //切换线程 + ThreadPoolUtil.execute(() -> { + + ILineRecordDataSource stationBatchDataSource = SurveyorDatabaseFactory + .instance.getLineRecordDatabase(); + ISurveyorStationDataSource stationDataSource = SurveyorDatabaseFactory + .instance.getSurveyorStation(); + + String lineId = ""; + if (getArguments() != null) { + lineId = getArguments().getString(BundleConstants.KEY_LINE_ID); + } + if (lineId != null && !lineId.isEmpty()) { + //0.删除原有导线和相关测站 + stationBatchDataSource.deleteSync(lineId); + stationDataSource.deleteByLineIdSync(lineId); + } + + String error = checkValidate(projectId, periodId, + unknownItems, knownItems1, knownItems2); + if (error != null && !error.isEmpty()) { + tipsError(error); + return; + } + //0.处理全局控制点 + PointUtil.globalToProjectControlPoint(knownItems1, projectId); + PointUtil.globalToProjectControlPoint(unknownItems, projectId); + PointUtil.globalToProjectControlPoint(knownItems2, projectId); + + + //1.创建并存储batch + List records = new ArrayList<>(); + records.add(new StationDetailItem( + getString(selectKnownPointTitle()), + StationDetailItem.ITEM_TYPE_KNOWN_POINT_GROUP1, + null)); + records.addAll(knownItems1); + records.add(new StationDetailItem( + getString(R.string.select_1_unknown_point), + StationDetailItem.ITEM_TYPE_UN_KNOWN_POINT_GROUP, + null)); + records.addAll(unknownItems); + records.add(new StationDetailItem( + getString(selectKnownPointTitle()), + StationDetailItem.ITEM_TYPE_KNOWN_POINT_GROUP2, + null)); + records.addAll(knownItems2); + LineRecord batchRecord = LineRecord.attach(lineName, projectId, periodId, records); + stationBatchDataSource.save(batchRecord); + + ProjectRecord projectRecord = currentProject(); + boolean showSlopDistance = true; + if (projectRecord != null) { + showSlopDistance = projectRecord.showSlopDistance; + } + + //2.创建测站列表 + StationDetailItem item1 = knownItems1.get(0); + StationDetailItem item2 = knownItems1.get(1); + long dateValue = (new Date()).getTime(); + List stationRecordList = new ArrayList<>(); + boolean needLeftRightSurveyor = needLeftRightSurveyor(); + for (int index = 0; index < unknownItems.size(); index++) { + StationDetailItem item3 = unknownItems.get(index); + + SurveyorStationRecord record = + SurveyorStationRecord.lineStation(dateValue++, + projectId, periodId, batchRecord.id, item1, item2, item3); + record.setLeftAndRightSurveyor(needLeftRightSurveyor); + record.setShowSlopDistance(showSlopDistance); + stationRecordList.add(record); + + item1 = item2; + item2 = item3; + } + //添加konwn point2 + for (int index = 0; index < knownItems2.size(); index++) { + StationDetailItem item3 = knownItems2.get(index); + + SurveyorStationRecord record = + SurveyorStationRecord.lineStation(dateValue++, + projectId, periodId, batchRecord.id, item1, item2, item3); + record.setLeftAndRightSurveyor(needLeftRightSurveyor); + record.setShowSlopDistance(showSlopDistance); + stationRecordList.add(record); + + item1 = item2; + item2 = item3; + } + + //3.存储新建的测站列表 + stationDataSource.save(stationRecordList); + + if (runnable != null) { + runnable.run(); + } + }); + } + + private static String checkValidate(String projectId, String cycleId, + List unknownItems, + List knownItems1, + List knownItems2) { + //检测该测期下是否有同名测站 + ISurveyorStationDataSource stationDataSource = SurveyorDatabaseFactory + .instance + .getSurveyorStation(); + List currentStationList = + stationDataSource.getDataList(projectId, cycleId); + + //收集要创建的测站站点id + List expectedStationIds = new ArrayList<>(); + StationDetailItem tmp = knownItems1.get(1); + for (int index = 0; index < unknownItems.size(); index++) { + StationDetailItem item3 = unknownItems.get(index); + expectedStationIds.add(tmp.getOriginalPointId()); + tmp = item3; + } + //添加konwn point2 + for (int index = 0; index < knownItems2.size(); index++) { + StationDetailItem item3 = knownItems2.get(index); + expectedStationIds.add(tmp.getOriginalPointId()); + tmp = item3; + } + + if (currentStationList != null) {//遍历当前已有测站,检测是否有同名测站 + for (SurveyorStationRecord record : currentStationList) { + List items = record.getItems(); + if (items != null) {//检测测站名是否相同 + for (SurveyorPoint stationItem : items) { + if (SurveyorPoint.TYPE_STATION.equals(stationItem.getType())) { + for (String stationDetailItemId : expectedStationIds) {//遍历即将创建的测站列表,对比是否有相同的 + if (stationItem.getPointId().equals(stationDetailItemId)) { + PointRecord pointRecord = SurveyorDatabaseFactory + .instance + .getPointDataSource() + .findByIdSync(stationItem.getOriginalPointId()); + if (pointRecord != null) { + return pointRecord.getName(); + } + return ""; + } + } + break; + } + } + } + } + } + return null; + } + + public static final int titleCreate = R.string.title_create_attach_line_station; + public static final int titleEdit = R.string.title_edit_attach_line_station; + public static final String TAG = LineStationAttachedSetupFragment.class.getName(); + + public static void startCreate(Context context, String projectId, String periodId) { + Bundle bundle = new Bundle(); + bundle.putString(BundleConstants.KEY_PROJECT_ID, projectId); + bundle.putString(BundleConstants.KEY_PERIOD_ID, periodId); + FragmentContainerActivity.start(context, TAG, titleCreate, bundle); + } + + public static void startEdit(Context context, String projectId, String batchId) { + Bundle bundle = new Bundle(); + bundle.putString(BundleConstants.KEY_PROJECT_ID, projectId); + bundle.putString(BundleConstants.KEY_LINE_ID, batchId); + FragmentContainerActivity.start(context, TAG, titleEdit, bundle); + } + + public static LineStationAttachedSetupFragment newInstance(Bundle bundle) { + LineStationAttachedSetupFragment fragment = new LineStationAttachedSetupFragment(); + fragment.setArguments(bundle); + return fragment; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/close/LineStationCloseSetupFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/close/LineStationCloseSetupFragment.java new file mode 100644 index 0000000..1e5d2f2 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/close/LineStationCloseSetupFragment.java @@ -0,0 +1,326 @@ +package com.bingce.controlnetwork.fragment.station.line.close; + +import android.content.Context; +import android.os.Bundle; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.line.ILineRecordDataSource; +import com.bingce.controlapphelper.datasource.database.line.LineRecord; +import com.bingce.controlapphelper.datasource.database.point.PointRecord; +import com.bingce.controlapphelper.datasource.database.project.ProjectRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.ISurveyorStationDataSource; +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.model.SurveyorPoint; +import com.bingce.controlapphelper.model.BundleConstants; +import com.bingce.controlapphelper.model.StationDetailItem; +import com.bingce.controlapphelper.util.PointUtil; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.activity.fragmentcontainer.FragmentContainerActivity; +import com.bingce.controlnetwork.fragment.station.line.single.LineStationSingleSetupFragment; +import com.bingce.utils.ThreadPoolUtil; + +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +/** + * 新建闭合导线 + */ +public class LineStationCloseSetupFragment extends LineStationSingleSetupFragment { + + @Override + protected int layoutRes() { + return R.layout.fragment_close_line_surveyor_station_setup_layout; + } + + @Override + public void onViewCreated(@NonNull @NotNull View view, @Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + View leftRightSwitch = view.findViewById(R.id.left_right_switch); + if (leftRightSwitch != null) { + leftRightSwitch.setVisibility(View.GONE); + } + } + + @Override + protected int unknownItemMinCount() { + return 2; + } + + @Override + protected int unknownGroupTitle() { + return R.string.select_2_unknown_point; + } + + @Override + protected int unknownPointCountError() { + return R.string.tips_unknown_point_must_more_than_2; + } + + @Override + protected String defaultLineName() { + return getString(R.string.wire_bihe); + } + + @Override + protected void setup(String projectId, String periodId, + String lineName, + List knownItems, + List unknownItems, + Runnable runnable) { + ILineRecordDataSource stationBatchDataSource = SurveyorDatabaseFactory + .instance.getLineRecordDatabase(); + ISurveyorStationDataSource stationDataSource = SurveyorDatabaseFactory + .instance.getSurveyorStation(); + + ThreadPoolUtil.execute(() -> { + + String lineId = ""; + if (getArguments() != null) { + lineId = getArguments().getString(BundleConstants.KEY_LINE_ID); + } + if (lineId != null && !lineId.isEmpty()) { + //0.删除原有导线和相关测站 + stationBatchDataSource.deleteSync(lineId); + stationDataSource.deleteByLineIdSync(lineId); + } + + //验证重复测站 + String name = checkValidate(projectId, periodId, + startPointSetupOnce(), knownItems, unknownItems); + if (name != null && !name.isEmpty()) { + tipsError(name); + return; + } + //0.处理全局控制点 + PointUtil.globalToProjectControlPoint(knownItems, projectId); + PointUtil.globalToProjectControlPoint(unknownItems, projectId); + + //1.创建并存储batch + List records = new ArrayList<>(); + records.add(new StationDetailItem( + getString(knownGroupTitle()), + StationDetailItem.ITEM_TYPE_KNOWN_POINT_GROUP, + null)); + records.addAll(knownItems); + records.add(new StationDetailItem( + getString(unknownGroupTitle()), + StationDetailItem.ITEM_TYPE_UN_KNOWN_POINT_GROUP, + null)); + records.addAll(unknownItems); + LineRecord lineRecord = LineRecord.close(lineName, projectId, periodId, records); + stationBatchDataSource.save(lineRecord); + + ProjectRecord projectRecord = currentProject(); + boolean showSlopDistance = true; + if (projectRecord != null) { + showSlopDistance = projectRecord.showSlopDistance; + } + //2.创建测站列表 + if (startPointSetupOnce()) { + List stationRecordList = setup2( + projectId, periodId, lineRecord.id, showSlopDistance, needLeftRightSurveyor(), knownItems, unknownItems); + //3.存储 + stationDataSource.save(stationRecordList); + } else { + List stationRecordList = setup1( + projectId, periodId, lineRecord.id, showSlopDistance, needLeftRightSurveyor(), knownItems, unknownItems); + //3.存储 + stationDataSource.save(stationRecordList); + } + + if (runnable != null) { + runnable.run(); + } + }); + } + + protected static String checkValidate(String projectId, String cycleId, + boolean startPointSetupOnce, + List unknownItems, + List knownItems) { + ISurveyorStationDataSource stationDataSource = + SurveyorDatabaseFactory.instance.getSurveyorStation(); + //检测该测期下是否有同名测站 + List currentStationList = + stationDataSource.getDataList(projectId, cycleId); + //收集要创建的测站站点id + List expectedStationIds = new ArrayList<>(); + if (startPointSetupOnce) { + StationDetailItem tmp2 = knownItems.get(1); + StationDetailItem tmp3 = unknownItems.get(0); + //起算点有3个测点 + expectedStationIds.add(tmp2.getOriginalPointId()); + tmp2 = tmp3; + for (int index = 1; index < unknownItems.size(); index++) { + tmp3 = unknownItems.get(index); + expectedStationIds.add(tmp2.getOriginalPointId()); + tmp2 = tmp3; + } + //创建最后一个闭合站 + expectedStationIds.add(tmp2.getOriginalPointId()); + } else { + StationDetailItem tmp = knownItems.get(1); + for (int index = 0; index < unknownItems.size(); index++) { + StationDetailItem item3 = unknownItems.get(index); + expectedStationIds.add(tmp.getOriginalPointId()); + tmp = item3; + } + //--闭合导线添加最后一个闭环 + StationDetailItem item3 = knownItems.get(1); + expectedStationIds.add(tmp.getOriginalPointId()); + //--最后以known2做站点再加一站 + tmp = item3; + expectedStationIds.add(tmp.getOriginalPointId()); + } + if (currentStationList != null) {//遍历当前已有测站,检测是否有同名测站 + for (SurveyorStationRecord record : currentStationList) { + List items = record.getItems(); + if (items != null) {//检测测站名是否相同 + for (SurveyorPoint stationItem : items) { + if (SurveyorPoint.TYPE_STATION.equals(stationItem.getType())) { + for (String stationDetailItemId : expectedStationIds) {//遍历即将创建的测站列表,对比是否有相同的 + if (stationItem.getPointId().equals(stationDetailItemId)) { + PointRecord pointRecord = SurveyorDatabaseFactory + .instance + .getPointDataSource() + .findByIdSync(stationItem.getOriginalPointId()); + if (pointRecord != null) { + return pointRecord.getName(); + } + return ""; + } + } + break; + } + } + } + } + } + return null; + } + + protected boolean startPointSetupOnce() { + return switchIsChecked(getView(), R.id.start_point_setup_once); + } + + private static final int titleCreate = R.string.title_create_close_line_station; + private static final int titleEdit = R.string.title_edit_close_line_station; + public static final String TAG = LineStationCloseSetupFragment.class.getName(); + + public static void startCreateCloseLine(Context context, String projectId, String periodId) { + Bundle bundle = new Bundle(); + bundle.putString(BundleConstants.KEY_PROJECT_ID, projectId); + bundle.putString(BundleConstants.KEY_PERIOD_ID, periodId); + FragmentContainerActivity.start(context, TAG, titleCreate, bundle); + } + + public static void startEdit(Context context, String projectId, String batchId) { + Bundle bundle = new Bundle(); + bundle.putString(BundleConstants.KEY_PROJECT_ID, projectId); + bundle.putString(BundleConstants.KEY_LINE_ID, batchId); + FragmentContainerActivity.start(context, TAG, titleEdit, bundle); + } + + public static LineStationCloseSetupFragment newInstance(Bundle bundle) { + LineStationCloseSetupFragment fragment = new LineStationCloseSetupFragment(); + fragment.setArguments(bundle); + return fragment; + } + + private static List setup1(String projectId, String cycleId, String lineId, + boolean showSlopDistance, boolean needLeftRightSurveyor, + List knownItems, List unknownItems) { + StationDetailItem item1 = knownItems.get(0); + StationDetailItem item2 = knownItems.get(1); + long dateValue = (new Date()).getTime(); + List stationRecordList = new ArrayList<>(); + for (int index = 0; index < unknownItems.size(); index++) { + StationDetailItem item3 = unknownItems.get(index); + + SurveyorStationRecord record = + SurveyorStationRecord.lineStation(dateValue++, + projectId, cycleId, lineId, item1, item2, item3); + record.setLeftAndRightSurveyor(needLeftRightSurveyor); + record.setShowSlopDistance(showSlopDistance); + stationRecordList.add(record); + + item1 = item2; + item2 = item3; + } + //--闭合导线添加最后一个闭环 + StationDetailItem item3 = knownItems.get(1); + SurveyorStationRecord record1 = + SurveyorStationRecord.lineStation(dateValue++, + projectId, cycleId, lineId, item1, item2, item3); + record1.setLeftAndRightSurveyor(needLeftRightSurveyor); + record1.setShowSlopDistance(showSlopDistance); + stationRecordList.add(record1); + + //--最后以known2做站点再加一站 + item1 = item2; + item2 = item3; + item3 = knownItems.get(0); + SurveyorStationRecord record2 = + SurveyorStationRecord.lineStation(dateValue++, + projectId, cycleId, lineId, item1, item2, item3); + record2.setLeftAndRightSurveyor(needLeftRightSurveyor); + record2.setShowSlopDistance(showSlopDistance); + stationRecordList.add(record2); + + return stationRecordList; + } + + private static List setup2(String projectId, String cycleId, String lineId, + boolean showSlopDistance, boolean needLeftRightSurveyor, + List knownItems, List unknownItems) { + long dateValue = (new Date()).getTime(); + List stationRecordList = new ArrayList<>(); + + StationDetailItem item1 = knownItems.get(0); + StationDetailItem item2 = knownItems.get(1); + StationDetailItem item3 = unknownItems.get(0); + StationDetailItem item4 = unknownItems.get(unknownItems.size() - 1); + //起算点有3个测点 + SurveyorStationRecord startStation = + SurveyorStationRecord.closeLineStartPointStation(dateValue++, + projectId, cycleId, lineId, item1, item2, item3, item4); + startStation.setLeftAndRightSurveyor(false); + startStation.setShowSlopDistance(showSlopDistance); + stationRecordList.add(startStation); + + item1 = item2; + item2 = item3; + + for (int index = 1; index < unknownItems.size(); index++) { + item3 = unknownItems.get(index); + + SurveyorStationRecord record = + SurveyorStationRecord.lineStation(dateValue++, + projectId, cycleId, lineId, item1, item2, item3); + record.setLeftAndRightSurveyor(needLeftRightSurveyor); + record.setShowSlopDistance(showSlopDistance); + stationRecordList.add(record); + + item1 = item2; + item2 = item3; + } + + //创建最后一个闭合站 + item3 = knownItems.get(1); + SurveyorStationRecord record = + SurveyorStationRecord.lineStation(dateValue++, + projectId, cycleId, lineId, item1, item2, item3); + record.setLeftAndRightSurveyor(needLeftRightSurveyor); + record.setShowSlopDistance(showSlopDistance); + stationRecordList.add(record); + + return stationRecordList; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/random/LineStationRandomSetupFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/random/LineStationRandomSetupFragment.java new file mode 100644 index 0000000..0d10ef1 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/random/LineStationRandomSetupFragment.java @@ -0,0 +1,272 @@ +package com.bingce.controlnetwork.fragment.station.line.random; + +import android.content.Context; +import android.os.Bundle; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.line.ILineRecordDataSource; +import com.bingce.controlapphelper.datasource.database.line.LineRecord; +import com.bingce.controlapphelper.datasource.database.point.PointRecord; +import com.bingce.controlapphelper.datasource.database.project.ProjectRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.ISurveyorStationDataSource; +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.model.SurveyorPoint; +import com.bingce.controlapphelper.model.BundleConstants; +import com.bingce.controlapphelper.model.StationDetailItem; +import com.bingce.controlapphelper.util.PointUtil; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.activity.fragmentcontainer.FragmentContainerActivity; +import com.bingce.controlnetwork.fragment.station.line.AbstractLineStationKnownUnknownKnownSetupFragment; +import com.bingce.utils.IOnListGetCallback; +import com.bingce.utils.ThreadPoolUtil; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.List; + +import blankj.utilcode.util.ToastUtils; + +/** + * 新建无定向导线 + */ +public class LineStationRandomSetupFragment extends AbstractLineStationKnownUnknownKnownSetupFragment { + + @Override + protected int knownItemMinCount() { + return 1; + } + + @Override + protected void defaultItems(IOnListGetCallback callback) { + if (callback == null || getArguments() == null) { + return; + } + String batchId = getArguments().getString(BundleConstants.KEY_LINE_ID); + if (batchId == null || batchId.isEmpty()) { + callback.onGet(Arrays.asList( + new StationDetailItem( + getString(selectKnownPointTitle()), + StationDetailItem.ITEM_TYPE_KNOWN_POINT_GROUP1, + null), + new StationDetailItem( + getString(R.string.select_1_unknown_point), + StationDetailItem.ITEM_TYPE_UN_KNOWN_POINT_GROUP, + null), + new StationDetailItem( + getString(selectKnownPointTitle()), + StationDetailItem.ITEM_TYPE_KNOWN_POINT_GROUP2, + null))); + } else { + loadBatchRecord(batchId, callback); + } + } + + @Override + protected int selectKnownPointTitle() { + return R.string.select_1_known_point; + } + + @Override + protected int knownPointCountError() { + return R.string.tips_known_point_must_more_than_1; + } + + @Override + protected boolean initLeftRightMeasure() { + return true; + } + + @Override + protected String defaultLineName() { + return getString(R.string.wire_wudingxxiang); + } + + @Override + protected void setup(String projectId, String periodId, + String lineName, + List knownItems1, + List unknownItems, + List knownItems2, + Runnable runnable) { + //检测条件是否合法 + if (knownItems1.size() != knownItemMinCount()) { + ToastUtils.showShort(knownPointCountError()); + return; + } + if (unknownItems.isEmpty()) { + ToastUtils.showShort(R.string.tips_unknown_point_must_not_empty); + return; + } + if (knownItems2.size() != knownItemMinCount()) { + ToastUtils.showShort(knownPointCountError()); + return; + } + ThreadPoolUtil.execute(() -> { + + ILineRecordDataSource stationBatchDataSource = SurveyorDatabaseFactory + .instance.getLineRecordDatabase(); + ISurveyorStationDataSource stationDataSource = SurveyorDatabaseFactory + .instance.getSurveyorStation(); + + String lineId = ""; + if (getArguments() != null) { + lineId = getArguments().getString(BundleConstants.KEY_LINE_ID); + } + if (lineId != null && !lineId.isEmpty()) { + //0.删除原有导线和相关测站 + stationBatchDataSource.deleteSync(lineId); + stationDataSource.deleteByLineIdSync(lineId); + } + + String error = checkValidate(projectId, periodId, unknownItems, knownItems2); + if (error != null && !error.isEmpty()) { + tipsError(error); + return; + } + //0.处理全局控制点 + PointUtil.globalToProjectControlPoint(knownItems1, projectId); + PointUtil.globalToProjectControlPoint(unknownItems, projectId); + PointUtil.globalToProjectControlPoint(knownItems2, projectId); + + //1.创建并存储batch + List records = new ArrayList<>(); + records.add(new StationDetailItem( + getString(selectKnownPointTitle()), + StationDetailItem.ITEM_TYPE_KNOWN_POINT_GROUP1, + null)); + records.addAll(knownItems1); + records.add(new StationDetailItem( + getString(R.string.select_1_unknown_point), + StationDetailItem.ITEM_TYPE_UN_KNOWN_POINT_GROUP, + null)); + records.addAll(unknownItems); + records.add(new StationDetailItem( + getString(selectKnownPointTitle()), + StationDetailItem.ITEM_TYPE_KNOWN_POINT_GROUP2, + null)); + records.addAll(knownItems2); + LineRecord batchRecord = LineRecord.random(lineName, projectId, periodId, records); + stationBatchDataSource.save(batchRecord); + + ProjectRecord projectRecord = currentProject(); + boolean showSlopDistance = true; + if (projectRecord != null) { + showSlopDistance = projectRecord.showSlopDistance; + } + //2.创建测站列表 + StationDetailItem item1 = knownItems1.get(0); + StationDetailItem item2 = unknownItems.get(0); + long dateValue = (new Date()).getTime(); + List stationRecordList = new ArrayList<>(); + boolean needLeftRightSurveyor = needLeftRightSurveyor(); + for (int index = 1; index < unknownItems.size(); index++) { + StationDetailItem item3 = unknownItems.get(index); + + SurveyorStationRecord record = + SurveyorStationRecord.lineStation(dateValue++, + projectId, periodId, batchRecord.id, item1, item2, item3); + record.setLeftAndRightSurveyor(needLeftRightSurveyor); + record.setShowSlopDistance(showSlopDistance); + stationRecordList.add(record); + + item1 = item2; + item2 = item3; + } + //添加konwn point2 + for (int index = 0; index < knownItems2.size(); index++) { + StationDetailItem item3 = knownItems2.get(index); + + SurveyorStationRecord record = + SurveyorStationRecord.lineStation(dateValue++, + projectId, periodId, batchRecord.id, item1, item2, item3); + record.setLeftAndRightSurveyor(needLeftRightSurveyor); + record.setShowSlopDistance(showSlopDistance); + stationRecordList.add(record); + + item1 = item2; + item2 = item3; + } + + stationDataSource.save(stationRecordList); + + if (runnable != null) { + runnable.run(); + } + }); + } + + private static String checkValidate(String projectId, String cycleId, + List unknownItems, + List knownItems2) { + //检测该测期下是否有同名测站 + ISurveyorStationDataSource stationDataSource = SurveyorDatabaseFactory + .instance.getSurveyorStation(); + List currentStationList = + stationDataSource.getDataList(projectId, cycleId); + //收集要创建的测站站点id + List expectedStationIds = new ArrayList<>(); + + StationDetailItem tmp = unknownItems.get(0); + for (int index = 1; index < unknownItems.size(); index++) { + StationDetailItem item3 = unknownItems.get(index); + expectedStationIds.add(tmp.getOriginalPointId()); + tmp = item3; + } + //添加konwn point2 + for (int index = 0; index < knownItems2.size(); index++) { + StationDetailItem item3 = knownItems2.get(index); + expectedStationIds.add(tmp.getOriginalPointId()); + tmp = item3; + } + if (currentStationList != null) {//遍历当前已有测站,检测是否有同名测站 + for (SurveyorStationRecord record : currentStationList) { + List items = record.getItems(); + if (items != null) {//检测测站名是否相同 + for (SurveyorPoint stationItem : items) { + if (SurveyorPoint.TYPE_STATION.equals(stationItem.getType())) { + for (String stationDetailItemId : expectedStationIds) {//遍历即将创建的测站列表,对比是否有相同的 + if (stationItem.getPointId().equals(stationDetailItemId)) { + PointRecord pointRecord = SurveyorDatabaseFactory + .instance + .getPointDataSource() + .findByIdSync(stationItem.getOriginalPointId()); + if (pointRecord != null) { + return pointRecord.getName(); + } + return ""; + } + } + break; + } + } + } + } + } + return null; + } + + public static final int titleCreate = R.string.title_create_random_line_station; + public static final int titleEdit = R.string.title_edit_random_line_station; + public static final String TAG = LineStationRandomSetupFragment.class.getName(); + + public static void startCreate(Context context, String projectId, String periodId) { + Bundle bundle = new Bundle(); + bundle.putString(BundleConstants.KEY_PROJECT_ID, projectId); + bundle.putString(BundleConstants.KEY_PERIOD_ID, periodId); + FragmentContainerActivity.start(context, TAG, titleCreate, bundle); + } + + public static void startEdit(Context context, String projectId, String batchId) { + Bundle bundle = new Bundle(); + bundle.putString(BundleConstants.KEY_PROJECT_ID, projectId); + bundle.putString(BundleConstants.KEY_LINE_ID, batchId); + FragmentContainerActivity.start(context, TAG, titleEdit, bundle); + } + + public static LineStationRandomSetupFragment newInstance(Bundle bundle) { + LineStationRandomSetupFragment fragment = new LineStationRandomSetupFragment(); + fragment.setArguments(bundle); + return fragment; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/single/LineStationSingleSetupFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/single/LineStationSingleSetupFragment.java new file mode 100644 index 0000000..9d55c3f --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/single/LineStationSingleSetupFragment.java @@ -0,0 +1,240 @@ +package com.bingce.controlnetwork.fragment.station.line.single; + +import android.content.Context; +import android.os.Bundle; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.line.ILineRecordDataSource; +import com.bingce.controlapphelper.datasource.database.line.LineRecord; +import com.bingce.controlapphelper.datasource.database.point.PointRecord; +import com.bingce.controlapphelper.datasource.database.project.ProjectRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.ISurveyorStationDataSource; +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.model.SurveyorPoint; +import com.bingce.controlapphelper.model.BundleConstants; +import com.bingce.controlapphelper.model.StationDetailItem; +import com.bingce.controlapphelper.util.PointUtil; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.activity.fragmentcontainer.FragmentContainerActivity; +import com.bingce.controlnetwork.fragment.station.line.AbstractLineStationKnownUnknownSetupFragment; +import com.bingce.utils.IOnListGetCallback; +import com.bingce.utils.ThreadPoolUtil; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.List; + +/** + * 新建支导线 + */ +public class LineStationSingleSetupFragment extends AbstractLineStationKnownUnknownSetupFragment { + + @Override + protected int knownItemMinCount() { + return 2; + } + + @Override + protected int knownGroupTitle() { + return R.string.select_2_known_point; + } + + @Override + protected int knownPointCountError() { + return R.string.tips_known_point_must_more_than_2; + } + + @Override + protected int unknownItemMinCount() { + return 1; + } + + @Override + protected int unknownGroupTitle() { + return R.string.select_1_unknown_point; + } + + @Override + protected int unknownPointCountError() { + return R.string.tips_unknown_point_must_not_empty; + } + + @Override + protected boolean initLeftRightMeasure() { + return true; + } + + @Override + protected String defaultLineName() { + return getString(R.string.wire_zhi); + } + + @Override + protected void defaultItems(IOnListGetCallback callback) { + if (callback == null || getArguments() == null) { + return; + } + String batchId = getArguments().getString(BundleConstants.KEY_LINE_ID); + if (batchId == null || batchId.isEmpty()) { + callback.onGet(Arrays.asList( + new StationDetailItem( + getString(knownGroupTitle()), + StationDetailItem.ITEM_TYPE_KNOWN_POINT_GROUP, + null), + new StationDetailItem( + getString(unknownGroupTitle()), + StationDetailItem.ITEM_TYPE_UN_KNOWN_POINT_GROUP, + null))); + } else { + loadBatchRecord(batchId, callback); + } + } + + @Override + protected void setup(String projectId, String periodId, + String lineName, + List knownItems, + List unknownItems, + Runnable runnable) { + ILineRecordDataSource stationBatchDataSource = SurveyorDatabaseFactory + .instance.getLineRecordDatabase(); + ISurveyorStationDataSource stationDataSource = SurveyorDatabaseFactory + .instance.getSurveyorStation(); + + ThreadPoolUtil.execute(() -> { + String lineId = ""; + if (getArguments() != null) { + lineId = getArguments().getString(BundleConstants.KEY_LINE_ID); + } + if (lineId != null && !lineId.isEmpty()) { + //0.删除原有导线和相关测站 + stationBatchDataSource.deleteSync(lineId); + stationDataSource.deleteByLineIdSync(lineId); + } + + String error = checkValidate(projectId, periodId, knownItems, unknownItems); + if (error != null && !error.isEmpty()) { + tipsError(error); + return; + } + //0.处理全局控制点 + PointUtil.globalToProjectControlPoint(knownItems, projectId); + PointUtil.globalToProjectControlPoint(unknownItems, projectId); + + //1.创建并存储batch + List records = new ArrayList<>(); + records.add(new StationDetailItem( + getString(knownGroupTitle()), + StationDetailItem.ITEM_TYPE_KNOWN_POINT_GROUP, + null)); + records.addAll(knownItems); + records.add(new StationDetailItem( + getString(unknownGroupTitle()), + StationDetailItem.ITEM_TYPE_UN_KNOWN_POINT_GROUP, + null)); + records.addAll(unknownItems); + LineRecord batchRecord = LineRecord.single(lineName, projectId, periodId, records); + stationBatchDataSource.save(batchRecord); + + ProjectRecord projectRecord = currentProject(); + boolean showSlopDistance = true; + if (projectRecord != null) { + showSlopDistance = projectRecord.showSlopDistance; + } + //2.创建测站列表 + StationDetailItem item1 = knownItems.get(0); + StationDetailItem item2 = knownItems.get(1); + long dateValue = (new Date()).getTime(); + List stationRecordList = new ArrayList<>(); + boolean needLeftRightSurveyor = needLeftRightSurveyor(); + for (int index = 0; index < unknownItems.size(); index++) { + StationDetailItem item3 = unknownItems.get(index); + SurveyorStationRecord record = + SurveyorStationRecord.lineStation(dateValue++, + projectId, periodId, batchRecord.id, item1, item2, item3); + record.setLeftAndRightSurveyor(needLeftRightSurveyor); + record.setShowSlopDistance(showSlopDistance); + stationRecordList.add(record); + + item1 = item2; + item2 = item3; + } + + stationDataSource.save(stationRecordList); + + if (runnable != null) { + runnable.run(); + } + }); + } + + private static String checkValidate(String projectId, String cycleId, + List knownItems, + List unknownItems) { + ISurveyorStationDataSource stationDataSource = + SurveyorDatabaseFactory.instance.getSurveyorStation(); + //检测该测期下是否有同名测站 + List currentStationList = + stationDataSource.getDataList(projectId, cycleId); + //收集要创建的测站站点id + List expectedStationIds = new ArrayList<>(); + StationDetailItem tmp = knownItems.get(1); + for (int index = 0; index < unknownItems.size(); index++) { + StationDetailItem item3 = unknownItems.get(index); + expectedStationIds.add(tmp.getOriginalPointId()); + tmp = item3; + } + if (currentStationList != null) {//遍历当前已有测站,检测是否有同名测站 + for (SurveyorStationRecord record : currentStationList) { + List items = record.getItems(); + if (items != null) {//检测测站名是否相同 + for (SurveyorPoint stationItem : items) { + if (SurveyorPoint.TYPE_STATION.equals(stationItem.getType())) { + for (String stationDetailItemId : expectedStationIds) {//遍历即将创建的测站列表,对比是否有相同的 + if (stationItem.getPointId().equals(stationDetailItemId)) { +// return false; + PointRecord pointRecord = SurveyorDatabaseFactory + .instance + .getPointDataSource() + .findByIdSync(stationItem.getOriginalPointId()); + if (pointRecord != null) { + return pointRecord.getName(); + } + return ""; + } + } + break; + } + } + } + } + } + return null; + } + + public static final int titleCreate = R.string.title_create_sinle_line_station; + public static final int titleEdit = R.string.title_edit_sinle_line_station; + + public static final String TAG = LineStationSingleSetupFragment.class.getName(); + + public static void startCreate(Context context, String projectId, String period) { + Bundle bundle = new Bundle(); + bundle.putString(BundleConstants.KEY_PROJECT_ID, projectId); + bundle.putString(BundleConstants.KEY_PERIOD_ID, period); + FragmentContainerActivity.start(context, TAG, titleCreate, bundle); + } + + public static void startEdit(Context context, String projectId, String batchId) { + Bundle bundle = new Bundle(); + bundle.putString(BundleConstants.KEY_PROJECT_ID, projectId); + bundle.putString(BundleConstants.KEY_LINE_ID, batchId); + FragmentContainerActivity.start(context, TAG, titleEdit, bundle); + } + + public static LineStationSingleSetupFragment newInstance(Bundle bundle) { + LineStationSingleSetupFragment fragment = new LineStationSingleSetupFragment(); + fragment.setArguments(bundle); + return fragment; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/well/LineStationWellDoubleGroundSetupFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/well/LineStationWellDoubleGroundSetupFragment.java new file mode 100644 index 0000000..7abcc1a --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/well/LineStationWellDoubleGroundSetupFragment.java @@ -0,0 +1,342 @@ +package com.bingce.controlnetwork.fragment.station.line.well; + +import android.content.Context; +import android.os.Bundle; +import android.text.TextUtils; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.line.ILineRecordDataSource; +import com.bingce.controlapphelper.datasource.database.line.LineRecord; +import com.bingce.controlapphelper.datasource.database.point.PointRecord; +import com.bingce.controlapphelper.datasource.database.project.ProjectRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.ISurveyorStationDataSource; +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationConstants; +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.model.SurveyorPoint; +import com.bingce.controlapphelper.model.BundleConstants; +import com.bingce.controlapphelper.model.StationDetailItem; +import com.bingce.controlapphelper.util.PointUtil; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.activity.fragmentcontainer.FragmentContainerActivity; +import com.bingce.controlnetwork.fragment.station.line.AbstractLineStationWellDoubleGroundSetupFragment; +import com.bingce.utils.IOnListGetCallback; +import com.bingce.utils.ThreadPoolUtil; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.List; + +/** + * 新建二井定向-地上 + */ +public class LineStationWellDoubleGroundSetupFragment extends AbstractLineStationWellDoubleGroundSetupFragment { + + public static final int titleCreate = R.string.title_create_well_line_station_double_ground; + public static final int titleEdit = R.string.title_edit_well_line_station_double_ground; + public static final String TAG = LineStationWellDoubleGroundSetupFragment.class.getName(); + //区分是初始页面还是编辑页面 + private boolean isDefaultPage; + + public static void startCreate(Context context, String projectId, String periodId) { + Bundle bundle = new Bundle(); + bundle.putString(BundleConstants.KEY_PROJECT_ID, projectId); + bundle.putString(BundleConstants.KEY_PERIOD_ID, periodId); + FragmentContainerActivity.start(context, TAG, titleCreate, bundle); + } + + public static void startEdit(Context context, String projectId, String batchId) { + Bundle bundle = new Bundle(); + bundle.putString(BundleConstants.KEY_LINE_ID, batchId); + bundle.putString(BundleConstants.KEY_PROJECT_ID, projectId); + FragmentContainerActivity.start(context, TAG, titleEdit, bundle); + } + + public static LineStationWellDoubleGroundSetupFragment newInstance(Bundle bundle) { + LineStationWellDoubleGroundSetupFragment fragment = new LineStationWellDoubleGroundSetupFragment(); + fragment.setArguments(bundle); + return fragment; + } + + @Override + protected boolean initLeftRightMeasure() { + return false; + } + + @Override + protected int groundLinkLeftMinCount() { + return 1; + } + + @Override + protected int groundSideAMinCount() { + return 1; + } + + @Override + protected int groundLinkMiddleMinCount() { + return 0; + } + + @Override + protected int groundSideBMinCount() { + return 1; + } + + @Override + protected int groundLinkRightMinCount() { + return 1; + } + + @Override + protected void defaultItems(IOnListGetCallback callback) { + if (callback == null || getArguments() == null) { + return; + } + String batchId = getArguments().getString(BundleConstants.KEY_LINE_ID); + isDefaultPage = TextUtils.isEmpty(batchId); + if (isDefaultPage) { + callback.onGet(Arrays.asList( + new StationDetailItem( + Tools.getString(R.string.well_a_surface_connection_direction_limit), + StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_LEFT, + null), + new StationDetailItem( + Tools.getString(R.string.well_a_surface_near_well_point), + StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_A, + null), + new StationDetailItem( + Tools.getString(R.string.ground_connection_point_optional), + StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_MIDDLE, + null), + new StationDetailItem( + Tools.getString(R.string.well_b_surface_near_well_point), + StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_B, + null), + new StationDetailItem( + Tools.getString(R.string.well_b_surface_connection_direction_limit), + StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_RIGHT, + null) + )); + } else { + loadBatchRecord(batchId, callback); + } + } + + + @Override + protected String defaultLineName() { + return getString(R.string.station_type_well_wire_double); + } + + @Override + protected void setup(String projectId, String periodId, String lineName, + List groundLinkLeftDataList, List groundLinkMiddleDataList, + List groundLinkRightDataList, List groundSideBDataList, + List groundSideADataList, Runnable callback) { + //判断数据是否准确 + if (groundLinkLeftDataList.size() < groundLinkLeftMinCount()) { + showErrorMsgForWell(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_LEFT); + return; + } + if (groundLinkMiddleDataList.size() < groundLinkMiddleMinCount()) { + showErrorMsgForWell(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_MIDDLE); + return; + } + if (groundLinkRightDataList.size() < groundLinkRightMinCount()) { + showErrorMsgForWell(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_RIGHT); + return; + } + if (groundSideBDataList.size() < groundSideBMinCount()) { + showErrorMsgForWell(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_B); + return; + } + if (groundSideADataList.size() < groundSideAMinCount()) { + showErrorMsgForWell(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_A); + return; + } + //切换线程 + ThreadPoolUtil.execute(() -> { + + ILineRecordDataSource stationBatchDataSource = SurveyorDatabaseFactory + .instance.getLineRecordDatabase(); + ISurveyorStationDataSource stationDataSource = SurveyorDatabaseFactory + .instance.getSurveyorStation(); + + String lineId = ""; + if (getArguments() != null) { + lineId = getArguments().getString(BundleConstants.KEY_LINE_ID); + } + if (lineId != null && !lineId.isEmpty()) { + //0.删除原有导线和相关测站 + stationBatchDataSource.deleteSync(lineId); + stationDataSource.deleteByLineIdSync(lineId); + } + + String error = checkValidate(projectId, periodId, + groundLinkMiddleDataList, groundSideADataList, groundSideBDataList); + if (error != null && !error.isEmpty()) { + tipsError(error); + return; + } + + //0.处理全局控制点 + PointUtil.globalToProjectControlPoint(groundLinkLeftDataList, projectId); + PointUtil.globalToProjectControlPoint(groundLinkMiddleDataList, projectId); + PointUtil.globalToProjectControlPoint(groundLinkRightDataList, projectId); + PointUtil.globalToProjectControlPoint(groundSideBDataList, projectId); + PointUtil.globalToProjectControlPoint(groundSideADataList, projectId); + + //1.创建并存储batch + List lineRecordPointList = getAdapterDataList(); + LineRecord batchRecord = LineRecord.well(LineRecord.TYPE_WELL_DOUBLE_GROUND, lineName, projectId, periodId, lineRecordPointList); + stationBatchDataSource.save(batchRecord); + + ProjectRecord projectRecord = currentProject(); + boolean showSlopDistance = true; + if (projectRecord != null) { + showSlopDistance = projectRecord.showSlopDistance; + } + + //2.创建测站列表 + long dateValue = (new Date()).getTime(); + List stationRecordList = new ArrayList<>(); + boolean needLeftRightSurveyor = needLeftRightSurveyor(); + + for (StationDetailItem itemSideA : groundSideADataList) { + List pointList = new ArrayList<>(); + pointList.add(itemSideA); + pointList.addAll(groundLinkLeftDataList); + if (groundLinkMiddleDataList != null && !groundLinkMiddleDataList.isEmpty()) { + pointList.add(groundLinkMiddleDataList.get(0)); + } else { + pointList.add(groundSideBDataList.get(0)); + } + + SurveyorStationRecord wellStationRecord = SurveyorStationRecord.createWellStationRecord(dateValue++, + projectId, periodId, batchRecord.id, pointList); + //设置站是否闭合 + if (pointList.size() > SurveyorStationConstants.AUTO_CLOSE_NUM_INCLUDE_STATION) { + wellStationRecord.setAutoClose(true); + } + wellStationRecord.setLeftAndRightSurveyor(needLeftRightSurveyor); + wellStationRecord.setShowSlopDistance(showSlopDistance); + stationRecordList.add(wellStationRecord); + } + + if (groundLinkMiddleDataList != null && !groundLinkMiddleDataList.isEmpty()) { + for (int i = 0; i < groundLinkMiddleDataList.size(); i++) { + List pointList = new ArrayList<>(); + pointList.add(groundLinkMiddleDataList.get(i)); + + if (i - 1 < 0) { + //第一个节点 + pointList.add(groundSideADataList.get(0)); + } else { + pointList.add(groundLinkMiddleDataList.get(i - 1)); + } + + if (i + 1 > groundLinkMiddleDataList.size() - 1) { + pointList.add(groundSideBDataList.get(0)); + } else { + pointList.add(groundLinkMiddleDataList.get(i + 1)); + } + + SurveyorStationRecord wellStationRecord = SurveyorStationRecord.createWellStationRecord(dateValue++, + projectId, periodId, batchRecord.id, pointList); +// 设置站是否闭合 + if (pointList.size() > SurveyorStationConstants.AUTO_CLOSE_NUM_INCLUDE_STATION) { + wellStationRecord.setAutoClose(true); + } + wellStationRecord.setLeftAndRightSurveyor(needLeftRightSurveyor); + wellStationRecord.setShowSlopDistance(showSlopDistance); + stationRecordList.add(wellStationRecord); + } + } + + for (StationDetailItem itemSideB : groundSideBDataList) { + List pointList = new ArrayList<>(); + pointList.add(itemSideB); + if (groundLinkMiddleDataList != null && !groundLinkMiddleDataList.isEmpty()) { + pointList.add(groundLinkMiddleDataList.get(groundLinkMiddleDataList.size() - 1)); + } else { + pointList.add(groundSideADataList.get(0)); + } + pointList.addAll(groundLinkRightDataList); + + SurveyorStationRecord wellStationRecord = SurveyorStationRecord.createWellStationRecord(dateValue++, + projectId, periodId, batchRecord.id, pointList); + //设置站是否闭合 + if (pointList.size() > SurveyorStationConstants.AUTO_CLOSE_NUM_INCLUDE_STATION) { + wellStationRecord.setAutoClose(true); + } + wellStationRecord.setLeftAndRightSurveyor(needLeftRightSurveyor); + wellStationRecord.setShowSlopDistance(showSlopDistance); + stationRecordList.add(wellStationRecord); + } + + //3.存储新建的测站列表 + stationDataSource.save(stationRecordList); + + if (callback != null) { + callback.run(); + } + }); + } + + private String checkValidate(String projectId, String cycleId, + List groundLinkMiddleDataList, + List groundSideADataList, List groundSideBDataList) { + //如果是编辑页面就不检查 + if (!isDefaultPage) return null; + + //检测该测期下是否有同名测站 + ISurveyorStationDataSource stationDataSource = SurveyorDatabaseFactory.instance.getSurveyorStation(); + List currentStationList = + stationDataSource.getDataList(projectId, cycleId); + + //收集要创建的测站站点id + List expectedStationIds = new ArrayList<>(); + collectIdsFromList(expectedStationIds, groundLinkMiddleDataList); + collectIdsFromList(expectedStationIds, groundSideADataList); + collectIdsFromList(expectedStationIds, groundSideBDataList); + + if (currentStationList != null) {//遍历当前已有测站,检测是否有同名测站 + for (SurveyorStationRecord record : currentStationList) { + List items = record.getItems(); + if (items != null) {//检测测站名是否相同 + for (SurveyorPoint stationItem : items) { + if (SurveyorPoint.TYPE_STATION.equals(stationItem.getType())) { + for (String stationDetailItemId : expectedStationIds) {//遍历即将创建的测站列表,对比是否有相同的 + if (stationItem.getPointId().equals(stationDetailItemId)) { + PointRecord pointRecord = SurveyorDatabaseFactory + .instance + .getPointDataSource() + .findByIdSync(stationItem.getOriginalPointId()); + if (pointRecord != null) { + return pointRecord.getName(); + } + return ""; + } + } + break; + } + } + } + } + } + return null; + } + + private void collectIdsFromList(List collectIdList, List tagetList) { + for (StationDetailItem stationDetailItem : tagetList) { + String pointId = stationDetailItem.getOriginalPointId(); + if (!TextUtils.isEmpty(pointId)) { + collectIdList.add(pointId); + } + } + } + + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/well/LineStationWellDoubleUnderGroundSetupFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/well/LineStationWellDoubleUnderGroundSetupFragment.java new file mode 100644 index 0000000..3aba334 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/well/LineStationWellDoubleUnderGroundSetupFragment.java @@ -0,0 +1,382 @@ +package com.bingce.controlnetwork.fragment.station.line.well; + +import android.content.Context; +import android.os.Bundle; +import android.text.TextUtils; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.line.ILineRecordDataSource; +import com.bingce.controlapphelper.datasource.database.line.LineRecord; +import com.bingce.controlapphelper.datasource.database.point.PointRecord; +import com.bingce.controlapphelper.datasource.database.point.PointRecordOperate; +import com.bingce.controlapphelper.datasource.database.project.ProjectRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.ISurveyorStationDataSource; +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationConstants; +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.model.SurveyorPoint; +import com.bingce.controlapphelper.model.BundleConstants; +import com.bingce.controlapphelper.model.StationDetailItem; +import com.bingce.controlapphelper.util.PointUtil; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.activity.fragmentcontainer.FragmentContainerActivity; +import com.bingce.controlnetwork.fragment.station.line.AbstractLineStationWellDoubleUnderGroundSetupFragment; +import com.bingce.utils.IOnListGetCallback; +import com.bingce.utils.ThreadPoolUtil; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.List; + +/** + * 新建二井定向-地下 + */ +public class LineStationWellDoubleUnderGroundSetupFragment extends AbstractLineStationWellDoubleUnderGroundSetupFragment { + + public static final int titleCreate = R.string.title_create_well_line_station_double_under_ground; + public static final int titleEdit = R.string.title_edit_well_line_station_double_under_ground; + public static final String TAG = LineStationWellDoubleUnderGroundSetupFragment.class.getName(); + //区分是初始页面还是编辑页面 + private boolean isDefaultPage; + + public static void startCreate(Context context, String projectId, String periodId) { + Bundle bundle = new Bundle(); + bundle.putString(BundleConstants.KEY_PROJECT_ID, projectId); + bundle.putString(BundleConstants.KEY_PERIOD_ID, periodId); + FragmentContainerActivity.start(context, TAG, titleCreate, bundle); + } + + public static void startEdit(Context context, String projectId, String batchId) { + Bundle bundle = new Bundle(); + bundle.putString(BundleConstants.KEY_LINE_ID, batchId); + bundle.putString(BundleConstants.KEY_PROJECT_ID, projectId); + FragmentContainerActivity.start(context, TAG, titleEdit, bundle); + } + + public static LineStationWellDoubleUnderGroundSetupFragment newInstance(Bundle bundle) { + LineStationWellDoubleUnderGroundSetupFragment fragment = new LineStationWellDoubleUnderGroundSetupFragment(); + fragment.setArguments(bundle); + return fragment; + } + + @Override + protected boolean initLeftRightMeasure() { + return false; + } + + @Override + protected int groundLinkLeftMinCount() { + return 1; + } + + @Override + protected int groundSideAMinCount() { + return 1; + } + + @Override + protected int steelAMinCount() { + return 1; + } + + @Override + protected int underGroundLinkMinCount() { + return 2; + } + + @Override + protected int steelBMinCount() { + return 1; + } + + @Override + protected int groundSideBMinCount() { + return 1; + } + + @Override + protected int groundLinkRightMinCount() { + return 1; + } + + @Override + protected void defaultItems(IOnListGetCallback callback) { + if (callback == null || getArguments() == null) { + return; + } + String batchId = getArguments().getString(BundleConstants.KEY_LINE_ID); + isDefaultPage = TextUtils.isEmpty(batchId); + if (isDefaultPage) { + callback.onGet(Arrays.asList( + new StationDetailItem( + Tools.getString(R.string.well_a_surface_connection_direction_limit), + StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_LEFT, + null), + new StationDetailItem( + Tools.getString(R.string.well_a_surface_near_well_point), + StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_A, + null), + new StationDetailItem( + Tools.getString(R.string.a_well_wire), + StationDetailItem.TYPE_WELL_DOUBLE_STEEL_A, + null), + new StationDetailItem( + Tools.getString(R.string.underground_connection_points_min_hint), + StationDetailItem.TYPE_WELL_DOUBLE_UNDERGROUND_LINK, + null), + new StationDetailItem( + Tools.getString(R.string.b_well_wire), + StationDetailItem.TYPE_WELL_DOUBLE_STEEL_B, + null), + new StationDetailItem( + Tools.getString(R.string.well_b_surface_near_well_point), + StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_B, + null), + new StationDetailItem( + Tools.getString(R.string.well_b_surface_connection_direction_limit), + StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_RIGHT, + null) + )); + } else { + loadBatchRecord(batchId, callback); + } + } + + @Override + protected void setup(String projectId, String periodId, String lineName, + List groundLinkLeftDataList, List groundSideADataList, + List steelADataList, List underGroundLinkDataList, + List steelBDataList, List groundSideBDataList, + List groundLinkRightDataList, + Runnable callback) { + //判断数据是否准确 + if (groundLinkLeftDataList.size() < groundLinkLeftMinCount()) { + showErrorMsgForWell(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_LEFT); + return; + } + if (groundSideADataList.size() < groundSideAMinCount()) { + showErrorMsgForWell(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_A); + return; + } + if (steelADataList.size() < steelAMinCount()) { + showErrorMsgForWell(StationDetailItem.TYPE_WELL_DOUBLE_STEEL_A); + return; + } + if (underGroundLinkDataList.size() < underGroundLinkMinCount()) { + showErrorMsgForWell(StationDetailItem.TYPE_WELL_DOUBLE_UNDERGROUND_LINK); + return; + } + if (steelBDataList.size() < steelBMinCount()) { + showErrorMsgForWell(StationDetailItem.TYPE_WELL_DOUBLE_STEEL_B); + return; + } + if (groundSideBDataList.size() < groundSideBMinCount()) { + showErrorMsgForWell(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_SIDE_B); + return; + } + if (groundLinkRightDataList.size() < groundLinkRightMinCount()) { + showErrorMsgForWell(StationDetailItem.TYPE_WELL_DOUBLE_GROUND_LINK_RIGHT); + return; + } + + //存储钢丝点到数据库 + List stationDetailItemList = new ArrayList<>(); + stationDetailItemList.addAll(steelADataList); + stationDetailItemList.addAll(steelBDataList); + //save里有切换到子线程 + PointRecordOperate.saveStationDetailItemListToPointRecord(stationDetailItemList, projectId()); + + //切换线程 + ThreadPoolUtil.execute(() -> { + ILineRecordDataSource stationBatchDataSource = SurveyorDatabaseFactory + .instance.getLineRecordDatabase(); + ISurveyorStationDataSource stationDataSource = SurveyorDatabaseFactory + .instance.getSurveyorStation(); + + String lineId = ""; + if (getArguments() != null) { + lineId = getArguments().getString(BundleConstants.KEY_LINE_ID); + } + if (lineId != null && !lineId.isEmpty()) { + //0.删除原有导线和相关测站 + stationBatchDataSource.deleteSync(lineId); + stationDataSource.deleteByLineIdSync(lineId); + } + + String error = checkValidate(projectId, periodId, + groundSideADataList, + underGroundLinkDataList, + groundSideBDataList); + if (error != null && !error.isEmpty()) { + tipsError(error); + return; + } + //0.处理全局控制点 + PointUtil.globalToProjectControlPoint(groundLinkLeftDataList, projectId); + PointUtil.globalToProjectControlPoint(groundSideADataList, projectId); +// ProjectPointUtil.dealGlobalControlPoints2(steelADataList, projectId); + PointUtil.globalToProjectControlPoint(underGroundLinkDataList, projectId); +// ProjectPointUtil.dealGlobalControlPoints2(steelBDataList, projectId); + PointUtil.globalToProjectControlPoint(groundSideBDataList, projectId); + PointUtil.globalToProjectControlPoint(groundLinkRightDataList, projectId); + //1.创建并存储batch + List lineRecordPointList = getAdapterDataList(); + LineRecord batchRecord = LineRecord.well(LineRecord.TYPE_WELL_DOUBLE_UNDERGROUND, lineName, projectId, periodId, lineRecordPointList); + stationBatchDataSource.save(batchRecord); + + ProjectRecord projectRecord = currentProject(); + boolean showSlopDistance = true; + if (projectRecord != null) { + showSlopDistance = projectRecord.showSlopDistance; + } + + //2.创建测站列表 + long dateValue = (new Date()).getTime(); + List stationRecordList = new ArrayList<>(); + boolean needLeftRightSurveyor = needLeftRightSurveyor(); + + //A井地面近井点 + for (StationDetailItem itemSideA : groundSideADataList) { + List pointList = new ArrayList<>(); + pointList.add(itemSideA); + pointList.addAll(groundLinkLeftDataList); + pointList.addAll(steelADataList); + + SurveyorStationRecord wellStationRecord = SurveyorStationRecord.createWellStationRecord(dateValue++, + projectId, periodId, batchRecord.id, pointList); +// //设置站是否闭合 + if (pointList.size() > SurveyorStationConstants.AUTO_CLOSE_NUM_INCLUDE_STATION) { + wellStationRecord.setAutoClose(true); + } + wellStationRecord.setLeftAndRightSurveyor(needLeftRightSurveyor); + wellStationRecord.setShowSlopDistance(showSlopDistance); + stationRecordList.add(wellStationRecord); + } + + //地下连接点至少两个 + if (underGroundLinkDataList != null && !underGroundLinkDataList.isEmpty()) { + for (int i = 0; i < underGroundLinkDataList.size(); i++) { + List pointList = new ArrayList<>(); + pointList.add(underGroundLinkDataList.get(i)); + + if (i - 1 < 0) { + //第一个节点 + pointList.addAll(steelADataList); + } else { + pointList.add(underGroundLinkDataList.get(i - 1)); + } + + if (i + 1 > underGroundLinkDataList.size() - 1) { + pointList.addAll(steelBDataList); + } else { + pointList.add(underGroundLinkDataList.get(i + 1)); + } + + SurveyorStationRecord wellStationRecord = SurveyorStationRecord.createWellStationRecord(dateValue++, + projectId, periodId, batchRecord.id, pointList); + + //设置站是否闭合 + if (pointList.size() > SurveyorStationConstants.AUTO_CLOSE_NUM_INCLUDE_STATION) { + wellStationRecord.setAutoClose(true); + } + + wellStationRecord.setLeftAndRightSurveyor(needLeftRightSurveyor); + wellStationRecord.setShowSlopDistance(showSlopDistance); + stationRecordList.add(wellStationRecord); + } + } + + //B井地面近井点 + for (StationDetailItem itemSideB : groundSideBDataList) { + List pointList = new ArrayList<>(); + pointList.add(itemSideB); + pointList.addAll(steelBDataList); + pointList.addAll(groundLinkRightDataList); + + SurveyorStationRecord wellStationRecord = SurveyorStationRecord.createWellStationRecord(dateValue++, + projectId, periodId, batchRecord.id, pointList); + //设置站是否闭合 + if (pointList.size() > SurveyorStationConstants.AUTO_CLOSE_NUM_INCLUDE_STATION) { + wellStationRecord.setAutoClose(true); + } + wellStationRecord.setLeftAndRightSurveyor(needLeftRightSurveyor); + wellStationRecord.setShowSlopDistance(showSlopDistance); + stationRecordList.add(wellStationRecord); + } + + + //3.存储新建的测站列表 + stationDataSource.save(stationRecordList); + + if (callback != null) { + callback.run(); + } + }); + + } + + + @Override + protected String defaultLineName() { + return getString(R.string.station_type_well_wire_double); + } + + + private String checkValidate(String projectId, String cycleId, + List groundSideADataList, + List underGroundLinkDataList, + List groundSideBDataList) { + + //如果是编辑页面就不检查 + if (!isDefaultPage) return null; + + //检测该测期下是否有同名测站 + ISurveyorStationDataSource stationDataSource = SurveyorDatabaseFactory.instance.getSurveyorStation(); + List currentStationList = + stationDataSource.getDataList(projectId, cycleId); + + //收集要创建的测站站点id + List expectedStationIds = new ArrayList<>(); + collectIdsFromList(expectedStationIds, groundSideADataList); + collectIdsFromList(expectedStationIds, underGroundLinkDataList); + collectIdsFromList(expectedStationIds, groundSideBDataList); + + if (currentStationList != null) {//遍历当前已有测站,检测是否有同名测站 + for (SurveyorStationRecord record : currentStationList) { + List items = record.getItems(); + if (items != null) {//检测测站名是否相同 + for (SurveyorPoint stationItem : items) { + if (SurveyorPoint.TYPE_STATION.equals(stationItem.getType())) { + for (String stationDetailItemId : expectedStationIds) {//遍历即将创建的测站列表,对比是否有相同的 + if (stationItem.getPointId().equals(stationDetailItemId)) { + PointRecord pointRecord = SurveyorDatabaseFactory + .instance + .getPointDataSource() + .findByIdSync(stationItem.getOriginalPointId()); + if (pointRecord != null) { + return pointRecord.getName(); + } + return ""; + } + } + break; + } + } + } + } + } + return null; + } + + private void collectIdsFromList(List collectIdList, List tagetList) { + for (StationDetailItem stationDetailItem : tagetList) { + String pointId = stationDetailItem.getOriginalPointId(); + if (!TextUtils.isEmpty(pointId)) { + collectIdList.add(pointId); + } + } + } + + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/well/LineStationWellSetupFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/well/LineStationWellSetupFragment.java new file mode 100644 index 0000000..ff2de9c --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/station/line/well/LineStationWellSetupFragment.java @@ -0,0 +1,312 @@ +package com.bingce.controlnetwork.fragment.station.line.well; + +import android.content.Context; +import android.os.Bundle; +import android.text.TextUtils; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.line.ILineRecordDataSource; +import com.bingce.controlapphelper.datasource.database.line.LineRecord; +import com.bingce.controlapphelper.datasource.database.point.PointRecord; +import com.bingce.controlapphelper.datasource.database.point.PointRecordOperate; +import com.bingce.controlapphelper.datasource.database.project.ProjectRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.ISurveyorStationDataSource; +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationConstants; +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.model.SurveyorPoint; +import com.bingce.controlapphelper.model.BundleConstants; +import com.bingce.controlapphelper.model.StationDetailItem; +import com.bingce.controlapphelper.util.PointUtil; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.activity.fragmentcontainer.FragmentContainerActivity; +import com.bingce.controlnetwork.fragment.station.line.AbstractLineStationWellSetupFragment; +import com.bingce.utils.IOnListGetCallback; +import com.bingce.utils.ThreadPoolUtil; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.List; + + +/** + * 新建一井定向 + */ +public class LineStationWellSetupFragment extends AbstractLineStationWellSetupFragment { + + public static final int titleCreate = R.string.title_create_well_line_station; + public static final int titleEdit = R.string.title_edit_well_line_station; + public static final String TAG = LineStationWellSetupFragment.class.getName(); + //区分是初始页面还是编辑页面 + private boolean isDefaultPage; + + public static void startCreate(Context context, String projectId, String periodId) { + Bundle bundle = new Bundle(); + bundle.putString(BundleConstants.KEY_PROJECT_ID, projectId); + bundle.putString(BundleConstants.KEY_PERIOD_ID, periodId); + FragmentContainerActivity.start(context, TAG, titleCreate, bundle); + } + + public static void startEdit(Context context, String projectId, String batchId) { + Bundle bundle = new Bundle(); + bundle.putString(BundleConstants.KEY_LINE_ID, batchId); + bundle.putString(BundleConstants.KEY_PROJECT_ID, projectId); + FragmentContainerActivity.start(context, TAG, titleEdit, bundle); + } + + public static LineStationWellSetupFragment newInstance(Bundle bundle) { + LineStationWellSetupFragment fragment = new LineStationWellSetupFragment(); + fragment.setArguments(bundle); + return fragment; + } + + @Override + protected boolean initLeftRightMeasure() { + return false; + } + + @Override + protected void defaultItems(IOnListGetCallback callback) { + if (callback == null || getArguments() == null) { + return; + } + String batchId = getArguments().getString(BundleConstants.KEY_LINE_ID); + isDefaultPage = TextUtils.isEmpty(batchId); + if (isDefaultPage) { + callback.onGet(Arrays.asList( + new StationDetailItem( + Tools.getString(R.string.ground_connection_direction_one_or_two), + StationDetailItem.ITEM_TYPE_WELL_GROUP_GROUND_LINK, + null), + new StationDetailItem( + Tools.getString(R.string.surface_near_well_point), + StationDetailItem.ITEM_TYPE_WELL_GROUP_GROUND_SIDE, + null), + new StationDetailItem( + Tools.getString(R.string.steel_wire_two_or_three), + StationDetailItem.ITEM_TYPE_WELL_GROUP_STEEL_WIRE, + null), + new StationDetailItem( + Tools.getString(R.string.underground_near_well_point), + StationDetailItem.ITEM_TYPE_WELL_GROUP_UNDERGROUND_SIDE, + null), + new StationDetailItem( + Tools.getString(R.string.underground_connection_direction_one_or_two), + StationDetailItem.ITEM_TYPE_WELL_GROUP_UNDERGROUND_LINK, + null) + )); + } else { + loadBatchRecord(batchId, callback); + } + } + + @Override + protected int groundLinkMinCount() { + return 1; + } + + @Override + protected int groundSideMinCount() { + return 1; + } + + @Override + protected int steelWireMinCount() { + return 2; + } + + @Override + protected int undergroundSideMinCount() { + return 1; + } + + @Override + protected int undergroundLinkMinCount() { + return 1; + } + + @Override + protected String defaultLineName() { + return getString(R.string.station_type_well_wire); + } + + @Override + protected void setup(String projectId, String cycleId, String lineName, + List groundLinkDataList, List groundSideDataList, + List steelWireDataList, List ungroundLinkDataList, + List ungroundSideDataList, Runnable callback) { + //判断数据是否准确 + if (groundLinkDataList.size() < groundLinkMinCount()) { + showErrorMsgForWell(StationDetailItem.ITEM_TYPE_WELL_GROUP_GROUND_LINK); + return; + } + if (groundSideDataList.size() < groundSideMinCount()) { + showErrorMsgForWell(StationDetailItem.ITEM_TYPE_WELL_GROUP_GROUND_SIDE); + return; + } + if (steelWireDataList.size() < steelWireMinCount()) { + showErrorMsgForWell(StationDetailItem.ITEM_TYPE_WELL_GROUP_STEEL_WIRE); + return; + } + if (ungroundLinkDataList.size() < undergroundLinkMinCount()) { + showErrorMsgForWell(StationDetailItem.ITEM_TYPE_WELL_GROUP_UNDERGROUND_LINK); + return; + } + if (ungroundSideDataList.size() < undergroundSideMinCount()) { + showErrorMsgForWell(StationDetailItem.ITEM_TYPE_WELL_GROUP_UNDERGROUND_SIDE); + return; + } + + //存储钢丝点到数据库 + List stationDetailItemList = new ArrayList<>(); + stationDetailItemList.addAll(steelWireDataList); + //save里有切换到子线程 + PointRecordOperate.saveStationDetailItemListToPointRecord(stationDetailItemList, projectId()); + + //切换线程 + ThreadPoolUtil.execute(() -> { + ILineRecordDataSource stationBatchDataSource = SurveyorDatabaseFactory + .instance.getLineRecordDatabase(); + ISurveyorStationDataSource stationDataSource = SurveyorDatabaseFactory + .instance.getSurveyorStation(); + + String lineId = ""; + if (getArguments() != null) { + lineId = getArguments().getString(BundleConstants.KEY_LINE_ID); + } + if (lineId != null && !lineId.isEmpty()) { + //0.删除原有导线和相关测站 + stationBatchDataSource.deleteSync(lineId); + stationDataSource.deleteByLineIdSync(lineId); + } + + String error = checkValidate(projectId, cycleId, + groundSideDataList, ungroundSideDataList); + if (error != null && !error.isEmpty()) { + tipsError(error); + return; + } + //0.处理全局控制点 + PointUtil.globalToProjectControlPoint(groundLinkDataList, projectId); + PointUtil.globalToProjectControlPoint(groundSideDataList, projectId); + PointUtil.globalToProjectControlPoint(steelWireDataList, projectId); + PointUtil.globalToProjectControlPoint(ungroundLinkDataList, projectId); + PointUtil.globalToProjectControlPoint(ungroundSideDataList, projectId); + //1.创建并存储batch + List lineRecordPointList = getAdapterDataList(); + LineRecord batchRecord = LineRecord.well(LineRecord.TYPE_WELL, lineName, projectId, cycleId, lineRecordPointList); + stationBatchDataSource.save(batchRecord); + + ProjectRecord projectRecord = currentProject(); + boolean showSlopDistance = true; + if (projectRecord != null) { + showSlopDistance = projectRecord.showSlopDistance; + } + + //2.创建测站列表 + long dateValue = (new Date()).getTime(); + List stationRecordList = new ArrayList<>(); + boolean needLeftRightSurveyor = needLeftRightSurveyor(); + + for (StationDetailItem groundStationDetailItem : groundSideDataList) { + List pointList = new ArrayList<>(); + pointList.add(groundStationDetailItem); + //添加地上观测点 + pointList.addAll(groundLinkDataList); + //添加钢丝点 + pointList.addAll(steelWireDataList); + SurveyorStationRecord wellStationRecord = SurveyorStationRecord.createWellStationRecord(dateValue++, + projectId, cycleId, batchRecord.id, pointList); + //设置站是否闭合 + if (pointList.size() > SurveyorStationConstants.AUTO_CLOSE_NUM_INCLUDE_STATION) { + wellStationRecord.setAutoClose(true); + } + wellStationRecord.setLeftAndRightSurveyor(needLeftRightSurveyor); + wellStationRecord.setShowSlopDistance(showSlopDistance); + stationRecordList.add(wellStationRecord); + } + + for (StationDetailItem ungroundStationDetailItem : ungroundSideDataList) { + List pointList = new ArrayList<>(); + pointList.add(ungroundStationDetailItem); + //添加地下观测点 + pointList.addAll(ungroundLinkDataList); + //添加钢丝点 + pointList.addAll(steelWireDataList); + SurveyorStationRecord wellStationRecord = SurveyorStationRecord.createWellStationRecord(dateValue++, + projectId, cycleId, batchRecord.id, pointList); + //设置站是否闭合 + if (pointList.size() > SurveyorStationConstants.AUTO_CLOSE_NUM_INCLUDE_STATION) { + wellStationRecord.setAutoClose(true); + } + + wellStationRecord.setLeftAndRightSurveyor(needLeftRightSurveyor); + wellStationRecord.setShowSlopDistance(showSlopDistance); + stationRecordList.add(wellStationRecord); + } + + + //3.存储新建的测站列表 + stationDataSource.save(stationRecordList); + + if (callback != null) { + callback.run(); + } + }); + } + + private String checkValidate(String projectId, String cycleId, + List groundSideDataList, + List ungroundSideDataList) { + //如果是编辑页面就不检查 + if (!isDefaultPage) return null; + + //检测该测期下是否有同名测站 + ISurveyorStationDataSource stationDataSource = SurveyorDatabaseFactory.instance.getSurveyorStation(); + List currentStationList = + stationDataSource.getDataList(projectId, cycleId); + + //收集要创建的测站站点id + List expectedStationIds = new ArrayList<>(); + collectIdsFromList(expectedStationIds, groundSideDataList); + collectIdsFromList(expectedStationIds, ungroundSideDataList); + + if (currentStationList != null) {//遍历当前已有测站,检测是否有同名测站 + for (SurveyorStationRecord record : currentStationList) { + List items = record.getItems(); + if (items != null) {//检测测站名是否相同 + for (SurveyorPoint stationItem : items) { + if (SurveyorPoint.TYPE_STATION.equals(stationItem.getType())) { + for (String stationDetailItemId : expectedStationIds) {//遍历即将创建的测站列表,对比是否有相同的 + if (stationItem.getPointId().equals(stationDetailItemId)) { + PointRecord pointRecord = SurveyorDatabaseFactory + .instance + .getPointDataSource() + .findByIdSync(stationItem.getOriginalPointId()); + if (pointRecord != null) { + return pointRecord.getName(); + } + return ""; + } + } + break; + } + } + } + } + } + return null; + } + + private void collectIdsFromList(List collectIdList, List tagetList) { + for (StationDetailItem stationDetailItem : tagetList) { + String pointId = stationDetailItem.getOriginalPointId(); + if (!TextUtils.isEmpty(pointId)) { + collectIdList.add(pointId); + } + } + } + + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/stationdetail/SingleStationDetailAndEditFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/stationdetail/SingleStationDetailAndEditFragment.java new file mode 100644 index 0000000..8c27a9d --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/stationdetail/SingleStationDetailAndEditFragment.java @@ -0,0 +1,141 @@ +package com.bingce.controlnetwork.fragment.stationdetail; + +import android.content.Context; +import android.os.Bundle; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.lifecycle.ViewModelProvider; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.surveyorstation.ISurveyorStationDataSource; +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord; +import com.bingce.controlapphelper.model.BundleConstants; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.activity.fragmentcontainer.FragmentContainerActivity; +import com.bingce.controlnetwork.fragment.base.BaseFragment; +import com.bingce.controlnetwork.fragment.station.defaultstation.SingleStationDetailAndEditContentFragment; +import com.bingce.controlnetwork.newui.widget.switchtext.SwitchWithText; +import com.bingce.utils.ThreadPoolUtil; + +import org.jetbrains.annotations.NotNull; + + +/** + * 测站编辑--包含编辑测点、站点功能,可能是「多测回测角」,也可能是「导线测站」中某站 + */ +public class SingleStationDetailAndEditFragment extends BaseFragment { + public static final int title = R.string.title_surveyor_station_edit; + public static final String TAG = SingleStationDetailAndEditFragment.class.getName(); + + private StationDetailViewModel stationDetailViewModel; + private String lineType; + private SwitchWithText leftRightSwitch; + private SingleStationDetailAndEditContentFragment contentFragment; + + @Override + public View onCreateView(@NotNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + return inflater.inflate(R.layout.fragment_surveyor_station_detail_or_edit_layout, container, false); + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + if (getArguments() == null) { + return; + } + //创建显示点列表的fragment + String stationId = getArguments().getString(BundleConstants.KEY_SURVEYOR_STATION_ID); + String projectId = getArguments().getString(BundleConstants.KEY_PROJECT_ID); + lineType = getArguments().getString(BundleConstants.KEY_LINE_TYPE); + + leftRightSwitch = view.findViewById(R.id.left_right_switch); + leftRightSwitch.setEnabled(true); + + stationDetailViewModel = new ViewModelProvider(requireActivity()).get(StationDetailViewModel.class); + stationDetailViewModel.getRefreshUiLiveData().observe(getViewLifecycleOwner(), refresh -> { + if (contentFragment != null) { + int surveyorPointSize = contentFragment.getSurveyorPointSize(); + + boolean leftAndRightSurveyor = stationDetailViewModel.isLeftAndRightSurveyor(); + if (surveyorPointSize == 2) { + leftRightSwitch.setVisibility(View.VISIBLE); + leftRightSwitch.setChecked(leftAndRightSurveyor); + updateStationLeftRightSurveyor(leftAndRightSurveyor, stationId); + } else { + leftRightSwitch.setVisibility(View.GONE); + updateStationLeftRightSurveyor(false, stationId); + } + + updateStationAutoClose(surveyorPointSize > 3, stationId); + + } + + }); + + contentFragment = SingleStationDetailAndEditContentFragment.newInstance(stationId, projectId); + //添加fragment + getChildFragmentManager() + .beginTransaction() + .replace(R.id.fragment_container, + contentFragment, + SingleStationDetailAndEditContentFragment.TAG) + .commit(); + + leftRightSwitch.setOnCheckChangeListener(checked -> { + stationDetailViewModel.setLeftOrRight(checked); + updateStationLeftRightSurveyor(checked, stationId); + }); + } + + private void updateStationAutoClose(boolean autoClose, String stationId) { + ThreadPoolUtil.execute(() -> { + ISurveyorStationDataSource surveyorStationDataSource = + SurveyorDatabaseFactory + .instance + .getSurveyorStation(); + SurveyorStationRecord surveyorStationRecord = + surveyorStationDataSource.getRecordSync(stationId); + //修改 + surveyorStationRecord.setAutoClose(autoClose); + //存储 + surveyorStationDataSource.save(surveyorStationRecord); + }); + } + + private void updateStationLeftRightSurveyor(boolean leftRightSurveyor, String stationId) { + Log.d("hwhw", "更新左右角到数据库"); + ThreadPoolUtil.execute(() -> { + ISurveyorStationDataSource surveyorStationDataSource = + SurveyorDatabaseFactory + .instance + .getSurveyorStation(); + SurveyorStationRecord surveyorStationRecord = + surveyorStationDataSource.getRecordSync(stationId); + //修改 + surveyorStationRecord.setLeftAndRightSurveyor(leftRightSurveyor); + //存储 + surveyorStationDataSource.save(surveyorStationRecord); + }); + } + + public static void start(Context context, String surveyorStationId, + String surveyorStationName, String projectId, String lineType) { + Bundle bundle = new Bundle(); + bundle.putString(BundleConstants.KEY_SURVEYOR_STATION_ID, surveyorStationId); + bundle.putString(BundleConstants.KEY_SURVEYOR_STATION_NAME, surveyorStationName); + bundle.putString(BundleConstants.KEY_PROJECT_ID, projectId); + bundle.putString(BundleConstants.KEY_LINE_TYPE, lineType); + FragmentContainerActivity.start(context, TAG, context.getString(title) + "-" + surveyorStationName, bundle); + } + + public static SingleStationDetailAndEditFragment newInstance(Bundle bundle) { + SingleStationDetailAndEditFragment fragment = new SingleStationDetailAndEditFragment(); + fragment.setArguments(bundle); + return fragment; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/stationdetail/StationDetailViewModel.java b/app/src/main/java/com/bingce/controlnetwork/fragment/stationdetail/StationDetailViewModel.java new file mode 100644 index 0000000..41d4dbc --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/stationdetail/StationDetailViewModel.java @@ -0,0 +1,26 @@ +package com.bingce.controlnetwork.fragment.stationdetail; + +import androidx.lifecycle.LiveData; +import androidx.lifecycle.MutableLiveData; +import androidx.lifecycle.ViewModel; + +public class StationDetailViewModel extends ViewModel { + private final MutableLiveData refreshUiLiveData = new MutableLiveData<>(); + private boolean leftAndRightSurveyor; + + public LiveData getRefreshUiLiveData() { + return refreshUiLiveData; + } + + public void setRefreshUi() { + refreshUiLiveData.setValue(true); + } + + public void setLeftOrRight(boolean leftAndRightSurveyor) { + this.leftAndRightSurveyor = leftAndRightSurveyor; + } + + public boolean isLeftAndRightSurveyor() { + return leftAndRightSurveyor; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/stationsetting/BaseStationSettingFragment.kt b/app/src/main/java/com/bingce/controlnetwork/fragment/stationsetting/BaseStationSettingFragment.kt new file mode 100644 index 0000000..eea4028 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/stationsetting/BaseStationSettingFragment.kt @@ -0,0 +1,49 @@ +package com.bingce.controlnetwork.fragment.stationsetting + +import android.os.Bundle +import android.view.Menu +import android.view.MenuInflater +import android.view.MenuItem +import com.bingce.controlnetwork.fragment.base.BaseFragment +import com.bingce.controlnetwork.R + +abstract class BaseStationSettingFragment : BaseFragment() { + + companion object { + const val DEFAULT_TEMPERATURE = "12" + const val DEFAULT_HUMIDITY = "60" + const val DEFAULT_AIR_PRESSURE = "1013.3" + const val DEFAULT_CONSTANT = "0" + const val DEFAULT_INSTRUMEN_HEIGHT = "0" + + const val KEY_SURVEYOR_STATION_ID = "___surveyor_station_id___" + + } + + protected abstract fun clickConfirm() + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setHasOptionsMenu(true) + } + + override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { + inflater.inflate(R.menu.menu_confirm, menu) + super.onCreateOptionsMenu(menu, inflater) + } + + override fun onOptionsItemSelected(item: MenuItem): Boolean { + if (R.id.menu_confirm === item.itemId) { + clickConfirm() + } + return super.onOptionsItemSelected(item) + } + + /** + * 返回非空测站id + */ + fun stationId(): String { + return requireArguments().getString(KEY_SURVEYOR_STATION_ID)!! + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/stationsetting/StationSettingHeightTraverseFragment.kt b/app/src/main/java/com/bingce/controlnetwork/fragment/stationsetting/StationSettingHeightTraverseFragment.kt new file mode 100644 index 0000000..b559ec3 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/stationsetting/StationSettingHeightTraverseFragment.kt @@ -0,0 +1,496 @@ +package com.bingce.controlnetwork.fragment.stationsetting + +import android.content.Context +import android.os.Bundle +import android.text.TextUtils +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.EditText +import androidx.annotation.WorkerThread +import blankj.utilcode.util.ToastUtils +import com.bingce.controlnetwork.activity.fragmentcontainer.FragmentContainerActivity +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory +import com.bingce.controlapphelper.datasource.database.config.ConfigConstants +import com.bingce.controlapphelper.datasource.database.config.ConfigRecord +import com.bingce.controlapphelper.datasource.database.heighttraverse.stationsetting.model.StationSettingHeightTraverseRecord +import com.bingce.controlapphelper.util.Tools +import com.bingce.controlnetwork.R +import com.bingce.controlnetwork.databinding.FragmentStationSettingHeightTraverseBinding +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.MainScope +import kotlinx.coroutines.cancel +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + +class StationSettingHeightTraverseFragment : BaseStationSettingFragment() { + + + private var _binding: FragmentStationSettingHeightTraverseBinding? = null + + val mBinding get() = _binding!! + + private val mainScope = MainScope() + + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + _binding = + FragmentStationSettingHeightTraverseBinding.inflate(inflater, container, false) + return mBinding.root + } + + override fun onDestroyView() { + super.onDestroyView() + mainScope.cancel() + _binding = null + + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + initView() + initData() + initListener() + } + + private fun initListener() { + + //距离修正参数 + mBinding.ilTitle1.button1.setOnClickListener { + //默认设置 + setDataFromRecord(null) + } + + mBinding.ilTitle1.button2.setOnClickListener { + //使用上次数据 + setDataFromLast() + } + + //仪器高,棱镜高 + mBinding.ilInstrumentHeight.button1.setOnClickListener { + mBinding.ilInstrumentHeight.etValueAfter.setText( + getEtText(mBinding.ilInstrumentHeight.etValueBefore) + ) + } + mBinding.ilBackPrismHeight.button1.setOnClickListener { + mBinding.ilBackPrismHeight.etValueAfter.setText( + getEtText(mBinding.ilBackPrismHeight.etValueBefore) + ) + } + mBinding.ilFrontPrismHeight.button1.setOnClickListener { + mBinding.ilFrontPrismHeight.etValueAfter.setText( + getEtText(mBinding.ilFrontPrismHeight.etValueBefore) + ) + } + + } + + private fun setDataFromLast() { + mainScope.launch { + val record = withContext(Dispatchers.IO) { + val dryTemperature = getValueFromLastKey(ConfigConstants.KEY_LAST_DRY_TEMPERATURE) + val humidityTemperature = + getValueFromLastKey(ConfigConstants.KEY_LAST_HUMIDITY_TEMPERATURE) + val airPressure = getValueFromLastKey(ConfigConstants.KEY_LAST_AIR_PRESSURE) + val additionConstant = + getValueFromLastKey(ConfigConstants.KEY_LAST_ADDITION_CONSTANT) + val multiplicationConstant = + getValueFromLastKey(ConfigConstants.KEY_LAST_MULTIPLICATION_CONSTANT) + val instrumentHeightBefore = + getValueFromLastKey(ConfigConstants.KEY_LAST_INSTRUMENT_HEIGHT_BEFORE) + val instrumentHeightAfter = + getValueFromLastKey(ConfigConstants.KEY_LAST_INSTRUMENT_HEIGHT_AFTER) + val backPrismHeightBefore = + getValueFromLastKey(ConfigConstants.KEY_LAST_BACK_PRISM_HEIGHT_BEFORE) + val backPrismHeightAfter = + getValueFromLastKey(ConfigConstants.KEY_LAST_BACK_PRISM_HEIGHT_AFTER) + val frontPrismHeightBefore = + getValueFromLastKey(ConfigConstants.KEY_LAST_FRONT_PRISM_HEIGHT_BEFORE) + val frontPrismHeightAfter = + getValueFromLastKey(ConfigConstants.KEY_LAST_FRONT_PRISM_HEIGHT_AFTER) + + if (dryTemperature == null + || humidityTemperature == null + || airPressure == null + || additionConstant == null + || multiplicationConstant == null + || instrumentHeightBefore == null + || instrumentHeightAfter == null + || backPrismHeightBefore == null + || backPrismHeightAfter == null + || frontPrismHeightBefore == null + || frontPrismHeightAfter == null + ) { + return@withContext null + } + + StationSettingHeightTraverseRecord.newInstance( + stationId(), + dryTemperature, + humidityTemperature, + airPressure, + additionConstant, + multiplicationConstant, + instrumentHeightBefore, + instrumentHeightAfter, + backPrismHeightBefore, + backPrismHeightAfter, + frontPrismHeightBefore, + frontPrismHeightAfter + ) + } + + setDataFromRecord(record) + } + } + + private fun getValueFromLastKey(key: String): String? { + val record = + SurveyorDatabaseFactory.instance.configDataSource.getByKeySync(key) + return record?.configValue + } + + private fun initData() { + + mainScope.launch { + val record = withContext(Dispatchers.IO) { + SurveyorDatabaseFactory.instance.getStationSettingHeightTraverseDataSource() + .getRecordByStationId(stationId()) + } + setDataFromRecord(record) + } + } + + private fun setDataFromRecord(record: StationSettingHeightTraverseRecord?) { + mBinding.ilDryTemperature.etValue.setText( + record?.dryTemperature ?: DEFAULT_TEMPERATURE + ) + mBinding.ilHumidityTemperature.etValue.setText( + record?.humidityTemperature ?: DEFAULT_TEMPERATURE + ) + mBinding.ilAirPressure.etValue.setText(record?.airPressure ?: DEFAULT_AIR_PRESSURE) + mBinding.ilAdditionConstant.etValue.setText( + record?.additionConstant ?: DEFAULT_CONSTANT + ) + mBinding.ilmultiplicationConstant.etValue.setText( + record?.multiplicationConstant ?: DEFAULT_CONSTANT + ) + + mBinding.ilInstrumentHeight.etValueBefore.setText( + record?.instrumentHeightBefore ?: DEFAULT_INSTRUMEN_HEIGHT + ) + mBinding.ilInstrumentHeight.etValueAfter.setText( + record?.instrumentHeightAfter ?: DEFAULT_INSTRUMEN_HEIGHT + ) + mBinding.ilBackPrismHeight.etValueBefore.setText( + record?.backPrismHeightBefore ?: DEFAULT_INSTRUMEN_HEIGHT + ) + mBinding.ilBackPrismHeight.etValueAfter.setText( + record?.backPrismHeightAfter ?: DEFAULT_INSTRUMEN_HEIGHT + ) + mBinding.ilFrontPrismHeight.etValueBefore.setText( + record?.frontPrismHeightBefore ?: DEFAULT_INSTRUMEN_HEIGHT + ) + mBinding.ilFrontPrismHeight.etValueAfter.setText( + record?.frontPrismHeightAfter ?: DEFAULT_INSTRUMEN_HEIGHT + ) + } + + + private fun initView() { + mBinding.ilTitle1.title.text = Tools.getString(R.string.distance_correction_parameter) + mBinding.ilTitle1.button1.text = Tools.getString(R.string.default_setting) + mBinding.ilTitle1.button2.text = Tools.getString(R.string.button_use_last_station_settings) + + mBinding.ilTitle2.title.text = Tools.getString(R.string.instrument_height_prism_height_m) + + + mBinding.ilDryTemperature.tvName.text = getString(R.string.dry_temperature) + mBinding.ilDryTemperature.etValue.hint = getString(R.string.dry_temperature) + mBinding.ilDryTemperature.tvUnit.text = "℃" + + mBinding.ilHumidityTemperature.tvName.text = getString(R.string.humidity_temperature) + mBinding.ilHumidityTemperature.etValue.hint = getString(R.string.humidity_temperature) + mBinding.ilHumidityTemperature.tvUnit.text = "℃" + + mBinding.ilAirPressure.tvName.text = getString(R.string.hint_air_pressure) + mBinding.ilAirPressure.etValue.hint = getString(R.string.hint_air_pressure) + mBinding.ilAirPressure.tvUnit.text = "hPa" + + mBinding.ilAdditionConstant.tvName.text = getString(R.string.addition_constant) + mBinding.ilAdditionConstant.etValue.hint = getString(R.string.addition_constant) + mBinding.ilAdditionConstant.tvUnit.text = "mm" + + mBinding.ilmultiplicationConstant.tvName.text = getString(R.string.multiplication_constant) + mBinding.ilmultiplicationConstant.etValue.hint = getString(R.string.multiplication_constant) + mBinding.ilmultiplicationConstant.tvUnit.text = "ppm" + + mBinding.ilInstrumentHeight.tvName.text = getString(R.string.instrument_height) + mBinding.ilBackPrismHeight.tvName.text = getString(R.string.back_prism_height) + mBinding.ilFrontPrismHeight.tvName.text = getString(R.string.front_prism_height) + } + + companion object { + + @JvmField + val TAG: String = StationSettingHeightTraverseFragment::class.java.name + + @JvmStatic + fun newInstance(bundle: Bundle?): StationSettingHeightTraverseFragment { + val fragment = StationSettingHeightTraverseFragment() + fragment.arguments = bundle + return fragment + } + + @JvmStatic + fun start(context: Context, surveyorStationId: String?) { + val bundle = Bundle() + bundle.putString(KEY_SURVEYOR_STATION_ID, surveyorStationId) + FragmentContainerActivity.start( + context, + TAG, + R.string.surveyor_station_edit, + bundle + ) + } + } + + override fun clickConfirm() { + + mainScope.launch(Dispatchers.IO) { + if (checkConfirmEmpty()) { + return@launch + } + + val stationId = stationId() + + val stationSettingHeightTraverseRecord = + SurveyorDatabaseFactory.instance.getStationSettingHeightTraverseDataSource() + .getRecordByStationId(stationId) + + + val dryTemperature = getEtText(mBinding.ilDryTemperature.etValue) + val humidityTemperature = getEtText(mBinding.ilHumidityTemperature.etValue) + val airPressure = getEtText(mBinding.ilAirPressure.etValue) + val additionConstant = getEtText(mBinding.ilAdditionConstant.etValue) + val multiplicationConstant = getEtText(mBinding.ilmultiplicationConstant.etValue) + val instrumentHeightBefore = getEtText(mBinding.ilInstrumentHeight.etValueBefore) + val instrumentHeightAfter = getEtText(mBinding.ilInstrumentHeight.etValueAfter) + val backPrismHeightBefore = getEtText(mBinding.ilBackPrismHeight.etValueBefore) + val backPrismHeightAfter = getEtText(mBinding.ilBackPrismHeight.etValueAfter) + val frontPrismHeightBefore = getEtText(mBinding.ilFrontPrismHeight.etValueBefore) + val frontPrismHeightAfter = getEtText(mBinding.ilFrontPrismHeight.etValueAfter) + + if (stationSettingHeightTraverseRecord == null) { + val stationSettingHeightTraverseRecordNew = + StationSettingHeightTraverseRecord.newInstance( + stationId, + dryTemperature, + humidityTemperature, + airPressure, + additionConstant, + multiplicationConstant, + instrumentHeightBefore, + instrumentHeightAfter, + backPrismHeightBefore, + backPrismHeightAfter, + frontPrismHeightBefore, + frontPrismHeightAfter + ) + SurveyorDatabaseFactory.instance.getStationSettingHeightTraverseDataSource() + .saveRecord(stationSettingHeightTraverseRecordNew) + } else { + stationSettingHeightTraverseRecord.dryTemperature = dryTemperature + stationSettingHeightTraverseRecord.humidityTemperature = humidityTemperature + stationSettingHeightTraverseRecord.airPressure = airPressure + stationSettingHeightTraverseRecord.additionConstant = additionConstant + stationSettingHeightTraverseRecord.multiplicationConstant = multiplicationConstant + stationSettingHeightTraverseRecord.instrumentHeightBefore = instrumentHeightBefore + stationSettingHeightTraverseRecord.instrumentHeightAfter = instrumentHeightAfter + stationSettingHeightTraverseRecord.backPrismHeightBefore = backPrismHeightBefore + stationSettingHeightTraverseRecord.backPrismHeightAfter = backPrismHeightAfter + stationSettingHeightTraverseRecord.frontPrismHeightBefore = frontPrismHeightBefore + stationSettingHeightTraverseRecord.frontPrismHeightAfter = frontPrismHeightAfter + SurveyorDatabaseFactory.instance.getStationSettingHeightTraverseDataSource() + .updateRecord(stationSettingHeightTraverseRecord) + } + + val stationRecord = + SurveyorDatabaseFactory.instance.surveyorStation.getRecordSync(stationId) + if (stationRecord != null) { + stationRecord.instrumentHeight = instrumentHeightBefore + if (!stationRecord.items.isNullOrEmpty()) { + stationRecord.items.last().prismHeight = frontPrismHeightBefore + if (stationRecord.items.size > 2) { + stationRecord.items[1].prismHeight = backPrismHeightBefore + } + } + } + SurveyorDatabaseFactory.instance.surveyorStation.update(stationRecord) + + saveLastData( + dryTemperature, + humidityTemperature, + airPressure, + additionConstant, + multiplicationConstant, + instrumentHeightBefore, + instrumentHeightAfter, + backPrismHeightBefore, + backPrismHeightAfter, + frontPrismHeightBefore, + frontPrismHeightAfter + ) + + ToastUtils.showShort(R.string.save_success) + requireActivity().finish() + + } + + } + + @WorkerThread + private fun saveLastData( + dryTemperature: String, + humidityTemperature: String, + airPressure: String, + additionConstant: String, + multiplicationConstant: String, + instrumentHeightBefore: String, + instrumentHeightAfter: String, + backPrismHeightBefore: String, + backPrismHeightAfter: String, + frontPrismHeightBefore: String, + frontPrismHeightAfter: String + ) { + SurveyorDatabaseFactory.instance.configDataSource.recordSync( + ConfigRecord( + ConfigConstants.KEY_LAST_DRY_TEMPERATURE, + dryTemperature + ) + ) + SurveyorDatabaseFactory.instance.configDataSource.recordSync( + ConfigRecord( + ConfigConstants.KEY_LAST_HUMIDITY_TEMPERATURE, + humidityTemperature + ) + ) + SurveyorDatabaseFactory.instance.configDataSource.recordSync( + ConfigRecord( + ConfigConstants.KEY_LAST_AIR_PRESSURE, + airPressure + ) + ) + SurveyorDatabaseFactory.instance.configDataSource.recordSync( + ConfigRecord( + ConfigConstants.KEY_LAST_ADDITION_CONSTANT, + additionConstant + ) + ) + SurveyorDatabaseFactory.instance.configDataSource.recordSync( + ConfigRecord( + ConfigConstants.KEY_LAST_MULTIPLICATION_CONSTANT, + multiplicationConstant + ) + ) + SurveyorDatabaseFactory.instance.configDataSource.recordSync( + ConfigRecord( + ConfigConstants.KEY_LAST_INSTRUMENT_HEIGHT_BEFORE, + instrumentHeightBefore + ) + ) + SurveyorDatabaseFactory.instance.configDataSource.recordSync( + ConfigRecord( + ConfigConstants.KEY_LAST_INSTRUMENT_HEIGHT_AFTER, + instrumentHeightAfter + ) + ) + SurveyorDatabaseFactory.instance.configDataSource.recordSync( + ConfigRecord( + ConfigConstants.KEY_LAST_BACK_PRISM_HEIGHT_BEFORE, + backPrismHeightBefore + ) + ) + SurveyorDatabaseFactory.instance.configDataSource.recordSync( + ConfigRecord( + ConfigConstants.KEY_LAST_BACK_PRISM_HEIGHT_AFTER, + backPrismHeightAfter + ) + ) + SurveyorDatabaseFactory.instance.configDataSource.recordSync( + ConfigRecord( + ConfigConstants.KEY_LAST_FRONT_PRISM_HEIGHT_BEFORE, + frontPrismHeightBefore + ) + ) + SurveyorDatabaseFactory.instance.configDataSource.recordSync( + ConfigRecord( + ConfigConstants.KEY_LAST_FRONT_PRISM_HEIGHT_AFTER, + frontPrismHeightAfter + ) + ) + } + + + private fun checkConfirmEmpty(): Boolean { + if (editTextEmpty(mBinding.ilDryTemperature.etValue)) { + ToastUtils.showShort(R.string.please_enter_dry_temperature) + return true + } + if (editTextEmpty(mBinding.ilHumidityTemperature.etValue)) { + ToastUtils.showShort(R.string.please_enter_humidity_temperature) + return true + } + if (editTextEmpty(mBinding.ilAirPressure.etValue)) { + ToastUtils.showShort(Tools.getString(R.string.please_enter_air_pressure)) + return true + } + if (editTextEmpty(mBinding.ilAdditionConstant.etValue)) { + ToastUtils.showShort(R.string.please_enter_addition_constant) + return true + } + if (editTextEmpty(mBinding.ilmultiplicationConstant.etValue)) { + ToastUtils.showShort(R.string.please_enter_multiplication_constant) + return true + } + + if (editTextEmpty(mBinding.ilInstrumentHeight.etValueBefore)) { + ToastUtils.showShort(R.string.please_enter_instrument_height_before) + return true + } + if (editTextEmpty(mBinding.ilInstrumentHeight.etValueAfter)) { + ToastUtils.showShort(R.string.please_enter_instrument_height_after) + return true + } + if (editTextEmpty(mBinding.ilBackPrismHeight.etValueBefore)) { + ToastUtils.showShort(R.string.please_enter_back_prism_height_before) + return true + } + if (editTextEmpty(mBinding.ilBackPrismHeight.etValueAfter)) { + ToastUtils.showShort(R.string.please_enter_back_prism_height_after) + return true + } + if (editTextEmpty(mBinding.ilFrontPrismHeight.etValueBefore)) { + ToastUtils.showShort(R.string.please_enter_front_prism_height_before) + return true + } + if (editTextEmpty(mBinding.ilFrontPrismHeight.etValueAfter)) { + ToastUtils.showShort(R.string.please_enter_front_prism_height_after) + return true + } + return false + } + + + private fun editTextEmpty(et: EditText): Boolean { + return TextUtils.isEmpty(getEtText(et)) + } + + private fun getEtText(et: EditText) = et.text.toString().trim() + + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/stationsetting/StationSettingsFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/stationsetting/StationSettingsFragment.java new file mode 100644 index 0000000..7fc342e --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/stationsetting/StationSettingsFragment.java @@ -0,0 +1,774 @@ +package com.bingce.controlnetwork.fragment.stationsetting; + +import android.content.Context; +import android.os.Bundle; +import android.text.Editable; +import android.text.TextWatcher; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.CheckBox; +import android.widget.Spinner; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.datasource.database.ProjectType; +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.config.ConfigConstants; +import com.bingce.controlapphelper.datasource.database.config.ConfigRecord; +import com.bingce.controlapphelper.datasource.database.config.IConfigDataSource; +import com.bingce.controlapphelper.datasource.database.point.IPointDataSource; +import com.bingce.controlapphelper.datasource.database.point.PointRecord; +import com.bingce.controlapphelper.datasource.database.prism.IPrismManagerDataSource; +import com.bingce.controlapphelper.datasource.database.prism.PrismRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.model.SurveyorPoint; +import com.bingce.controlapphelper.util.HideKeyUtil; +import com.bingce.controlapphelper.util.StationUtil; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.activity.fragmentcontainer.FragmentContainerActivity; +import com.bingce.controlnetwork.adapter.BaseAdapter; +import com.bingce.controlnetwork.adapter.SpinnerAdapter; +import com.bingce.utils.ThreadPoolUtil; +import com.rengwuxian.materialedittext.MaterialEditText; + +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +import blankj.utilcode.util.ToastUtils; + +/** + * 仪器棱镜设置 + */ +public class StationSettingsFragment extends BaseStationSettingFragment { + public static final String TAG = StationSettingsFragment.class.getName(); + private SurveyorStationRecord surveyorStationRecord; + private _Adapter adapter = null; + private List prismRecords; + + private StationSettingsFragment() { + super(); + } + + @Nullable + @Override + public View onCreateView(@NonNull @NotNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.fragment_list_layout, container, false); + RecyclerView recyclerView = view.findViewById(R.id.list); + if (recyclerView != null && getArguments() != null) { + String stationId = getArguments().getString(KEY_SURVEYOR_STATION_ID); + ThreadPoolUtil.execute(() -> { + surveyorStationRecord = + SurveyorDatabaseFactory.instance.getSurveyorStation() + .getRecordSync(stationId); + if (surveyorStationRecord == null) { + return; + } + + + IConfigDataSource configDataSource = + SurveyorDatabaseFactory + .instance.getConfigDataSource(); + + ConfigRecord temperature = configDataSource.getByKeySync(ConfigConstants.KEY_LAST_TEMPERATURE); + ConfigRecord humidity = configDataSource.getByKeySync(ConfigConstants.KEY_LAST_HUMIDITY); + ConfigRecord airPress = configDataSource.getByKeySync(ConfigConstants.KEY_LAST_AIR_PRESSURE); + + List<_Item> items = new ArrayList<>(); + //添加环境title + items.add(new _TitleWithButtonItem(getString(R.string.title_set_environment_info), + getString(R.string.button_use_default_station_settings), + getString(R.string.button_use_last_station_settings), + items)); + //添加温度 + items.add(new _1EditTextItem(getString(R.string.hint_temperature), + temperature(surveyorStationRecord, temperature, DEFAULT_TEMPERATURE), + getString(R.string.hint_temperature), + "℃", + _VH.ATTRIBUTE_TEMPERATURE, + surveyorStationRecord)); + //添加湿度 + items.add(new _1EditTextItem(getString(R.string.hint_humidity), + humidity(surveyorStationRecord, humidity, DEFAULT_HUMIDITY), + getString(R.string.hint_humidity), + "%", + _VH.ATTRIBUTE_HUMIDITY, + surveyorStationRecord)); + //添加气压 + items.add(new _1EditTextItem(getString(R.string.hint_air_pressure), + airPress(surveyorStationRecord, airPress, DEFAULT_AIR_PRESSURE), + getString(R.string.hint_air_pressure), + "hPa", + _VH.ATTRIBUTE_AIR_PRESSURE, + surveyorStationRecord)); + + if (surveyorStationRecord.getTemperature() == null) { + surveyorStationRecord.setTemperature(DEFAULT_TEMPERATURE); + } + if (surveyorStationRecord.getHumidity() == null) { + surveyorStationRecord.setHumidity(DEFAULT_HUMIDITY); + } + if (surveyorStationRecord.getAirPressure() == null) { + surveyorStationRecord.setAirPressure(DEFAULT_AIR_PRESSURE); + } + + //添加高度title + items.add(new _TitleItem(getString(R.string.title_set_height_info))); + //添加仪器高 + items.add(new _1EditTextItem(getString(R.string.instrument_height), + valueOf(surveyorStationRecord.getInstrumentHeight()), + getString(R.string.instrument_height), + "m", + _VH.ATTRIBUTE_INSTRUMENT_HEIGHT, + surveyorStationRecord)); + if (surveyorStationRecord.getInstrumentHeight() == null) { + surveyorStationRecord.setInstrumentHeight("0"); + } + //是否是联系测量 + boolean isConnection = ProjectType.isConnection(surveyorStationRecord.projectType); + + //添加point title + items.add(new _PointTitleItem(isConnection)); + //添加点坐标 + IPointDataSource pointDataSource = SurveyorDatabaseFactory.instance.getPointDataSource(); + List stationItems = surveyorStationRecord.getItems(); + + IPrismManagerDataSource prismManagerDataSource = SurveyorDatabaseFactory.instance.getPrismManagerDataSource(); + prismRecords = prismManagerDataSource.getAllRecordSync(); + + boolean stationHasRecord = StationUtil.hasRecord(surveyorStationRecord.getId()); + if (stationItems != null) { + for (SurveyorPoint surveyorPoint : stationItems) { + if (surveyorPoint == null || !SurveyorPoint.TYPE_POINT.equals(surveyorPoint.getType())) { + continue; + } + if (surveyorPoint.isWellSteel()) { + continue; + } + + if (surveyorPoint.getPrismHeight() == null) { + surveyorPoint.setPrismHeight("0"); + } + + //当是测点的时候 + PointRecord pointRecord = pointDataSource.findByIdSync(surveyorPoint.getOriginalPointId()); + items.add(new _2EditTextItem( + pointRecord.getName(), + surveyorPoint, + prismRecords, + !stationHasRecord, + isConnection + )); + } + } + //刷新recycle view + adapter = new _Adapter(items); + runOnUI(() -> recyclerView.setAdapter(adapter)); + }); + } + return view; + } + + @Override + protected void clickConfirm() { + if (adapter != null) { + String error = adapter.checkSave(); + if (error == null || error.isEmpty()) {//成功 + SurveyorDatabaseFactory + .instance + .getSurveyorStation() + .save(surveyorStationRecord); + + IConfigDataSource configDataSource = + SurveyorDatabaseFactory.instance.getConfigDataSource(); + configDataSource.set(ConfigConstants.KEY_LAST_TEMPERATURE, surveyorStationRecord.getTemperature()); + configDataSource.set(ConfigConstants.KEY_LAST_AIR_PRESSURE, surveyorStationRecord.getAirPressure()); + configDataSource.set(ConfigConstants.KEY_LAST_HUMIDITY, surveyorStationRecord.getHumidity()); + + HideKeyUtil.hideSoftInput(getActivity()); + if (getActivity() != null) { + getActivity().finish(); + } + } else { + ToastUtils.showShort(error); + } + } + } + + private abstract static class _Item { + final int type; + final String name; + View itemView = null; + + _Item(int type, String name) { + this.type = type; + this.name = name; + } + + void attach(View itemView) { + this.itemView = itemView; + } + + abstract String prepare2Save(); + } + + private static class _TitleItem extends _Item { + _TitleItem(String name) { + super(_VH.TYPE_TITLE, name); + } + + @Override + String prepare2Save() { + return null; + } + } + + private static class _TitleWithButtonItem extends _Item { + final String button1; + final String button2; + final List<_Item> items; + + _TitleWithButtonItem(String name, String button1, String button2, List<_Item> items) { + super(_VH.TYPE_TITLE_WITH_2BUTTON, name); + this.button1 = button1; + this.button2 = button2; + this.items = items; + } + + @Override + String prepare2Save() { + return null; + } + } + + private static class _PointTitleItem extends _Item { + private final boolean isConnection;//是否是联系测量 + + _PointTitleItem(boolean isConnection) { + super(_VH.TYPE_POINT_TITLE, null); + this.isConnection = isConnection; + } + + @Override + String prepare2Save() { + return null; + } + + @Override + void attach(View itemView) { + super.attach(itemView); + TextView tvAloneDistanceTitle = itemView.findViewById(R.id.tvAloneDistanceTitle); + if (isConnection) { + tvAloneDistanceTitle.setVisibility(View.VISIBLE); + } else { + tvAloneDistanceTitle.setVisibility(View.INVISIBLE); + } + } + } + + private static class _1EditTextItem extends _Item { + private final String value; + private final String hintString; + private final String unit; + private final SurveyorStationRecord stationRecord; + private final int attributeType; + + _1EditTextItem(String name, String value, + String hintString, String unit, + int attributeType, + SurveyorStationRecord stationRecord) { + super(_VH.TYPE_1_EDIT_TEXT, name); + this.value = value; + this.hintString = hintString; + this.unit = unit; + this.attributeType = attributeType; + this.stationRecord = stationRecord; + } + + @Override + void attach(View itemView) { + super.attach(itemView); + MaterialEditText value = itemView.findViewById(R.id.value); + if (value != null) { + Watcher watcher = new Watcher() { + @Override + void onChanged(String string) { + if (_VH.ATTRIBUTE_TEMPERATURE == attributeType) { + stationRecord.setTemperature(string); + } else if (_VH.ATTRIBUTE_HUMIDITY == attributeType) { + stationRecord.setHumidity(string); + } else if (_VH.ATTRIBUTE_AIR_PRESSURE == attributeType) { + stationRecord.setAirPressure(string); + } else if (_VH.ATTRIBUTE_INSTRUMENT_HEIGHT == attributeType) { + stationRecord.setInstrumentHeight(string); + } + } + }; + value.addTextChangedListener(watcher); + } + } + + @Override + String prepare2Save() { + if (_VH.ATTRIBUTE_TEMPERATURE == attributeType) { + if (!isEmptyString(stationRecord.getTemperature())) { + return null; + } + } else if (_VH.ATTRIBUTE_HUMIDITY == attributeType) { + if (!isEmptyString(stationRecord.getHumidity())) { + return null; + } + } else if (_VH.ATTRIBUTE_AIR_PRESSURE == attributeType) { + if (!isEmptyString(stationRecord.getAirPressure())) { + return null; + } + } else if (_VH.ATTRIBUTE_INSTRUMENT_HEIGHT == attributeType) { + if (!isEmptyString(stationRecord.getInstrumentHeight())) { + return null; + } + } + return Tools.getString(R.string.please_enter) + name; + } + } + + private static class _2EditTextItem extends _Item { + private final SurveyorPoint surveyorPoint; + private final List prismRecords; + private final boolean isCanSelectAloneDistance; + private final boolean isConnection;//是否是联系测量 + private final List prismTypes; + + _2EditTextItem(String pointName, + SurveyorPoint surveyorPoint, + List prismRecords, + boolean isCanSelectAloneDistance, + boolean isConnection) { + super(_VH.TYPE_2_EDIT_TEXT, pointName); + this.surveyorPoint = surveyorPoint; + this.prismRecords = prismRecords; + this.isCanSelectAloneDistance = isCanSelectAloneDistance; + this.isConnection = isConnection; + prismTypes = new ArrayList<>(); + for (PrismRecord prismRecord : prismRecords) { + prismTypes.add(prismRecord.getShowPrismTypeName()); + } + } + + @Override + void attach(View itemView) { + super.attach(itemView); + MaterialEditText value1 = itemView.findViewById(R.id.value1); + if (value1 != null) { + value1.addTextChangedListener(new Watcher() { + @Override + void onChanged(String string) { + surveyorPoint.setPrismHeight(string); + } + }); + } + + Spinner spinner = itemView.findViewById(R.id.spinner); + if (spinner != null) { + spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView parent, View view, int position, long id) { + PrismRecord prismRecord = prismRecords.get(position); + surveyorPoint.setPrismType(prismRecord.prismType); + surveyorPoint.setPrismTypeConstant(prismRecord.prismTypeConstant); + surveyorPoint.setPrismTypeName(prismRecord.getShowPrismTypeName()); + } + + @Override + public void onNothingSelected(AdapterView parent) { + + } + }); + } + + CheckBox checkBox = itemView.findViewById(R.id.checkBox); + if (checkBox != null) { + if (isConnection) { + checkBox.setVisibility(View.VISIBLE); + checkBox.setEnabled(isCanSelectAloneDistance); + checkBox.setOnCheckedChangeListener((compoundButton, checked) -> { + surveyorPoint.setAloneDistance(checked); + }); + } else { + checkBox.setVisibility(View.INVISIBLE); + } + } + + } + + @Override + String prepare2Save() { + if (!isEmptyString(surveyorPoint.getPrismHeight())) { + return null; + } + return Tools.getString(R.string.please_enter) + name + Tools.getString(R.string.prism_height); + } + } + + private static abstract class _VH extends RecyclerView.ViewHolder { + static final int TYPE_TITLE = 0; + static final int TYPE_TITLE_WITH_2BUTTON = TYPE_TITLE + 1; + static final int TYPE_POINT_TITLE = TYPE_TITLE_WITH_2BUTTON + 1; + static final int TYPE_1_EDIT_TEXT = TYPE_POINT_TITLE + 1; + static final int TYPE_2_EDIT_TEXT = TYPE_1_EDIT_TEXT + 1; + + static final int ATTRIBUTE_TEMPERATURE = 0;//温度 + static final int ATTRIBUTE_HUMIDITY = ATTRIBUTE_TEMPERATURE + 1;//湿度 + static final int ATTRIBUTE_AIR_PRESSURE = ATTRIBUTE_HUMIDITY + 1;//气压 + static final int ATTRIBUTE_INSTRUMENT_HEIGHT = ATTRIBUTE_AIR_PRESSURE + 1;//仪器高 + + public _VH(@NonNull @NotNull View itemView) { + super(itemView); + } + + abstract void setup(_Item item); + } + + private static class _TitleVH extends _VH { + private final TextView titleText; + + public _TitleVH(@NonNull @NotNull View itemView) { + super(itemView); + titleText = itemView.findViewById(R.id.title); + } + + @Override + void setup(_Item item) { + if (titleText != null) { + titleText.setText(item.name); + } + } + } + + private static class _TitleWith2ButtonVH extends _TitleVH { + final TextView button1; + final TextView button2; + + public _TitleWith2ButtonVH(@NonNull @NotNull View itemView) { + super(itemView); + button1 = itemView.findViewById(R.id.button1); + button2 = itemView.findViewById(R.id.button2); + } + + @Override + void setup(_Item item) { + super.setup(item); + if (item instanceof _TitleWithButtonItem) { + _TitleWithButtonItem titleWithButtonItem = (_TitleWithButtonItem) item; + if (button1 != null) { + button1.setText(titleWithButtonItem.button1); + button1.setOnClickListener(v -> update(titleWithButtonItem.items, + DEFAULT_TEMPERATURE, DEFAULT_HUMIDITY, DEFAULT_AIR_PRESSURE)); + } + if (button2 != null) { + button2.setText(titleWithButtonItem.button2); + //判断能否点击 + ThreadPoolUtil.execute(() -> { + IConfigDataSource configDataSource = + SurveyorDatabaseFactory + .instance.getConfigDataSource(); + + ConfigRecord temperature = configDataSource.getByKeySync(ConfigConstants.KEY_LAST_TEMPERATURE); + ConfigRecord humidity = configDataSource.getByKeySync(ConfigConstants.KEY_LAST_HUMIDITY); + ConfigRecord airPress = configDataSource.getByKeySync(ConfigConstants.KEY_LAST_AIR_PRESSURE); + if (temperature != null && humidity != null && airPress != null) { + ThreadPoolUtil.executeInMain(() -> { + button2.setEnabled(true); + button2.setAlpha(1); + button2.setOnClickListener(v -> update(titleWithButtonItem.items, + temperature.getConfigValue(), + humidity.getConfigValue(), + airPress.getConfigValue())); + }); + } + }); + } + } + } + + private void update(List<_Item> items, String temperature, String humidity, String airPress) { + for (int index = 0; index < items.size(); index++) { + _Item item = items.get(index); + if (!(item instanceof _1EditTextItem)) { + continue; + } + _1EditTextItem editTextItem = (_1EditTextItem) item; + MaterialEditText value = item.itemView.findViewById(R.id.value); + if (editTextItem.attributeType == _VH.ATTRIBUTE_TEMPERATURE) {//温度 + if (value != null) { + value.setText(temperature); + } + } else if (editTextItem.attributeType == _VH.ATTRIBUTE_AIR_PRESSURE) {//气压 + if (value != null) { + value.setText(airPress); + } + } else if (editTextItem.attributeType == _VH.ATTRIBUTE_HUMIDITY) {//湿度 + if (value != null) { + value.setText(humidity); + } + } + } + } + } + + private static class _PointTitleVH extends _VH { + public _PointTitleVH(@NonNull @NotNull View itemView) { + super(itemView); + } + + @Override + void setup(_Item item) { + } + } + + private static class _1EditTextVH extends _VH { + private final TextView name; + private final MaterialEditText value; + private final TextView unit; + + public _1EditTextVH(@NonNull @NotNull View itemView) { + super(itemView); + name = itemView.findViewById(R.id.name); + value = itemView.findViewById(R.id.value); + unit = itemView.findViewById(R.id.unit); + } + + @Override + void setup(_Item item) { + if (item instanceof _1EditTextItem) { + _1EditTextItem editTextItem = (_1EditTextItem) item; + if (name != null) { + name.setText(editTextItem.name); + } + String v1 = null; + if (editTextItem.attributeType == _VH.ATTRIBUTE_INSTRUMENT_HEIGHT) { + v1 = editTextItem.stationRecord.getInstrumentHeight(); + } else if (editTextItem.attributeType == _VH.ATTRIBUTE_TEMPERATURE) {//温度 + v1 = editTextItem.stationRecord.getTemperature(); + } else if (editTextItem.attributeType == _VH.ATTRIBUTE_AIR_PRESSURE) {//气压 + v1 = editTextItem.stationRecord.getAirPressure(); + } else if (editTextItem.attributeType == _VH.ATTRIBUTE_HUMIDITY) {//湿度 + v1 = editTextItem.stationRecord.getHumidity(); + } + + + if (value != null) { + value.setText(v1); + value.setHint(editTextItem.hintString); + } + if (unit != null) { + unit.setText(editTextItem.unit); + } + } + } + } + + private static class _2EditTextVH extends _VH { + private final TextView tvPointName; + private final MaterialEditText etPrismHeight; + private final Spinner spinnerPrismType; + private final CheckBox checkBoxAloneDistance; + + public _2EditTextVH(@NonNull @NotNull View itemView) { + super(itemView); + tvPointName = itemView.findViewById(R.id.name); + etPrismHeight = itemView.findViewById(R.id.value1); + spinnerPrismType = itemView.findViewById(R.id.spinner); + checkBoxAloneDistance = itemView.findViewById(R.id.checkBox); + } + + @Override + void setup(_Item item) { + if (item instanceof _2EditTextItem) { + _2EditTextItem editTextItem = (_2EditTextItem) item; + if (tvPointName != null) { + tvPointName.setText(editTextItem.name); + } + + if (etPrismHeight != null) { + etPrismHeight.setText(editTextItem.surveyorPoint.getPrismHeight()); + } + + if (spinnerPrismType != null) { + SpinnerAdapter spinnerAdapter = new SpinnerAdapter(itemView.getContext(), editTextItem.prismTypes); + spinnerPrismType.setAdapter(spinnerAdapter); + spinnerPrismType.setSelection(editTextItem.prismTypes.indexOf(editTextItem.surveyorPoint.getPrismTypeName())); + } + + if (checkBoxAloneDistance != null) { + checkBoxAloneDistance.setChecked(editTextItem.surveyorPoint.isAloneDistance()); + } + + } + } + } + + private static class _Adapter extends BaseAdapter<_Item, _VH> { + + public _Adapter(List<_Item> items) { + super(items); + } + + @Override + public int getItemViewType(int position) { + _Item item = getItem(position); + return item.type; + } + + @Override + protected _VH createVH(@NotNull ViewGroup parent, int viewType) { + if (_VH.TYPE_TITLE == viewType) { + View itemView = LayoutInflater + .from(parent.getContext()) + .inflate(R.layout.item_surveyor_station_settings_title_layout, parent, false); + return new _TitleVH(itemView); + } else if (_VH.TYPE_TITLE_WITH_2BUTTON == viewType) { + View itemView = LayoutInflater + .from(parent.getContext()) + .inflate(R.layout.item_surveyor_station_settings_title_with_2button_layout, parent, false); + return new _TitleWith2ButtonVH(itemView); + } else if (_VH.TYPE_POINT_TITLE == viewType) { + View itemView = LayoutInflater + .from(parent.getContext()) + .inflate(R.layout.item_surveyor_station_settings_point_title_layout, parent, false); + return new _PointTitleVH(itemView); + } else if (_VH.TYPE_1_EDIT_TEXT == viewType) { + View itemView = LayoutInflater + .from(parent.getContext()) + .inflate(R.layout.item_surveyor_station_settings_1_edittext_layout, parent, false); + return new _1EditTextVH(itemView); + } else if (_VH.TYPE_2_EDIT_TEXT == viewType) { + View itemView = LayoutInflater + .from(parent.getContext()) + .inflate(R.layout.item_surveyor_station_settings_2_edittext_layout, parent, false); + return new _2EditTextVH(itemView); + } + return null; + } + + @Override + public void onBindViewHolder(@NonNull @NotNull StationSettingsFragment._VH holder, int position) { + _Item item = getItem(position); + item.attach(holder.itemView); + holder.setup(item); + } + + /** + * 保存前的检查 + * + * @return + */ + String checkSave() { + for (int index = 0; index < getItemCount(); index++) { + _Item item = getItem(index); + String error = item.prepare2Save(); + if (error != null && !error.isEmpty()) { + return error; + } + } + return null; + } + } + + private static String getString(MaterialEditText editText) { + if (editText == null) { + return ""; + } + if (editText.getText() == null) { + return ""; + } + return editText.getText().toString(); + } + + private String valueOf(String value) { + if (value == null) { + return ""; + } + return value; + } + + public static StationSettingsFragment newInstance(Bundle bundle) { + StationSettingsFragment fragment = new StationSettingsFragment(); + fragment.setArguments(bundle); + return fragment; + } + + public static void start(Context context, String surveyorStationId) { + Bundle bundle = new Bundle(); + bundle.putString(KEY_SURVEYOR_STATION_ID, surveyorStationId); + FragmentContainerActivity.start(context, TAG, R.string.title_instrument_prism_setting, bundle); + } + + private String temperature(SurveyorStationRecord surveyorStationRecord, + ConfigRecord lastRecord, + String defaultRecord) { + if (surveyorStationRecord != null && !valueOf(surveyorStationRecord.temperature).isEmpty()) { + return surveyorStationRecord.temperature; + } + + return configValue(lastRecord, defaultRecord); + } + + private String humidity(SurveyorStationRecord surveyorStationRecord, + ConfigRecord lastRecord, + String defaultRecord) { + if (surveyorStationRecord != null && !valueOf(surveyorStationRecord.humidity).isEmpty()) { + return surveyorStationRecord.humidity; + } + + return configValue(lastRecord, defaultRecord); + } + + private String airPress(SurveyorStationRecord surveyorStationRecord, + ConfigRecord lastRecord, + String defaultRecord) { + if (surveyorStationRecord != null && !valueOf(surveyorStationRecord.airPressure).isEmpty()) { + return surveyorStationRecord.airPressure; + } + + return configValue(lastRecord, defaultRecord); + } + + private String configValue(ConfigRecord lastRecord, String defaultRecord) { + if (lastRecord != null && !valueOf(lastRecord.getConfigValue()).isEmpty()) { + return lastRecord.getConfigValue(); + } + return defaultRecord; + } + + private abstract static class Watcher implements TextWatcher { + @Override + final public void beforeTextChanged(CharSequence s, int start, int count, int after) { + + } + + @Override + final public void onTextChanged(CharSequence s, int start, int before, int count) { + + } + + @Override + final public void afterTextChanged(Editable s) { + onChanged(s.toString()); + } + + abstract void onChanged(String string); + } + + private static boolean isEmptyString(String string) { + return string == null || string.isEmpty(); + } + + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/IMeasureOperate.java b/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/IMeasureOperate.java new file mode 100644 index 0000000..ac6ee3c --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/IMeasureOperate.java @@ -0,0 +1,28 @@ +package com.bingce.controlnetwork.fragment.stationsurvey; + +/** + * 开始测量等操作接口 + */ +public interface IMeasureOperate { + void doSurveyor(); + + void autoSurvey(); + + void switchCycle(int cycleIndex); + + void deleteStationAllPeroidRecord(); + + void deleteStationOnePeriodRecord(int cycleIndex); + + String stationCheck(); + + void stationAdjust(); + + void goBack(); + + boolean isCurrentCycleComplete(); + + void refreshGoBackBtnEnable(); + + int measureTypePosition(); +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/MethodCheckSetting.java b/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/MethodCheckSetting.java new file mode 100644 index 0000000..3a14141 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/MethodCheckSetting.java @@ -0,0 +1,93 @@ +package com.bingce.controlnetwork.fragment.stationsurvey; + +import androidx.annotation.NonNull; +import androidx.annotation.WorkerThread; +import androidx.fragment.app.Fragment; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.surveyorstation.ISurveyorStationDataSource; +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.model.SurveyorPoint; +import com.bingce.controlapphelper.util.IUIRunner; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.fragment.TipsWith2OptionFragment; +import com.bingce.controlnetwork.newui.stationsetting.StationSettingsActivity; + +import java.util.List; + +public class MethodCheckSetting { + /** + * 检测测站是否设置了棱镜相关属性,如果没有则跳转到设置界面 + */ + @WorkerThread + public static void checkStationSettings(String stationId, + @NonNull Fragment fragment, + @NonNull IUIRunner runner) { + ISurveyorStationDataSource stationDataSource = + SurveyorDatabaseFactory.instance.getSurveyorStation(); + //检测温度、湿度、气压、棱镜是否设置 + SurveyorStationRecord stationRecord = stationDataSource.getRecordSync(stationId); + if (stationRecord == null) { + return; + } + List stationItemList = stationRecord.getItems(); + if (stationItemList == null || stationItemList.isEmpty()) { + return; + } + boolean failure = false; + for (SurveyorPoint stationItem : stationItemList) { + if (SurveyorPoint.TYPE_STATION.equals(stationItem.getType())) { + continue; + } + if (stationItem.isWellSteel()) { + continue; + } + if (isEmpty(stationItem.getPrismHeight())) { + failure = true; + break; + } + } + if (!failure && (isEmpty(stationRecord.getTemperature()) || + isEmpty(stationRecord.getHumidity()) || + isEmpty(stationRecord.getAirPressure()) || + isEmpty(stationRecord.getInstrumentHeight()))) { + failure = true; + } + + if (!failure) { + TipsWith2OptionFragment.dismissNowMe(); + return; + } + + runner.runOnUI(() -> { + TipsWith2OptionFragment.Argument argument = new TipsWith2OptionFragment.Argument(); + argument.content(Tools.getString(R.string.please_set_environment)); + argument.cancelable(false); + argument.autoDismiss(false); + + TipsWith2OptionFragment.tips( + fragment.getChildFragmentManager(), + fragment.getViewLifecycleOwner(), + argument, + new TipsWith2OptionFragment.SimpleCallback() { + @Override + public void onConfirm() { + StationSettingsActivity.start(fragment.requireContext(), stationId); +// StationSettingsFragment.start(fragment.getContext(), stationId); + } + + @Override + public void onCancel() { + if (fragment.getActivity() != null) { + fragment.getActivity().finish(); + } + } + }); + }); + } + + public static boolean isEmpty(String string) { + return string == null || string.isEmpty(); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/StationSurveyorFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/StationSurveyorFragment.java new file mode 100644 index 0000000..304d5a6 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/StationSurveyorFragment.java @@ -0,0 +1,414 @@ +package com.bingce.controlnetwork.fragment.stationsurvey; + +import android.content.Context; +import android.graphics.Color; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; +import android.view.WindowManager; +import android.widget.Button; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.WorkerThread; +import androidx.fragment.app.Fragment; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.project.ProjectRecord; +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord; +import com.bingce.controlapphelper.datasource.database.tolerance.detail.ToleranceDetailRecord; +import com.bingce.controlapphelper.event.AutoSurveyorButtonVisibleEvent; +import com.bingce.controlapphelper.event.RefreshGoBackButton; +import com.bingce.controlapphelper.event.SurveyStateEvent; +import com.bingce.controlapphelper.model.BundleConstants; +import com.bingce.controlapphelper.surveyor.test.Test; +import com.bingce.controlapphelper.util.DigitalUtil; +import com.bingce.controlapphelper.util.StationUtil; +import com.bingce.controlapphelper.util.SurveyorCycleUtil; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.activity.fragmentcontainer.FragmentContainerActivity; +import com.bingce.controlnetwork.fragment.BottomSheetSelectListFragment; +import com.bingce.controlnetwork.fragment.ComponentStationSurveyorDataListFragment; +import com.bingce.controlnetwork.fragment.SurveyorSettingsFragment; +import com.bingce.controlnetwork.fragment.base.BaseFragment; +import com.bingce.controlnetwork.newui.stationsetting.StationSettingsActivity; +import com.bingce.controlnetwork.surveyor.surveyor.TestDataSelectFragment; +import com.bingce.utils.ThreadPoolUtil; +import com.github.razir.progressbutton.DrawableButtonExtensionsKt; +import com.github.razir.progressbutton.ProgressButtonHolderKt; + +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; +import org.greenrobot.eventbus.ThreadMode; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; + +/** + * 测站测量页面(开始测量) + */ +public class StationSurveyorFragment extends BaseFragment { + public static final String TAG = StationSurveyorFragment.class.getName(); + private ComponentStationSurveyorDataListFragment fragment; + private MenuItem goBack = null;//数据回退菜单 + private SurveyorStationRecord surveyorStationRecord; + private int cycleIndex = 0; + + @Subscribe(threadMode = ThreadMode.MAIN) + public void onRefreshGoBack(RefreshGoBackButton event) { + if (goBack != null) { + goBack.setEnabled(event.validate); + } + } + + @Subscribe(threadMode = ThreadMode.MAIN) + public void onSurveyorStateChanged(SurveyStateEvent event) { + if (getView() == null) { + return; + } + Button surveyorButton = getView().findViewById(R.id.surveyor); + if (surveyorButton == null) { + return; + } + if (event.isIdle() || event.isSuccess() || event.isCompleted()) { + DrawableButtonExtensionsKt.hideProgress(surveyorButton, R.string.start_surveyor); + } else if (event.isSurveying()) { + DrawableButtonExtensionsKt.showProgress(surveyorButton, progressParams -> { + progressParams.setButtonTextRes(R.string.tips_surveying); + progressParams.setProgressColor(Color.WHITE); + return null; + }); + } else if (event.isFailure()) { + DrawableButtonExtensionsKt.hideProgress(surveyorButton, R.string.tips_surveyor_failure_and_retry); + } + + boolean enable = event.isIdle() || event.isFailure() || event.isSuccess(); + setSurveyorEnable(getView(), R.id.surveyor, enable); + setSurveyorEnable(getView(), R.id.auto_surveyor, enable); + } + + + @Subscribe(threadMode = ThreadMode.MAIN) + public void onAutoSurveyorChanged(AutoSurveyorButtonVisibleEvent event) { + if (getView() == null) { + return; + } + Button autoSurveyButton = getView().findViewById(R.id.auto_surveyor); + if (autoSurveyButton != null) { + autoSurveyButton.setVisibility(event.isReadyAutoSurvey() && !event.isOpenAutoSurvey() + ? View.VISIBLE : View.GONE); + } + } + + private String stationId() { + if (getArguments() == null) { + return null; + } + return getArguments().getString(BundleConstants.KEY_SURVEYOR_STATION_ID); + } + + @Override + public void onResume() { + super.onResume(); + //测量界面保持常亮 + if (getActivity() != null) { + getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + } + } + + @Override + public void onPause() { + super.onPause(); + //关闭测量界面保持常亮 + if (getActivity() != null) { + getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + } + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + EventBus.getDefault().unregister(this); + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, + @Nullable ViewGroup container, + @Nullable Bundle savedInstanceState) { + EventBus.getDefault().register(this); + + View view = inflater.inflate(R.layout.fragment_project_surveyor_station_detail_layout, + container, + false); + + replaceFragment(); + + //2.设置测量按钮 + Button surveyor = view.findViewById(R.id.surveyor); + if (surveyor != null) { + ProgressButtonHolderKt.bindProgressButton(getViewLifecycleOwner(), surveyor); + } + setSurveyorClick(view, R.id.surveyor, () -> { + if (fragment != null) { + fragment.doSurveyor(); + } + }); + setSurveyorClick(view, R.id.auto_surveyor, () -> { + if (fragment != null) { + fragment.autoSurvey(); + } + }); + //3.查询测站信息 + ThreadPoolUtil.execute(() -> { + surveyorStationRecord = SurveyorDatabaseFactory + .instance + .getSurveyorStation() + .getRecordSync(stationId()); + //监听当前测回切换 + initObserver(view); + //监听数据变化 + ToleranceDetailRecord toleranceRecord = getTolerance(surveyorStationRecord); + if (toleranceRecord == null) { + return; + } + //注册UI监听 + View pick = view.findViewById(R.id.cycleLayout); + if (pick == null) { + return; + } + int cycleCount = toleranceRecord.getCycleCount(); + pick.setOnClickListener(v -> { + ArrayList cycleList = SurveyorCycleUtil.cycleStrings(cycleCount, + surveyorStationRecord != null && surveyorStationRecord.leftAndRightSurveyor); + + TextView circleText = view.findViewById(R.id.circle_text); + runOnUI(() -> BottomSheetSelectListFragment.showSelect( + getChildFragmentManager(), + getViewLifecycleOwner(), + cycleIndex, + cycleList, + null,//不再限制测期 + (index, string) -> { + if (circleText != null) { + circleText.setText(string); + } + cycleIndex = index; + if (fragment != null) { + //检测当前测回是否完成 + fragment.switchCycle(cycleIndex); + } + })); + }); + }); + + + setHasOptionsMenu(true); + + return view; + } + + private void replaceFragment() { + //1.添加测量数据显示fragment + fragment = ComponentStationSurveyorDataListFragment + .newInstance(stationId()); + getChildFragmentManager() + .beginTransaction() + .replace(R.id.fragment_container, fragment, "___station_list") + .commit(); + } + + private void initObserver(View view) { + runOnUI(() -> { + monitorCurrentCycle(view); + //监听测站变化 + SurveyorDatabaseFactory + .instance + .getSurveyorStation() + .getLiveDataRecord(stationId()) + .observe(getViewLifecycleOwner(), + stationRecord -> { + replaceFragment(); + checkStationSettings(); + }); + + }); + } + + private void checkStationSettings() { + ThreadPoolUtil.execute(() -> MethodCheckSetting.checkStationSettings(stationId(), fragment, this::runOnUI)); + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + + + } + + private void monitorCurrentCycle(View view) { + SurveyorDatabaseFactory + .instance + .getScheduleDataSource() + .findSchedule(SurveyorScheduleConstants.getCurrentCycleKey(stationId(), null)) + .observe(getViewLifecycleOwner(), record -> { + TextView circleText = view.findViewById(R.id.circle_text); + //测回发生变化的时候,更新相应ui + int cycleIndex = DigitalUtil.valueOfIntString(record == null ? "0" : record.getStatue(), 0); + //更新测回名称 + if (circleText != null) { + boolean showLeftOrRight = true; + if (surveyorStationRecord != null) { + showLeftOrRight = surveyorStationRecord.leftAndRightSurveyor; + } + circleText.setText(SurveyorCycleUtil.cycleName(cycleIndex, showLeftOrRight)); + } + StationSurveyorFragment.this.cycleIndex = cycleIndex; + }); + } + + private static void setSurveyorClick(View rootView, int id, Runnable runnable) { + View view = rootView.findViewById(id); + if (view != null) { + view.setOnClickListener(v -> runnable.run()); + } + } + + private static void setSurveyorEnable(View rootView, int id, boolean enable) { + if (rootView == null) { + return; + } + View view = rootView.findViewById(id); + if (view != null) { + view.setEnabled(enable); + if (enable) { + view.setAlpha(1); + } else { + view.setAlpha(.4f); + } + } + } + + @Override + public void onCreateOptionsMenu(@NonNull @NotNull Menu menu, @NonNull @NotNull MenuInflater inflater) { + if (Test.DEBUG) { + inflater.inflate(R.menu.menu_surveyor_station_record_data_edit_debug, menu); + } else { + inflater.inflate(R.menu.menu_surveyor_station_record_data_edit_release, menu); + } +// MenuItem stationCheck = menu.findItem(R.id.menu_item_station_check); +// MenuItem stationAdjust = menu.findItem(R.id.menu_item_station_adjust); + goBack = menu.findItem(R.id.menu_item_go_back); +// SurveyorDatabaseFactory +// .instance +// .getScheduleDataSource() +// .findSchedule(SurveyorScheduleConstants.getAllCycleScheduleKey(stationId(), null)) +// .observe(getViewLifecycleOwner(), surveyorScheduleRecord -> { +// boolean checkStatue = false; +// boolean adjustStatue = false; +// if (surveyorScheduleRecord != null) { +// String statue = surveyorScheduleRecord.getStatue(); +// if (SurveyorScheduleConstants.STATUE_VALUE_CHECKED.equals(statue)) { +// adjustStatue = true; +// } else if (SurveyorScheduleConstants.STATUE_VALUE_COMPLETED.equals(statue)) { +// checkStatue = true; +// } else if (SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED.equals(statue)) { +// //重置提醒标识 +// String key = ConfigConstants.KEY_CONFIG_STATION_CHECK_REMINDED + stationId(); +// SurveyorDatabaseFactory +// .instance +// .getConfigDataSource() +// .set(key, ConfigConstants.VALUE_NO); +// } +// } +// //更新菜单enable +// if (stationCheck != null) { +// stationCheck.setEnabled(checkStatue); +// } +// if (stationAdjust != null) { +// stationAdjust.setEnabled(adjustStatue); +// } +// }); + } + + @Override + public boolean onOptionsItemSelected(@NonNull @NotNull MenuItem item) { + if (R.id.menu_item_delete_current_records == item.getItemId()) { + //删除当前测回记录 + if (surveyorStationRecord != null) { + //通知fragment + fragment.deleteByStationAndPeriod(cycleIndex); + } + } else if (R.id.menu_item_delete_all_records == item.getItemId()) { + //删除所有测回记录 + if (surveyorStationRecord != null) { + //通知fragment + fragment.deleteCurrentStationSurveyorData(); + } + } else if (R.id.menu_item_station_check == item.getItemId()) { + //测站检测,检测所有测回 + fragment.stationCheck(); + } else if (R.id.menu_item_data_source == item.getItemId()) { + //数据源 debug使用 + TestDataSelectFragment.show(getChildFragmentManager()); + } else if (R.id.menu_item_go_back == item.getItemId()) { + //回退 + fragment.goBack(); + } else if (R.id.menu_item_station_environment_prism_settings == item.getItemId()) { + //环境、棱镜设置 + StationSettingsActivity.start(requireContext(), stationId()); +// StationSettingsFragment.start(getContext(), stationId()); + } else if (R.id.menu_item_surveyor_settings == item.getItemId()) { + //测量设置 + ThreadPoolUtil.execute(() -> { + String name = StationUtil.getStationName(surveyorStationRecord); + runOnUI(() -> SurveyorSettingsFragment.start(getContext(), surveyorStationRecord.getId(), name)); + }); + } else if (R.id.menu_item_station_adjust == item.getItemId()) { + //测站平差,平差检测 + fragment.stationAdjust(); + } else if (R.id.menu_item_check_adjust == item.getItemId()) { + //检测平差 + fragment.stationCheckAdjust(); + } + return super.onOptionsItemSelected(item); + } + + @WorkerThread + private static ToleranceDetailRecord getTolerance(SurveyorStationRecord surveyorStationRecord) { + if (surveyorStationRecord == null) { + return null; + } + //获取project信息 + ProjectRecord projectRecord = SurveyorDatabaseFactory + .instance + .getProjectDataSource() + .getRecord(surveyorStationRecord.getProjectId()); + if (projectRecord == null) { + return null; + } + //获取限差数据 + return SurveyorDatabaseFactory + .instance + .getToleranceDetailDataSource() + .getRecordSync(projectRecord.getToleranceId()); + } + + public static void start(Context context, String surveyorStationId, String surveyorStationName) { + Bundle bundle = new Bundle(); + bundle.putString(BundleConstants.KEY_SURVEYOR_STATION_ID, surveyorStationId); + FragmentContainerActivity.start(context, TAG, surveyorStationName, bundle); + } + + public static Fragment newInstance(Bundle args) { + Fragment fragment = new StationSurveyorFragment(); + fragment.setArguments(args); + return fragment; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/angledistance/MeasureDefaultFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/angledistance/MeasureDefaultFragment.java new file mode 100644 index 0000000..d381b58 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/angledistance/MeasureDefaultFragment.java @@ -0,0 +1,411 @@ +package com.bingce.controlnetwork.fragment.stationsurvey.angledistance; + +import android.content.Context; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.WorkerThread; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; +import androidx.lifecycle.ViewModelProvider; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.project.ProjectRecord; +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord; +import com.bingce.controlapphelper.datasource.database.tolerance.detail.ToleranceDetailRecord; +import com.bingce.controlapphelper.event.RefreshGoBackButton; +import com.bingce.controlapphelper.surveyor.data.CachedData; +import com.bingce.controlapphelper.surveyor.data.IDistanceTypeChangeListener; +import com.bingce.controlapphelper.surveyor.data.SurveyorData; +import com.bingce.controlapphelper.surveyor.state.ISurveyState; +import com.bingce.controlapphelper.surveyor.surveyor.RequestSurveyorParamAuto; +import com.bingce.controlapphelper.util.DigitalUtil; +import com.bingce.controlapphelper.util.IUIRunner; +import com.bingce.controlnetwork.adapter.MeasureAngleDistanceAdapter; +import com.bingce.controlnetwork.fragment.ComponentStationSurveyorDataListFragment; +import com.bingce.controlnetwork.fragment.StationDataAdjustDialogFragment; +import com.bingce.controlnetwork.fragment.base.BaseFragment; +import com.bingce.controlnetwork.fragment.stationsurvey.IMeasureOperate; +import com.bingce.controlnetwork.surveyor.state.IScrollDelegate; +import com.bingce.controlnetwork.surveyor.state.angledistance.StateManager; +import com.bingce.controlnetwork.surveyor.state.angledistance._IsSingleCycleCompletedState; +import com.bingce.totalstation.TotalStation; +import com.bingce.utils.ThreadPoolUtil; + +import org.greenrobot.eventbus.EventBus; + +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.adapter.MeasureAngleDistanceAdapter; +import com.bingce.controlnetwork.fragment.ComponentStationSurveyorDataListFragment; +import com.bingce.controlnetwork.fragment.StationDataAdjustDialogFragment; +import com.bingce.controlnetwork.fragment.base.BaseFragment; +import com.bingce.controlnetwork.fragment.stationsurvey.IMeasureOperate; +import com.bingce.controlnetwork.surveyor.state.IScrollDelegate; +import com.bingce.controlnetwork.surveyor.state.angledistance.StateManager; +import com.bingce.controlnetwork.surveyor.state.angledistance._IsSingleCycleCompletedState; + +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.surveyor.data.ICachedData; +import com.bingce.controlapphelper.surveyor.data.ISurveyorData; + +/** + * 测角测距 + */ +public class MeasureDefaultFragment extends BaseFragment + implements IDistanceTypeChangeListener, ISurveyState, IMeasureOperate { + private MeasureAngleDistanceAdapter adapter = null; + private StateManager stateManager; + private RecyclerView recyclerView; + private ICachedData cachedData = null; + private ISurveyorData surveyedData = null; + private ISurveyState surveyState; + + private String stationId() { + if (getArguments() == null) { + return null; + } + return getArguments().getString(KEY_STATION_ID); + } + + private String getTypeAngleOrDistance() { + if (getArguments() != null) { + return getArguments().getString(KEY_TYPE_ANGLE_OR_DISTANCE); + } + return null; + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, + @Nullable ViewGroup container, + @Nullable Bundle savedInstanceState) { + View view = inflater.inflate( + R.layout.fragment_project_surveyor_station_point_list_layout, + container, + false); + String stationId = stationId(); + recyclerView = view.findViewById(R.id.recycler_view); + if (stationId != null) { + //收集信息 + collectData(stationId, + getContext(), + getChildFragmentManager(), + getViewLifecycleOwner(), + this::runOnUI, + index -> { + if (index >= 0 && adapter != null && index < adapter.getItemCount()) { + recyclerView.scrollToPosition(index); + } + }, + new ICollectCacheCallback() { + @Override + public void onFailure() { + } + + @Override + public void onSuccess(boolean showSlopDistance, ICachedData cachedData, SurveyorData surveyorData, StateManager stateManager) { + onCollectStationData(showSlopDistance, cachedData, surveyorData, stateManager); + surveyState = stateManager; + } + } + ); + } + + return view; + } + + @WorkerThread + private void onCollectStationData( + boolean showSlopDistance, + ICachedData cachedData, + SurveyorData surveyorData, + StateManager stateManager) { + this.stateManager = stateManager; + this.cachedData = cachedData; + surveyedData = surveyorData; + + //测量数据收集完毕后,就可以更新UI了 + runOnUI(() -> { + //刷新UI + if (adapter == null) { + adapter = new MeasureAngleDistanceAdapter(stationId(), + cachedData, surveyorData, surveyorData, getTypeAngleOrDistance()); + adapter.onShowSlopDistance(showSlopDistance); + if (recyclerView != null) { + recyclerView.setAdapter(adapter); + //滚动到当前目标点 + int currentItemIndex = surveyorData.currentIndex(); + if (currentItemIndex >= 0 && currentItemIndex < adapter.getItemCount()) { + recyclerView.scrollToPosition(currentItemIndex); + } + } + } + + //监听测站数据 + //监听「平距」「斜距」切换,更新UI显示 + SurveyorDatabaseFactory + .instance + .getSurveyorStation() + .getLiveDataRecord(stationId()) + .observe(getViewLifecycleOwner(), + surveyorStationRecord -> onShowSlopDistance(surveyorStationRecord.isShowSlopDistance())); + }); + } + + /** + * 收集测站信息 + */ + private void collectData( + String stationId, + Context context, + FragmentManager fragmentManager, + LifecycleOwner lifecycleOwner, + IUIRunner runner, + IScrollDelegate scrollDelegate, + ICollectCacheCallback callback) { + if (callback == null) { + return; + } + boolean isSupportAutoMode = TotalStation.getInstance().isSupportMotor(); + ThreadPoolUtil.execute(() -> { + //读取当前测站的当前测回--很重要 + SurveyorScheduleRecord scheduleRecord = + SurveyorDatabaseFactory + .instance + .getScheduleDataSource() + .findScheduleSync(SurveyorScheduleConstants.getCurrentCycleKey(stationId, SurveyorScheduleConstants.SCHEDULE_OR_CYCLE_TYPE_ALONE_DISTANCE)); + int defaultCycle = scheduleRecord == null ? 0 : + DigitalUtil.valueOfIntString(scheduleRecord.getStatue(), 0); + //加载测站信息 + SurveyorStationRecord surveyorStationRecord = + SurveyorDatabaseFactory + .instance + .getSurveyorStation() + .getRecordSync(stationId); + //加载对应项目 + ProjectRecord projectRecord = SurveyorDatabaseFactory + .instance + .getProjectDataSource() + .getRecord(surveyorStationRecord.getProjectId()); + if (projectRecord == null) { + callback.onFailure(); + return; + } + //加载对应限差 + ToleranceDetailRecord toleranceRecord = SurveyorDatabaseFactory + .instance + .getToleranceDetailDataSource() + .getRecordSync(projectRecord.getToleranceId()); + if (toleranceRecord == null) { + callback.onFailure(); + return; + } + //创建缓存数据 + CachedData cachedData = + CachedData.newInstance(surveyorStationRecord.isAutoClose(), + surveyorStationRecord.isLeftAndRightSurveyor(), + stationId, toleranceRecord); + if (cachedData == null) { + callback.onFailure(); + return; + } + + + //是否显示斜距? + cachedData.onShowSlopDistance(surveyorStationRecord.isShowSlopDistance()); + if (cachedData.pointCount() <= 0) { + callback.onFailure(); + return; + } + + //创建stateManager实例 + SurveyorData surveyorDataSource = new SurveyorData(toleranceRecord.getSurveyorCount()); + surveyorDataSource.onShowSlopDistance(surveyorStationRecord.isShowSlopDistance()); + + //存入cacheData 用于自动测量时使用 + MeasureVm measureVm = new ViewModelProvider(requireParentFragment()).get(MeasureVm.class); + RequestSurveyorParamAuto requestSurveyorParamAuto = new RequestSurveyorParamAuto(stationId, cachedData); + measureVm.setRequestSurveyorParamAuto(requestSurveyorParamAuto); + + StateManager stateManager = StateManager.newInstance( + isSupportAutoMode, + requestSurveyorParamAuto, + surveyorStationRecord, + context, + fragmentManager, + lifecycleOwner, + toleranceRecord, + surveyorDataSource, + surveyorDataSource, + cachedData, + scrollDelegate, + runner); + //fragment创建后立即计算当前cycle的测量状态 + runner.runOnUI(() -> stateManager.calScheduleWhenEnterSurveyFragment(defaultCycle)); + callback.onSuccess(surveyorStationRecord.isShowSlopDistance(), cachedData, surveyorDataSource, stateManager); + }); + } + + @Override + public void onResume() { + super.onResume(); + if (stateManager != null) { + stateManager.resume(); + } + } + + @Override + public void onPause() { + super.onPause(); + if (stateManager != null) { + stateManager.quite(); + } + } + + public interface ICollectCacheCallback { + void onFailure(); + + void onSuccess(boolean showSlopDistance, ICachedData cachedData, SurveyorData surveyorData, StateManager stateManager); + } + + @Override + public void doSurveyor() { + if (stateManager == null) { + return; + } + stateManager.doSurveyor(); + } + + @Override + public void autoSurvey() { + if (stateManager == null) { + return; + } + stateManager.doAutoSurveyor(); + } + + @Override + public void switchCycle(int cycleIndex) { + if (stateManager == null) { + return; + } + stateManager.switch2Cycle(cycleIndex); + } + + @Override + public void deleteStationAllPeroidRecord() { + if (stateManager == null) { + return; + } + stateManager.deleteCurrentStationSurveyorData(); + } + + @Override + public void deleteStationOnePeriodRecord(int cycleIndex) { + if (stateManager == null) { + return; + } + stateManager.deleteCurrentStationSurveyorData(cycleIndex); + } + + @Override + public String stationCheck() { + if (stateManager == null) { + return null; + } + return stateManager.stationCheckOnly(); + } + + @Override + public void stationAdjust() { + if (stateManager == null) { + return; + } + stateManager.stationAdjustOnly(StationDataAdjustDialogFragment.TYPE_ANGLE_DISTANCE); + } + + @Override + public void goBack() { + if (stateManager == null) { + return; + } + stateManager.moveBack(); + } + + @Override + public boolean isCurrentCycleComplete() { + if (stateManager == null) + return false; + boolean completed = _IsSingleCycleCompletedState.isSingleCycleCompleted( + stationId(), + stateManager.getCurrentCycle(), + stateManager.getCachedData()); + return completed; + } + + @Override + public void refreshGoBackBtnEnable() { + if (stateManager == null || stateManager.getCachedData().pointCount() == 0) { + EventBus.getDefault().post(new RefreshGoBackButton(false)); + return; + } + stateManager.refreshGoBackBtnEnable(); + } + + @Override + public int measureTypePosition() { + return MeasureFragment.POSITION_DIRECTION_MEASURE; + } + + @Override + public void onShowSlopDistance(boolean value) { + if (cachedData != null) { + cachedData.onShowSlopDistance(value); + } + if (surveyedData != null) { + surveyedData.onShowSlopDistance(value); + } + if (adapter != null) { + adapter.onShowSlopDistance(value); + adapter.notifyItemRangeChanged(0, adapter.getItemCount()); + } + } + + @Override + public boolean isSurveying() { + if (surveyState != null) { + return surveyState.isSurveying(); + } + return false; + } + + @Override + public boolean isAutoSurveying() { + if (surveyState != null) { + return surveyState.isAutoSurveying(); + } + return false; + } + + private static final String KEY_STATION_ID = "__station_id"; + private static final String KEY_TYPE_ANGLE_OR_DISTANCE = "__key_type_angle_or_distance"; + public static final String TAG = ComponentStationSurveyorDataListFragment.class.getName(); + + public static MeasureDefaultFragment newInstance(String stationId, String typeAngleOrDistance) { + MeasureDefaultFragment fragment = new MeasureDefaultFragment(); + Bundle bundle = new Bundle(); + bundle.putString(KEY_STATION_ID, stationId); + bundle.putString(KEY_TYPE_ANGLE_OR_DISTANCE, typeAngleOrDistance); + fragment.setArguments(bundle); + return fragment; + } +} + + + diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/angledistance/MeasureDistanceFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/angledistance/MeasureDistanceFragment.java new file mode 100644 index 0000000..c1254a1 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/angledistance/MeasureDistanceFragment.java @@ -0,0 +1,394 @@ +package com.bingce.controlnetwork.fragment.stationsurvey.angledistance; + +import android.content.Context; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.WorkerThread; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; +import androidx.lifecycle.ViewModelProvider; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.project.ProjectRecord; +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord; +import com.bingce.controlapphelper.datasource.database.tolerance.detail.ToleranceDetailRecord; +import com.bingce.controlapphelper.event.RefreshGoBackButtonAloneDistance; +import com.bingce.controlapphelper.surveyor.data.CachedDataAloneDistance; +import com.bingce.controlapphelper.surveyor.data.IDistanceTypeChangeListener; +import com.bingce.controlapphelper.surveyor.data.IMeasureCache; +import com.bingce.controlapphelper.surveyor.data.ISurveyorData; +import com.bingce.controlapphelper.surveyor.data.SurveyorData; +import com.bingce.controlapphelper.surveyor.state.ISurveyState; +import com.bingce.controlapphelper.util.DigitalUtil; +import com.bingce.controlapphelper.util.IUIRunner; +import com.bingce.controlnetwork.adapter.MeasureAngleDistanceAdapter; +import com.bingce.controlnetwork.fragment.ComponentStationSurveyorDataListFragment; +import com.bingce.controlnetwork.fragment.base.BaseFragment; +import com.bingce.controlnetwork.fragment.stationsurvey.IMeasureOperate; +import com.bingce.controlnetwork.surveyor.state.IScrollDelegate; +import com.bingce.totalstation.TotalStation; +import com.bingce.utils.ThreadPoolUtil; + +import org.greenrobot.eventbus.EventBus; + +import blankj.utilcode.util.ToastUtils; + +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.adapter.MeasureAngleDistanceAdapter; +import com.bingce.controlnetwork.fragment.base.BaseFragment; +import com.bingce.controlnetwork.fragment.ComponentStationSurveyorDataListFragment; +import com.bingce.controlnetwork.fragment.stationsurvey.IMeasureOperate; +import com.bingce.controlnetwork.surveyor.state.IScrollDelegate; +import com.bingce.controlnetwork.surveyor.state.alonedistance.StateManagerAloneDistance; +import com.bingce.controlnetwork.surveyor.state.alonedistance._CheckStationState; +import com.bingce.controlnetwork.surveyor.state.alonedistance._DoCalAdjustState; +import com.bingce.controlnetwork.surveyor.state.alonedistance._IsSingleCycleCompletedState; + +/** + * 单独测距 + */ +public class MeasureDistanceFragment extends BaseFragment + implements IDistanceTypeChangeListener, ISurveyState, IMeasureOperate { + + private MeasureAngleDistanceAdapter adapter = null; + private StateManagerAloneDistance stateManager; //这里的stateManager是克隆StateManager + private RecyclerView recyclerView; + private IMeasureCache cachedData = null; + private ISurveyorData surveyedData = null; + + private String stationId() { + if (getArguments() == null) { + return null; + } + return getArguments().getString(KEY_STATION_ID); + } + + private String getWellType() { + if (getArguments() != null) { + return getArguments().getString(KEY_TYPE_ANGLE_OR_DISTANCE); + } + return null; + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, + @Nullable ViewGroup container, + @Nullable Bundle savedInstanceState) { + View view = inflater.inflate( + R.layout.fragment_project_surveyor_station_point_list_layout, + container, + false); + recyclerView = view.findViewById(R.id.recycler_view); + + + collectData(stationId(), + getContext(), + getChildFragmentManager(), + getViewLifecycleOwner(), + this::runOnUI, + index -> { + scrollToPosition(index); + }, + new ICollectCacheCallback() { + @Override + public void onFailure() { + } + + @Override + public void onSuccess(boolean showSlopDistance, IMeasureCache cachedData, SurveyorData surveyorData, StateManagerAloneDistance stateManager) { + onCollectStationData(showSlopDistance, cachedData, surveyorData, stateManager); + } + } + ); + + return view; + } + + @WorkerThread + private void onCollectStationData( + boolean showSlopDistance, + IMeasureCache cachedData, + SurveyorData surveyorData, + StateManagerAloneDistance stateManager) { + this.stateManager = stateManager; + this.cachedData = cachedData; + this.surveyedData = surveyorData; + + //测量数据收集完毕后,就可以更新UI了 + runOnUI(() -> { + //刷新UI + if (adapter == null) { + adapter = new MeasureAngleDistanceAdapter(stationId(), + cachedData, surveyorData, surveyorData, getWellType()); + adapter.onShowSlopDistance(showSlopDistance); + if (recyclerView != null) { + recyclerView.setAdapter(adapter); + //滚动到当前目标点 + int currentItemIndex = surveyorData.currentIndex(); + scrollToPosition(currentItemIndex); + } + + adapter.setOnItemClickListener(position -> { + if (isSurveying() || isAutoSurveying()) { + ToastUtils.showShort(R.string.measuring_please_waite); + return; + } + stateManager.switchCurrentMeasurePosition(position); + scrollToPosition(position); +// adapter.notifyDataSetChanged(); + }); + } + + //监听测站数据,更新界面「平距」「斜距」显示 + SurveyorDatabaseFactory + .instance + .getSurveyorStation() + .getLiveDataRecord(stationId()) + .observe(getViewLifecycleOwner(), + surveyorStationRecord -> { + stateManager.updateStationRecord(surveyorStationRecord); + onShowSlopDistance(surveyorStationRecord.isShowSlopDistance()); + }); + }); + } + + private void scrollToPosition(int position) { + if (position >= 0 && adapter != null && position < adapter.getItemCount()) { + recyclerView.scrollToPosition(position); + adapter.notifyDataSetChanged(); + } + } + + /** + * 收集测站信息 + */ + private synchronized void collectData( + String stationId, + Context context, + FragmentManager fragmentManager, + LifecycleOwner lifecycleOwner, + IUIRunner runner, + IScrollDelegate scrollDelegate, + ICollectCacheCallback callback) { + + boolean isSupportAutoMode = TotalStation.getInstance().isSupportMotor(); + ThreadPoolUtil.execute(() -> { + //读取当前测站的当前测回--很重要 + SurveyorScheduleRecord scheduleRecord = + SurveyorDatabaseFactory + .instance + .getScheduleDataSource() + .findScheduleSync(SurveyorScheduleConstants.getCurrentCycleKey(stationId, SurveyorScheduleConstants.SCHEDULE_OR_CYCLE_TYPE_ALONE_DISTANCE)); + int defaultCycle = scheduleRecord == null ? 0 : + DigitalUtil.valueOfIntString(scheduleRecord.getStatue(), 0); + //加载测站信息 + SurveyorStationRecord surveyorStationRecord = + SurveyorDatabaseFactory + .instance + .getSurveyorStation() + .getRecordSync(stationId); + //加载对应项目 + ProjectRecord projectRecord = SurveyorDatabaseFactory + .instance + .getProjectDataSource() + .getRecord(surveyorStationRecord.getProjectId()); + if (projectRecord == null) { + callback.onFailure(); + return; + } + //加载对应限差 + ToleranceDetailRecord toleranceRecord = SurveyorDatabaseFactory + .instance + .getToleranceDetailDataSource() + .getRecordSync(projectRecord.getToleranceId()); + if (toleranceRecord == null) { + callback.onFailure(); + return; + } + //创建缓存数据 + CachedDataAloneDistance cachedData = CachedDataAloneDistance.newInstance(stationId); + //是否显示斜距? + cachedData.onShowSlopDistance(surveyorStationRecord.isShowSlopDistance()); + + //创建stateManager实例 + SurveyorData surveyorDataSource = new SurveyorData(ToleranceDetailRecord.ALONE_DISTANCE_MEASURE_COUNT); + surveyorDataSource.onShowSlopDistance(surveyorStationRecord.isShowSlopDistance()); + + StateManagerAloneDistance stateManager = StateManagerAloneDistance.newInstance( + isSupportAutoMode, + surveyorStationRecord, + context, + fragmentManager, + lifecycleOwner, + toleranceRecord, + surveyorDataSource, + surveyorDataSource, + cachedData, + createMeasureVm(), + scrollDelegate, + runner); + //fragment创建后立即计算当前cycle的测量状态 + runner.runOnUI(() -> + stateManager.calScheduleWhenEnterSurveyFragment(defaultCycle)); + callback.onSuccess(surveyorStationRecord.isShowSlopDistance(), cachedData, surveyorDataSource, stateManager); + }); + } + + public interface ICollectCacheCallback { + void onFailure(); + + void onSuccess(boolean showSlopDistance, IMeasureCache cachedData, SurveyorData surveyorData, StateManagerAloneDistance stateManager); + } + + @Override + public void doSurveyor() { + if (stateManager == null) { + return; + } + stateManager.doSurveyor(); + } + + @Override + public void autoSurvey() { + if (stateManager == null) { + return; + } + stateManager.doAutoSurveyor(); + } + + @Override + public void switchCycle(int cycleIndex) { + if (stateManager == null) { + return; + } + stateManager.switch2Cycle(cycleIndex); + } + + @Override + public void deleteStationAllPeroidRecord() { + if (stateManager == null) { + return; + } + stateManager.deleteCurrentStationSurveyorData(); + } + + @Override + public void deleteStationOnePeriodRecord(int cycleIndex) { +// if (stateManager == null) { +// return; +// } +// stateManager.deleteCurrentStationSurveyorData(cycleIndex); + } + + @Override + public String stationCheck() { + if (stateManager == null) { + return null; + } + return _CheckStationState._stationCheckAloneDistance(stationId(), stateManager.getToleranceRecord(), stateManager.getCachedData()); + } + + @Override + public void stationAdjust() { + if (stateManager == null) { + return; + } + _DoCalAdjustState.doCalAdjust(stationId(), stateManager.getCachedData(), requireContext(), + getChildFragmentManager(), getViewLifecycleOwner()); +// stateManager.stationAdjust(); + } + + @Override + public void goBack() { + if (stateManager == null) { + return; + } + stateManager.moveBack(); + } + + @Override + public void onShowSlopDistance(boolean value) { + if (cachedData != null) { + cachedData.onShowSlopDistance(value); + } + if (surveyedData != null) { + surveyedData.onShowSlopDistance(value); + } + if (adapter != null) { + adapter.onShowSlopDistance(value); + adapter.notifyItemRangeChanged(0, adapter.getItemCount()); + } + } + + @Override + public boolean isSurveying() { + if (stateManager != null) { + return stateManager.isSurveying(); + } + return false; + } + + @Override + public boolean isAutoSurveying() { + if (stateManager != null) { + return stateManager.isAutoSurveying(); + } + return false; + } + + private static final String KEY_STATION_ID = "__station_id"; + private static final String KEY_TYPE_ANGLE_OR_DISTANCE = "__key_type_angle_or_distance"; + public static final String TAG = ComponentStationSurveyorDataListFragment.class.getName(); + + public static MeasureDistanceFragment newInstance(String stationId, String typeAngleOrDistance) { + MeasureDistanceFragment fragment = new MeasureDistanceFragment(); + Bundle bundle = new Bundle(); + bundle.putString(KEY_STATION_ID, stationId); + bundle.putString(KEY_TYPE_ANGLE_OR_DISTANCE, typeAngleOrDistance); + fragment.setArguments(bundle); + return fragment; + } + + @Override + public boolean isCurrentCycleComplete() { + if (stateManager == null) + return false; + boolean completed = _IsSingleCycleCompletedState.isSingleCycleCompleted( + stationId(), + StateManagerAloneDistance.CYCLE_INDEX_DEFAULT, + stateManager.getCachedData(), ToleranceDetailRecord.ALONE_DISTANCE_MEASURE_COUNT); + return completed; + } + + @Override + public void refreshGoBackBtnEnable() { + if (stateManager == null || stateManager.getCachedData().pointCount() == 0) { + EventBus.getDefault().post(new RefreshGoBackButtonAloneDistance(false)); + return; + } + stateManager.refreshGoBackBtnEnable(); + } + + @Override + public int measureTypePosition() { + return MeasureFragment.POSITION_DISTANCE_MEASURE; + } + + private MeasureVm createMeasureVm() { + return new ViewModelProvider(requireParentFragment()).get(MeasureVm.class); + } + + +} + + + diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/angledistance/MeasureFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/angledistance/MeasureFragment.java new file mode 100644 index 0000000..53d79e6 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/angledistance/MeasureFragment.java @@ -0,0 +1,180 @@ +package com.bingce.controlnetwork.fragment.stationsurvey.angledistance; + +import android.content.Context; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.model.BundleConstants; +import com.bingce.controlapphelper.util.StationUtil; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.activity.fragmentcontainer.FragmentContainerActivity; +import com.bingce.controlnetwork.adapter.MeasureAngleDistanceAdapter; +import com.bingce.controlnetwork.fragment.SurveyorSettingsFragment; +import com.bingce.controlnetwork.fragment.stationsurvey.MethodCheckSetting; +import com.bingce.controlnetwork.fragment.stationsurvey.base.MeasureBaseFragment; +import com.bingce.controlnetwork.newui.stationsetting.StationSettingsActivity; +import com.bingce.controlnetwork.surveyor.surveyor.TestDataSelectFragment; +import com.bingce.utils.ThreadPoolUtil; + +import org.jetbrains.annotations.NotNull; + +/** + * 测站测量页面(开始测量) + */ +public class MeasureFragment extends MeasureBaseFragment { + public static final String TAG = MeasureFragment.class.getName(); + + //方位观测fragment的在adapter的索引 + public static final int POSITION_DIRECTION_MEASURE = 0; + public static final int POSITION_DISTANCE_MEASURE = 1; + + @Override + protected boolean isShowSelectCycle(int position) { + return POSITION_DIRECTION_MEASURE == position; + } + + @Override + protected int defaultPageIndex() { + return POSITION_DIRECTION_MEASURE; + } + + @Override + protected void addFragmentsTabs(Runnable runnable) { + MeasureDefaultFragment fragmentAngle = MeasureDefaultFragment.newInstance(stationId(), MeasureAngleDistanceAdapter.TYPE_ANGLE); + fragments.add(fragmentAngle); + MeasureDistanceFragment fragmentDistance = MeasureDistanceFragment.newInstance(stationId(), MeasureAngleDistanceAdapter.TYPE_DISTANCE); + fragments.add(fragmentDistance); + + tabs.add(Tools.getString(R.string.azimuth_observation)); + tabs.add(Tools.getString(R.string.alone_measure_distance)); + runnable.run(); + } + + @Override + protected boolean isAloneDistancePage(int pageIndex) { + return POSITION_DISTANCE_MEASURE == pageIndex; + } + + @Override + protected String getCurrentPageCycleKey() { + if (mBinding.vp.getCurrentItem() == POSITION_DIRECTION_MEASURE) { + return SurveyorScheduleConstants.getCurrentCycleKey(stationId(), null); + } else { + return SurveyorScheduleConstants.getCurrentCycleKey(stationId(), SurveyorScheduleConstants.SCHEDULE_OR_CYCLE_TYPE_ALONE_DISTANCE); + } + } + + @Override + protected String getScheduleIdForAllCycle() { + int currentItem = mBinding.vp.getCurrentItem(); + String scheduleId; + if (!isAloneDistancePage(currentItem)) { + scheduleId = SurveyorScheduleConstants.getAllCycleScheduleKey(stationId(), null); + } else { + scheduleId = SurveyorScheduleConstants.getAllCycleScheduleKey(stationId(), SurveyorScheduleConstants.SCHEDULE_OR_CYCLE_TYPE_ALONE_DISTANCE); + } + return scheduleId; + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = super.onCreateView(inflater, container, savedInstanceState); + initObserver(); + return view; + } + + private void initObserver() { + //监听测站变化 + SurveyorDatabaseFactory + .instance + .getSurveyorStation() + .getLiveDataRecord(stationId()) + .observe(getViewLifecycleOwner(), + stationRecord -> { + checkStationSettings(); + }); + +// SurveyorScheduleConstants.getCurrentCycleKey(stationId(), SurveyorScheduleConstants.SCHEDULE_OR_CYCLE_TYPE_ALONE_DISTANCE); + monitorCurrentCycle(SurveyorScheduleConstants.getCurrentCycleKey(stationId(), null)); + } + + private void checkStationSettings() { + ThreadPoolUtil.execute(() -> MethodCheckSetting.checkStationSettings(stationId(), this, this::runOnUI)); + } + + @Override + public void onPrepareOptionsMenu(@NonNull Menu menu) { + super.onPrepareOptionsMenu(menu); + //删除当前测回记录 + menu.findItem(R.id.menu_item_delete_current_records).setEnabled(deleteSingleCycleEnable()); + } + + @Override + public boolean onOptionsItemSelected(@NonNull @NotNull MenuItem item) { + if (R.id.menu_item_delete_current_records == item.getItemId()) { + //删除当前测回记录 + if (surveyorStationRecord != null && currentFragment != null) { + //通知fragment + currentFragment.deleteStationOnePeriodRecord(cycleIndex); + } + } else if (R.id.menu_item_delete_all_records == item.getItemId()) { + //删除所有测回记录 + if (surveyorStationRecord != null && currentFragment != null) { + //通知fragment + currentFragment.deleteStationAllPeroidRecord(); + } + } else if (R.id.menu_item_station_check == item.getItemId() && currentFragment != null) { + //测站检测 被检测平差替代 + stationCheckBefore(); + } else if (R.id.menu_item_data_source == item.getItemId()) { + //数据源 debug使用 + TestDataSelectFragment.show(getChildFragmentManager()); + } else if (R.id.menu_item_go_back == item.getItemId() && currentFragment != null) { + //回退 + currentFragment.goBack(); + } else if (R.id.menu_item_station_environment_prism_settings == item.getItemId()) { + //环境、棱镜设置 + StationSettingsActivity.start(requireContext(), stationId()); +// StationSettingsFragment.start(getContext(), stationId()); + } else if (R.id.menu_item_surveyor_settings == item.getItemId()) { + //测量设置 设置是否显示平距 + ThreadPoolUtil.execute(() -> { + String name = StationUtil.getStationName(surveyorStationRecord); + runOnUI(() -> SurveyorSettingsFragment.start(getContext(), surveyorStationRecord.getId(), name)); + }); + } else if (R.id.menu_item_check_adjust == item.getItemId() && currentFragment != null) { + //检测平差 + stationCheckAdjustBefore(); + } + return super.onOptionsItemSelected(item); + } + + private boolean deleteSingleCycleEnable() { + return currentFragment != null && currentFragment instanceof MeasureDefaultFragment; + } + + public static void start(Context context, String surveyorStationId, String surveyorStationName) { + Bundle bundle = new Bundle(); + bundle.putString(BundleConstants.KEY_SURVEYOR_STATION_ID, surveyorStationId); + FragmentContainerActivity.start(context, TAG, surveyorStationName, bundle); + } + + public static Fragment newInstance(Bundle args) { + Fragment fragment = new MeasureFragment(); + fragment.setArguments(args); + return fragment; + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/angledistance/MeasureVm.java b/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/angledistance/MeasureVm.java new file mode 100644 index 0000000..133f85c --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/angledistance/MeasureVm.java @@ -0,0 +1,20 @@ +package com.bingce.controlnetwork.fragment.stationsurvey.angledistance; + +import androidx.lifecycle.ViewModel; + +import com.bingce.controlapphelper.surveyor.surveyor.RequestSurveyorParamAuto; + +public class MeasureVm extends ViewModel { + private RequestSurveyorParamAuto requestSurveyorParamAuto; + + + public RequestSurveyorParamAuto getRequestSurveyorParamAuto() { + return requestSurveyorParamAuto; + } + + public void setRequestSurveyorParamAuto(RequestSurveyorParamAuto requestSurveyorParamAuto) { + this.requestSurveyorParamAuto = requestSurveyorParamAuto; + } + + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/angledistance/StationCheckBeforeUtil.java b/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/angledistance/StationCheckBeforeUtil.java new file mode 100644 index 0000000..621e2a2 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/angledistance/StationCheckBeforeUtil.java @@ -0,0 +1,83 @@ +package com.bingce.controlnetwork.fragment.stationsurvey.angledistance; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleRecord; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.utils.ThreadPoolUtil; + +import com.bingce.controlnetwork.R; + +public class StationCheckBeforeUtil { + + public static final int STATION_CHECK = 1; + public static final int STATION_ADJUST = 2; + + + private static final String DATA_COMPLETE_NOT = Tools.getString(R.string.station_data_is_incomplete_hint); + + /** + * @param scheduleId 进度id eg:SurveyorScheduleConstants.stationScheduleKeyForAllCycle(stationId(), null) + * @param callBack + */ + public static void stationDetectBefore(String scheduleId, ICallBack callBack) { + ThreadPoolUtil.execute(() -> { + SurveyorScheduleRecord surveyorScheduleRecord = SurveyorDatabaseFactory + .instance + .getScheduleDataSource() + .findScheduleSync(scheduleId); + ThreadPoolUtil.executeInMain(() -> { + if (surveyorScheduleRecord == null) { + callBack.error(DATA_COMPLETE_NOT); + return; + } + String statue = surveyorScheduleRecord.getStatue(); + if (SurveyorScheduleConstants.STATUE_VALUE_CHECKED.equals(statue) + || SurveyorScheduleConstants.STATUE_VALUE_COMPLETED.equals(statue)) { + //完成测量或者经过检测后进行测站检测 + callBack.next(STATION_CHECK); + } else { + callBack.error(DATA_COMPLETE_NOT); + } + }); + }); + } + + /** + * 测站平差 + * + * @param scheduleId 进度id eg:SurveyorScheduleConstants.stationScheduleKeyForAllCycle(stationId(), null) + * @param callBack + */ + public static void stationAdjustBefore(String scheduleId, ICallBack callBack) { + ThreadPoolUtil.execute(() -> { + SurveyorScheduleRecord surveyorScheduleRecord = SurveyorDatabaseFactory + .instance + .getScheduleDataSource() + .findScheduleSync(scheduleId); + ThreadPoolUtil.executeInMain(() -> { + if (surveyorScheduleRecord == null) { + callBack.error(DATA_COMPLETE_NOT); + return; + } + String statue = surveyorScheduleRecord.getStatue(); + if (SurveyorScheduleConstants.STATUE_VALUE_CHECKED.equals(statue)) { + //测站经过检测->测站平差 + callBack.next(STATION_ADJUST); + } else if (SurveyorScheduleConstants.STATUE_VALUE_COMPLETED.equals(statue)) { + //测站完成测量->测站检测 + callBack.next(STATION_CHECK); + } else { + callBack.error(DATA_COMPLETE_NOT); + } + }); + }); + } + + public interface ICallBack { + void next(int nextType); + + void error(String error); + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/base/MeasureBaseFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/base/MeasureBaseFragment.java new file mode 100644 index 0000000..2bfc492 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/base/MeasureBaseFragment.java @@ -0,0 +1,490 @@ +package com.bingce.controlnetwork.fragment.stationsurvey.base; + +import android.graphics.Color; +import android.os.Bundle; +import android.text.TextUtils; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.WindowManager; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.WorkerThread; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; +import androidx.lifecycle.Lifecycle; +import androidx.viewpager.widget.ViewPager; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.project.ProjectRecord; +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord; +import com.bingce.controlapphelper.datasource.database.tolerance.detail.ToleranceDetailRecord; +import com.bingce.controlapphelper.event.AutoSurveyorButtonVisibleEvent; +import com.bingce.controlapphelper.event.RefreshGoBackButton; +import com.bingce.controlapphelper.event.RefreshGoBackButtonAloneDistance; +import com.bingce.controlapphelper.event.SurveyStateEvent; +import com.bingce.controlapphelper.model.BundleConstants; +import com.bingce.controlapphelper.surveyor.test.Test; +import com.bingce.controlapphelper.util.DigitalUtil; +import com.bingce.controlapphelper.util.SurveyorCycleUtil; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.databinding.FragmentMeasureBinding; +import com.bingce.controlnetwork.fragment.BottomSheetSelectListFragment; +import com.bingce.controlnetwork.fragment.TipsFragment; +import com.bingce.controlnetwork.fragment.base.BaseFragment; +import com.bingce.controlnetwork.fragment.stationsurvey.IMeasureOperate; +import com.bingce.controlnetwork.fragment.stationsurvey.angledistance.StationCheckBeforeUtil; +import com.bingce.utils.ThreadPoolUtil; +import com.flyco.tablayout.SlidingTabLayout; +import com.github.razir.progressbutton.DrawableButtonExtensionsKt; +import com.github.razir.progressbutton.ProgressButtonHolderKt; + +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; +import org.greenrobot.eventbus.ThreadMode; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; + +import blankj.utilcode.util.ToastUtils; + +public abstract class MeasureBaseFragment extends BaseFragment { + private boolean menuItemRollBackEnable; + + @Subscribe(threadMode = ThreadMode.MAIN) + public void onRefreshGoBack(RefreshGoBackButton event) { + if (mBinding != null) { + int currentItem = mBinding.vp.getCurrentItem(); + if (!isAloneDistancePage(currentItem)) { + menuItemRollBackEnable = event.validate; + } + } + } + + @Subscribe(threadMode = ThreadMode.MAIN) + public void onRefreshGoBack(RefreshGoBackButtonAloneDistance event) { + if (mBinding != null) { + int currentItem = mBinding.vp.getCurrentItem(); + if (isAloneDistancePage(currentItem)) { + menuItemRollBackEnable = event.validate; + } + } + } + + @Subscribe(threadMode = ThreadMode.MAIN) + public void onSurveyorStateChanged(SurveyStateEvent event) { + if (isInValidEventPosition(event.getPosition())) + return; + + if (event.isIdle() || event.isSuccess() || event.isCompleted()) { + DrawableButtonExtensionsKt.hideProgress(mBinding.surveyor, R.string.start_surveyor); + } else if (event.isSurveying()) { + DrawableButtonExtensionsKt.showProgress(mBinding.surveyor, progressParams -> { + progressParams.setButtonTextRes(R.string.tips_surveying); + progressParams.setProgressColor(Color.WHITE); + return null; + }); + } else if (event.isFailure()) { + DrawableButtonExtensionsKt.hideProgress(mBinding.surveyor, R.string.tips_surveyor_failure_and_retry); + } + + boolean enable = event.isIdle() || event.isFailure() || event.isSuccess(); + setSurveyorEnable(mBinding.surveyor, enable); + setSurveyorEnable(mBinding.autoSurveyor, enable); + } + + @Subscribe(threadMode = ThreadMode.MAIN) + public void onAutoSurveyorChanged(AutoSurveyorButtonVisibleEvent event) { + if (isInValidEventPosition(event.getPosition())) + return; + mBinding.autoSurveyor.setVisibility(event.isReadyAutoSurvey() ? View.VISIBLE : View.GONE); + } + + protected FragmentMeasureBinding mBinding; + + protected IMeasureOperate currentFragment; + + protected SurveyorStationRecord surveyorStationRecord; + protected int cycleIndex = 0; + protected ArrayList cycleList; + + protected abstract boolean isShowSelectCycle(int position); + + protected abstract int defaultPageIndex(); + + protected abstract void addFragmentsTabs(Runnable runnable); + + protected abstract boolean isAloneDistancePage(int pageIndex); + + protected abstract String getCurrentPageCycleKey(); + + protected abstract String getScheduleIdForAllCycle(); + + protected void setSurveyorEnable(View view, boolean enable) { + if (view != null) { + view.setEnabled(enable); + if (enable) { + view.setAlpha(1); + } else { + view.setAlpha(.4f); + } + } + } + + protected List fragments = new ArrayList<>(); + protected List tabs = new ArrayList<>(); + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + setHasOptionsMenu(true); + EventBus.getDefault().register(this); + mBinding = FragmentMeasureBinding.inflate(inflater, container, false); + //设置测量按钮 + ProgressButtonHolderKt.bindProgressButton(getViewLifecycleOwner(), mBinding.surveyor); + initClickListener(); + return mBinding.getRoot(); + } + + @Override + public void onResume() { + super.onResume(); + //测量界面保持常亮 + if (getActivity() != null) { + getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + } + } + + @Override + public void onPause() { + super.onPause(); + //关闭测量界面保持常亮 + if (getActivity() != null) { + getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + } + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initStation(); + initView(); + initViewPager(view); + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + mBinding = null; + EventBus.getDefault().unregister(this); + } + + @Override + public void onCreateOptionsMenu(@NonNull @NotNull Menu menu, @NonNull @NotNull MenuInflater inflater) { + if (Test.DEBUG) { + inflater.inflate(R.menu.menu_surveyor_station_record_data_edit_debug, menu); + } else { + inflater.inflate(R.menu.menu_surveyor_station_record_data_edit_release, menu); + } + super.onCreateOptionsMenu(menu, inflater); + } + + @Override + public void onPrepareOptionsMenu(@NonNull Menu menu) { + super.onPrepareOptionsMenu(menu); + menu.findItem(R.id.menu_item_go_back).setEnabled(menuItemRollBackEnable); + } + + private void initClickListener() { + mBinding.surveyor.setOnClickListener(view -> { + goSurvey(); + }); + mBinding.autoSurveyor.setOnClickListener(view -> { + goAutoSurvey(); + }); + + //测回点击 + mBinding.cycleLayout.setOnClickListener(view -> { + if (cycleList == null || cycleList.isEmpty()) { + ToastUtils.showShort(R.string.cycle_data_abnormal_toast); + return; + } + BottomSheetSelectListFragment.showSelect( + getChildFragmentManager(), + getViewLifecycleOwner(), + cycleIndex, + cycleList, + null,//不再限制测期 + (index, string) -> { + mBinding.circleText.setText(string); + cycleIndex = index; + refreshCycleForFragment(); + }); + } + ); + } + + private void refreshCycleForFragment() { + if (currentFragment != null) { + //检测当前测回是否完成 + currentFragment.switchCycle(cycleIndex); + } + } + + protected String stationId() { + if (getArguments() == null) { + return null; + } + return getArguments().getString(BundleConstants.KEY_SURVEYOR_STATION_ID); + } + + private void initStation() { + ThreadPoolUtil.execute(() -> { + surveyorStationRecord = SurveyorDatabaseFactory + .instance + .getSurveyorStation() + .getRecordSync(stationId()); + //监听数据变化 + ToleranceDetailRecord toleranceRecord = getTolerance(surveyorStationRecord); + if (toleranceRecord == null) { + return; + } + AtomicInteger cycleCount = new AtomicInteger(toleranceRecord.getCycleCount()); + cycleList = SurveyorCycleUtil.cycleStrings(cycleCount.get(), + surveyorStationRecord != null && surveyorStationRecord.leftAndRightSurveyor); + + }); + } + + protected void initView() { + + } + + private void initViewPager(View view) { + fragments = new ArrayList<>(); + addFragmentsTabs(() -> { + mBinding.tabLayout.setVisibility(fragments.size() == 1 ? View.GONE : View.VISIBLE); + + mBinding.cycleLayout.setVisibility(isShowSelectCycle(mBinding.vp.getCurrentItem()) ? View.VISIBLE : View.GONE); + + SlidingTabLayout tabLayout = view.findViewById(R.id.tabLayout); + mBinding.vp.setAdapter(new MyPagerAdapter(getChildFragmentManager())); + tabLayout.setViewPager(mBinding.vp); + + mBinding.vp.setCurrentItem(defaultPageIndex()); + currentFragment = fragments.get(defaultPageIndex()); + + mBinding.vp.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + currentFragment = fragments.get(position); + View pick = view.findViewById(R.id.cycleLayout); +// //是否显示选择测期 + pick.setVisibility(isShowSelectCycle(position) ? View.VISIBLE : View.GONE); + //刷新测量按钮状态 + boolean currentCycleComplete = currentFragment.isCurrentCycleComplete(); + if (currentCycleComplete) { + SurveyStateEvent.postCompleted(position); + } else { + SurveyStateEvent.postIdle(position); + } + + //切换tab测回可能会变刷新当前fragment + refreshCycleAndFragment(); + + currentFragment.refreshGoBackBtnEnable(); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + }); + } + + private void refreshCycleAndFragment() { + ThreadPoolUtil.execute(() -> { + SurveyorScheduleRecord record = SurveyorDatabaseFactory + .instance + .getScheduleDataSource() + .findScheduleSync(getCurrentPageCycleKey()); + + if (record != null) { + refreshCycleUi(record); + refreshCycleForFragment(); + } + }); + } + + protected void monitorCurrentCycle(String currentCycleKey) { + SurveyorDatabaseFactory + .instance + .getScheduleDataSource() + .findSchedule(currentCycleKey) + .observe(getViewLifecycleOwner(), record -> { + if (!currentCycleKey.equals(getCurrentPageCycleKey())) { + return; + } + refreshCycleUi(record); + }); + } + + private void refreshCycleUi(SurveyorScheduleRecord record) { + int cycleIndex = DigitalUtil.valueOfIntString(record == null ? "0" : record.getStatue(), 0); + //更新测回名称 + boolean showLeftOrRight = true; + if (surveyorStationRecord != null) { + showLeftOrRight = surveyorStationRecord.leftAndRightSurveyor; + } + mBinding.circleText.setText(SurveyorCycleUtil.cycleName(cycleIndex, showLeftOrRight)); + this.cycleIndex = cycleIndex; + } + + + @WorkerThread + private static ToleranceDetailRecord getTolerance(SurveyorStationRecord surveyorStationRecord) { + if (surveyorStationRecord == null) { + return null; + } + //获取project信息 + ProjectRecord projectRecord = SurveyorDatabaseFactory + .instance + .getProjectDataSource() + .getRecord(surveyorStationRecord.getProjectId()); + if (projectRecord == null) { + return null; + } + //获取限差数据 + return SurveyorDatabaseFactory + .instance + .getToleranceDetailDataSource() + .getRecordSync(projectRecord.getToleranceId()); + } + + private void goSurvey() { + if (currentFragment != null) { + currentFragment.doSurveyor(); + } + } + + private void goAutoSurvey() { + if (currentFragment != null) { + currentFragment.autoSurvey(); + } + } + + private class MyPagerAdapter extends FragmentPagerAdapter { + public MyPagerAdapter(FragmentManager fm) { + super(fm); + } + + @Override + public int getCount() { + return fragments.size(); + } + + @Override + public CharSequence getPageTitle(int position) { + return tabs.get(position); + } + + @Override + public Fragment getItem(int position) { + return (Fragment) fragments.get(position); + } + } + + protected void stationCheckAdjustBefore() { + StationCheckBeforeUtil.stationAdjustBefore(getScheduleIdForAllCycle(), new StationCheckBeforeUtil.ICallBack() { + + @Override + public void next(int nextType) { + if (currentFragment != null) { + if (nextType == StationCheckBeforeUtil.STATION_ADJUST) { + currentFragment.stationAdjust(); + } else if (nextType == StationCheckBeforeUtil.STATION_CHECK) { + //已经完成测量,开始测站检测 + String error = currentFragment.stationCheck(); + if (TextUtils.isEmpty(error)) { + currentFragment.stationAdjust(); + } else { + TipsFragment.cancelAbleTips(getChildFragmentManager(), getViewLifecycleOwner(), requireContext(), + error + Tools.getString(R.string.is_adjustment_forced), 0, () -> { + currentFragment.stationAdjust(); + }); + } + } + } + } + + @Override + public void error(String error) { + tipsError(error); + } + }); + + } + + protected void stationCheckBefore() { + StationCheckBeforeUtil.stationDetectBefore(getScheduleIdForAllCycle(), new StationCheckBeforeUtil.ICallBack() { + @Override + public void next(int nextType) { + if (currentFragment != null) { + String error = currentFragment.stationCheck(); + if (TextUtils.isEmpty(error)) { + if (isVisiable()) { + TipsFragment.cancelAbleTips(getChildFragmentManager(), getViewLifecycleOwner(), requireContext(), + Tools.getString(R.string.station_passed_is_adjust), 0, + () -> currentFragment.stationAdjust()); + } + } else { + tipsError(error); + } + } + } + + @Override + public void error(String error) { + tipsError(error); + } + }); + } + + private void tipsError(String error) { + if (isVisiable() && !TextUtils.isEmpty(error)) { + TipsFragment.tipsOnly(getChildFragmentManager(), getViewLifecycleOwner(), requireContext(), error); + } + } + + private boolean isVisiable() { + return getViewLifecycleOwner().getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED); + } + + private int getCurrentPageTypePosition() { + return fragments.get(mBinding.vp.getCurrentItem()).measureTypePosition(); + } + + /** + * 是否是无效的点 + * + * @param position + * @return + */ + private boolean isInValidEventPosition(int position) { + return mBinding == null || position != getCurrentPageTypePosition(); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/heighttraverse/MeasureHeightTraverseFragment.kt b/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/heighttraverse/MeasureHeightTraverseFragment.kt new file mode 100644 index 0000000..9bbe7e6 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/heighttraverse/MeasureHeightTraverseFragment.kt @@ -0,0 +1,229 @@ +package com.bingce.controlnetwork.fragment.stationsurvey.heighttraverse + +import android.content.Context +import android.os.Bundle +import android.view.MenuItem +import android.view.View +import androidx.fragment.app.Fragment +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory +import com.bingce.controlapphelper.datasource.database.heighttraverse.config.model.StationLayout +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleConstants +import com.bingce.controlapphelper.model.BundleConstants +import com.bingce.controlapphelper.util.StationUtil.getStationName +import com.bingce.controlapphelper.util.Tools +import com.bingce.controlnetwork.R +import com.bingce.controlnetwork.activity.fragmentcontainer.FragmentContainerActivity +import com.bingce.controlnetwork.fragment.SurveyorSettingsFragment +import com.bingce.controlnetwork.fragment.TipsWith2OptionFragment +import com.bingce.controlnetwork.fragment.stationsetting.StationSettingHeightTraverseFragment +import com.bingce.controlnetwork.fragment.stationsurvey.base.MeasureBaseFragment +import com.bingce.controlnetwork.surveyor.state.heighttraverse.__BaseState +import com.bingce.controlnetwork.surveyor.surveyor.TestDataSelectFragment +import com.bingce.utils.ThreadPoolUtil +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.MainScope +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + +class MeasureHeightTraverseFragment : MeasureBaseFragment() { + + private val mainScope = MainScope() + + companion object { + const val POSITION_BACK_PAGE = 0 + const val POSITION_FRONT_PAGE = 1 + + @JvmField + val TAG: String = MeasureHeightTraverseFragment::class.java.name + + @JvmStatic + fun start(context: Context, surveyorStationId: String, surveyorStationName: String?) { + val bundle = Bundle() + bundle.putString(BundleConstants.KEY_SURVEYOR_STATION_ID, surveyorStationId) + FragmentContainerActivity.start( + context, + TAG, + surveyorStationName, + bundle + ) + } + + @JvmStatic + fun newInstance(args: Bundle?): Fragment { + val fragment: Fragment = MeasureHeightTraverseFragment() + fragment.arguments = args + return fragment + } + } + + override fun isShowSelectCycle(position: Int): Boolean { + return false + } + + override fun defaultPageIndex(): Int { + return POSITION_BACK_PAGE + } + + override fun initView() { + super.initView() + setSurveyorEnable(mBinding.surveyor, false) + } + + override fun addFragmentsTabs(runnable: Runnable) { + mainScope.launch(Dispatchers.IO) { + val stationId = stationId() + + val stationRecord = + SurveyorDatabaseFactory.instance.surveyorStation.getRecordSync(stationId) + val configRecord = + SurveyorDatabaseFactory.instance.getHeightTraverseConfigDataSource() + .getRecordByProjectId(stationRecord.getProjectId()) + + if (configRecord?.stationLayout == StationLayout.SEPARATE) { + fragments.add( + MeasureHeightTraverseSubFragment.newInstance( + stationId, + POSITION_BACK_PAGE + ) + ) + fragments.add( + MeasureHeightTraverseSubFragment.newInstance( + stationId, + POSITION_FRONT_PAGE + ) + ) + + tabs.add(Tools.getString(R.string.rearview)) + tabs.add(Tools.getString(R.string.forward_view)) + } else if (configRecord?.stationLayout == StationLayout.EVERY) { + fragments.add( + MeasureHeightTraverseSubFragment.newInstance( + stationId, + POSITION_FRONT_PAGE + ) + ) + tabs.add(Tools.getString(R.string.forward_view)) + } + withContext(Dispatchers.Main) { + runnable.run() + } + } + } + + override fun isAloneDistancePage(pageIndex: Int): Boolean { + return false + } + + override fun getCurrentPageCycleKey(): String { + return SurveyorScheduleConstants.getCurrentCycleKey( + stationId(), + __BaseState.getScheduleKey(mBinding.vp.currentItem) + ) + } + + override fun getScheduleIdForAllCycle(): String { + val positionFragment = getCurrentMeasurePos() + return SurveyorScheduleConstants.getAllCycleScheduleKey( + stationId(), + __BaseState.getScheduleKey(positionFragment) + ) + } + + private fun getCurrentMeasurePos(): Int { + val measureHeightTraverseSubFragment = currentFragment as MeasureHeightTraverseSubFragment + return measureHeightTraverseSubFragment.backOrFrontPosition + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + monitorCurrentCycle( + SurveyorScheduleConstants.getCurrentCycleKey( + stationId(), + SurveyorScheduleConstants.STATION_TYPE_HEIGHT_TRAVERSE_BACK + ) + ) + monitorCurrentCycle( + SurveyorScheduleConstants.getCurrentCycleKey( + stationId(), + SurveyorScheduleConstants.STATION_TYPE_HEIGHT_TRAVERSE_FRONT + ) + ) + } + + override fun onOptionsItemSelected(item: MenuItem): Boolean { + if (R.id.menu_item_delete_current_records == item.itemId) { + //删除当前测回记录 + if (surveyorStationRecord != null && currentFragment != null) { + //通知fragment + currentFragment.deleteStationOnePeriodRecord(getCurrentMeasurePos()) + } + } else if (R.id.menu_item_delete_all_records == item.itemId) { + //删除所有测回记录 + showDeleteStationRecord() + } else if (R.id.menu_item_station_check == item.itemId && currentFragment != null) { + //测站检测 + stationCheckBefore() + } else if (R.id.menu_item_data_source == item.itemId) { + //数据源 debug使用 + TestDataSelectFragment.show(childFragmentManager) + } else if (R.id.menu_item_go_back == item.itemId && currentFragment != null) { + //回退 + currentFragment.goBack() + } else if (R.id.menu_item_station_environment_prism_settings == item.itemId) { + //环境、棱镜设置 + StationSettingHeightTraverseFragment.start(requireContext(), stationId()) + } else if (R.id.menu_item_surveyor_settings == item.itemId) { + //测量设置 设置是否显示平距 + ThreadPoolUtil.execute { + val name = getStationName(surveyorStationRecord) + runOnUI { + SurveyorSettingsFragment.start( + context, + surveyorStationRecord.getId(), + name + ) + } + } + } else if (R.id.menu_item_check_adjust == item.itemId && currentFragment != null) { + //检测平差 + stationCheckAdjustBefore() + } + return super.onOptionsItemSelected(item) + } + + /** + * 删除测站的后视和前视的所有测回记录 + */ + private fun showDeleteStationRecord() { + if (surveyorStationRecord == null || currentFragment == null) { + return + } + val fragment = currentFragment as MeasureHeightTraverseSubFragment + if (fragment.isInvalite || fragment.isDead) { + return + } + + val msg = if (fragments.size == 1) { + "是否确定删除该站的所有测回数据?" + } else { + "是否确定删除该站的后视和前视的所有测回数据?" + } + + TipsWith2OptionFragment.tips( + childFragmentManager, + this, + null, + null, + null, + msg, + object : TipsWith2OptionFragment.SimpleCallback() { + override fun onConfirm() { + for (fragmentI in fragments) { + fragmentI.deleteStationAllPeroidRecord() + } + } + }) + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/heighttraverse/MeasureHeightTraverseSubFragment.java b/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/heighttraverse/MeasureHeightTraverseSubFragment.java new file mode 100644 index 0000000..89d7499 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/fragment/stationsurvey/heighttraverse/MeasureHeightTraverseSubFragment.java @@ -0,0 +1,415 @@ +package com.bingce.controlnetwork.fragment.stationsurvey.heighttraverse; + +import android.content.Context; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.WorkerThread; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; +import androidx.lifecycle.ViewModelProvider; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.project.ProjectRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord; +import com.bingce.controlapphelper.datasource.database.tolerance.detail.ToleranceDetailRecord; +import com.bingce.controlapphelper.event.RefreshGoBackButton; +import com.bingce.controlapphelper.model.DataCategory; +import com.bingce.controlapphelper.model.LeftOrRight; +import com.bingce.controlapphelper.surveyor.data.CachedDataHeightTraverse; +import com.bingce.controlapphelper.surveyor.data.ICachedData; +import com.bingce.controlapphelper.surveyor.data.IDistanceTypeChangeListener; +import com.bingce.controlapphelper.surveyor.data.ISurveyorData; +import com.bingce.controlapphelper.surveyor.data.SurveyorData; +import com.bingce.controlapphelper.surveyor.state.ISurveyState; +import com.bingce.controlapphelper.surveyor.surveyor.RequestSurveyorParamAuto; +import com.bingce.controlapphelper.util.IUIRunner; +import com.bingce.controlapphelper.util.IdUtil; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.adapter.MeasureHeightTraverseAdapter; +import com.bingce.controlnetwork.fragment.ComponentStationSurveyorDataListFragment; +import com.bingce.controlnetwork.fragment.StationDataAdjustDialogFragment; +import com.bingce.controlnetwork.fragment.base.BaseLazyFragment; +import com.bingce.controlnetwork.fragment.stationsurvey.IMeasureOperate; +import com.bingce.controlnetwork.fragment.stationsurvey.angledistance.MeasureVm; +import com.bingce.controlnetwork.surveyor.state.IScrollDelegate; +import com.bingce.controlnetwork.surveyor.state.heighttraverse.StateManagerHeightTraverse; +import com.bingce.totalstation.TotalStation; +import com.bingce.utils.ThreadPoolUtil; + +import org.greenrobot.eventbus.EventBus; + +/** + * 测角测距 + */ +public class MeasureHeightTraverseSubFragment extends BaseLazyFragment + implements IDistanceTypeChangeListener, ISurveyState, IMeasureOperate { + private MeasureHeightTraverseAdapter adapter = null; + private StateManagerHeightTraverse stateManager; + private RecyclerView recyclerView; + private ICachedData cachedData = null; + private ISurveyorData surveyedData = null; + private ISurveyState surveyState; + + private String stationId() { + if (getArguments() == null) { + throw new RuntimeException("getArguments()==null"); + } + return getArguments().getString(KEY_STATION_ID); + } + + public int getBackOrFrontPosition() { + if (getArguments() == null) { + throw new RuntimeException("getArguments()==null"); + } + return getArguments().getInt(KEY_TYPE_BACK_OR_FRONT); + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, + @Nullable ViewGroup container, + @Nullable Bundle savedInstanceState) { + View view = inflater.inflate( + R.layout.fragment_project_surveyor_station_point_list_layout, + container, + false); + recyclerView = view.findViewById(R.id.recycler_view); + return view; + } + + @WorkerThread + private void onCollectStationData( + boolean showSlopDistance, + ICachedData cachedData, + SurveyorData surveyorData, + StateManagerHeightTraverse stateManager) { + this.stateManager = stateManager; + this.cachedData = cachedData; + surveyedData = surveyorData; + + //测量数据收集完毕后,就可以更新UI了 + runOnUI(() -> { + //刷新UI + if (adapter == null) { + adapter = new MeasureHeightTraverseAdapter(stationId(), + cachedData, surveyorData, surveyorData, getBackOrFrontPosition()); + adapter.onShowSlopDistance(showSlopDistance); + if (recyclerView != null) { + recyclerView.setAdapter(adapter); + //滚动到当前目标点 + int currentItemIndex = surveyorData.currentIndex(); + if (currentItemIndex >= 0 && currentItemIndex < adapter.getItemCount()) { + recyclerView.scrollToPosition(currentItemIndex); + } + } + } + + //监听测站数据 + //监听「平距」「斜距」切换,更新UI显示 + SurveyorDatabaseFactory + .instance + .getSurveyorStation() + .getLiveDataRecord(stationId()) + .observe(getViewLifecycleOwner(), + surveyorStationRecord -> onShowSlopDistance(surveyorStationRecord.isShowSlopDistance())); + }); + } + + /** + * 收集测站信息 + */ + private void collectData( + String stationId, + Context context, + FragmentManager fragmentManager, + LifecycleOwner lifecycleOwner, + IUIRunner runner, + IScrollDelegate scrollDelegate, + ICollectCacheCallback callback) { + if (callback == null) { + return; + } + boolean isSupportAutoMode = TotalStation.getInstance().isSupportMotor(); + ThreadPoolUtil.execute(() -> { + //加载测站信息 + SurveyorStationRecord surveyorStationRecord = + SurveyorDatabaseFactory + .instance + .getSurveyorStation() + .getRecordSync(stationId); + //加载对应项目 + ProjectRecord projectRecord = SurveyorDatabaseFactory + .instance + .getProjectDataSource() + .getRecord(surveyorStationRecord.getProjectId()); + if (projectRecord == null) { + callback.onFailure(); + return; + } + //加载对应限差 + ToleranceDetailRecord toleranceRecord = SurveyorDatabaseFactory + .instance + .getToleranceDetailDataSource() + .getRecordSync(projectRecord.getToleranceId()); + if (toleranceRecord == null) { + callback.onFailure(); + return; + } + //创建缓存数据 + CachedDataHeightTraverse cachedData = + CachedDataHeightTraverse.newInstance(getBackOrFrontPosition(), + stationId, toleranceRecord); + if (cachedData == null) { + callback.onFailure(); + return; + } + + //是否显示斜距? + cachedData.onShowSlopDistance(surveyorStationRecord.isShowSlopDistance()); + if (cachedData.pointCount() <= 0) { + callback.onFailure(); + return; + } + + //创建stateManager实例 + SurveyorData surveyorDataSource = new SurveyorData(toleranceRecord.getSurveyorCount()); + surveyorDataSource.onShowSlopDistance(surveyorStationRecord.isShowSlopDistance()); + + //存入cacheData 用于自动测量时使用 + MeasureVm measureVm = new ViewModelProvider(requireParentFragment()).get(MeasureVm.class); + RequestSurveyorParamAuto requestSurveyorParamAuto = new RequestSurveyorParamAuto(stationId, cachedData); + measureVm.setRequestSurveyorParamAuto(requestSurveyorParamAuto); + + StateManagerHeightTraverse stateManager = StateManagerHeightTraverse.newInstance( + getBackOrFrontPosition(), + isSupportAutoMode, + requestSurveyorParamAuto, + surveyorStationRecord, + context, + fragmentManager, + lifecycleOwner, + toleranceRecord, + surveyorDataSource, + surveyorDataSource, + cachedData, + scrollDelegate, + runner); + //fragment创建后立即计算当前cycle的测量状态 + runner.runOnUI(() -> stateManager.calScheduleWhenEnterSurveyFragment(0)); + callback.onSuccess(surveyorStationRecord.isShowSlopDistance(), cachedData, surveyorDataSource, stateManager); + }); + } + + @Override + public void onResume() { + super.onResume(); + if (stateManager != null) { + stateManager.resume(); + } + } + + @Override + public void onPause() { + super.onPause(); + if (stateManager != null) { + stateManager.quite(); + } + } + + @Override + protected void loadData() { + String stationId = stationId(); + if (stationId != null) { + //收集信息 + collectData(stationId, + getContext(), + getChildFragmentManager(), + getViewLifecycleOwner(), + this::runOnUI, + index -> { + if (index >= 0 && adapter != null && index < adapter.getItemCount()) { + recyclerView.scrollToPosition(index); + } + }, + new ICollectCacheCallback() { + @Override + public void onFailure() { + } + + @Override + public void onSuccess(boolean showSlopDistance, ICachedData cachedData, SurveyorData surveyorData, StateManagerHeightTraverse stateManager) { + onCollectStationData(showSlopDistance, cachedData, surveyorData, stateManager); + surveyState = stateManager; + } + } + ); + } + } + + public interface ICollectCacheCallback { + void onFailure(); + + void onSuccess(boolean showSlopDistance, ICachedData cachedData, SurveyorData surveyorData, StateManagerHeightTraverse stateManager); + } + + @Override + public void doSurveyor() { + if (stateManager == null) { + return; + } + stateManager.doSurveyor(); + } + + @Override + public void autoSurvey() { + if (stateManager == null) { + return; + } + stateManager.doAutoSurveyor(); + } + + @Override + public void switchCycle(int cycleIndex) { + if (stateManager == null) { + return; + } + stateManager.switch2Cycle(cycleIndex); + } + + @Override + public void deleteStationAllPeroidRecord() { + if (stateManager == null) { + return; + } + stateManager.deleteCurrentStationSurveyorData(); + } + + @Override + public void deleteStationOnePeriodRecord(int positionFragment) { + if (stateManager == null) { + return; + } + stateManager.deleteCurrentStationSurveyorData(positionFragment); + } + + @Override + public String stationCheck() { + if (stateManager == null) { + return null; + } + return stateManager.stationCheckOnly(); + } + + @Override + public void stationAdjust() { + if (stateManager == null) { + return; + } + stateManager.stationAdjustOnly(StationDataAdjustDialogFragment.TYPE_ANGLE_VER_AND_DISTANCE); + } + + @Override + public void goBack() { + if (stateManager == null) { + return; + } + stateManager.moveBack(); + } + + /** + * 对于高程导线来说 这个方法实现当前目标的所有测回是否完成 + * + * @return + */ + @Override + public boolean isCurrentCycleComplete() { + if (stateManager == null || cachedData == null || cachedData.pointCount() == 0) + return false; + for (int i = 0; i < cachedData.pointCount(); i++) { + String pointId = cachedData.pointId(i, i); + String recordIdLeft = IdUtil.createSurveyorRecordId(stationId(), i, pointId, LeftOrRight.left); + String recordIdRight = IdUtil.createSurveyorRecordId(stationId(), i, pointId, LeftOrRight.right); + DataCategory dataCategoryLeft = cachedData.valueState(recordIdLeft); + DataCategory dataCategoryRight = cachedData.valueState(recordIdRight); + if (dataCategoryLeft.isEmptyData() || dataCategoryRight.isEmptyData()) { + //只要有空数据就是未完成 + return false; + } + } + return true; + } + + @Override + public void refreshGoBackBtnEnable() { + if (stateManager == null || stateManager.getCachedData().pointCount() == 0) { + EventBus.getDefault().post(new RefreshGoBackButton(false)); + return; + } + stateManager.refreshGoBackBtnEnable(); + } + + @Override + public int measureTypePosition() { + return getBackOrFrontPosition(); + } + + @Override + public void onShowSlopDistance(boolean value) { + if (cachedData != null) { + cachedData.onShowSlopDistance(value); + } + if (surveyedData != null) { + surveyedData.onShowSlopDistance(value); + } + if (adapter != null) { + adapter.onShowSlopDistance(value); + adapter.notifyItemRangeChanged(0, adapter.getItemCount()); + } + } + + @Override + public boolean isSurveying() { + if (surveyState != null) { + return surveyState.isSurveying(); + } + return false; + } + + @Override + public boolean isAutoSurveying() { + if (surveyState != null) { + return surveyState.isAutoSurveying(); + } + return false; + } + + public boolean isInvalite() { + return stateManager.isInValidate(); + } + + public boolean isDead() { + return stateManager.isDead(); + } + + private static final String KEY_STATION_ID = "__station_id"; + private static final String KEY_TYPE_BACK_OR_FRONT = "__KEY_TYPE_BACK_OR_FRONT"; + public static final String TAG = ComponentStationSurveyorDataListFragment.class.getName(); + + public static MeasureHeightTraverseSubFragment newInstance(String stationId, int frontOrBack) { + MeasureHeightTraverseSubFragment fragment = new MeasureHeightTraverseSubFragment(); + Bundle bundle = new Bundle(); + bundle.putString(KEY_STATION_ID, stationId); + bundle.putInt(KEY_TYPE_BACK_OR_FRONT, frontOrBack); + fragment.setArguments(bundle); + return fragment; + } +} + + + diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/activity/LevelStationSettingActivity.kt b/app/src/main/java/com/bingce/controlnetwork/func/level/activity/LevelStationSettingActivity.kt new file mode 100644 index 0000000..bea6c46 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/activity/LevelStationSettingActivity.kt @@ -0,0 +1,145 @@ +package com.bingce.controlnetwork.func.level.activity + +import android.content.Context +import android.content.Intent +import android.view.Menu +import android.view.MenuItem +import androidx.activity.viewModels +import androidx.fragment.app.Fragment +import androidx.fragment.app.FragmentManager +import androidx.fragment.app.FragmentStatePagerAdapter +import androidx.viewpager.widget.ViewPager.OnPageChangeListener +import com.bingce.controlnetwork.func.level.fragment.LevelStationSettingConditionFragment +import com.bingce.controlnetwork.func.level.fragment.LevelStationSettingInformationFragment +import com.bingce.controlnetwork.func.level.viewmodel.LevelStationSettingVm +import com.bingce.controlapphelper.model.BundleConstants +import com.bingce.controlnetwork.R +import com.bingce.controlnetwork.databinding.ActivityLevelStationSettingBinding +import com.bingce.controlnetwork.newui.base.BaseBindingActivity +import com.bingce.controlnetwork.newui.stationsetting.IStationSettingOperate + +class LevelStationSettingActivity : BaseBindingActivity() { + + private val viewModel by viewModels() + private val fragments = mutableListOf() + private val fragmentTitleList = listOf("观测信息", "观测条件") + + companion object { + private const val KEY_IS_SAVE_END_STATION = "KEY_IS_SAVE_END_STATION" + + @JvmStatic + fun start(context: Context, routeId: String, stationId: String, isSaveEndStation: Boolean) { + context.startActivity(Intent(context, LevelStationSettingActivity::class.java).apply { + putExtra(BundleConstants.KEY_ROUTE_ID, routeId) + putExtra(BundleConstants.KEY_SURVEYOR_STATION_ID, stationId) + putExtra(KEY_IS_SAVE_END_STATION, isSaveEndStation) + }) + } + } + + + override fun getBinding(): ActivityLevelStationSettingBinding { + return ActivityLevelStationSettingBinding.inflate(layoutInflater) + } + + override fun initView() { + viewModel.initRouteStationId(getRouteId(), getStationId()) + initViewPager() + } + + override fun initData() { + viewModel.getEditLastData(getStationId()) + + viewModel.getInitCurrentTabPos { + mBinding.tabLayout.currentTab = it + } + } + + override fun onCreateOptionsMenu(menu: Menu?): Boolean { + menuInflater.inflate(R.menu.menu_confirm, menu) + return super.onCreateOptionsMenu(menu) + } + + override fun onOptionsItemSelected(item: MenuItem): Boolean { + if (R.id.menu_confirm == item.itemId) { + doConfirm() + } + return super.onOptionsItemSelected(item) + } + + private fun initViewPager() { + fragments.add(LevelStationSettingInformationFragment()) + fragments.add(LevelStationSettingConditionFragment()) + mBinding.vp.offscreenPageLimit = 3 + mBinding.vp.adapter = MyPagerAdapter(supportFragmentManager) + mBinding.tabLayout.setViewPager(mBinding.vp) + mBinding.vp.addOnPageChangeListener(object : OnPageChangeListener { + override fun onPageScrolled( + position: Int, + positionOffset: Float, + positionOffsetPixels: Int + ) { + } + + override fun onPageSelected(position: Int) { + + } + + override fun onPageScrollStateChanged(state: Int) { + + } + }) + +// //设置当前tab为仪高镜高 +// mBinding.vp.currentItem = 1 + } + + + private inner class MyPagerAdapter(fm: FragmentManager) : FragmentStatePagerAdapter(fm) { + override fun getCount(): Int { + return fragments.size + } + + override fun getPageTitle(position: Int): CharSequence { + return fragmentTitleList[position] + } + + override fun getItem(position: Int): Fragment { + return fragments[position] + } + + override fun getItemPosition(`object`: Any): Int { + return POSITION_NONE + } + } + + private fun doConfirm() { + //检查未完成的选项 + for (fragment in fragments) { + val operate = fragment as IStationSettingOperate + if (operate.checkSaveNot()) { + val fragmentNotFinishPos = fragments.indexOf(fragment) + if (mBinding.vp.currentItem != fragmentNotFinishPos) { + mBinding.tabLayout.currentTab = fragmentNotFinishPos + } + return + } + } + + viewModel.createNeedSaveLevelRouteSave(getRouteId(), getStationId()) + //赋值 + for (fragment in fragments) { + val operate = fragment as IStationSettingOperate + operate.setDataToStation() + } + + viewModel.save(getIsSaveEndStation()) { + finish() + } + } + + private fun getStationId() = intent.getStringExtra(BundleConstants.KEY_SURVEYOR_STATION_ID)!! + + private fun getRouteId() = intent.getStringExtra(BundleConstants.KEY_ROUTE_ID)!! + private fun getIsSaveEndStation() = intent.getBooleanExtra(KEY_IS_SAVE_END_STATION, false) +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/adapter/LevelRouteListAdapter.java b/app/src/main/java/com/bingce/controlnetwork/func/level/adapter/LevelRouteListAdapter.java new file mode 100644 index 0000000..6ec1daf --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/adapter/LevelRouteListAdapter.java @@ -0,0 +1,38 @@ +package com.bingce.controlnetwork.func.level.adapter; + + +import android.content.Context; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; + +import com.bingce.controlapphelper.datasource.database.leveling.route.LevelRouteRecord; +import com.bingce.controlapphelper.model.LevelingMeasureOrderUtil; + +import com.bingce.controlnetwork.databinding.ItemLevelRouteListBinding; +import com.bingce.controlnetwork.newui.adapter.BaseAdapterNew; + + +public class LevelRouteListAdapter extends BaseAdapterNew { + + public LevelRouteListAdapter(Context context) { + super(context); + } + + @NonNull + @Override + public LevelRouteListViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + return new LevelRouteListViewHolder(ItemLevelRouteListBinding.inflate(getInflater(), parent, false)); + } + + @Override + protected void onBindViewHolderDo(LevelRouteListViewHolder holder, int position) { + LevelRouteRecord bean = mDataList.get(position); + holder.mBinding.tvIndex.setText(String.valueOf(position + 1)); + holder.mBinding.tvRouteName.setText(bean.getRouteName()); + holder.mBinding.tvOrderType.setText(LevelingMeasureOrderUtil.INSTANCE.getTextByLevelingMeasureOrder(bean.getLevelingMeasureOrder())); + holder.mBinding.tvWay.setText(bean.getObservationDirection()); + } + + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/adapter/LevelRouteListViewHolder.java b/app/src/main/java/com/bingce/controlnetwork/func/level/adapter/LevelRouteListViewHolder.java new file mode 100644 index 0000000..12bc6ce --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/adapter/LevelRouteListViewHolder.java @@ -0,0 +1,15 @@ +package com.bingce.controlnetwork.func.level.adapter; + +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlnetwork.databinding.ItemLevelRouteListBinding; + + +public class LevelRouteListViewHolder extends RecyclerView.ViewHolder { + public final ItemLevelRouteListBinding mBinding; + + public LevelRouteListViewHolder(ItemLevelRouteListBinding binding) { + super(binding.getRoot()); + mBinding = binding; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/constant/LevelConstant.kt b/app/src/main/java/com/bingce/controlnetwork/func/level/constant/LevelConstant.kt new file mode 100644 index 0000000..5b84f2e --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/constant/LevelConstant.kt @@ -0,0 +1,13 @@ +package com.bingce.controlnetwork.func.level.constant + +/** + * 水准常量 + */ +object LevelConstant { + /** + * 默认经纬度郑州 + */ + const val LONGITUDE_DEFAULT = 113.6482317 + const val LATITUDE_DEFAULT = 34.7492133 + const val HEIGHT_DEFAULT = 0.0 +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/constant/LevelStationSettingContant.kt b/app/src/main/java/com/bingce/controlnetwork/func/level/constant/LevelStationSettingContant.kt new file mode 100644 index 0000000..b76a247 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/constant/LevelStationSettingContant.kt @@ -0,0 +1,55 @@ +package com.bingce.controlnetwork.func.level.constant + +import com.bingce.controlapphelper.util.Tools +import com.bingce.controlnetwork.R + +object LevelStationSettingContant { + val observationDirectionList = listOf("往测", "返测", "检往", "检返", "重往", "重返") + val weatherList = listOf("晴", "阴", "雨", "雪") + val imagingList = + listOf("清晰", "小雾", "中雾", "大雾") + val sunDirectionList = + listOf("无太阳", "前", "后", "左", "右") + val windDirectionList = + listOf( + "无", + "东", + "南", + "西", + "北", + "东南", + "西南", + "东北", + "西北" + ) + val windSpeedList = + listOf( + "无", + "0级无风", + "1级软风", + "2级轻风", + "3级微风", + "4级和风", + "5级清劲风", + "6级强风", + "7级疾风", + "8级大风" + ) + val roadsList = + listOf( + Tools.getString(R.string.please_choose), + "柏油路", "水泥路", "土路", "砂石路", "铁路", "其他" + ) + + val soilList = + listOf( + Tools.getString(R.string.please_choose), + "柏油", "水泥", "实土", "沙石", "草地" + ) + + val rulerTypeList = listOf("铟瓦尺", "木质", "其他") + + //尺承类型 + val rulerReceptTypeList = + listOf("钢尺桩", "5kg以上尺台", "不足5kg尺台", "钢帽钉", "木桩", "其他") +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/dialog/LevelToleranceTipsFragment.java b/app/src/main/java/com/bingce/controlnetwork/func/level/dialog/LevelToleranceTipsFragment.java new file mode 100644 index 0000000..e6bd0f7 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/dialog/LevelToleranceTipsFragment.java @@ -0,0 +1,129 @@ +package com.bingce.controlnetwork.func.level.dialog; + +import static com.bingce.controlapphelper.model.LevelToleranceNoticeKt.VALUE_IGNORE; +import static com.bingce.controlapphelper.model.LevelToleranceNoticeKt.VALUE_REMEASURE_POINT; +import static com.bingce.controlapphelper.model.LevelToleranceNoticeKt.VALUE_REMEASURE_STATION; + +import android.app.Dialog; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.WindowManager; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatDialogFragment; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; + +import com.bingce.controlnetwork.R; + +/** + * 水准限差超限提示框 + */ +public class LevelToleranceTipsFragment extends AppCompatDialogFragment { + + private static final String KEY_TITLE = "__TITLE"; + private static final String KEY_CONTENT = "___CONTENT"; + private static final String KEY_RESULT = "KEY_RESULT"; + private static final String KEY_BUNDLE = "KEY_BUNDLE"; + + private static final String TAG = LevelToleranceTipsFragment.class.getName(); + + public static void tips(@NonNull FragmentManager fragmentManager, + @NonNull LifecycleOwner lifecycleOwner, + String title, + String content, + IOperatorCallback callback) { + Bundle args = new Bundle(); + LevelToleranceTipsFragment fragment = new LevelToleranceTipsFragment(); + fragment.setArguments(args); + args.putString(KEY_TITLE, title); + args.putString(KEY_CONTENT, content); + fragmentManager + .setFragmentResultListener( + KEY_BUNDLE, + lifecycleOwner, + (requestKey, result) -> { + int type = result.getInt(KEY_RESULT, -1); + if (VALUE_IGNORE == type) { + callback.onIgnore(); + } else if (VALUE_REMEASURE_STATION == type) { + callback.onReMeasureStation(); + } else if (VALUE_REMEASURE_POINT == type) { + callback.onReMeasurePoint(); + } + }); + fragment.show(fragmentManager, TAG); + } + + public interface IOperatorCallback { + void onReMeasureStation(); + + void onReMeasurePoint(); + + void onIgnore(); + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View contentView = inflater.inflate(R.layout.fragment_level_tolerance_tips, container, false); + + TextView tvTitle = contentView.findViewById(R.id.tvTitle); + tvTitle.setText(getTitle()); + TextView tvContent = contentView.findViewById(R.id.tvContent); + tvContent.setText(getContent()); + + contentView.findViewById(R.id.btnIgnore).setOnClickListener(v -> { + setBackResult(VALUE_IGNORE); + }); + contentView.findViewById(R.id.btnRemeasureStation).setOnClickListener(v -> { + setBackResult(VALUE_REMEASURE_STATION); + }); + contentView.findViewById(R.id.btnRemeasureCurrent).setOnClickListener(v -> { + setBackResult(VALUE_REMEASURE_POINT); + }); + return contentView; + } + + private void setBackResult(int clickType) { + Bundle bundle = new Bundle(); + bundle.putInt(KEY_RESULT, clickType); + getParentFragmentManager().setFragmentResult(KEY_BUNDLE, bundle); + //关闭dialog + dismissAllowingStateLoss(); + } + + @Override + public void onStart() { + super.onStart(); + Dialog dialog = getDialog(); + if (dialog == null) { + return; + } + dialog.getWindow().setLayout( + WindowManager.LayoutParams.MATCH_PARENT, + WindowManager.LayoutParams.WRAP_CONTENT); + } + + private String getTitle() { + Bundle arguments = getArguments(); + if (arguments != null) { + return arguments.getString(KEY_TITLE); + } + return null; + } + + private String getContent() { + Bundle arguments = getArguments(); + if (arguments != null) { + return arguments.getString(KEY_CONTENT); + } + return null; + } + + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/export/LevelExportIDetection.kt b/app/src/main/java/com/bingce/controlnetwork/func/level/export/LevelExportIDetection.kt new file mode 100644 index 0000000..4e58355 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/export/LevelExportIDetection.kt @@ -0,0 +1,231 @@ +package com.bingce.controlnetwork.func.level.export + +import android.util.Log +import androidx.annotation.WorkerThread +import com.bingce.controlapphelper.datasource.database.leveling.LevelingDbFactory +import com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant +import com.bingce.controlapphelper.datasource.database.leveling.idetection.list.LevelIDetectionList +import com.bingce.controlapphelper.datasource.database.leveling.idetection.record.LevelIDetectionRecord +import com.bingce.controlapphelper.leveling.detaction.LevelFormatUtil +import com.bingce.controlapphelper.model.getLength +import com.bingce.controlnetwork.func.level.util.LevelDateUtil +import com.bingce.controlnetwork.func.level.util.LevelDateUtil.getLevelHeadDateHourMin + +/** + * i角检测导出 + */ +class LevelExportIDetection { + + private var levelNoIndex = 0 + + companion object { + const val _N = "\r\n" + const val _S = "\u0020" + const val LEVEL_NO = "LEVEL|No" + const val TO = "TO" + const val INF = "INF" + const val SHU = "|" + const val CHECK_RECORD_SIZE = 20 + } + + + @WorkerThread + fun export(iDetection: LevelIDetectionList): String? { + val recordList = + LevelingDbFactory.instance.iDetectionRecordDataSource.getRecordsByIDetectionId( + iDetection.id + ) + + if (recordList.isEmpty() || recordList.size != CHECK_RECORD_SIZE) { + return null + } + if (iDetection.iResult == null) { + return null + } + if (iDetection.shortDistance == null || iDetection.longDistance == null + || iDetection.measureType == null + ) { + return null + } + val firstRecordCreateDate = recordList.first().createDate + val dateYMD = + LevelDateUtil.getLevelHeadDateYearMonthDay(firstRecordCreateDate) + val dateHM = getLevelHeadDateHourMin(firstRecordCreateDate) + + val settting = + LevelingDbFactory.instance.iDetectionSettingDataSource.getByIDetectionId(iDetection.id) + + val sb = StringBuilder() + + //startI + sb.append(LEVEL_NO).append(getLevelNoRightSpace()).append(getNoIndexName()).append(SHU) + .append(TO).append(getSpace2()).append("Start-I").append(getSpace10()) + .append(iDetection.measureType).append(SHU).append(getSpace30()).append(SHU) + .append(getSpace30()).append(SHU).append(getSpace30()).append(SHU) + .append(_N) + + levelNoIndexIncrease() + + //i角检测的设置 + appendSetting(sb, "instrumentModel", toString(settting.instrumentModel)) + appendSetting(sb, "deviceNumber", "No.${toString(settting.deviceNumber)}") + appendSetting(sb, "dateYMD", dateYMD) + appendSetting(sb, "dateHM", dateHM) + appendSetting(sb, "rulerNum1", toString(settting.rulerNum1)) + appendSetting(sb, "rulerNum2", toString(settting.rulerNum2)) + appendSetting(sb, "imaging", toString(settting.imaging)) + appendSetting(sb, "watcher", toString(settting.watcher)) + appendSetting(sb, "recorder", toString(settting.recorder)) + appendSetting(sb, "examiner", toString(settting.examiner)) + //D1 D2 + appendD1D2(sb, "D1", iDetection.shortDistance) + appendD1D2(sb, "D2", iDetection.longDistance) + + //先排个序 + recordList.sortWith( + Comparator.comparing(LevelIDetectionRecord::stationType) + .thenComparing(LevelIDetectionRecord::rulerType) + .thenComparing(LevelIDetectionRecord::measureTime) + ) + for (record in recordList) { + Log.d( + "hwhw", + "" + record.stationType + "," + record.rulerType + "," + record.measureTime + ) + appendRecord(sb, record) + } + //iResult + val iResultUnit = if (iDetection.iResult != null) { + "${iDetection.iResult} s" + } else { + "" + } + val spaceIResultLeft = getSpace(30 - 4 - iResultUnit.length - 1) + sb.append(LEVEL_NO).append(getLevelNoRightSpace()).append(getNoIndexName()).append(SHU) + .append("I").append(getSpace(29)).append(SHU) + .append(getSpace30()).append(SHU) + .append(getSpace30()).append(SHU) + .append("I").append(spaceIResultLeft).append(iResultUnit).append(getSpace4()) + .append(SHU) + .append(_N) + levelNoIndexIncrease() + //endI + sb.append(LEVEL_NO).append(getLevelNoRightSpace()).append(getNoIndexName()).append(SHU) + .append(TO).append(getSpace(4)).append("End-I").append(getSpace(19)).append(SHU) + .append(getSpace30()).append(SHU) + .append(getSpace30()).append(SHU) + .append(getSpace30()).append(SHU) + .append(_N) + + return sb.toString() + } + + private fun levelNoIndexIncrease() { + levelNoIndex++ + } + + private fun appendRecord(sb: StringBuilder, record: LevelIDetectionRecord) { + val hourMinSec = LevelDateUtil.getHourMinSec(record.createDate) + + val height = LevelFormatUtil.formatHeight(record.height) + val distance = LevelFormatUtil.formatDistance(record.distance) + val heightUnit = "$height m" + val distanceUnit = "$distance m" + + val space2 = getSpace2() + val spaceHeightLeft = getSpace(24 - 2 - heightUnit.length) + val spaceDistanceLeft = getSpace(28 - 2 - distanceUnit.length) + + sb.append(LEVEL_NO).append(getLevelNoRightSpace()).append(getNoIndexName()).append(SHU) + .append("KD1").append(getSpace10()).append("${record.measureTime + 1}") + .append(getSpace8()).append(hourMinSec).append(SHU) + .append(getRI1A(record)).append(spaceHeightLeft).append(heightUnit).append(space2) + .append(SHU) + .append("HD").append(spaceDistanceLeft).append(distanceUnit).append(space2).append(SHU) + .append(getSpace30()).append(SHU) + .append(_N) + + levelNoIndexIncrease() + } + + private fun getRI1A(record: LevelIDetectionRecord): String { + return if (record.stationType == LevelIDetectionConstant.STATION_TYPE_0) { + if (record.rulerType == LevelIDetectionConstant.RULER_TYPE_0) { + "R_I1_A" + } else { + "R_I1_B" + } + } else { + if (record.rulerType == LevelIDetectionConstant.RULER_TYPE_0) { + "R_I2_A" + } else { + "R_I2_B" + } + } + } + + private fun appendD1D2(sb: StringBuilder, d1: String, d1Value: String) { + val d1ValueFormat = LevelFormatUtil.formatHeight(toDouble(d1Value)) + val d1ValueUnit = "$d1ValueFormat m" + + val d1ValueUnitLength = d1ValueUnit.length + + val spaceValueLeft = getSpace(30 - 4 - d1ValueUnitLength - 1) + val spaceValueRight = getSpace4() + + sb.append(LEVEL_NO).append(getLevelNoRightSpace()).append(getNoIndexName()).append(SHU) + .append(d1).append(getSpace28()).append(SHU) + .append(getSpace30()).append(SHU) + .append(getSpace30()).append(SHU) + .append("D").append(spaceValueLeft).append(d1ValueUnit).append(spaceValueRight) + .append(SHU) + .append(_N) + levelNoIndexIncrease() + } + + private fun appendSetting(sb: StringBuilder, key: String, value: String) { + sb.append(LEVEL_NO).append(getLevelNoRightSpace()).append(getNoIndexName()).append(SHU) + .append(INF).append(getSpace27()).append(SHU) + .append(key).append(getSettingKeyRightSpace(key)).append(SHU) + .append(getSpace30()).append(SHU) + .append(value).append(getSettingValueRightSpace(value)).append(SHU) + .append(_N) + levelNoIndexIncrease() + } + + private fun getLevelNoRightSpace(): String { + val length = getNoIndexName().length + return getSpace(8 - length) + } + + private fun getSettingKeyRightSpace(key: String): String { + val length = key.length + return getSpace(30 - length) + } + + private fun getSettingValueRightSpace(value: String): String { + val length = getLength(value) + return getSpace(30 - length) + } + + private fun getNoIndexName() = "${levelNoIndex + 1}" + + + private fun getSpace2() = getSpace(2) + private fun getSpace4() = getSpace(4) + private fun getSpace8() = getSpace(8) + private fun getSpace10() = getSpace(10) + private fun getSpace27() = getSpace(27) + private fun getSpace28() = getSpace(28) + + private fun getSpace30() = getSpace(30) + + private fun getSpace(size: Int) = _S.repeat(size) + + private fun toString(value: String?) = value ?: "" + private fun toDouble(value: String?): Double { + return value?.toDouble() ?: 0.0 + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/export/LevelExportSingalHeight.kt b/app/src/main/java/com/bingce/controlnetwork/func/level/export/LevelExportSingalHeight.kt new file mode 100644 index 0000000..3813d9c --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/export/LevelExportSingalHeight.kt @@ -0,0 +1,218 @@ +package com.bingce.controlnetwork.func.level.export + +import android.text.TextUtils +import androidx.annotation.WorkerThread +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory +import com.bingce.controlapphelper.datasource.database.leveling.LevelingDbFactory +import com.bingce.controlapphelper.datasource.database.leveling.stationsetting.LevelingStationSettingRecord +import com.bingce.controlapphelper.datasource.database.point.PointRecord +import com.bingce.controlapphelper.leveling.detaction.LevelFormatUtil +import com.bingce.controlapphelper.model.LevelingMeasureOrder +import com.bingce.controlapphelper.model._N +import com.bingce.controlapphelper.model._S +import com.bingce.controlapphelper.model._T +import com.bingce.controlapphelper.surveyor.method.ExportStationMethod +import com.bingce.controlapphelper.surveyor.method.model.MeasureConstant +import java.io.File + +class LevelExportSingalHeight { + private var routeIndex = 0 + + private val singalHeightSb = StringBuilder() + private val rulerLengthSb = StringBuilder() + private val pointNumNameSb = StringBuilder() + private val heightDistanceSb = StringBuilder() + private val pointKnownSb = StringBuilder() + + + @WorkerThread + fun export(projectFolder: File, projectId: String) { + collectRulerLength(projectId) + collectPoint(projectId) + collectSingalHeight(projectId) + + val prepare4Folder = initPrepare4Folder(projectFolder) + + saveData(projectFolder, singalHeightSb, "SingalHeight.txt") + saveData(prepare4Folder, rulerLengthSb, "尺长.txt") + saveData(prepare4Folder, pointNumNameSb, "点名点号.txt") + saveData(prepare4Folder, heightDistanceSb, "高差文件.txt") + saveData(prepare4Folder, pointKnownSb, "已知.txt") + } + + private fun saveData(projectFolder: File, data: StringBuilder, fileName: String) { + if (data.isNotEmpty()) { + ExportStationMethod.save( + data.toString(), + projectFolder, + fileName + ) + } + } + + private fun collectSingalHeight(projectId: String) { + val routeList = LevelingDbFactory.instance.levelDataSource.getByProjectIdSync(projectId) + + for (route in routeList) { + + val routeId = route.getId() + + val pointNameStart = getPointName(route.startPointId) + val pointNameEnd = getPointName(route.endPointId) + + val levelingMeasureOrder = route.levelingMeasureOrder + val isHasTwiceStation = when (levelingMeasureOrder) { + LevelingMeasureOrder.SIM_BF, + LevelingMeasureOrder.SIM_BFFB -> { + true + } + + else -> false + } + + val routeLastStationSetting = + LevelingDbFactory.instance.stationSettingDataSource.getLatest(routeId) + + appendData( + projectId, + routeId, + pointNameStart, + pointNameEnd, + false, + routeLastStationSetting + ) + if (isHasTwiceStation) { + appendData( + projectId, + routeId, + pointNameStart, + pointNameEnd, + true, + routeLastStationSetting + ) + } + } + + heightDistanceSb.append("END") + } + + /** + * 点名点号 + * 已知点 + */ + private fun collectPoint(projectId: String) { + val pointList = SurveyorDatabaseFactory.instance.pointDataSource.findByProjectIdSync(projectId) + for (point in pointList) { + if (PointRecord.TYPE_KNOWN_POINT == point.pointType) { + pointKnownSb.append(point.getName()).append(_S).append(point.getZFormat(4)) + } + pointNumNameSb.append(point.getName()).append(_S).append("") + .append(_N) + } + pointNumNameSb.append("END") + pointKnownSb.append("END") + } + + /** + * 收集尺长 + */ + private fun collectRulerLength(projectId: String) { + val routeList = SurveyorDatabaseFactory.instance.pointDataSource.findByProjectIdSync(projectId) + for (route in routeList) { + val latest = LevelingDbFactory.instance.stationSettingDataSource.getLatest(route.id) + + val rulerCorrectionFactor = if (!TextUtils.isEmpty(latest.rulerCorrectionFactor)) { + "${latest.rulerCorrectionFactor.toDouble() / 1000}" + } else { + "0" + } + + rulerLengthSb.append("1").append(_S).append(rulerCorrectionFactor) + .append(_N) + } + rulerLengthSb.append("END") + } + + private fun appendData( + projectId: String, + routeId: String, + pointNameStart: String, + pointNameEnd: String, + twiceStation: Boolean, + routeLatestSetting: LevelingStationSettingRecord + ) { + + val stationFirst = + LevelingDbFactory.instance.stationDataSource.getStationFirstTwiceStation( + projectId, + routeId, + twiceStation + ) + + val stationLatest = + LevelingDbFactory.instance.stationDataSource.getStationLatestTwiceStation( + projectId, + routeId, + twiceStation + ) + + val measureStation = + LevelingDbFactory.instance.measureStationDataSource.getRecordSync(stationLatest.getId()) + ?: return + + singalHeightSb.append(getRouteNum()).append(_T)//编号 + .append(pointNameStart).append(_T)//起点 + .append(pointNameEnd).append(_T)//终点 + .append(LevelFormatUtil.formatHeight(measureStation.heightDiffTotal)).append(_T)//高差 + .append(LevelFormatUtil.formatHeight(measureStation.distanceTotal)).append(_T)//距离 + .append("0.00000").append(_T)//温度改正 + .append(getExportRulerCorrectionFactor(routeLatestSetting)).append(_T)//标尺改正系数 + .append("1").append(_T)//结束标志 + .append(routeLatestSetting.soil ?: "水泥").append(_T)//土质 + .append(stationFirst.createDate.time).append(_T)//开始时间 + .append(stationLatest.createDate.time).append(_T)//结束时间 + .append(routeLatestSetting.temperature ?: MeasureConstant.DEFAULT_TEMPERATURE) + .append(_T)//温度 + .append(routeLatestSetting.firstStationFrontFootNumber ?: "").append(_T)//标尺1 + .append(routeLatestSetting.firstStationBackFootNumber ?: "").append(_T)//标尺2 + .append(measureStation.stationNumForenoonTotal).append(_T)//上午测站数 + .append(measureStation.stationNumAfternoonTotal).append(_T)//下午测站数 + .append(_N) + + heightDistanceSb.append(pointNameStart).append(_S) + .append(pointNameEnd).append(_S) + .append(LevelFormatUtil.formatHeight(measureStation.heightDiffTotal)).append(_S)//高差 + .append(LevelFormatUtil.formatHeight(measureStation.distanceTotal)).append(_S)//距离 + .append("1").append(_N)//结束标志 + + routeIndex++ + } + + private fun getExportRulerCorrectionFactor(routeLatestSetting: LevelingStationSettingRecord): String { + return if (!TextUtils.isEmpty(routeLatestSetting.rulerCorrectionFactor)) { + "${routeLatestSetting.rulerCorrectionFactor.toDouble() / 1000}" + } else { + "0" + } + } + + private fun getPointName(pointId: String): String { + return SurveyorDatabaseFactory.instance.pointDataSource.findByIdSync(pointId)?.getName() ?: "" + } + + private fun getRouteNum(): String { + return String.format("%04d", routeIndex + 1) + } + + /** + * 初始化平差准备文件夹 + */ + private fun initPrepare4Folder(projectFolder: File): File { + val exportFolder = File(projectFolder, "平差准备文件") + if (!exportFolder.exists()) { + exportFolder.mkdir() + } + return exportFolder + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/LevelIDetectionCreateFragment.java b/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/LevelIDetectionCreateFragment.java new file mode 100644 index 0000000..479c420 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/LevelIDetectionCreateFragment.java @@ -0,0 +1,86 @@ +package com.bingce.controlnetwork.func.level.fragment; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.EditText; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; + +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.fragment.AbstractFullScreenDialogFragment; + +/** + * 新建编辑i角检测 + */ +public class LevelIDetectionCreateFragment extends AbstractFullScreenDialogFragment { + @Override + protected View createContentView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.fragment_level_i_detection_create_edit, container, false); + EditText editText = view.findViewById(R.id.editor); + if (editText != null && getArguments() != null) { + editText.setText(getArguments().getString(KEY_DEFAULT_STRING)); + } + return view; + } + + @Override + protected void onConfirm() { + Bundle args = new Bundle(); + if (getView() != null) { + EditText editText = getView().findViewById(R.id.editor); + if (editText.getText() != null) { + String string = editText.getText().toString(); + if (string.isEmpty()) { + Toast.makeText(getContext(), + R.string.string_no_empty, + Toast.LENGTH_SHORT).show(); + return; + } + args.putString(KEY_STRING_RESULT, string); + } + } + getParentFragmentManager() + .setFragmentResult(KEY_REQUEST_INPUT, args); + super.onConfirm(); + } + + private static final String TAG = LevelIDetectionCreateFragment.class.getName(); + private static final String KEY_REQUEST_INPUT = LevelIDetectionCreateFragment.class.getName() + "_REQUEST"; + private static final String KEY_STRING_RESULT = LevelIDetectionCreateFragment.class.getName() + "_result"; + private static final String KEY_DEFAULT_STRING = LevelIDetectionCreateFragment.class.getName() + "__DEFAULT_STRING"; + + + public static void input(FragmentManager fragmentManager, + String title, + String defaultString, + LifecycleOwner lifecycleOwner, + IInputCallback callback) { + Bundle args = new Bundle(); + LevelIDetectionCreateFragment fragment = new LevelIDetectionCreateFragment(); + fragment.setArguments(args); + if (defaultString != null) { + args.putString(KEY_DEFAULT_STRING, defaultString); + } + AbstractFullScreenDialogFragment.setArgs(args, title, null); + fragmentManager + .setFragmentResultListener( + KEY_REQUEST_INPUT, + lifecycleOwner, + (requestKey, result) -> { + if (KEY_REQUEST_INPUT.equals(requestKey)) { + callback.onGetInput(result.getString(KEY_STRING_RESULT)); + } + }); + fragment.show(fragmentManager, TAG); + } + + public interface IInputCallback { + void onGetInput(String string); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/LevelInputAllowFragment.java b/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/LevelInputAllowFragment.java new file mode 100644 index 0000000..8ec55ec --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/LevelInputAllowFragment.java @@ -0,0 +1,91 @@ +package com.bingce.controlnetwork.func.level.fragment; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.WindowManager; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatDialogFragment; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; + +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.newui.widget.switchtext.SwitchWithText; + + +public class LevelInputAllowFragment extends AppCompatDialogFragment { + + public static String KEY_AUTO = "KEY_AUTO"; + public static String KEY_REQUEST = "KEY_REQUEST"; + + public static void show(FragmentManager fragmentManager, LifecycleOwner lifecycleOwner, + boolean auto, IConfirmCallback callback) { + Bundle args = new Bundle(); + LevelInputAllowFragment fragment = new LevelInputAllowFragment(); + fragment.setArguments(args); + args.putBoolean(KEY_AUTO, auto); + + fragmentManager + .setFragmentResultListener( + KEY_REQUEST, + lifecycleOwner, + (requestKey, result) -> { + if (KEY_REQUEST.equals(requestKey)) { + if (callback != null) { + callback.onConfirm(result.getBoolean(KEY_AUTO)); + } + } + }); + + fragment.show(fragmentManager, null); + + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View contentView = inflater.inflate(R.layout.fragment_level_input_allow, container, false); + SwitchWithText receiveDataType = contentView.findViewById(R.id.receiveDataType); + + receiveDataType.setChecked(getAuto()); + + contentView.findViewById(R.id.btnConfirm).setOnClickListener(v -> { + Bundle bundle = new Bundle(); + bundle.putBoolean(KEY_AUTO, receiveDataType.isChecked()); + getParentFragmentManager() + .setFragmentResult(KEY_REQUEST, bundle); + dismissAllowingStateLoss(); + }); + + return contentView; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + if (getDialog() == null) { + return; + } + getDialog().getWindow().setLayout( + WindowManager.LayoutParams.MATCH_PARENT, + WindowManager.LayoutParams.WRAP_CONTENT); + } + + public interface IConfirmCallback { + void onConfirm(Boolean auto); + } + + /** + * 仪器获取 + */ + private boolean getAuto() { + if (getArguments() != null) { + return getArguments().getBoolean(KEY_AUTO); + } + return true; + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/LevelInputFragment.java b/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/LevelInputFragment.java new file mode 100644 index 0000000..135b644 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/LevelInputFragment.java @@ -0,0 +1,102 @@ +package com.bingce.controlnetwork.func.level.fragment; + +import android.os.Bundle; +import android.text.TextUtils; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.WindowManager; +import android.widget.EditText; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatDialogFragment; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; + +import com.bingce.controlnetwork.R; + +import blankj.utilcode.util.ToastUtils; + + +public class LevelInputFragment extends AppCompatDialogFragment { + + public static String KEY_DISTANCE = "KEY_DISTANCE"; + public static String KEY_HEIGHT = "KEY_HEIGHT"; + public static String KEY_REQUEST = "KEY_REQUEST"; + + public static void show(FragmentManager fragmentManager, LifecycleOwner lifecycleOwner, + IConfirmCallback callback) { + Bundle args = new Bundle(); + LevelInputFragment fragment = new LevelInputFragment(); + fragment.setArguments(args); + + fragmentManager + .setFragmentResultListener( + KEY_REQUEST, + lifecycleOwner, + (requestKey, result) -> { + if (KEY_REQUEST.equals(requestKey)) { + if (callback != null) { + double distance = result.getDouble(KEY_DISTANCE); + double height = result.getDouble(KEY_HEIGHT); + callback.onConfirm(distance, height); + } + } + }); + + fragment.show(fragmentManager, null); + + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View contentView = inflater.inflate(R.layout.fragment_level_input, container, false); + + EditText etDisTance = contentView.findViewById(R.id.etDisTance); + EditText etHeight = contentView.findViewById(R.id.etHeight); + + contentView.findViewById(R.id.btnConfirm).setOnClickListener(v -> { + + String disTance = getEtValue(etDisTance); + String height = getEtValue(etHeight); + if (TextUtils.isEmpty(disTance)) { + ToastUtils.showShort("请输入距离"); + return; + } + if (TextUtils.isEmpty(height)) { + ToastUtils.showShort("请输入高度"); + return; + } + + Bundle bundle = new Bundle(); + bundle.putDouble(KEY_DISTANCE, Double.parseDouble(disTance)); + bundle.putDouble(KEY_HEIGHT, Double.parseDouble(height)); + getParentFragmentManager() + .setFragmentResult(KEY_REQUEST, bundle); + dismissAllowingStateLoss(); + }); + + return contentView; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + if (getDialog() == null) { + return; + } + getDialog().getWindow().setLayout( + WindowManager.LayoutParams.MATCH_PARENT, + WindowManager.LayoutParams.WRAP_CONTENT); + } + + private String getEtValue(EditText et) { + return et.getText().toString().trim(); + } + + public interface IConfirmCallback { + void onConfirm(double distance, double height); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/LevelRouteCreateEditFragment.kt b/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/LevelRouteCreateEditFragment.kt new file mode 100644 index 0000000..0c69b8c --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/LevelRouteCreateEditFragment.kt @@ -0,0 +1,382 @@ +package com.bingce.controlnetwork.func.level.fragment + +import android.content.Context +import android.os.Bundle +import android.text.TextUtils +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.AdapterView +import android.widget.ArrayAdapter +import android.widget.EditText +import androidx.fragment.app.Fragment +import androidx.fragment.app.viewModels +import androidx.lifecycle.lifecycleScope +import blankj.utilcode.util.ToastUtils +import com.bingce.controlnetwork.func.level.constant.LevelConstant +import com.bingce.controlnetwork.func.level.constant.LevelStationSettingContant +import com.bingce.controlnetwork.func.level.util.LevelStationSettingUtil.getSpinnerText +import com.bingce.controlapphelper.model.BundleConstants +import com.bingce.controlapphelper.model.LevelRouteSave +import com.bingce.controlapphelper.model.LevelingMeasureOrder +import com.bingce.controlapphelper.model.LevelingMeasureOrderUtil +import com.bingce.controlapphelper.model.PickPointResult +import com.bingce.controlapphelper.util.CheckLocationUtil +import com.bingce.controlapphelper.util.GetLocationUtil +import com.bingce.controlnetwork.R +import com.bingce.controlnetwork.activity.fragmentcontainer.FragmentContainerActivity +import com.bingce.controlnetwork.databinding.FragmentLevelCreateRouteBinding +import com.bingce.controlnetwork.fragment.PickPointFragment +import com.bingce.controlnetwork.func.level.viewmodel.LevelCreateOrEditRouteVm +import com.bingce.controlnetwork.newui.base.BaseFragmentBinding +import com.bingce.controlnetwork.newui.projectedit.ProjectLastData +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + +class LevelRouteCreateEditFragment : BaseFragmentBinding() { + + private val viewModel by viewModels() + + private val SELECT_POINT_TYPE_START = "SELECT_POINT_TYPE_START" + private val SELECT_POINT_TYPE_END = "SELECT_POINT_TYPE_END" + + private var pickPointResultStart: PickPointResult? = null + private var pickPointResultEnd: PickPointResult? = null + + private lateinit var levelingMeasureOrder: LevelingMeasureOrder + + private val getLocation by lazy { + GetLocationUtil() + } + + + private val defaultStationLauncher = PickPointFragment.createActivityLauncher( + this + ) { type: String, pickPointResult: PickPointResult -> + if (SELECT_POINT_TYPE_START == type) { + pickPointResultStart = pickPointResult + } else if (SELECT_POINT_TYPE_END == type) { + pickPointResultEnd = pickPointResult + } + if (pickPointResult.selectedIds.isNullOrEmpty() + || pickPointResult.selectedNames.isNullOrEmpty() + || pickPointResult.selectedNames.size != pickPointResult.selectedIds.size + ) { + ToastUtils.showShort(R.string.abnormal_point_selection) + return@createActivityLauncher + } + setSelectPointUi() + } + + + companion object { + @JvmField + val TAG = LevelRouteCreateEditFragment::class.java.getName() + + @JvmStatic + fun newInstance(args: Bundle?): Fragment { + val fragment: Fragment = LevelRouteCreateEditFragment() + fragment.setArguments(args) + return fragment + } + + @JvmStatic + fun start(context: Context, projectId: String, routeId: String?, title: String) { + val bundle = Bundle() + bundle.putString(BundleConstants.KEY_PROJECT_ID, projectId) + bundle.putString(BundleConstants.KEY_ROUTE_ID, routeId) + FragmentContainerActivity.start(context, TAG, title, bundle) + } + } + + + override fun getViewBinding( + inflater: LayoutInflater, + container: ViewGroup? + ): FragmentLevelCreateRouteBinding { + return FragmentLevelCreateRouteBinding.inflate(inflater, container, false) + } + + override fun initView() { + lifecycle.addObserver(getLocation) + initLevelOrder() + initListener() + } + + private fun initListener() { + mBinding.btnConfirm.setOnClickListener { + checkConfirm() + } + mBinding.btnDetermineAndMeasure.setOnClickListener { + + } + + mBinding.ivSelectStartPoint.setOnClickListener { + selectPoint(SELECT_POINT_TYPE_START) + } + mBinding.ivSelectEndPoint.setOnClickListener { + selectPoint(SELECT_POINT_TYPE_END) + } + + mBinding.ivGetLocation.setOnClickListener { + getLocation { + setLocation(mBinding.etLongitude, mBinding.etLatitude, mBinding.etHeight, it) + } + } + } + + override fun initData() { + initSpinnerObservationDirection() + + initEditData() + } + + private fun initEditData() { + val routeId = getRouteId() + if (routeId != null) { + viewModel.getEditRouteData(routeId) { + mBinding.etStartPoint.setText(it.startPointName) + mBinding.etEndPoint.setText(it.endPointName) + mBinding.spinnerObservationDirection.setSelection( + LevelStationSettingContant.observationDirectionList.indexOf( + it.observationDirection + ) + ) + +// //经纬度 +// if (isEmpty(it.longitude) || isEmpty(it.latitude)) { +// setDefaultLocation() +// } else { +// setLocation( +// mBinding.etLongitude, +// mBinding.etLatitude, +// mBinding.etHeight, +// it.longitude, +// it.latitude, +// it.z +// ) +// } + + } + } else { + setDefaultLocation() + } + } + + private fun setSelectPointUi() { + if (pickPointResultStart == null) { + mBinding.etStartPoint.setText("") + } else { + mBinding.etStartPoint.setText(pickPointResultStart!!.selectedNames[0]) + } + if (pickPointResultEnd == null) { + mBinding.etEndPoint.setText("") + } else { + mBinding.etEndPoint.setText(pickPointResultEnd!!.selectedNames[0]) + } + } + + private fun selectPoint(type: String) { + var title: String? = null + var pickPointResultSelected: PickPointResult? = null + var filderIds: List? = null + if (SELECT_POINT_TYPE_START == type) { + pickPointResultSelected = pickPointResultStart + filderIds = pickPointResultEnd?.selectedIds + title = getString(R.string.choose_starting_point) + } else if (SELECT_POINT_TYPE_END == type) { + pickPointResultSelected = pickPointResultStart + filderIds = pickPointResultStart?.selectedIds + title = getString(R.string.select_end_point) + } + PickPointFragment.pickKnownAndUnknownPoint( + context, + type, + 1, + title, + filderIds, + getProjectId(), + pickPointResultSelected, + defaultStationLauncher + ) + } + + /** + * 照准次序 + */ + private fun initLevelOrder() { + val showList = LevelingMeasureOrderUtil.getShowList() + mBinding.spinner.setAdapter( + ArrayAdapter( + requireContext(), + android.R.layout.simple_list_item_1, + showList + ) + ) + mBinding.spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { + override fun onItemSelected( + parent: AdapterView<*>?, + view: View, + position: Int, + id: Long + ) { + levelingMeasureOrder = LevelingMeasureOrderUtil.getLevelingMeasureOrderByCreate( + showList[position] + ) + } + + override fun onNothingSelected(parent: AdapterView<*>?) {} + } + + + + mBinding.spinner.setSelection(0) + } + + /** + * 观测方向 + */ + private fun initSpinnerObservationDirection() { + mBinding.spinnerObservationDirection.adapter = ArrayAdapter( + requireContext(), + android.R.layout.simple_list_item_1, + LevelStationSettingContant.observationDirectionList + ) + mBinding.spinnerObservationDirection.onItemSelectedListener = + object : AdapterView.OnItemSelectedListener { + override fun onItemSelected( + parent: AdapterView<*>?, + view: View, + position: Int, + id: Long + ) { + + } + + override fun onNothingSelected(parent: AdapterView<*>?) { + + } + } + } + + private fun checkConfirm() { + val projectId = getProjectId() + if (projectId == null) { + ToastUtils.showShort(R.string.project_data_is_empty) + return + } + + val startPointName = mBinding.etStartPoint.getText().toString().trim() + if (TextUtils.isEmpty(startPointName)) { + ToastUtils.showShort(R.string.please_enter_or_select_a_starting_point) + return + } + val endPointName = mBinding.etEndPoint.getText().toString().trim() + if (TextUtils.isEmpty(endPointName)) { + ToastUtils.showShort(R.string.please_enter_or_select_a_destination) + return + } + + val longitude = mBinding.etLongitude.getText().toString().trim() + if (TextUtils.isEmpty(longitude)) { + ToastUtils.showShort(R.string.please_input_longitude) + return + } + val latitude = mBinding.etLatitude.getText().toString().trim() + if (TextUtils.isEmpty(latitude)) { + ToastUtils.showShort(R.string.please_input_latitude) + return + } + val height = mBinding.etHeight.getText().toString().trim() + if (TextUtils.isEmpty(height)) { + ToastUtils.showShort(R.string.please_enter_elevation) + return + } + + val levelRouteSave = LevelRouteSave() + levelRouteSave.projectId = projectId + levelRouteSave.routeId = getRouteId() + levelRouteSave.routeName = "$startPointName-$endPointName" + levelRouteSave.startPointName = startPointName + levelRouteSave.endPointName = endPointName + levelRouteSave.levelingMeasureOrder = levelingMeasureOrder + + //观测方向 + levelRouteSave.observationDirection = getSpinnerText(mBinding.spinnerObservationDirection) + + viewModel.startSave(requireContext(), levelRouteSave) { isSuccess: Boolean -> + if (isSuccess) requireActivity().finish() + } + } + + private fun getProjectId() = getArgumentString(BundleConstants.KEY_PROJECT_ID) + private fun getRouteId() = getArgumentString(BundleConstants.KEY_ROUTE_ID) + + + private fun getLocation(resultListener: GetLocationUtil.IResultListener) { + CheckLocationUtil.check(requireContext()) { + getLocation.getResult(resultListener) + } + } + + private fun setLocation( + etLongitude: EditText, + etLatitude: EditText, + etHeight: EditText, + result: GetLocationUtil.Result? + ) { + setLocation( + etLongitude, + etLatitude, + etHeight, + result?.longitude, + result?.latitude, + result?.altitude + ) + } + + private fun setLocation( + etLongitude: EditText, + etLatitude: EditText, + etHeight: EditText, + longitude: String?, + latitude: String?, + z: String? + ) { + etLongitude.setText(longitude) + etLatitude.setText(latitude) + etHeight.setText(z) + } + + private fun setDefaultLocation() { + lifecycleScope.launch(Dispatchers.IO) { + val longitude = ProjectLastData.getLongitude() + val latitude = ProjectLastData.getLatitude() + withContext(Dispatchers.Main) { + if (isEmpty(latitude) || isEmpty(latitude)) { + setLocation( + mBinding.etLongitude, + mBinding.etLatitude, + mBinding.etHeight, + LevelConstant.LONGITUDE_DEFAULT.toString(), + LevelConstant.LATITUDE_DEFAULT.toString(), + LevelConstant.HEIGHT_DEFAULT.toString() + ) + } else { + setLocation( + mBinding.etLongitude, + mBinding.etLatitude, + mBinding.etHeight, + longitude, + latitude, + LevelConstant.HEIGHT_DEFAULT.toString() + ) + } + } + } + } + + private fun isEmpty(value: String?) = TextUtils.isEmpty(value) + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/LevelRouteFragment.kt b/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/LevelRouteFragment.kt new file mode 100644 index 0000000..8e77396 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/LevelRouteFragment.kt @@ -0,0 +1,158 @@ +package com.bingce.controlnetwork.func.level.fragment + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import androidx.fragment.app.viewModels +import androidx.lifecycle.lifecycleScope +import androidx.room.withTransaction +import com.bingce.controlapphelper.datasource.database.SurveyorDataBase +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory +import com.bingce.controlapphelper.datasource.database.leveling.LevelingDbFactory +import com.bingce.controlapphelper.datasource.database.leveling.route.LevelRouteRecord +import com.bingce.controlnetwork.R +import com.bingce.controlnetwork.func.level.viewmodel.LevelCreateOrEditRouteVm +import com.bingce.controlapphelper.model.BundleConstants +import com.bingce.controlnetwork.adapter.contextmenu.ContextMenuDeleteEdit +import com.bingce.controlnetwork.databinding.FragmentListLayoutBinding +import com.bingce.controlnetwork.fragment.TipsFragment +import com.bingce.controlnetwork.func.level.adapter.LevelRouteListAdapter +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + +class LevelRouteFragment : Fragment() { + + private val createOrEditRouteVm by viewModels() + + private var _binding: FragmentListLayoutBinding? = null + val mBinding get() = _binding!! + + private val dataList = mutableListOf() + + private val adapter by lazy { + LevelRouteListAdapter(requireContext()) + } + + private fun doLookAndEditRoute(item: LevelRouteRecord) { + createOrEditRouteVm.showCreateOrEditDialog( + requireContext(), + getProjectId(), + routeId = item.getId() + ) + } + + private fun doDelete(item: LevelRouteRecord) { + lifecycleScope.launch(Dispatchers.IO) { + + val stationList = SurveyorDatabaseFactory.instance.surveyorStation.getByProjectRoute( + item.projectId, + item.getId() + ) + + var hasData = false + for (stationItem in stationList) { + val recordCount = + SurveyorDatabaseFactory.instance.surveyorRecordDataSource.recordCount( + stationItem.getId() + ) + if (recordCount > 0) { + hasData = true + break + } + } + + if (hasData) { + withContext(Dispatchers.Main) { + TipsFragment.cancelAbleTips( + childFragmentManager, viewLifecycleOwner, context, + getString(R.string.tips_is_sure_to_delete_route_with_record), + 4 + ) { + deleteDatabase(item) + } + } + } else { + deleteDatabase(item) + } + } + } + + private fun deleteDatabase(routeRecord: LevelRouteRecord) { + lifecycleScope.launch(Dispatchers.IO) { + SurveyorDataBase.getInstance().withTransaction { + //删除路线 + LevelingDbFactory.instance.levelDataSource.delete(routeRecord) + //删除测站 + LevelingDbFactory.instance.stationDataSource.deleteByRouteId(routeRecord.getId()) + } + } + } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + _binding = FragmentListLayoutBinding.inflate(inflater, container, false) + return mBinding.root + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + initAdapter() + + LevelingDbFactory.instance.levelDataSource.getListLiveData(getProjectId()) + .observe(viewLifecycleOwner) { + adapter.refreshData(it) + } + } + + private fun initAdapter() { + mBinding.list.adapter = adapter + + adapter.setAdapterContextMenu(object : ContextMenuDeleteEdit() { + override fun delete(item: LevelRouteRecord) { + doDelete(item) + } + + override fun edit(item: LevelRouteRecord) { + doLookAndEditRoute(item) + } + }) + } + + + fun getProjectId() = requireArguments().getString(BundleConstants.KEY_PROJECT_ID)!! + + + companion object { + @JvmStatic + fun newInstance(projectId: String): LevelRouteFragment { + val bundle = Bundle() + bundle.putString(BundleConstants.KEY_PROJECT_ID, projectId) + val routeFragment = LevelRouteFragment() + routeFragment.arguments = bundle + return routeFragment + } + } + + /** + * 获取即将要测量的路线id + */ + fun getSurveyorRouteId(): String? { + if (dataList.isNotEmpty()) { + return dataList.last().getId() + } + return null + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/LevelSelectExportFragment.java b/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/LevelSelectExportFragment.java new file mode 100644 index 0000000..2fd7761 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/LevelSelectExportFragment.java @@ -0,0 +1,248 @@ +package com.bingce.controlnetwork.func.level.fragment; + +import android.content.Context; +import android.os.Bundle; +import android.os.Environment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.fragment.app.DialogFragment; +import androidx.lifecycle.ViewModelProvider; + +import com.bingce.controlapphelper.util.CheckStorageUtil; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlapphelper.widget.treeview.TreeNode; +import com.bingce.controlapphelper.widget.treeview.TreeView; +import com.bingce.controlapphelper.widget.treeview.custom.MyNodeViewFactory; +import com.bingce.controlnetwork.BuildConfig; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.activity.fragmentcontainer.FragmentContainerActivity; +import com.bingce.controlnetwork.databinding.FragmentSelectExportBinding; +import com.bingce.controlnetwork.fragment.FullLoadingFragment; +import com.bingce.controlnetwork.fragment.TipsWith2OptionFragment; +import com.bingce.controlnetwork.func.level.util.LevelExportUtilTj; +import com.bingce.controlnetwork.func.level.viewmodel.LevelSelectExportVm; +import com.bingce.controlnetwork.newui.base.BaseFragmentBinding; +import com.bingce.controlnetwork.surveyor.method.ExportUtilsPla; +import com.bingce.file.FileOperator; +import com.bingce.utils.ThreadPoolUtil; +import com.bingce.zip.ZipUtil; + +import java.io.File; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Locale; + +import blankj.utilcode.util.FileUtils; +import blankj.utilcode.util.ToastUtils; + + +/** + * 水准选择导出 + */ +public class LevelSelectExportFragment extends BaseFragmentBinding { + public static final String TAG = LevelSelectExportFragment.class.getName(); + + private LevelSelectExportVm viewModel; + + private TreeNode rootNode; + + public static LevelSelectExportFragment newInstance(Bundle args) { + LevelSelectExportFragment fragment = new LevelSelectExportFragment(); + fragment.setArguments(args); + return fragment; + } + + public static void start(Context context) { + FragmentContainerActivity.start(context, TAG, R.string.level_export, null); + } + + @Override + protected FragmentSelectExportBinding getViewBinding(@NonNull LayoutInflater inflater, ViewGroup container) { + return FragmentSelectExportBinding.inflate(inflater, container, false); + } + + @Override + protected void initView() { + viewModel = new ViewModelProvider(this).get(LevelSelectExportVm.class); + mBinding.title.setText(R.string.tips_select_expected_export_data_level); + initListener(); + } + + private void initListener() { + mBinding.export.setOnClickListener(v -> { + if (ExportUtilsPla.isCanExport()) { + CheckStorageUtil.check(requireContext(), this::startExport); + } + }); + } + + private void startExport() { + DialogFragment dialogFragment = FullLoadingFragment.showLoading(getChildFragmentManager()); + + doExport(new ICallback() { + @Override + public void onFailureInMainThread(String msg) { + dialogFragment.dismiss(); + ToastUtils.showShort(msg); + } + + @Override + public void onSuccessInMainThread(File zip) { + if (dialogFragment.isVisible()) { + dialogFragment.dismiss(); + } + TipsWith2OptionFragment.tipsCannotCancel(getChildFragmentManager(), getViewLifecycleOwner(), + getString(R.string.share), + getString(R.string.cancel), + getString(R.string.export_successful), + new TipsWith2OptionFragment.SimpleCallback() { + @Override + public void onConfirm() { + FileOperator.shareFile(getContext(), zip, BuildConfig.APPLICATION_ID); + } + }); + } + }); + } + + private void doExport(ICallback callback) { + List projectList = rootNode.getChildren(); + + ThreadPoolUtil.execute(() -> { + List exportRouteList = new ArrayList<>(); + HashSet exportProjectIdSet = new HashSet<>(); + for (TreeNode projectNode : projectList) { + List children = projectNode.getChildren(); + for (TreeNode routeNode : children) { + if (routeNode.isEnable() && routeNode.isSelected()) { + String projectId = projectNode.getValue().getId(); + String projectName = projectNode.getValue().getValue().toString(); + exportProjectIdSet.add(projectId); + exportRouteList.add(new ExportRoute(projectId, projectName, + routeNode.getValue().getId(), + routeNode.getValue().getValue().toString())); + } + } + } + if (exportRouteList.isEmpty()) { + backError(callback, "没有要导出的数据"); + return; + } + + try { + LevelExportUtilTj levelExportUtilTj = new LevelExportUtilTj(); + //导出路线数据 + for (ExportRoute exportRoute : exportRouteList) { + levelExportUtilTj.doExportRouteData(exportRoute.projectId, + exportRoute.routeId); + } + + for (String projectId : exportProjectIdSet) { + //导出项目数据 + levelExportUtilTj.exportProjectTxt(projectId); + //导出点信息 + levelExportUtilTj.exportControlTxt(projectId); + //导出i角检测 + levelExportUtilTj.exportIDetection(projectId); + //导出SingalHeight和平差准备文件 + levelExportUtilTj.exportTjSingalHeight(projectId); + } + + } catch (Exception e) { + e.printStackTrace(); + backError(callback, Tools.getString(R.string.export_failure)); + File sourceFileFolder = LevelExportUtilTj.Companion.getExportOutFolder(); + FileUtils.delete(sourceFileFolder); + return; + } + + //压缩文件 + File file = startZipFile(); + if (file == null) { + return; + } + ThreadPoolUtil.executeInMain(() -> callback.onSuccessInMainThread(file)); + }); + } + + private void backError(ICallback callback, String msg) { + ThreadPoolUtil.executeInMain(() -> callback.onFailureInMainThread(msg)); + } + + private File startZipFile() { + //源数据文件 + File sourceFileFolder = LevelExportUtilTj.Companion.getExportOutFolder(); + if (!sourceFileFolder.exists()) return null; + File[] files = sourceFileFolder.listFiles(); + if (files == null || files.length == 0) return null; + List sourceFileList = Arrays.asList(files); + + //将文件存储到一个zip中 + File zipFolder = new File(Environment.getExternalStorageDirectory(), ExportUtilsPla.getExportFirstDirectory()); + if (!zipFolder.exists()) { + zipFolder.mkdir(); + } + + Date date = new Date(); + SimpleDateFormat format = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss", Locale.getDefault()); + String dateString = format.format(date); + File zip = new File(zipFolder, "水准数据_" + dateString + ".zip"); + if (!ZipUtil.zip(zip, sourceFileList)) { + ToastUtils.showShort(R.string.export_failure); + return null; + } + try { + //存储成功,删除被压缩的源文件 + FileUtils.delete(sourceFileFolder); + } catch (Exception e) { + e.printStackTrace(); + ToastUtils.showShort(R.string.export_failure); + return null; + } + return zip; + } + + @Override + protected void initData() { + viewModel.initData(treeNode -> { + setData(treeNode); + return null; + }); + } + + private void setData(TreeNode treeNode) { + rootNode = treeNode; + TreeView treeView = new TreeView(treeNode, requireContext(), new MyNodeViewFactory()); + treeView.setup(mBinding.list); + mBinding.list.setVisibility(View.VISIBLE); + mBinding.loading.setVisibility(View.GONE); + } + + private interface ICallback { + void onFailureInMainThread(String msg); + + void onSuccessInMainThread(File zip); + } + + private static class ExportRoute { + public String projectId; + public String projectName; + public String routeId; + public String routeName; + + public ExportRoute(String projectId, String projectName, String routeId, String routeName) { + this.projectId = projectId; + this.projectName = projectName; + this.routeId = routeId; + this.routeName = routeName; + } + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/LevelStationSettingConditionFragment.kt b/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/LevelStationSettingConditionFragment.kt new file mode 100644 index 0000000..7096797 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/LevelStationSettingConditionFragment.kt @@ -0,0 +1,185 @@ +package com.bingce.controlnetwork.func.level.fragment + +import android.text.TextUtils +import android.view.LayoutInflater +import android.view.ViewGroup +import android.widget.ArrayAdapter +import androidx.fragment.app.activityViewModels +import blankj.utilcode.util.ToastUtils +import com.bingce.controlnetwork.func.level.constant.LevelStationSettingContant +import com.bingce.controlnetwork.func.level.util.LevelStationSettingUtil +import com.bingce.controlnetwork.func.level.viewmodel.LevelStationSettingVm +import com.bingce.controlapphelper.model.LevelRouteSave +import com.bingce.controlapphelper.surveyor.method.model.MeasureConstant +import com.bingce.controlnetwork.databinding.FragmentLevelStationSettingConditionBinding +import com.bingce.controlnetwork.newui.base.BaseFragmentBinding +import com.bingce.controlnetwork.newui.stationsetting.IStationSettingOperate + +/** + * 水准测站设置-观测条件 + */ +class LevelStationSettingConditionFragment : + BaseFragmentBinding(), IStationSettingOperate { + + private val stationSettingVm by activityViewModels() + + private lateinit var levelRouteSave: LevelRouteSave + + override fun getViewBinding( + inflater: LayoutInflater, + container: ViewGroup? + ): FragmentLevelStationSettingConditionBinding { + return FragmentLevelStationSettingConditionBinding.inflate(inflater, container, false) + } + + override fun initView() { + initEditTextTitle() + } + + private fun initEditTextTitle() { + mBinding.ilTemperature.tvTitle.text = "温度(℃)" + } + + override fun initData() { + initSpinnerWeather() + initSpinnerImaging() + initSpinnerSunDirection() + initSpinnerWindDirection() + initSpinnerWindSpeed() + initSpinnerRoads() + initSpinnerSoil() + + stationSettingVm.editLastDataLiveData.observe(viewLifecycleOwner) { + if (it == null) { + setTemperatureData(MeasureConstant.DEFAULT_TEMPERATURE) + } else { + setData(it) + } + } + } + + private fun initSpinnerSoil() { + mBinding.spinnerSoil.adapter = ArrayAdapter( + requireContext(), + android.R.layout.simple_list_item_1, + LevelStationSettingContant.soilList + ) + } + + private fun initSpinnerRoads() { + mBinding.spinnerRoads.adapter = ArrayAdapter( + requireContext(), + android.R.layout.simple_list_item_1, + LevelStationSettingContant.roadsList + ) + } + + private fun initSpinnerWindSpeed() { + mBinding.spinnerWindSpeed.adapter = ArrayAdapter( + requireContext(), + android.R.layout.simple_list_item_1, + LevelStationSettingContant.windSpeedList + ) + } + + private fun initSpinnerWindDirection() { + mBinding.spinnerWindDirection.adapter = ArrayAdapter( + requireContext(), + android.R.layout.simple_list_item_1, + LevelStationSettingContant.windDirectionList + ) + } + + private fun initSpinnerSunDirection() { + mBinding.spinnerSunDirection.adapter = ArrayAdapter( + requireContext(), + android.R.layout.simple_list_item_1, + LevelStationSettingContant.sunDirectionList + ) + } + + private fun initSpinnerImaging() { + mBinding.spinnerImaging.adapter = ArrayAdapter( + requireContext(), + android.R.layout.simple_list_item_1, + LevelStationSettingContant.imagingList + ) + } + + private fun initSpinnerWeather() { + mBinding.spinnerWeather.adapter = ArrayAdapter( + requireContext(), + android.R.layout.simple_list_item_1, + LevelStationSettingContant.weatherList + ) + } + + override fun checkSaveNot(): Boolean { + if (isEmpty(mBinding.ilTemperature.editText.text.toString().trim())) { + ToastUtils.showShort("请输入温度") + return true + } + collectData() + return false + } + + override fun setDataToStation() { + stationSettingVm.addConditionDataToLevelRouteSave(levelRouteSave) + } + + private fun collectData() { + levelRouteSave = LevelRouteSave() + levelRouteSave.temperature = mBinding.ilTemperature.editText.text.toString().trim() + levelRouteSave.weather = LevelStationSettingUtil.getSpinnerText(mBinding.spinnerWeather) + levelRouteSave.imaging = LevelStationSettingUtil.getSpinnerText(mBinding.spinnerImaging) + levelRouteSave.sunDirection = + LevelStationSettingUtil.getSpinnerText(mBinding.spinnerSunDirection) + levelRouteSave.windDirection = + LevelStationSettingUtil.getSpinnerText(mBinding.spinnerWindDirection) + levelRouteSave.windSpeed = LevelStationSettingUtil.getSpinnerText(mBinding.spinnerWindSpeed) + levelRouteSave.roads = LevelStationSettingUtil.getSpinnerText(mBinding.spinnerRoads) + levelRouteSave.soil = LevelStationSettingUtil.getSpinnerText(mBinding.spinnerSoil) + } + + private fun isEmpty(value: String?) = TextUtils.isEmpty(value) + + private fun setData(levelRouteSave: LevelRouteSave) { + setTemperatureData(levelRouteSave.temperature) + + mBinding.spinnerWeather.setSelection( + LevelStationSettingContant.weatherList.indexOf( + levelRouteSave.weather + ) + ) + mBinding.spinnerImaging.setSelection( + LevelStationSettingContant.imagingList.indexOf( + levelRouteSave.imaging + ) + ) + mBinding.spinnerSunDirection.setSelection( + LevelStationSettingContant.sunDirectionList.indexOf( + levelRouteSave.sunDirection + ) + ) + mBinding.spinnerWindDirection.setSelection( + LevelStationSettingContant.windDirectionList.indexOf( + levelRouteSave.windDirection + ) + ) + mBinding.spinnerWindSpeed.setSelection( + LevelStationSettingContant.windSpeedList.indexOf( + levelRouteSave.windSpeed + ) + ) + mBinding.spinnerRoads.setSelection( + LevelStationSettingContant.roadsList.indexOf( + levelRouteSave.roads + ) + ) + mBinding.spinnerSoil.setSelection(LevelStationSettingContant.soilList.indexOf(levelRouteSave.soil)) + } + + private fun setTemperatureData(value: String?) { + mBinding.ilTemperature.editText.setText(value) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/LevelStationSettingInformationFragment.kt b/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/LevelStationSettingInformationFragment.kt new file mode 100644 index 0000000..cbbb4d5 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/LevelStationSettingInformationFragment.kt @@ -0,0 +1,201 @@ +package com.bingce.controlnetwork.func.level.fragment + +import android.text.TextUtils +import android.view.Gravity +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ArrayAdapter +import android.widget.TextView +import androidx.fragment.app.activityViewModels +import blankj.utilcode.util.ToastUtils +import com.bingce.controlnetwork.func.level.constant.LevelStationSettingContant +import com.bingce.controlnetwork.func.level.util.LevelStationSettingUtil +import com.bingce.controlnetwork.func.level.viewmodel.LevelStationSettingVm +import com.bingce.controlapphelper.model.LevelRouteSave +import com.bingce.controlapphelper.util.Tools +import com.bingce.controlnetwork.R +import com.bingce.controlnetwork.databinding.FragmentLevelStationSettingInformationBinding +import com.bingce.controlnetwork.newui.base.BaseFragmentBinding +import com.bingce.controlnetwork.newui.stationsetting.IStationSettingOperate +import com.bingce.controlnetwork.widget.editspinner.EditSpinner +import com.bingce.controlnetwork.widget.editspinner.SimpleAdapter + +/** + * 水准测站设置-观测信息 + */ +class LevelStationSettingInformationFragment : + BaseFragmentBinding(), IStationSettingOperate { + + private val viewModel by activityViewModels() + + private lateinit var levelRouteSave: LevelRouteSave + + override fun getViewBinding( + inflater: LayoutInflater, + container: ViewGroup? + ): FragmentLevelStationSettingInformationBinding { + return FragmentLevelStationSettingInformationBinding.inflate(inflater, container, false) + } + + override fun initView() { + initEditTextTitle() + initSpinnerRulerType() + initRulerReceptType() + viewModel.initHasTwoRuler { hasTwoRuler -> + if (hasTwoRuler) { + mBinding.ilFirstStationBackFootNumber.tvTitle.setText(R.string.first_station_back_foot_number_l) + mBinding.ilFirstStationFrontFootNumber.tvTitle.setText(R.string.first_station_front_foot_number_l) + mBinding.llRuler2.visibility = View.VISIBLE + } else { + mBinding.llRuler2.visibility = View.GONE + } + } + } + + /** + * 初始化editText坐标的title + */ + private fun initEditTextTitle() { + mBinding.ilWatcher.tvTitle.text = "观测者" + mBinding.ilRecorder.tvTitle.text = "记录者" + mBinding.ilExaminer.tvTitle.text = "检查者" + mBinding.ilFirstStationBackFootNumber.tvTitle.text = + Tools.getString(R.string.first_station_back_foot_number) + mBinding.ilFirstStationFrontFootNumber.tvTitle.text = + Tools.getString(R.string.first_station_front_foot_number) + mBinding.ilFirstStationBackFootNumber2.tvTitle.text = + Tools.getString(R.string.first_station_back_foot_number_r) + mBinding.ilFirstStationFrontFootNumber2.tvTitle.text = + Tools.getString(R.string.first_station_front_foot_number_r) + mBinding.ilInstrumentModel.tvTitle.text = "仪器型号" + mBinding.ilDeviceNumber.tvTitle.text = "仪器编号" + mBinding.ilSteelRuleParam.tvTitle.text = "标尺因瓦带膨胀系数" + mBinding.ilRulerCorrectionFactor.tvTitle.text = "标尺改正系数(mm/m)" + mBinding.ilRulerLengthProvingTemperature.tvTitle.text = "标尺长度检定温度(℃)" + } + + private fun initRulerReceptType() { + initEditSpinner( + mBinding.ilEditSpinnerRulerRecept.tvName, + "尺承类型", + mBinding.ilEditSpinnerRulerRecept.etSpinner, + "请输入或选择" + ) + val adapter = + SimpleAdapter(requireContext(), LevelStationSettingContant.rulerReceptTypeList) + mBinding.ilEditSpinnerRulerRecept.etSpinner.setAdapter(adapter) + } + + private fun initSpinnerRulerType() { + mBinding.spinnerRulerType.adapter = ArrayAdapter( + requireContext(), + android.R.layout.simple_list_item_1, + LevelStationSettingContant.rulerTypeList + ) + } + + override fun initData() { + viewModel.editLastDataLiveData.observe(viewLifecycleOwner) { + if (it == null) { + setRulerReceptTypeData("不足5kg尺台") + } else { + setData(it) + } + } + } + + override fun checkSaveNot(): Boolean { + collectData() + if (isEmpty(levelRouteSave.frontFootNumber)) { + ToastUtils.showShort(R.string.first_station_front_foot_number_hint) + return true + } + if (isEmpty(levelRouteSave.backFootNumber)) { + ToastUtils.showShort(R.string.first_station_back_foot_number_hint) + return true + } + + if (mBinding.llRuler2.visibility == View.VISIBLE) { + if (isEmpty(levelRouteSave.frontFootNumber2)) { + ToastUtils.showShort(R.string.first_station_front_foot_number_hint) + return true + } + if (isEmpty(levelRouteSave.backFootNumber2)) { + ToastUtils.showShort(R.string.first_station_back_foot_number_hint) + return true + } + } + + return false + } + + override fun setDataToStation() { + viewModel.addInforDataToLevelRouteSave(levelRouteSave) + } + + private fun collectData() { + levelRouteSave = LevelRouteSave() + levelRouteSave.watcher = mBinding.ilWatcher.editText.text.toString().trim() + levelRouteSave.recorder = mBinding.ilRecorder.editText.text.toString().trim() + levelRouteSave.examiner = mBinding.ilExaminer.editText.text.toString().trim() + levelRouteSave.frontFootNumber = + mBinding.ilFirstStationFrontFootNumber.editText.text.toString().trim() + levelRouteSave.backFootNumber = + mBinding.ilFirstStationBackFootNumber.editText.text.toString().trim() + if (mBinding.llRuler2.visibility == View.VISIBLE) { + levelRouteSave.frontFootNumber2 = + mBinding.ilFirstStationFrontFootNumber2.editText.text.toString().trim() + levelRouteSave.backFootNumber2 = + mBinding.ilFirstStationBackFootNumber2.editText.text.toString().trim() + } + levelRouteSave.instrumentModel = mBinding.ilInstrumentModel.editText.text.toString().trim() + levelRouteSave.deviceNumber = mBinding.ilDeviceNumber.editText.text.toString().trim() + levelRouteSave.steelRuleParam = mBinding.ilSteelRuleParam.editText.text.toString().trim() + levelRouteSave.rulerCorrectionFactor = + mBinding.ilRulerCorrectionFactor.editText.text.toString().trim() + levelRouteSave.rulerLengthProvingTemperature = + mBinding.ilRulerLengthProvingTemperature.editText.text.toString().trim() + levelRouteSave.rulerType = LevelStationSettingUtil.getSpinnerText(mBinding.spinnerRulerType) + levelRouteSave.rulerReceptType = mBinding.ilEditSpinnerRulerRecept.etSpinner.text.trim() + } + + private fun isEmpty(value: String?) = TextUtils.isEmpty(value) + + private fun setData(levelRouteSave: LevelRouteSave) { + mBinding.ilWatcher.editText.setText(levelRouteSave.watcher) + mBinding.ilRecorder.editText.setText(levelRouteSave.recorder) + mBinding.ilExaminer.editText.setText(levelRouteSave.examiner) + mBinding.ilFirstStationBackFootNumber.editText.setText(levelRouteSave.backFootNumber) + mBinding.ilFirstStationFrontFootNumber.editText.setText(levelRouteSave.frontFootNumber) + mBinding.ilFirstStationBackFootNumber2.editText.setText(levelRouteSave.backFootNumber2) + mBinding.ilFirstStationFrontFootNumber2.editText.setText(levelRouteSave.frontFootNumber2) + mBinding.ilInstrumentModel.editText.setText(levelRouteSave.instrumentModel) + mBinding.ilDeviceNumber.editText.setText(levelRouteSave.deviceNumber) + mBinding.ilSteelRuleParam.editText.setText(levelRouteSave.steelRuleParam) + mBinding.ilRulerCorrectionFactor.editText.setText(levelRouteSave.rulerCorrectionFactor) + mBinding.ilRulerLengthProvingTemperature.editText.setText(levelRouteSave.rulerLengthProvingTemperature) + + mBinding.spinnerRulerType.setSelection( + LevelStationSettingContant.rulerTypeList.indexOf( + levelRouteSave.rulerType + ) + ) + setRulerReceptTypeData(levelRouteSave.rulerReceptType) + } + + private fun setRulerReceptTypeData(value: String?) { + mBinding.ilEditSpinnerRulerRecept.etSpinner.text = value + } + + private fun initEditSpinner( + textView: TextView, + textViewName: String, + view: EditSpinner, + textHint: String + ) { + textView.text = textViewName + view.setHint(textHint) + view.setEtGravity(Gravity.CENTER_VERTICAL or Gravity.END) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/LevelSurveyFragment.java b/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/LevelSurveyFragment.java new file mode 100644 index 0000000..1ea0265 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/LevelSurveyFragment.java @@ -0,0 +1,497 @@ +package com.bingce.controlnetwork.func.level.fragment; + + +import android.content.Context; +import android.os.Bundle; +import android.text.TextUtils; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentStatePagerAdapter; +import androidx.lifecycle.ViewModelProvider; +import androidx.viewpager.widget.PagerAdapter; +import androidx.viewpager.widget.ViewPager; + +import com.bingce.controlapphelper.datasource.database.leveling.station.LevelingStationRecord; +import com.bingce.controlapphelper.leveling.detaction.ILevelRefreshBtn; +import com.bingce.controlapphelper.leveling.detaction.INextStation; +import com.bingce.controlapphelper.leveling.detaction.LevelCheckBtnUtil; +import com.bingce.controlapphelper.leveling.detaction.LevelReceiveData; +import com.bingce.controlapphelper.model.BundleConstants; +import com.bingce.controlapphelper.surveyor.test.Test; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.activity.fragmentcontainer.FragmentContainerActivity; +import com.bingce.controlnetwork.databinding.FragmentLevelSurveyorBinding; +import com.bingce.controlnetwork.fragment.TipsFragment; +import com.bingce.controlnetwork.func.level.activity.LevelStationSettingActivity; +import com.bingce.controlnetwork.func.level.viewmodel.LevelSuveyorVm; +import com.bingce.controlnetwork.newui.base.BaseFragmentBinding; +import com.bingce.controlnetwork.util.DialogUtil; +import com.bingce.controlnetwork.util.StationSettingCheckUtil; +import com.bingce.utils.ThreadPoolUtil; + +import java.util.ArrayList; +import java.util.List; + +import blankj.utilcode.util.ToastUtils; +import com.bingce.controlnetwork.func.level.sendreceive.ILevelBackData; +import com.bingce.controlnetwork.func.level.sendreceive.LevelRequest; +import com.bingce.controlnetwork.func.level.sendreceive.LevelRequestRelease; +import com.bingce.controlnetwork.func.level.sendreceive.LevelRequestTest; + +/** + * 水准测量页 + */ +public class LevelSurveyFragment extends BaseFragmentBinding { + public static final String TAG = LevelSurveyFragment.class.getName(); + + public static final String KEY_STATION_INDEX = "STATION_INDEX"; + private LevelSuveyorVm viewModel; + private List fragments; + private MenuItem rollBackBtn; + private MenuItem reMeasureStationBtn; + + private StationSettingCheckUtil stationSettingCheckUtil; + + private final INextStation nextStationI = this::showSelectLevelNextStepDialog; + + private LevelRequest levelRequest; + private final ILevelBackData levelBackData = new ILevelBackData() { + @Override + public void receive(@NonNull LevelReceiveData data) { + receiveData(data); + } + + @Override + public void measureError(@NonNull String msg) { + if (getView() == null) { + return; + } + DialogUtil.showAlertDialog(requireContext(), getChildFragmentManager(), getViewLifecycleOwner(), msg); + } + }; + + private MyPagerAdapter myPagerAdapter; + + private void receiveData(LevelReceiveData data) { + if (getView() == null) { + return; + } + LevelSurveySubFragment currentFragment = getCurrentFragment(); + if (currentFragment != null) { + currentFragment.recieveData(data); + } + } + + private final ILevelRefreshBtn levelRefreshBtnI = new ILevelRefreshBtn() { + @Override + public void refreshMeasureBtn() { + boolean measureEnable = LevelCheckBtnUtil.getMeasureEnable(viewModel.getCurrentStationId()); + ThreadPoolUtil.executeInMain(() -> { + setViewEnable(mBinding.surveyor, measureEnable); + setViewEnable(mBinding.btnInput, measureEnable); + }); + } + + @Override + public void refreshNextStationBtn() { + boolean measureEnable = LevelCheckBtnUtil.getNextStationEnable(viewModel.getCurrentStationId()); + ThreadPoolUtil.executeInMain(() -> setViewEnable(mBinding.btnNextStation, measureEnable)); + } + + @Override + public void refreshRollBackBtn() { + doRefreshRollBackBtn(); + } + + @Override + public void refreshReMeasureBtn() { + doRefreshReMeasureBtn(); + } + }; + + private void doRefreshReMeasureBtn() { + if (reMeasureStationBtn != null) { + boolean measureEnable = LevelCheckBtnUtil.getReMeasureStationEnable(viewModel.getCurrentStationId()); + ThreadPoolUtil.executeInMain(() -> reMeasureStationBtn.setEnabled(measureEnable)); + } + } + + private void doRefreshRollBackBtn() { + if (rollBackBtn != null) { + boolean measureEnable = LevelCheckBtnUtil.getRollBackEnable(viewModel.getCurrentStationId()); + ThreadPoolUtil.executeInMain(() -> rollBackBtn.setEnabled(measureEnable)); + } + } + + public static void start(Context context, String projectId, String routeId, String routeName) { + Bundle bundle = new Bundle(); + bundle.putString(BundleConstants.KEY_PROJECT_ID, projectId); + bundle.putString(BundleConstants.KEY_ROUTE_ID, routeId); + bundle.putString(BundleConstants.KEY_ROUTE_NAME, routeName); + FragmentContainerActivity.start(context, TAG, "水准测量", bundle); + } + + public static Fragment newInstance(Bundle args) { + Fragment fragment = new LevelSurveyFragment(); + fragment.setArguments(args); + return fragment; + } + + @Override + protected FragmentLevelSurveyorBinding getViewBinding(@NonNull LayoutInflater inflater, ViewGroup container) { + return FragmentLevelSurveyorBinding.inflate(inflater, container, false); + } + + @Override + public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { + super.onCreateOptionsMenu(menu, inflater); + inflater.inflate(R.menu.menu_level_survey, menu); + rollBackBtn = menu.findItem(R.id.rollBack); + reMeasureStationBtn = menu.findItem(R.id.reMeasureStation); + doRefreshRollBackBtn(); + doRefreshReMeasureBtn(); + } + + @Override + public void onPrepareOptionsMenu(@NonNull Menu menu) { + if (Test.DEBUG) { + menu.findItem(R.id.test).setVisible(true); + } + super.onPrepareOptionsMenu(menu); + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + if (R.id.rollBack == item.getItemId()) { + showConfirmDialog(getString(R.string.level_roll_back_hint), () -> { + LevelSurveySubFragment currentFragment = getCurrentFragment(); + if (currentFragment != null) { + currentFragment.startRollBack(); + } + }); + } else if (R.id.reMeasureStation == item.getItemId()) { + showConfirmDialog(getString(R.string.level_remeasure_station_hint), () -> { + LevelSurveySubFragment currentFragment = getCurrentFragment(); + if (currentFragment != null) { + currentFragment.reMeasureStation(); + } + }); + } else if (R.id.surveyorSettings == item.getItemId()) { + LevelingStationRecord currentStation = viewModel.getCurrentStation(); + if (currentStation != null) { + LevelStationSettingActivity.start(requireContext(), getRouteId(), currentStation.getId(), false); + } + } else if (R.id.levelRouteResult == item.getItemId()) { + viewModel.calLevelRouteResult(result -> { + DialogUtil.showAlertDialog(requireContext(), getChildFragmentManager(), getViewLifecycleOwner(), result); + return null; + }); + } else if (R.id.receiveDataType == item.getItemId()) { + LevelInputAllowFragment.show(getChildFragmentManager(), getViewLifecycleOwner(), + mBinding.surveyor.getVisibility() == View.VISIBLE,//是否仪器获取数据 + auto -> { + viewModel.setGetDataAuto(getRouteId(), auto); + refreshManuleAutoInput(auto); + }); + } else if (R.id.test == item.getItemId()) { + TestDataSelectLevelFragment.show(getChildFragmentManager(), position -> { + LevelRequestTest levelReceiveData1 = (LevelRequestTest) levelRequest; + levelReceiveData1.initTestData(position); + }); + } else if (R.id.rollBackStation == item.getItemId()) { + startRollBackStation(); + } + return super.onOptionsItemSelected(item); + } + + private void startRollBackStation() { + if (!viewModel.getMeasureStationList().isEmpty()) { + String lastStationId = viewModel.getMeasureStationList().get(0).lastStationId; + if (TextUtils.isEmpty(lastStationId)) { + ToastUtils.showShort("没有上一站了"); + return; + } + showConfirmDialog("是否要回退至上一站,该操作将清空当前站所有数据", () -> { + viewModel.rollBackStation(); + }); + } + } + + + @Override + public void onDestroyView() { + super.onDestroyView(); +// EventBus.getDefault().unregister(this); + levelRequest.onDestroy(); + LevelCheckBtnUtil.destroy(); + } + + @Override + protected void initView() { + setHasOptionsMenu(true); + initLevelRequest(); + stationSettingCheckUtil = new StationSettingCheckUtil(); + viewModel = new ViewModelProvider(this).get(LevelSuveyorVm.class); + + viewModel.initData(levelRefreshBtnI, () -> { + initViewPager(); + return null; + }, integer -> { + mBinding.vp.setCurrentItem(integer); + return null; + }, nextStationI); + + viewModel.getGetDadaAuto(getRouteId(), auto -> { + refreshManuleAutoInput(auto); + return null; + }); + + initTitle(); + + initListener(); + } + + private void initLevelRequest() { + if (Test.DEBUG) { + levelRequest = new LevelRequestTest(levelBackData); + } else { + levelRequest = new LevelRequestRelease(levelBackData); + } + levelRequest.onStart(); + } + + private void initTitle() { + mBinding.tvRouteName.setText("测段:" + getRouteName()); + } + + @Override + protected void initData() { + viewModel.initDataStationList(getProjectId(), getRouteId()); + + viewModel.checkSunTime(getProjectId(), hint -> { + if (!TextUtils.isEmpty(hint)) { + DialogUtil.showAlertDialog(requireContext(), getChildFragmentManager(), getViewLifecycleOwner(), hint); + } + return null; + }); + } + + private void initListener() { + mBinding.surveyor.setOnClickListener(v -> { + stationSettingCheckUtil.checkStationSettingsLevel(viewModel.getCurrentStationId(), getChildFragmentManager(), this, + requireContext(), + this, + () -> levelRequest.requeset()); + }); + + mBinding.btnNextStation.setOnClickListener(v -> { + stationSettingCheckUtil.checkStationSettingsLevel(viewModel.getCurrentStationId(), getChildFragmentManager(), this, + requireContext(), + this, + () -> { + LevelSurveySubFragment currentFragment = getCurrentFragment(); + if (currentFragment != null) { + currentFragment.nextStation(); + } + }); + }); + + mBinding.btnInput.setOnClickListener(v -> { + stationSettingCheckUtil.checkStationSettingsLevel(viewModel.getCurrentStationId(), getChildFragmentManager(), this, + requireContext(), + this, + () -> { + runOnUI(() -> { + LevelInputFragment.show(getChildFragmentManager(), getViewLifecycleOwner(), + (distance, height) -> receiveData(new LevelReceiveData(height, distance))); + + }); + }); + }); + + } + + private String getProjectId() { + return getArgumentString(BundleConstants.KEY_PROJECT_ID); + } + + private String getRouteId() { + return getArgumentString(BundleConstants.KEY_ROUTE_ID); + } + + private String getRouteName() { + return getArgumentString(BundleConstants.KEY_ROUTE_NAME); + } + + private void initViewPager() { + fragments = new ArrayList<>(); + for (int i = 0; i < viewModel.getMeasureStationList().size(); i++) { + fragments.add(LevelSurveySubFragment.newInstance(i)); + } + + if (myPagerAdapter == null) { + mBinding.vp.setOffscreenPageLimit(3); + myPagerAdapter = new MyPagerAdapter(getChildFragmentManager()); + mBinding.vp.setAdapter(myPagerAdapter); + mBinding.tabLayout.setViewPager(mBinding.vp); + + mBinding.vp.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + viewModel.setCurrentFragmentPos(position); + viewModel.switchRefreshBtnEnable(); + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }); + } else { + myPagerAdapter.notifyDataSetChanged(); + mBinding.tabLayout.notifyDataSetChanged(); + mBinding.tabLayout.setCurrentTab(0); + } + } + + private LevelSurveySubFragment getCurrentFragment() { + int currentFragmentPos = viewModel.getCurrentFragmentPos(); + if (fragments != null && fragments.size() > currentFragmentPos) { + return fragments.get(currentFragmentPos); + } + return null; + } + + private void setViewEnable(View view, boolean measureEnable) { + view.setEnabled(measureEnable); + if (measureEnable) { + view.setAlpha(1); + } else { + view.setAlpha(.4f); + } + } + + private class MyPagerAdapter extends FragmentStatePagerAdapter { + public MyPagerAdapter(FragmentManager fm) { + super(fm); + } + + @Override + public int getCount() { + return fragments.size(); + } + + @Override + public CharSequence getPageTitle(int position) { + return viewModel.getMeasureStationList().get(position).stationName; + } + + @Override + public Fragment getItem(int position) { + return fragments.get(position); + } + + @Override + public int getItemPosition(@NonNull Object object) { + return PagerAdapter.POSITION_NONE; + } + } + + + private void showConfirmDialog(String content, TipsFragment.IConfirmCallback callback) { + TipsFragment.cancelAbleTips(getChildFragmentManager(), getViewLifecycleOwner(), requireContext(), + content, -1, callback); + } + + /** + * 下一站的弹框 + */ + private void showSelectLevelNextStepDialog(LevelingStationRecord station) { + runOnUI(() -> SelectLevelNextStationTypeFragment.select(getChildFragmentManager(), getViewLifecycleOwner(), type -> { + switch (type) { + case SelectLevelNextStationTypeFragment.TYPE_CONTINUE_OBSERVE: + //继续观测 + startMeasureNextStation(station); + break; + case SelectLevelNextStationTypeFragment.TYPE_INTERMITTENT: + viewModel.intermittent(station); + break; + case SelectLevelNextStationTypeFragment.TYPE_END_STATION: + checkEndStation(station); + break; + } + })); + } + + /** + * 点击结束测站时验证 + * + * @param station + */ + private void checkEndStation(LevelingStationRecord station) { + ThreadPoolUtil.execute(() -> { + //增加确认结束测站的提醒 + if (station.isOddStation()) { + //当前是奇数站 + ToastUtils.showShort("结束测站必须是偶数站!"); + return; + } + //是否设置过结束测站的测站设置 + boolean isSetEndStationSetting = viewModel.isHaveSetEndStationSetting(station.getId()); + if (!isSetEndStationSetting) { + runOnUI(() -> StationSettingCheckUtil.showLevelSetStationSetting(getChildFragmentManager(), + getViewLifecycleOwner(), getContext(), StationSettingCheckUtil.HINT_LEVEL_END, + getRouteId(), station.getId(), true)); + return; + } + runOnUI(() -> showConfirmEndRouteStartEndStation(station)); + }); + + } + + /** + * 下一站继续观测 + */ + public void startMeasureNextStation(LevelingStationRecord station) { + viewModel.contineObserve(station); + } + + /** + * 结束路线开始下一站的确认提醒 + * + * @param station + */ + private void showConfirmEndRouteStartEndStation(LevelingStationRecord station) { + DialogUtil.showConfirmDialog(getChildFragmentManager(), getViewLifecycleOwner(), Tools.getString(R.string.level_end_route_hint), Tools.getString(R.string.confirm), new DialogUtil.IConfirmBack() { + @Override + public void onConfirm() { + viewModel.endStation(station); + } + }); + } + + private void refreshManuleAutoInput(boolean receiveDataTypeAuto) { + if (receiveDataTypeAuto) { + mBinding.surveyor.setVisibility(View.VISIBLE); + mBinding.btnInput.setVisibility(View.GONE); + } else { + mBinding.btnInput.setVisibility(View.VISIBLE); + mBinding.surveyor.setVisibility(View.GONE); + } + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/LevelSurveySubFragment.java b/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/LevelSurveySubFragment.java new file mode 100644 index 0000000..fd65769 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/LevelSurveySubFragment.java @@ -0,0 +1,380 @@ +package com.bingce.controlnetwork.func.level.fragment; + + +import static com.bingce.controlapphelper.model.LevelToleranceNoticeKt.VALUE_IGNORE; +import static com.bingce.controlapphelper.model.LevelToleranceNoticeKt.VALUE_REMEASURE_POINT; +import static com.bingce.controlapphelper.model.LevelToleranceNoticeKt.VALUE_REMEASURE_STATION; + +import android.content.Intent; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import androidx.activity.result.ActivityResultLauncher; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.lifecycle.ViewModelProvider; + +import com.bingce.controlapphelper.datasource.database.leveling.LevelingDbFactory; +import com.bingce.controlapphelper.datasource.database.leveling.measure.backfront.LevelingMeasureBackFrontRecord; +import com.bingce.controlapphelper.datasource.database.leveling.measure.station.LevelingMeasureStationRecord; +import com.bingce.controlapphelper.datasource.database.leveling.station.LevelingStationRecord; +import com.bingce.controlapphelper.leveling.detaction.IDetectionHint; +import com.bingce.controlapphelper.leveling.detaction.LevelReceiveData; +import com.bingce.controlapphelper.leveling.detaction.LevelSpeakMsg; +import com.bingce.controlapphelper.leveling.detaction.surveyorcache.SurveyorCacheData; +import com.bingce.controlapphelper.model.LevelToleranceNotice; +import com.bingce.controlapphelper.model.LevelingMeasureOrderUtil; +import com.bingce.controlapphelper.model.PickPointResult; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.databinding.FragmentLevelSurveyorSubBinding; +import com.bingce.controlnetwork.fragment.PickPointFragment; +import com.bingce.controlnetwork.fragment.TipsFragment; +import com.bingce.controlnetwork.func.level.dialog.LevelToleranceTipsFragment; +import com.bingce.controlnetwork.newui.base.BaseFragmentBinding; + +import java.util.ArrayList; +import java.util.List; +import com.bingce.controlnetwork.func.level.viewmodel.LevelSuveyorSubVm; +import com.bingce.controlnetwork.func.level.viewmodel.LevelSuveyorVm; +import com.bingce.controlnetwork.util.DialogUtil; + +/** + * 水准测量页 + */ +public class LevelSurveySubFragment extends BaseFragmentBinding { + public static final String TAG = LevelSurveySubFragment.class.getName(); + private LevelSuveyorSubVm viewModel; + private LevelSuveyorVm stationListVm; + + + private final ActivityResultLauncher defaultStationLauncher = PickPointFragment.createActivityLauncher(this, (type, pickPointResult) -> { +// if (pickPointResult.getSelectedIds().isEmpty() || pickPointResult.getSelectedNames().isEmpty()) { +// return; +// } +// //只有前视才允许选点 +// String pointId = pickPointResult.getSelectedIds().get(0); +// viewModel.saveMeasureFrontPointId(pointId, () -> { +// setFrontPointNameUi(pickPointResult.getSelectedNames().get(0)); +// return null; +// }); + }); + +// private void setFrontPointNameUi(String name) { +// mBinding.ilPoint.tvPoint.setText(name); +// } + + public static LevelSurveySubFragment newInstance(int stationIndex) { + Bundle args = new Bundle(); + args.putInt(LevelSurveyFragment.KEY_STATION_INDEX, stationIndex); + LevelSurveySubFragment fragment = new LevelSurveySubFragment(); + fragment.setArguments(args); + return fragment; + } + + @Override + protected FragmentLevelSurveyorSubBinding getViewBinding(@NonNull LayoutInflater inflater, ViewGroup container) { + return FragmentLevelSurveyorSubBinding.inflate(inflater, container, false); + } + + @Override + protected void initView() { + viewModel = new ViewModelProvider(this).get(LevelSuveyorSubVm.class); + stationListVm = new ViewModelProvider(requireParentFragment()).get(LevelSuveyorVm.class); + + mBinding.ilSightDistanceDiffCurrent.tvTitle.setText("视距差:"); + mBinding.ilDistanceTotal.tvTitle.setText("总距离:"); + mBinding.ilSightDistanceDiffTotal.tvTitle.setText("累积视距差:"); + mBinding.ilHeightDiffTotal.tvTitle.setText("总高差:"); + mBinding.ilZ.tvTitle.setText("高程:"); + initListener(); + initObserver(); + } + + private void initObserver() { + viewModel.getStationLiveData().observe(this, stationRecord -> { + boolean measureBack = LevelingMeasureOrderUtil.INSTANCE.isMeasureBack(stationRecord); + + String backFrontType = measureBack ? getString(R.string.rearview) : getString(R.string.forward_view); + mBinding.tvBackFrontType.setText(backFrontType); + + //除了结束测站的第一个前视点可以选择测点 +// setSelectPointShowHide(stationRecord); + + setMeasureOrderAndCurrent(stationRecord); + + setSurveyorCacheUiVisiable(stationRecord); + +// viewModel.getMeasurePointName(stationRecord, pointName -> { +// setFrontPointNameUi(pointName); +// return null; +// }); + + }); + + viewModel.getSurveyorCacheDataLiveData().observe(this, this::setSurveyorCacheUi); + + viewModel.getMeasureStationLiveData().observe(this, this::setMeasureStationUi); + + //监听路线的最后一次设置更新尺子编号 + if (stationListVm.getRouteId() != null) { + LevelingDbFactory.instance.getStationSettingDataSource().getLatestLiveData(stationListVm.getRouteId()) + .observe(getViewLifecycleOwner(), levelingStationSettingRecord -> { + if (levelingStationSettingRecord != null) { + int stationIndex = getStationIndex(); + if (stationIndex == 0) { + mBinding.tvRulerNumBack.setText(getRulerNumShow(levelingStationSettingRecord.firstStationBackFootNumber)); + mBinding.tvRulerNumFront.setText(getRulerNumShow(levelingStationSettingRecord.firstStationFrontFootNumber)); + } else { + mBinding.tvRulerNumBack.setText(getRulerNumShow(levelingStationSettingRecord.firstStationBackFootNumber2)); + mBinding.tvRulerNumFront.setText(getRulerNumShow(levelingStationSettingRecord.firstStationFrontFootNumber2)); + } + } + }); + } + + } + + private String getRulerNumShow(String rulerNum) { + if (rulerNum==null) { + rulerNum = ""; + } + return "No." + rulerNum; + } + + private void setSelectPointShowHide(LevelingStationRecord stationRecord) { + viewModel.isEndStation(stationRecord, endStation -> { + //非单程双侧,前视,非终点站可以选择测点 + boolean measureFirstFront = LevelingMeasureOrderUtil.INSTANCE.isMeasureFirstFront(stationRecord); + boolean canSelectPoint = measureFirstFront && getStationIndex() == 0 && !endStation; +// mBinding.ilPoint.ivSelectPoint.setVisibility(canSelectPoint ? View.VISIBLE : View.INVISIBLE); +// mBinding.ilPoint.tvPoint.setClickable(canSelectPoint); + return null; + }); + } + + private void setSurveyorCacheUiVisiable(LevelingStationRecord stationRecord) { + boolean showTwiceRead = LevelingMeasureOrderUtil.INSTANCE.isShowTwiceRead(stationRecord); + if (showTwiceRead) { + mBinding.ilB2.getRoot().setVisibility(View.VISIBLE); + mBinding.ilF2.getRoot().setVisibility(View.VISIBLE); + } else { + mBinding.ilB2.getRoot().setVisibility(View.GONE); + mBinding.ilF2.getRoot().setVisibility(View.GONE); + } + + viewModel.setMeasureTextColor(stationRecord, mBinding.ilB1, mBinding.ilB2, mBinding.ilF1, mBinding.ilF2); + } + + private void setMeasureOrderAndCurrent(LevelingStationRecord stationRecord) { +// String textByLevelingMeasureOrder = LevelingMeasureOrderUtil.INSTANCE.getTextByLevelingMeasureOrder(stationRecord.levelingMeasureOrder); +// mBinding.tvOrderType.setText(textByLevelingMeasureOrder); + + CharSequence[] currentOrderArray = viewModel.getCurrentOrderArray(stationRecord); + mBinding.tvCurrentOrderOdd.setText(currentOrderArray[0]); + mBinding.tvCurrentOrderEven.setText(currentOrderArray[1]); + } + + private void setSurveyorCacheUi(SurveyorCacheData surveyorCacheData) { + LevelingMeasureBackFrontRecord b1Data = surveyorCacheData.getB1Data(); + LevelingMeasureBackFrontRecord b2Data = surveyorCacheData.getB2Data(); + LevelingMeasureBackFrontRecord f1Data = surveyorCacheData.getF1Data(); + LevelingMeasureBackFrontRecord f2Data = surveyorCacheData.getF2Data(); + + setSurveyorPointData(mBinding.ilB1.tvDisTance, mBinding.ilB1.tvHeight, b1Data); + setSurveyorPointData(mBinding.ilB2.tvDisTance, mBinding.ilB2.tvHeight, b2Data); + setSurveyorPointData(mBinding.ilF1.tvDisTance, mBinding.ilF1.tvHeight, f1Data); + setSurveyorPointData(mBinding.ilF2.tvDisTance, mBinding.ilF2.tvHeight, f2Data); + + //更新视距差 + String currentFrontBackDistancceDiff = surveyorCacheData.getCurrentFrontBackDistancceDiff(); + mBinding.ilSightDistanceDiffCurrent.tvValue.setText(currentFrontBackDistancceDiff); + } + + private void setSurveyorPointData(TextView tvDisTance, TextView tvHeight, LevelingMeasureBackFrontRecord data) { + if (data == null) { + tvDisTance.setText(""); + tvHeight.setText(""); + } else { + tvDisTance.setText(data.getMeasureDistanceShow()); + tvHeight.setText(data.getMeasureHeightShow()); + } + } + + private void setMeasureStationUi(LevelingMeasureStationRecord record) { + if (record == null) { + mBinding.ilDistanceTotal.tvValue.setText(""); + mBinding.ilSightDistanceDiffTotal.tvValue.setText(""); + mBinding.ilHeightDiffTotal.tvValue.setText(""); + mBinding.ilZ.tvValue.setText(""); + return; + } + + viewModel.getZ(z -> { + mBinding.ilZ.tvValue.setText(record.getZShow(z)); + return null; + }); + + mBinding.ilDistanceTotal.tvValue.setText(record.getDistanceTotalShow()); + mBinding.ilSightDistanceDiffTotal.tvValue.setText(record.getCumulativeVisualDistanceDiffShow()); + mBinding.ilHeightDiffTotal.tvValue.setText(record.getHeightDiffTotalShow()); + } + + @Override + protected void initData() { + String currentStationId = getCurrentStationId(); + if (currentStationId != null) { + viewModel.initData(currentStationId, new IDetectionHint() { + + @Override + public void noticeHint(@NonNull LevelToleranceNotice notice) { + LevelToleranceTipsFragment.tips(getChildFragmentManager(), getViewLifecycleOwner(), + notice.getTitle(), notice.getContent(), new LevelToleranceTipsFragment.IOperatorCallback() { + @Override + public void onReMeasureStation() { + notice.getNoticeBack().levelContinue(VALUE_REMEASURE_STATION, notice.getIgnoreToleranceList()); + } + + @Override + public void onReMeasurePoint() { + notice.getNoticeBack().levelContinue(VALUE_REMEASURE_POINT, notice.getIgnoreToleranceList()); + } + + @Override + public void onIgnore() { + notice.getNoticeBack().levelContinue(VALUE_IGNORE, notice.getIgnoreToleranceList()); + } + }); + } + + @Override + public void stationCheckFinish(@NonNull LevelingStationRecord stationRecord) { + if (stationRecord.endStation) { + LevelSpeakMsg.speakStationFinish("该测段已观测完毕"); + stationListVm.calLevelRouteResult(result -> { + DialogUtil.showAlertDialog(requireContext(), getChildFragmentManager(), getViewLifecycleOwner(), + "该测段已观测完毕\n" + result); + return null; + }); + } else { + boolean simStation = stationRecord.isSimStation(); + if (simStation && !stationRecord.twiceStation) { + String hint = "请观测单程双转第二测站"; + LevelSpeakMsg.speakStationFinish(hint); + //单程双转的第一个测站提示 + TipsFragment.cancelAbleTips(getChildFragmentManager(), getViewLifecycleOwner(), requireContext(), + hint, -1, + () -> switchTwiceStation(stationRecord)); + } else { + String hint = getString(R.string.level_check_finish_next_station_hint); + LevelSpeakMsg.speakStationFinish(hint); + + TipsFragment.tipsOnly(getChildFragmentManager(), getViewLifecycleOwner(), requireContext(), + hint); + } + } + } + }, stationListVm.getNextStationI()); + } + } + + private String getCurrentStationId() { + int stationIndex = getStationIndex(); + List measureStationList = stationListVm.getMeasureStationList(); + if (stationIndex >= 0 && measureStationList.size() > stationIndex) { + return measureStationList.get(stationIndex).getId(); + } + return null; + } + + /** + * 开始切换到第二测站(第二个tab) + */ + private void switchTwiceStation(LevelingStationRecord record) { + LevelSurveyFragment parentFragment = (LevelSurveyFragment) getParentFragment(); + if (parentFragment != null) { + parentFragment.startMeasureNextStation(record); + } + } + + /** + * 去创建测段 + */ + private void goCreateRoute() { + String projectId = viewModel.getProjectId(); + if (projectId != null) { + LevelRouteCreateEditFragment.start(requireContext(), projectId, null, getString(R.string.create_segment_survey)); + requireActivity().finish(); + } + } + + private void initListener() { +// mBinding.ilPoint.tvPoint.setOnClickListener((v) -> { +// StringInputFragment.input(getChildFragmentManager(), "新建点", getViewLifecycleOwner(), string -> { +// if (TextUtils.isEmpty(string)) return; +// viewModel.saveMeasureFrontPoint(PointRecordTj.createHidePoint(string), () -> { +// setFrontPointNameUi(string); +// return null; +// }); +// }); +// }); +// +// mBinding.ilPoint.ivSelectPoint.setOnClickListener((v) -> { +// if (viewModel.getProjectId() == null) return; +// PickPointResult alreadyResult = getAlreadySelectFrontPoint(); +// PickPointFragment.pickKnownAndUnknownPoint(getChildFragmentManager(), +// getViewLifecycleOwner(), +// getContext(), +// "", +// 1, +// getString(R.string.select_surveyor_point), +// null, +// viewModel.getProjectId(), alreadyResult, defaultStationLauncher); +// }); + + } + + @Nullable + private PickPointResult getAlreadySelectFrontPoint() { + PickPointResult alreadyResult = null; + LevelingStationRecord station = viewModel.getStationLiveData().getValue(); + String measurePointId = null; + if (station != null) { + measurePointId = LevelingMeasureOrderUtil.INSTANCE.getMeasurePointId(station); + } + if (measurePointId != null) { + alreadyResult = new PickPointResult(); + List ids = new ArrayList<>(); + List names = new ArrayList<>(); + ids.add(measurePointId); + alreadyResult.setSelectedIds(ids); + alreadyResult.setSelectedNames(names); + } + return alreadyResult; + } + + public void startRollBack() { + viewModel.startRollBack(); + } + + public void reMeasureStation() { + viewModel.reMeasureStation(); + } + + public void recieveData(LevelReceiveData data) { + if (viewModel != null) { + viewModel.recieveData(data); + } + } + + public void nextStation() { + viewModel.nextStation(); + } + + private int getStationIndex() { + return requireArguments().getInt(LevelSurveyFragment.KEY_STATION_INDEX); + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/LevelSurveyorHomeFragment.java b/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/LevelSurveyorHomeFragment.java new file mode 100644 index 0000000..c92082c --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/LevelSurveyorHomeFragment.java @@ -0,0 +1,107 @@ +package com.bingce.controlnetwork.func.level.fragment; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.bingce.controlapphelper.datasource.database.leveling.LevelingDbFactory; +import com.bingce.controlapphelper.datasource.database.leveling.route.LevelRouteRecord; +import com.bingce.controlapphelper.model.BundleConstants; +import com.bingce.controlnetwork.databinding.FragmentLevelSurveyorHomeBinding; +import com.bingce.controlnetwork.fragment.base.BaseFragment; +import com.bingce.controlnetwork.func.level.adapter.LevelRouteListAdapter; + +import blankj.utilcode.util.ToastUtils; + + +/** + * 水准测量首页 + */ +public class LevelSurveyorHomeFragment extends BaseFragment { + public static final String TAG = LevelSurveyorHomeFragment.class.getName(); + private LevelRouteListAdapter adapter; + private FragmentLevelSurveyorHomeBinding mBinding; + + private static final String KEY_DETAIL_OR_SURVEYOR = "___editable___";//标识点击item进入测量界面还是测站详情 + + public static LevelSurveyorHomeFragment newInstance(String projectId, String routeId) { + return newInstance(projectId, routeId, true); + } + + public static LevelSurveyorHomeFragment newInstance(String projectId, String routeId, boolean detailOrSurveyor) { + LevelSurveyorHomeFragment fragment = new LevelSurveyorHomeFragment(); + Bundle bundle = new Bundle(); + bundle.putString(BundleConstants.KEY_PROJECT_ID, projectId); + bundle.putString(BundleConstants.KEY_ROUTE_ID, routeId); + bundle.putBoolean(KEY_DETAIL_OR_SURVEYOR, detailOrSurveyor); + fragment.setArguments(bundle); + return fragment; + } + + /** + * 去测量 + */ + private void goMeasurePage(LevelRouteRecord item) { + String projectId = item.getProjectId(); + if (projectId == null) { + ToastUtils.showShort("项目id异常"); + return; + } + LevelSurveyFragment.start(getContext(), projectId, item.getId(), item.getRouteName()); + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + mBinding = FragmentLevelSurveyorHomeBinding.inflate(inflater, container, false); + return mBinding.getRoot(); + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + mBinding = null; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initView(); + initData(); + } + + private void initView() { + adapter = new LevelRouteListAdapter(requireContext()); + mBinding.recyclerView.setAdapter(adapter); + adapter.setOnItemClickListener(this::goMeasurePage); + } + + private void initData() { + String projectId = getProjectId(); + if (projectId != null) { + LevelingDbFactory.instance.getLevelDataSource().getListLiveData(projectId) + .observe(getViewLifecycleOwner(), routeList -> { + adapter.refreshData(routeList); + }); + } + } + + private String getProjectId() { + if (getArguments() != null) { + return getArguments().getString(BundleConstants.KEY_PROJECT_ID); + } + return null; + } + + private String getRouteId() { + if (getArguments() != null) { + return getArguments().getString(BundleConstants.KEY_ROUTE_ID); + } + return null; + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/ProjectDetailLevelFragment.java b/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/ProjectDetailLevelFragment.java new file mode 100644 index 0000000..2bf7064 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/ProjectDetailLevelFragment.java @@ -0,0 +1,162 @@ +package com.bingce.controlnetwork.func.level.fragment; + +import android.content.Context; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.FragmentActivity; +import androidx.lifecycle.ViewModelProvider; + +import com.bingce.controlapphelper.datasource.database.config.ConfigOperate; +import com.bingce.controlapphelper.event.SwitchPageEvent; +import com.bingce.controlapphelper.model.BundleConstants; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.activity.fragmentcontainer.FragmentContainerActivity; +import com.bingce.controlnetwork.fragment.PointListFragment; +import com.bingce.controlnetwork.fragment.ProjectToleranceSettingFragment; +import com.bingce.controlnetwork.fragment.base.BaseFragment; +import com.bingce.controlnetwork.func.level.idetection.LevelIDetectionListActivity; +import com.bingce.controlnetwork.func.level.viewmodel.LevelCreateOrEditRouteVm; +import com.bingce.controlnetwork.ui.ViewUtil; +import com.bingce.utils.ThreadPoolUtil; + +import org.greenrobot.eventbus.EventBus; +import org.jetbrains.annotations.NotNull; + + +/** + * 水准路线列表,新建测段 + */ +public class ProjectDetailLevelFragment extends BaseFragment { + public static final int title = R.string.project_detail; + public static final String TAG = ProjectDetailLevelFragment.class.getName(); + private String projectId = ""; + private String projectType = ""; + //测站列表 + private LevelRouteFragment fragment; + + private LevelCreateOrEditRouteVm createEditRouteVm; + + + @Override + public View onCreateView(@NotNull LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + if (getArguments() != null) { + projectId = getArguments().getString(BundleConstants.KEY_PROJECT_ID); + projectType = getArguments().getString(BundleConstants.KEY_PROJECT_TYPE); + } + createEditRouteVm = new ViewModelProvider(this).get(LevelCreateOrEditRouteVm.class); + View view = inflater.inflate(R.layout.fragment_project_detail_list_level, container, false); + fragment = LevelRouteFragment.newInstance(projectId); + getChildFragmentManager() + .beginTransaction() + .replace(R.id.fragment_container, fragment, "__station_list") + .commit(); + //已知点 + View known = view.findViewById(R.id.known_point_list); + initKnownPoint(known); + //未知点 + View unknown = view.findViewById(R.id.unknown_point_list); + initUnKnownPoint(unknown); + //新建测段 + View ilBtn = view.findViewById(R.id.ilBtn); + Button createNewRoute = ilBtn.findViewById(R.id.btnOne); + createNewRoute.setText(R.string.create_segment_survey); + initCreateNewRoute(createNewRoute); + //去测量页面 + Button ivGoMeasurePage = ilBtn.findViewById(R.id.btnTwo); + ivGoMeasurePage.setText(R.string.start_surveyor); + initGoMeasurePage(ivGoMeasurePage); + + setHasOptionsMenu(true); + return view; + } + + private void initGoMeasurePage(View ivGoMeasurePage) { + ViewUtil.setOnClick(ivGoMeasurePage, v -> { + FragmentActivity activity = getActivity(); + if (activity != null) { + activity.finish(); + } + + ThreadPoolUtil.execute(() -> { + String surveyorRouteId = fragment.getSurveyorRouteId(); + ConfigOperate.changeDefaultProjectAndRoute(projectId, surveyorRouteId); + EventBus.getDefault().post(new SwitchPageEvent<>(SwitchPageEvent.TYPE_SWITCH_TO_MEASURE_PAGE_AND_DATA, null)); + }); + }); + } + + private void initUnKnownPoint(View unknown) { + ViewUtil.setOnClick(unknown, + v -> PointListFragment.go2UnknownPointList(projectId, projectType, getContext())); + } + + private void initKnownPoint(View known) { + ViewUtil.setOnClick( + known, + v -> PointListFragment.go2KnownPointList(projectId, projectType, getContext())); + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + getData(); + } + + private void getData() { + + } + + /** + * 新建测段 + */ + private void initCreateNewRoute(View viewCreateRoute) { + if (viewCreateRoute != null) { + viewCreateRoute.setOnClickListener((v) -> createEditRouteVm.showCreateOrEditDialog( + requireContext(), + projectId, + null + )); + } + } + + @Override + public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { + inflater.inflate(R.menu.project_detail_fragment_menu_level, menu); + super.onCreateOptionsMenu(menu, inflater); + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + if (item.getItemId() == R.id.project_parameter_setting) { + //设置参数点击事件 + ProjectToleranceSettingFragment.start(getContext(), projectId, projectType); + return true; + } else if (R.id.iAngleDetection == item.getItemId()) { + LevelIDetectionListActivity.launch(requireContext(), projectId); + } + return super.onOptionsItemSelected(item); + } + + public static void start(Context context, String projectType, String projectId, String projectName) { + Bundle bundle = new Bundle(); + bundle.putString(BundleConstants.KEY_PROJECT_ID, projectId); + bundle.putString(BundleConstants.KEY_PROJECT_TYPE, projectType); + FragmentContainerActivity.start(context, TAG, projectName, bundle); + } + + public static ProjectDetailLevelFragment newInstance(Bundle bundle) { + ProjectDetailLevelFragment fragment = new ProjectDetailLevelFragment(); + fragment.setArguments(bundle); + return fragment; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/ProjectEditForLevelFragment.java b/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/ProjectEditForLevelFragment.java new file mode 100644 index 0000000..e5d04eb --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/ProjectEditForLevelFragment.java @@ -0,0 +1,282 @@ +package com.bingce.controlnetwork.func.level.fragment; + +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.Button; +import android.widget.EditText; +import android.widget.Spinner; +import android.widget.Toast; + +import androidx.activity.result.ActivityResultLauncher; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.WorkerThread; +import androidx.fragment.app.DialogFragment; +import androidx.fragment.app.FragmentManager; + +import com.bingce.controlapphelper.datasource.database.ProjectTypeValue; +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.project.ProjectRecord; +import com.bingce.controlapphelper.datasource.database.tolerance.detail.IToleranceDetail; +import com.bingce.controlapphelper.datasource.database.tolerance.detail.ToleranceDetailRecord; +import com.bingce.controlapphelper.datasource.database.tolerance.group.ToleranceGroupRecord; +import com.bingce.controlapphelper.datasource.database.tolerance.level.ToleranceLevelRecord; +import com.bingce.controlapphelper.datasource.database.tolerance.load.IToleranceOperate; +import com.bingce.controlapphelper.model.LevelingMeasureOrder; +import com.bingce.controlapphelper.model.LevelingMeasureOrderUtil; +import com.bingce.controlapphelper.util.ToleranceUtil; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.fragment.AbstractFullScreenDialogFragment; +import com.bingce.controlnetwork.fragment.ToleranceSelectFragment; +import com.bingce.controlnetwork.util.tolerance.ToleranceOperateUtil; +import com.bingce.utils.DateUtils; +import com.bingce.utils.ThreadPoolUtil; + +import java.util.Date; +import java.util.List; + +import blankj.utilcode.util.ToastUtils; + + +/** + * 水准新建编辑项目 + */ +public class ProjectEditForLevelFragment extends AbstractFullScreenDialogFragment { + public final String TAG = ProjectEditForLevelFragment.class.getSimpleName(); + private String toleranceId; + private final ActivityResultLauncher activityResultLauncher; + + private LevelingMeasureOrder levelingMeasureOrder; + + public ProjectEditForLevelFragment() { + super(); + activityResultLauncher = ToleranceSelectFragment + .createActivityLauncher( + this, + this::dealSelectTolerance); + } + + @Override + protected View createContentView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.fragment_project_edit_for_level, container, false); + + Button selectToleranceButton = view.findViewById(R.id.select_tolerance); + if (selectToleranceButton != null) { + selectToleranceButton.setOnClickListener(v -> + //选择限差方案 + ToleranceSelectFragment.start(getContext(), toleranceId, ProjectTypeValue.LEVEL, activityResultLauncher) + ); + } + //设置项目名称 + EditText projectNameEdit = view.findViewById(R.id.editor); + if (projectNameEdit != null && getArguments() != null) { + String projectName = getArguments().getString(KEY_PROJECT_NAME); + if (projectName == null || projectName.isEmpty()) { + projectName = DateUtils.ymdWithCharacter(new Date()); + } + projectNameEdit.setText(projectName); + } + if (getArguments() != null) { + toleranceId = getArguments().getString(KEY_TOLERANCE_ID); + if (toleranceId != null && !toleranceId.isEmpty()) { + ThreadPoolUtil.execute(() -> { + ToleranceDetailRecord instance = + SurveyorDatabaseFactory + .instance + .getToleranceDetailDataSource() + .getRecordSync(toleranceId); + updateTolerance(selectToleranceButton, instance); + }); + } + + String projectId = getArguments().getString(KEY_PROJECT_ID); + if (projectId != null && !projectId.isEmpty()) { + ThreadPoolUtil.execute(() -> { + ProjectRecord projectRecord = + SurveyorDatabaseFactory + .instance + .getProjectDataSource() + .getRecord(projectId); + if (projectRecord == null) { + return; + } + }); + } + } + return view; + } + + @WorkerThread + private void updateTolerance(Button button, IToleranceDetail iToleranceDetail) { + if (iToleranceDetail == null) { + return; + } + toleranceId = iToleranceDetail.getId(); + + IToleranceOperate operate = ToleranceOperateUtil.getOperate(toleranceId); + if (operate == null) return; + ToleranceGroupRecord group = operate.getGroup(iToleranceDetail); + ToleranceLevelRecord level = operate.getLevel(iToleranceDetail); + runOnUI(() -> { + if (button != null) { + String toleranceShowName = ToleranceUtil.completedToleranceName(group, level, iToleranceDetail); + button.setText(toleranceShowName); + } + }); + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + List showList = LevelingMeasureOrderUtil.INSTANCE.getShowList(); + Spinner spinner = view.findViewById(R.id.spinner); + spinner.setAdapter(new ArrayAdapter<>(requireContext(), android.R.layout.simple_list_item_1, showList)); +// spinner.setSelection(editTextItem.prismTypes.indexOf(editTextItem.surveyorPoint.getPrismTypeName())); + spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView parent, View view, int position, long id) { + levelingMeasureOrder = LevelingMeasureOrderUtil.INSTANCE.getLevelingMeasureOrderByCreate(showList.get(position)); + } + + @Override + public void onNothingSelected(AdapterView parent) { + + } + }); + } + + private void runOnUI(Runnable runnable) { + if (getActivity() != null) { + getActivity().runOnUiThread(runnable); + } + } + + @Override + protected boolean quitWhenTouchBg() { + return true; + } + + @Override + protected void onConfirm() { + View view = getView(); + if (view == null) { + return; + } + //判断项目名称是否为空 + EditText editor = view.findViewById(R.id.editor); + String projectName = editor.getText().toString(); + if (projectName.isEmpty()) { + Toast.makeText(getContext(), R.string.tips_need_select_input_project_name, Toast.LENGTH_SHORT).show(); + return; + } + //判断限差参数 + if (toleranceId == null || toleranceId.isEmpty()) { + Toast.makeText(getContext(), R.string.tips_need_select_project_tolerance, Toast.LENGTH_SHORT).show(); + return; + } + if (levelingMeasureOrder == null) { + ToastUtils.showShort(R.string.please_select_measure_order); + return; + } + if (getArguments() == null) { + return; + } + String projectId = getArguments().getString(KEY_PROJECT_ID); + boolean showSlop = true; + if (projectId == null || projectId.isEmpty()) { + ProjectRecord projectRecord = new ProjectRecord(projectName); + projectRecord.setToleranceId(toleranceId); + projectRecord.projectType = ProjectTypeValue.LEVEL; + projectRecord.setShowSlopDistance(showSlop); + //存储 + SurveyorDatabaseFactory + .instance + .getProjectDataSource() + .saveRecordSync(projectRecord); + + + //判断是否需要记录默认项目和测期 +// ThreadPoolUtil.execute(() -> { +// IConfigDataSource configDataSource = +// TjDbFactory.instance.getConfigDataSource(); +// ConfigRecord defaultProject = configDataSource.getByKeySync(ConfigConstantsTj.KEY_DEFAULT_PROJECT_ID); +// if (defaultProject != null && !defaultProject.getConfigValue().isEmpty()) { +// return; +// } +// }); + } else { + ThreadPoolUtil.execute(() -> { + ProjectRecord projectRecord = + SurveyorDatabaseFactory + .instance + .getProjectDataSource() + .getRecord(projectId); + projectRecord.setProjectName(projectName); + projectRecord.setToleranceId(toleranceId); + projectRecord.setShowSlopDistance(showSlop); + //存储 + SurveyorDatabaseFactory + .instance + .getProjectDataSource() + .saveRecordSync(projectRecord); + }); + } + super.onConfirm(); + } + + private static final String KEY_PROJECT_ID = "___project__id"; + private static final String KEY_TOLERANCE_ID = "___tolerance_id"; + private static final String KEY_PROJECT_NAME = "___project___name___"; + + private static DialogFragment newInstance(Context context, String projectId, String toleranceId, String projectName) { + ProjectEditForLevelFragment fragment = new ProjectEditForLevelFragment(); + Bundle args = new Bundle(); + if (projectId == null || projectId.isEmpty()) { + setArgs(args, context.getString(R.string.title_create_new_project), null); + } else { + setArgs(args, context.getString(R.string.title_edit_project), null); + args.putString(KEY_PROJECT_ID, projectId); + args.putString(KEY_TOLERANCE_ID, toleranceId); + args.putString(KEY_PROJECT_NAME, projectName); + } + fragment.setArguments(args); + return fragment; + } + + public static void editProject(FragmentManager fragmentManager, + Context context, + String projectId, String toleranceId, String projectName) { + newInstance(context, projectId, toleranceId, projectName).show(fragmentManager, "_edit_project_fragment"); + } + + public static void createProject(FragmentManager fragmentManager, Context context) { + newInstance(context, null, null, null) + .show(fragmentManager, "__create_project_fragment__"); + } + + /** + * 处理选择返回的限差id + * + * @param id + */ + private void dealSelectTolerance(String id) { + ThreadPoolUtil.execute(() -> { + IToleranceOperate operate = ToleranceOperateUtil.getOperate(id); + if (operate == null) return; + IToleranceDetail toleranceDetail = operate.getIToleranceDetail(id); + //存限差数据 + operate.saveToleranceDetail(toleranceDetail); + View view = getView(); + if (view != null) { + updateTolerance(view.findViewById(R.id.select_tolerance), toleranceDetail); + } + }); + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/SelectLevelNextStationTypeFragment.java b/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/SelectLevelNextStationTypeFragment.java new file mode 100644 index 0000000..731d225 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/SelectLevelNextStationTypeFragment.java @@ -0,0 +1,95 @@ +package com.bingce.controlnetwork.func.level.fragment; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.WindowManager; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; + +import com.bingce.controlnetwork.fragment.SelectProjectAndSurveyorCycleFragment; +import com.google.android.material.bottomsheet.BottomSheetDialogFragment; + +import com.bingce.controlnetwork.R; + +/** + * 水准选择下一站观测方式 + */ +public class SelectLevelNextStationTypeFragment extends BottomSheetDialogFragment { + public static final String TAG = SelectProjectAndSurveyorCycleFragment.class.getName(); + private static final String KEY_REQUEST_SELECT = "__SELECT__"; + private static final String KEY_TYPE = "__SELECT_TYPE__"; + public static final String TYPE_CONTINUE_OBSERVE = "TYPE_CONTINUE_OBSERVE"; + public static final String TYPE_INTERMITTENT = "TYPE_INTERMITTENT"; + public static final String TYPE_END_STATION = "TYPE_END_STATION"; + + private SelectLevelNextStationTypeFragment() { + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View view = inflater.inflate( + R.layout.fragment_select_level_next_station_type, + container, + false); + initClickListener(view); + return view; + } + + private void initClickListener(View view) { + setOnClickListener(view, R.id.continueObserve, v -> backData(TYPE_CONTINUE_OBSERVE)); + setOnClickListener(view, R.id.intermittent, v -> backData(TYPE_INTERMITTENT)); + setOnClickListener(view, R.id.endStation, v -> backData(TYPE_END_STATION)); + setOnClickListener(view, R.id.cancel, v -> dismiss()); + } + + private void backData(String type) { + Bundle args = new Bundle(); + args.putString(KEY_TYPE, type); + getParentFragmentManager().setFragmentResult(KEY_REQUEST_SELECT, args); + dismissAllowingStateLoss(); + } + + private static void setOnClickListener(View root, int id, View.OnClickListener onClickListener) { + View view = root.findViewById(id); + if (view != null) { + view.setOnClickListener(onClickListener); + } + } + + public static void select(FragmentManager fragmentManager, + @NonNull LifecycleOwner lifecycleOwner, + IOnSelectCallback callback) { + SelectLevelNextStationTypeFragment fragment = new SelectLevelNextStationTypeFragment(); + fragmentManager + .setFragmentResultListener( + KEY_REQUEST_SELECT, + lifecycleOwner, + (requestKey, result) -> { + if (KEY_REQUEST_SELECT.equals(requestKey)) { + callback.onSurveyorCycleSelected(result.getString(KEY_TYPE)); + } + }); + fragment.show(fragmentManager, TAG); + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + if (getDialog() == null) { + return; + } + getDialog().getWindow().setLayout( + WindowManager.LayoutParams.MATCH_PARENT, + WindowManager.LayoutParams.WRAP_CONTENT); + } + + public interface IOnSelectCallback { + void onSurveyorCycleSelected(String type); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/TestDataSelectLevelFragment.java b/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/TestDataSelectLevelFragment.java new file mode 100644 index 0000000..a77e6e6 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/fragment/TestDataSelectLevelFragment.java @@ -0,0 +1,136 @@ +package com.bingce.controlnetwork.func.level.fragment; + +import android.app.Dialog; +import android.content.Context; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.Window; +import android.view.WindowManager; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.DialogFragment; +import androidx.fragment.app.FragmentManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlnetwork.R; + +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +import com.bingce.controlnetwork.func.level.sendreceive.TestData; + +public class TestDataSelectLevelFragment extends DialogFragment { + private static IClickItem clickItem; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.fragment_single_list_layout, container, false); + + // Set the adapter + if (view instanceof RecyclerView) { + RecyclerView recyclerView = (RecyclerView) view; + refreshRecyclerView(recyclerView); + } + + return view; + } + + @Override + public void onViewCreated(@NonNull @NotNull View view, @Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + Dialog dialog = getDialog(); + if (dialog == null) { + return; + } + Window window = dialog.getWindow(); + if (window == null) { + return; + } + window.setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT); + WindowManager.LayoutParams lps = window.getAttributes(); + lps.verticalMargin = 0.4F; + lps.horizontalMargin = 0.4F; + window.setAttributes(lps); + } + + protected void refreshRecyclerView(RecyclerView recyclerView) { + List list = TestData.Companion.getTextShowList(); + recyclerView.setAdapter(new MyAdapter(list)); + } + + public static void show(FragmentManager fragmentManager, IClickItem clickItem) { + TestDataSelectLevelFragment.clickItem = clickItem; + TestDataSelectLevelFragment fragment = new TestDataSelectLevelFragment(); + fragment.show(fragmentManager, TestDataSelectLevelFragment.class.getName()); + } + + private class MyAdapter extends RecyclerView.Adapter { + + private final List data; + + public MyAdapter(List data) { + this.data = data; + } + + @NonNull + @Override + public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + Context context = parent.getContext(); + LayoutInflater inflater = LayoutInflater.from(context); + + // Inflate the custom layout + View itemView = inflater.inflate(R.layout.list_item_index_text_layout, parent, false); + + // Return a new holder instance + return new ViewHolder(itemView); + } + + @Override + public void onBindViewHolder(@NonNull ViewHolder holder, int position) { + // Get the data model based on position + String item = data.get(position); + + // Set item views based on your views and data model + holder.index.setText(String.valueOf(position + 1)); + holder.text.setText(item); + + holder.itemView.setOnClickListener(v -> { + if (clickItem != null) { + clickItem.click(holder.getBindingAdapterPosition()); + + dismissAllowingStateLoss(); + } + + }); + } + + @Override + public int getItemCount() { + return data.size(); + } + + // Provide a reference to the views for each data item + + } + + private static class ViewHolder extends RecyclerView.ViewHolder { + public TextView index; + public TextView text; + + public ViewHolder(View itemView) { + super(itemView); + index = itemView.findViewById(R.id.index); + text = itemView.findViewById(R.id.text); + } + } + + public interface IClickItem { + void click(int position); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/LevelIDetectionCalUtil.kt b/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/LevelIDetectionCalUtil.kt new file mode 100644 index 0000000..435cd77 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/LevelIDetectionCalUtil.kt @@ -0,0 +1,234 @@ +package com.bingce.controlnetwork.func.level.idetection + +import com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant +import com.bingce.controlapphelper.datasource.database.leveling.idetection.record.LevelIDetectionRecord +import kotlin.math.pow + +object LevelIDetectionCalUtil { + private val station1 = LevelIDetectionConstant.STATION_TYPE_0 + private val station2 = LevelIDetectionConstant.STATION_TYPE_1 + private val ruler1 = LevelIDetectionConstant.RULER_TYPE_0 + private val ruler2 = LevelIDetectionConstant.RULER_TYPE_1 + private val measureTime1 = LevelIDetectionConstant.MEASURE_TIME_0 + private val measureTime2 = LevelIDetectionConstant.MEASURE_TIME_1 + private val measureTime3 = LevelIDetectionConstant.MEASURE_TIME_2 + private val measureTime4 = LevelIDetectionConstant.MEASURE_TIME_3 + private val measureTime5 = LevelIDetectionConstant.MEASURE_TIME_4 + + /** + * 单位mm + * d1短距 + * d2长距 + */ + fun getIResult( + iDetectionId: String, + measureType: String, + d1: Double, + d2: Double, + stationRecordMap: HashMap + ): Double { + val a1 = getA1(iDetectionId, stationRecordMap) + val b1 = getB1(iDetectionId, stationRecordMap) + val a2 = getA2(iDetectionId, stationRecordMap) + val b2 = getB2(iDetectionId, stationRecordMap) + val deTa = getDeTa(measureType, a1, b1, a2, b2) + return getI(deTa, d1, d2) + } + + private fun getI(deTa: Double, d1: Double, d2: Double) = + deTa * 206265 / (d2 - d1) - 1.61 * 10.0.pow(-5.0) * (d1 + d2) + + + private fun getDeTa( + measureType: String, + a1: Double, + b1: Double, + a2: Double, + b2: Double + ): Double { + return if (LevelIDetectionConstant.A_I_I_B == measureType || LevelIDetectionConstant.I_A_B_I == measureType) { + ((a2 - b2) - (a1 - b1)) / 2 + } else { + (a2 - b2) - (a1 - b1) + } + } + + + /** + * 一站一尺 + */ + private fun getA1( + iDetectionId: String, + stationRecordMap: HashMap + ): Double { + val height1 = getHeight( + stationRecordMap[LevelIDetectionRecord.getRecordId( + iDetectionId, station1, ruler1, + measureTime1 + )] + ) + val height2 = getHeight( + stationRecordMap[LevelIDetectionRecord.getRecordId( + iDetectionId, station1, ruler1, + measureTime2 + )] + ) + val height3 = getHeight( + stationRecordMap[LevelIDetectionRecord.getRecordId( + iDetectionId, station1, ruler1, + measureTime3 + )] + ) + val height4 = getHeight( + stationRecordMap[LevelIDetectionRecord.getRecordId( + iDetectionId, station1, ruler1, + measureTime4 + )] + ) + val height5 = getHeight( + stationRecordMap[LevelIDetectionRecord.getRecordId( + iDetectionId, station1, ruler1, + measureTime5 + )] + ) + return getAverage(height1, height2, height3, height4, height5) + } + + /** + * 一站二尺 + */ + private fun getB1( + iDetectionId: String, + stationRecordMap: HashMap + ): Double { + val height1 = getHeight( + stationRecordMap[LevelIDetectionRecord.getRecordId( + iDetectionId, station1, ruler2, + measureTime1 + )] + ) + val height2 = getHeight( + stationRecordMap[LevelIDetectionRecord.getRecordId( + iDetectionId, station1, ruler2, + measureTime2 + )] + ) + val height3 = getHeight( + stationRecordMap[LevelIDetectionRecord.getRecordId( + iDetectionId, station1, ruler2, + measureTime3 + )] + ) + val height4 = getHeight( + stationRecordMap[LevelIDetectionRecord.getRecordId( + iDetectionId, station1, ruler2, + measureTime4 + )] + ) + val height5 = getHeight( + stationRecordMap[LevelIDetectionRecord.getRecordId( + iDetectionId, station1, ruler2, + measureTime5 + )] + ) + return getAverage(height1, height2, height3, height4, height5) + } + + /** + * 二站一尺 + */ + private fun getA2( + iDetectionId: String, + stationRecordMap: HashMap + ): Double { + val height1 = getHeight( + stationRecordMap[LevelIDetectionRecord.getRecordId( + iDetectionId, station2, ruler1, + measureTime1 + )] + ) + val height2 = getHeight( + stationRecordMap[LevelIDetectionRecord.getRecordId( + iDetectionId, station2, ruler1, + measureTime2 + )] + ) + val height3 = getHeight( + stationRecordMap[LevelIDetectionRecord.getRecordId( + iDetectionId, station2, ruler1, + measureTime3 + )] + ) + val height4 = getHeight( + stationRecordMap[LevelIDetectionRecord.getRecordId( + iDetectionId, station2, ruler1, + measureTime4 + )] + ) + val height5 = getHeight( + stationRecordMap[LevelIDetectionRecord.getRecordId( + iDetectionId, station2, ruler1, + measureTime5 + )] + ) + return getAverage(height1, height2, height3, height4, height5) + } + + /** + * 二站二尺 + */ + private fun getB2( + iDetectionId: String, + stationRecordMap: HashMap + ): Double { + val height1 = getHeight( + stationRecordMap[LevelIDetectionRecord.getRecordId( + iDetectionId, station2, ruler2, + measureTime1 + )] + ) + val height2 = getHeight( + stationRecordMap[LevelIDetectionRecord.getRecordId( + iDetectionId, station2, ruler2, + measureTime2 + )] + ) + val height3 = getHeight( + stationRecordMap[LevelIDetectionRecord.getRecordId( + iDetectionId, station2, ruler2, + measureTime3 + )] + ) + val height4 = getHeight( + stationRecordMap[LevelIDetectionRecord.getRecordId( + iDetectionId, station2, ruler2, + measureTime4 + )] + ) + val height5 = getHeight( + stationRecordMap[LevelIDetectionRecord.getRecordId( + iDetectionId, station2, ruler2, + measureTime5 + )] + ) + return getAverage(height1, height2, height3, height4, height5) + } + + private fun getHeight(record: LevelIDetectionRecord?): Double { + return record?.height ?: 0.0 + } + + /** + * 返回单位mm + */ + private fun getAverage( + height1: Double, + height2: Double, + height3: Double, + height4: Double, + height5: Double + ): Double { + return (height1 + height2 + height3 + height4 + height5) / 5 * 1000 + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/LevelIDetectionListActivity.kt b/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/LevelIDetectionListActivity.kt new file mode 100644 index 0000000..9b168ce --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/LevelIDetectionListActivity.kt @@ -0,0 +1,101 @@ +package com.bingce.controlnetwork.func.level.idetection + +import android.content.Context +import android.content.Intent +import androidx.activity.viewModels +import com.bingce.controlapphelper.datasource.database.leveling.idetection.list.LevelIDetectionList +import com.bingce.controlapphelper.model.BundleConstants +import com.bingce.controlapphelper.util.Tools +import com.bingce.controlapphelper.widget.swiperecyclerview.widget.DefaultItemDecoration +import com.bingce.controlnetwork.R +import com.bingce.controlnetwork.databinding.ActivityLevelIDetectionListBinding +import com.bingce.controlnetwork.func.level.fragment.LevelIDetectionCreateFragment +import com.bingce.controlnetwork.func.level.idetection.adapter.LevelIDetectionListAdapter +import com.bingce.controlnetwork.func.level.idetection.viewmodel.LevelIDetectionListVm +import com.bingce.controlnetwork.newui.base.BaseBindingActivity +import com.bingce.controlnetwork.newui.widget.swipemenu.SwipeMenuDelete +import com.bingce.controlnetwork.util.DialogUtil +import com.bingce.utils.DateUtils +import java.util.Date + +/** + * 水准i角检测列表 + */ +class LevelIDetectionListActivity : BaseBindingActivity() { + private val viewModel by viewModels() + + private val adater by lazy { + LevelIDetectionListAdapter(this) + } + + companion object { + @JvmStatic + fun launch(context: Context, projectId: String) { + context.startActivity(Intent(context, LevelIDetectionListActivity::class.java).apply { + putExtra(BundleConstants.KEY_PROJECT_ID, projectId) + }) + } + } + + override fun getBinding(): ActivityLevelIDetectionListBinding { + return ActivityLevelIDetectionListBinding.inflate(layoutInflater) + } + + override fun initView() { + initAdapter() + initListener() + } + + private fun initListener() { + mBinding.tvCreateIAngleDetection.setOnClickListener { + LevelIDetectionCreateFragment.input( + supportFragmentManager, + "i角检测名称", + DateUtils.ymdHMSWithCharacter(Date()), + this + ) { name -> viewModel.saveNewRecord(getProjectId(), name) } + + } + } + + private fun initAdapter() { + mBinding.ilSwipeList.swipeRecyclerView.addItemDecoration( + DefaultItemDecoration( + Tools.getColor(R.color.transparent), 1, 1 + ) + ) + mBinding.ilSwipeList.swipeRecyclerView.setSwipeMenuCreator( + SwipeMenuDelete(this) + ) + mBinding.ilSwipeList.swipeRecyclerView.setOnItemMenuClickListener { menuBridge, adapterPosition -> + menuBridge.closeMenu() + dealMenuClick(menuBridge.position, adater.getBean(adapterPosition)) + } + mBinding.ilSwipeList.swipeRecyclerView.setOnItemClickListener { view, adapterPosition -> + val bean = adater.getBean(adapterPosition) + LevelIDetectionRecordActivity.launch(this, bean.id) + } + mBinding.ilSwipeList.swipeRecyclerView.adapter = adater + } + + private fun dealMenuClick(position: Int, bean: LevelIDetectionList?) { + DialogUtil.showConfirmDialog( + supportFragmentManager, this, "您确定要删除该i角检测吗?", + Tools.getString(R.string.confirm) + ) { + bean?.let { + viewModel.deleteRecord(it) + } + } + } + + override fun initData() { + viewModel.getListLiveData(getProjectId()).observe(this) { + adater.refreshData(it) + } + } + + private fun getProjectId() = intent.getStringExtra(BundleConstants.KEY_PROJECT_ID)!! + + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/LevelIDetectionRecordActivity.kt b/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/LevelIDetectionRecordActivity.kt new file mode 100644 index 0000000..e5d1a6a --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/LevelIDetectionRecordActivity.kt @@ -0,0 +1,371 @@ +package com.bingce.controlnetwork.func.level.idetection + +import android.content.Context +import android.content.Intent +import android.text.TextUtils +import android.view.Menu +import android.view.MenuItem +import android.view.View +import android.widget.EditText +import androidx.activity.viewModels +import blankj.utilcode.util.ToastUtils +import com.bingce.controlnetwork.func.level.idetection.viewmodel.LevelIDetectionRecordVm +import com.bingce.controlnetwork.func.level.sendreceive.ILevelBackData +import com.bingce.controlnetwork.func.level.sendreceive.LevelRequest +import com.bingce.controlnetwork.func.level.sendreceive.LevelRequestRelease +import com.bingce.controlnetwork.newui.widget.selectitem.SelectIDetectionStationFragment +import com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant +import com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant.I_A_B_I +import com.bingce.controlapphelper.datasource.database.leveling.idetection.list.LevelIDetectionList +import com.bingce.controlapphelper.leveling.detaction.LevelReceiveData +import com.bingce.controlapphelper.model.BundleConstants +import com.bingce.controlapphelper.util.Tools +import com.bingce.controlapphelper.widget.swiperecyclerview.widget.DefaultItemDecoration +import com.bingce.controlnetwork.R +import com.bingce.controlnetwork.databinding.ActivityLevelIDetectionRecordBinding +import com.bingce.controlnetwork.event.RefreshEvent +import com.bingce.controlnetwork.fragment.TipsFragment +import com.bingce.controlnetwork.func.level.fragment.LevelInputAllowFragment +import com.bingce.controlnetwork.func.level.fragment.LevelInputFragment +import com.bingce.controlnetwork.func.level.idetection.adapter.LevelIDetectionRecordAdapter +import com.bingce.controlnetwork.newui.base.BaseBindingActivity +import com.bingce.controlnetwork.newui.widget.selectitem.BaseSelectItemFragment +import com.bingce.controlnetwork.newui.widget.selectitem.SelectIDetectionStationMeasureTypeFragment +import com.bingce.controlnetwork.util.DialogUtil +import com.bingce.controlnetwork.util.StationSettingCheckUtil +import com.bingce.utils.ScreenUtil +import org.greenrobot.eventbus.EventBus +import org.greenrobot.eventbus.Subscribe +import org.greenrobot.eventbus.ThreadMode + +/** + * 水准i角检测-测量 + */ +class LevelIDetectionRecordActivity : BaseBindingActivity() { + private val viewModel by viewModels() + + private val stationSettingCheckUtil = StationSettingCheckUtil() + + private val adapter by lazy { + LevelIDetectionRecordAdapter(this, surveyorData) + } + + private val surveyorData by lazy { + LevelIDetectionSurveyorData(getIDetectionId()) + } + + private val levelReceiveData: LevelRequest = LevelRequestRelease(object : ILevelBackData { + override fun receive(data: LevelReceiveData) { + receiveData(data) + } + + override fun measureError(msg: String) { + if (isDestroyed || isFinishing) { + return + } + DialogUtil.showAlertDialog( + this@LevelIDetectionRecordActivity, + supportFragmentManager, + this@LevelIDetectionRecordActivity, + msg + ) + } + }) + + @Subscribe(threadMode = ThreadMode.BACKGROUND) + fun refresh(event: RefreshEvent<*>) { + if (event.type == RefreshEvent.REFRESH_BY_LEVEL_I_DETECTION_SETTING_UPDATE) { + viewModel.updateStationSetting() + adapter.setStationSetting(viewModel.stationSetting) + runOnUiThread { + adapter.notifyDataSetChanged() + } + } + } + + companion object { + @JvmStatic + fun launch(context: Context, levelIDetectionId: String) { + context.startActivity(Intent(context, LevelIDetectionRecordActivity::class.java).apply { + putExtra(BundleConstants.KEY_I_DETECTION_ID, levelIDetectionId) + }) + } + } + + override fun getBinding(): ActivityLevelIDetectionRecordBinding { + return ActivityLevelIDetectionRecordBinding.inflate(layoutInflater) + } + + override fun onDestroy() { + super.onDestroy() + levelReceiveData.onDestroy() + EventBus.getDefault().unregister(this) + } + + override fun onCreateOptionsMenu(menu: Menu?): Boolean { + menuInflater.inflate(R.menu.menu_level_survey_i_detection, menu) + return super.onCreateOptionsMenu(menu) + } + + override fun onOptionsItemSelected(item: MenuItem): Boolean { + if (R.id.result == item.itemId) { + startIResult() + } else if (R.id.stationSetting == item.itemId) { + goLevelIDetectionSetting() + } else if (R.id.rollBack == item.itemId) { + startRollBack() + } else if (R.id.level_i_detection_sample == item.itemId) { + LevelIDetectionSampleActivity.launch(this) + } else if (R.id.receiveDataType == item.itemId) { + showReceiveDataTypeDialog() + } + return super.onOptionsItemSelected(item) + } + + /** + * i角检测的测站设置 + */ + private fun goLevelIDetectionSetting() { + LevelIDetectionStationSettingActivity.launch(this, getIDetectionId()) + } + + private fun showReceiveDataTypeDialog() { + LevelInputAllowFragment.show( + supportFragmentManager, + this, + mBinding.surveyor.visibility == View.VISIBLE + ) { + viewModel.setGetDataAuto(getIDetectionId(), it) + refreshManuleAutoInput(it) + } + } + + private fun startIResult() { + val d1String = getEtText(mBinding.etShortDistance) + if (TextUtils.isEmpty(d1String)) { + ToastUtils.showShort("请输入短距") + return + } + val d2String = getEtText(mBinding.etLongDistance) + if (TextUtils.isEmpty(d2String)) { + ToastUtils.showShort("请输入长距") + return + } + + if (viewModel.measureType == null) { + ToastUtils.showShort("请选择测量方式") + return + } + + //存短长距和测量方式 + viewModel.saveShortLongDistanceMeasureType(d1String, d2String) + //计算结果 + val result = viewModel.startResult(getD(d1String), getD(d2String)) + if (!TextUtils.isEmpty(result)) { + DialogUtil.showAlertDialog( + this, + supportFragmentManager, + this, + result + ) + } + } + + private fun getEtText(et: EditText): String { + return et.text.toString().trim() + } + + /** + * 返回mm的D + */ + private fun getD(value: String): Double { + return value.toDouble() * 1000 + } + + private fun startRollBack() { + val findRollBackData = viewModel.findRollBackData() + if (findRollBackData == null) { + ToastUtils.showShort("没有可以回退的数据") + return + } + + val deleteStationShow = + LevelIDetectionConstant.getStationTypeShow(findRollBackData.currentStationType) + val deleteRuleShow = + LevelIDetectionConstant.getRulerTypeShow(findRollBackData.currentRulerType) + + val hint = "回退操作将删除 $deleteStationShow $deleteRuleShow 的数据,您是否还要回退?" + + showConfirmDialog(hint) { + viewModel.deleteStationRulerData(findRollBackData) { + refreshAdapterAndButton() + } + } + } + + override fun initView() { + EventBus.getDefault().register(this) + levelReceiveData.onStart() + initAdapter() + + initListener() + + viewModel.getGetDadaAuto(getIDetectionId()) { + refreshManuleAutoInput(it) + } + } + + private fun initListener() { + mBinding.llStation.setOnClickListener { + if (adapter.itemCount == 0) { + ToastUtils.showShort("数据加载中,请稍后尝试") + return@setOnClickListener + } + BaseSelectItemFragment.select( + SelectIDetectionStationFragment(), + supportFragmentManager, + this, object : BaseSelectItemFragment.ISelectItem { + override fun onBack(value: String) { + //value stationType + viewModel.switchStation(value.toInt()) + setCurrentStation() + refreshAdapterAndButton() + } + }) + } + + mBinding.llMeasureType.setOnClickListener { + BaseSelectItemFragment.select( + SelectIDetectionStationMeasureTypeFragment(), + supportFragmentManager, + this, object : BaseSelectItemFragment.ISelectItem { + override fun onBack(value: String) { + switchMeasureType(value) + } + }) + } + + mBinding.surveyor.setOnClickListener { + stationSettingCheckUtil.checkStationSettingsIDetection( + getIDetectionId(), + this, + this::runOnUiThread + ) { + levelReceiveData.requeset() + } + } + + mBinding.btnInput.setOnClickListener { + LevelInputFragment.show( + supportFragmentManager, this + ) { distance: Double, height: Double -> + receiveData(LevelReceiveData(height, distance)) + } + } + } + + private fun receiveData(data: LevelReceiveData) { + if (isFinishing || isDestroyed) { + return + } + viewModel.receiveData(data.height, data.distance) + refreshAdapterAndButton() + } + + /** + * 切换测量方法带存储 + */ + private fun switchMeasureType(measureType: String) { + setCurrentMeasureType(measureType) + viewModel.saveMeasureType(getIDetectionId(), measureType) + } + + private fun setCurrentMeasureType(measureType: String?) { + mBinding.tvMeasureType.text = measureType + viewModel.measureType = measureType + } + + private fun setCurrentStation() { + val stationTypeShow = + LevelIDetectionConstant.getStationTypeShow(surveyorData.currentStationType) + mBinding.tvStation.text = stationTypeShow + } + + private fun initAdapter() { + mBinding.recyclerView.adapter = adapter + mBinding.recyclerView.addItemDecoration( + DefaultItemDecoration( + Tools.getColor(R.color.transparent), + 1, + ScreenUtil.dp2px(this, 10f) + ) + ) + } + + override fun initData() { + viewModel.initData(surveyorData) { + adapter.setStationSetting(viewModel.stationSetting) + + setCurrentStation() + + if (it.measureType == null) { + switchMeasureType(I_A_B_I) + } else { + setCurrentMeasureType(it.measureType) + } + + //设置短长距 + setShortLongDistance(it) + + refreshButton() + + adapter.refreshData(viewModel.dataListAdapter) + } + } + + private fun setShortLongDistance(it: LevelIDetectionList) { + mBinding.etShortDistance.setText(it.shortDistance) + mBinding.etLongDistance.setText(it.longDistance) + } + + private fun getIDetectionId() = intent.getStringExtra(BundleConstants.KEY_I_DETECTION_ID)!! + + + private fun showConfirmDialog(content: String, callback: TipsFragment.IConfirmCallback) { + TipsFragment.cancelAbleTips( + supportFragmentManager, this, this, + content, -1, callback + ) + } + + private fun refreshAdapterAndButton() { + adapter.notifyDataSetChanged() + refreshButton() + } + + private fun refreshButton() { + //刷新测量按钮 + setViewEnable(mBinding.surveyor, surveyorData.isHaveSurveyor()) + setViewEnable(mBinding.btnInput, surveyorData.isHaveSurveyor()) + } + + private fun setViewEnable(view: View, measureEnable: Boolean) { + view.isEnabled = measureEnable + if (measureEnable) { + view.alpha = 1f + } else { + view.alpha = .4f + } + } + + private fun refreshManuleAutoInput(receiveDataTypeAuto: Boolean) { + if (receiveDataTypeAuto) { + mBinding.surveyor.visibility = View.VISIBLE + mBinding.btnInput.visibility = View.GONE + } else { + mBinding.btnInput.visibility = View.VISIBLE + mBinding.surveyor.visibility = View.GONE + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/LevelIDetectionSampleActivity.kt b/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/LevelIDetectionSampleActivity.kt new file mode 100644 index 0000000..f223be4 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/LevelIDetectionSampleActivity.kt @@ -0,0 +1,31 @@ +package com.bingce.controlnetwork.func.level.idetection + +import android.content.Context +import android.content.Intent +import com.bingce.controlnetwork.databinding.ActivityLevelIDetectionSampleBinding +import com.bingce.controlnetwork.newui.base.BaseBindingActivity + +/** + * 水准i角检测示例图 + */ +class LevelIDetectionSampleActivity : BaseBindingActivity() { + + companion object { + @JvmStatic + fun launch(context: Context) { + context.startActivity(Intent(context, LevelIDetectionSampleActivity::class.java)) + } + } + + override fun getBinding(): ActivityLevelIDetectionSampleBinding { + return ActivityLevelIDetectionSampleBinding.inflate(layoutInflater) + } + + override fun initView() { + + } + + override fun initData() { + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/LevelIDetectionStationSettingActivity.kt b/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/LevelIDetectionStationSettingActivity.kt new file mode 100644 index 0000000..fa3f9f4 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/LevelIDetectionStationSettingActivity.kt @@ -0,0 +1,173 @@ +package com.bingce.controlnetwork.func.level.idetection + +import android.content.Context +import android.content.Intent +import android.text.TextUtils +import android.view.Menu +import android.view.MenuItem +import android.widget.ArrayAdapter +import androidx.lifecycle.lifecycleScope +import blankj.utilcode.util.ToastUtils +import com.bingce.controlnetwork.func.level.constant.LevelStationSettingContant +import com.bingce.controlnetwork.func.level.util.LevelStationSettingUtil +import com.bingce.controlapphelper.datasource.database.leveling.LevelingDbFactory +import com.bingce.controlapphelper.datasource.database.leveling.idetection.isetting.LevelIDetectionSetting +import com.bingce.controlapphelper.model.BundleConstants +import com.bingce.controlnetwork.R +import com.bingce.controlnetwork.databinding.ActivityLevelIDetectionStationSettingBinding +import com.bingce.controlnetwork.event.RefreshEvent +import com.bingce.controlnetwork.newui.base.BaseBindingActivity +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import org.greenrobot.eventbus.EventBus + +/** + * i角检测测站设置 + */ +class LevelIDetectionStationSettingActivity : + BaseBindingActivity() { + + companion object { + @JvmStatic + fun launch(context: Context, iDetectionId: String) { + context.startActivity( + Intent( + context, + LevelIDetectionStationSettingActivity::class.java + ).apply { + putExtra(BundleConstants.KEY_I_DETECTION_ID, iDetectionId) + }) + } + } + + override fun getBinding(): ActivityLevelIDetectionStationSettingBinding { + return ActivityLevelIDetectionStationSettingBinding.inflate(layoutInflater) + } + + override fun initView() { + initEditTextTitle() + initSpinnerImaging() + } + + override fun initData() { + getEditData() + } + + private fun getEditData() { + lifecycleScope.launch(Dispatchers.IO) { + val iDetectionId = getIDetectionId() + val record = + LevelingDbFactory.instance.iDetectionSettingDataSource.getByIDetectionId( + iDetectionId + ) + + if (record != null) { + withContext(Dispatchers.Main) { + setData(record) + } + } + } + } + + /** + * 初始化editText坐标的title + */ + private fun initEditTextTitle() { + mBinding.ilWatcher.tvTitle.text = "观测者" + mBinding.ilRecorder.tvTitle.text = "记录者" + mBinding.ilExaminer.tvTitle.text = "检查者" + mBinding.ilRuler1.tvTitle.text = "尺一编号" + mBinding.ilRuler2.tvTitle.text = "尺二编号" + mBinding.ilInstrumentModel.tvTitle.text = "仪器型号" + mBinding.ilDeviceNumber.tvTitle.text = "仪器编号" + } + + private fun setData(record: LevelIDetectionSetting) { + mBinding.ilWatcher.editText.setText(record.watcher) + mBinding.ilRecorder.editText.setText(record.recorder) + mBinding.ilExaminer.editText.setText(record.examiner) + mBinding.ilRuler1.editText.setText(record.rulerNum1) + mBinding.ilRuler2.editText.setText(record.rulerNum2) + mBinding.ilInstrumentModel.editText.setText(record.instrumentModel) + mBinding.ilDeviceNumber.editText.setText(record.deviceNumber) + mBinding.spinnerImaging.setSelection(LevelStationSettingContant.imagingList.indexOf(record.imaging)) + } + + override fun onCreateOptionsMenu(menu: Menu?): Boolean { + menuInflater.inflate(R.menu.menu_save, menu) + return super.onCreateOptionsMenu(menu) + } + + override fun onOptionsItemSelected(item: MenuItem): Boolean { + if (item.itemId == R.id.menuSave) { + startSave() + } + return super.onOptionsItemSelected(item) + } + + private fun initSpinnerImaging() { + mBinding.spinnerImaging.adapter = ArrayAdapter( + this, + android.R.layout.simple_list_item_1, + LevelStationSettingContant.imagingList + ) + } + + private fun startSave() { + val watcher = mBinding.ilWatcher.editText.text.toString().trim() + val recorder = mBinding.ilRecorder.editText.text.toString().trim() + val examiner = mBinding.ilExaminer.editText.text.toString().trim() + val ruler1 = mBinding.ilRuler1.editText.text.toString().trim() + val ruler2 = mBinding.ilRuler2.editText.text.toString().trim() + val instrumentModel = mBinding.ilInstrumentModel.editText.text.toString().trim() + val deviceNumber = mBinding.ilDeviceNumber.editText.text.toString().trim() + val imaging = LevelStationSettingUtil.getSpinnerText(mBinding.spinnerImaging) + + if (isEmpty(ruler1)) { + ToastUtils.showShort("请输入尺一编号") + return + } + if (isEmpty(ruler2)) { + ToastUtils.showShort("请输入尺二编号") + return + } + + lifecycleScope.launch(Dispatchers.IO) { + val iDetectionId = getIDetectionId() + val record = + LevelingDbFactory.instance.iDetectionSettingDataSource.getByIDetectionId( + iDetectionId + ) + + val saveRecord = record ?: LevelIDetectionSetting(iDetectionId) + + saveRecord.watcher = watcher + saveRecord.recorder = recorder + saveRecord.examiner = examiner + saveRecord.rulerNum1 = ruler1 + saveRecord.rulerNum2 = ruler2 + saveRecord.instrumentModel = instrumentModel + saveRecord.deviceNumber = deviceNumber + saveRecord.imaging = imaging + + if (record == null) { + LevelingDbFactory.instance.iDetectionSettingDataSource.save(saveRecord) + } else { + LevelingDbFactory.instance.iDetectionSettingDataSource.update(saveRecord) + } + + EventBus.getDefault() + .post(RefreshEvent(RefreshEvent.REFRESH_BY_LEVEL_I_DETECTION_SETTING_UPDATE, null)) + + finish() + } + + } + + private fun isEmpty(value: String?) = TextUtils.isEmpty(value) + + + private fun getIDetectionId() = intent.getStringExtra(BundleConstants.KEY_I_DETECTION_ID)!! + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/LevelIDetectionSurveyorData.kt b/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/LevelIDetectionSurveyorData.kt new file mode 100644 index 0000000..d7b9782 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/LevelIDetectionSurveyorData.kt @@ -0,0 +1,14 @@ +package com.bingce.controlnetwork.func.level.idetection + +import com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant + +/** + * 当前测量的测站,尺子,第几个 + */ +class LevelIDetectionSurveyorData(val currentIDetectionId: String) { + var currentStationType = LevelIDetectionConstant.STATION_TYPE_0 + var currentMeasureTime = LevelIDetectionConstant.MEASURE_TIME_0 + var currentRulerType = -1//默认不选中尺寸,因为可能已经测完 + + fun isHaveSurveyor() = currentRulerType != -1 +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/adapter/LevelIDetectionListAdapter.java b/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/adapter/LevelIDetectionListAdapter.java new file mode 100644 index 0000000..d102e9f --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/adapter/LevelIDetectionListAdapter.java @@ -0,0 +1,34 @@ +package com.bingce.controlnetwork.func.level.idetection.adapter; + +import android.content.Context; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; + +import com.bingce.controlapphelper.datasource.database.leveling.idetection.list.LevelIDetectionList; +import com.bingce.controlnetwork.databinding.ItemLevelIDetectionListBinding; +import com.bingce.controlnetwork.newui.adapter.BaseAdapterNew; + + +/** + * i角检测列表 + */ +public class LevelIDetectionListAdapter extends BaseAdapterNew { + + public LevelIDetectionListAdapter(Context context) { + super(context); + } + + @Override + protected void onBindViewHolderDo(LevelIDetectionListHolder holder, int position) { + LevelIDetectionList bean = mDataList.get(position); + holder.mBinding.tvIndex.setText(String.valueOf(position + 1)); + holder.mBinding.tvName.setText(bean.name); + } + + @NonNull + @Override + public LevelIDetectionListHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + return new LevelIDetectionListHolder(ItemLevelIDetectionListBinding.inflate(getInflater(), parent, false)); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/adapter/LevelIDetectionListHolder.java b/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/adapter/LevelIDetectionListHolder.java new file mode 100644 index 0000000..9fcdb78 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/adapter/LevelIDetectionListHolder.java @@ -0,0 +1,15 @@ +package com.bingce.controlnetwork.func.level.idetection.adapter; + +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlnetwork.databinding.ItemLevelIDetectionListBinding; + + +public class LevelIDetectionListHolder extends RecyclerView.ViewHolder { + public final ItemLevelIDetectionListBinding mBinding; + + public LevelIDetectionListHolder(ItemLevelIDetectionListBinding binding) { + super(binding.getRoot()); + mBinding = binding; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/adapter/LevelIDetectionRecordAdapter.java b/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/adapter/LevelIDetectionRecordAdapter.java new file mode 100644 index 0000000..e7092b8 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/adapter/LevelIDetectionRecordAdapter.java @@ -0,0 +1,120 @@ +package com.bingce.controlnetwork.func.level.idetection.adapter; + +import static com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant.MEASURE_TIME_0; +import static com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant.MEASURE_TIME_1; +import static com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant.MEASURE_TIME_2; +import static com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant.MEASURE_TIME_3; +import static com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant.MEASURE_TIME_4; +import static com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant.RULER_TYPE_0; +import static com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant.RULER_TYPE_1; + +import android.content.Context; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; + +import com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant; +import com.bingce.controlapphelper.datasource.database.leveling.idetection.isetting.LevelIDetectionSetting; +import com.bingce.controlapphelper.datasource.database.leveling.idetection.record.LevelIDetectionRecord; +import com.bingce.controlapphelper.leveling.detaction.LevelFormatUtil; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.databinding.ItemLevelIDetectionRecordBinding; +import com.bingce.controlnetwork.newui.adapter.BaseAdapterNew; + +import java.util.Map; + +import com.bingce.controlnetwork.func.level.idetection.LevelIDetectionSurveyorData; + + +/** + * i角检测列表 + */ +public class LevelIDetectionRecordAdapter extends BaseAdapterNew> { + + private final LevelIDetectionSurveyorData surveyorData; + private LevelIDetectionSetting stationSetting; + + public LevelIDetectionRecordAdapter(Context context, LevelIDetectionSurveyorData surveyorData) { + super(context); + this.surveyorData = surveyorData; + } + + @NonNull + @Override + public LevelIDetectionRecordHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + return new LevelIDetectionRecordHolder(ItemLevelIDetectionRecordBinding.inflate(getInflater(), parent, false)); + } + + @Override + protected void onBindViewHolderDo(LevelIDetectionRecordHolder holder, int position) { + Map recordMap = mDataList.get(0); + + //尺子 + int rulerType; + if (position == 0) { + rulerType = RULER_TYPE_0; + } else { + rulerType = RULER_TYPE_1; + } + + + //当前测的尺子选中 + boolean isSelect = rulerType == surveyorData.getCurrentRulerType(); + if (isSelect) { + holder.mBinding.getRoot().setBackgroundDrawable(Tools.getDrawable(R.drawable.select_mask)); + } else { + holder.mBinding.getRoot().setBackgroundColor(Tools.getColor(R.color.white)); + } + + LevelIDetectionRecord record1 = getRecord(recordMap, rulerType, MEASURE_TIME_0); + LevelIDetectionRecord record2 = getRecord(recordMap, rulerType, MEASURE_TIME_1); + LevelIDetectionRecord record3 = getRecord(recordMap, rulerType, MEASURE_TIME_2); + LevelIDetectionRecord record4 = getRecord(recordMap, rulerType, MEASURE_TIME_3); + LevelIDetectionRecord record5 = getRecord(recordMap, rulerType, MEASURE_TIME_4); + + //尺几 + holder.mBinding.tvRulerType.setText(LevelIDetectionConstant.getRulerTypeShow(rulerType)); + //尺号 + holder.mBinding.tvRulerNum.setText(LevelIDetectionConstant.getRulerNumShow(rulerType, stationSetting)); + + holder.mBinding.tvHeight1.setText(getHeight(record1)); + holder.mBinding.tvDistance1.setText(getDistance(record1)); + holder.mBinding.tvHeight2.setText(getHeight(record2)); + holder.mBinding.tvDistance2.setText(getDistance(record2)); + holder.mBinding.tvHeight3.setText(getHeight(record3)); + holder.mBinding.tvDistance3.setText(getDistance(record3)); + holder.mBinding.tvHeight4.setText(getHeight(record4)); + holder.mBinding.tvDistance4.setText(getDistance(record4)); + holder.mBinding.tvHeight5.setText(getHeight(record5)); + holder.mBinding.tvDistance5.setText(getDistance(record5)); + } + + private LevelIDetectionRecord getRecord(Map map, int rulerType, int measureTime) { + String recordId = LevelIDetectionRecord.getRecordId(surveyorData.getCurrentIDetectionId(), surveyorData.getCurrentStationType(), rulerType, measureTime); + return map.get(recordId); + } + + private String getHeight(LevelIDetectionRecord record) { + if (record == null) { + return ""; + } + return LevelFormatUtil.INSTANCE.formatHeight(record.height); + } + + private String getDistance(LevelIDetectionRecord record) { + if (record == null) { + return ""; + } + return LevelFormatUtil.INSTANCE.formatDistance(record.distance); + } + + @Override + public int getItemCount() { + return mDataList == null ? 0 : 2; + } + + public void setStationSetting(LevelIDetectionSetting stationSetting) { + this.stationSetting = stationSetting; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/adapter/LevelIDetectionRecordHolder.java b/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/adapter/LevelIDetectionRecordHolder.java new file mode 100644 index 0000000..271baf5 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/adapter/LevelIDetectionRecordHolder.java @@ -0,0 +1,15 @@ +package com.bingce.controlnetwork.func.level.idetection.adapter; + +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlnetwork.databinding.ItemLevelIDetectionRecordBinding; + + +public class LevelIDetectionRecordHolder extends RecyclerView.ViewHolder { + public final ItemLevelIDetectionRecordBinding mBinding; + + public LevelIDetectionRecordHolder(ItemLevelIDetectionRecordBinding binding) { + super(binding.getRoot()); + mBinding = binding; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/util/LevelIDetectionFindUtil.kt b/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/util/LevelIDetectionFindUtil.kt new file mode 100644 index 0000000..762300b --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/util/LevelIDetectionFindUtil.kt @@ -0,0 +1,247 @@ +package com.bingce.controlnetwork.func.level.idetection.util + +import com.bingce.controlnetwork.func.level.idetection.LevelIDetectionSurveyorData +import com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant.MEASURE_TIME_0 +import com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant.MEASURE_TIME_1 +import com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant.MEASURE_TIME_2 +import com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant.MEASURE_TIME_3 +import com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant.MEASURE_TIME_4 +import com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant.RULER_TYPE_0 +import com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant.RULER_TYPE_1 +import com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant.STATION_TYPE_0 +import com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant.STATION_TYPE_1 +import com.bingce.controlapphelper.datasource.database.leveling.idetection.record.LevelIDetectionRecord + +/** + * 查找工具 + */ +class LevelIDetectionFindUtil { + + fun getFindMeasureList(iDetectionId: String): List { + val station1 = STATION_TYPE_0 + val station2 = STATION_TYPE_1 + val ruler1 = RULER_TYPE_0 + val ruler2 = RULER_TYPE_1 + val measureTime1 = MEASURE_TIME_0 + val measureTime2 = MEASURE_TIME_1 + val measureTime3 = MEASURE_TIME_2 + val measureTime4 = MEASURE_TIME_3 + val measureTime5 = MEASURE_TIME_4 + + return listOf( + LevelIDetectionRecord.create( + iDetectionId, + station1, + ruler1, + measureTime1 + ), + LevelIDetectionRecord.create( + iDetectionId, + station1, + ruler1, + measureTime2 + ), + LevelIDetectionRecord.create( + iDetectionId, + station1, + ruler1, + measureTime3 + ), + LevelIDetectionRecord.create( + iDetectionId, + station1, + ruler1, + measureTime4 + ), + LevelIDetectionRecord.create( + iDetectionId, + station1, + ruler1, + measureTime5 + ), + LevelIDetectionRecord.create( + iDetectionId, + station1, + ruler2, + measureTime1 + ), + LevelIDetectionRecord.create( + iDetectionId, + station1, + ruler2, + measureTime2 + ), + LevelIDetectionRecord.create( + iDetectionId, + station1, + ruler2, + measureTime3 + ), + LevelIDetectionRecord.create( + iDetectionId, + station1, + ruler2, + measureTime4 + ), + LevelIDetectionRecord.create( + iDetectionId, + station1, + ruler2, + measureTime5 + ), + LevelIDetectionRecord.create( + iDetectionId, + station2, + ruler1, + measureTime1 + ), + LevelIDetectionRecord.create( + iDetectionId, + station2, + ruler1, + measureTime2 + ), + LevelIDetectionRecord.create( + iDetectionId, + station2, + ruler1, + measureTime3 + ), + LevelIDetectionRecord.create( + iDetectionId, + station2, + ruler1, + measureTime4 + ), + LevelIDetectionRecord.create( + iDetectionId, + station2, + ruler1, + measureTime5 + ), + LevelIDetectionRecord.create( + iDetectionId, + station2, + ruler2, + measureTime1 + ), + LevelIDetectionRecord.create( + iDetectionId, + station2, + ruler2, + measureTime2 + ), + LevelIDetectionRecord.create( + iDetectionId, + station2, + ruler2, + measureTime3 + ), + LevelIDetectionRecord.create( + iDetectionId, + station2, + ruler2, + measureTime4 + ), + LevelIDetectionRecord.create( + iDetectionId, + station2, + ruler2, + measureTime5 + ) + ) + } + + fun getFindMeasureList( + iDetectionId: String, + stationType: Int + ): List { + val ruler1 = RULER_TYPE_0 + val ruler2 = RULER_TYPE_1 + val measureTime1 = MEASURE_TIME_0 + val measureTime2 = MEASURE_TIME_1 + val measureTime3 = MEASURE_TIME_2 + val measureTime4 = MEASURE_TIME_3 + val measureTime5 = MEASURE_TIME_4 + + return listOf( + LevelIDetectionRecord.create( + iDetectionId, + stationType, + ruler1, + measureTime1 + ), + LevelIDetectionRecord.create( + iDetectionId, + stationType, + ruler1, + measureTime2 + ), + LevelIDetectionRecord.create( + iDetectionId, + stationType, + ruler1, + measureTime3 + ), + LevelIDetectionRecord.create( + iDetectionId, + stationType, + ruler1, + measureTime4 + ), + LevelIDetectionRecord.create( + iDetectionId, + stationType, + ruler1, + measureTime5 + ), + LevelIDetectionRecord.create( + iDetectionId, + stationType, + ruler2, + measureTime1 + ), + LevelIDetectionRecord.create( + iDetectionId, + stationType, + ruler2, + measureTime2 + ), + LevelIDetectionRecord.create( + iDetectionId, + stationType, + ruler2, + measureTime3 + ), + LevelIDetectionRecord.create( + iDetectionId, + stationType, + ruler2, + measureTime4 + ), + LevelIDetectionRecord.create( + iDetectionId, + stationType, + ruler2, + measureTime5 + ) + ) + } + + fun find( + recordList: List, + findCase: (LevelIDetectionRecord) -> Boolean + ): LevelIDetectionSurveyorData? { + for (record in recordList) { + if (findCase(record)) { + val surveyorData = LevelIDetectionSurveyorData("") + surveyorData.currentStationType = record.stationType + surveyorData.currentRulerType = record.rulerType + surveyorData.currentMeasureTime = record.measureTime + return surveyorData + } + } + return null + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/viewmodel/LevelIDetectionListVm.kt b/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/viewmodel/LevelIDetectionListVm.kt new file mode 100644 index 0000000..274e192 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/viewmodel/LevelIDetectionListVm.kt @@ -0,0 +1,39 @@ +package com.bingce.controlnetwork.func.level.idetection.viewmodel + +import androidx.lifecycle.LiveData +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.bingce.controlapphelper.datasource.database.leveling.LevelingDbFactory +import com.bingce.controlapphelper.datasource.database.leveling.idetection.list.LevelIDetectionList +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch + +class LevelIDetectionListVm : ViewModel() { + + fun getListLiveData(projectId: String): LiveData> { + return LevelingDbFactory.instance.iDetectionListDataSource.getListByProjectIdDescLiveData( + projectId + ) + } + + /** + * 创建i角检测 + */ + fun saveNewRecord(projectId: String, name: String) { + viewModelScope.launch(Dispatchers.IO) { + val bean = LevelIDetectionList.create(projectId, name) + LevelingDbFactory.instance.iDetectionListDataSource.save(bean) + } + } + + /** + * 创建i角检测 + */ + fun deleteRecord(bean: LevelIDetectionList) { + viewModelScope.launch(Dispatchers.IO) { + LevelingDbFactory.instance.iDetectionListDataSource.delete(bean) + } + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/viewmodel/LevelIDetectionRecordVm.kt b/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/viewmodel/LevelIDetectionRecordVm.kt new file mode 100644 index 0000000..8bad019 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/idetection/viewmodel/LevelIDetectionRecordVm.kt @@ -0,0 +1,361 @@ +package com.bingce.controlnetwork.func.level.idetection.viewmodel + +import androidx.annotation.WorkerThread +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import blankj.utilcode.util.ToastUtils +import com.bingce.controlnetwork.func.level.idetection.LevelIDetectionCalUtil +import com.bingce.controlnetwork.func.level.idetection.LevelIDetectionSurveyorData +import com.bingce.controlnetwork.func.level.idetection.util.LevelIDetectionFindUtil +import com.bingce.controlapphelper.datasource.database.leveling.LevelingDb +import com.bingce.controlapphelper.datasource.database.leveling.LevelingDbFactory +import com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant +import com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant.MEASURE_TIME_0 +import com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant.MEASURE_TIME_1 +import com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant.MEASURE_TIME_2 +import com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant.MEASURE_TIME_3 +import com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant.MEASURE_TIME_4 +import com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant.RULER_TYPE_1 +import com.bingce.controlapphelper.datasource.database.leveling.idetection.isetting.LevelIDetectionSetting +import com.bingce.controlapphelper.datasource.database.leveling.idetection.list.LevelIDetectionList +import com.bingce.controlapphelper.datasource.database.leveling.idetection.record.LevelIDetectionRecord +import com.bingce.controlapphelper.leveling.detaction.LevelFormatUtil +import com.bingce.controlapphelper.util.Tools +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + +class LevelIDetectionRecordVm : ViewModel() { + + //key 记录id + val dataListAdapter = mutableListOf>() + + //key 记录id + private val stationRecordMap = hashMapOf() + + lateinit var surveyorData: LevelIDetectionSurveyorData + + var measureType: String? = null + + var stationSetting: LevelIDetectionSetting? = null + + val findUtil = LevelIDetectionFindUtil() + + fun initData( + surveyorData: LevelIDetectionSurveyorData, + callBack: (LevelIDetectionList) -> Unit + ) { + this.surveyorData = surveyorData + viewModelScope.launch(Dispatchers.IO) { + dataListAdapter.clear() + dataListAdapter.add(stationRecordMap) + val records = + LevelingDbFactory.instance.iDetectionRecordDataSource.getRecordsByIDetectionId( + surveyorData.currentIDetectionId + ) + //更新测站设置 + updateStationSetting() + + for (record in records) { + stationRecordMap[record.id] = record + } + + //查询第一个需要测量的数据 + val findMeasureDataAll = findMeasureDataAll() + if (findMeasureDataAll != null) { + changeCurrentSurveyorData(findMeasureDataAll) + } + + val iDetectionRecord = + LevelingDbFactory.instance.iDetectionListDataSource.getById(surveyorData.currentIDetectionId) + + withContext(Dispatchers.Main) { + callBack(iDetectionRecord) + } + } + } + + /** + * 存数据 + */ + fun receiveData(height: Double, distance: Double) { + if (surveyorData.currentRulerType == -1) { + ToastUtils.showShort("未找到观测尺") + return + } + + //存当前测量的数据 + val recordId = LevelIDetectionRecord.getRecordId( + surveyorData.currentIDetectionId, + surveyorData.currentStationType, + surveyorData.currentRulerType, + surveyorData.currentMeasureTime + ) + val record = LevelIDetectionRecord.create( + surveyorData.currentIDetectionId, surveyorData.currentStationType, + surveyorData.currentRulerType, surveyorData.currentMeasureTime, + height, distance + ) + + stationRecordMap[recordId] = record + + //测完一个数据更新尺子和测量次数 + if (surveyorData.currentMeasureTime == MEASURE_TIME_4) { + //最后一个测完了 + if (surveyorData.currentRulerType == RULER_TYPE_1) { + //该站全部测完 + surveyorData.currentRulerType = -1 + surveyorData.currentMeasureTime = MEASURE_TIME_0 + + Tools.speak("该测站测量完毕") + } else { + //一尺测量完 + surveyorData.currentRulerType = RULER_TYPE_1 + surveyorData.currentMeasureTime = MEASURE_TIME_0 + Tools.speak("尺一测量完毕") + } + } else { + //不是最后一次直接加 + surveyorData.currentMeasureTime++ + if (surveyorData.currentMeasureTime > MEASURE_TIME_4) { + surveyorData.currentMeasureTime = MEASURE_TIME_4 + } + } + + //存数据库 + viewModelScope.launch(Dispatchers.IO) { + LevelingDb.getInstance().iDetectionRecordDao().save(record) + } + } + + /** + * 找第一个没有数据的 + */ + private fun findMeasureDataAll(): LevelIDetectionSurveyorData? { + val recordList = findUtil.getFindMeasureList(surveyorData.currentIDetectionId) + return findUtil.find(recordList) { + stationRecordMap[it.id] == null + } + } + + /** + * 找第一个没有数据的 + */ + fun switchStation(stationType: Int) { + val recordList = findUtil.getFindMeasureList(surveyorData.currentIDetectionId, stationType) + val find = findUtil.find(recordList) { + stationRecordMap[it.id] == null + } + if (find != null) { + changeCurrentSurveyorData(find) + } else { + val surveyorData = LevelIDetectionSurveyorData("") + surveyorData.currentStationType = stationType + changeCurrentSurveyorData(surveyorData) + } + } + + private fun changeCurrentSurveyorData(surveyorData: LevelIDetectionSurveyorData) { + this.surveyorData.currentStationType = surveyorData.currentStationType + this.surveyorData.currentRulerType = surveyorData.currentRulerType + this.surveyorData.currentMeasureTime = surveyorData.currentMeasureTime + } + + /** + * 找最后一个有数据的 + */ + fun findRollBackData(): LevelIDetectionSurveyorData? { + val recordList = findUtil.getFindMeasureList( + surveyorData.currentIDetectionId, + surveyorData.currentStationType + ).reversed() + return findUtil.find(recordList) { + stationRecordMap[it.id] != null + } + } + + + /** + * 回退删除数据 + * 一次删一个测站的一个尺子的数据 + */ + fun deleteStationRulerData(findRollBackData: LevelIDetectionSurveyorData, success: () -> Unit) { + viewModelScope.launch(Dispatchers.IO) { + val deleteIDetectionId = surveyorData.currentIDetectionId + val deleteStationType = findRollBackData.currentStationType + val deleteRulerType = findRollBackData.currentRulerType + + val recordId1 = LevelIDetectionRecord.getRecordId( + deleteIDetectionId, + deleteStationType, + deleteRulerType, + MEASURE_TIME_0 + ) + val recordId2 = LevelIDetectionRecord.getRecordId( + deleteIDetectionId, + deleteStationType, + deleteRulerType, + MEASURE_TIME_1 + ) + val recordId3 = LevelIDetectionRecord.getRecordId( + deleteIDetectionId, + deleteStationType, + deleteRulerType, + MEASURE_TIME_2 + ) + val recordId4 = LevelIDetectionRecord.getRecordId( + deleteIDetectionId, + deleteStationType, + deleteRulerType, + MEASURE_TIME_3 + ) + val recordId5 = LevelIDetectionRecord.getRecordId( + deleteIDetectionId, + deleteStationType, + deleteRulerType, + MEASURE_TIME_4 + ) + //删除缓存 + stationRecordMap.remove(recordId1) + stationRecordMap.remove(recordId2) + stationRecordMap.remove(recordId3) + stationRecordMap.remove(recordId4) + stationRecordMap.remove(recordId5) + //删除数据 + LevelingDbFactory.instance.iDetectionRecordDataSource.deleteById(recordId1) + LevelingDbFactory.instance.iDetectionRecordDataSource.deleteById(recordId2) + LevelingDbFactory.instance.iDetectionRecordDataSource.deleteById(recordId3) + LevelingDbFactory.instance.iDetectionRecordDataSource.deleteById(recordId4) + LevelingDbFactory.instance.iDetectionRecordDataSource.deleteById(recordId5) + + //确定要测哪个 + findRollBackData.currentMeasureTime = MEASURE_TIME_0 + changeCurrentSurveyorData(findRollBackData) + + withContext(Dispatchers.Main) { + success() + } + } + } + + /** + * 保存测量方式 + */ + fun saveMeasureType(iDetectionId: String, measureType: String) { + viewModelScope.launch(Dispatchers.IO) { + val record = + LevelingDbFactory.instance.iDetectionListDataSource.getById(iDetectionId) + record.measureType = measureType + LevelingDbFactory.instance.iDetectionListDataSource.update(record) + } + } + + /** + * 单位mm + * d1短距 + * d2长距 + */ + fun startResult(d1: Double, d2: Double): String? { + val findMeasureList = findUtil.getFindMeasureList(surveyorData.currentIDetectionId) + for (needCheckItem in findMeasureList) { + val levelIDetectionRecord = stationRecordMap[needCheckItem.id] + if (levelIDetectionRecord == null) { + ToastUtils.showShort(LevelIDetectionConstant.getStationTypeShow(needCheckItem.stationType) + "数据不完整") + return null + } + } + + val iResult = LevelIDetectionCalUtil.getIResult( + surveyorData.currentIDetectionId, + measureType!!, + d1, + d2, + stationRecordMap + ) + + val hint = if (iResult.isFinite()) { + val formatAngle = LevelFormatUtil.formatAngle(iResult) + saveIResult(formatAngle) + if (iResult > 15) { + "i角计算结果:$formatAngle\"\n大于15\",请校正仪器" + } else { + "i角计算结果:$formatAngle\"\n合限" + } + } else { + saveIResult(null) + "i角计算结果:数据异常,请检查" + } + return hint + } + + /** + * 存短长距和测量方法 + * 这些变化快,统一存 + */ + private fun saveIResult(iResult: String?) { + viewModelScope.launch(Dispatchers.IO) { + val iDetectionItem = + LevelingDbFactory.instance.iDetectionListDataSource.getById(surveyorData.currentIDetectionId) + iDetectionItem.iResult = iResult + LevelingDbFactory.instance.iDetectionListDataSource.update(iDetectionItem) + } + } + + /** + * 存短长距和测量方法 + * 这些变化快,统一存 + */ + fun saveShortLongDistanceMeasureType(d1Short: String, d2Long: String) { + viewModelScope.launch(Dispatchers.IO) { + val iDetectionItem = + LevelingDbFactory.instance.iDetectionListDataSource.getById(surveyorData.currentIDetectionId) + iDetectionItem.shortDistance = d1Short + iDetectionItem.longDistance = d2Long + iDetectionItem.measureType = measureType + LevelingDbFactory.instance.iDetectionListDataSource.update(iDetectionItem) + } + } + + fun getGetDadaAuto(iDetectionId: String, callBack: (Boolean) -> Unit) { + viewModelScope.launch(Dispatchers.IO) { + val record = + LevelingDbFactory.instance.iDetectionSettingDataSource.getByIDetectionId( + iDetectionId + ) + withContext(Dispatchers.Main) { + if (record == null) { + callBack(true) + } else { + callBack(!record.getDataManually) + } + } + } + } + + fun setGetDataAuto(iDetectionId: String, auto: Boolean) { + viewModelScope.launch(Dispatchers.IO) { + var record = + LevelingDbFactory.instance.iDetectionSettingDataSource.getByIDetectionId( + iDetectionId + ) + if (record == null) { + record = LevelIDetectionSetting(iDetectionId) + record.getDataManually = !auto + LevelingDbFactory.instance.iDetectionSettingDataSource.save(record) + } else { + record.getDataManually = !auto + LevelingDbFactory.instance.iDetectionSettingDataSource.update(record) + } + } + } + + @WorkerThread + fun updateStationSetting() { + stationSetting = + LevelingDbFactory.instance.iDetectionSettingDataSource.getByIDetectionId( + surveyorData.currentIDetectionId + ) + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/sendreceive/ILevelBackData.kt b/app/src/main/java/com/bingce/controlnetwork/func/level/sendreceive/ILevelBackData.kt new file mode 100644 index 0000000..ade43ba --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/sendreceive/ILevelBackData.kt @@ -0,0 +1,8 @@ +package com.bingce.controlnetwork.func.level.sendreceive + +import com.bingce.controlapphelper.leveling.detaction.LevelReceiveData + +interface ILevelBackData { + fun receive(data: LevelReceiveData) + fun measureError(msg: String) +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/sendreceive/LevelRequest.kt b/app/src/main/java/com/bingce/controlnetwork/func/level/sendreceive/LevelRequest.kt new file mode 100644 index 0000000..a8bc98e --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/sendreceive/LevelRequest.kt @@ -0,0 +1,84 @@ +package com.bingce.controlnetwork.func.level.sendreceive + +import blankj.utilcode.util.ToastUtils +import com.bingce.controlapphelper.leveling.detaction.LevelReceiveData +import com.bingce.controlnetwork.App + +abstract class LevelRequest(protected val backDataI: ILevelBackData) { + + private var requestTime = 0L + private var requestState = LevelRequestState.INIT + + private val receiveDataList = mutableListOf() + + abstract fun doRequest() + abstract fun onStart() + abstract fun onDestroy() + abstract fun sendCommand() + + + fun requeset() { + if (checkRequestNot()) { + return + } + requestState = LevelRequestState.REQUEST_ING + requestTime = System.currentTimeMillis() + + //获取数据 + doRequest() + } + + private fun checkRequestNot(): Boolean { + val intervalTime = System.currentTimeMillis() - requestTime +// if (intervalTime < 600) { +// return true +// } + if (requestState == LevelRequestState.REQUEST_ING) { + ToastUtils.showShort("测量中,请稍后...") + return true + } + + if (requestState == LevelRequestState.REQUEST_ING) { + if (intervalTime > 20000) { + //超过20秒回复默认状态 + requestState = LevelRequestState.INIT + } + } + return false + } + + protected fun resetInit() { + requestTime = 0 + requestState = LevelRequestState.INIT + } + + protected fun addReceiveData(data: LevelReceiveData) { + receiveDataList.add(data) + } + + protected fun clearReceiveDataList() { + receiveDataList.clear() + } + + protected fun isNeedRequestAgain(): Boolean { + val levelSurveyorTime = App.getApp().levelSurveyorTime.toInt() + return receiveDataList.size < levelSurveyorTime + } + + /** + * 获取返回的数据 + */ + protected fun getBackData(): LevelReceiveData { + var height = 0.0 + var distance = 0.0 + for (item in receiveDataList) { + height += item.height + distance += item.distance + } + val size = receiveDataList.size + return LevelReceiveData(height / size, distance / size) + } + + protected fun hasData() = receiveDataList.isNotEmpty() + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/sendreceive/LevelRequestRelease.kt b/app/src/main/java/com/bingce/controlnetwork/func/level/sendreceive/LevelRequestRelease.kt new file mode 100644 index 0000000..5040e5b --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/sendreceive/LevelRequestRelease.kt @@ -0,0 +1,58 @@ +package com.bingce.controlnetwork.func.level.sendreceive + +import blankj.utilcode.util.ToastUtils +import com.bingce.controlapphelper.leveling.detaction.LevelReceiveData +import com.bingce.device.Device +import com.bingce.level.Level +import com.bingce.level.LevelListener + +/** + * 发布版 + */ +class LevelRequestRelease(backDataI: ILevelBackData) : LevelRequest(backDataI), + LevelListener.LevelReadListener { + + override fun doRequest() { + if (!Device.getInstance().isDeviceConnected) { + ToastUtils.showShort("设备未连接,请连接设备") + resetInit() + return + } + ToastUtils.showShort("开始测量") + sendCommand() + } + + override fun onStart() { + //LevelListener + LevelListener.getInstance().addLevelReadListener(this) + } + + override fun onDestroy() { + LevelListener.getInstance().removeLevelReadListener(this) + } + + override fun onReadSuccess(height: Double, distance: Double) { + addReceiveData(LevelReceiveData(height, distance)) + if (isNeedRequestAgain()) { + sendCommand() + return + } + if (hasData()) { + backDataI.receive(getBackData()) + } + clearReceiveDataList() + resetInit() + } + + override fun onReadFailed(errorCode: String?, errorMsg: String?, original: String?) { + val error = errorMsg ?: "" + backDataI.measureError(error) + clearReceiveDataList() + resetInit() + } + + override fun sendCommand() { + Level.getInstance().requestMeasure() + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/sendreceive/LevelRequestState.kt b/app/src/main/java/com/bingce/controlnetwork/func/level/sendreceive/LevelRequestState.kt new file mode 100644 index 0000000..a4eec44 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/sendreceive/LevelRequestState.kt @@ -0,0 +1,8 @@ +package com.bingce.controlnetwork.func.level.sendreceive + +import androidx.annotation.Keep + +@Keep +enum class LevelRequestState { + INIT,REQUEST_ING +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/sendreceive/LevelRequestTest.kt b/app/src/main/java/com/bingce/controlnetwork/func/level/sendreceive/LevelRequestTest.kt new file mode 100644 index 0000000..2e947a1 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/sendreceive/LevelRequestTest.kt @@ -0,0 +1,175 @@ +package com.bingce.controlnetwork.func.level.sendreceive + +import android.content.res.AssetManager +import android.os.Handler +import android.os.Looper +import android.os.Message +import android.util.Log +import blankj.utilcode.util.ToastUtils +import blankj.utilcode.util.Utils +import com.bingce.controlapphelper.leveling.detaction.LevelReceiveData +import com.bingce.controlapphelper.util.GsonUtil +import com.bingce.path.PathManager +import com.bingce.utils.FileUtil +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.launch +import java.io.BufferedReader +import java.io.File +import java.io.IOException +import java.io.InputStreamReader +import java.nio.charset.StandardCharsets +import java.util.regex.Pattern + + +class LevelRequestTest(backDataI: ILevelBackData) : LevelRequest(backDataI) { + private var dataIndex = 0 + private var dataList = emptyList() + + private val handler = object : Handler(Looper.getMainLooper()) { + override fun handleMessage(msg: Message) { + val data = dataList[dataIndex] + addReceiveData(data) + if (isNeedRequestAgain()) { + dataIndex++ + sendCommand() + return + } + + if (hasData()) { + backDataI.receive(getBackData()) + } + + clearReceiveDataList() + resetInit() + } + } + + init { + GlobalScope.launch(Dispatchers.IO) { + dataList = TestData().getData() + } + } + + override fun doRequest() { + if (dataList.lastIndex < dataIndex) { + ToastUtils.showShort("没有数据了") + return + } + ToastUtils.showShort("开始测量") + sendCommand() + } + + override fun onStart() { + + } + + override fun onDestroy() { + + } + + override fun sendCommand() { + handler.sendEmptyMessageDelayed(0, 500) + } + + fun initTestData(position: Int) { + dataList = TestData().getData(position) + } + +} + +class TestData { + private val data11 = + "[{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0},{\"distance\":1.0,\"height\":1.0}]" + private val dataBFFBNormal = + "[{\"distance\":4.154,\"height\":2.42073},{\"distance\":4.905,\"height\":0.97681},{\"distance\":4.904,\"height\":0.97685},{\"distance\":4.157,\"height\":2.42074},{\"distance\":5.367,\"height\":0.91105},{\"distance\":6.041,\"height\":2.55628},{\"distance\":6.047,\"height\":2.55615},{\"distance\":5.371,\"height\":0.91101},{\"distance\":5.837,\"height\":2.45984},{\"distance\":5.553,\"height\":0.92191},{\"distance\":5.553,\"height\":0.92189},{\"distance\":5.837,\"height\":2.45978},{\"distance\":6.341,\"height\":0.85347},{\"distance\":6.85,\"height\":2.69778},{\"distance\":6.833,\"height\":2.69768},{\"distance\":6.345,\"height\":0.85337},{\"distance\":7.445,\"height\":2.66834},{\"distance\":7.025,\"height\":0.67221},{\"distance\":7.025,\"height\":0.67225},{\"distance\":7.44,\"height\":2.66833},{\"distance\":6.899,\"height\":0.69217},{\"distance\":7.812,\"height\":2.55316},{\"distance\":7.815,\"height\":2.55313},{\"distance\":6.9,\"height\":0.69219},{\"distance\":6.717,\"height\":2.53018},{\"distance\":6.31,\"height\":0.89984},{\"distance\":6.31,\"height\":0.89981},{\"distance\":6.72,\"height\":2.53014},{\"distance\":6.785,\"height\":0.75673},{\"distance\":7.375,\"height\":2.6826},{\"distance\":7.372,\"height\":2.68262},{\"distance\":6.79,\"height\":0.75672},{\"distance\":6.753,\"height\":2.55411},{\"distance\":7.238,\"height\":0.56473}]" + + private val dataBFFBError1 = + "[{\"distance\":4.154,\"height\":2.42073},{\"distance\":4.905,\"height\":0.97681},{\"distance\":5.904,\"height\":1.97685},{\"distance\":5.157,\"height\":3.42074},{\"distance\":5.367,\"height\":0.91105},{\"distance\":6.041,\"height\":2.55628},{\"distance\":6.047,\"height\":2.55615},{\"distance\":5.371,\"height\":0.91101},{\"distance\":5.837,\"height\":2.45984},{\"distance\":5.553,\"height\":0.92191},{\"distance\":5.553,\"height\":0.92189},{\"distance\":5.837,\"height\":2.45978},{\"distance\":6.341,\"height\":0.85347},{\"distance\":6.85,\"height\":2.69778},{\"distance\":6.833,\"height\":2.69768},{\"distance\":6.345,\"height\":0.85337},{\"distance\":7.445,\"height\":2.66834},{\"distance\":7.025,\"height\":0.67221},{\"distance\":7.025,\"height\":0.67225},{\"distance\":7.44,\"height\":2.66833},{\"distance\":6.899,\"height\":0.69217},{\"distance\":7.812,\"height\":2.55316},{\"distance\":7.815,\"height\":2.55313},{\"distance\":6.9,\"height\":0.69219},{\"distance\":6.717,\"height\":2.53018},{\"distance\":6.31,\"height\":0.89984},{\"distance\":6.31,\"height\":0.89981},{\"distance\":6.72,\"height\":2.53014},{\"distance\":6.785,\"height\":0.75673},{\"distance\":7.375,\"height\":2.6826},{\"distance\":7.372,\"height\":2.68262},{\"distance\":6.79,\"height\":0.75672},{\"distance\":6.753,\"height\":2.55411},{\"distance\":7.238,\"height\":0.56473}]" + + private val dataBFFBError2 = + "[{\"distance\":4.154,\"height\":2.42073},{\"distance\":14.905,\"height\":0.97681},{\"distance\":15.904,\"height\":0.97685},{\"distance\":5.157,\"height\":3.42074},{\"distance\":5.367,\"height\":0.91105},{\"distance\":6.041,\"height\":2.55628},{\"distance\":6.047,\"height\":2.55615},{\"distance\":5.371,\"height\":0.91101},{\"distance\":5.837,\"height\":2.45984},{\"distance\":5.553,\"height\":0.92191},{\"distance\":5.553,\"height\":0.92189},{\"distance\":5.837,\"height\":2.45978},{\"distance\":6.341,\"height\":0.85347},{\"distance\":6.85,\"height\":2.69778},{\"distance\":6.833,\"height\":2.69768},{\"distance\":6.345,\"height\":0.85337},{\"distance\":7.445,\"height\":2.66834},{\"distance\":7.025,\"height\":0.67221},{\"distance\":7.025,\"height\":0.67225},{\"distance\":7.44,\"height\":2.66833},{\"distance\":6.899,\"height\":0.69217},{\"distance\":7.812,\"height\":2.55316},{\"distance\":7.815,\"height\":2.55313},{\"distance\":6.9,\"height\":0.69219},{\"distance\":6.717,\"height\":2.53018},{\"distance\":6.31,\"height\":0.89984},{\"distance\":6.31,\"height\":0.89981},{\"distance\":6.72,\"height\":2.53014},{\"distance\":6.785,\"height\":0.75673},{\"distance\":7.375,\"height\":2.6826},{\"distance\":7.372,\"height\":2.68262},{\"distance\":6.79,\"height\":0.75672},{\"distance\":6.753,\"height\":2.55411},{\"distance\":7.238,\"height\":0.56473}]" + + private val dataBFFBError3 = + "[{\"distance\":4.154,\"height\":2.42073},{\"distance\":4.905,\"height\":0.97681},{\"distance\":4.904,\"height\":0.97685},{\"distance\":4.157,\"height\":2.42074},{\"distance\":4.154,\"height\":2.42073},{\"distance\":4.905,\"height\":0.97681},{\"distance\":4.904,\"height\":0.97685},{\"distance\":4.157,\"height\":2.42074}]" + + companion object { + val textShowList = listOf( + "11数据", + "BFFB", + "BFFB异常数据1", + "BFFB异常数据-前后视距差", + "BFFB异常数据-转角差" + ) + } + + fun getData(): List { + return GsonUtil.toAny>(dataBFFBNormal) ?: emptyList() + } + + fun getData(position: Int): List { + return when (position) { + 0 -> GsonUtil.toAny>(data11) ?: emptyList() + 1 -> GsonUtil.toAny>(dataBFFBNormal) ?: emptyList() + 2 -> GsonUtil.toAny>(dataBFFBError1) ?: emptyList() + 3 -> GsonUtil.toAny>(dataBFFBError2) ?: emptyList() + 4 -> GsonUtil.toAny>(dataBFFBError3) ?: emptyList() + else -> emptyList() + } + } + + fun test() { + val processFile = processFile("test666.DAT") + val toJson = GsonUtil.toJson(processFile) + FileUtil.writeString(toJson, File(PathManager.appDocumentFolder(), "test.json")) + Log.d("hwhw", "hwhwhw写入成功") + } + + private fun loadJsonFromAsset(fileName: String): String? { + val json: String = try { + val manager: AssetManager = Utils.getApp().assets + val `is` = manager.open(fileName) + val size = `is`.available() + val buffer = ByteArray(size) + `is`.read(buffer) + `is`.close() + String(buffer, StandardCharsets.UTF_8) + } catch (e: IOException) { + e.printStackTrace() + return null + } + return json + } + + private fun processFile(fileName: String): List { + val result = mutableListOf() + try { + val assetManager: AssetManager = Utils.getApp().assets + val inputStream = assetManager.open(fileName) + val reader = BufferedReader(InputStreamReader(inputStream)) + var line = "" + + // 定义正则表达式 + val regex = "(Rf|Rb)\\s+([\\d.]+)\\s+m" + val regex2 = "HD\\s+([\\d.]+)\\s+m" + val pattern1 = Pattern.compile(regex) + val pattern2 = Pattern.compile(regex2) + + while (reader.readLine()?.also { line = it } != null && !line.contains("#")) { + val matcher = pattern1.matcher(line) + val matcher2 = pattern2.matcher(line) + + if (matcher.find() && matcher2.find()) { + val height = matcher.group(2)?.toDouble() ?: 0.0 + val distance = matcher2.group(1)?.toDouble() ?: 0.0 + result.add(LevelReceiveData(height, distance)) + } + } + inputStream.close() + } catch (e: IOException) { + e.printStackTrace() + } + return result + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/util/LevelDateUtil.java b/app/src/main/java/com/bingce/controlnetwork/func/level/util/LevelDateUtil.java new file mode 100644 index 0000000..f03cb0d --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/util/LevelDateUtil.java @@ -0,0 +1,84 @@ +package com.bingce.controlnetwork.func.level.util; + +import com.bingce.controlnetwork.func.level.util.suntime.SunTimes; + +import java.text.SimpleDateFormat; +import java.time.Duration; +import java.time.LocalTime; +import java.time.ZonedDateTime; +import java.util.Date; + + + +public class LevelDateUtil { + /** + * 34.757975, 113.665412 + * + * @param lat + * @param lng + */ + public static String getLevelOperateSunTimeHint(double lat, double lng) { + ZonedDateTime now = ZonedDateTime.now(); + SunTimes times = SunTimes.compute() + .on(now.with(LocalTime.MIN)) // set a date + .at(lat, lng) // set a location + .execute(); // get the results + + ZonedDateTime rise = times.getRise(); + ZonedDateTime set = times.getSet(); + if (rise == null || set == null) { + //未计算出日出和日落时间 + return null; + } + // 计算日中时间 + ZonedDateTime noon = rise.plus(Duration.between(rise, set).dividedBy(2)); + + // 计算前后两个小时的时间窗口 + ZonedDateTime startWindow = noon.minusHours(2); + ZonedDateTime endWindow = noon.plusHours(2); + + ZonedDateTime riseAfter2 = rise.plusMinutes(30); + ZonedDateTime setBefore2 = set.minusMinutes(30); + + boolean isWithinTwoHoursOfNoon = !now.isBefore(startWindow) && !now.isAfter(endWindow); + + if (now.isBefore(riseAfter2)) { + //当前时间在日出前2小时内 + return "请在日出后30分钟进行作业"; + } + + if (now.isAfter(setBefore2)) { + //当前时间在日落后2小时 + return "请在日落前30分钟进行作业"; + } + + // 输出结果 + if (isWithinTwoHoursOfNoon) { + //当前时间在日中前后2小时内 + return "请勿在日中前后2小时内进行作业"; + } + + return null; + } + + public static String dateToYearMonthDayHourMin(Date date) { + SimpleDateFormat simple = new SimpleDateFormat("yyyy年MM月dd日HH:mm"); + return simple.format(date); + } + + public static String getLevelHeadDateYearMonthDay(Date date) { + SimpleDateFormat simple = new SimpleDateFormat("yyyy年MM月dd日"); + return simple.format(date); + } + + public static String getLevelHeadDateHourMin(Date date) { + SimpleDateFormat simple = new SimpleDateFormat("HH:mm"); + return simple.format(date); + } + + public static String getHourMinSec(Date date) { + SimpleDateFormat simple = new SimpleDateFormat("HH:mm:ss"); + return simple.format(date); + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/util/LevelExportUtilTj.kt b/app/src/main/java/com/bingce/controlnetwork/func/level/util/LevelExportUtilTj.kt new file mode 100644 index 0000000..79f8909 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/util/LevelExportUtilTj.kt @@ -0,0 +1,704 @@ +package com.bingce.controlnetwork.func.level.util + +import android.text.TextUtils +import androidx.annotation.WorkerThread +import blankj.utilcode.util.Utils + +import com.bingce.controlnetwork.func.level.export.LevelExportIDetection +import com.bingce.controlnetwork.func.level.export.LevelExportSingalHeight +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory +import com.bingce.controlapphelper.datasource.database.leveling.LevelingDbFactory +import com.bingce.controlapphelper.datasource.database.leveling.measure.backfront.LevelingMeasureBackFrontRecord +import com.bingce.controlapphelper.datasource.database.leveling.route.LevelRouteRecord +import com.bingce.controlapphelper.datasource.database.leveling.station.LevelingStationRecord +import com.bingce.controlapphelper.datasource.database.point.PointRecord +import com.bingce.controlapphelper.leveling.detaction.LevelFormatUtil +import com.bingce.controlapphelper.model.LevelExportLine +import com.bingce.controlapphelper.model.LevelingMeasureOrder +import com.bingce.controlapphelper.model.LevelingMeasureOrderUtil +import com.bingce.controlapphelper.model.LevelingStationState +import com.bingce.controlapphelper.model._N +import com.bingce.controlapphelper.surveyor.method.ExportStationMethod +import com.bingce.controlapphelper.surveyor.method.ExportUtils +import com.bingce.controlapphelper.util.DateUtil +import com.bingce.utils.DateUtils +import com.bingce.utils.Util +import java.io.File + + +class LevelExportUtilTj { + + companion object { + const val EXPORT_LEVEL_FOLDER = "Leveling" + + //导出的外层目录 + val exportOutFolder = File(Utils.getApp().externalCacheDir, EXPORT_LEVEL_FOLDER) + } + + private lateinit var exportRouteFolder: File + private lateinit var exportProjectFolder: File + + private var column1Index = 0 + + private var startPointHeight = 0.0 + private var startPointName = "" + private var endPointName = "" + + + private val printSbLev = StringBuilder() + + /** + * 导出路线文件夹下的数据 + */ + @WorkerThread + fun doExportRouteData(projectId: String, routeId: String) { + val routeRecord = LevelingDbFactory.instance.levelDataSource.getByIdSync(routeId) + ?: throw IllegalArgumentException("routeRecord==null") + //路线的基础数据 + confirmRouteCommonData(routeRecord) + //收集路线的具体数据 + collectRouteLevData(projectId, routeRecord) + } + + private fun confirmRouteCommonData(it: LevelRouteRecord) { + val startPoint = + SurveyorDatabaseFactory.instance.pointDataSource.findByIdSync(it.startPointId) + startPointHeight = getPointHeight(startPoint) + startPointName = getPointName(startPoint) + val endPoint = SurveyorDatabaseFactory.instance.pointDataSource.findByIdSync(it.endPointId) + endPointName = getPointName(endPoint) + } + + private fun collectRouteLevData(projectId: String, it: LevelRouteRecord) { + val routeId = it.getId() + val routeName = it.routeName + val levelingMeasureOrder = it.levelingMeasureOrder + val isHasTwiceStation = when (levelingMeasureOrder) { + LevelingMeasureOrder.SIM_BF, + LevelingMeasureOrder.SIM_BFFB -> { + true + } + + else -> false + } + + collectRouteLevDataLeftOrRight( + projectId, + routeId, + false, + levelingMeasureOrder + ) + if (isHasTwiceStation) { + collectRouteLevDataLeftOrRight( + projectId, + routeId, + true, + levelingMeasureOrder + ) + } + + if (printSbLev.isNotEmpty()) { + initExportFile(projectId, routeName) + if (::exportRouteFolder.isInitialized) { + saveRouteLevFile(exportRouteFolder, routeName) + saveRouteTxtFile(exportRouteFolder, routeId, routeName) + saveRouteInfoFile(exportRouteFolder, projectId, routeId, routeName) + } + } + } + + /** + * INF 观测记录 + */ + private fun saveRouteInfoFile( + exportFolder: File, + projectId: String, + routeId: String, + routeName: String + ) { + val projectRecord = SurveyorDatabaseFactory.instance.projectDataSource.getRecord(projectId) + val routeRecord = LevelingDbFactory.instance.levelDataSource.getByIdSync(routeId)!! + val toleranceTetail = + LevelingDbFactory.instance.toleranceDetailDataSource.getRecordSync(projectRecord.toleranceId) + + val startPointNameRoute = + SurveyorDatabaseFactory.instance.pointDataSource.findByIdSync(routeRecord.startPointId) + .getName() + val endPointNameRoute = + SurveyorDatabaseFactory.instance.pointDataSource.findByIdSync(routeRecord.endPointId) + .getName() + + //作业单位 + val measureUnit = projectRecord.measureUnit ?: "" + //限差等级 + val exportGrade = toleranceTetail.exportGrade + + //测站数量 单程双转的按照twiceStaion false处理 + val stationCount = + LevelingDbFactory.instance.stationDataSource.getCountByRoute(projectId, routeId, false) + + val stationListLeft = + LevelingDbFactory.instance.stationDataSource.getStationList(projectId, routeId, false) + val stationListRight = + LevelingDbFactory.instance.stationDataSource.getStationList(projectId, routeId, true) + + val remeasureCountAll = + getRemeasureCount(stationListLeft) + getRemeasureCount(stationListRight) + + //8,9,10行 + val routeDistanceHeightInfo = + getRouteDistanceHeightInfo( + stationListLeft?.lastOrNull(), + stationListRight?.lastOrNull() + ) + + val record = LevelingDbFactory.instance.stationSettingDataSource.getLatest(routeId) + record?.let { + val sb = StringBuilder() + //第一行 + sb.append(measureUnit).append(",") + sb.append(exportToString(it.watcher)).append(",") + sb.append(exportToString(it.recorder)).append(",") + sb.append(exportToString(it.examiner)).append("\n") + //第二行 + sb.append(exportGrade).append(",") + sb.append("").append(",")//观测方法:自动采集法 + sb.append(routeRecord.observationDirection).append(",") + sb.append(stationCount).append(",")//测站数 + sb.append(remeasureCountAll).append("\n")//重测数 + //第三行 + sb.append(exportToString(it.instrumentModel)).append(",") + sb.append("No.${exportToString(it.deviceNumber)}").append(",") + sb.append("").append(",")//测微读数精度 + sb.append("").append(",")//视距乘常数 + sb.append("").append("\n")//视距加常数 + //第四行 + sb.append(exportToString(it.rulerType)).append(",") + sb.append("").append(",")//标尺分划 + sb.append(exportToString(it.rulerReceptType)).append("\n")//尺承类型 + //第五行 + sb.append(startPointNameRoute).append(",")//起点 + sb.append(endPointNameRoute).append("\n")//终点 + //第六行 + sb.append(exportToString(it.firstStationBackFootNumber)).append(",") + sb.append(exportToString(it.firstStationFrontFootNumber)).append("\n") + //第七行 + sb.append(exportToString(it.firstStationBackFootNumber2)).append(",") + sb.append(exportToString(it.firstStationFrontFootNumber2)).append("\n") + //第八行 + sb.append(routeDistanceHeightInfo) + + ExportStationMethod.save(sb.toString(), exportFolder, "${routeName}.INF") + } + } + + /** + * INFO文件里的距离和高差 + */ + private fun getRouteDistanceHeightInfo( + leftEndStation: LevelingStationRecord?, + rightEndStation: LevelingStationRecord? + ): String { + val sb = StringBuilder() + if (leftEndStation == null && rightEndStation == null) { + sb.append("").append(",").append("").append(",").append("").append(",").append("") + .append("\n") + .append(",").append("\n") + .append("").append("\n") + .append("").append("\n") + return sb.toString() + } + + val left = + LevelingDbFactory.instance.measureStationDataSource.getRecordSync(leftEndStation?.getId()) + val right = + LevelingDbFactory.instance.measureStationDataSource.getRecordSync(rightEndStation?.getId()) + + val distanceTotalLeft = formatDistance(left?.distanceTotal) + val heightDiffTotalLeft = formatDistance(left?.heightDiffTotal) + val distanceTotalRight = formatDistance(right?.distanceTotal) + val heightDiffTotalRight = formatDistance(right?.heightDiffTotal) + + val heightAverage = if (left?.heightDiffTotal != null && right?.heightDiffTotal != null) { + formatDistance((left.heightDiffTotal + right.heightDiffTotal) / 2) + } else if (left?.heightDiffTotal != null) { + formatDistance(left.heightDiffTotal) + } else { + "" + } + + //测段不符值 右-左 + val rightLeftHeightDiff = + if (left?.heightDiffTotal != null && right?.heightDiffTotal != null) { + formatDistance(right.heightDiffTotal - left.heightDiffTotal) + } else { + "0" + } + + sb.append(distanceTotalLeft).append(",").append(heightDiffTotalLeft).append(",") + .append(distanceTotalRight).append(",").append(heightDiffTotalRight).append("\n") + //第二行 + .append(heightAverage).append("\n") + //第三行 + .append(rightLeftHeightDiff).append("\n") + + return sb.toString() + } + + private fun formatDistance(value: Double?): String { + if (value == null) { + return "" + } + return ExportUtils.formatDistance(value) + } + + private fun exportToString(value: String?) = value ?: "" + + /** + * 通过测站列表获取重测数量 + */ + @WorkerThread + private fun getRemeasureCount(stationList: List): Int { + var count = 0 + for (station in stationList) { + val remeasureCountByStationId = + LevelingDbFactory.instance.measureBackFrontDataSource.getRemeasureCountByStationId( + station.getId() + ) + count += remeasureCountByStationId + } + return count + } + + /** + * TXT 观测条件 + */ + private fun saveRouteTxtFile(exportFolder: File, routeId: String, routeName: String) { +// //起点,终点,照准次序,测站数量,路线总长度(km),路线总高差 +// val routeRecord = TjDbFactory.instance.routeDataSource.getByIdSync(routeId) ?: return +// val startPointName = +// TjDbFactory.instance.pointDataSource.findByIdSync(routeRecord.startPointId).name +// val endPointName = +// TjDbFactory.instance.pointDataSource.findByIdSync(routeRecord.endPointId).name +// val orderText = +// LevelingMeasureOrderUtil.getTextByLevelingMeasureOrder(routeRecord.levelingMeasureOrder) +// +// val stationCount = LevelingDbFactory.instance.stationDataSource.getCountByRoute( +// routeRecord.projectId, +// routeId, +// false +// ) +// +// val stationLatest = LevelingDbFactory.instance.stationDataSource.getStationLatest( +// routeRecord.projectId, +// routeId +// ) +// +// val measureStationList = mutableListOf() +// val measureStationRecordLast = +// LevelingDbFactory.instance.measureStationDataSource.getRecordSync(stationLatest.getId()) +// if (stationLatest.twiceStation) { +// val measureStationRecordLeft = +// LevelingDbFactory.instance.measureStationDataSource.getRecordSync(stationLatest.lastStationId) +// measureStationList.add(measureStationRecordLeft) +// measureStationList.add(measureStationRecordLast) +// } else { +// measureStationList.add(measureStationRecordLast) +// } +// +// val sb = StringBuilder() +// for (item in measureStationList) { +// sb.append(startPointName).append(",") +// sb.append(endPointName).append(",") +// sb.append(orderText).append(",") +// sb.append(stationCount).append(",") +// +// sb.append(ExportUtilsTj.formatDistance(item.distanceTotal)).append(",") +// sb.append(ExportUtilsTj.formatDistance(item.heightDiffTotal)) +// sb.append("\n") +// } + + //观测条件list + val observationConditionList = + LevelingDbFactory.instance.stationSettingDataSource.getByRouteId(routeId) + + val sb = StringBuilder() + for (item in observationConditionList) { + val station = + LevelingDbFactory.instance.stationDataSource.getRecordSync(item.stationId) + val stationNum = station.stationName.replace("测站", "") + + //第一行 + sb.append(stationNum).append(",") + .append(LevelDateUtil.dateToYearMonthDayHourMin(item.createDate)).append("\n") + //第二行 + sb.append(exportToString(item.temperature)).append(",") + .append(exportToString(item.sunDirection)).append(",") + .append(exportToString(item.imaging)).append(",") + .append(exportToString(item.weather)).append("\n") + //第三行 + sb.append(exportToString(item.windDirection)).append(",") + .append(exportToString(item.windSpeed)).append(",") + .append(exportToString(item.roads)).append(",") + .append(exportToString(item.soil)).append("\n") + } + + ExportStationMethod.save(sb.toString(), exportFolder, "${routeName}.TXT") + } + + private fun removeLastBuilder(sb: StringBuilder) { + if (sb.isNotEmpty()) { + sb.deleteCharAt(sb.lastIndex) + } + } + + private fun saveRouteLevFile(exportFolder: File, routeName: String) { + ExportStationMethod.save(printSbLev.toString(), exportFolder, "${routeName}.LEV") + } + + private fun initExportFile(projectId: String, routeName: String) { + exportProjectFolder = initExportProjectFolder(projectId) + confirmRouteFolder(exportProjectFolder, routeName) + } + + private fun initExportProjectFolder(projectId: String): File { + val exportFolder = File(Utils.getApp().externalCacheDir, EXPORT_LEVEL_FOLDER) + if (!exportFolder.exists()) { + exportFolder.mkdirs() + } + val projectName = + SurveyorDatabaseFactory.instance.projectDataSource.getRecord(projectId).projectName + val projectFolder = File(exportFolder, projectName) + if (!projectFolder.exists()) { + projectFolder.mkdir() + } + return projectFolder + } + + /** + * 重名项目或路线文件夹增加_1 + */ + private fun confirmRouteFolder(exportProjectFolder: File, name: String) { + val exportFolderTarget = File(exportProjectFolder, name) + if (!exportFolderTarget.exists()) { + exportFolderTarget.mkdir() + this.exportRouteFolder = exportFolderTarget + return + } + confirmRouteFolder(exportProjectFolder, name + "_1") + } + + /** + * 收集左线或者右线的数据 + */ + private fun collectRouteLevDataLeftOrRight( + projectId: String, + routeId: String, + twiceStation: Boolean, + levelingMeasureOrder: LevelingMeasureOrder + ) { + val orderText = + LevelingMeasureOrderUtil.getTextByLevelingMeasureOrder(levelingMeasureOrder) + + val stationList = LevelingDbFactory.instance.stationDataSource.getStationList( + projectId, + routeId, + twiceStation + ) + + var finishIndex = 0 + for ((index, station) in stationList.withIndex()) { + if (station.stationState != LevelingStationState.FINISH) + break + + if (index == 0) { + appendStartOrEndLine("Start-Line", orderText) + appendRouteStationHead(routeId, station) + appendZ(station.backSightPointId, startPointHeight) + } + + //测量数据 + appendMeasureData(station) + finishIndex = index + column1Index++ + } + + //最后完成测站 + val lastFinishStation = stationList[finishIndex] + val stationHeightDiffTotal = getStationHeightDiffTotal(lastFinishStation) + + //结束点高程 + appendZ( + lastFinishStation.frontSightPointId, + getFrontPointZ(stationHeightDiffTotal) + ) + column1Index++ + //end-line + appendStartOrEndLine("End-Line", "") + } + + private fun getStationHeightDiffTotal(stationRecord: LevelingStationRecord): Double { + //当前站的累积高差 + return LevelingDbFactory.instance.measureStationDataSource.getRecordSync(stationRecord.getId()).heightDiffTotal + } + + private fun getFrontPointZ(heightDiffTotal: Double) = startPointHeight + heightDiffTotal + + private fun appendStartOrEndLine(startOrEndLine: String, column2Name3: String) { + val dataFirstLine = LevelExportLine( + LevelExportLine.Column1(column1Index), + LevelExportLine.Column2("TO", startOrEndLine, column2Name3), + LevelExportLine.ColumnHeight("", ""), + LevelExportLine.ColumnDistance(""), + LevelExportLine.ColumnEnd(null, null) + ).getData() + printSbLev.append(dataFirstLine).append(_N) + + column1Index++ + } + + /** + * 路线的首站头 + * 起点,终点等 + */ + private fun appendRouteStationHead(routeId: String, station: LevelingStationRecord) { + val stationSetting = LevelingDbFactory.instance.stationSettingDataSource.getLatest(routeId) + + val measureDataList = + LevelingDbFactory.instance.measureBackFrontDataSource.getMeasureDataList(station.getId()) + val firstRecordDate = measureDataList.first().createDate + val endRecordDate = measureDataList.last().createDate + + val levelHeadDateYearMonthDay = + LevelDateUtil.getLevelHeadDateYearMonthDay(firstRecordDate) + val startHourMin = LevelDateUtil.getLevelHeadDateHourMin(firstRecordDate) + val endHourMin = LevelDateUtil.getLevelHeadDateHourMin(endRecordDate) + + val line1 = getRouteStationHeadLine("startName", startPointName) + printSbLev.append(line1).append(_N) + val line2 = getRouteStationHeadLine("endName", endPointName) + printSbLev.append(line2).append(_N) + val line3 = getRouteStationHeadLine("observationDate", levelHeadDateYearMonthDay) + printSbLev.append(line3).append(_N) + val line4 = getRouteStationHeadLine("observationStartTime", startHourMin) + printSbLev.append(line4).append(_N) + val line5 = getRouteStationHeadLine("observationEndTime", endHourMin) + printSbLev.append(line5).append(_N) + val line6 = getRouteStationHeadLine("weather", stationSetting.weather ?: "") + printSbLev.append(line6).append(_N) + val line7 = getRouteStationHeadLine("imaging", stationSetting.imaging ?: "") + printSbLev.append(line7).append(_N) + + column1Index++ + } + + private fun getRouteStationHeadLine(key: String, value: String): String { + return LevelExportLine( + LevelExportLine.Column1(column1Index), + LevelExportLine.Column2("INF", "", ""), + LevelExportLine.ColumnHeight(key, ""), + LevelExportLine.ColumnDistance(""), + LevelExportLine.ColumnEnd(value, "") + ).getData() + } + + /** + * 测量数据 + */ + private fun appendMeasureData(station: LevelingStationRecord) { + val measureDataList = + LevelingDbFactory.instance.measureBackFrontDataSource.getMeasureDataList(station.getId()) + + val stationHeightDiffTotal = getStationHeightDiffTotal(station) + + val backDataList = mutableListOf() + val frontDataList = mutableListOf() + + for ((index, record) in measureDataList.withIndex()) { + val point = getPoint(record.measurePointId) + val pointName = getPointName(point) + + var rbOrRf: String + if (record.measurePointId == station.backSightPointId) { + rbOrRf = "Rb" + backDataList.add(record) + } else { + rbOrRf = "Rf" + frontDataList.add(record) + } + + val time = DateUtil.formatDateHHmmss(record.createDate) + + val line = LevelExportLine( + LevelExportLine.Column1(column1Index), + LevelExportLine.Column2("KD1", pointName, time), + LevelExportLine.ColumnHeight(rbOrRf, "${record.measureHeightShow} m"), + LevelExportLine.ColumnDistance(record.measureDistanceShow), + LevelExportLine.ColumnEnd(null, null) + ).getData() + printSbLev.append(line).append(_N) + + //最后再增加一行 + if (index == measureDataList.lastIndex) { + //每一站的结果 + column1Index++ + appendZ(point.getId(), getFrontPointZ(stationHeightDiffTotal)) + } + + column1Index++ + } + } + + private fun getPointHeight(point: PointRecord?): Double { + return point?.getZ() ?: 0.0 + } + + private fun getPointName(point: PointRecord?): String { + return point?.getName() ?: "" + } + + private fun getPoint(pointId: String): PointRecord { + return SurveyorDatabaseFactory.instance.pointDataSource.findByIdSync(pointId) + } + + private fun appendZ(pointId: String, height: Double) { + val startPoint = getPoint(pointId) + val z = LevelFormatUtil.formatHeight(height) + val dataSecondLine = LevelExportLine( + LevelExportLine.Column1(column1Index), + LevelExportLine.Column2("KD1", getPointName(startPoint), ""), + LevelExportLine.ColumnHeight("", ""), + LevelExportLine.ColumnDistance(""), + LevelExportLine.ColumnEnd("Z", "$z m") + ).getData() + printSbLev.append(dataSecondLine).append(_N) + column1Index++ + } + + + data class CalTotal(var heightDiffTotal: Double = 0.0, var distanceTotal: Double = 0.0) { + fun addHeightDiffTotal(heightDiffTotal: Double) { + this.heightDiffTotal += heightDiffTotal + } + + fun addDistanceTotal(distanceTotal: Double) { + this.distanceTotal += distanceTotal + } + } + + @WorkerThread + fun exportProjectTxt(projectId: String) { + val projectFolder = initExportProjectFolder(projectId) + val projectRecord = SurveyorDatabaseFactory.instance.projectDataSource.getRecord(projectId) + + val text = projectRecord.projectName + + "," + + "" + + "," + + "," + + "," + + "," + + "," + + "," + + "," + + (if (projectRecord == null) "" else projectRecord.getMeasureUnit()) + + "," + + (if (projectRecord == null) "" else DateUtils.toDate(projectRecord.getCreateDate())) + + "\n" + ExportStationMethod.save( + text, + projectFolder, + "project.TXT" + ) + } + + fun exportControlTxt(projectId: String) { + val projectFolder = initExportProjectFolder(projectId) + val knownList = SurveyorDatabaseFactory.instance.pointDataSource.getListByProjectId( + projectId, + PointRecord.TYPE_KNOWN_POINT + ) + val unknownList = SurveyorDatabaseFactory.instance.pointDataSource.getListByProjectId( + projectId, + PointRecord.TYPE_UNKNOWN_POINT + ) + + val stringBuilder = StringBuilder() + appendExportPoint(stringBuilder, knownList) + appendExportPoint(stringBuilder, unknownList) + + ExportStationMethod.save( + stringBuilder.toString(), + projectFolder, + "controlpoint.TXT" + ) + } + + private fun appendExportPoint(sb: StringBuilder, list: List) { + for (pointRecord in list) { + sb + .append(pointRecord.getName()) + .append(",") + .append(pointRecord.getCode()) + .append(",") + .append(getXyzFormat(pointRecord.getX())) + .append(",") + .append(getXyzFormat(pointRecord.getY())) + .append(",") + .append(getXyzFormat(pointRecord.getZ())) + .append(",") +// .append(pointRecord.getLongitude()) + .append(",") +// .append(pointRecord.getLatitude()) + .append(",") + .append("") + .append("\n") + } + } + + private fun getXyzFormat(xyz: Double): String { + return Util.formatDouble2String(xyz, 4) + } + + /** + * 导出i角检测 + */ + @WorkerThread + fun exportIDetection(projectId: String) { + val projectName = + SurveyorDatabaseFactory.instance.projectDataSource.getRecord(projectId).projectName + + val iDetectionList = + LevelingDbFactory.instance.iDetectionListDataSource.getListByProjectIdDesc(projectId) + + val sb = StringBuilder() + val levelExportIDetection = LevelExportIDetection() + for (iDetection in iDetectionList) { + val export = levelExportIDetection.export(iDetection) + if (!TextUtils.isEmpty(export)) { + sb.append(export) + } + } + + if (sb.isNotEmpty()) { + val projectFolder = initExportProjectFolder(projectId) + ExportStationMethod.save( + sb.toString(), + projectFolder, + "$projectName.IAC" + ) + } + } + + + /** + * 导出 + */ + fun exportTjSingalHeight(projectId: String) { + val levelExportSingalHeight = LevelExportSingalHeight() + val projectFolder = initExportProjectFolder(projectId) + levelExportSingalHeight.export(projectFolder, projectId) + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/util/LevelPointUtilTj.kt b/app/src/main/java/com/bingce/controlnetwork/func/level/util/LevelPointUtilTj.kt new file mode 100644 index 0000000..a1fabcb --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/util/LevelPointUtilTj.kt @@ -0,0 +1,38 @@ +package com.bingce.controlnetwork.func.level.util + +import androidx.annotation.WorkerThread +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory +import com.bingce.controlapphelper.datasource.database.leveling.LevelingDbFactory +import com.bingce.controlapphelper.datasource.database.point.PointRecord +import com.bingce.controlapphelper.util.RegExUtil + +object LevelPointUtilTj { + @WorkerThread + @JvmStatic + fun createFrontPointByBackPointId( + routeId: String, + backPointId: String, + firstStaion: Boolean = false, + endStattion: Boolean = false, + ): PointRecord { + val frontPoint = if (endStattion) { + val route = LevelingDbFactory.instance.levelDataSource.getByIdSync(routeId) + SurveyorDatabaseFactory.instance.pointDataSource.findByIdSync(route?.endPointId) + } else if (firstStaion) { + createHidePoint("1") + } else { + val backPoint = SurveyorDatabaseFactory.instance.pointDataSource.findByIdSync(backPointId) + val frontPointName = RegExUtil.getPointNameIncrease(backPoint.getName()) + createHidePoint(frontPointName) + } + return frontPoint + } + + private fun createHidePoint(pointName: String): PointRecord { + val point = PointRecord.createHidePoint(pointName) + //存点 + SurveyorDatabaseFactory.instance.pointDataSource.saveSync(point) + return point + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/util/LevelStationSettingLastData.kt b/app/src/main/java/com/bingce/controlnetwork/func/level/util/LevelStationSettingLastData.kt new file mode 100644 index 0000000..5eec352 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/util/LevelStationSettingLastData.kt @@ -0,0 +1,271 @@ +package com.bingce.controlnetwork.func.level.util + +import androidx.annotation.WorkerThread +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory + +/** + * 水准测站设置上次值 + */ +object LevelStationSettingLastData { + + private const val KEY_WATCHER = "LEVEL_STATION_SETTING_LAST_DATA_WATCHER" + private const val KEY_RECORDER = "LEVEL_STATION_SETTING_LAST_DATA_RECORDER" + private const val KEY_EXAMINER = "LEVEL_STATION_SETTING_LAST_DATA_EXAMINER" + private const val KEY_FRONT_FOOT_NUMBER = "LEVEL_STATION_SETTING_LAST_DATA_FRONT_FOOT_NUMBER" + private const val KEY_BACK_FOOT_NUMBER = "LEVEL_STATION_SETTING_LAST_DATA_BACK_FOOT_NUMBER" + private const val KEY_FRONT_FOOT_NUMBER_2 = + "LEVEL_STATION_SETTING_LAST_DATA_FRONT_FOOT_NUMBER_2" + private const val KEY_BACK_FOOT_NUMBER_2 = "LEVEL_STATION_SETTING_LAST_DATA_BACK_FOOT_NUMBER_2" + private const val KEY_INSTRUMENT_MODEL = "LEVEL_STATION_SETTING_LAST_DATA_INSTRUMENT_MODEL" + private const val KEY_DEVICE_NUMBER = "LEVEL_STATION_SETTING_LAST_DATA_DEVICE_NUMBER" + private const val KEY_STEEL_RULE_PARAM = "LEVEL_STATION_SETTING_LAST_DATA_STEEL_RULE_PARAM" + private const val KEY_RULER_LENGTH_PROVING_TEMPERATURE = + "LEVEL_STATION_SETTING_LAST_DATA_RULER_LENGTH_PROVING_TEMPERATURE" + private const val KEY_TEMPERATURE = "LEVEL_STATION_SETTING_LAST_DATA_TEMPERATURE" + private const val KEY_WEATHER = "LEVEL_STATION_SETTING_LAST_DATA_WEATHER" + private const val KEY_IMAGING = "LEVEL_STATION_SETTING_LAST_DATA_IMAGING" + private const val KEY_SUN_DIRECTION = "LEVEL_STATION_SETTING_LAST_DATA_SUN_DIRECTION" + private const val KEY_WIND_DIRECTION = "LEVEL_STATION_SETTING_LAST_DATA_WIND_DIRECTION" + private const val KEY_WIND_SPEED = "LEVEL_STATION_SETTING_LAST_DATA_WIND_SPEED" + private const val KEY_ROADS = "LEVEL_STATION_SETTING_LAST_DATA_ROADS" + private const val KEY_SOIL = "LEVEL_STATION_SETTING_LAST_DATA_SOIL" + private const val KEY_RULER_TYPE = "LEVEL_STATION_SETTING_LAST_DATA_RULER_TYPE" + private const val KEY_RULER_RECEPT_TYPE = "LEVEL_STATION_SETTING_LAST_DATA_RULER_RECEPT_TYPE" + private const val KEY_RULER_CORRECTION_FACTOR = + "LEVEL_STATION_SETTING_LAST_DATA_RULER_CORRECTION_FACTOR" + + @WorkerThread + fun getExaminer(): String? { + return get(KEY_EXAMINER) + } + + @WorkerThread + fun setExaminer(examiner: String?) { + save(KEY_EXAMINER, examiner) + } + + @WorkerThread + fun getRecorder(): String? { + return get(KEY_RECORDER) + } + + @WorkerThread + fun setRecorder(recorder: String?) { + save(KEY_RECORDER, recorder) + } + + @WorkerThread + fun getWatcher(): String? { + return get(KEY_WATCHER) + } + + @WorkerThread + fun setWatcher(watcher: String?) { + save(KEY_WATCHER, watcher) + } + + @WorkerThread + fun getFrontFootNumber(): String? { + return get(KEY_FRONT_FOOT_NUMBER) + } + + @WorkerThread + fun setFrontFootNumber(watcher: String?) { + save(KEY_FRONT_FOOT_NUMBER, watcher) + } + + @WorkerThread + fun getFrontFootNumber2(): String? { + return get(KEY_FRONT_FOOT_NUMBER_2) + } + + @WorkerThread + fun setFrontFootNumber2(watcher: String?) { + save(KEY_FRONT_FOOT_NUMBER_2, watcher) + } + + @WorkerThread + fun getBackFootNumber(): String? { + return get(KEY_BACK_FOOT_NUMBER) + } + + @WorkerThread + fun setBackFootNumber(watcher: String?) { + save(KEY_BACK_FOOT_NUMBER, watcher) + } + + @WorkerThread + fun getBackFootNumber2(): String? { + return get(KEY_BACK_FOOT_NUMBER_2) + } + + @WorkerThread + fun setBackFootNumber2(watcher: String?) { + save(KEY_BACK_FOOT_NUMBER_2, watcher) + } + + @WorkerThread + fun getInstrumentModel(): String? { + return get(KEY_INSTRUMENT_MODEL) + } + + @WorkerThread + fun setInstrumentModel(watcher: String?) { + save(KEY_INSTRUMENT_MODEL, watcher) + } + + @WorkerThread + fun getDeviceNumber(): String? { + return get(KEY_DEVICE_NUMBER) + } + + @WorkerThread + fun setDeviceNumber(watcher: String?) { + save(KEY_DEVICE_NUMBER, watcher) + } + + @WorkerThread + fun getSteelRuleParam(): String? { + return get(KEY_STEEL_RULE_PARAM) + } + + @WorkerThread + fun setTemperature(watcher: String?) { + save(KEY_TEMPERATURE, watcher) + } + + @WorkerThread + fun getTemperature(): String? { + return get(KEY_TEMPERATURE) + } + + @WorkerThread + fun setWeather(watcher: String?) { + save(KEY_WEATHER, watcher) + } + + @WorkerThread + fun getWeather(): String? { + return get(KEY_WEATHER) + } + + @WorkerThread + fun setImaging(watcher: String?) { + save(KEY_IMAGING, watcher) + } + + @WorkerThread + fun getImaging(): String? { + return get(KEY_IMAGING) + } + + + ///////////// + @WorkerThread + fun setSteelRuleParam(watcher: String?) { + save(KEY_STEEL_RULE_PARAM, watcher) + } + + @WorkerThread + fun getRulerLengthProvingTemperature(): String? { + return get(KEY_RULER_LENGTH_PROVING_TEMPERATURE) + } + + @WorkerThread + fun setRulerLengthProvingTemperature(watcher: String?) { + save(KEY_RULER_LENGTH_PROVING_TEMPERATURE, watcher) + } + + @WorkerThread + fun getSunDirection(): String? { + return get(KEY_SUN_DIRECTION) + } + + @WorkerThread + fun setSunDirection(watcher: String?) { + save(KEY_SUN_DIRECTION, watcher) + } + + @WorkerThread + fun getWindDirection(): String? { + return get(KEY_WIND_DIRECTION) + } + + @WorkerThread + fun setWindDirection(watcher: String?) { + save(KEY_WIND_DIRECTION, watcher) + } + + @WorkerThread + fun getWindSpeed(): String? { + return get(KEY_WIND_SPEED) + } + + @WorkerThread + fun setWindSpeed(watcher: String?) { + save(KEY_WIND_SPEED, watcher) + } + + @WorkerThread + fun getRoads(): String? { + return get(KEY_ROADS) + } + + @WorkerThread + fun setRoads(watcher: String?) { + save(KEY_ROADS, watcher) + } + + @WorkerThread + fun getSoil(): String? { + return get(KEY_SOIL) + } + + @WorkerThread + fun setSoil(watcher: String?) { + save(KEY_SOIL, watcher) + } + + @WorkerThread + fun getRulerType(): String? { + return get(KEY_RULER_TYPE) + } + + @WorkerThread + fun setRulerType(watcher: String?) { + save(KEY_RULER_TYPE, watcher) + } + + @WorkerThread + fun getRulerReceptType(): String? { + return get(KEY_RULER_RECEPT_TYPE) + } + + @WorkerThread + fun setRulerReceptType(watcher: String?) { + save(KEY_RULER_RECEPT_TYPE, watcher) + } + + @WorkerThread + fun getRulerCorrectionFactor(): String? { + return get(KEY_RULER_CORRECTION_FACTOR) + } + + @WorkerThread + fun setRulerCorrectionFactor(watcher: String?) { + save(KEY_RULER_CORRECTION_FACTOR, watcher) + } + + + private fun save(key: String, value: String?) { + SurveyorDatabaseFactory.instance.getConfigDataSource().setSync(key, value) + } + + private fun get(key: String): String? { + val measureUnitRecord = + SurveyorDatabaseFactory.instance.getConfigDataSource() + .getByKeySync(key) + return measureUnitRecord?.getConfigValue() + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/util/LevelStationSettingUtil.kt b/app/src/main/java/com/bingce/controlnetwork/func/level/util/LevelStationSettingUtil.kt new file mode 100644 index 0000000..4c1518d --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/util/LevelStationSettingUtil.kt @@ -0,0 +1,132 @@ +package com.bingce.controlnetwork.func.level.util + +import android.widget.Spinner +import androidx.annotation.WorkerThread +import com.bingce.controlapphelper.datasource.database.leveling.LevelingDbFactory +import com.bingce.controlapphelper.datasource.database.leveling.stationsetting.LevelingStationSettingRecord +import com.bingce.controlapphelper.model.LevelRouteSave +import com.bingce.controlapphelper.util.Tools +import com.bingce.controlnetwork.R + +object LevelStationSettingUtil { + + /** + * 保存测站设置 + */ + fun saveStationSetting( + isSaveEndStationToStationSetting: Boolean, + levelRouteSave: LevelRouteSave + ) { + + var saveEndStation = isSaveEndStationToStationSetting + + val stationSetting = if (levelRouteSave.stationId != null) { + val before = + LevelingDbFactory.instance.stationSettingDataSource.getByStationId(levelRouteSave.stationId) + + if (before != null) { + saveEndStation = before.setEndStationSetting or saveEndStation + } + + before ?: LevelingStationSettingRecord() + } else { + LevelingStationSettingRecord() + } + + //初始化保存的endStation + stationSetting.setEndStationSetting = saveEndStation + + stationSetting.routeId = levelRouteSave.routeId + stationSetting.stationId = levelRouteSave.stationId + stationSetting.watcher = levelRouteSave.watcher + stationSetting.recorder = levelRouteSave.recorder + stationSetting.examiner = levelRouteSave.examiner + stationSetting.firstStationBackFootNumber = levelRouteSave.backFootNumber + stationSetting.firstStationFrontFootNumber = levelRouteSave.frontFootNumber + stationSetting.firstStationBackFootNumber2 = levelRouteSave.backFootNumber2 + stationSetting.firstStationFrontFootNumber2 = levelRouteSave.frontFootNumber2 + stationSetting.instrumentModel = levelRouteSave.instrumentModel + stationSetting.deviceNumber = levelRouteSave.deviceNumber + stationSetting.steelRuleParam = levelRouteSave.steelRuleParam + stationSetting.rulerLengthProvingTemperature = levelRouteSave.rulerLengthProvingTemperature + stationSetting.rulerCorrectionFactor = levelRouteSave.rulerCorrectionFactor + stationSetting.rulerType = levelRouteSave.rulerType + stationSetting.rulerReceptType = levelRouteSave.rulerReceptType + + stationSetting.temperature = levelRouteSave.temperature + stationSetting.weather = levelRouteSave.weather + stationSetting.imaging = levelRouteSave.imaging + stationSetting.sunDirection = levelRouteSave.sunDirection + stationSetting.windDirection = levelRouteSave.windDirection + stationSetting.windSpeed = levelRouteSave.windSpeed + stationSetting.roads = levelRouteSave.roads + stationSetting.soil = levelRouteSave.soil + + LevelingDbFactory.instance.stationSettingDataSource.save(stationSetting) + } + + fun getSpinnerText(spinner: Spinner): String { + val text = spinner.selectedItem.toString() + if (text.contains(Tools.getString(R.string.please_choose))) { + return "" + } + return text + } + + @WorkerThread + fun saveStationSettingLastData(levelRouteSave: LevelRouteSave) { + LevelStationSettingLastData.setWatcher(levelRouteSave.watcher) + LevelStationSettingLastData.setRecorder(levelRouteSave.recorder) + LevelStationSettingLastData.setExaminer(levelRouteSave.examiner) + LevelStationSettingLastData.setBackFootNumber(levelRouteSave.backFootNumber) + LevelStationSettingLastData.setFrontFootNumber(levelRouteSave.frontFootNumber) + LevelStationSettingLastData.setBackFootNumber2(levelRouteSave.backFootNumber2) + LevelStationSettingLastData.setFrontFootNumber2(levelRouteSave.frontFootNumber2) + LevelStationSettingLastData.setInstrumentModel(levelRouteSave.instrumentModel) + LevelStationSettingLastData.setDeviceNumber(levelRouteSave.deviceNumber) + LevelStationSettingLastData.setSteelRuleParam(levelRouteSave.steelRuleParam) + LevelStationSettingLastData.setRulerLengthProvingTemperature(levelRouteSave.rulerLengthProvingTemperature) + LevelStationSettingLastData.setRulerCorrectionFactor(levelRouteSave.rulerCorrectionFactor) + LevelStationSettingLastData.setRulerType(levelRouteSave.rulerType) + LevelStationSettingLastData.setRulerReceptType(levelRouteSave.rulerReceptType) + + LevelStationSettingLastData.setTemperature(levelRouteSave.temperature) + LevelStationSettingLastData.setWeather(levelRouteSave.weather) + LevelStationSettingLastData.setImaging(levelRouteSave.imaging) + LevelStationSettingLastData.setSunDirection(levelRouteSave.sunDirection) + LevelStationSettingLastData.setWindDirection(levelRouteSave.windDirection) + LevelStationSettingLastData.setWindSpeed(levelRouteSave.windSpeed) + LevelStationSettingLastData.setRoads(levelRouteSave.roads) + LevelStationSettingLastData.setSoil(levelRouteSave.soil) + } + + @WorkerThread + fun getStationSettingLastData(): LevelRouteSave { + return LevelRouteSave.createLastData( + LevelStationSettingLastData.getWatcher(), + LevelStationSettingLastData.getRecorder(), + LevelStationSettingLastData.getExaminer(), + LevelStationSettingLastData.getBackFootNumber(), + LevelStationSettingLastData.getFrontFootNumber(), + LevelStationSettingLastData.getBackFootNumber2(), + LevelStationSettingLastData.getFrontFootNumber2(), + LevelStationSettingLastData.getInstrumentModel(), + LevelStationSettingLastData.getDeviceNumber(), + LevelStationSettingLastData.getSteelRuleParam(), + LevelStationSettingLastData.getRulerLengthProvingTemperature(), + LevelStationSettingLastData.getRulerCorrectionFactor(), + LevelStationSettingLastData.getRulerType(), + LevelStationSettingLastData.getRulerReceptType(), + + LevelStationSettingLastData.getTemperature(), + LevelStationSettingLastData.getWeather(), + LevelStationSettingLastData.getImaging(), + LevelStationSettingLastData.getSunDirection(), + LevelStationSettingLastData.getWindDirection(), + LevelStationSettingLastData.getWindSpeed(), + LevelStationSettingLastData.getRoads(), + LevelStationSettingLastData.getSoil() + ) + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/util/LevelStationUtilTj.kt b/app/src/main/java/com/bingce/controlnetwork/func/level/util/LevelStationUtilTj.kt new file mode 100644 index 0000000..39074ec --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/util/LevelStationUtilTj.kt @@ -0,0 +1,237 @@ +package com.bingce.controlnetwork.func.level.util + +import androidx.annotation.WorkerThread +import blankj.utilcode.util.ToastUtils +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory +import com.bingce.controlapphelper.datasource.database.leveling.LevelingDbFactory +import com.bingce.controlapphelper.datasource.database.leveling.measure.station.LevelingMeasureStationRecord +import com.bingce.controlapphelper.datasource.database.leveling.station.LevelingStationRecord +import com.bingce.controlapphelper.model.LevelingMeasureOrder +import com.bingce.controlapphelper.model.StationOddEven +import com.bingce.controlapphelper.util.RegExUtil +import com.bingce.utils.DateUtils + +object LevelStationUtilTj { + @WorkerThread + @JvmStatic + fun createStation( + projectId: String, + routeId: String, + backPointId: String, + firstStation: Boolean = false, + endStation: Boolean = false + ) { + val routeRecord = LevelingDbFactory.instance.levelDataSource.getByIdSync(routeId) + routeRecord?.let { + val levelingMeasureOrder = it.levelingMeasureOrder + + //新建路线的时候创建一个水准测站 + val frontPoint = + LevelPointUtilTj.createFrontPointByBackPointId( + routeId, + backPointId, + firstStation, + endStation + ) + + val stationNamePrefix = "测站" + val lastStationNameIndex = getLastStationNameIndex(projectId, routeId) + + //创建测站的奇偶站 + val createStationOdd = getCreateStationOdd(projectId, routeId) + + when (levelingMeasureOrder) { + LevelingMeasureOrder.SIM_BF, LevelingMeasureOrder.SIM_BFFB -> { + val relationId = DateUtils.genRandomTimeId() + saveOneStationRecord( + projectId, + routeId, + "${stationNamePrefix}${lastStationNameIndex.plus(1)}_L", + backPointId, + frontPoint.getId(), + false, + createStationOdd, + relationId, + endStation = false + ) + saveOneStationRecord( + projectId, + routeId, + "${stationNamePrefix}${lastStationNameIndex.plus(1)}_R", + backPointId, + frontPoint.getId(), + true, + createStationOdd, + relationId, + endStation = endStation + ) + } + + LevelingMeasureOrder.A_BF, LevelingMeasureOrder.A_BFFB, LevelingMeasureOrder.A_FBBF -> { + saveOneStationRecord( + projectId, + routeId, + "${stationNamePrefix}${lastStationNameIndex.plus(1)}", + backPointId, + frontPoint.getId(), + false, + createStationOdd, + endStation = endStation + ) + } + + else -> { + saveOneStationRecord( + projectId, + routeId, + "${stationNamePrefix}${lastStationNameIndex.plus(1)}", + backPointId, + frontPoint.getId(), + false, + createStationOdd, + endStation = endStation + ) + } + } + } + } + + @WorkerThread + private fun getLastStationNameIndex(projectId: String, routeId: String): Int { + val stationLatest = + LevelingDbFactory.instance.stationDataSource.getStationLatest(projectId, routeId) + return stationLatest?.stationName?.let { + val findNum = RegExUtil.findNum(it) + findNum?.toInt() ?: 0 + } ?: 0 + } + + @WorkerThread + private fun getLastStationId(projectId: String, routeId: String): String? { + return getStationLatest(projectId, routeId)?.id + } + + private fun getStationLatest(projectId: String, routeId: String) = + LevelingDbFactory.instance.stationDataSource.getStationLatest(projectId, routeId) + + @WorkerThread + private fun saveOneStationRecord( + projectId: String, + routeId: String, + stationName: String, + backPointId: String, + frontPointId: String, + twiceStation: Boolean, + oddStation: StationOddEven, + relationId: String? = null, + endStation: Boolean = false + ) { + val lastStationId = getLastStationId(projectId, routeId) + + val station = LevelingStationRecord.createStation( + projectId, + routeId, + stationName, + lastStationId, + twiceStation, + backPointId, + frontPointId, + 0, + oddStation, + endStation + ) + station.relationStationId = relationId + LevelingDbFactory.instance.stationDataSource.save(station) + } + + private fun getCreateStationOdd( + projectId: String, + routeId: String + ): StationOddEven { + val stationLatest = getStationLatest(projectId, routeId) + ?: return StationOddEven.ODD_STATION + return if (stationLatest.isOddStation) { + StationOddEven.EVEN_STATION + } else { + StationOddEven.ODD_STATION + } + } + + @JvmStatic + fun checkStationForResult(stationId: String): Boolean { + val stationRecord = LevelingDbFactory.instance.stationDataSource.getRecordSync(stationId) + if (stationRecord.isFinish) { + return true + } else { + if (stationRecord == null || !stationRecord.isFull) { + ToastUtils.showShort("该测站数据不完整!") + } + if (!stationRecord.isFinish) { + ToastUtils.showShort("该测站未通过检测!") + } + return false + } + } + + @JvmStatic + fun getStationFinishCount(projectId: String, routeId: String): Int { + return LevelingDbFactory.instance.stationDataSource.getCountFinish(projectId, routeId) + } + + /** + * 获取要测量的测站列表 + */ + fun getMeasureStationList(projectId: String, routeId: String): List { + val stationLatest = + LevelingDbFactory.instance.stationDataSource.getStationLatest(projectId, routeId) + val returnList = mutableListOf() + if (stationLatest != null) { + if (stationLatest.twiceStation) { + //单程双转点 + val statonList = + LevelingDbFactory.instance.stationDataSource.getStationListByRelationId( + projectId, + routeId, + stationLatest.relationStationId + ) + returnList.addAll(statonList) + } else { + returnList.add(stationLatest) + } + } + return returnList + } + + @WorkerThread + fun getStationRouteResult(stationRecord: LevelingStationRecord): String { + val routeName = + LevelingDbFactory.instance.levelDataSource.getByIdSync(stationRecord.routeId)?.routeName ?: "" + + val sb = StringBuilder() + + if (stationRecord.twiceStation) { + val relationStation = LevelingDbFactory.instance.stationDataSource + .getRelationStation(stationRecord.relationStationId, false) + val twiceStationMeasureRecord = getMeasureStationRecord(relationStation.getId()) + appendMeasureResult(sb, routeName, twiceStationMeasureRecord) + } + + val measureStationRecord = getMeasureStationRecord(stationRecord.getId()) + appendMeasureResult(sb, routeName, measureStationRecord) + + return sb.toString() + } + + private fun appendMeasureResult( + sb: StringBuilder, + routeName: String, + measureStationRecord: LevelingMeasureStationRecord + ) { + sb.append("${routeName}的总高差${measureStationRecord.heightDiffTotalShow},总距离${measureStationRecord.distanceTotalShow}") + .append("\n") + } + + private fun getMeasureStationRecord(stationId: String) = + LevelingDbFactory.instance.measureStationDataSource.getRecordSync(stationId) + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/MoonIllumination.java b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/MoonIllumination.java new file mode 100644 index 0000000..deab2f2 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/MoonIllumination.java @@ -0,0 +1,225 @@ +/* + * Shredzone Commons - suncalc + * + * Copyright (C) 2017 Richard "Shred" Körber + * http://commons.shredzone.org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package com.bingce.controlnetwork.func.level.util.suntime; + +import static java.lang.Math.PI; +import static java.lang.Math.acos; +import static java.lang.Math.atan2; +import static java.lang.Math.cos; +import static java.lang.Math.signum; +import static java.lang.Math.sin; +import static java.lang.Math.toDegrees; + +import com.bingce.controlnetwork.func.level.util.suntime.param.Builder; +import com.bingce.controlnetwork.func.level.util.suntime.param.GenericParameter; +import com.bingce.controlnetwork.func.level.util.suntime.param.LocationParameter; +import com.bingce.controlnetwork.func.level.util.suntime.param.TimeParameter; +import com.bingce.controlnetwork.func.level.util.suntime.util.BaseBuilder; +import com.bingce.controlnetwork.func.level.util.suntime.util.JulianDate; +import com.bingce.controlnetwork.func.level.util.suntime.util.Moon; +import com.bingce.controlnetwork.func.level.util.suntime.util.Sun; +import com.bingce.controlnetwork.func.level.util.suntime.util.Vector; + + +/** + * Calculates the illumination of the moon. + *

+ * Starting with v3.9, a geolocation can be set optionally. If set, the results will be + * topocentric, relative to the given location. If not set, the result is geocentric, + * which was the standard behavior before v3.9. + */ +public class MoonIllumination { + + private final double fraction; + private final double phase; + private final double angle; + private final double elongation; + private final double radius; + private final double crescentWidth; + + private MoonIllumination(double fraction, double phase, double angle, + double elongation, double radius, double crescentWidth) { + this.fraction = fraction; + this.phase = phase; + this.angle = angle; + this.elongation = elongation; + this.radius = radius; + this.crescentWidth = crescentWidth; + } + + /** + * Starts the computation of {@link MoonIllumination}. + * + * @return {@link Parameters} to set. + */ + public static Parameters compute() { + return new MoonIlluminationBuilder(); + } + + /** + * Collects all parameters for {@link MoonIllumination}. + */ + public interface Parameters extends + GenericParameter, + TimeParameter, + LocationParameter, + Builder { + + /** + * Clears the geolocation, so the result will be geocentric. + * + * @return itself + * @since 3.9 + */ + Parameters geocentric(); + + } + + /** + * Builder for {@link MoonIllumination}. Performs the computations based on the + * parameters, and creates a {@link MoonIllumination} object that holds the result. + */ + private static class MoonIlluminationBuilder extends BaseBuilder implements Parameters { + @Override + public Parameters geocentric() { + clearLocation(); + return this; + } + + @Override + public MoonIllumination execute() { + JulianDate t = getJulianDate(); + Vector s = Sun.position(t); + Vector m = Moon.position(t); + + double phi = PI - acos(m.dot(s) / (m.getR() * s.getR())); + Vector sunMoon = m.cross(s); + double angle = atan2( + cos(s.getTheta()) * sin(s.getPhi() - m.getPhi()), + sin(s.getTheta()) * cos(m.getTheta()) - cos(s.getTheta()) * sin(m.getTheta()) * cos(s.getPhi() - m.getPhi()) + ); + + Vector sTopo, mTopo; + if (hasLocation()) { + sTopo = Sun.positionTopocentric(t, getLatitudeRad(), getLongitudeRad(), getElevation()); + mTopo = Moon.positionTopocentric(t, getLatitudeRad(), getLongitudeRad(), getElevation()); + } else { + sTopo = s; + mTopo = m; + } + + double r = mTopo.subtract(sTopo).norm(); + double re = sTopo.norm(); + double d = mTopo.norm(); + double elongation = acos((d*d + re*re - r*r) / (2.0*d*re)); + double moonRadius = Moon.angularRadius(mTopo.getR()); + double crescentWidth = moonRadius * (1 - cos(elongation)); + + return new MoonIllumination( + (1 + cos(phi)) / 2, + toDegrees(phi * signum(sunMoon.getTheta())), + toDegrees(angle), + toDegrees(elongation), + toDegrees(moonRadius), + toDegrees(crescentWidth)); + } + } + + /** + * Illuminated fraction. {@code 0.0} indicates new moon, {@code 1.0} indicates full + * moon. + */ + public double getFraction() { + return fraction; + } + + /** + * Moon phase. Starts at {@code -180.0} (new moon, waxing), passes {@code 0.0} (full + * moon) and moves toward {@code 180.0} (waning, new moon). + *

+ * Note that for historical reasons, the range of this phase is different to the + * moon phase angle used in {@link MoonPhase}. + */ + public double getPhase() { + return phase; + } + + /** + * The angle of the moon illumination relative to earth. The moon is waxing if the + * angle is negative, and waning if positive. + *

+ * By subtracting {@link MoonPosition#getParallacticAngle()} from {@link #getAngle()}, + * one can get the zenith angle of the moons bright limb (anticlockwise). The zenith + * angle can be used do draw the moon shape from the observer's perspective (e.g. the + * moon lying on its back). + */ + public double getAngle() { + return angle; + } + + /** + * The closest {@link MoonPhase.Phase} that is matching the moon's angle. + * + * @return Closest {@link MoonPhase.Phase} + * @since 3.5 + */ + public MoonPhase.Phase getClosestPhase() { + return MoonPhase.Phase.toPhase(phase + 180.0); + } + + /** + * The elongation, which is the angular distance between the moon and the sun as + * observed from a specific location on earth. + * + * @return Elongation between moon and sun, in degrees. + * @since 3.9 + */ + public double getElongation() { + return elongation; + } + + /** + * The radius of the moon disk, as observed from a specific location on earth. + * + * @return Moon radius, in degrees. + * @since 3.9 + */ + public double getRadius() { + return radius; + } + + /** + * The width of the moon crescent, as observed from a specific location on earth. + * + * @return Crescent width, in degrees. + * @since 3.9 + */ + public double getCrescentWidth() { + return crescentWidth; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("MoonIllumination[fraction=").append(fraction); + sb.append(", phase=").append(phase); + sb.append("°, angle=").append(angle); + sb.append("°, elongation=").append(elongation); + sb.append("°, radius=").append(radius); + sb.append("°, crescentWidth=").append(crescentWidth); + sb.append("°]"); + return sb.toString(); + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/MoonPhase.java b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/MoonPhase.java new file mode 100644 index 0000000..751a4e4 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/MoonPhase.java @@ -0,0 +1,322 @@ +/* + * Shredzone Commons - suncalc + * + * Copyright (C) 2018 Richard "Shred" Körber + * http://commons.shredzone.org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package com.bingce.controlnetwork.func.level.util.suntime; + +import static com.bingce.controlnetwork.func.level.util.suntime.util.ExtendedMath.PI2; +import static java.lang.Math.PI; +import static java.lang.Math.toRadians; + +import com.bingce.controlnetwork.func.level.util.suntime.param.Builder; +import com.bingce.controlnetwork.func.level.util.suntime.param.GenericParameter; +import com.bingce.controlnetwork.func.level.util.suntime.param.TimeParameter; +import com.bingce.controlnetwork.func.level.util.suntime.util.BaseBuilder; +import com.bingce.controlnetwork.func.level.util.suntime.util.JulianDate; +import com.bingce.controlnetwork.func.level.util.suntime.util.Moon; +import com.bingce.controlnetwork.func.level.util.suntime.util.Pegasus; +import com.bingce.controlnetwork.func.level.util.suntime.util.Sun; +import com.bingce.controlnetwork.func.level.util.suntime.util.Vector; + +import java.time.ZonedDateTime; + + + + +/** + * Calculates the date and time when the moon reaches the desired phase. + *

+ * Note: Due to the simplified formulas used in suncalc, the returned time can have an + * error of several minutes. + */ +public class MoonPhase { + + private final ZonedDateTime time; + private final double distance; + + private MoonPhase(ZonedDateTime time, double distance) { + this.time = time; + this.distance = distance; + } + + /** + * Starts the computation of {@link MoonPhase}. + * + * @return {@link Parameters} to set. + */ + public static Parameters compute() { + return new MoonPhaseBuilder(); + } + + /** + * Collects all parameters for {@link MoonPhase}. + */ + public interface Parameters extends + GenericParameter, + TimeParameter, + Builder { + + /** + * Sets the desired {@link Phase}. + *

+ * Defaults to {@link Phase#NEW_MOON}. + * + * @param phase {@link Phase} to be used. + * @return itself + */ + Parameters phase(Phase phase); + + /** + * Sets a free phase to be used. + * + * @param phase Desired phase, in degrees. 0 = new moon, 90 = first quarter, 180 = + * full moon, 270 = third quarter. + * @return itself + */ + Parameters phase(double phase); + } + + /** + * Enumeration of moon phases. + */ + public enum Phase { + + /** + * New moon. + */ + NEW_MOON(0.0), + + /** + * Waxing crescent moon. + * + * @since 3.5 + */ + WAXING_CRESCENT(45.0), + + /** + * Waxing half moon. + */ + FIRST_QUARTER(90.0), + + /** + * Waxing gibbous moon. + * + * @since 3.5 + */ + WAXING_GIBBOUS(135.0), + + /** + * Full moon. + */ + FULL_MOON(180.0), + + /** + * Waning gibbous moon. + * + * @since 3.5 + */ + WANING_GIBBOUS(225.0), + + /** + * Waning half moon. + */ + LAST_QUARTER(270.0), + + /** + * Waning crescent moon. + * + * @since 3.5 + */ + WANING_CRESCENT(315.0); + + /** + * Converts an angle to the closest matching moon phase. + * + * @param angle Moon phase angle, in degrees. 0 = New Moon, 180 = Full Moon. Angles + * outside the [0,360) range are normalized into that range. + * @return Closest Phase that is matching that angle. + * @since 3.5 + */ + public static Phase toPhase(double angle) { + // bring into range 0.0 .. 360.0 + double normalized = angle % 360.0; + if (normalized < 0.0) { + normalized += 360.0; + } + + if (normalized < 22.5) { + return NEW_MOON; + } + if (normalized < 67.5) { + return WAXING_CRESCENT; + } + if (normalized < 112.5) { + return FIRST_QUARTER; + } + if (normalized < 157.5) { + return WAXING_GIBBOUS; + } + if (normalized < 202.5) { + return FULL_MOON; + } + if (normalized < 247.5) { + return WANING_GIBBOUS; + } + if (normalized < 292.5) { + return LAST_QUARTER; + } + if (normalized < 337.5) { + return WANING_CRESCENT; + } + return NEW_MOON; + } + + private final double angle; + private final double angleRad; + + Phase(double angle) { + this.angle = angle; + this.angleRad = toRadians(angle); + } + + /** + * Returns the moons's angle in reference to the sun, in degrees. + */ + public double getAngle() { + return angle; + } + + /** + * Returns the moons's angle in reference to the sun, in radians. + */ + public double getAngleRad() { + return angleRad; + } + } + + /** + * Builder for {@link MoonPhase}. Performs the computations based on the parameters, + * and creates a {@link MoonPhase} object that holds the result. + */ + private static class MoonPhaseBuilder extends BaseBuilder implements Parameters { + private static final double SUN_LIGHT_TIME_TAU = 8.32 / (1440.0 * 36525.0); + + private double phase = Phase.NEW_MOON.getAngleRad(); + + @Override + public Parameters phase(Phase phase) { + this.phase = phase.getAngleRad(); + return this; + } + + @Override + public Parameters phase(double phase) { + this.phase = toRadians(phase); + return this; + } + + @Override + public MoonPhase execute() { + final JulianDate jd = getJulianDate(); + + double dT = 7.0 / 36525.0; // step rate: 1 week + double accuracy = (0.5 / 1440.0) / 36525.0; // accuracy: 30 seconds + + double t0 = jd.getJulianCentury(); + double t1 = t0 + dT; + + double d0 = moonphase(jd, t0); + double d1 = moonphase(jd, t1); + + while (d0 * d1 > 0.0 || d1 < d0) { + t0 = t1; + d0 = d1; + t1 += dT; + d1 = moonphase(jd, t1); + } + + double tphase = Pegasus.calculate(t0, t1, accuracy, x -> moonphase(jd, x)); + JulianDate tjd = jd.atJulianCentury(tphase); + return new MoonPhase(tjd.getDateTime(), Moon.positionEquatorial(tjd).getR()); + } + + /** + * Calculates the position of the moon at the given phase. + * + * @param jd Base Julian date + * @param t Ephemeris time + * @return difference angle of the sun's and moon's position + */ + private double moonphase(JulianDate jd, double t) { + Vector sun = Sun.positionEquatorial(jd.atJulianCentury(t - SUN_LIGHT_TIME_TAU)); + Vector moon = Moon.positionEquatorial(jd.atJulianCentury(t)); + double diff = moon.getPhi() - sun.getPhi() - phase; //NOSONAR: false positive + while (diff < 0.0) { + diff += PI2; + } + return ((diff + PI) % PI2) - PI; + } + + } + + /** + * Date and time of the desired moon phase. The time is rounded to full minutes. + */ + public ZonedDateTime getTime() { + return time; + } + + /** + * Geocentric distance of the moon at the given phase, in kilometers. + * + * @since 3.4 + */ + public double getDistance() { + return distance; + } + + /** + * Checks if the moon is in a SuperMoon position. + *

+ * Note that there is no official definition of supermoon. Suncalc will assume a + * supermoon if the center of the moon is closer than 360,000 km to the center of + * Earth. Usually only full moons or new moons are candidates for supermoons. + * + * @since 3.4 + */ + public boolean isSuperMoon() { + return distance < 360000.0; + } + + /** + * Checks if the moon is in a MicroMoon position. + *

+ * Note that there is no official definition of micromoon. Suncalc will assume a + * micromoon if the center of the moon is farther than 405,000 km from the center of + * Earth. Usually only full moons or new moons are candidates for micromoons. + * + * @since 3.4 + */ + public boolean isMicroMoon() { + return distance > 405000.0; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("MoonPhase[time=").append(time); + sb.append(", distance=").append(distance); + sb.append(" km]"); + return sb.toString(); + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/MoonPosition.java b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/MoonPosition.java new file mode 100644 index 0000000..d940e9c --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/MoonPosition.java @@ -0,0 +1,167 @@ +/* + * Shredzone Commons - suncalc + * + * Copyright (C) 2017 Richard "Shred" Körber + * http://commons.shredzone.org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package com.bingce.controlnetwork.func.level.util.suntime; + +import static com.bingce.controlnetwork.func.level.util.suntime.util.ExtendedMath.equatorialToHorizontal; +import static com.bingce.controlnetwork.func.level.util.suntime.util.ExtendedMath.refraction; +import static java.lang.Math.atan2; +import static java.lang.Math.cos; +import static java.lang.Math.sin; +import static java.lang.Math.tan; +import static java.lang.Math.toDegrees; + +import com.bingce.controlnetwork.func.level.util.suntime.param.Builder; +import com.bingce.controlnetwork.func.level.util.suntime.param.GenericParameter; +import com.bingce.controlnetwork.func.level.util.suntime.param.LocationParameter; +import com.bingce.controlnetwork.func.level.util.suntime.param.TimeParameter; +import com.bingce.controlnetwork.func.level.util.suntime.util.BaseBuilder; +import com.bingce.controlnetwork.func.level.util.suntime.util.JulianDate; +import com.bingce.controlnetwork.func.level.util.suntime.util.Moon; +import com.bingce.controlnetwork.func.level.util.suntime.util.Vector; + + +/** + * Calculates the position of the moon. + */ +public class MoonPosition { + + private final double azimuth; + private final double altitude; + private final double trueAltitude; + private final double distance; + private final double parallacticAngle; + + private MoonPosition(double azimuth, double altitude, double trueAltitude, double distance, double parallacticAngle) { + this.azimuth = (toDegrees(azimuth) + 180.0) % 360.0; + this.altitude = toDegrees(altitude); + this.trueAltitude = toDegrees(trueAltitude); + this.distance = distance; + this.parallacticAngle = toDegrees(parallacticAngle); + } + + /** + * Starts the computation of {@link MoonPosition}. + * + * @return {@link Parameters} to set. + */ + public static Parameters compute() { + return new MoonPositionBuilder(); + } + + /** + * Collects all parameters for {@link MoonPosition}. + */ + public interface Parameters extends + GenericParameter, + LocationParameter, + TimeParameter, + Builder { + } + + /** + * Builder for {@link MoonPosition}. Performs the computations based on the + * parameters, and creates a {@link MoonPosition} object that holds the result. + */ + private static class MoonPositionBuilder extends BaseBuilder implements Parameters { + @Override + public MoonPosition execute() { + if (!hasLocation()) { + throw new IllegalArgumentException("Geolocation is missing."); + } + + JulianDate t = getJulianDate(); + + double phi = getLatitudeRad(); + double lambda = getLongitudeRad(); + + Vector mc = Moon.position(t); + double h = t.getGreenwichMeanSiderealTime() + lambda - mc.getPhi(); + + Vector horizontal = equatorialToHorizontal(h, mc.getTheta(), mc.getR(), phi); + + double hRef = refraction(horizontal.getTheta()); + + double pa = atan2(sin(h), tan(phi) * cos(mc.getTheta()) - sin(mc.getTheta()) * cos(h)); + + return new MoonPosition( + horizontal.getPhi(), + horizontal.getTheta() + hRef, + horizontal.getTheta(), + mc.getR(), + pa); + } + } + + /** + * Moon altitude above the horizon, in degrees. + *

+ * {@code 0.0} means the moon's center is at the horizon, {@code 90.0} at the zenith + * (straight over your head). Atmospheric refraction is taken into account. + * + * @see #getTrueAltitude() + */ + public double getAltitude() { + return altitude; + } + + /** + * The true moon altitude above the horizon, in degrees. + *

+ * {@code 0.0} means the moon's center is at the horizon, {@code 90.0} at the zenith + * (straight over your head). + * + * @see #getAltitude() + * @since 3.8 + */ + public double getTrueAltitude() { + return trueAltitude; + } + + /** + * Moon azimuth, in degrees, north-based. + *

+ * This is the direction along the horizon, measured from north to east. For example, + * {@code 0.0} means north, {@code 135.0} means southeast, {@code 270.0} means west. + */ + public double getAzimuth() { + return azimuth; + } + + /** + * Distance to the moon in kilometers. + */ + public double getDistance() { + return distance; + } + + /** + * Parallactic angle of the moon, in degrees. + */ + public double getParallacticAngle() { + return parallacticAngle; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("MoonPosition[azimuth=").append(azimuth); + sb.append("°, altitude=").append(altitude); + sb.append("°, true altitude=").append(trueAltitude); + sb.append("°, distance=").append(distance); + sb.append(" km, parallacticAngle=").append(parallacticAngle); + sb.append("°]"); + return sb.toString(); + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/MoonTimes.java b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/MoonTimes.java new file mode 100644 index 0000000..82f940e --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/MoonTimes.java @@ -0,0 +1,255 @@ +/* + * Shredzone Commons - suncalc + * + * Copyright (C) 2017 Richard "Shred" Körber + * http://commons.shredzone.org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package com.bingce.controlnetwork.func.level.util.suntime; + +import static com.bingce.controlnetwork.func.level.util.suntime.util.ExtendedMath.apparentRefraction; +import static com.bingce.controlnetwork.func.level.util.suntime.util.ExtendedMath.parallax; +import static java.lang.Math.ceil; + +import androidx.annotation.Nullable; + +import com.bingce.controlnetwork.func.level.util.suntime.param.Builder; +import com.bingce.controlnetwork.func.level.util.suntime.param.GenericParameter; +import com.bingce.controlnetwork.func.level.util.suntime.param.LocationParameter; +import com.bingce.controlnetwork.func.level.util.suntime.param.TimeParameter; +import com.bingce.controlnetwork.func.level.util.suntime.util.BaseBuilder; +import com.bingce.controlnetwork.func.level.util.suntime.util.JulianDate; +import com.bingce.controlnetwork.func.level.util.suntime.util.Moon; +import com.bingce.controlnetwork.func.level.util.suntime.util.QuadraticInterpolation; +import com.bingce.controlnetwork.func.level.util.suntime.util.Vector; + +import java.time.Duration; +import java.time.ZonedDateTime; + + + +/** + * Calculates the times of the moon. + */ +public final class MoonTimes { + + private final @Nullable ZonedDateTime rise; + private final @Nullable ZonedDateTime set; + private final boolean alwaysUp; + private final boolean alwaysDown; + + private MoonTimes(@Nullable ZonedDateTime rise, @Nullable ZonedDateTime set, + boolean alwaysUp, boolean alwaysDown) { + this.rise = rise; + this.set = set; + this.alwaysUp = alwaysUp; + this.alwaysDown = alwaysDown; + } + + /** + * Starts the computation of {@link MoonTimes}. + * + * @return {@link Parameters} to set. + */ + public static Parameters compute() { + return new MoonTimesBuilder(); + } + + /** + * Collects all parameters for {@link MoonTimes}. + */ + public static interface Parameters extends + GenericParameter, + LocationParameter, + TimeParameter, + Builder { + + /** + * Limits the calculation window to the given {@link Duration}. + * + * @param duration Duration of the calculation window. Must be positive. + * @return itself + * @since 3.1 + */ + Parameters limit(Duration duration); + + /** + * Limits the time window to the next 24 hours. + * + * @return itself + */ + default Parameters oneDay() { + return limit(Duration.ofDays(1L)); + } + + /** + * Computes until all rise and set times are found. + *

+ * This is the default. + * + * @return itself + */ + default Parameters fullCycle() { + return limit(Duration.ofDays(365L)); + } + } + + /** + * Builder for {@link MoonTimes}. Performs the computations based on the parameters, + * and creates a {@link MoonTimes} object that holds the result. + */ + private static class MoonTimesBuilder extends BaseBuilder implements Parameters { + private Duration limit = Duration.ofDays(365L); + private double refraction = apparentRefraction(0.0); + + @Override + public Parameters limit(Duration duration) { + if (duration == null || duration.isNegative()) { + throw new IllegalArgumentException("duration must be positive"); + } + limit = duration; + return this; + } + + @Override + public MoonTimes execute() { + if (!hasLocation()) { + throw new IllegalArgumentException("Geolocation is missing."); + } + + JulianDate jd = getJulianDate(); + + Double rise = null; + Double set = null; + boolean alwaysUp = false; + boolean alwaysDown = false; + double ye; + + int hour = 0; + double limitHours = limit.toMillis() / (60 * 60 * 1000.0); + int maxHours = (int) ceil(limitHours); + + double y_minus = correctedMoonHeight(jd.atHour(hour - 1.0)); + double y_0 = correctedMoonHeight(jd.atHour(hour)); + double y_plus = correctedMoonHeight(jd.atHour(hour + 1.0)); + + if (y_0 > 0.0) { + alwaysUp = true; + } else { + alwaysDown = true; + } + + while (hour <= maxHours) { + QuadraticInterpolation qi = new QuadraticInterpolation(y_minus, y_0, y_plus); + ye = qi.getYe(); + + if (qi.getNumberOfRoots() == 1) { + double rt = qi.getRoot1() + hour; + if (y_minus < 0.0) { + if (rise == null && rt >= 0.0 && rt < limitHours) { + rise = rt; + alwaysDown = false; + } + } else { + if (set == null && rt >= 0.0 && rt < limitHours) { + set = rt; + alwaysUp = false; + } + } + } else if (qi.getNumberOfRoots() == 2) { + if (rise == null) { + double rt = hour + (ye < 0.0 ? qi.getRoot2() : qi.getRoot1()); + if (rt >= 0.0 && rt < limitHours) { + rise = rt; + alwaysDown = false; + } + } + if (set == null) { + double rt = hour + (ye < 0.0 ? qi.getRoot1() : qi.getRoot2()); + if (rt >= 0.0 && rt < limitHours) { + set = rt; + alwaysUp = false; + } + } + } + + if (rise != null && set != null) { + break; + } + + hour++; + y_minus = y_0; + y_0 = y_plus; + y_plus = correctedMoonHeight(jd.atHour(hour + 1.0)); + } + + return new MoonTimes( + rise != null ? jd.atHour(rise).getDateTime() : null, + set != null ? jd.atHour(set).getDateTime() : null, + alwaysUp, + alwaysDown); + } + + /** + * Computes the moon height at the given date and position. + * + * @param jd {@link JulianDate} to use + * @return height, in radians + */ + private double correctedMoonHeight(JulianDate jd) { + Vector pos = Moon.positionHorizontal(jd, getLatitudeRad(), getLongitudeRad()); + double hc = parallax(getElevation(), pos.getR()) + - refraction + - Moon.angularRadius(pos.getR()); + return pos.getTheta() - hc; + } + } + + /** + * Moonrise time. {@code null} if the moon does not rise that day. + */ + @Nullable + public ZonedDateTime getRise() { + return rise; + } + + /** + * Moonset time. {@code null} if the moon does not set that day. + */ + @Nullable + public ZonedDateTime getSet() { + return set; + } + + /** + * {@code true} if the moon never rises/sets, but is always above the horizon. + */ + public boolean isAlwaysUp() { + return alwaysUp; + } + + /** + * {@code true} if the moon never rises/sets, but is always below the horizon. + */ + public boolean isAlwaysDown() { + return alwaysDown; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("MoonTimes[rise=").append(rise); + sb.append(", set=").append(set); + sb.append(", alwaysUp=").append(alwaysUp); + sb.append(", alwaysDown=").append(alwaysDown); + sb.append(']'); + return sb.toString(); + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/SunPosition.java b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/SunPosition.java new file mode 100644 index 0000000..5932eaf --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/SunPosition.java @@ -0,0 +1,139 @@ +/* + * Shredzone Commons - suncalc + * + * Copyright (C) 2017 Richard "Shred" Körber + * http://commons.shredzone.org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package com.bingce.controlnetwork.func.level.util.suntime; + +import static com.bingce.controlnetwork.func.level.util.suntime.util.ExtendedMath.refraction; +import static java.lang.Math.toDegrees; + +import com.bingce.controlnetwork.func.level.util.suntime.param.Builder; +import com.bingce.controlnetwork.func.level.util.suntime.param.GenericParameter; +import com.bingce.controlnetwork.func.level.util.suntime.param.LocationParameter; +import com.bingce.controlnetwork.func.level.util.suntime.param.TimeParameter; +import com.bingce.controlnetwork.func.level.util.suntime.util.BaseBuilder; +import com.bingce.controlnetwork.func.level.util.suntime.util.JulianDate; +import com.bingce.controlnetwork.func.level.util.suntime.util.Sun; +import com.bingce.controlnetwork.func.level.util.suntime.util.Vector; + + +/** + * Calculates the position of the sun. + */ +public class SunPosition { + + private final double azimuth; + private final double altitude; + private final double trueAltitude; + private final double distance; + + private SunPosition(double azimuth, double altitude, double trueAltitude, double distance) { + this.azimuth = (toDegrees(azimuth) + 180.0) % 360.0; + this.altitude = toDegrees(altitude); + this.trueAltitude = toDegrees(trueAltitude); + this.distance = distance; + } + + /** + * Starts the computation of {@link SunPosition}. + * + * @return {@link Parameters} to set. + */ + public static Parameters compute() { + return new SunPositionBuilder(); + } + + /** + * Collects all parameters for {@link SunPosition}. + */ + public interface Parameters extends + GenericParameter, + LocationParameter, + TimeParameter, + Builder { + } + + /** + * Builder for {@link SunPosition}. Performs the computations based on the parameters, + * and creates a {@link SunPosition} object that holds the result. + */ + private static class SunPositionBuilder extends BaseBuilder implements Parameters { + @Override + public SunPosition execute() { + if (!hasLocation()) { + throw new IllegalArgumentException("Geolocation is missing."); + } + + JulianDate t = getJulianDate(); + + Vector horizontal = Sun.positionHorizontal(t, getLatitudeRad(), getLongitudeRad()); + double hRef = refraction(horizontal.getTheta()); + + return new SunPosition(horizontal.getPhi(), + horizontal.getTheta() + hRef, + horizontal.getTheta(), + horizontal.getR()); + } + } + + /** + * The visible sun altitude above the horizon, in degrees. + *

+ * {@code 0.0} means the sun's center is at the horizon, {@code 90.0} at the zenith + * (straight over your head). Atmospheric refraction is taken into account. + * + * @see #getTrueAltitude() + */ + public double getAltitude() { + return altitude; + } + + /** + * The true sun altitude above the horizon, in degrees. + *

+ * {@code 0.0} means the sun's center is at the horizon, {@code 90.0} at the zenith + * (straight over your head). + * + * @see #getAltitude() + */ + public double getTrueAltitude() { + return trueAltitude; + } + + /** + * Sun azimuth, in degrees, north-based. + *

+ * This is the direction along the horizon, measured from north to east. For example, + * {@code 0.0} means north, {@code 135.0} means southeast, {@code 270.0} means west. + */ + public double getAzimuth() { + return azimuth; + } + + /** + * Sun's distance, in kilometers. + */ + public double getDistance() { + return distance; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("SunPosition[azimuth=").append(azimuth); + sb.append("°, altitude=").append(altitude); + sb.append("°, true altitude=").append(trueAltitude); + sb.append("°, distance=").append(distance).append(" km]"); + return sb.toString(); + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/SunTimes.java b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/SunTimes.java new file mode 100644 index 0000000..bfeb6a8 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/SunTimes.java @@ -0,0 +1,487 @@ +/* + * Shredzone Commons - suncalc + * + * Copyright (C) 2017 Richard "Shred" Körber + * http://commons.shredzone.org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package com.bingce.controlnetwork.func.level.util.suntime; + +import static com.bingce.controlnetwork.func.level.util.suntime.util.ExtendedMath.apparentRefraction; +import static com.bingce.controlnetwork.func.level.util.suntime.util.ExtendedMath.parallax; +import static com.bingce.controlnetwork.func.level.util.suntime.util.ExtendedMath.readjustMax; +import static com.bingce.controlnetwork.func.level.util.suntime.util.ExtendedMath.readjustMin; +import static java.lang.Math.abs; +import static java.lang.Math.ceil; +import static java.lang.Math.toRadians; + +import androidx.annotation.Nullable; + +import com.bingce.controlnetwork.func.level.util.suntime.param.Builder; +import com.bingce.controlnetwork.func.level.util.suntime.param.GenericParameter; +import com.bingce.controlnetwork.func.level.util.suntime.param.LocationParameter; +import com.bingce.controlnetwork.func.level.util.suntime.param.TimeParameter; +import com.bingce.controlnetwork.func.level.util.suntime.util.BaseBuilder; +import com.bingce.controlnetwork.func.level.util.suntime.util.JulianDate; +import com.bingce.controlnetwork.func.level.util.suntime.util.QuadraticInterpolation; +import com.bingce.controlnetwork.func.level.util.suntime.util.Sun; +import com.bingce.controlnetwork.func.level.util.suntime.util.Vector; + +import java.time.Duration; +import java.time.ZonedDateTime; + + + +/** + * Calculates the rise and set times of the sun. + */ +public class SunTimes { + + private final @Nullable ZonedDateTime rise; + private final @Nullable ZonedDateTime set; + private final @Nullable ZonedDateTime noon; + private final @Nullable ZonedDateTime nadir; + private final boolean alwaysUp; + private final boolean alwaysDown; + + private SunTimes(@Nullable ZonedDateTime rise, @Nullable ZonedDateTime set, + @Nullable ZonedDateTime noon, @Nullable ZonedDateTime nadir, + boolean alwaysUp, boolean alwaysDown) { + this.rise = rise; + this.set = set; + this.noon = noon; + this.nadir = nadir; + this.alwaysUp = alwaysUp; + this.alwaysDown = alwaysDown; + } + + /** + * Starts the computation of {@link SunTimes}. + * + * @return {@link Parameters} to set. + */ + public static Parameters compute() { + return new SunTimesBuilder(); + } + + /** + * Collects all parameters for {@link SunTimes}. + */ + public interface Parameters extends + GenericParameter, + LocationParameter, + TimeParameter, + Builder { + + /** + * Sets the {@link Twilight} mode. + *

+ * Defaults to {@link Twilight#VISUAL}. + * + * @param twilight {@link Twilight} mode to be used. + * @return itself + */ + Parameters twilight(Twilight twilight); + + /** + * Sets the desired elevation angle of the sun. The sunrise and sunset times are + * referring to the moment when the center of the sun passes this angle. + * + * @param angle Geocentric elevation angle, in degrees. + * @return itself + */ + Parameters twilight(double angle); + + /** + * Limits the calculation window to the given {@link Duration}. + * + * @param duration Duration of the calculation window. Must be positive. + * @return itself + * @since 3.1 + */ + Parameters limit(Duration duration); + + /** + * Limits the time window to the next 24 hours. + * + * @return itself + */ + default Parameters oneDay() { + return limit(Duration.ofDays(1L)); + } + + /** + * Computes until all rise, set, noon, and nadir times are found. + *

+ * This is the default. + * + * @return itself + */ + default Parameters fullCycle() { + return limit(Duration.ofDays(365L)); + } + } + + /** + * Enumeration of predefined twilights. + *

+ * The twilight angles use a geocentric reference, by definition. However, + * {@link #VISUAL} and {@link #VISUAL_LOWER} are topocentric, and take the spectator's + * elevation and the atmospheric refraction into account. + * + * @see Wikipedia: Twilight + */ + public enum Twilight { + + /** + * The moment when the visual upper edge of the sun crosses the horizon. This is + * commonly referred to as "sunrise" and "sunset". Atmospheric refraction is taken + * into account. + *

+ * This is the default. + */ + VISUAL(0.0, 1.0), + + /** + * The moment when the visual lower edge of the sun crosses the horizon. This is + * the ending of the sunrise and the starting of the sunset. Atmospheric + * refraction is taken into account. + */ + VISUAL_LOWER(0.0, -1.0), + + /** + * The moment when the center of the sun crosses the horizon (0°). + */ + HORIZON(0.0), + + /** + * Civil twilight (-6°). + */ + CIVIL(-6.0), + + /** + * Nautical twilight (-12°). + */ + NAUTICAL(-12.0), + + /** + * Astronomical twilight (-18°). + */ + ASTRONOMICAL(-18.0), + + /** + * Golden hour (6°). The Golden hour is between {@link #GOLDEN_HOUR} and + * {@link #BLUE_HOUR}. The Magic hour is between {@link #GOLDEN_HOUR} and + * {@link #CIVIL}. + * + * @see Wikipedia: + * Golden hour + */ + GOLDEN_HOUR(6.0), + + /** + * Blue hour (-4°). The Blue hour is between {@link #NIGHT_HOUR} and + * {@link #BLUE_HOUR}. + * + * @see Wikipedia: Blue hour + */ + BLUE_HOUR(-4.0), + + /** + * End of Blue hour (-8°). + *

+ * "Night Hour" is not an official term, but just a name that is marking the + * beginning/end of the Blue hour. + */ + NIGHT_HOUR(-8.0); + + private final double angle; + private final double angleRad; + private final @Nullable Double position; + + Twilight(double angle) { + this(angle, null); + } + + Twilight(double angle, @Nullable Double position) { + this.angle = angle; + this.angleRad = toRadians(angle); + this.position = position; + } + + /** + * Returns the sun's angle at the twilight position, in degrees. + */ + public double getAngle() { + return angle; + } + + /** + * Returns the sun's angle at the twilight position, in radians. + */ + public double getAngleRad() { + return angleRad; + } + + /** + * Returns {@code true} if this twilight position is topocentric. Then the + * parallax and the atmospheric refraction is taken into account. + */ + public boolean isTopocentric() { + return position != null; + } + + /** + * Returns the angular position. {@code 0.0} means center of the sun. {@code 1.0} + * means upper edge of the sun. {@code -1.0} means lower edge of the sun. + * {@code null} means the angular position is not topocentric. + */ + @Nullable + private Double getAngularPosition() { + return position; + } + } + + /** + * Builder for {@link SunTimes}. Performs the computations based on the parameters, + * and creates a {@link SunTimes} object that holds the result. + */ + private static class SunTimesBuilder extends BaseBuilder implements Parameters { + private double angle = Twilight.VISUAL.getAngleRad(); + private @Nullable Double position = Twilight.VISUAL.getAngularPosition(); + private Duration limit = Duration.ofDays(365L); + + @Override + public Parameters twilight(Twilight twilight) { + this.angle = twilight.getAngleRad(); + this.position = twilight.getAngularPosition(); + return this; + } + + @Override + public Parameters twilight(double angle) { + this.angle = toRadians(angle); + this.position = null; + return this; + } + + @Override + public Parameters limit(Duration duration) { + if (duration == null || duration.isNegative()) { + throw new IllegalArgumentException("duration must be positive"); + } + limit = duration; + return this; + } + + @Override + public SunTimes execute() { + if (!hasLocation()) { + throw new IllegalArgumentException("Geolocation is missing."); + } + + JulianDate jd = getJulianDate(); + + Double rise = null; + Double set = null; + Double noon = null; + Double nadir = null; + boolean alwaysUp = false; + boolean alwaysDown = false; + double ye; + + int hour = 0; + double limitHours = limit.toMillis() / (60 * 60 * 1000.0); + int maxHours = (int) ceil(limitHours); + + double y_minus = correctedSunHeight(jd.atHour(hour - 1.0)); + double y_0 = correctedSunHeight(jd.atHour(hour)); + double y_plus = correctedSunHeight(jd.atHour(hour + 1.0)); + + if (y_0 > 0.0) { + alwaysUp = true; + } else { + alwaysDown = true; + } + + while (hour <= maxHours) { + QuadraticInterpolation qi = new QuadraticInterpolation(y_minus, y_0, y_plus); + ye = qi.getYe(); + + if (qi.getNumberOfRoots() == 1) { + double rt = qi.getRoot1() + hour; + if (y_minus < 0.0) { + if (rise == null && rt >= 0.0 && rt < limitHours) { + rise = rt; + alwaysDown = false; + } + } else { + if (set == null && rt >= 0.0 && rt < limitHours) { + set = rt; + alwaysUp = false; + } + } + } else if (qi.getNumberOfRoots() == 2) { + if (rise == null) { + double rt = hour + (ye < 0.0 ? qi.getRoot2() : qi.getRoot1()); + if (rt >= 0.0 && rt < limitHours) { + rise = rt; + alwaysDown = false; + } + } + if (set == null) { + double rt = hour + (ye < 0.0 ? qi.getRoot1() : qi.getRoot2()); + if (rt >= 0.0 && rt < limitHours) { + set = rt; + alwaysUp = false; + } + } + } + + double xeAbs = abs(qi.getXe()); + if (xeAbs <= 1.0) { + double xeHour = qi.getXe() + hour; + if (xeHour >= 0.0) { + if (qi.isMaximum()) { + if (noon == null) { + noon = xeHour; + } + } else { + if (nadir == null) { + nadir = xeHour; + } + } + } + } + + if (rise != null && set != null && noon != null && nadir != null) { + break; + } + + hour++; + y_minus = y_0; + y_0 = y_plus; + y_plus = correctedSunHeight(jd.atHour(hour + 1.0)); + } + + if (noon != null) { + noon = readjustMax(noon, 2.0, 14, t -> correctedSunHeight(jd.atHour(t))); + if (noon < 0.0 || noon >= limitHours) { + noon = null; + } + } + + if (nadir != null) { + nadir = readjustMin(nadir, 2.0, 14, t -> correctedSunHeight(jd.atHour(t))); + if (nadir < 0.0 || nadir >= limitHours) { + nadir = null; + } + } + + return new SunTimes( + rise != null ? jd.atHour(rise).getDateTime() : null, + set != null ? jd.atHour(set).getDateTime() : null, + noon != null ? jd.atHour(noon).getDateTime() : null, + nadir != null ? jd.atHour(nadir).getDateTime() : null, + alwaysUp, + alwaysDown + ); + } + + /** + * Computes the sun height at the given date and position. + * + * @param jd {@link JulianDate} to use + * @return height, in radians + */ + private double correctedSunHeight(JulianDate jd) { + Vector pos = Sun.positionHorizontal(jd, getLatitudeRad(), getLongitudeRad()); + + double hc = angle; + if (position != null) { + hc -= apparentRefraction(hc); + hc += parallax(getElevation(), pos.getR()); + hc -= position * Sun.angularRadius(pos.getR()); + } + + return pos.getTheta() - hc; + } + } + + /** + * Sunrise time. {@code null} if the sun does not rise that day. + *

+ * Always returns a sunrise time if {@link Parameters#fullCycle()} was set. + */ + @Nullable + public ZonedDateTime getRise() { + return rise; + } + + /** + * Sunset time. {@code null} if the sun does not set that day. + *

+ * Always returns a sunset time if {@link Parameters#fullCycle()} was set. + */ + @Nullable + public ZonedDateTime getSet() { + return set; + } + + /** + * The time when the sun reaches its highest point. + *

+ * Use {@link #isAlwaysDown()} to find out if the highest point is still below the + * twilight angle. + */ + @Nullable + public ZonedDateTime getNoon() { + return noon; + } + + /** + * The time when the sun reaches its lowest point. + *

+ * Use {@link #isAlwaysUp()} to find out if the lowest point is still above the + * twilight angle. + */ + @Nullable + public ZonedDateTime getNadir() { + return nadir; + } + + /** + * {@code true} if the sun never rises/sets, but is always above the twilight angle. + */ + public boolean isAlwaysUp() { + return alwaysUp; + } + + /** + * {@code true} if the sun never rises/sets, but is always below the twilight angle. + */ + public boolean isAlwaysDown() { + return alwaysDown; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("SunTimes[rise=").append(rise); + sb.append(", set=").append(set); + sb.append(", noon=").append(noon); + sb.append(", nadir=").append(nadir); + sb.append(", alwaysUp=").append(alwaysUp); + sb.append(", alwaysDown=").append(alwaysDown); + sb.append(']'); + return sb.toString(); + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/param/Builder.java b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/param/Builder.java new file mode 100644 index 0000000..f5b49f1 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/param/Builder.java @@ -0,0 +1,34 @@ +/* + * Shredzone Commons - suncalc + * + * Copyright (C) 2017 Richard "Shred" Körber + * http://commons.shredzone.org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package com.bingce.controlnetwork.func.level.util.suntime.param; + +/** + * An interface for the method that eventually executes the calculation. + * + * @param + * Result type + */ +public interface Builder { + + /** + * Executes the calculation and returns the desired result. + *

+ * The resulting object is immutable. You can change parameters, and then invoke + * {@link #execute()} again, to get a new object with new results. + * + * @return Result of the calculation. + */ + T execute(); + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/param/GenericParameter.java b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/param/GenericParameter.java new file mode 100644 index 0000000..1118077 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/param/GenericParameter.java @@ -0,0 +1,29 @@ +/* + * Shredzone Commons - suncalc + * + * Copyright (C) 2020 Richard "Shred" Körber + * http://commons.shredzone.org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package com.bingce.controlnetwork.func.level.util.suntime.param; + +/** + * Generic parameters and options. + * + * @param + * Type of the final builder + */ +public interface GenericParameter { + + /** + * Creates a copy of the current parameters. The copy can be changed independently. + */ + T copy(); + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/param/LocationParameter.java b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/param/LocationParameter.java new file mode 100644 index 0000000..c7535f2 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/param/LocationParameter.java @@ -0,0 +1,165 @@ +/* + * Shredzone Commons - suncalc + * + * Copyright (C) 2017 Richard "Shred" Körber + * http://commons.shredzone.org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package com.bingce.controlnetwork.func.level.util.suntime.param; + + +import static com.bingce.controlnetwork.func.level.util.suntime.util.ExtendedMath.dms; + +/** + * Location based parameters. + *

+ * Use them to give information about the geolocation of the observer. If ommitted, the + * coordinates of Null Island are + * used. + * + * @param Type of the final builder + */ +@SuppressWarnings("unchecked") +public interface LocationParameter { + + /** + * Sets the latitude. + * + * @param lat Latitude, in degrees. + * @return itself + */ + T latitude(double lat); + + /** + * Sets the longitude. + * + * @param lng Longitude, in degrees. + * @return itself + */ + T longitude(double lng); + + /** + * Sets the elevation. + * + * @param h Elevation, in meters above sea level. Default: 0.0 m. Negative values + * are silently changed to the acceptable minimum of 0.0 m. + * @return itself + * @see #elevationFt(double) + * @since 3.9 + */ + T elevation(double h); + + /** + * Sets the elevation, in foot. + * + * @param ft Elevation, in foot above sea level. Default: 0.0 ft. Negative values are + * silently changed to the acceptable minimum of 0.0 ft. + * @return itself + * @see #elevation(double) + * @since 3.9 + */ + default T elevationFt(double ft) { + return elevation(ft * 0.3048); + } + + /** + * Sets the height. + * + * @param h Height, in meters above sea level. Default: 0.0 m. Negative values are + * silently changed to the acceptable minimum of 0.0 m. + * @return itself + * @deprecated Use {@link #elevation(double)} instead. + */ + @Deprecated + default T height(double h) { + return elevation(h); + } + + /** + * Sets the height, in foot. + * + * @param ft Height, in foot above sea level. Default: 0.0 ft. Negative values are + * silently changed to the acceptable minimum of 0.0 ft. + * @return itself + * @since 3.8 + * @deprecated Use {@link #elevationFt(double)} instead. + */ + @Deprecated + default T heightFt(double ft) { + return elevationFt(ft); + } + + /** + * Sets the geolocation. + * + * @param lat Latitude, in degrees. + * @param lng Longitude, in degrees. + * @return itself + */ + default T at(double lat, double lng) { + latitude(lat); + longitude(lng); + return (T) this; + } + + /** + * Sets the geolocation. In the given array, index 0 must contain the latitude, and + * index 1 must contain the longitude. An optional index 2 may contain the elevation, + * in meters. + *

+ * This call is meant to be used for coordinates stored in constants. + * + * @param coords Array containing the latitude and longitude, in degrees. + * @return itself + */ + default T at(double[] coords) { + if (coords.length != 2 && coords.length != 3) { + throw new IllegalArgumentException("Array must contain 2 or 3 doubles"); + } + if (coords.length == 3) { + elevation(coords[2]); + } + return at(coords[0], coords[1]); + } + + /** + * Sets the latitude. + * + * @param d Degrees + * @param m Minutes + * @param s Seconds (and fraction of seconds) + * @return itself + */ + default T latitude(int d, int m, double s) { + return latitude(dms(d, m, s)); + } + + /** + * Sets the longitude. + * + * @param d Degrees + * @param m Minutes + * @param s Seconds (and fraction of seconds) + * @return itself + */ + default T longitude(int d, int m, double s) { + return longitude(dms(d, m, s)); + } + + /** + * Uses the same location as given in the {@link LocationParameter} at this moment. + *

+ * Changes to the source parameter will not affect this parameter, though. + * + * @param l {@link LocationParameter} to be used. + * @return itself + */ + T sameLocationAs(LocationParameter l); + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/param/TimeParameter.java b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/param/TimeParameter.java new file mode 100644 index 0000000..27fd9be --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/param/TimeParameter.java @@ -0,0 +1,244 @@ +/* + * Shredzone Commons - suncalc + * + * Copyright (C) 2017 Richard "Shred" Körber + * http://commons.shredzone.org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package com.bingce.controlnetwork.func.level.util.suntime.param; + +import java.time.Instant; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.util.Calendar; +import java.util.Date; +import java.util.Objects; +import java.util.TimeZone; + +/** + * Time based parameters. + *

+ * Use them to give information about the desired time. If ommitted, the current time and + * the system's time zone is used. + * + * @param + * Type of the final builder + */ +@SuppressWarnings("unchecked") +public interface TimeParameter { + + /** + * Sets date and time. Note that also seconds can be passed in for convenience, but + * the results are not that accurate. + * + * @param year + * Year + * @param month + * Month (1 = January, 2 = February, ...) + * @param date + * Day of month + * @param hour + * Hour of day + * @param minute + * Minute + * @param second + * Second + * @return itself + */ + T on(int year, int month, int date, int hour, int minute, int second); + + /** + * Sets midnight of the year, month and date. + * + * @param year + * Year + * @param month + * Month (1 = January, 2 = February, ...) + * @param date + * Day of month + * @return itself + */ + default T on(int year, int month, int date) { + return on(year, month, date, 0, 0, 0); + } + + /** + * Uses the given {@link ZonedDateTime} instance. + * + * @param dateTime + * {@link ZonedDateTime} to be used. + * @return itself + */ + T on(ZonedDateTime dateTime); + + /** + * Uses the given {@link LocalDateTime} instance. + * + * @param dateTime + * {@link LocalDateTime} to be used. + * @return itself + */ + T on(LocalDateTime dateTime); + + /** + * Uses the given {@link LocalDate} instance, and assumes midnight. + * + * @param date + * {@link LocalDate} to be used. + * @return itself + */ + T on(LocalDate date); + + /** + * Uses the given {@link Instant} instance. + * + * @param instant + * {@link Instant} to be used. + * @return itself + */ + T on(Instant instant); + + /** + * Uses the given {@link Date} instance. + * + * @param date + * {@link Date} to be used. + * @return itself + */ + default T on(Date date) { + Objects.requireNonNull(date, "date"); + return on(date.toInstant()); + } + + /** + * Uses the given {@link Calendar} instance. + * + * @param cal + * {@link Calendar} to be used + * @return itself + */ + default T on(Calendar cal) { + Objects.requireNonNull(cal, "cal"); + return on(ZonedDateTime.ofInstant(cal.toInstant(), cal.getTimeZone().toZoneId())); + } + + /** + * Sets the current date and time. This is the default. + * + * @return itself + */ + T now(); + + /** + * Sets the time to the start of the current date ("last midnight"). + * + * @return itself + */ + T midnight(); + + /** + * Adds a number of days to the current date. + * + * @param days + * Number of days to add + * @return itself + */ + T plusDays(int days); + + /** + * Sets today, midnight. + *

+ * It is the same as now().midnight(). + * + * @return itself + */ + default T today() { + now(); + midnight(); + return (T) this; + } + + /** + * Sets tomorrow, midnight. + *

+ * It is the same as now().midnight().plusDays(1). + * + * @return itself + */ + default T tomorrow() { + today(); + plusDays(1); + return (T) this; + } + + /** + * Sets the given {@link ZoneId}. The local time is retained, so the parameter order + * is not important. + * + * @param tz + * {@link ZoneId} to be used. + * @return itself + */ + T timezone(ZoneId tz); + + /** + * Sets the given timezone. This is a convenience method that just invokes + * {@link ZoneId#of(String)}. + * + * @param id + * ID of the time zone. + * @return itself + * @see ZoneId#of(String) + */ + default T timezone(String id) { + return timezone(ZoneId.of(id)); + } + + /** + * Sets the system's timezone. This is the default. + * + * @return itself + */ + default T localTime() { + return timezone(ZoneId.systemDefault()); + } + + /** + * Sets the time zone to UTC. + * + * @return itself + */ + default T utc() { + return timezone("UTC"); + } + + /** + * Sets the {@link TimeZone}. + * + * @param tz {@link TimeZone} to be used + * @return itself + */ + default T timezone(TimeZone tz) { + Objects.requireNonNull(tz, "tz"); + return timezone(tz.toZoneId()); + } + + /** + * Uses the same time as given in the {@link TimeParameter}. + *

+ * Changes to the source parameter will not affect this parameter, though. + * + * @param t {@link TimeParameter} to be used. + * @return itself + */ + T sameTimeAs(TimeParameter t); + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/util/BaseBuilder.java b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/util/BaseBuilder.java new file mode 100644 index 0000000..b85e092 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/util/BaseBuilder.java @@ -0,0 +1,236 @@ +/* + * Shredzone Commons - suncalc + * + * Copyright (C) 2017 Richard "Shred" Körber + * http://commons.shredzone.org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package com.bingce.controlnetwork.func.level.util.suntime.util; + +import static java.lang.Math.max; +import static java.lang.Math.toRadians; + +import androidx.annotation.Nullable; + +import com.bingce.controlnetwork.func.level.util.suntime.param.GenericParameter; +import com.bingce.controlnetwork.func.level.util.suntime.param.LocationParameter; +import com.bingce.controlnetwork.func.level.util.suntime.param.TimeParameter; + +import java.time.Instant; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.time.temporal.ChronoUnit; +import java.util.Objects; + + + +/** + * A base implementation of {@link LocationParameter} and {@link TimeParameter}. + *

+ * For internal use only. + * + * @param Type of the final builder + */ +@SuppressWarnings("unchecked") +public class BaseBuilder implements GenericParameter, LocationParameter, + TimeParameter, Cloneable { + + private @Nullable Double lat = null; + private @Nullable Double lng = null; + private double elevation = 0.0; + private ZonedDateTime dateTime = ZonedDateTime.now(); + + @Override + public T on(ZonedDateTime dateTime) { + this.dateTime = Objects.requireNonNull(dateTime, "dateTime"); + return (T) this; + } + + @Override + public T on(LocalDateTime dateTime) { + Objects.requireNonNull(dateTime, "dateTime"); + return on(ZonedDateTime.of(dateTime, this.dateTime.getZone())); + } + + @Override + public T on(LocalDate date) { + Objects.requireNonNull(date, "date"); + return on(ZonedDateTime.of(date, LocalTime.MIDNIGHT, dateTime.getZone())); + } + + @Override + public T on(Instant instant) { + Objects.requireNonNull(instant, "instant"); + return on(ZonedDateTime.ofInstant(instant, dateTime.getZone())); + } + + @Override + public T on(int year, int month, int date, int hour, int minute, int second) { + return on(ZonedDateTime.of(year, month, date, hour, minute, second, 0, dateTime.getZone())); + } + + @Override + public T now() { + return on(ZonedDateTime.now(dateTime.getZone())); + } + + @Override + public T plusDays(int days) { + return on(dateTime.plusDays(days)); + } + + @Override + public T midnight() { + return on(dateTime.truncatedTo(ChronoUnit.DAYS)); + } + + @Override + public T timezone(ZoneId tz) { + Objects.requireNonNull(tz, "tz"); + on(dateTime.withZoneSameLocal(tz)); + return (T) this; + } + + @Override + public T latitude(double lat) { + if (lat < -90.0 || lat > 90.0) { + throw new IllegalArgumentException("Latitude out of range, -90.0 <= " + lat + " <= 90.0"); + } + this.lat = lat; + return (T) this; + } + + @Override + public T longitude(double lng) { + if (lng < -180.0 || lng > 180.0) { + throw new IllegalArgumentException("Longitude out of range, -180.0 <= " + lng + " <= 180.0"); + } + this.lng = lng; + return (T) this; + } + + @Override + public T elevation(double h) { + this.elevation = max(h, 0.0); + return (T) this; + } + + @Override + public T sameTimeAs(TimeParameter t) { + if (!(t instanceof BaseBuilder)) { + throw new IllegalArgumentException("Cannot read the TimeParameter"); + } + this.dateTime = ((BaseBuilder) t).dateTime; + return (T) this; + } + + @Override + public T sameLocationAs(LocationParameter l) { + if (!(l instanceof BaseBuilder)) { + throw new IllegalArgumentException("Cannot read the LocationParameter"); + } + BaseBuilder origin = (BaseBuilder) l; + this.lat = origin.lat; + this.lng = origin.lng; + this.elevation = origin.elevation; + return (T) this; + } + + @Override + public T copy() { + try { + return (T) clone(); + } catch (CloneNotSupportedException ex) { + throw new RuntimeException(ex); // Should never be thrown anyway + } + } + + /** + * Returns the longitude. + * + * @return Longitude, in degrees. + */ + public double getLongitude() { + if (lng == null) { + throw new IllegalStateException("longitude is not set"); + } + return lng; + } + + /** + * Returns the latitude. + * + * @return Latitude, in degrees. + */ + public double getLatitude() { + if (lat == null) { + throw new IllegalStateException("latitude is not set"); + } + return lat; + } + + /** + * Returns the longitude. + * + * @return Longitude, in radians. + */ + public double getLongitudeRad() { + return toRadians(getLongitude()); + } + + /** + * Returns the latitude. + * + * @return Latitude, in radians. + */ + public double getLatitudeRad() { + return toRadians(getLatitude()); + } + + /** + * Returns the elevation, in meters above sea level. + * + * @return Elevation, meters above sea level + */ + public double getElevation() { + return elevation; + } + + /** + * Returns the {@link JulianDate} to be used. + * + * @return {@link JulianDate} + */ + public JulianDate getJulianDate() { + return new JulianDate(dateTime); + } + + /** + * Returns {@code true} if a geolocation has been set. + * + * @since 3.9 + */ + public boolean hasLocation() { + return lat != null && lng != null; + } + + /** + * Unset the geolocation. + * + * @since 3.9 + */ + public void clearLocation() { + lat = null; + lng = null; + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/util/ExtendedMath.java b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/util/ExtendedMath.java new file mode 100644 index 0000000..8141fda --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/util/ExtendedMath.java @@ -0,0 +1,275 @@ +/* + * Shredzone Commons - suncalc + * + * Copyright (C) 2017 Richard "Shred" Körber + * http://commons.shredzone.org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package com.bingce.controlnetwork.func.level.util.suntime.util; + +import static java.lang.Math.PI; +import static java.lang.Math.abs; +import static java.lang.Math.acos; +import static java.lang.Math.asin; +import static java.lang.Math.round; +import static java.lang.Math.signum; +import static java.lang.Math.tan; +import static java.lang.Math.toDegrees; +import static java.lang.Math.toRadians; + +import java.util.Comparator; +import java.util.function.Function; + +/** + * Contains constants and mathematical operations that are not available in {@link Math}. + */ +public final class ExtendedMath { + + /** + * PI * 2 + */ + public static final double PI2 = PI * 2.0; + + /** + * Arc-Seconds per Radian. + */ + public static final double ARCS = toDegrees(3600.0); + + /** + * Mean radius of the earth, in kilometers. + */ + public static final double EARTH_MEAN_RADIUS = 6371.0; + + /** + * Refraction at the horizon, in radians. + */ + public static final double REFRACTION_AT_HORIZON = PI / (tan(toRadians(7.31 / 4.4)) * 10800.0); + + private ExtendedMath() { + // utility class without constructor + } + + /** + * Returns the decimal part of a value. + * + * @param a + * Value + * @return Fraction of that value. It has the same sign as the input value. + */ + public static double frac(double a) { + return a % 1.0; + } + + /** + * Performs a safe check if the given double is actually zero (0.0). + *

+ * Note that "almost zero" returns {@code false}, so this method should not be used + * for comparing calculation results to zero. + * + * @param d + * double to check for zero. + * @return {@code true} if the value was zero, or negative zero. + */ + public static boolean isZero(double d) { + // This should keep squid:S1244 silent... + return !Double.isNaN(d) && round(signum(d)) == 0L; + } + + /** + * Converts equatorial coordinates to horizontal coordinates. + * + * @param tau + * Hour angle (radians) + * @param dec + * Declination (radians) + * @param dist + * Distance of the object + * @param lat + * Latitude of the observer (radians) + * @return {@link Vector} containing the horizontal coordinates + */ + public static Vector equatorialToHorizontal(double tau, double dec, double dist, double lat) { + return Matrix.rotateY(PI / 2.0 - lat).multiply(Vector.ofPolar(tau, dec, dist)); + } + + /** + * Creates a rotational {@link Matrix} for converting equatorial to ecliptical + * coordinates. + * + * @param t + * {@link JulianDate} to use + * @return {@link Matrix} for converting equatorial to ecliptical coordinates + */ + public static Matrix equatorialToEcliptical(JulianDate t) { + double jc = t.getJulianCentury(); + double eps = toRadians(23.43929111 - (46.8150 + (0.00059 - 0.001813 * jc) * jc) * jc / 3600.0); + return Matrix.rotateX(eps); + } + + /** + * Returns the parallax for objects at the horizon. + * + * @param elevation + * Observer's elevation, in meters above sea level. Must not be negative. + * @param distance + * Distance of the object, in kilometers. + * @return parallax, in radians + */ + public static double parallax(double elevation, double distance) { + return asin(EARTH_MEAN_RADIUS / distance) + - acos(EARTH_MEAN_RADIUS / (EARTH_MEAN_RADIUS + (elevation / 1000.0))); + } + + /** + * Calculates the atmospheric refraction of an object at the given apparent altitude. + *

+ * The result is only valid for positive altitude angles. If negative, 0.0 is + * returned. + *

+ * Assumes an atmospheric pressure of 1010 hPa and a temperature of 10 °C. + * + * @param ha + * Apparent altitude, in radians. + * @return Refraction at this altitude + * @see Wikipedia: + * Atmospheric Refraction + */ + public static double apparentRefraction(double ha) { + if (ha < 0.0) { + return 0.0; + } + + if (isZero(ha)) { + return REFRACTION_AT_HORIZON; + } + + return PI / (tan(toRadians(ha + (7.31 / (ha + 4.4)))) * 10800.0); + } + + /** + * Calculates the atmospheric refraction of an object at the given altitude. + *

+ * The result is only valid for positive altitude angles. If negative, 0.0 is + * returned. + *

+ * Assumes an atmospheric pressure of 1010 hPa and a temperature of 10 °C. + * + * @param h + * True altitude, in radians. + * @return Refraction at this altitude + * @see Wikipedia: + * Atmospheric Refraction + */ + public static double refraction(double h) { + if (h < 0.0) { + return 0.0; + } + + // refraction formula, converted to radians + return 0.000296706 / tan(h + 0.00312537 / (h + 0.0890118)); + } + + /** + * Converts dms to double. + * + * @param d + * Degrees. Sign is used for result. + * @param m + * Minutes. Sign is ignored. + * @param s + * Seconds and fractions. Sign is ignored. + * @return angle, in degrees + */ + public static double dms(int d, int m, double s) { + double sig = d < 0 ? -1.0 : 1.0; + return sig * ((abs(s) / 60.0 + abs(m)) / 60.0 + abs(d)); + } + + /** + * Locates the true maximum within the given time frame. + * + * @param time + * Base time + * @param frame + * Time frame, which is added to and subtracted from the base time for the + * interval + * @param depth + * Maximum recursion depth. For each recursion, the function is invoked once. + * @param f + * Function to be used for calculation + * @return time of the true maximum + */ + public static double readjustMax(double time, double frame, int depth, Function f) { + double left = time - frame; + double right = time + frame; + double leftY = f.apply(left); + double rightY = f.apply(right); + + return readjustInterval(left, right, leftY, rightY, depth, f, Double::compare); + } + + /** + * Locates the true minimum within the given time frame. + * + * @param time + * Base time + * @param frame + * Time frame, which is added to and subtracted from the base time for the + * interval + * @param depth + * Maximum recursion depth. For each recursion, the function is invoked once. + * @param f + * Function to be used for calculation + * @return time of the true minimum + */ + public static double readjustMin(double time, double frame, int depth, Function f) { + double left = time - frame; + double right = time + frame; + double leftY = f.apply(left); + double rightY = f.apply(right); + + return readjustInterval(left, right, leftY, rightY, depth, f, (yl, yr) -> Double.compare(yr, yl)); + } + + /** + * Recursively find the true maximum/minimum within the given time frame. + * + * @param left + * Left interval border + * @param right + * Right interval border + * @param yl + * Function result at the left interval + * @param yr + * Function result at the right interval + * @param depth + * Maximum recursion depth. For each recursion, the function is invoked once. + * @param f + * Function to invoke + * @param cmp + * Comparator to decide whether the left or right side of the interval half is + * to be used + * @return Position of the approximated minimum/maximum + */ + private static double readjustInterval(double left, double right, double yl, double yr, int depth, + Function f, Comparator cmp) { + if (depth <= 0) { + return (cmp.compare(yl, yr) < 0) ? right : left; + } + + double middle = (left + right) / 2.0; + double ym = f.apply(middle); + if (cmp.compare(yl, yr) < 0) { + return readjustInterval(middle, right, ym, yr, depth - 1, f, cmp); + } else { + return readjustInterval(left, middle, yl, ym, depth - 1, f, cmp); + } + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/util/JulianDate.java b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/util/JulianDate.java new file mode 100644 index 0000000..989a5f5 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/util/JulianDate.java @@ -0,0 +1,146 @@ +/* + * Shredzone Commons - suncalc + * + * Copyright (C) 2017 Richard "Shred" Körber + * http://commons.shredzone.org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package com.bingce.controlnetwork.func.level.util.suntime.util; + +import static com.bingce.controlnetwork.func.level.util.suntime.util.ExtendedMath.PI2; +import static com.bingce.controlnetwork.func.level.util.suntime.util.ExtendedMath.frac; +import static java.lang.Math.floor; +import static java.lang.Math.round; + + +import java.time.Instant; +import java.time.ZonedDateTime; +import java.util.Objects; + +/** + * This class contains a Julian Date representation of a date. + *

+ * Objects are immutable and threadsafe. + */ +public class JulianDate { + + private final ZonedDateTime dateTime; + private final double mjd; + + /** + * Creates a new {@link JulianDate}. + * + * @param time {@link ZonedDateTime} to use for the date. + */ + public JulianDate(ZonedDateTime time) { + dateTime = Objects.requireNonNull(time, "time"); + mjd = dateTime.toInstant().toEpochMilli() / 86400000.0 + 40587.0; + } + + /** + * Returns a {@link JulianDate} of the current date and the given hour. + * + * @param hour Hour of this date. This is a floating point value. Fractions are used + * for minutes and seconds. + * @return {@link JulianDate} instance. + */ + public JulianDate atHour(double hour) { + return new JulianDate(dateTime.plusSeconds(round(hour * 60.0 * 60.0))); + } + + /** + * Returns a {@link JulianDate} of the given modified Julian date. + * + * @param mjd Modified Julian Date + * @return {@link JulianDate} instance. + */ + public JulianDate atModifiedJulianDate(double mjd) { + Instant mjdi = Instant.ofEpochMilli(Math.round((mjd - 40587.0) * 86400000.0)); + return new JulianDate(ZonedDateTime.ofInstant(mjdi, dateTime.getZone())); + } + + /** + * Returns a {@link JulianDate} of the given Julian century. + * + * @param jc Julian Century + * @return {@link JulianDate} instance. + */ + public JulianDate atJulianCentury(double jc) { + return atModifiedJulianDate(jc * 36525.0 + 51544.5); + } + + /** + * Returns this {@link JulianDate} as {@link ZonedDateTime} object. + * + * @return {@link ZonedDateTime} of this {@link JulianDate}. + */ + public ZonedDateTime getDateTime() { + return dateTime; + } + + /** + * Returns the Modified Julian Date. + * + * @return Modified Julian Date, UTC. + */ + public double getModifiedJulianDate() { + return mjd; + } + + /** + * Returns the Julian Centuries. + * + * @return Julian Centuries, based on J2000 epoch, UTC. + */ + public double getJulianCentury() { + return (mjd - 51544.5) / 36525.0; + } + + /** + * Returns the Greenwich Mean Sidereal Time of this Julian Date. + * + * @return GMST + */ + public double getGreenwichMeanSiderealTime() { + final double secs = 86400.0; + + double mjd0 = floor(mjd); + double ut = (mjd - mjd0) * secs; + double t0 = (mjd0 - 51544.5) / 36525.0; + double t = (mjd - 51544.5) / 36525.0; + + double gmst = 24110.54841 + + 8640184.812866 * t0 + + 1.0027379093 * ut + + (0.093104 - 6.2e-6 * t) * t * t; + + return (PI2 / secs) * (gmst % secs); + } + + /** + * Returns the earth's true anomaly of the current date. + *

+ * A simple approximation is used here. + * + * @return True anomaly, in radians + */ + public double getTrueAnomaly() { + return PI2 * frac((dateTime.getDayOfYear() - 5.0) / 365.256363); + } + + @Override + public String toString() { + return String.format("%dd %02dh %02dm %02ds", + (long) mjd, + (long) (mjd * 24 % 24), + (long) (mjd * 24 * 60 % 60), + (long) (mjd * 24 * 60 * 60 % 60)); + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/util/Matrix.java b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/util/Matrix.java new file mode 100644 index 0000000..c1b80dc --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/util/Matrix.java @@ -0,0 +1,287 @@ +/* + * Shredzone Commons - suncalc + * + * Copyright (C) 2017 Richard "Shred" Körber + * http://commons.shredzone.org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package com.bingce.controlnetwork.func.level.util.suntime.util; + +import static java.lang.Math.cos; +import static java.lang.Math.sin; + +import java.util.Arrays; + +/** + * A three dimensional matrix. + *

+ * Objects are immutable and threadsafe. + */ +public class Matrix { + + private final double[] mx; + + private Matrix() { + mx = new double[9]; + } + + private Matrix(double... values) { + if (values == null || values.length != 9) { + throw new IllegalArgumentException("requires 9 values"); + } + mx = values; + } + + /** + * Creates an identity matrix. + * + * @return Identity {@link Matrix} + */ + public static Matrix identity() { + return new Matrix( + 1.0, 0.0, 0.0, + 0.0, 1.0, 0.0, + 0.0, 0.0, 1.0); + } + + /** + * Creates a matrix that rotates a vector by the given angle at the X axis. + * + * @param angle + * angle, in radians + * @return Rotation {@link Matrix} + */ + public static Matrix rotateX(double angle) { + double s = sin(angle); + double c = cos(angle); + return new Matrix( + 1.0, 0.0, 0.0, + 0.0, c, s, + 0.0, -s, c + ); + } + + /** + * Creates a matrix that rotates a vector by the given angle at the Y axis. + * + * @param angle + * angle, in radians + * @return Rotation {@link Matrix} + */ + public static Matrix rotateY(double angle) { + double s = sin(angle); + double c = cos(angle); + return new Matrix( + c, 0.0, -s, + 0.0, 1.0, 0.0, + s, 0.0, c + ); + } + + /** + * Creates a matrix that rotates a vector by the given angle at the Z axis. + * + * @param angle + * angle, in radians + * @return Rotation {@link Matrix} + */ + public static Matrix rotateZ(double angle) { + double s = sin(angle); + double c = cos(angle); + return new Matrix( + c, s, 0.0, + -s, c, 0.0, + 0.0, 0.0, 1.0 + ); + } + + /** + * Transposes this matrix. + * + * @return {@link Matrix} that is a transposition of this matrix. + */ + public Matrix transpose() { + Matrix result = new Matrix(); + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + result.set(i, j, get(j, i)); + } + } + return result; + } + + /** + * Negates this matrix. + * + * @return {@link Matrix} that is a negation of this matrix. + */ + public Matrix negate() { + Matrix result = new Matrix(); + for (int i = 0; i < 9; i++) { + result.mx[i] = -mx[i]; + } + return result; + } + + /** + * Adds a matrix to this matrix. + * + * @param right + * {@link Matrix} to add + * @return {@link Matrix} that is a sum of both matrices + */ + public Matrix add(Matrix right) { + Matrix result = new Matrix(); + for (int i = 0; i < 9; i++) { + result.mx[i] = mx[i] + right.mx[i]; + } + return result; + } + + /** + * Subtracts a matrix from this matrix. + * + * @param right + * {@link Matrix} to subtract + * @return {@link Matrix} that is the difference of both matrices + */ + public Matrix subtract(Matrix right) { + Matrix result = new Matrix(); + for (int i = 0; i < 9; i++) { + result.mx[i] = mx[i] - right.mx[i]; + } + return result; + } + + /** + * Multiplies two matrices. + * + * @param right + * {@link Matrix} to multiply with + * @return {@link Matrix} that is the product of both matrices + */ + public Matrix multiply(Matrix right) { + Matrix result = new Matrix(); + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + double scalp = 0.0; + for (int k = 0; k < 3; k++) { + scalp += get(i, k) * right.get(k, j); + } + result.set(i, j, scalp); + } + } + return result; + } + + /** + * Performs a scalar multiplication. + * + * @param scalar + * Scalar to multiply with + * @return {@link Matrix} that is the scalar product + */ + public Matrix multiply(double scalar) { + Matrix result = new Matrix(); + for (int i = 0; i < 9; i++) { + result.mx[i] = mx[i] * scalar; + } + return result; + } + + /** + * Applies this matrix to a {@link Vector}. + * + * @param right + * {@link Vector} to multiply with + * @return {@link Vector} that is the product of this matrix and the given vector + */ + public Vector multiply(Vector right) { + double[] vec = new double[] {right.getX(), right.getY(), right.getZ()}; + double[] result = new double[3]; + + for (int i = 0; i < 3; i++) { + double scalp = 0.0; + for (int j = 0; j < 3; j++) { + scalp += get(i, j) * vec[j]; + } + result[i] = scalp; + } + + return new Vector(result); + } + + /** + * Gets a value from the matrix. + * + * @param r + * Row number (0..2) + * @param c + * Column number (0..2) + * @return Value at that position + */ + public double get(int r, int c) { + if (r < 0 || r > 2 || c < 0 || c > 2) { + throw new IllegalArgumentException("row/column out of range: " + r + ":" + c); + } + return mx[r * 3 + c]; + } + + /** + * Changes a value in the matrix. As a {@link Matrix} object is immutable from the + * outside, this method is private. + * + * @param r + * Row number (0..2) + * @param c + * Column number (0..2) + * @param v + * New value + */ + private void set(int r, int c, double v) { + if (r < 0 || r > 2 || c < 0 || c > 2) { + throw new IllegalArgumentException("row/column out of range: " + r + ":" + c); + } + mx[r * 3 + c] = v; + } + + @Override + public boolean equals(Object obj) { + if (obj == null || !(obj instanceof Matrix)) { + return false; + } + return Arrays.equals(mx, ((Matrix) obj).mx); + } + + @Override + public int hashCode() { + return Arrays.hashCode(mx); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append('['); + for (int ix = 0; ix < 9; ix++) { + if (ix % 3 == 0) { + sb.append('['); + } + sb.append(mx[ix]); + if (ix % 3 == 2) { + sb.append(']'); + } + if (ix < 8) { + sb.append(", "); + } + } + sb.append(']'); + return sb.toString(); + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/util/Moon.java b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/util/Moon.java new file mode 100644 index 0000000..d987162 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/util/Moon.java @@ -0,0 +1,154 @@ +/* + * Shredzone Commons - suncalc + * + * Copyright (C) 2017 Richard "Shred" Körber + * http://commons.shredzone.org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package com.bingce.controlnetwork.func.level.util.suntime.util; + +import static com.bingce.controlnetwork.func.level.util.suntime.util.ExtendedMath.ARCS; +import static com.bingce.controlnetwork.func.level.util.suntime.util.ExtendedMath.PI2; +import static com.bingce.controlnetwork.func.level.util.suntime.util.ExtendedMath.equatorialToEcliptical; +import static com.bingce.controlnetwork.func.level.util.suntime.util.ExtendedMath.equatorialToHorizontal; +import static com.bingce.controlnetwork.func.level.util.suntime.util.ExtendedMath.frac; +import static com.bingce.controlnetwork.func.level.util.suntime.util.ExtendedMath.parallax; +import static java.lang.Math.asin; +import static java.lang.Math.cos; +import static java.lang.Math.sin; + + +/** + * Calculations and constants for the Moon. + * + * @see "Astronomy on the Personal Computer, 4th edition + * (Oliver Montenbruck, Thomas Pfleger) - + * ISBN 978-3-540-67221-0" + */ +public final class Moon { + + private static final double MOON_MEAN_RADIUS = 1737.1; + + private Moon() { + // Utility class without constructor + } + + /** + * Calculates the equatorial position of the moon. + * + * @param date {@link JulianDate} to be used + * @return {@link Vector} of equatorial moon position + */ + public static Vector positionEquatorial(JulianDate date) { + double T = date.getJulianCentury(); + double L0 = frac(0.606433 + 1336.855225 * T); + double l = PI2 * frac(0.374897 + 1325.552410 * T); + double ls = PI2 * frac(0.993133 + 99.997361 * T); + double D = PI2 * frac(0.827361 + 1236.853086 * T); + double F = PI2 * frac(0.259086 + 1342.227825 * T); + double D2 = 2.0 * D; + double l2 = 2.0 * l; + double F2 = 2.0 * F; + + double dL = 22640.0 * sin(l) + - 4586.0 * sin(l - D2) + + 2370.0 * sin(D2) + + 769.0 * sin(l2) + - 668.0 * sin(ls) + - 412.0 * sin(F2) + - 212.0 * sin(l2 - D2) + - 206.0 * sin(l + ls - D2) + + 192.0 * sin(l + D2) + - 165.0 * sin(ls - D2) + - 125.0 * sin(D) + - 110.0 * sin(l + ls) + + 148.0 * sin(l - ls) + - 55.0 * sin(F2 - D2); + + double S = F + (dL + 412.0 * sin(F2) + 541.0 * sin(ls)) / ARCS; + double h = F - D2; + double N = -526.0 * sin(h) + + 44.0 * sin(l + h) + - 31.0 * sin(-l + h) + - 23.0 * sin(ls + h) + + 11.0 * sin(-ls + h) + - 25.0 * sin(-l2 + F) + + 21.0 * sin(-l + F); + + double l_Moon = PI2 * frac(L0 + dL / 1296.0e3); + double b_Moon = (18520.0 * sin(S) + N) / ARCS; + + double dt = 385000.5584 + - 20905.3550 * cos(l) + - 3699.1109 * cos(D2 - l) + - 2955.9676 * cos(D2) + - 569.9251 * cos(l2); + + return Vector.ofPolar(l_Moon, b_Moon, dt); + } + + /** + * Calculates the geocentric position of the moon. + * + * @param date {@link JulianDate} to be used + * @return {@link Vector} of geocentric moon position + */ + public static Vector position(JulianDate date) { + Matrix rotateMatrix = equatorialToEcliptical(date).transpose(); + return rotateMatrix.multiply(positionEquatorial(date)); + } + + /** + * Calculates the horizontal position of the moon. + * + * @param date {@link JulianDate} to be used + * @param lat Latitude, in radians + * @param lng Longitute, in radians + * @return {@link Vector} of horizontal moon position + */ + public static Vector positionHorizontal(JulianDate date, double lat, double lng) { + Vector mc = position(date); + double h = date.getGreenwichMeanSiderealTime() + lng - mc.getPhi(); + return equatorialToHorizontal(h, mc.getTheta(), mc.getR(), lat); + } + + /** + * Calculates the topocentric position of the moon. + *

+ * Atmospheric refraction is not taken into account. + * + * @param date {@link JulianDate} to be used + * @param lat Latitude, in radians + * @param lng Longitute, in radians + * @param elev Elevation, in meters + * @return {@link Vector} of topocentric moon position + * @since 3.9 + */ + public static Vector positionTopocentric(JulianDate date, double lat, double lng, double elev) { + Vector pos = positionHorizontal(date, lat, lng); + return Vector.ofPolar( + pos.getPhi(), + pos.getTheta() - parallax(elev, pos.getR()), + pos.getR() + ); + } + + /** + * Returns the angular radius of the moon. + * + * @param distance Distance of the moon, in kilometers. + * @return Angular radius of the moon, in radians. + * @see Wikipedia: Angular + * Diameter + */ + public static double angularRadius(double distance) { + return asin(MOON_MEAN_RADIUS / distance); + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/util/Pegasus.java b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/util/Pegasus.java new file mode 100644 index 0000000..c73d401 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/util/Pegasus.java @@ -0,0 +1,76 @@ +/* + * Shredzone Commons - suncalc + * + * Copyright (C) 2018 Richard "Shred" Körber + * http://commons.shredzone.org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package com.bingce.controlnetwork.func.level.util.suntime.util; + +import static java.lang.Math.abs; + +import java.util.function.Function; + +/** + * Finds the root of a function by using the Pegasus method. + * + * @see regula falsi + */ +public class Pegasus { + + private static final int MAX_ITERATIONS = 30; + + /** + * Find the root of the given function within the boundaries. + * + * @param lower Lower boundary + * @param upper Upper boundary + * @param accuracy Desired accuracy + * @param f Function to be used for calculation + * @return root that was found + * @throws ArithmeticException if the root could not be found in the given accuracy within + * {@value #MAX_ITERATIONS} iterations. + */ + public static Double calculate(double lower, double upper, double accuracy, Function f) { + double x1 = lower; + double x2 = upper; + + double f1 = f.apply(x1); + double f2 = f.apply(x2); + + if (f1 * f2 >= 0.0) { + throw new ArithmeticException("No root within the given boundaries"); + } + + int i = MAX_ITERATIONS; + + while (i-- > 0) { + double x3 = x2 - f2 / ((f2 - f1) / (x2 - x1)); + double f3 = f.apply(x3); + + if (f3 * f2 <= 0.0) { + x1 = x2; + f1 = f2; + x2 = x3; + f2 = f3; + } else { + f1 = f1 * f2 / (f2 + f3); + x2 = x3; + f2 = f3; + } + + if (abs(x2 - x1) <= accuracy) { + return abs(f1) < abs(f2) ? x1 : x2; + } + } + + throw new ArithmeticException("Maximum number of iterations exceeded"); + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/util/QuadraticInterpolation.java b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/util/QuadraticInterpolation.java new file mode 100644 index 0000000..58db08c --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/util/QuadraticInterpolation.java @@ -0,0 +1,125 @@ +/* + * Shredzone Commons - suncalc + * + * Copyright (C) 2017 Richard "Shred" Körber + * http://commons.shredzone.org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package com.bingce.controlnetwork.func.level.util.suntime.util; + +import static java.lang.Math.abs; +import static java.lang.Math.sqrt; + +/** + * Calculates the roots and extremum of a quadratic equation. + */ +public class QuadraticInterpolation { + + private final double xe; + private final double ye; + private final double root1; + private final double root2; + private final int nRoot; + private final boolean maximum; + + /** + * Creates a new quadratic equation. + * + * @param yMinus y at x == -1 + * @param y0 y at x == 0 + * @param yPlus y at x == 1 + */ + public QuadraticInterpolation(double yMinus, double y0, double yPlus) { + double a = 0.5 * (yPlus + yMinus) - y0; + double b = 0.5 * (yPlus - yMinus); + double c = y0; + + xe = -b / (2.0 * a); + ye = (a * xe + b) * xe + c; + maximum = a < 0.0; + double dis = b * b - 4.0 * a * c; + + int rootCount = 0; + + if (dis >= 0.0) { + double dx = 0.5 * sqrt(dis) / abs(a); + root1 = xe - dx; + root2 = xe + dx; + + if (abs(root1) <= 1.0) { + rootCount++; + } + + if (abs(root2) <= 1.0) { + rootCount++; + } + } else { + root1 = Double.NaN; + root2 = Double.NaN; + } + + nRoot = rootCount; + } + + /** + * Returns X of extremum. Can be outside [-1 .. 1]. + * + * @return X + */ + public double getXe() { + return xe; + } + + /** + * Returns the Y value at the extremum. + * + * @return Y + */ + public double getYe() { + return ye; + } + + /** + * Returns the first root that was found. + * + * @return X of first root + */ + public double getRoot1() { + return root1 < -1.0 ? root2 : root1; + } + + /** + * Returns the second root that was found. + * + * @return X of second root + */ + public double getRoot2() { + return root2; + } + + /** + * Returns the number of roots found in [-1 .. 1]. + * + * @return Number of roots + */ + public int getNumberOfRoots() { + return nRoot; + } + + /** + * Returns whether the extremum is a minimum or a maximum. + * + * @return {@code true}: Extremum at xe is a maximum. {@code false}: Extremum at xe is + * a minimum. + */ + public boolean isMaximum() { + return maximum; + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/util/Sun.java b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/util/Sun.java new file mode 100644 index 0000000..640fb55 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/util/Sun.java @@ -0,0 +1,117 @@ +/* + * Shredzone Commons - suncalc + * + * Copyright (C) 2017 Richard "Shred" Körber + * http://commons.shredzone.org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package com.bingce.controlnetwork.func.level.util.suntime.util; + +import static com.bingce.controlnetwork.func.level.util.suntime.util.ExtendedMath.PI2; +import static com.bingce.controlnetwork.func.level.util.suntime.util.ExtendedMath.equatorialToEcliptical; +import static com.bingce.controlnetwork.func.level.util.suntime.util.ExtendedMath.equatorialToHorizontal; +import static com.bingce.controlnetwork.func.level.util.suntime.util.ExtendedMath.frac; +import static com.bingce.controlnetwork.func.level.util.suntime.util.ExtendedMath.parallax; +import static java.lang.Math.asin; +import static java.lang.Math.cos; +import static java.lang.Math.sin; + +/** + * Calculations and constants for the Sun. + * + * @see "Astronomy on the Personal Computer, 4th edition + * (Oliver Montenbruck, Thomas Pfleger) - + * ISBN 978-3-540-67221-0" + */ +public final class Sun { + + private static final double SUN_DISTANCE = 149598000.0; + private static final double SUN_MEAN_RADIUS = 695700.0; + + private Sun() { + // Utility class without constructor + } + + /** + * Calculates the equatorial position of the sun. + * + * @param date {@link JulianDate} to be used + * @return {@link Vector} containing the sun position + */ + public static Vector positionEquatorial(JulianDate date) { + double T = date.getJulianCentury(); + double M = PI2 * frac(0.993133 + 99.997361 * T); + double L = PI2 * frac(0.7859453 + M / PI2 + + (6893.0 * sin(M) + 72.0 * sin(2.0 * M) + 6191.2 * T) / 1296.0e3); + + double d = SUN_DISTANCE + * (1 - 0.016718 * cos(date.getTrueAnomaly())); + + return Vector.ofPolar(L, 0.0, d); + } + + /** + * Calculates the geocentric position of the sun. + * + * @param date {@link JulianDate} to be used + * @return {@link Vector} containing the sun position + */ + public static Vector position(JulianDate date) { + Matrix rotateMatrix = equatorialToEcliptical(date).transpose(); + return rotateMatrix.multiply(positionEquatorial(date)); + } + + /** + * Calculates the horizontal position of the sun. + * + * @param date {@link JulianDate} to be used + * @param lat Latitude, in radians + * @param lng Longitute, in radians + * @return {@link Vector} of horizontal sun position + */ + public static Vector positionHorizontal(JulianDate date, double lat, double lng) { + Vector mc = position(date); + double h = date.getGreenwichMeanSiderealTime() + lng - mc.getPhi(); + return equatorialToHorizontal(h, mc.getTheta(), mc.getR(), lat); + } + + /** + * Calculates the topocentric position of the sun. + *

+ * Atmospheric refraction is not taken into account. + * + * @param date {@link JulianDate} to be used + * @param lat Latitude, in radians + * @param lng Longitute, in radians + * @param elev Elevation, in meters + * @return {@link Vector} of topocentric sun position + * @since 3.9 + */ + public static Vector positionTopocentric(JulianDate date, double lat, double lng, double elev) { + Vector pos = positionHorizontal(date, lat, lng); + return Vector.ofPolar( + pos.getPhi(), + pos.getTheta() - parallax(elev, pos.getR()), + pos.getR() + ); + } + + /** + * Returns the angular radius of the sun. + * + * @param distance Distance of the sun, in kilometers. + * @return Angular radius of the sun, in radians. + * @see Wikipedia: Angular + * Diameter + */ + public static double angularRadius(double distance) { + return asin(SUN_MEAN_RADIUS / distance); + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/util/Vector.java b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/util/Vector.java new file mode 100644 index 0000000..eea316e --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/util/suntime/util/Vector.java @@ -0,0 +1,330 @@ +/* + * Shredzone Commons - suncalc + * + * Copyright (C) 2017 Richard "Shred" Körber + * http://commons.shredzone.org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package com.bingce.controlnetwork.func.level.util.suntime.util; + +import static com.bingce.controlnetwork.func.level.util.suntime.util.ExtendedMath.PI2; +import static com.bingce.controlnetwork.func.level.util.suntime.util.ExtendedMath.isZero; +import static java.lang.Math.atan2; +import static java.lang.Math.cos; +import static java.lang.Math.sin; +import static java.lang.Math.sqrt; + + +import androidx.annotation.Nullable; + + +/** + * A three dimensional vector. + *

+ * Objects are is immutable and threadsafe. + */ +public class Vector { + + private final double x; + private final double y; + private final double z; + private final Polar polar = new Polar(); + + /** + * Creates a new {@link Vector} of the given cartesian coordinates. + * + * @param x + * X coordinate + * @param y + * Y coordinate + * @param z + * Z coordinate + */ + public Vector(double x, double y, double z) { + this.x = x; + this.y = y; + this.z = z; + } + + /** + * Creates a new {@link Vector} of the given cartesian coordinates. + * + * @param d + * Array of coordinates, must have 3 elements + */ + public Vector(double[] d) { + if (d.length != 3) { + throw new IllegalArgumentException("invalid vector length"); + } + this.x = d[0]; + this.y = d[1]; + this.z = d[2]; + } + + /** + * Creates a new {@link Vector} of the given polar coordinates, with a radial distance + * of 1. + * + * @param φ + * Azimuthal Angle + * @param θ + * Polar Angle + * @return Created {@link Vector} + */ + public static Vector ofPolar(double φ, double θ) { + return ofPolar(φ, θ, 1.0); + } + + /** + * Creates a new {@link Vector} of the given polar coordinates. + * + * @param φ + * Azimuthal Angle + * @param θ + * Polar Angle + * @param r + * Radial Distance + * @return Created {@link Vector} + */ + public static Vector ofPolar(double φ, double θ, double r) { + double cosθ = cos(θ); + Vector result = new Vector( + r * cos(φ) * cosθ, + r * sin(φ) * cosθ, + r * sin(θ) + ); + result.polar.setPolar(φ, θ, r); + return result; + } + + /** + * Returns the cartesian X coordinate. + */ + public double getX() { + return x; + } + + /** + * Returns the cartesian Y coordinate. + */ + public double getY() { + return y; + } + + /** + * Returns the cartesian Z coordinate. + */ + public double getZ() { + return z; + } + + /** + * Returns the azimuthal angle (φ) in radians. + */ + public double getPhi() { + return polar.getPhi(); + } + + /** + * Returns the polar angle (θ) in radians. + */ + public double getTheta() { + return polar.getTheta(); + } + + /** + * Returns the polar radial distance (r). + */ + public double getR() { + return polar.getR(); + } + + /** + * Returns a {@link Vector} that is the sum of this {@link Vector} and the given + * {@link Vector}. + * + * @param vec + * {@link Vector} to add + * @return Resulting {@link Vector} + */ + public Vector add(Vector vec) { + return new Vector( + x + vec.x, + y + vec.y, + z + vec.z + ); + } + + /** + * Returns a {@link Vector} that is the difference of this {@link Vector} and the + * given {@link Vector}. + * + * @param vec + * {@link Vector} to subtract + * @return Resulting {@link Vector} + */ + public Vector subtract(Vector vec) { + return new Vector( + x - vec.x, + y - vec.y, + z - vec.z + ); + } + + /** + * Returns a {@link Vector} that is the scalar product of this {@link Vector} and the + * given scalar. + * + * @param scalar + * Scalar to multiply + * @return Resulting {@link Vector} + */ + public Vector multiply(double scalar) { + return new Vector( + x * scalar, + y * scalar, + z * scalar + ); + } + + /** + * Returns the negation of this {@link Vector}. + * + * @return Resulting {@link Vector} + */ + public Vector negate() { + return new Vector( + -x, + -y, + -z + ); + } + + /** + * Returns a {@link Vector} that is the cross product of this {@link Vector} and the + * given {@link Vector}. + * + * @param right + * {@link Vector} to multiply + * @return Resulting {@link Vector} + */ + public Vector cross(Vector right) { + return new Vector( + y * right.z - z * right.y, + z * right.x - x * right.z, + x * right.y - y * right.x + ); + } + + /** + * Returns the dot product of this {@link Vector} and the given {@link Vector}. + * + * @param right + * {@link Vector} to multiply + * @return Resulting dot product + */ + public double dot(Vector right) { + return x * right.x + y * right.y + z * right.z; + } + + /** + * Returns the norm of this {@link Vector}. + * + * @return Norm of this vector + */ + public double norm() { + return sqrt(dot(this)); + } + + @Override + public boolean equals(Object obj) { + if (obj == null || !(obj instanceof Vector)) { + return false; + } + + Vector vec = (Vector) obj; + return Double.compare(x, vec.x) == 0 + && Double.compare(y, vec.y) == 0 + && Double.compare(z, vec.z) == 0; + } + + @Override + public int hashCode() { + return Double.valueOf(x).hashCode() + ^ Double.valueOf(y).hashCode() + ^ Double.valueOf(z).hashCode(); + } + + @Override + public String toString() { + return "(x=" + x + ", y=" + y + ", z=" + z + ")"; + } + + /** + * Helper class for lazily computing the polar coordinates in an immutable Vector + * object. + */ + private class Polar { + private @Nullable Double φ = null; + private @Nullable Double θ = null; + private @Nullable Double r = null; + + /** + * Sets polar coordinates. + * + * @param φ + * Phi + * @param θ + * Theta + * @param r + * R + */ + public synchronized void setPolar(double φ, double θ, double r) { + this.φ = φ; + this.θ = θ; + this.r = r; + } + + public synchronized double getPhi() { + if (φ == null) { + if (isZero(x) && isZero(y)) { + φ = 0.0; + } else { + φ = atan2(y, x); + } + + if (φ < 0.0) { + φ += PI2; + } + } + return φ; + } + + public synchronized double getTheta() { + if (θ == null) { + double ρSqr = x * x + y * y; + + if (isZero(z) && isZero(ρSqr)) { + θ = 0.0; + } else { + θ = atan2(z, sqrt(ρSqr)); + } + } + return θ; + } + + public synchronized double getR() { + if (r == null) { + r = sqrt(x * x + y * y + z * z); + } + return r; + } + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/viewmodel/LevelCreateOrEditRouteVm.kt b/app/src/main/java/com/bingce/controlnetwork/func/level/viewmodel/LevelCreateOrEditRouteVm.kt new file mode 100644 index 0000000..cc300c1 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/viewmodel/LevelCreateOrEditRouteVm.kt @@ -0,0 +1,271 @@ +package com.bingce.controlnetwork.func.level.viewmodel + +import android.content.Context +import android.text.TextUtils +import androidx.annotation.WorkerThread +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import androidx.room.withTransaction +import blankj.utilcode.util.ToastUtils +import com.bingce.controlnetwork.func.level.fragment.LevelRouteCreateEditFragment +import com.bingce.controlnetwork.func.level.util.LevelStationUtilTj +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory +import com.bingce.controlapphelper.datasource.database.config.ConfigOperate +import com.bingce.controlapphelper.datasource.database.leveling.LevelingDb +import com.bingce.controlapphelper.datasource.database.leveling.LevelingDbFactory +import com.bingce.controlapphelper.datasource.database.leveling.route.LevelRouteRecord +import com.bingce.controlapphelper.datasource.database.point.PointRecord +import com.bingce.controlapphelper.dialog.loading.LoadingUtil +import com.bingce.controlapphelper.model.LevelRouteSave +import com.bingce.controlapphelper.util.Tools +import com.bingce.controlnetwork.R +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + +class LevelCreateOrEditRouteVm : ViewModel() { + + fun showCreateOrEditDialog( + context: Context, + projectId: String, + routeId: String? + ) { + val title = if (routeId == null) + Tools.getString(R.string.create_segment_survey) + else Tools.getString(R.string.edit_segment_survey) + + LevelRouteCreateEditFragment.start(context, projectId, routeId, title) +// LevelRouteCreateEditDialog.start(projectId, routeId, childFragmentManager) + } + + /** + * 新建路线 存默认路线 + * 编辑路线 + */ + private fun startSaveRoute( + levelRouteSave: LevelRouteSave, + callBack: (Boolean) -> Unit + ) { + viewModelScope.launch(Dispatchers.IO) { + LevelingDb.getInstance().withTransaction { + try { + if (levelRouteSave.routeId != null) { + editRoute(levelRouteSave) + } else { + createRoute(levelRouteSave) + } + + dismissLoading() + mainBack(callBack, true) + } catch (e: Exception) { + e.printStackTrace() + dismissLoading() + mainBack(callBack, false) + } + } + } + } + + private suspend fun mainBack(callBack: (Boolean) -> Unit, isSuccess: Boolean) { + withContext(Dispatchers.Main) { + callBack(isSuccess) + } + } + + private suspend fun editRoute(levelRouteSave: LevelRouteSave) { + val routeRecord = + LevelingDbFactory.instance.levelDataSource.getById(levelRouteSave.routeId) + routeRecord?.let { + //编辑路线的时候先把路线下的所有测站都删除 + deleteRouteStation(it.getId()) + + it.routeName = levelRouteSave.routeName + it.startPointId = levelRouteSave.startPointId + it.endPointId = levelRouteSave.endPointId + it.observationDirection = levelRouteSave.observationDirection + it.levelingMeasureOrder = levelRouteSave.levelingMeasureOrder + + //更新路线 + LevelingDbFactory.instance.levelDataSource.update(it) + //创建测站 + createRouteStation(it.projectId, it.getId(), levelRouteSave.startPointId) + } + } + + /** + * 删除路线下的所有测站 + */ + private fun deleteRouteStation(routeId: String) { + LevelingDbFactory.instance.stationDataSource.deleteByRouteId(routeId) + } + + @WorkerThread + private suspend fun createRoute( + levelRouteSave: LevelRouteSave + ) { + val routeRecord = + LevelRouteRecord.createRouteRecord( + levelRouteSave.projectId, + levelRouteSave.routeName, + levelRouteSave.startPointId, + levelRouteSave.endPointId, + levelRouteSave.observationDirection, + levelRouteSave.levelingMeasureOrder + ) + //存路线 + LevelingDbFactory.instance.levelDataSource.saveRecord(routeRecord) + + //创建测站 + createRouteStation( + levelRouteSave.projectId, + routeRecord.getId(), + levelRouteSave.startPointId + ) + + ConfigOperate.changeDefaultProjectAndRoute( + levelRouteSave.projectId, + routeRecord.getId() + ) + } + + private fun createRouteStation(projectId: String, routeId: String, startPointId: String) { + //创建测站 + LevelStationUtilTj.createStation(projectId, routeId, startPointId, true) + } + + fun startSave(context: Context, levelRouteSave: LevelRouteSave, callBack: (Boolean) -> Unit) { + showLoading(context) + viewModelScope.launch(Dispatchers.IO) { + val canEdit = checkCanEdit(levelRouteSave.projectId, levelRouteSave.routeId) + if (!canEdit) { + dismissLoading() + ToastUtils.showShort(R.string.route_has_data_not_edit_hint) + return@launch + } + + var startPoint = + SurveyorDatabaseFactory.instance.getPointDataSource() + .findByNameSync(levelRouteSave.startPointName, levelRouteSave.projectId) + if (startPoint == null) { + startPoint = + createPoint(levelRouteSave.projectId, levelRouteSave.startPointName!!, "") + //存数据库 + SurveyorDatabaseFactory.instance.getPointDataSource().saveSync(startPoint) + } + + var endPoint = + SurveyorDatabaseFactory.instance.getPointDataSource() + .findByNameSync(levelRouteSave.endPointName, levelRouteSave.projectId) + if (endPoint == null) { + endPoint = + createPoint(levelRouteSave.projectId, levelRouteSave.endPointName!!, "") + //存数据库 + SurveyorDatabaseFactory.instance.getPointDataSource().saveSync(endPoint) + } + + levelRouteSave.startPointId = startPoint.getId() + levelRouteSave.endPointId = endPoint.getId() + + startSaveRoute( + levelRouteSave, + callBack + ) + } + } + + private fun showLoading(context: Context) { + LoadingUtil.show(context, context.getString(R.string.loading)) + } + + private suspend fun dismissLoading() { + withContext(Dispatchers.Main) { + LoadingUtil.dismiss() + } + } + + /** + * @return + */ + @WorkerThread + private fun checkCanEdit(projectId: String, routeIdParam: String?): Boolean { + //路线有数据时候不能编辑 + val routeId = routeIdParam ?: return true + val routeRecord = SurveyorDatabaseFactory.instance.getRouteDataSource().getByIdSync(routeId) + if (routeRecord != null) { + val stationList = LevelingDbFactory.instance.getStationDataSource() + .getStationList(projectId, routeRecord.getId(), false) + if (stationList != null && stationList.isNotEmpty()) { + for (stationRecord in stationList) { + val recordCount = LevelingDbFactory.instance.getMeasureBackFrontDataSource() + .getCountByStationId(stationRecord.getId()) + if (recordCount > 0) { + return false + } + } + } + } + return true + } + + @WorkerThread + private fun createPoint(projectId: String, pointName: String, height: String): PointRecord { + return createPointRecord(projectId, pointName, height) + } + + private fun createPointRecord( + projectId: String, + pointText: String, + height: String + ): PointRecord { + val pointType = if (isKnownPoint(height)) { + PointRecord.TYPE_KNOWN_POINT + } else { + PointRecord.TYPE_UNKNOWN_POINT + } + val h: Double = stringToDouble(height) + return PointRecord.point( + projectId, + pointType, + pointText, + "", + 0.0, + 0.0, + 0.0, + "", + -1, + ) + } + + private fun isKnownPoint(height: String): Boolean { + val heightD: Double = stringToDouble(height) + return heightD != 0.0 + } + + private fun stringToDouble(value: String): Double { + return if (TextUtils.isEmpty(value)) { + 0.0 + } else value.toDouble() + } + + fun getEditRouteData(routeId: String, callBack: (LevelRouteSave) -> Unit) { + viewModelScope.launch(Dispatchers.IO) { + val routeRecord = LevelingDbFactory.instance.levelDataSource.getByIdSync(routeId) + routeRecord?.let { + val result = LevelRouteSave() + result.observationDirection = it.observationDirection + result.routeName = it.routeName + + val startPoint = + SurveyorDatabaseFactory.instance.pointDataSource.findByIdSync(it.startPointId) + val endPoint = + SurveyorDatabaseFactory.instance.pointDataSource.findByIdSync(it.endPointId) + result.startPointName = startPoint?.name + result.endPointName = endPoint?.name + withContext(Dispatchers.Main) { + callBack(result) + } + } + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/viewmodel/LevelSelectExportVm.kt b/app/src/main/java/com/bingce/controlnetwork/func/level/viewmodel/LevelSelectExportVm.kt new file mode 100644 index 0000000..6e93e6e --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/viewmodel/LevelSelectExportVm.kt @@ -0,0 +1,72 @@ +package com.bingce.controlnetwork.func.level.viewmodel + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.bingce.controlapphelper.datasource.database.ProjectTypeValue +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory +import com.bingce.controlapphelper.datasource.database.leveling.LevelingDbFactory +import com.bingce.controlapphelper.model.LevelingMeasureOrder +import com.bingce.controlapphelper.widget.treeview.TreeNode +import com.bingce.controlnetwork.func.level.util.LevelStationUtilTj +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + +/** + * 水准选择导出 + */ +class LevelSelectExportVm : ViewModel() { + + fun initData(callBack: (TreeNode) -> Unit) { + viewModelScope.launch(Dispatchers.IO) { + val root = TreeNode.root() + val projectList = + SurveyorDatabaseFactory.instance.projectDataSource.getListByProjectType( + ProjectTypeValue.LEVEL + ) + for (project in projectList) { + val projectNode = TreeNode(TreeNode.Value(project.projectName, project.id), 0) + root.addChild(projectNode) + val routeList = + LevelingDbFactory.instance.levelDataSource.getByProjectIdSync(project.id) + //当项目里没有路线的时候禁止选中 + if (routeList.isEmpty()) { + projectNode.isEnable = false + } + + for (route in routeList) { + + val routeNode = TreeNode(TreeNode.Value(route.routeName, route.id), 1) + projectNode.addChild(routeNode) + + val countFinish = LevelStationUtilTj.getStationFinishCount( + project.id, + route.id + ) + if (countFinish < 1) { + routeNode.isEnable = false + } else { + val isEnable = when (route.levelingMeasureOrder) { + LevelingMeasureOrder.A_BF, + LevelingMeasureOrder.A_BFFB, + LevelingMeasureOrder.A_FBBF, + LevelingMeasureOrder.SIM_BF, + LevelingMeasureOrder.SIM_BFFB -> { + countFinish % 2 == 0 + } + + else -> true + } + routeNode.isEnable = isEnable + } + } + } + + withContext(Dispatchers.Main) { + callBack(root) + } + + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/viewmodel/LevelStationSettingVm.kt b/app/src/main/java/com/bingce/controlnetwork/func/level/viewmodel/LevelStationSettingVm.kt new file mode 100644 index 0000000..0bfc79b --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/viewmodel/LevelStationSettingVm.kt @@ -0,0 +1,151 @@ +package com.bingce.controlnetwork.func.level.viewmodel + +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.bingce.controlnetwork.func.level.util.LevelStationSettingUtil +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory +import com.bingce.controlapphelper.datasource.database.leveling.LevelingDbFactory +import com.bingce.controlapphelper.datasource.database.leveling.stationsetting.LevelingStationSettingRecord +import com.bingce.controlapphelper.model.LevelRouteSave +import com.bingce.controlapphelper.model.LevelingMeasureOrder +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + +class LevelStationSettingVm : ViewModel() { + private lateinit var routeId: String + private lateinit var stationId: String + + private lateinit var needSaveLevelRouteSave: LevelRouteSave + + val editLastDataLiveData = MutableLiveData() + + + fun getEditLastData(stationId: String) { + viewModelScope.launch(Dispatchers.IO) { + val record = + LevelingDbFactory.instance.stationSettingDataSource.getByStationId(stationId) + if (record != null) { + editLastDataLiveData.postValue(recordToLevelSave(record)) + return@launch + } + val stationSettingLastData = LevelStationSettingUtil.getStationSettingLastData() + if (stationSettingLastData.weather != null) { + editLastDataLiveData.postValue(stationSettingLastData) + return@launch + } + editLastDataLiveData.postValue(null) + } + } + + fun getInitCurrentTabPos(callBack: (Int) -> Unit) { + viewModelScope.launch(Dispatchers.IO) { + val record = + LevelingDbFactory.instance.stationSettingDataSource.getLatest(routeId) + withContext(Dispatchers.Main) { + val pos = if (record?.weather != null) { + 1 + } else { + 0 + } + callBack(pos) + } + } + } + + fun initRouteStationId(routeId: String, stationId: String) { + this.routeId = routeId + this.stationId = stationId + } + + fun initHasTwoRuler(callBack: (Boolean) -> Unit) { + viewModelScope.launch(Dispatchers.IO) { + val route = LevelingDbFactory.instance.levelDataSource.getByIdSync(routeId) + ?: return@launch + val hasTwoRuler = + route.levelingMeasureOrder == LevelingMeasureOrder.SIM_BF || route.levelingMeasureOrder == LevelingMeasureOrder.SIM_BFFB + withContext(Dispatchers.Main) { + callBack(hasTwoRuler) + } + } + } + + private fun recordToLevelSave(record: LevelingStationSettingRecord): LevelRouteSave { + return LevelRouteSave.createLastData( + record.watcher, + record.recorder, + record.examiner, + record.firstStationBackFootNumber, + record.firstStationFrontFootNumber, + record.firstStationBackFootNumber2, + record.firstStationFrontFootNumber2, + record.instrumentModel, + record.deviceNumber, + record.steelRuleParam, + record.rulerLengthProvingTemperature, + record.rulerCorrectionFactor, + record.rulerType, + record.rulerReceptType, + + record.temperature, + record.weather, + record.imaging, + record.sunDirection, + record.windDirection, + record.windSpeed, + record.roads, + record.soil + ) + } + + fun createNeedSaveLevelRouteSave(routeId: String, stationId: String) { + needSaveLevelRouteSave = LevelRouteSave() + needSaveLevelRouteSave.routeId = routeId + needSaveLevelRouteSave.stationId = stationId + } + + fun addInforDataToLevelRouteSave(needAdd: LevelRouteSave) { + needSaveLevelRouteSave.watcher = needAdd.watcher + needSaveLevelRouteSave.recorder = needAdd.recorder + needSaveLevelRouteSave.examiner = needAdd.examiner + needSaveLevelRouteSave.frontFootNumber = needAdd.frontFootNumber + needSaveLevelRouteSave.backFootNumber = needAdd.backFootNumber + needSaveLevelRouteSave.frontFootNumber2 = needAdd.frontFootNumber2 + needSaveLevelRouteSave.backFootNumber2 = needAdd.backFootNumber2 + needSaveLevelRouteSave.instrumentModel = needAdd.instrumentModel + needSaveLevelRouteSave.deviceNumber = needAdd.deviceNumber + needSaveLevelRouteSave.steelRuleParam = needAdd.steelRuleParam + needSaveLevelRouteSave.rulerLengthProvingTemperature = needAdd.rulerLengthProvingTemperature + needSaveLevelRouteSave.rulerCorrectionFactor = needAdd.rulerCorrectionFactor + needSaveLevelRouteSave.rulerType = needAdd.rulerType + needSaveLevelRouteSave.rulerReceptType = needAdd.rulerReceptType + } + + fun addConditionDataToLevelRouteSave(needAdd: LevelRouteSave) { + needSaveLevelRouteSave.temperature = needAdd.temperature + needSaveLevelRouteSave.weather = needAdd.weather + needSaveLevelRouteSave.imaging = needAdd.imaging + needSaveLevelRouteSave.sunDirection = needAdd.sunDirection + needSaveLevelRouteSave.windDirection = needAdd.windDirection + needSaveLevelRouteSave.windSpeed = needAdd.windSpeed + needSaveLevelRouteSave.roads = needAdd.roads + needSaveLevelRouteSave.soil = needAdd.soil + } + + fun save(isSaveEndStationToStationSetting: Boolean, callBack: () -> Unit) { + viewModelScope.launch(Dispatchers.IO) { + LevelStationSettingUtil.saveStationSetting( + isSaveEndStationToStationSetting, + needSaveLevelRouteSave + ) + + LevelStationSettingUtil.saveStationSettingLastData(needSaveLevelRouteSave) + + withContext(Dispatchers.Main) { + callBack() + } + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/viewmodel/LevelSuveyorSubVm.kt b/app/src/main/java/com/bingce/controlnetwork/func/level/viewmodel/LevelSuveyorSubVm.kt new file mode 100644 index 0000000..b9e5959 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/viewmodel/LevelSuveyorSubVm.kt @@ -0,0 +1,335 @@ +package com.bingce.controlnetwork.func.level.viewmodel + +import android.widget.TextView +import androidx.annotation.WorkerThread +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import androidx.room.withTransaction +import blankj.utilcode.util.ToastUtils +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory +import com.bingce.controlapphelper.datasource.database.leveling.LevelingDb +import com.bingce.controlapphelper.datasource.database.leveling.LevelingDbFactory +import com.bingce.controlapphelper.datasource.database.leveling.measure.station.LevelingMeasureStationRecord +import com.bingce.controlapphelper.datasource.database.leveling.station.LevelingStationRecord +import com.bingce.controlapphelper.datasource.database.leveling.tolerance.LevelingToleranceDetail +import com.bingce.controlapphelper.datasource.database.point.PointRecord +import com.bingce.controlapphelper.leveling.detaction.DetectionController +import com.bingce.controlapphelper.leveling.detaction.IDetectionHint +import com.bingce.controlapphelper.leveling.detaction.INextStation +import com.bingce.controlapphelper.leveling.detaction.LevelReceiveData +import com.bingce.controlapphelper.leveling.detaction.LevelingProcess +import com.bingce.controlapphelper.leveling.detaction.surveyorcache.SurveyorCacheData +import com.bingce.controlapphelper.model.B1 +import com.bingce.controlapphelper.model.B2 +import com.bingce.controlapphelper.model.F1 +import com.bingce.controlapphelper.model.F2 +import com.bingce.controlapphelper.model.LevelingMeasureOrder +import com.bingce.controlapphelper.model.LevelingMeasureOrderUtil +import com.bingce.controlapphelper.model.StationOddEven +import com.bingce.controlapphelper.util.SpannableStringUtil +import com.bingce.controlapphelper.util.Tools +import com.bingce.controlnetwork.R +import com.bingce.controlnetwork.databinding.ItemLevelSuveyorSurveyorBinding +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + +class LevelSuveyorSubVm : ViewModel() { + + var projectId: String? = null//项目id + + val stationLiveData = MutableLiveData() + val surveyorCacheDataLiveData = MutableLiveData() + val measureStationLiveData = MutableLiveData() + + private var detectionHintI: IDetectionHint? = null + private var nextStationI: INextStation? = null + + private var process: LevelingProcess? = null + private var toleranceDetail: LevelingToleranceDetail? = null + + fun initData( + stationId: String, + detectionHintI: IDetectionHint, + nextStationI: INextStation? + ) { + this.detectionHintI = detectionHintI + this.nextStationI = nextStationI + viewModelScope.launch(Dispatchers.IO) { + val station = getStation(stationId) + + val project = + SurveyorDatabaseFactory.instance.projectDataSource.getRecord(station.projectId) + projectId = project.getId() + toleranceDetail = + LevelingDbFactory.instance.toleranceDetailDataSource.getRecordSync(project.toleranceId) + + refreshStationProcess(station) + } + } + + @WorkerThread + private fun refreshStationProcess(station: LevelingStationRecord?) { + if (toleranceDetail == null) { + ToastUtils.showShort("限差异常") + return + } + if (station == null) { + ToastUtils.showShort("测站异常") + return + } + + if (station.levelingMeasureOrder == null) { + setStationLevelOrder(station) + } + + process = DetectionController.createProcess( + viewModelScope, + station, + toleranceDetail!!, + detectionHintI, + nextStationI, + stationLiveData, + surveyorCacheDataLiveData, + measureStationLiveData + ) + } + + /** + * 接受数据 + */ + fun recieveData(data: LevelReceiveData) { + process?.receiveData(data) + } + + fun saveMeasureFrontPointId(pointId: String, callBack: () -> Unit) { + val station = stationLiveData.value + if (station != null && !LevelingMeasureOrderUtil.isMeasureBack(station)) { + viewModelScope.launch(Dispatchers.IO) { + station.frontSightPointId = pointId + LevelingDbFactory.instance.stationDataSource.update(station) + withContext(Dispatchers.Main) { + callBack() + } + } + } + } + + fun saveMeasureFrontPoint(point: PointRecord, callBack: () -> Unit) { + val station = stationLiveData.value + if (station != null) { + viewModelScope.launch(Dispatchers.IO) { + LevelingDb.getInstance().withTransaction { + SurveyorDatabaseFactory.instance.pointDataSource.saveSync(point) + station.frontSightPointId = point.getId() + LevelingDbFactory.instance.stationDataSource.update(station) + withContext(Dispatchers.Main) { + callBack() + } + } + } + } + } + + fun getMeasurePointName(station: LevelingStationRecord, callBack: (String) -> Unit) { + viewModelScope.launch(Dispatchers.IO) { + val measurePointId = LevelingMeasureOrderUtil.getMeasurePointId(station) + val name = + SurveyorDatabaseFactory.instance.pointDataSource.findByIdSync(measurePointId)?.name + withContext(Dispatchers.Main) { + callBack(name ?: "") + } + } + } + + /** + * 回退 + */ + fun startRollBack() { + process?.startRollBack() + } + + fun reMeasureStation() { + process?.dealReMeasureStation() + } + + fun getZ(callBack: (Double) -> Unit) { + stationLiveData.value?.let { stationRecord -> + viewModelScope.launch(Dispatchers.IO) { + val routeRecord = + LevelingDbFactory.instance.levelDataSource.getByIdSync(stationRecord.routeId) + val startPointHeight = + SurveyorDatabaseFactory.instance.pointDataSource.findByIdSync(routeRecord?.startPointId) + ?.getZ() + ?: 0.0 + withContext(Dispatchers.Main) { + callBack(startPointHeight) + } + } + } + } + + fun getCurrentOrderText(stationRecord: LevelingStationRecord): CharSequence { + val textByLevelingMeasureOrder = + LevelingMeasureOrderUtil.getTextByLevelingMeasureOrder(stationRecord.levelingMeasureOrder) + val text = textByLevelingMeasureOrder.replaceFirst("(Sim|a])".toRegex(), "") + + return SpannableStringUtil.getSelectedText( + text, + stationRecord.currentPosition + ) + } + + fun getCurrentOrderArray(stationRecord: LevelingStationRecord): Array = + when (stationRecord.levelingMeasureOrder) { + LevelingMeasureOrder.A_BF -> { + getArrayString(stationRecord, "BF", "FB") + } + + LevelingMeasureOrder.A_BFFB -> { + getArrayString(stationRecord, "BFFB", "FBBF") + } + + LevelingMeasureOrder.A_FBBF -> { + getArrayString(stationRecord, "FBBF", "BFFB") + } + + else -> { + val text = + LevelingMeasureOrderUtil.getTextByLevelingMeasureOrder(stationRecord.levelingMeasureOrder) + .replaceFirst("(Sim|a])".toRegex(), "") + getArrayString(stationRecord, text, text) + } + } + + private fun getArrayString( + stationRecord: LevelingStationRecord, + text1: String, + text2: String + ): Array { + return if (stationRecord.oddEvenStation == StationOddEven.ODD_STATION) { + arrayOf( + SpannableStringUtil.getSelectedText(text1, stationRecord.currentPosition), + text2 + ) + } else { + arrayOf( + text1, + SpannableStringUtil.getSelectedText(text2, stationRecord.currentPosition), + ) + } + } + + private fun getStation(stationId: String): LevelingStationRecord { + val station = LevelingDbFactory.instance.stationDataSource.getRecordSync(stationId) + setStationLevelOrder(station) + return station + } + + private fun setStationLevelOrder(station: LevelingStationRecord) { + val routeRecord = LevelingDbFactory.instance.levelDataSource.getByIdSync(station.routeId) + station.levelingMeasureOrder = routeRecord?.levelingMeasureOrder + } + + fun isShowOddEvenStation(station: LevelingStationRecord) = + when (station.levelingMeasureOrder) { + LevelingMeasureOrder.A_BF, + LevelingMeasureOrder.A_BFFB, + LevelingMeasureOrder.A_FBBF -> true + + else -> false + } + + fun setMeasureTextColor( + station: LevelingStationRecord, + ilB1: ItemLevelSuveyorSurveyorBinding, + ilB2: ItemLevelSuveyorSurveyorBinding, + ilF1: ItemLevelSuveyorSurveyorBinding, + ilF2: ItemLevelSuveyorSurveyorBinding + ) { + val measureWhichPoint = LevelingMeasureOrderUtil.getMeasureWhichPoint(station) + resetTextColor(ilB1.tvDistanceTitle, ilB1.tvHeightTitle, ilB1.tvDisTance, ilB1.tvHeight) + resetTextColor(ilB2.tvDistanceTitle, ilB2.tvHeightTitle, ilB2.tvDisTance, ilB2.tvHeight) + resetTextColor(ilF1.tvDistanceTitle, ilF1.tvHeightTitle, ilF1.tvDisTance, ilF1.tvHeight) + resetTextColor(ilF2.tvDistanceTitle, ilF2.tvHeightTitle, ilF2.tvDisTance, ilF2.tvHeight) + when (measureWhichPoint) { + B1 -> { + selectTextColor( + ilB1.tvDistanceTitle, + ilB1.tvHeightTitle, + ilB1.tvDisTance, + ilB1.tvHeight + ) + } + + B2 -> { + selectTextColor( + ilB2.tvDistanceTitle, + ilB2.tvHeightTitle, + ilB2.tvDisTance, + ilB2.tvHeight + ) + } + + F1 -> { + selectTextColor( + ilF1.tvDistanceTitle, + ilF1.tvHeightTitle, + ilF1.tvDisTance, + ilF1.tvHeight + ) + } + + F2 -> { + selectTextColor( + ilF2.tvDistanceTitle, + ilF2.tvHeightTitle, + ilF2.tvDisTance, + ilF2.tvHeight + ) + } + } + + } + + private fun resetTextColor( + tvDisTanceTitle: TextView, + tvHeightTitle: TextView, + tvDisTance: TextView, + tvHeight: TextView + ) { + tvDisTanceTitle.setTextColor(Tools.getColor(R.color.color_333333)) + tvHeightTitle.setTextColor(Tools.getColor(R.color.color_333333)) + tvDisTance.setTextColor(Tools.getColor(R.color.color_333333)) + tvHeight.setTextColor(Tools.getColor(R.color.color_333333)) + } + + private fun selectTextColor( + tvDisTanceTitle: TextView, + tvHeightTitle: TextView, + tvDisTance: TextView, + tvHeight: TextView + ) { + tvDisTanceTitle.setTextColor(Tools.getColor(R.color.value_1_selected)) + tvHeightTitle.setTextColor(Tools.getColor(R.color.value_1_selected)) + tvHeight.setTextColor(Tools.getColor(R.color.value_1_selected)) + tvDisTance.setTextColor(Tools.getColor(R.color.value_1_selected)) + } + + fun isEndStation(station: LevelingStationRecord, callBack: (Boolean) -> Unit) { + viewModelScope.launch(Dispatchers.IO) { + val routeRecord = LevelingDbFactory.instance.levelDataSource.getById(station.routeId) + val endStation = routeRecord?.endPointId == station.frontSightPointId + withContext(Dispatchers.Main) { + callBack(endStation) + } + } + } + + fun nextStation() { + process?.nextStationCheck() + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/func/level/viewmodel/LevelSuveyorVm.kt b/app/src/main/java/com/bingce/controlnetwork/func/level/viewmodel/LevelSuveyorVm.kt new file mode 100644 index 0000000..69c6477 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/func/level/viewmodel/LevelSuveyorVm.kt @@ -0,0 +1,280 @@ +package com.bingce.controlnetwork.func.level.viewmodel + +import android.text.TextUtils +import androidx.annotation.WorkerThread +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.bingce.controlnetwork.func.level.util.LevelStationUtilTj +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory +import com.bingce.controlapphelper.datasource.database.leveling.LevelingDbFactory +import com.bingce.controlapphelper.datasource.database.leveling.station.LevelingStationRecord +import com.bingce.controlapphelper.datasource.database.leveling.stationsetting.LevelingStationSettingRecord +import com.bingce.controlapphelper.leveling.detaction.ILevelRefreshBtn +import com.bingce.controlapphelper.leveling.detaction.INextStation +import com.bingce.controlapphelper.leveling.detaction.LevelCheckBtnUtil +import com.bingce.controlapphelper.model.LevelingMeasureOrder +import com.bingce.controlapphelper.model.LevelingStationState +import com.bingce.controlnetwork.func.level.util.LevelDateUtil +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + +class LevelSuveyorVm : ViewModel() { + var routeId: String? = null + private var levelRefreshBtnI: ILevelRefreshBtn? = null + var currentFragmentPos = 0 + + //测量测站列表 + var measureStationList = emptyList() + + private var initVpCallBack: (() -> Unit)? = null + private var switchPageCallBack: ((Int) -> Unit)? = null + var nextStationI: INextStation? = null + + + fun initDataStationList(projectId: String, routeId: String) { + viewModelScope.launch(Dispatchers.IO) { + getMeasureStationList(projectId, routeId) + } + } + + private suspend fun getMeasureStationList(projectId: String, routeId: String) { + this.routeId = routeId + val routeRecord = LevelingDbFactory.instance.levelDataSource.getByIdSync(routeId) + routeRecord?.let { + measureStationList = LevelStationUtilTj.getMeasureStationList(projectId, routeId) + LevelCheckBtnUtil.reset(levelRefreshBtnI) + //初始化按钮状态 + initBtnState(routeRecord.levelingMeasureOrder) + withContext(Dispatchers.Main) { + initVpCallBack?.invoke() + } + } + } + + private fun initBtnState(levelingMeasureOrder: LevelingMeasureOrder) { + for (station in measureStationList) { + station.levelingMeasureOrder = levelingMeasureOrder + refreshBtnActive(station) + } + } + + fun initData( + levelRefreshBtnI: ILevelRefreshBtn, + initVpCallBack: (() -> Unit), + switchPageCallBack: ((Int) -> Unit), + nextStationI: INextStation + ) { + this.levelRefreshBtnI = levelRefreshBtnI + this.initVpCallBack = initVpCallBack + this.switchPageCallBack = switchPageCallBack + this.nextStationI = nextStationI + } + + /** + * 切换页面刷新按钮 + */ + fun switchRefreshBtnEnable() { + levelRefreshBtnI?.refreshMeasureBtn() + levelRefreshBtnI?.refreshNextStationBtn() + levelRefreshBtnI?.refreshRollBackBtn() + levelRefreshBtnI?.refreshReMeasureBtn() + } + + private fun refreshBtnActive(station: LevelingStationRecord) { + LevelCheckBtnUtil.refreshMeasureBtn(station) + LevelCheckBtnUtil.refreshNextStationBtn(station) + LevelCheckBtnUtil.refreshRollBackBtn(station) + LevelCheckBtnUtil.refreshRemeasureStationBtn(station) + } + + fun getCurrentStationId(): String? { + if (measureStationList.size > currentFragmentPos) { + return measureStationList[currentFragmentPos].getId() + } + return null + } + + /** + * 继续观测下一站 + */ + fun contineObserve(station: LevelingStationRecord) { + viewModelScope.launch(Dispatchers.IO) { + startNextStation(station, false) + } + } + + /** + * 间歇 + */ + fun intermittent(station: LevelingStationRecord) { + // TODO: + } + + /** + * 结束测站 + */ + fun endStation(station: LevelingStationRecord) { + viewModelScope.launch(Dispatchers.IO) { + val checkStaionIsFinish = checkStaionIsFinish(station) + if (!checkStaionIsFinish) { + return@launch + } + + station.endStation = true + LevelingDbFactory.instance.stationDataSource.update(station) + + refreshBtnActive(station) + switchRefreshBtnEnable() + } + } + + private suspend fun startNextStation(station: LevelingStationRecord, endStation: Boolean) { + //单程双测 判断测站是否测完 + val checkStaionIsFinish = checkStaionIsFinish(station) + if (!checkStaionIsFinish) { + return + } + + LevelStationUtilTj.createStation( + station.getProjectId(), + station.routeId, + station.frontSightPointId, + endStation = endStation + ) + //重新获取下一站 + getMeasureStationList(station.getProjectId(), station.routeId) + } + + /** + * 回退测站 + */ + fun rollBackStation() { + viewModelScope.launch(Dispatchers.IO) { + var projectId = "" + var routeId = "" + for (station in measureStationList) { + if (TextUtils.isEmpty(projectId)) { + projectId = station.projectId + } + if (TextUtils.isEmpty(routeId)) { + routeId = station.routeId + } + + LevelingDbFactory.instance.stationDataSource.deleteById(station.getId()) + LevelingDbFactory.instance.measureStationDataSource.deleteById(station.getId()) + LevelingDbFactory.instance.measureBackFrontDataSource.deleteByStationId(station.getId()) + } + getMeasureStationList(projectId, routeId) + } + } + + private fun checkStaionIsFinish(station: LevelingStationRecord): Boolean { + //单程双测 判断测站是否测完 + var index = -1 + if (station.relationStationId != null) { + val stationListByRelationId = + LevelingDbFactory.instance.stationDataSource.getStationListByRelationId( + station.getProjectId(), + station.routeId, + station.relationStationId + ) + for ((i, item) in stationListByRelationId.withIndex()) { + if (item.stationState != LevelingStationState.FINISH) { + index = i + break + } + } + } else { + if (station.stationState != LevelingStationState.FINISH) { + index = 0 + } + } + + if (index != -1) { + switchPageCallBack?.invoke(index) + return false + } + return true + } + + fun getCurrentStation(): LevelingStationRecord? { + if (measureStationList.size > currentFragmentPos) { + return measureStationList[currentFragmentPos] + } + return null + } + + fun calLevelRouteResult(callBack: (String) -> Unit) { + getCurrentStation()?.let { + viewModelScope.launch(Dispatchers.IO) { + val success = LevelStationUtilTj.checkStationForResult(it.getId()) + if (!success) { + return@launch + } + val stationRouteResult = LevelStationUtilTj.getStationRouteResult(it) + withContext(Dispatchers.Main) { + callBack(stationRouteResult) + } + } + } + } + + fun getGetDadaAuto(routeId: String, callBack: (Boolean) -> Unit) { + viewModelScope.launch(Dispatchers.IO) { + val record = LevelingDbFactory.instance.stationSettingDataSource.getLatest(routeId) + withContext(Dispatchers.Main) { + if (record == null) { + callBack(true) + } else { + callBack(!record.getDataManually) + } + } + } + } + + fun setGetDataAuto(routeId: String, auto: Boolean) { + viewModelScope.launch(Dispatchers.IO) { + var record = LevelingDbFactory.instance.stationSettingDataSource.getLatest(routeId) + if (record == null) { + record = LevelingStationSettingRecord() + record.routeId = routeId + record.getDataManually = !auto + LevelingDbFactory.instance.stationSettingDataSource.save(record) + } else { + record.getDataManually = !auto + LevelingDbFactory.instance.stationSettingDataSource.update(record) + } + } + } + + /** + * 是否设置过最后一站的测站设置 + */ + @WorkerThread + fun isHaveSetEndStationSetting(stationId: String): Boolean { + val stationSetting = + LevelingDbFactory.instance.stationSettingDataSource.getByStationId(stationId) + return stationSetting?.setEndStationSetting ?: false + } + + fun checkSunTime(projectId: String, showDialog: (String?) -> Unit) { + viewModelScope.launch(Dispatchers.IO) { + val projectRecord = SurveyorDatabaseFactory.instance.projectDataSource.getRecord(projectId) + val toleranceDetail = + LevelingDbFactory.instance.toleranceDetailDataSource.getRecordSync(projectRecord.toleranceId) + + var hint: String? = null + if (toleranceDetail.isCheckSunTime) { + hint = LevelDateUtil.getLevelOperateSunTimeHint( + projectRecord.latitude.toDouble(), + projectRecord.longitude.toDouble() + ) + } + withContext(Dispatchers.Main) { + showDialog(hint) + } + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/guide/GuideSequence.java b/app/src/main/java/com/bingce/controlnetwork/guide/GuideSequence.java new file mode 100644 index 0000000..239e38f --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/guide/GuideSequence.java @@ -0,0 +1,110 @@ +package com.bingce.controlnetwork.guide; + +import android.app.Activity; +import android.app.Dialog; +import android.view.View; + +import androidx.appcompat.widget.Toolbar; + +import com.getkeepsafe.taptargetview.TapTarget; +import com.getkeepsafe.taptargetview.TapTargetView; + +public class GuideSequence implements ITapTargetProvider { + private int currentIndex = 0; + private final int targetCount; + private final IDelegate delegate; + private final TapTargetView.Listener listener = new TapTargetView.Listener() { +// @Override +// public void onTargetClick(TapTargetView view) { +// super.onTargetClick(view); +// } + + @Override + public void onTargetDismissed(TapTargetView view, boolean userInitiated) { + super.onTargetDismissed(view, userInitiated); + //下一个 + delegate.dismiss(currentIndex); + currentIndex++; + if (currentIndex >= targetCount) { + return; + } + delegate.show(currentIndex, GuideSequence.this); + } + +// @Override +// public void onTargetCancel(TapTargetView view) { +// super.onTargetCancel(view); +// } +// +// @Override +// public void onTargetLongClick(TapTargetView view) { +// super.onTargetLongClick(view); +// } + +// @Override +// public void onOuterCircleClick(TapTargetView view) { +// super.onOuterCircleClick(view); +// } + }; + + public GuideSequence(int targetCount, final IDelegate delegate) { + this.targetCount = targetCount; + this.delegate = delegate; + } + + public void start(int index) { + if (index < 0) { + return; + } + currentIndex = index; + delegate.show(currentIndex, this); + } + + @Override + public void show4View(Activity activity, View target, String msg, String describe) { + if (activity.isFinishing()) { + return; + } + if (activity.isDestroyed()) { + return; + } + TapTargetView.showFor( + activity, + TapTarget.forView(target, msg, describe).transparentTarget(true), + listener + ); + } + + @Override + public void show4View(Dialog dialog, View target, String msg, String describe) { + if (!dialog.isShowing()) { + return; + } + TapTargetView.showFor( + dialog, + TapTarget.forView(target, msg, describe).transparentTarget(true), + listener + ); + } + + @Override + public void show4ToolbarMenu(Activity activity, Toolbar toolbar, int menuItem, String msg, String describe) { + if (activity.isFinishing()) { + return; + } + if (activity.isDestroyed()) { + return; + } + TapTargetView.showFor( + activity, + TapTarget.forToolbarMenuItem(toolbar, menuItem, msg, describe).transparentTarget(true), + listener + ); + } + + public interface IDelegate { + void show(int index, ITapTargetProvider provider); + + void dismiss(int index); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/guide/ITapTargetProvider.java b/app/src/main/java/com/bingce/controlnetwork/guide/ITapTargetProvider.java new file mode 100644 index 0000000..fe4f127 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/guide/ITapTargetProvider.java @@ -0,0 +1,15 @@ +package com.bingce.controlnetwork.guide; + +import android.app.Activity; +import android.app.Dialog; +import android.view.View; + +import androidx.appcompat.widget.Toolbar; + +public interface ITapTargetProvider { + void show4View(Activity activity, View target, String msg, String describe); + + void show4View(Dialog dialog, View target, String msg, String describe); + + void show4ToolbarMenu(Activity activity, Toolbar toolbar, int menuItem, String msg, String describe); +} diff --git a/app/src/main/java/com/bingce/controlnetwork/http/HttpExtend.kt b/app/src/main/java/com/bingce/controlnetwork/http/HttpExtend.kt new file mode 100644 index 0000000..ccee6b3 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/http/HttpExtend.kt @@ -0,0 +1,54 @@ +package com.bingce.controlnetwork.http + +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch + +fun CoroutineScope.retrofit(dsl: RetrofitDSL.() -> Unit) { + launch(Dispatchers.IO) { + val retrofitDsl = RetrofitDSL() + retrofitDsl.dsl() + try { + val result = retrofitDsl.api() ?: throw NullPointerException() + retrofitDsl.onSuccess?.invoke(result) + } catch (e: NullPointerException) { + retrofitDsl.onFailed?.invoke(e.message, -1) + } catch (e: Exception) { + retrofitDsl.onFailed?.invoke(e.message, -100) + } + } +} + +class RetrofitDSL { + internal lateinit var api: (suspend () -> T) + private set + internal var onSuccess: ((T) -> Unit)? = null + private set + internal var onFailed: ((msg: String?, code: Int) -> Unit)? = null + private set + + /** + * 获取数据 + * @param block (T) -> Unit + */ + fun api(block: suspend () -> T) { + this.api = block + } + + /** + * 获取数据成功 + * @param block (T) -> Unit + */ + fun onSuccess(block: (T) -> Unit) { + this.onSuccess = block + } + + /** + * 获取数据失败 + * @param block (msg: String, errorCode: Int) -> Unit + */ + fun onFailed(block: (msg: String?, code: Int) -> Unit) { + this.onFailed = block + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/http/RetrofitClient.kt b/app/src/main/java/com/bingce/controlnetwork/http/RetrofitClient.kt new file mode 100644 index 0000000..e1149cc --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/http/RetrofitClient.kt @@ -0,0 +1,142 @@ +package com.bingce.controlnetwork.http + +import android.util.Log +import blankj.utilcode.util.ToastUtils +import com.bingce.controlapphelper.util.GsonUtil +import com.bingce.controlnetwork.BuildConfig +import com.google.gson.JsonParseException +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import okhttp3.Interceptor +import okhttp3.MediaType.Companion.toMediaTypeOrNull +import okhttp3.OkHttpClient +import okhttp3.RequestBody +import okhttp3.RequestBody.Companion.toRequestBody +import okhttp3.logging.HttpLoggingInterceptor +import org.apache.http.conn.ConnectTimeoutException +import org.json.JSONException +import retrofit2.HttpException +import retrofit2.Retrofit +import retrofit2.converter.gson.GsonConverterFactory +import java.io.IOException +import java.net.SocketTimeoutException +import java.net.UnknownHostException +import java.util.concurrent.TimeUnit + +object RetrofitClient { + //根路径 + private const val BASE_URL = "https://www.wanandroid.com/" + + private val mMediaTypeJson = "application/json; charset=utf-8".toMediaTypeOrNull() + + private val retrofit = Retrofit.Builder() + .baseUrl(BASE_URL) + .addConverterFactory(GsonConverterFactory.create()) + .client(initOkhttpClient()) + .build() + + + private fun initOkhttpClient(): OkHttpClient { + return OkHttpClient.Builder() + .retryOnConnectionFailure(true) //重试 + .connectTimeout(20, TimeUnit.SECONDS) + .readTimeout(20, TimeUnit.SECONDS) + .writeTimeout(20, TimeUnit.SECONDS) +// .addNetworkInterceptor(initTokenInterceptor()) + .addInterceptor(initLogInterceptor()) + .build() + } + + private fun initTokenInterceptor(): Interceptor = Interceptor { chain -> // 为请求添加 Token + val token: String? = null + val originalRequest = chain.request() + if (token.isNullOrEmpty()) { + chain.proceed(originalRequest) + } else { + val updateRequest = originalRequest.newBuilder().header("token", token).build() + chain.proceed(updateRequest) + } + } + + + /* + * 日志拦截器 + * */ + private fun initLogInterceptor(): HttpLoggingInterceptor { + if (!BuildConfig.DEBUG) { //生产环境不打日志 + return HttpLoggingInterceptor() + } + + val interceptor = HttpLoggingInterceptor { message -> Log.d("OkhttpClient", message) } + interceptor.level = HttpLoggingInterceptor.Level.BODY + return interceptor + } + + // 请求数据转 Json 形式; + open fun getJsonBody(data: Any): RequestBody { + val strEntity = GsonUtil.toJson(data) + return strEntity.toRequestBody(mMediaTypeJson) + } + + fun create(serviceClass: Class): T = retrofit.create(serviceClass) + + inline fun createService(): T = create(T::class.java) + + + suspend inline fun apiCall(crossinline call: suspend CoroutineScope.() -> T): T? { + return withContext(Dispatchers.IO) { + var res: T? = null + try { + res = call() + } catch (e: Throwable) { + Log.e("ApiCaller", "request error", e) + // 请求出错,将状态码和消息封装为 ResponseResult +// return@withContext ApiException.build(e).toResponse() + ToastUtils.showShort(ApiException.build(e).toString()) + } + return@withContext res + } + } + + // 网络、数据解析错误处理 + class ApiException(val code: Int, override val message: String?, override val cause: Throwable? = null) : + RuntimeException(message, cause) { + companion object { + // 网络状态码 + const val CODE_NET_ERROR = 4000 + const val CODE_TIMEOUT = 4080 + const val CODE_JSON_PARSE_ERROR = 4010 + const val CODE_SERVER_ERROR = 5000 + + // 业务状态码 + const val CODE_AUTH_INVALID = 401 + + fun build(e: Throwable): ApiException { + return if (e is HttpException) { + ApiException(CODE_NET_ERROR, "网络异常(${e.code()},${e.message()})") + } else if (e is UnknownHostException) { + ApiException(CODE_NET_ERROR, "网络连接失败,请检查后再试") + } else if (e is ConnectTimeoutException || e is SocketTimeoutException) { + ApiException(CODE_TIMEOUT, "请求超时,请稍后再试") + } else if (e is IOException) { + ApiException(CODE_NET_ERROR, "网络异常(${e.message})") + } else if (e is JsonParseException || e is JSONException) { + // Json解析失败 + ApiException(CODE_JSON_PARSE_ERROR, "数据解析错误,请稍后再试") + } else { + ApiException(CODE_SERVER_ERROR, "系统错误(${e.message})") + } + } + } + +// fun toResponse(): ResponseResult { +// return ResponseResult(code, message) +// } + + override + fun toString(): String { + return "code:$code,message:$message" + } + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/http/sevice/CommonService.kt b/app/src/main/java/com/bingce/controlnetwork/http/sevice/CommonService.kt new file mode 100644 index 0000000..71c7c0b --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/http/sevice/CommonService.kt @@ -0,0 +1,9 @@ +package com.bingce.controlnetwork.http.sevice + +import com.google.gson.JsonObject +import retrofit2.http.GET + +interface CommonService { + @GET("article/list/0/json") + suspend fun getPassageData(): JsonObject +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/adapter/BaseAdapterNew.java b/app/src/main/java/com/bingce/controlnetwork/newui/adapter/BaseAdapterNew.java new file mode 100644 index 0000000..11fe598 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/adapter/BaseAdapterNew.java @@ -0,0 +1,89 @@ +package com.bingce.controlnetwork.newui.adapter; + +import android.content.Context; +import android.view.ContextMenu; +import android.view.LayoutInflater; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlnetwork.adapter.contextmenu.IAdapterContextMenu; + +import java.util.List; + +/** + * Created by YanZhenjie on 2017/10/3. + */ +public abstract class BaseAdapterNew extends RecyclerView.Adapter { + private IItemClickListener mItemClickListener; + protected IAdapterContextMenu adapterContextMenu; + + protected List mDataList; + protected Context mContext; + + private final LayoutInflater mInflater; + + public BaseAdapterNew(Context context) { + this.mContext = context; + this.mInflater = LayoutInflater.from(context); + } + + public LayoutInflater getInflater() { + return mInflater; + } + + + @Override + public int getItemCount() { + return mDataList == null ? 0 : mDataList.size(); + } + + public T getBean(int position) { + return mDataList.get(position); + } + + @Override + public void onBindViewHolder(@NonNull VH holder, int position) { + holder.itemView.setOnClickListener(v -> { + if (mItemClickListener != null) { + mItemClickListener.clickItem(mDataList.get(holder.getBindingAdapterPosition())); + } + }); + + holder.itemView.setOnCreateContextMenuListener((menu, v, menuInfo) -> + createMenu(menu, mDataList.get(holder.getBindingAdapterPosition()))); + + onBindViewHolderDo(holder, position); + } + + protected abstract void onBindViewHolderDo(VH holder, int position); + + + protected void createMenu(ContextMenu menu, T bean) { + if (adapterContextMenu == null) return; + menu.clear(); + for (int index = 0; index < adapterContextMenu.menuItemSize(); index++) { + menu.add(0, index, 0, adapterContextMenu.menuItemName(index)); + MenuItem menuItem = menu.getItem(index); + if (menuItem != null) { + menuItem.setOnMenuItemClickListener(item -> + adapterContextMenu.onMenuItemClick(bean, item)); + } + } + } + + public void setAdapterContextMenu(IAdapterContextMenu adapterContextMenu) { + this.adapterContextMenu = adapterContextMenu; + } + + public void setOnItemClickListener(IItemClickListener mItemClickListener) { + this.mItemClickListener = mItemClickListener; + } + + public void refreshData(List dataList) { + this.mDataList = dataList; + notifyDataSetChanged(); + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/adapter/IItemClickListener.java b/app/src/main/java/com/bingce/controlnetwork/newui/adapter/IItemClickListener.java new file mode 100644 index 0000000..e4c128b --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/adapter/IItemClickListener.java @@ -0,0 +1,5 @@ +package com.bingce.controlnetwork.newui.adapter; + +public interface IItemClickListener { + void clickItem(T t); +} diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/adapter/PointListAdapter.java b/app/src/main/java/com/bingce/controlnetwork/newui/adapter/PointListAdapter.java new file mode 100644 index 0000000..5d958a9 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/adapter/PointListAdapter.java @@ -0,0 +1,61 @@ +package com.bingce.controlnetwork.newui.adapter; + +import android.content.Context; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; + +import com.bingce.controlapphelper.datasource.database.ProjectType; +import com.bingce.controlapphelper.datasource.database.point.PointRecord; +import com.bingce.controlnetwork.databinding.NewItemPointListBinding; +import com.bingce.controlnetwork.newui.viewholder.PointListViewHolder; + + +public class PointListAdapter extends BaseAdapterNew { + + private boolean isPlatCoordinate; + private String projectType; + + public PointListAdapter(Context context) { + super(context); + } + + @NonNull + @Override + public PointListViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + return new PointListViewHolder(NewItemPointListBinding.inflate(getInflater(), parent, false)); + } + + @Override + protected void onBindViewHolderDo(PointListViewHolder holder, int position) { + PointRecord pointRecordTj = mDataList.get(position); + //num就是name 因为从天津拷贝过来的 + holder.mBinding.tvPointNum.setText(pointRecordTj.getName()); +// holder.mBinding.tvPointName.setText(""); + + holder.mBinding.tvX.setVisibility(View.VISIBLE); + holder.mBinding.tvY.setVisibility(View.VISIBLE); + if (ProjectType.isLevel(projectType)) { + holder.mBinding.tvX.setVisibility(View.GONE); + holder.mBinding.tvY.setVisibility(View.GONE); + holder.mBinding.tvZ.setText("高程:" + pointRecordTj.getZ()); + } else if (ProjectType.isHeightTraverse(projectType)) { + holder.mBinding.tvX.setText("经度:" + pointRecordTj.getLongitude()); + holder.mBinding.tvY.setText("纬度:" + pointRecordTj.getLatitude()); + holder.mBinding.tvZ.setText("高程:" + pointRecordTj.getZ()); + } else { + holder.mBinding.tvX.setText("X:" + pointRecordTj.getX()); + holder.mBinding.tvY.setText("Y:" + pointRecordTj.getY()); + holder.mBinding.tvZ.setText("Z:" + pointRecordTj.getZ()); + } + } + + public void setIsPlatCoordinate(boolean isPlatCoordinate) { + this.isPlatCoordinate = isPlatCoordinate; + } + + public void setProjectType(String projectType) { + this.projectType = projectType; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/adapter/ProjectListAdapter.java b/app/src/main/java/com/bingce/controlnetwork/newui/adapter/ProjectListAdapter.java new file mode 100644 index 0000000..1a659d2 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/adapter/ProjectListAdapter.java @@ -0,0 +1,70 @@ +package com.bingce.controlnetwork.newui.adapter; + +import android.content.Context; +import android.view.ContextMenu; +import android.view.MenuItem; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; + +import com.bingce.controlapphelper.datasource.database.ProjectTypeValue; +import com.bingce.controlapphelper.datasource.database.project.ProjectRecord; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.databinding.NewItemProjectListBinding; +import com.bingce.controlnetwork.newui.viewholder.ProjectListViewHolder; + + +public class ProjectListAdapter extends BaseAdapterNew { + + public ProjectListAdapter(Context context) { + super(context); + } + + @NonNull + @Override + public ProjectListViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + return new ProjectListViewHolder(NewItemProjectListBinding.inflate(getInflater(), parent, false)); + } + + @Override + protected void onBindViewHolderDo(ProjectListViewHolder holder, int position) { + ProjectRecord bean = mDataList.get(position); + holder.mBinding.tvIndex.setText(String.valueOf(position + 1)); + holder.mBinding.tvProjectName.setText(bean.getProjectName()); + + if (bean.projectType == null || ProjectTypeValue.TRIANGLE.equals(bean.projectType)) { + holder.mBinding.tvProjectType.setText(Tools.getString(R.string.triangular_wire)); + } else if (ProjectTypeValue.CONNECTION.equals(bean.projectType)) { + holder.mBinding.tvProjectType.setText(Tools.getString(R.string.contact_measurement)); + } else if (ProjectTypeValue.HEIGHT_TRAVERSE.equals(bean.projectType)) { + holder.mBinding.tvProjectType.setText(Tools.getString(R.string.elevation_conductor)); + } else if (ProjectTypeValue.LEVEL.equals(bean.projectType)) { + holder.mBinding.tvProjectType.setText(Tools.getString(R.string.level)); + } else if (ProjectTypeValue.GNSS.equals(bean.projectType)) { + holder.mBinding.tvProjectType.setText(Tools.getString(R.string.gnss)); + } else { + holder.mBinding.tvProjectType.setText(""); + } + + holder.mBinding.tvTolerance.setText(bean.getToleranceName()); + } + + @Override + protected void createMenu(ContextMenu menu, ProjectRecord bean) { + if (adapterContextMenu == null) return; + menu.clear(); + int menuSize = 2; + if (ProjectTypeValue.GNSS.equals(bean.projectType)) { + menuSize = 3; + } + for (int index = 0; index < menuSize; index++) { + menu.add(0, index, 0, adapterContextMenu.menuItemName(index)); + MenuItem menuItem = menu.getItem(index); + if (menuItem != null) { + menuItem.setOnMenuItemClickListener(item -> + adapterContextMenu.onMenuItemClick(bean, item)); + } + } + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/adapter/StationListAdapter.java b/app/src/main/java/com/bingce/controlnetwork/newui/adapter/StationListAdapter.java new file mode 100644 index 0000000..e84cf02 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/adapter/StationListAdapter.java @@ -0,0 +1,37 @@ +package com.bingce.controlnetwork.newui.adapter; + +import android.content.Context; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; + +import com.bingce.controlnetwork.databinding.NewItemStationListBinding; +import com.bingce.controlnetwork.newui.model.StationListBean; +import com.bingce.controlnetwork.newui.viewholder.StationListViewHolder; + + +/** + * 测站列表adapter + */ +public class StationListAdapter extends BaseAdapterNew { + + public StationListAdapter(Context context) { + super(context); + } + + @NonNull + @Override + public StationListViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + return new StationListViewHolder(NewItemStationListBinding.inflate(getInflater(), parent, false)); + } + + @Override + protected void onBindViewHolderDo(StationListViewHolder holder, int position) { + StationListBean bean = mDataList.get(position); + holder.mBinding.tvIndex.setText(String.valueOf(position + 1)); + holder.mBinding.tvStationName.setText(bean.getStationName()); + holder.mBinding.tvStationType.setText(bean.getStationType()); + holder.mBinding.tvPointOrder.setText(bean.getStationPiontOrder()); + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/base/BaseBindingActivity.kt b/app/src/main/java/com/bingce/controlnetwork/newui/base/BaseBindingActivity.kt new file mode 100644 index 0000000..7167151 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/base/BaseBindingActivity.kt @@ -0,0 +1,99 @@ +package com.bingce.controlnetwork.newui.base + +import android.os.Bundle +import android.view.MenuItem +import android.view.View +import android.view.ViewGroup +import android.view.WindowManager +import android.widget.LinearLayout +import androidx.annotation.StringRes +import androidx.appcompat.app.AppCompatActivity +import androidx.appcompat.app.AppCompatDelegate +import androidx.appcompat.widget.Toolbar +import androidx.core.content.ContextCompat +import androidx.viewbinding.ViewBinding +import blankj.utilcode.util.Utils +import com.bingce.controlnetwork.App +import com.bingce.controlnetwork.R +import com.bingce.controlnetwork.databinding.ActivityBaseBindingBinding + +import org.polaric.colorful.Colorful + +abstract class BaseBindingActivity : AppCompatActivity() { + protected val mBinding get() = _binding!! + private var _binding: VB? = null + + private lateinit var toolBar: Toolbar + + + abstract fun getBinding(): VB + abstract fun initView() + abstract fun initData() + + override fun onCreate(savedInstanceState: Bundle?) { + initTheme() + super.onCreate(savedInstanceState) + setContentView(getContentView()) + initToolBar() + initView() + initData() + } + + private fun initTheme() { + setTheme(Colorful.getThemeDelegate().styleResBase) + getTheme().applyStyle(Colorful.getThemeDelegate().styleResPrimary, true) + getTheme().applyStyle(Colorful.getThemeDelegate().styleResAccent, true) + val app = Utils.getApp() as App + if (app.isThemeDark) { + delegate.localNightMode = AppCompatDelegate.MODE_NIGHT_YES + } else { + delegate.localNightMode = AppCompatDelegate.MODE_NIGHT_NO + } + window.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); + } + + private fun getContentView(): View { + val baseBinding = ActivityBaseBindingBinding.inflate(layoutInflater) + val layoutParams = LinearLayout.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT + ) + _binding = getBinding() + baseBinding.llParent.addView(mBinding.root, layoutParams) + baseBinding.llParent.setBackgroundColor( + ContextCompat.getColor( + this, + R.color.bg_content_new + ) + ) + + toolBar = baseBinding.ilToolBar.toolbar + return baseBinding.root + } + + protected open fun initToolBar() { + setSupportActionBar(toolBar) + if (supportActionBar != null) supportActionBar!!.setDisplayHomeAsUpEnabled(true) + } + + protected fun setToolbarTitle(text: String?) { + toolBar.setTitle(text) + } + + protected fun setToolbarTitle(@StringRes text: Int) { + toolBar.setTitle(text) + } + + override fun onOptionsItemSelected(item: MenuItem): Boolean { + if (item.itemId == android.R.id.home) { + if (isFinishAtOnce()) + finish() + } + return super.onOptionsItemSelected(item) + } + + protected open fun isFinishAtOnce(): Boolean { + return true + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/base/BaseFragmentBinding.java b/app/src/main/java/com/bingce/controlnetwork/newui/base/BaseFragmentBinding.java new file mode 100644 index 0000000..2cbde91 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/base/BaseFragmentBinding.java @@ -0,0 +1,59 @@ +package com.bingce.controlnetwork.newui.base; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.viewbinding.ViewBinding; + +import com.bingce.controlnetwork.fragment.base.BaseFragment; + +public abstract class BaseFragmentBinding extends BaseFragment { + protected VB mBinding; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + mBinding = getViewBinding(inflater, container); + return mBinding.getRoot(); + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initView(); + initData(); + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + mBinding = null; + } + + protected abstract VB getViewBinding(@NonNull LayoutInflater inflater, @Nullable ViewGroup container); + + protected abstract void initView(); + + protected abstract void initData(); + + protected String getArgumentString(String key) { + Bundle bundle = getArguments(); + if (bundle != null) { + return bundle.getString(key); + } + return null; + } + + protected int getArgumentInt(String key) { + Bundle bundle = getArguments(); + if (bundle != null) { + return bundle.getInt(key); + } + return -1; + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/configfragment/ConfigFragment.kt b/app/src/main/java/com/bingce/controlnetwork/newui/configfragment/ConfigFragment.kt new file mode 100644 index 0000000..6f761d1 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/configfragment/ConfigFragment.kt @@ -0,0 +1,108 @@ +package com.bingce.controlnetwork.newui.configfragment + +import android.content.Context +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.core.os.bundleOf +import androidx.fragment.app.FragmentManager +import androidx.lifecycle.LifecycleOwner +import com.bingce.controlnetwork.R +import com.bingce.controlnetwork.databinding.NewFragmentConfigBinding +import com.bingce.controlnetwork.fragment.PrismManageFragment +import com.bingce.controlnetwork.fragment.SelectExportHeightTraverseFragment +import com.bingce.controlnetwork.fragment.SelectExportSurveyorRecordFragment +import com.bingce.controlnetwork.fragment.SelectExportSurveyorRecordWireFileFragment +import com.bingce.controlnetwork.fragment.ToleranceManageFragment +import com.bingce.controlnetwork.func.level.fragment.LevelSelectExportFragment +import com.bingce.controlnetwork.newui.base.BaseFragmentBinding +import com.bingce.controlnetwork.util.SelectDeviceTypeUtil + + +class ConfigFragment : BaseFragmentBinding() { + override fun getViewBinding( + inflater: LayoutInflater, + container: ViewGroup? + ): NewFragmentConfigBinding { + return NewFragmentConfigBinding.inflate(inflater, container, false) + } + + override fun initView() { + //管理 + mBinding.ilInstrumentManagement.iv.setImageResource(R.mipmap.icon_ts_connecting) + mBinding.ilInstrumentManagement.tv.setText(R.string.instrument_management) + mBinding.ilPrismManagement.iv.setImageResource(R.mipmap.icon_prism_manager) + mBinding.ilPrismManagement.tv.setText(R.string.prism_manager) + mBinding.ilCustomTolerance.iv.setImageResource(R.mipmap.ic_tolerance_24) + mBinding.ilCustomTolerance.tv.setText("自定义限差") + //三角导线联系测量 + mBinding.ilExportMeasure.iv.setImageResource(R.mipmap.ic_export) + mBinding.ilExportMeasure.tv.setText(R.string.export) + mBinding.ilExportWire.iv.setImageResource(R.mipmap.ic_export_wire) + mBinding.ilExportWire.tv.setText(R.string.export_wire_file) + //水准 + mBinding.ilExportLevel.iv.setImageResource(R.mipmap.ic_export) + mBinding.ilExportLevel.tv.setText(R.string.level_export) + //高程导线 + //高程导线数据导出 + mBinding.ilExportHeightTraverse.iv.setImageResource(R.mipmap.ic_export) + mBinding.ilExportHeightTraverse.tv.setText(R.string.export_height_traverse) + + initListener() + } + + private fun initListener() { + mBinding.ilInstrumentManagement.root.setOnClickListener { + //仪器管理 +// val intent = Intent(activity, ConnectTSActivity::class.java) +// intent.putExtra("customChannel", AppChannel.customChannel) +// startActivity(intent) + SelectDeviceTypeUtil.showDeviceTypeDialog() + } + mBinding.ilPrismManagement.root.setOnClickListener { + //棱镜管理 + PrismManageFragment.start(activity) + } + mBinding.ilCustomTolerance.root.setOnClickListener { + //自定义限差 + ToleranceManageFragment.start(activity, null) + } + mBinding.ilExportMeasure.root.setOnClickListener { + //观测数据导出 先选导出类型 + startExportMeasureData(requireContext(), childFragmentManager, viewLifecycleOwner) + } + mBinding.ilExportWire.root.setOnClickListener { + //导线文件导出 + SelectExportSurveyorRecordWireFileFragment.start(context) + } + mBinding.ilExportLevel.root.setOnClickListener { + //水准数据导出 + LevelSelectExportFragment.start(activity) + } + mBinding.ilExportHeightTraverse.root.setOnClickListener { + //高程导线导出 + SelectExportHeightTraverseFragment.start(requireContext()) + } + } + + override fun initData() { + } + + /** + * 测院导出观测前先选择导出文件类型 + * + * @param context + * @param fragmentManager + * @param lifecycleOwner + */ + private fun startExportMeasureData( + context: Context, fragmentManager: FragmentManager, + lifecycleOwner: LifecycleOwner + ) { + SelectMeasureDataExportTypeFragment.start(fragmentManager, lifecycleOwner) { beanList -> + SelectExportSurveyorRecordFragment.start( + context, bundleOf(SelectExportSurveyorRecordFragment.KEY_DATA to beanList) + ) + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/configfragment/SelectExportType.java b/app/src/main/java/com/bingce/controlnetwork/newui/configfragment/SelectExportType.java new file mode 100644 index 0000000..ba37586 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/configfragment/SelectExportType.java @@ -0,0 +1,70 @@ +package com.bingce.controlnetwork.newui.configfragment; + +import android.os.Parcel; +import android.os.Parcelable; + +import androidx.annotation.Keep; + +@Keep +public class SelectExportType implements Parcelable { + public static final String TYPE_CONTROL = "TYPE_CONTROL"; + public static final String TYPE_KE_SHA = "TYPE_KE_SHA"; + public static final String TYPE_NAN_FANG = "TYPE_NAN_FANG"; + public static final String TYPE_QI_FEI = "TYPE_QI_FEI"; + public static final String TYPE_PING_CHA_ZHI_XING = "TYPE_PING_CHA_ZHI_XING"; + + private final String name; + private final String type; + private boolean isSelect; + + public SelectExportType(String name, String type) { + this.name = name; + this.type = type; + } + + protected SelectExportType(Parcel in) { + name = in.readString(); + type = in.readString(); + isSelect = in.readByte() != 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeString(name); + dest.writeString(type); + dest.writeByte((byte) (isSelect ? 1 : 0)); + } + + @Override + public int describeContents() { + return 0; + } + + public static final Creator CREATOR = new Creator() { + @Override + public SelectExportType createFromParcel(Parcel in) { + return new SelectExportType(in); + } + + @Override + public SelectExportType[] newArray(int size) { + return new SelectExportType[size]; + } + }; + + public String getName() { + return name; + } + + public String getType() { + return type; + } + + public boolean isSelect() { + return isSelect; + } + + public void setSelect(boolean select) { + isSelect = select; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/configfragment/SelectMeasureDataExportTypeFragment.java b/app/src/main/java/com/bingce/controlnetwork/newui/configfragment/SelectMeasureDataExportTypeFragment.java new file mode 100644 index 0000000..80234a1 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/configfragment/SelectMeasureDataExportTypeFragment.java @@ -0,0 +1,170 @@ +package com.bingce.controlnetwork.newui.configfragment; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.databinding.ItemSelectMeasureDataExportTypeBinding; +import com.google.android.material.bottomsheet.BottomSheetDialogFragment; + +import java.util.ArrayList; +import java.util.List; + +import blankj.utilcode.util.ToastUtils; + +/** + * 选择观测数据导出的文件类型 + */ +public class SelectMeasureDataExportTypeFragment extends BottomSheetDialogFragment { + + private static final String KEY_REQUEST_SELECT = "__SELECT__"; + private static final String KEY_TYPE = "__SELECT_TYPE__"; + + private final List dataList = new ArrayList<>(); + private RecyclerView recyclerView; + private View btnCancel; + private View btnConfirm; + + @Override + public void onStart() { + super.onStart(); +// Dialog dialog = getDialog(); +// if (dialog != null) { +// Window window = dialog.getWindow(); +// if (window != null) { +// window.setLayout( +// WindowManager.LayoutParams.MATCH_PARENT, +// WindowManager.LayoutParams.WRAP_CONTENT); +// } +// } + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + return inflater.inflate(R.layout.fragment_select_measure_data_export_type, container, false); + } + + + public static void start(FragmentManager fragmentManager, + @NonNull LifecycleOwner lifecycleOwner, + IOnSelectCallback callback) { + SelectMeasureDataExportTypeFragment fragment = new SelectMeasureDataExportTypeFragment(); + fragmentManager + .setFragmentResultListener( + KEY_REQUEST_SELECT, + lifecycleOwner, + (requestKey, result) -> { + if (KEY_REQUEST_SELECT.equals(requestKey)) { + callback.onSurveyorCycleSelected(result.getParcelableArrayList(KEY_TYPE)); + } + }); + fragment.show(fragmentManager, null); + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + recyclerView = view.findViewById(R.id.recyclerView); + btnCancel = view.findViewById(R.id.btnCancel); + btnConfirm = view.findViewById(R.id.btnConfirm); + initView(); + initData(); + initListener(); + } + + private void initListener() { + btnCancel.setOnClickListener((v) -> { + dismissAllowingStateLoss(); + }); + btnConfirm.setOnClickListener((v) -> { + startConfirm(); + }); + } + + private void startConfirm() { + List exportList = new ArrayList<>(); + for (SelectExportType bean : dataList) { + if (bean.isSelect()) { + exportList.add(bean); + } + } + if (exportList.isEmpty()) { + ToastUtils.showShort("请选择导出格式"); + return; + } + backData(exportList); + } + + private void initView() { + + } + + private void initData() { + dataList.add(new SelectExportType("导线助手格式", SelectExportType.TYPE_CONTROL)); + dataList.add(new SelectExportType("科傻格式", SelectExportType.TYPE_KE_SHA)); + dataList.add(new SelectExportType("南方平差易格式", SelectExportType.TYPE_NAN_FANG)); + dataList.add(new SelectExportType("启飞格式", SelectExportType.TYPE_QI_FEI)); + dataList.add(new SelectExportType("平差之星格式", SelectExportType.TYPE_PING_CHA_ZHI_XING)); + recyclerView.setAdapter(new Adapter()); + } + + private void backData(List selectList) { + Bundle args = new Bundle(); + args.putParcelableArrayList(KEY_TYPE, new ArrayList<>(selectList)); + getParentFragmentManager().setFragmentResult(KEY_REQUEST_SELECT, args); + dismiss(); + } + + public interface IOnSelectCallback { + void onSurveyorCycleSelected(ArrayList beanList); + } + + class Adapter extends RecyclerView.Adapter { + + @NonNull + @Override + public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + return new ViewHolder(ItemSelectMeasureDataExportTypeBinding.inflate(getLayoutInflater(), parent, false)); + } + + @Override + public void onBindViewHolder(@NonNull ViewHolder holder, int position) { + + SelectExportType bean = dataList.get(position); + + holder.mBinding.tv.setText(bean.getName()); + holder.mBinding.cb.setChecked(bean.isSelect()); + + holder.itemView.setOnClickListener(v -> { + bean.setSelect(!bean.isSelect()); + notifyItemChanged(holder.getBindingAdapterPosition()); + }); + + } + + @Override + public int getItemCount() { + return dataList.size(); + } + } + + private static class ViewHolder extends RecyclerView.ViewHolder { + @NonNull + private final ItemSelectMeasureDataExportTypeBinding mBinding; + + public ViewHolder(ItemSelectMeasureDataExportTypeBinding binding) { + super(binding.getRoot()); + this.mBinding = binding; + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/createeditpoint/CreateEditPointActvity.kt b/app/src/main/java/com/bingce/controlnetwork/newui/createeditpoint/CreateEditPointActvity.kt new file mode 100644 index 0000000..adc8df2 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/createeditpoint/CreateEditPointActvity.kt @@ -0,0 +1,379 @@ +package com.bingce.controlnetwork.newui.createeditpoint + +import android.content.Context +import android.content.Intent +import android.text.TextUtils +import android.view.View +import androidx.annotation.StringRes +import androidx.annotation.WorkerThread +import androidx.lifecycle.lifecycleScope +import blankj.utilcode.util.ToastUtils +import com.bingce.controlapphelper.datasource.database.ProjectType +import com.bingce.controlapphelper.datasource.database.ProjectTypeValue +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory +import com.bingce.controlapphelper.datasource.database.point.PointRecord +import com.bingce.controlapphelper.model.BundleConstants +import com.bingce.controlnetwork.R +import com.bingce.controlnetwork.databinding.ActivityNewUiCreateEditPointBinding +import com.bingce.controlnetwork.fragment.TipsFragment +import com.bingce.controlnetwork.newui.base.BaseBindingActivity +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + +/** + * 新建或编辑点 + */ +class CreateEditPointActvity : BaseBindingActivity() { + + private var editPoint: PointRecord? = null + + private var isKnown = false + + companion object { + const val KEY_POINT_TYPE = "KEY_POINT_TYPE" + const val KEY_EDIT_POINT = "KEY_EDIT_POINT" + + @JvmStatic + fun launch( + context: Context, + projectId: String, + projectType: String, + pointType: String, + eidtPoint: PointRecord? = null + ) { + context.startActivity(Intent(context, CreateEditPointActvity::class.java).apply { + putExtra(BundleConstants.KEY_PROJECT_ID, projectId) + putExtra(BundleConstants.KEY_PROJECT_TYPE, projectType) + putExtra(KEY_POINT_TYPE, pointType) + putExtra(KEY_EDIT_POINT, eidtPoint) + }) + } + } + + override fun getBinding(): ActivityNewUiCreateEditPointBinding { + return ActivityNewUiCreateEditPointBinding.inflate(layoutInflater) + } + + override fun initView() { + mBinding.ilPointNum.tvTitle.setText(R.string.point_name) + mBinding.ilPointNum.editText.setHint(R.string.please_enter_roll_call) + + setBaseUi() + initListener() + } + + private fun initIntentData() { + val pointType = getPointType() + isKnown = + PointRecord.TYPE_KNOWN_POINT == pointType || PointRecord.TYPE_GLOBAL_POINT == pointType + editPoint = getEditPoint() + } + + private fun initListener() { + mBinding.tvSaveContinue.setOnClickListener { + startSaveContinue() + } + mBinding.tvSaveQuit.setOnClickListener { + startSaveQuite() + } + } + + private fun startSaveQuite() { + checkSave { + if (editPoint == null) { + saveRecordForCreate { + finish() + } + } else { + saveRecordForEdit(editPoint!!) { + finish() + } + } + } + } + + private fun startSaveContinue() { + checkSave { + saveRecordForCreate() + clearContent() + val nextPointNum = getNextPointNum() + mBinding.ilPointNum.editText.setText(nextPointNum) + } + } + + private fun checkSave(success: () -> Unit) { + val pointNum = getPointNumber() + if (TextUtils.isEmpty(pointNum)) { + ToastUtils.showShort(R.string.please_enter_roll_call) + return + } + + if (isKnown) { + if (mBinding.ilPointX.root.visibility == View.VISIBLE) { + val x = getX() + if (TextUtils.isEmpty(x)) { + val hint = R.string.please_input_x +// val hint = +// if (isPlatCood) R.string.please_input_x else R.string.please_input_longitude + ToastUtils.showShort(hint) + return + } + } + if (mBinding.ilPointY.root.visibility == View.VISIBLE) { + val y = getY() + if (TextUtils.isEmpty(y)) { + val hint = R.string.please_input_y +// val hint = +// if (isPlatCood) R.string.please_input_y else R.string.please_input_latitude + ToastUtils.showShort(hint) + return + } + } + val z = getZ() + if (TextUtils.isEmpty(z)) { + val hint = R.string.please_enter_elevation +// val hint = if (isLevelProject()) { +// R.string.please_enter_elevation +// } else { +// if (isPlatCood) R.string.please_input_z else R.string.please_enter_elevation +// } + ToastUtils.showShort(hint) + return + } + } + + if (isNewCreatePoint()) { + checkSameNamePoint(pointNum) { + success() + } + return + } + success() + } + + private fun checkSameNamePoint(pointNum: String, success: () -> Unit) { + lifecycleScope.launch { + val pointRecord = withContext(Dispatchers.IO) { + val pointDataSource = SurveyorDatabaseFactory.instance.getPointDataSource() + pointDataSource.findByNameSync(pointNum, getProjectId()) + } + + if (pointRecord != null) { + //点名重复,提示 + TipsFragment.tipsOnly( + supportFragmentManager, + this@CreateEditPointActvity, + this@CreateEditPointActvity, + "同一项目下点号不能重复,请修改后重试操作。" + ) + return@launch + } + success() + } + } + + /** + * 设置平面还是大地坐标 + */ + private fun setBaseUi() { + if (!isNewCreatePoint()) { + mBinding.tvSaveContinue.visibility = View.GONE + } + + val projectType = getProjectType() + if (isLevelProject()) { + mBinding.ilPointX.root.visibility = View.GONE + mBinding.ilPointY.root.visibility = View.GONE + + setBaseTitleHint( + R.string.x_coord, + R.string.y_coord, + R.string.elevation, + R.string.please_input_x, + R.string.please_input_y, + R.string.please_enter_elevation + ) + } else if (ProjectType.isHeightTraverse(projectType)) { + setBaseTitleHint( + R.string.longitude, + R.string.latitude, + R.string.elevation, + R.string.please_input_longitude, + R.string.please_input_latitude, + R.string.please_enter_elevation + ) + } else { + setBaseTitleHint( + R.string.x_coord, R.string.y_coord, R.string.z_coord, + R.string.please_input_x, R.string.please_input_y, R.string.please_input_z + ) + } + + setEditData() + } + + private fun setBaseTitleHint( + @StringRes xCoord: Int, yCoord: Int, zCoord: Int, + pleaseInputX: Int, pleaseInputY: Int, @StringRes pleaseInputZ: Int + ) { + mBinding.ilPointX.tvTitle.setText(xCoord) + mBinding.ilPointY.tvTitle.setText(yCoord) + mBinding.ilPointZ.tvTitle.setText(zCoord) + mBinding.ilPointX.editText.setHint(pleaseInputX) + mBinding.ilPointY.editText.setHint(pleaseInputY) + mBinding.ilPointZ.editText.setHint(pleaseInputZ) + } + + private fun setEditData() { + editPoint?.let { + mBinding.ilPointNum.editText.setText(it.getName()) + + setCoordData(it.getX(), it.getY(), it.getZ()) +// setCoordData(it.getLongitude(), it.getLatitude(), it.getZ()) + } + } + + private fun setCoordData(x: Double, y: Double, z: Double) { + mBinding.ilPointX.editText.setText(x.toString()) + mBinding.ilPointY.editText.setText(y.toString()) + mBinding.ilPointZ.editText.setText(z.toString()) + } + + override fun initData() { + + + } + + override fun initToolBar() { + initIntentData() + val title = if (editPoint == null) R.string.new_point else R.string.edit_point + setToolbarTitle(title) + super.initToolBar() + } + + private fun getProjectId() = intent.getStringExtra(BundleConstants.KEY_PROJECT_ID)!! + private fun getProjectType() = intent.getStringExtra(BundleConstants.KEY_PROJECT_TYPE)!! + + private fun getPointType() = intent.getStringExtra(KEY_POINT_TYPE)!! + + private fun getEditPoint() = + intent.getParcelableExtra(KEY_EDIT_POINT) + + private fun isNewCreatePoint() = editPoint == null + + private fun getPointNumber() = mBinding.ilPointNum.editText.text.toString().trim() + private fun getX() = mBinding.ilPointX.editText.text.toString().trim() + private fun getY() = mBinding.ilPointY.editText.text.toString().trim() + private fun getZ() = mBinding.ilPointZ.editText.text.toString().trim() + + private fun getXDouble(): Double { + return xToDouble(getX()) + } + + private fun getYDouble(): Double { + return xToDouble(getY()) + } + + private fun getZDouble(): Double { + return xToDouble(getZ()) + } + + private fun xToDouble(value: String): Double { + return if (TextUtils.isEmpty(value)) { + 0.0 + } else { + value.toDouble() + } + } + + private fun clearContent() { + mBinding.ilPointX.editText.setText("") + mBinding.ilPointY.editText.setText("") + mBinding.ilPointZ.editText.setText("") + mBinding.ilPointX.editText.requestFocus() + } + + private fun getNextPointNum(): String { + val pointNumber = getPointNumber() + val index = getIndexForTianjin(pointNumber) + val word = getWordForTianjin(pointNumber) + return "${word}${index + 1}" + } + + private fun getIndexForTianjin(pointName: String): Int { + val pre = "\\D*" + val data = pointName.replace(pre.toRegex(), "") + return try { + data.toInt() + } catch (e: NumberFormatException) { + 0 + } + } + + private fun getWordForTianjin(pointName: String): String { + val pre = "\\d*" + return pointName.replace(pre.toRegex(), "") + } + + private fun saveRecordForEdit(pointRecord: PointRecord, success: () -> Unit) { + lifecycleScope.launch(Dispatchers.IO) { + val projectType = getProjectType() + if (ProjectType.isLevel(projectType) || ProjectType.isHeightTraverse(projectType)) { + pointRecord.setLongitude(getXDouble()) + pointRecord.setLatitude(getYDouble()) + } else { + pointRecord.setX(getXDouble()) + pointRecord.setY(getYDouble()) + } + pointRecord.setZ(getZDouble()) + pointRecord.setName(getPointNumber()) + pointRecord.setCode("") + pointRecord.setRemarks("") + SurveyorDatabaseFactory.instance + .getPointDataSource() + .saveSync(pointRecord) + success() + } + } + + private fun saveRecordForCreate(success: (() -> Unit)? = null) { + lifecycleScope.launch(Dispatchers.IO) { + val pointRecord = createPointRecord( + getProjectId(), getPointType(), getPointNumber(), "", + getXDouble(), getYDouble(), getZDouble(), "", -1, + ) + SurveyorDatabaseFactory.instance + .getPointDataSource() + .save(pointRecord) + success?.invoke() + } + } + + @WorkerThread + private fun createPointRecord( + projectId: String, + pointType: String, + name: String, + code: String, + x: Double, + y: Double, + z: Double, + remarks: String, + orderIndex: Int, + ): PointRecord { + val projectType = getProjectType() + return if (ProjectType.isLevel(projectType) || ProjectType.isHeightTraverse(projectType)) { + PointRecord.createLlhPoint(projectId, pointType, name, x, y, z) + } else { + PointRecord.point( + projectId, pointType, name, code, + x, y, z, remarks, + orderIndex.toLong() + ) + } + } + + private fun isLevelProject() = ProjectTypeValue.LEVEL == getProjectType() + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/mefragment/MeFragment.kt b/app/src/main/java/com/bingce/controlnetwork/newui/mefragment/MeFragment.kt new file mode 100644 index 0000000..9ec0a21 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/mefragment/MeFragment.kt @@ -0,0 +1,116 @@ +package com.bingce.controlnetwork.newui.mefragment + +import android.content.Intent +import android.os.Process +import android.util.Log +import android.view.LayoutInflater +import android.view.Menu +import android.view.MenuInflater +import android.view.MenuItem +import android.view.ViewGroup +import androidx.fragment.app.activityViewModels +import blankj.utilcode.util.ToastUtils +import blankj.utilcode.util.Utils +import cn.leancloud.LCUser +import com.bingce.controlnetwork.R +import com.bingce.controlnetwork.activity.AboutActivity +import com.bingce.controlnetwork.activity.SettingsActivity +import com.bingce.controlnetwork.activity.backup.BackupExportActivity +import com.bingce.controlnetwork.activity.backup.launch.BackupImportHelper +import com.bingce.controlnetwork.activity.user.LoginActivity +import com.bingce.controlnetwork.activity.user.UserInfoActivity +import com.bingce.controlnetwork.databinding.NewFragmentMeBinding +import com.bingce.controlnetwork.newui.base.BaseFragmentBinding +import com.bingce.controlnetwork.viewmodel.MainActivityViewModel +import com.bingce.surveyor.agentweb.AgentWebActivity +import com.bumptech.glide.Glide + +/** + * 我的页面 + */ +class MeFragment : BaseFragmentBinding() { + private val backupImportUtil = BackupImportHelper(this) + + private val mainActivityVm by activityViewModels() + + override fun getViewBinding( + inflater: LayoutInflater, + container: ViewGroup? + ): NewFragmentMeBinding { + return NewFragmentMeBinding.inflate(inflater, container, false) + } + + override fun initView() { + setHasOptionsMenu(true) + initListener() + initObserver() + } + + private fun initObserver() { + mainActivityVm.refreshLoginUserLiveData.observe(this) { + Log.d("hwhw", " mainActivityVm.refreshLoginUserLiveData.=" + it.userName) + mBinding.tvNickName.text = it?.nickName ?: "请登录" + mBinding.tvPhoneOrEmail.text = it?.userName + it?.avator?.let { avator -> + Glide.with(this).load(avator).into(mBinding.ivAvatar) + } + } + } + + override fun initData() { + } + + override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { + inflater.inflate(R.menu.menu_measure_debug, menu) + super.onCreateOptionsMenu(menu, inflater) + } + + private fun initListener() { + mBinding.llSetting.setOnClickListener { + //设置 + startActivity(Intent(requireContext(), SettingsActivity::class.java)) + } + mBinding.llDataBackup.setOnClickListener { + //数据备份 + BackupExportActivity.start(requireContext(), BackupExportActivity::class.java) + } + mBinding.llDataImport.setOnClickListener { + //数据导入 + backupImportUtil.doImport(requireContext()) { success -> + if (success) { + restartApplication() + } + } + } + mBinding.llAbout.setOnClickListener { + //关于 + startActivity(Intent(requireContext(), AboutActivity::class.java)) + } + mBinding.llUser.setOnClickListener { + if (LCUser.getCurrentUser() != null) { + startActivity(Intent(requireContext(), UserInfoActivity::class.java)) + } else { + val intent = Intent(Utils.getApp(), LoginActivity::class.java) + intent.putExtra("finishTo", UserInfoActivity::class.java.name) + startActivity(intent) + } + } + } + + override fun onOptionsItemSelected(item: MenuItem): Boolean { + if (item.itemId == R.id.measureDebug) { + Utils.isTest = !Utils.isTest + if (Utils.isTest) { + ToastUtils.showShort(R.string.debug_on) + } else { + ToastUtils.showShort(R.string.debug_off) + } + } + return super.onOptionsItemSelected(item) + } + + private fun restartApplication() { + Process.killProcess(Process.myPid()) + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/model/StationListBean.kt b/app/src/main/java/com/bingce/controlnetwork/newui/model/StationListBean.kt new file mode 100644 index 0000000..5581a82 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/model/StationListBean.kt @@ -0,0 +1,15 @@ +package com.bingce.controlnetwork.newui.model + +import androidx.annotation.Keep + +@Keep +data class StationListBean( + val projectType: String?, + val stationId: String, + val stationName: String, + val stationType: String, + val stationPiontOrder: String, + + val lineType: String?, + val lineId: String? +) diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/projectedit/IProjectCreateEditOperate.kt b/app/src/main/java/com/bingce/controlnetwork/newui/projectedit/IProjectCreateEditOperate.kt new file mode 100644 index 0000000..f82435b --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/projectedit/IProjectCreateEditOperate.kt @@ -0,0 +1,5 @@ +package com.bingce.controlnetwork.newui.projectedit + +interface IProjectCreateEditOperate { + fun save(success: () -> Unit) +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/projectedit/ProjectCreateEditActivity.kt b/app/src/main/java/com/bingce/controlnetwork/newui/projectedit/ProjectCreateEditActivity.kt new file mode 100644 index 0000000..b1d1633 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/projectedit/ProjectCreateEditActivity.kt @@ -0,0 +1,90 @@ +package com.bingce.controlnetwork.newui.projectedit + +import android.content.Context +import android.content.Intent +import android.view.Menu +import android.view.MenuItem +import androidx.activity.viewModels +import androidx.fragment.app.Fragment + +import com.bingce.controlapphelper.datasource.database.ProjectTypeValue +import com.bingce.controlapphelper.model.BundleConstants +import com.bingce.controlnetwork.R +import com.bingce.controlnetwork.databinding.NewActivityProjectCreateEidtBinding +import com.bingce.controlnetwork.newui.base.BaseBindingActivity + +class ProjectCreateEditActivity : BaseBindingActivity() { + private val projectCreateEditVm by viewModels() + + private var currentFragment: Fragment? = null + + companion object { + @JvmStatic + fun launch(context: Context, projectType: String?, projectId: String? = null) { + context.startActivity(Intent(context, ProjectCreateEditActivity::class.java).apply { + putExtra(BundleConstants.KEY_PROJECT_ID, projectId) + putExtra(BundleConstants.KEY_PROJECT_TYPE, projectType) + }) + } + } + + override fun onCreateOptionsMenu(menu: Menu?): Boolean { + menuInflater.inflate(R.menu.menu_save, menu) + return super.onCreateOptionsMenu(menu) + } + + override fun onOptionsItemSelected(item: MenuItem): Boolean { + if (item.itemId == R.id.menuSave) { + val iProjectCreateEditOperate = currentFragment as? IProjectCreateEditOperate + iProjectCreateEditOperate?.save { + finish() + } + } + return super.onOptionsItemSelected(item) + } + + override fun getBinding(): NewActivityProjectCreateEidtBinding { + return NewActivityProjectCreateEidtBinding.inflate(layoutInflater) + } + + override fun initView() { + projectCreateEditVm.projectId = getProjectId() + projectCreateEditVm.projectType = getProjectType() + + startFragment() + } + + private fun startFragment() { + when (val projectType = getProjectType()) { + ProjectTypeValue.CONNECTION -> { +// currentFragment = ProjectCreateEditConnectionFragment() + } + + ProjectTypeValue.LEVEL -> { + currentFragment = ProjectCreateEditLevelFragment() + } + + ProjectTypeValue.TRIANGLE -> { +// currentFragment = ProjectCreateEditTriangleFragment() + } + + else -> { + if (projectType == null) { +// currentFragment = ProjectCreateEditTriangleFragment() + } + } + } + + if (currentFragment != null) { + supportFragmentManager.beginTransaction() + .replace(R.id.container, currentFragment!!) + .commitNow() + } + } + + override fun initData() { + } + + private fun getProjectType() = intent.getStringExtra(BundleConstants.KEY_PROJECT_TYPE) + private fun getProjectId() = intent.getStringExtra(BundleConstants.KEY_PROJECT_ID) +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/projectedit/ProjectCreateEditLevelFragment.kt b/app/src/main/java/com/bingce/controlnetwork/newui/projectedit/ProjectCreateEditLevelFragment.kt new file mode 100644 index 0000000..2912f01 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/projectedit/ProjectCreateEditLevelFragment.kt @@ -0,0 +1,298 @@ +package com.bingce.controlnetwork.newui.projectedit + +import android.text.TextUtils +import android.view.LayoutInflater +import android.view.ViewGroup +import android.widget.EditText +import androidx.annotation.WorkerThread +import androidx.fragment.app.activityViewModels +import androidx.lifecycle.lifecycleScope +import blankj.utilcode.util.ToastUtils +import com.bingce.controlnetwork.func.level.constant.LevelConstant + +import com.bingce.controlapphelper.datasource.database.ProjectTypeValue +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory +import com.bingce.controlapphelper.datasource.database.config.ConfigOperate +import com.bingce.controlapphelper.datasource.database.project.ProjectRecord +import com.bingce.controlapphelper.datasource.database.tolerance.detail.IToleranceDetail +import com.bingce.controlapphelper.datasource.database.tolerance.load.IToleranceOperate +import com.bingce.controlapphelper.datasource.database.tolerance.load.ToleranceLoadUtil +import com.bingce.controlapphelper.util.CheckLocationUtil +import com.bingce.controlapphelper.util.GetLocationUtil +import com.bingce.controlapphelper.util.ToleranceUtil.completedToleranceName +import com.bingce.controlnetwork.R +import com.bingce.controlnetwork.databinding.NewFragmentProjectCreateEditLevelBinding +import com.bingce.controlnetwork.fragment.ToleranceSelectFragment +import com.bingce.controlnetwork.newui.base.BaseFragmentBinding +import com.bingce.controlnetwork.util.tolerance.ToleranceOperateUtil.getOperate +import com.bingce.utils.DateUtils +import com.bingce.utils.ThreadPoolUtil +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import java.util.Date + +/** + * 新建编辑项目-水准 + */ +class ProjectCreateEditLevelFragment : + BaseFragmentBinding(), IProjectCreateEditOperate { + + private val projectCreateEditVm by activityViewModels() + + private var toleranceId: String? = null //回显,选择 + + private val getLocation by lazy { + GetLocationUtil() + } + + + private val activityResultLauncher = ToleranceSelectFragment + .createActivityLauncher( + this + ) { id: String -> + this.dealSelectTolerance(id) + } + + + override fun getViewBinding( + inflater: LayoutInflater, + container: ViewGroup? + ): NewFragmentProjectCreateEditLevelBinding { + return NewFragmentProjectCreateEditLevelBinding.inflate(inflater, container, false) + } + + override fun initView() { + lifecycle.addObserver(getLocation) + initListener() + } + + private fun initListener() { + mBinding.llSelectTolerance.setOnClickListener { + //选择限差方案 + ToleranceSelectFragment.start( + context, + toleranceId, + ProjectTypeValue.LEVEL, + activityResultLauncher + ) + } + mBinding.ivGetLocation.setOnClickListener { + getLocation { + setLocation(mBinding.etLongitude, mBinding.etLatitude, it) + } + } + } + + override fun initData() { + if (projectCreateEditVm.isEdit()) { + setAlreadyData() + } else { + mBinding.etProjectName.setText(DateUtils.ymdWithCharacter(Date())) + initCreateMeasureUnitData() + setDefaultLocation() + val iToleranceDetail = getIToleranceDetail(null) + updateTolerance(iToleranceDetail) + } + } + + private fun initCreateMeasureUnitData() { + lifecycleScope.launch(Dispatchers.IO) { + val measureUnit = ProjectLastData.getMeasureUnit() + withContext(Dispatchers.Main) { + mBinding.etMeasurementUnit.setText(measureUnit) + } + } + } + + private fun setAlreadyData() { + ThreadPoolUtil.execute { + val projectRecord = SurveyorDatabaseFactory.instance + .getProjectDataSource() + .getRecord(projectCreateEditVm.projectId) ?: return@execute + //设置项目名称 + mBinding.etProjectName.setText(projectRecord.getProjectName()) + //设置测量单位 + mBinding.etMeasurementUnit.setText(projectRecord.getMeasureUnit()) + //经纬度 + if (isEmpty(projectRecord.longitude) || isEmpty(projectRecord.latitude)) { + setDefaultLocation() + } else { + setLocation( + mBinding.etLongitude, + mBinding.etLatitude, + projectRecord.longitude, + projectRecord.latitude + ) + } + + //更新限差 + val iToleranceDetail = getIToleranceDetail(projectRecord.toleranceId) + updateTolerance(iToleranceDetail) + } + } + + private fun getIToleranceDetail(toleranceId: String?) = if (toleranceId != null) { + //编辑情况 + getOperate(toleranceId)?.getIToleranceDetail(toleranceId) + } else { + //新建情况走默认的限差 + ToleranceLoadUtil.getToleranceLoad(ProjectTypeValue.LEVEL) + .getNewDefaultTolerance(ProjectTypeValue.LEVEL) + } + + override fun save(success: () -> Unit) { + view ?: return + //判断项目名称是否为空 + val projectName = mBinding.etProjectName.text.toString().trim() + if (TextUtils.isEmpty(projectName)) { + ToastUtils.showShort(R.string.tips_need_select_input_project_name) + return + } + //判断限差参数 + if (TextUtils.isEmpty(toleranceId)) { + ToastUtils.showShort(R.string.tips_need_select_project_tolerance) + return + } + //经度 + val longitude = mBinding.etLongitude.getText().toString().trim() + if (TextUtils.isEmpty(longitude)) { + ToastUtils.showShort(R.string.please_input_longitude) + return + } + //纬度 + val latitude = mBinding.etLatitude.getText().toString().trim() + if (TextUtils.isEmpty(latitude)) { + ToastUtils.showShort(R.string.please_input_latitude) + return + } + + val measurementUnit = mBinding.etMeasurementUnit.text.toString().trim() + + ThreadPoolUtil.execute { + if (projectCreateEditVm.isEdit()) { + val projectRecord = + SurveyorDatabaseFactory.instance + .getProjectDataSource() + .getRecord(projectCreateEditVm.projectId) + projectRecord.setProjectName(projectName) + projectRecord.setToleranceId(toleranceId) + projectRecord.measureUnit = measurementUnit + projectRecord.longitude = longitude + projectRecord.latitude = latitude + //存储 + SurveyorDatabaseFactory.instance + .getProjectDataSource() + .saveRecordSync(projectRecord) + } else { + val projectRecord = ProjectRecord(projectName) + projectRecord.measureUnit = measurementUnit + projectRecord.setToleranceId(toleranceId) + projectRecord.projectType = ProjectTypeValue.LEVEL + projectRecord.isShowSlopDistance = true + projectRecord.longitude = longitude + projectRecord.latitude = latitude + //存储 + SurveyorDatabaseFactory.instance + .getProjectDataSource() + .saveRecordSync(projectRecord) + + ConfigOperate.changeDefaultProjectAndCycle(projectRecord.getId(), "") + + ProjectLastData.setMeasureUnit(measurementUnit) + //经纬度 + ProjectLastData.setLongitude(longitude) + ProjectLastData.setLatitude(latitude) + } + } + + success() + } + + /** + * 处理选择返回的限差id + * + * @param id + */ + private fun dealSelectTolerance(id: String) { + ThreadPoolUtil.execute { + val operate: IToleranceOperate = getOperate(id) + ?: return@execute + val toleranceDetail: IToleranceDetail? = operate.getIToleranceDetail(id) + //存限差数据 + operate.saveToleranceDetail(toleranceDetail) + val view: android.view.View? = view + if (view != null) { + updateTolerance(toleranceDetail) + } + } + } + + @WorkerThread + private fun updateTolerance(iToleranceDetail: IToleranceDetail?) { + if (iToleranceDetail == null) { + return + } + toleranceId = iToleranceDetail.getId() + val operate = getOperate(toleranceId) ?: return + val group = operate.getGroup(iToleranceDetail) + val level = operate.getLevel(iToleranceDetail) + runOnUI { + val toleranceShowName = + completedToleranceName(group, level, iToleranceDetail) + mBinding.btnSelectTolerance.text = toleranceShowName + } + } + + private fun getLocation(resultListener: GetLocationUtil.IResultListener) { + CheckLocationUtil.check(requireContext()) { + getLocation.getResult(resultListener) + } + } + + private fun setLocation( + etLongitude: EditText, + etLatitude: EditText, + result: GetLocationUtil.Result? + ) { + setLocation(etLongitude, etLatitude, result?.longitude, result?.latitude) + } + + private fun setLocation( + etLongitude: EditText, + etLatitude: EditText, + longitude: String?, + latitude: String? + ) { + etLongitude.setText(longitude) + etLatitude.setText(latitude) + } + + private fun setDefaultLocation() { + lifecycleScope.launch(Dispatchers.IO) { + val longitude = ProjectLastData.getLongitude() + val latitude = ProjectLastData.getLatitude() + withContext(Dispatchers.Main) { + if (isEmpty(longitude) || isEmpty(latitude)) { + setLocation( + mBinding.etLongitude, + mBinding.etLatitude, + LevelConstant.LONGITUDE_DEFAULT.toString(), + LevelConstant.LATITUDE_DEFAULT.toString() + ) + } else { + setLocation( + mBinding.etLongitude, + mBinding.etLatitude, + longitude, + latitude + ) + } + } + } + + } + + private fun isEmpty(value: String?) = TextUtils.isEmpty(value) + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/projectedit/ProjectCreateEditViewModel.kt b/app/src/main/java/com/bingce/controlnetwork/newui/projectedit/ProjectCreateEditViewModel.kt new file mode 100644 index 0000000..1b72c07 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/projectedit/ProjectCreateEditViewModel.kt @@ -0,0 +1,9 @@ +package com.bingce.controlnetwork.newui.projectedit + +import androidx.lifecycle.ViewModel + +class ProjectCreateEditViewModel : ViewModel() { + var projectId: String? = null + var projectType: String? = null + fun isEdit() = projectId != null +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/projectedit/ProjectLastData.kt b/app/src/main/java/com/bingce/controlnetwork/newui/projectedit/ProjectLastData.kt new file mode 100644 index 0000000..c8e7af5 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/projectedit/ProjectLastData.kt @@ -0,0 +1,65 @@ +package com.bingce.controlnetwork.newui.projectedit + +import androidx.annotation.WorkerThread +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory +import com.bingce.controlapphelper.datasource.database.config.ConfigConstants + + +/** + * 创建项目的保存的上次值 + */ +object ProjectLastData { + + /** + * 测量单位 + */ + @WorkerThread + fun getMeasureUnit(): String? { + val measureUnitRecord = + SurveyorDatabaseFactory.instance.getConfigDataSource() + .getByKeySync(ConfigConstants.KEY_LAST_MEASURE_UNIT) + return measureUnitRecord?.getConfigValue() + } + + @WorkerThread + fun setMeasureUnit(measureUnit: String?) { + SurveyorDatabaseFactory.instance.getConfigDataSource() + .setSync(ConfigConstants.KEY_LAST_MEASURE_UNIT, measureUnit) + } + + /** + * 经度 + */ + @WorkerThread + fun getLongitude(): String? { + val measureUnitRecord = + SurveyorDatabaseFactory.instance.getConfigDataSource() + .getByKeySync(ConfigConstants.KEY_LAST_LONGITUDE) + return measureUnitRecord?.getConfigValue() + } + + @WorkerThread + fun setLongitude(longitude: String?) { + SurveyorDatabaseFactory.instance.getConfigDataSource() + .setSync(ConfigConstants.KEY_LAST_LONGITUDE, longitude) + } + + /** + * 纬度 + */ + @WorkerThread + fun getLatitude(): String? { + val measureUnitRecord = + SurveyorDatabaseFactory.instance.getConfigDataSource() + .getByKeySync(ConfigConstants.KEY_LAST_LATITUDE) + return measureUnitRecord?.getConfigValue() + } + + @WorkerThread + fun setLatitude(latitude: String?) { + SurveyorDatabaseFactory.instance.getConfigDataSource() + .setSync(ConfigConstants.KEY_LAST_LATITUDE, latitude) + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/stationlist/StationListFragment.kt b/app/src/main/java/com/bingce/controlnetwork/newui/stationlist/StationListFragment.kt new file mode 100644 index 0000000..c938732 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/stationlist/StationListFragment.kt @@ -0,0 +1,190 @@ +package com.bingce.controlnetwork.newui.stationlist + +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.fragment.app.viewModels +import androidx.lifecycle.LiveData + +import com.bingce.controlapphelper.datasource.database.ProjectType.Companion.isConnection +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord +import com.bingce.controlnetwork.R +import com.bingce.controlnetwork.adapter.SurveyorStationListAdapter +import com.bingce.controlnetwork.adapter.contextmenu.ContextMenuEdit +import com.bingce.controlnetwork.databinding.FragmentListLayoutBinding +import com.bingce.controlnetwork.fragment.TipsWith2OptionFragment +import com.bingce.controlnetwork.fragment.stationdetail.SingleStationDetailAndEditFragment +import com.bingce.controlnetwork.fragment.stationsurvey.StationSurveyorFragment +import com.bingce.controlnetwork.fragment.stationsurvey.angledistance.MeasureFragment +import com.bingce.controlnetwork.newui.adapter.StationListAdapter +import com.bingce.controlnetwork.newui.base.BaseFragmentBinding +import com.bingce.controlnetwork.newui.model.StationListBean +import com.bingce.controlnetwork.util.SurveyorStationUtil +import com.bingce.utils.ThreadPoolUtil + +/** + * 测站列表仅仅是列表 + */ +class StationListFragment : BaseFragmentBinding() { + + private val viewModel by viewModels(ownerProducer = { requireParentFragment() }) + + private var stationListLiveData: LiveData>? = null + + private var hasSurvey = false + + + private val adapter by lazy { + StationListAdapter(requireContext()) + } + + override fun getViewBinding( + inflater: LayoutInflater, + container: ViewGroup? + ): FragmentListLayoutBinding { + return FragmentListLayoutBinding.inflate(inflater, container, false) + } + + override fun initView() { + initAdapter() + } + + private fun initAdapter() { + mBinding.list.adapter = adapter + + if (viewModel.isCanEditDelete) { + adapter.setAdapterContextMenu(object : ContextMenuEdit() { + override fun edit(item: StationListBean) { + startEdit(item) + } + }) + } else { + //不能编辑和删除是在测量页面中 + adapter.setOnItemClickListener { + clickStationItem(it) + } + } + + } + + /** + * 点击测站 + */ + private fun clickStationItem(bean: StationListBean) { + //StationSurveyorFragment原始测量页 + if (isConnection(bean.projectType)) { + MeasureFragment.start(context, bean.stationId, bean.stationName) + } else { + StationSurveyorFragment.start(context, bean.stationId, bean.stationName) + } + } + + private fun startEdit(item: StationListBean) { + if (SurveyorStationRecord.isLineWell(item.lineType)) { + TipsWith2OptionFragment.tips( + childFragmentManager, viewLifecycleOwner, + getString(R.string.button_edit_station), + getString(R.string.button_delete_station), + getString(R.string.tips_select_default_station_operator_well), + object : TipsWith2OptionFragment.SimpleCallback() { + override fun onConfirm() { + SurveyorStationUtil.editLine(context, item.lineId) + } + + override fun onCancel() { + SurveyorStationListAdapter.try2DeleteLine( + item.lineId, + context, + childFragmentManager, + viewLifecycleOwner, + this@StationListFragment + ) + } + }) + return + } + + //检测是否属于导线测量 + if (SurveyorStationRecord.isLineStation(item.lineId)) { + TipsWith2OptionFragment.tips( + childFragmentManager, viewLifecycleOwner, + getString(R.string.button_edit_line), + getString(R.string.button_delete_line), + getString(R.string.tips_forbid_delete_station_because_batch), + object : TipsWith2OptionFragment.SimpleCallback() { + override fun onConfirm() { + SurveyorStationListAdapter.try2EditLine( + item.lineId, + context, + childFragmentManager, + viewLifecycleOwner, + this@StationListFragment + ) + } + + override fun onCancel() { + SurveyorStationListAdapter.try2DeleteLine( + item.lineId, + context, + childFragmentManager, + viewLifecycleOwner, + this@StationListFragment + ) + } + }) + } else { + TipsWith2OptionFragment.tips( + childFragmentManager, viewLifecycleOwner, + getString(R.string.button_edit_station), + getString(R.string.button_delete_station), + getString(R.string.tips_select_default_station_operator), + object : TipsWith2OptionFragment.SimpleCallback() { + override fun onConfirm() { + ThreadPoolUtil.execute { + SingleStationDetailAndEditFragment.start( + context, + item.stationId, + item.stationName, + viewModel.projectId, + item.lineType + ) + } + } + + override fun onCancel() { + SurveyorStationListAdapter.try2DeleteStation( + item.stationId, + context, + childFragmentManager, + viewLifecycleOwner, + this@StationListFragment + ) + } + }) + } + } + + override fun initData() { + refreshUi() + } + + fun refreshUi() { + if (stationListLiveData != null) { + stationListLiveData!!.removeObservers(this) + } + stationListLiveData = SurveyorDatabaseFactory.instance.surveyorStation.getLiveDataList( + viewModel.projectId, + viewModel.periodId + ) + if (stationListLiveData != null) { + stationListLiveData!!.observe(this) { + viewModel.getStationListData(it) { stationList -> + hasSurvey = stationList.isNotEmpty() + adapter.refreshData(stationList) + } + } + } + } + + fun hasSurvey() = hasSurvey +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/stationlist/StationListVm.kt b/app/src/main/java/com/bingce/controlnetwork/newui/stationlist/StationListVm.kt new file mode 100644 index 0000000..a095fae --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/stationlist/StationListVm.kt @@ -0,0 +1,102 @@ +package com.bingce.controlnetwork.newui.stationlist + +import android.text.TextUtils +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory +import com.bingce.controlapphelper.datasource.database.line.LineRecord +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord +import com.bingce.controlapphelper.datasource.database.surveyorstation.model.SurveyorPoint +import com.bingce.controlapphelper.util.StationUtil +import com.bingce.controlnetwork.newui.model.StationListBean +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + +class StationListVm : ViewModel() { + + var isCanEditDelete = false + + var projectId: String? = null + var periodId: String? = null + + fun getStationListData( + stationList: List, + callBack: (List) -> Unit + ) { + viewModelScope.launch(Dispatchers.IO) { + + val showList = mutableListOf() + for (station in stationList) { + val stationName = StationUtil.getStationPointName(station) + + var lineName = "" + var lineTypeShow = "多测回测角" + var lineType: String? = null + station.lineId?.let { + val lineRecord = SurveyorDatabaseFactory + .instance + .lineRecordDatabase + .findById(station.lineId) + if (lineRecord != null) { + lineName = lineRecord.name ?: "" + lineTypeShow = LineRecord.lineTypeToName(lineRecord.type) + lineType = lineRecord.type + } + } + + val stationTypeSb = StringBuilder() + + stationTypeSb.append(lineTypeShow) + if (!TextUtils.isEmpty(lineName)) { + stationTypeSb.append("-") + stationTypeSb.append(lineName) + } + + val pointOrder = StringBuilder() + for (point in station.items) { + //排除站点 + if (point.type == SurveyorPoint.TYPE_STATION) { + continue + } + val pointRecord = + SurveyorDatabaseFactory.instance.pointDataSource.findByIdSync(point.originalPointId) + + pointOrder.append(pointRecord?.getName()) + pointOrder.append("-") + } + + if (pointOrder.isNotEmpty()) { + pointOrder.deleteCharAt(pointOrder.length - 1) + } + + val stationListBean = + StationListBean( + station.projectType, + station.id, + stationName ?: "", + stationTypeSb.toString(), + pointOrder.toString(), + lineType, + station.lineId + ) + + showList.add(stationListBean) + + } + + withContext(Dispatchers.Main) { + callBack(showList) + } + + } + + } + + fun setArgument(projectId: String?, periodId: String?) { + this.projectId = projectId + this.periodId = periodId + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/stationsetting/IStationSettingOperate.kt b/app/src/main/java/com/bingce/controlnetwork/newui/stationsetting/IStationSettingOperate.kt new file mode 100644 index 0000000..2372f0d --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/stationsetting/IStationSettingOperate.kt @@ -0,0 +1,6 @@ +package com.bingce.controlnetwork.newui.stationsetting + +interface IStationSettingOperate { + fun checkSaveNot(): Boolean + fun setDataToStation() +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/stationsetting/StationSettingEnvironmentFragment.kt b/app/src/main/java/com/bingce/controlnetwork/newui/stationsetting/StationSettingEnvironmentFragment.kt new file mode 100644 index 0000000..beb3ca4 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/stationsetting/StationSettingEnvironmentFragment.kt @@ -0,0 +1,99 @@ +package com.bingce.controlnetwork.newui.stationsetting + +import android.text.TextUtils +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.fragment.app.activityViewModels +import blankj.utilcode.util.ToastUtils +import com.bingce.controlnetwork.R +import com.bingce.controlnetwork.databinding.NewFragmentStationSettingEnvironmentBinding +import com.bingce.controlnetwork.newui.base.BaseFragmentBinding + +/** + * 测站设置-环境信息 + */ +class StationSettingEnvironmentFragment : + BaseFragmentBinding(), IStationSettingOperate { + + private val viewModel by activityViewModels() + + override fun getViewBinding( + inflater: LayoutInflater, + container: ViewGroup? + ): NewFragmentStationSettingEnvironmentBinding { + return NewFragmentStationSettingEnvironmentBinding.inflate(inflater, container, false) + } + + override fun initView() { + mBinding.ilTemperature.tvTitle.text = "温度(℃)" + mBinding.ilHumidity.tvTitle.text = "湿度(%)" + mBinding.ilAirPressure.tvTitle.text = "气压(hPa)" + + initListener() + } + + private fun initListener() { + mBinding.tvLastData.setOnClickListener { + useLastData() + } + mBinding.tvStandardData.setOnClickListener { + useStandardData() + } + } + + private fun useLastData() { + viewModel.getLastEnvironmentData { + setEnvironmentData() + } + } + + private fun useStandardData() { + viewModel.getDefaultEnvironmentData() + setEnvironmentData() + } + + private fun setEnvironmentData() { + mBinding.ilTemperature.editText.setText(viewModel.environmentData.temperature) + mBinding.ilHumidity.editText.setText(viewModel.environmentData.humidity) + mBinding.ilAirPressure.editText.setText(viewModel.environmentData.airPress) + } + + + override fun initData() { + viewModel.getEnvironmentData { + setEnvironmentData() + } + } + + override fun checkSaveNot(): Boolean { + val temperature = mBinding.ilTemperature.editText.text + if (TextUtils.isEmpty(temperature)) { + ToastUtils.showShort(R.string.temperature_hint) + return true + } + val humidity = mBinding.ilHumidity.editText.text + if (TextUtils.isEmpty(humidity)) { + ToastUtils.showShort(R.string.humidity_hint) + return true + } + val airPressure = mBinding.ilAirPressure.editText.text + if (TextUtils.isEmpty(airPressure)) { + ToastUtils.showShort(R.string.air_pressure_hint) + return true + } + return false + } + + private fun getTemperature() = mBinding.ilTemperature.editText.text.toString().trim() + private fun getHumidity() = mBinding.ilHumidity.editText.text.toString().trim() + private fun getAirPressure() = mBinding.ilAirPressure.editText.text.toString().trim() + + override fun setDataToStation() { + viewModel.setEnvironmentDataToStation( + getTemperature(), + getHumidity(), + getAirPressure() + ) + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/stationsetting/StationSettingHeightFragment.kt b/app/src/main/java/com/bingce/controlnetwork/newui/stationsetting/StationSettingHeightFragment.kt new file mode 100644 index 0000000..6583bbf --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/stationsetting/StationSettingHeightFragment.kt @@ -0,0 +1,108 @@ +package com.bingce.controlnetwork.newui.stationsetting + +import android.text.TextUtils +import android.view.LayoutInflater +import android.view.ViewGroup +import android.view.ViewGroup.MarginLayoutParams +import android.widget.EditText +import android.widget.TextView +import androidx.fragment.app.activityViewModels +import blankj.utilcode.util.ToastUtils +import com.bingce.controlnetwork.R +import com.bingce.controlnetwork.databinding.NewFragmentStationSettingHeightBinding +import com.bingce.controlnetwork.newui.base.BaseFragmentBinding + +import com.bingce.utils.ScreenUtil + +/** + * 测站设置-仪高镜高 + */ +class StationSettingHeightFragment : BaseFragmentBinding(), + IStationSettingOperate { + + private val viewModel by activityViewModels() + + + override fun getViewBinding( + inflater: LayoutInflater, + container: ViewGroup? + ): NewFragmentStationSettingHeightBinding { + return NewFragmentStationSettingHeightBinding.inflate(inflater, container, false) + } + + override fun initView() { + mBinding.ilInstrumentHeight.tvTitle.text = "仪器高(m)" + } + + override fun initData() { + //获取点 加载布局 + viewModel.getStationRecord { + //设置仪器高 + mBinding.ilInstrumentHeight.editText.setText(viewModel.heightData.getInstrumentHeight()) + + for (point in viewModel.heightData.pointList) { + val itemView = + layoutInflater.inflate(R.layout.new_item_station_setting_point_height, null) + val params = MarginLayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ScreenUtil.dp2px(requireContext(), 48f) + ) + + val tvPoint = itemView.findViewById(R.id.tvPoint) + val etHeight = itemView.findViewById(R.id.etHeight) + + setItemEtData( + tvPoint, etHeight, + viewModel.heightData.getPointName(point.originalPointId), + viewModel.heightData.getPointHeight(point.originalPointId) + ) + + mBinding.llPoints.addView(itemView, params) + } + } + } + + private fun setItemEtData( + tvPoint: TextView, + etHeight: EditText, + pointName: String?, + pointHeight: String + ) { + tvPoint.text = pointName + etHeight.setText(pointHeight) + } + + + override fun checkSaveNot(): Boolean { + val instrumentHeight = getInstrumentHeight() + if (TextUtils.isEmpty(instrumentHeight)) { + ToastUtils.showShort(R.string.instrument_height_hint) + return true + } + for (i in 0 until mBinding.llPoints.childCount) { + val itemView = mBinding.llPoints.getChildAt(i) + val pointHeight = itemView.findViewById(R.id.etHeight).text.toString().trim() + val pointName = itemView.findViewById(R.id.tvPoint).text.toString().trim() + if (TextUtils.isEmpty(pointHeight)) { + ToastUtils.showShort("请输入测点" + pointName + "高度") + return true + } + } + return false + } + + private fun getInstrumentHeight() = mBinding.ilInstrumentHeight.editText.text.toString().trim() + + override fun setDataToStation() { + viewModel.setStationHeightToStation(getInstrumentHeight()) + for (i in 0 until mBinding.llPoints.childCount) { + val itemView = mBinding.llPoints.getChildAt(i) + val etPointHeight = itemView.findViewById(R.id.etHeight) + val pointHeight = etPointHeight.text.toString().trim() + + viewModel.setPointDataToStation(i, pointHeight) + } + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/stationsetting/StationSettingSettingFragment.kt b/app/src/main/java/com/bingce/controlnetwork/newui/stationsetting/StationSettingSettingFragment.kt new file mode 100644 index 0000000..51155b1 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/stationsetting/StationSettingSettingFragment.kt @@ -0,0 +1,190 @@ +package com.bingce.controlnetwork.newui.stationsetting + +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.AdapterView +import android.widget.ArrayAdapter +import android.widget.Spinner +import android.widget.TextView +import androidx.appcompat.widget.SwitchCompat +import androidx.fragment.app.activityViewModels +import com.bingce.controlapphelper.datasource.database.prism.PrismRecord +import com.bingce.controlapphelper.datasource.database.surveyorstation.model.SurveyorPoint +import com.bingce.controlapphelper.util.StationUtil +import com.bingce.controlnetwork.R +import com.bingce.controlnetwork.databinding.NewFragmentStationSettingSettingBinding +import com.bingce.controlnetwork.newui.base.BaseFragmentBinding +import com.bingce.controlnetwork.util.SurveyorOpenAtrUtil +import com.bingce.utils.ScreenUtil + +/** + * 测站设置-测站设置 + */ +class StationSettingSettingFragment : + BaseFragmentBinding(), IStationSettingOperate { + + private val viewModel by activityViewModels() + + private var isCanSetAloneDistance = false + + override fun getViewBinding( + inflater: LayoutInflater, + container: ViewGroup? + ): NewFragmentStationSettingSettingBinding { + return NewFragmentStationSettingSettingBinding.inflate(inflater, container, false) + } + + override fun initView() { + + } + + override fun initData() { + viewModel.getStationRecord { + val pointSize = viewModel.getStationSurveyorPointSize() - 1 + if (StationUtil.isCanLeftOrRightSurveyor(pointSize)) { + mBinding.scLeftRight.visibility = View.VISIBLE + } else { + mBinding.scLeftRight.visibility = View.GONE + } + if (StationUtil.isCanZeroSurveyor(pointSize)) { + mBinding.scZero.visibility = View.VISIBLE + } else { + mBinding.scZero.visibility = View.GONE + } + mBinding.scLeftRight.isChecked = viewModel.getStationLeftRight() + mBinding.scZero.isChecked = viewModel.getStationZero() + //显示斜距还是平距 + mBinding.showSlopSwitch.isChecked = viewModel.getShowSlop() + + setDisEnableByHasData(mBinding.scLeftRight, mBinding.scZero) + + isCanSetAloneDistance = viewModel.isCanShowAloneDistance() + + refreshEveryPointUi() + } + } + + private fun refreshEveryPointUi() { + mBinding.llPoints.removeAllViews() + for (point in viewModel.settingData.pointList) { + val itemView = + layoutInflater.inflate(R.layout.new_item_station_setting_point_setting, null) + val params = ViewGroup.MarginLayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.WRAP_CONTENT + ) + + val tvPoint = itemView.findViewById(R.id.tvPoint) + val scAloneMeasureDistance = + itemView.findViewById(R.id.scAloneMeasureDistance) + val scOpenAtr = itemView.findViewById(R.id.scOpenAtr) + val spinnerPrismType = itemView.findViewById(R.id.spinnerPrismType) + + if (isCanSetAloneDistance) { + scAloneMeasureDistance.visibility=View.VISIBLE + }else{ + scAloneMeasureDistance.visibility=View.GONE + } + + + tvPoint.text = viewModel.settingData.getPointName(point.originalPointId) + //单独测距 + scAloneMeasureDistance.isChecked = point.isAloneDistance + + setDisEnableByHasData(scAloneMeasureDistance) + + setItemSpinnerData(spinnerPrismType, scOpenAtr, point) + + params.topMargin = ScreenUtil.dp2px(requireContext(), 12f) + mBinding.llPoints.addView(itemView, params) + } + } + + override fun checkSaveNot(): Boolean { + return false + } + + private fun setItemSpinnerData( + spinner: Spinner, + scOpenAtr: SwitchCompat, + point: SurveyorPoint + ) { + spinner.adapter = ArrayAdapter( + requireContext(), + android.R.layout.simple_list_item_1, + viewModel.settingData.getAllPrismNameList() + ) + spinner.setSelection(viewModel.settingData.getPointPrismSelection(point.originalPointId)) + spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { + override fun onItemSelected( + parent: AdapterView<*>?, + view: View?, + position: Int, + id: Long + ) { + val prismRecord = viewModel.settingData.getPrismRecord(position) + setItemOpenAtr(scOpenAtr, prismRecord, point) + } + + override fun onNothingSelected(parent: AdapterView<*>?) { + } + + } + } + + private fun setItemOpenAtr( + scOpenAtr: SwitchCompat, + selectPrismRecord: PrismRecord, + point: SurveyorPoint + ) { + val openAtrEnable = SurveyorOpenAtrUtil.isOpenAtr( + selectPrismRecord.prismType, + selectPrismRecord.prismTypeLarge + ) + val openAtrSurveyorPoint = SurveyorOpenAtrUtil.isOpenAtr(point) + val openAtr = openAtrEnable && openAtrSurveyorPoint + scOpenAtr.isChecked = openAtr + scOpenAtr.isEnabled = openAtrEnable + } + + override fun setDataToStation() { + if (mBinding.scLeftRight.visibility == View.VISIBLE) { + viewModel.setStationLeftRightToStation(mBinding.scLeftRight.isChecked) + } + if (mBinding.scZero.visibility == View.VISIBLE) { + viewModel.setStationZeroToStation(mBinding.scZero.isChecked) + } + //显示斜距还是平距 + viewModel.setStationShowSlop(mBinding.showSlopSwitch.isChecked) + + //更新测点 + for (i in 0 until mBinding.llPoints.childCount) { + val itemView = mBinding.llPoints.getChildAt(i) + val scAloneMeasureDistance = + itemView.findViewById(R.id.scAloneMeasureDistance) + val spinnerPrismType = itemView.findViewById(R.id.spinnerPrismType) + val scOpenAtr = itemView.findViewById(R.id.scOpenAtr) + + viewModel.setPointSettingToStation( + i, + scAloneMeasureDistance.isChecked, + spinnerPrismType.selectedItemPosition, + !scOpenAtr.isChecked + ) + } + + //更新测站的单独测距状态 +// viewModel.updateSeparetionToStation() + + } + + private fun setDisEnableByHasData(vararg ets: View) { + if (viewModel.hasSurveyorData) { + for (item in ets) { + item.isEnabled = false + } + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/stationsetting/StationSettingVm.kt b/app/src/main/java/com/bingce/controlnetwork/newui/stationsetting/StationSettingVm.kt new file mode 100644 index 0000000..4a2e1fc --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/stationsetting/StationSettingVm.kt @@ -0,0 +1,228 @@ +package com.bingce.controlnetwork.newui.stationsetting + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import blankj.utilcode.util.ToastUtils +import com.bingce.controlapphelper.datasource.database.ProjectType +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory +import com.bingce.controlapphelper.datasource.database.config.ConfigConstants +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord +import com.bingce.controlapphelper.util.StationUtil +import com.bingce.controlnetwork.newui.stationsetting.model.StationSettingEnvironmentData +import com.bingce.controlnetwork.newui.stationsetting.model.StationSettingHeightData +import com.bingce.controlnetwork.newui.stationsetting.model.StationSettingSettingData +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + +class StationSettingVm : ViewModel() { + + val environmentData = StationSettingEnvironmentData() + val heightData = StationSettingHeightData() + val settingData = StationSettingSettingData() + + private lateinit var stationId: String + var stationRecord: SurveyorStationRecord? = null + + //默认有测量数据 + var hasSurveyorData = true + + + fun getLastEnvironmentData(callBack: () -> Unit) { + viewModelScope.launch { + withContext(Dispatchers.IO) { + environmentData.getLastData() + } + if (isHasNotEnvironmentData()) { + ToastUtils.showShort("没有上次数据") + return@launch + } + callBack() + } + } + + /** + * 获取默认的环境数据 + */ + fun getDefaultEnvironmentData() { + environmentData.getStandardData() + } + + fun getEnvironmentData(callBack: () -> Unit) { + viewModelScope.launch { + withContext(Dispatchers.IO) { + environmentData.getLastData() + } + if (isHasNotEnvironmentData()) { + getDefaultEnvironmentData() + } + callBack() + } + } + + //没有环境数据(只判断温度就够了) + private fun isHasNotEnvironmentData() = environmentData.temperature == null + + + fun initStationId(stationId: String, callBack: () -> Unit) { + this.stationId = stationId + viewModelScope.launch(Dispatchers.IO) { + hasSurveyorData = StationUtil.hasSurveyorData(stationId) + withContext(Dispatchers.Main) { + callBack() + } + } + } + + /** + * 获取测站相关数据的入口 + */ + fun getStationRecord(callBack: () -> Unit) { + if (stationRecord != null) { + callBack() + return + } + synchronized(this) { + viewModelScope.launch(Dispatchers.IO) { + if (stationRecord == null) { + stationRecord = SurveyorDatabaseFactory.instance.getSurveyorStation() + .getRecordSync(stationId) + //初始化高度信息 + heightData.initData(stationRecord) + //初始化测站设置信息 + settingData.initData(stationRecord) + } + + if (stationRecord != null) { + withContext(Dispatchers.Main) { + callBack() + } + } + } + } + } + + fun setEnvironmentDataToStation( + temperature: String, + humidity: String, + airPressure: String, + ) { + stationRecord?.let { + it.temperature = temperature + it.humidity = humidity + it.airPressure = airPressure + } + } + + fun setPointDataToStation(pointIndex: Int, pointHeight: String) { + stationRecord?.let { + heightData.updatePointData(pointIndex, pointHeight) + } + } + + /** + * 更新测点的状态 + * 当有一个点是单独测距这个测站就是单独测距 + */ + fun setPointSettingToStation( + pointIndex: Int, + aloneMeasureDistance: Boolean, + selectionPrismType: Int, + isOpenAtrNot: Boolean + ) { + stationRecord?.let { + settingData.updatePointSettingData( + pointIndex, + aloneMeasureDistance, + selectionPrismType, + isOpenAtrNot + ) + } + } + + fun setStationHeightToStation(instrumentHeight: String) { + stationRecord?.let { + it.instrumentHeight = instrumentHeight + } + } + + fun setStationLeftRightToStation(leftRight: Boolean) { + stationRecord?.let { + it.isLeftAndRightSurveyor = leftRight + } + } + + fun getStationLeftRight() = stationRecord?.leftAndRightSurveyor ?: false + fun getShowSlop() = stationRecord?.showSlopDistance ?: true + fun setStationShowSlop(showSlopDistance: Boolean) { + stationRecord?.let { + it.showSlopDistance = showSlopDistance + } + } + + fun setStationZeroToStation(zero: Boolean) { + stationRecord?.let { + it.autoClose = zero + } + } + + fun getStationZero() = stationRecord?.autoClose ?: false + + fun getStationSurveyorPointSize() = stationRecord?.items?.size ?: 0 + + /** + * 存储数据库 + */ + fun saveToDataBase(callBack: () -> Unit) { + if (stationRecord == null) return + viewModelScope.launch { + withContext(Dispatchers.IO) { + saveLastConfigData() + SurveyorDatabaseFactory.instance.surveyorStation.update(stationRecord) + } + callBack() + } + } + + private fun saveLastConfigData() { + val configDataSource = SurveyorDatabaseFactory.instance.getConfigDataSource() + //环境信息 + configDataSource.setSync( + ConfigConstants.KEY_LAST_TEMPERATURE, + stationRecord!!.getTemperature() + ) + configDataSource.setSync( + ConfigConstants.KEY_LAST_AIR_PRESSURE, + stationRecord!!.getAirPressure() + ) + configDataSource.setSync( + ConfigConstants.KEY_LAST_HUMIDITY, + stationRecord!!.getHumidity() + ) + } + + fun isCanShowAloneDistance(): Boolean { + if (stationRecord == null) { + return false + } + return ProjectType.isConnection(stationRecord!!.projectType) + } + +// /** +// * 当测点的状态更新完再调用这个方法 +// */ +// fun updateSeparetionToStation() { +// stationRecord?.let { +// var aloneDistance = false +// for (item in it.items) { +// if (item.isAloneDistance) { +// aloneDistance = true +// break +// } +// } +// it.aloneMeasureDistance = aloneDistance +// } +// } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/stationsetting/StationSettingsActivity.kt b/app/src/main/java/com/bingce/controlnetwork/newui/stationsetting/StationSettingsActivity.kt new file mode 100644 index 0000000..9f1166a --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/stationsetting/StationSettingsActivity.kt @@ -0,0 +1,151 @@ +package com.bingce.controlnetwork.newui.stationsetting + +import android.content.Context +import android.content.Intent +import android.view.Menu +import android.view.MenuItem +import androidx.activity.viewModels +import androidx.fragment.app.Fragment +import androidx.fragment.app.FragmentManager +import androidx.fragment.app.FragmentStatePagerAdapter +import androidx.viewpager.widget.ViewPager.OnPageChangeListener +import blankj.utilcode.util.ToastUtils +import com.bingce.controlapphelper.model.BundleConstants +import com.bingce.controlapphelper.util.FastClickUtil +import com.bingce.controlnetwork.R +import com.bingce.controlnetwork.databinding.NewActivityStationSettingBinding +import com.bingce.controlnetwork.newui.base.BaseBindingActivity +import com.bingce.controlnetwork.util.KeyboardUtil + +class StationSettingsActivity : BaseBindingActivity() { + + private val viewModel by viewModels() + + private val fragments = mutableListOf() + private val fragmentTitleList = listOf("仪高镜高", "环境信息", "测站设置") + + companion object { + @JvmStatic + fun start(context: Context, stationId: String?) { + if (stationId == null) { + return + } + context.startActivity(Intent(context, StationSettingsActivity::class.java).apply { + putExtra(BundleConstants.KEY_SURVEYOR_STATION_ID, stationId) + }) + } + } + + override fun getBinding(): NewActivityStationSettingBinding { + return NewActivityStationSettingBinding.inflate(layoutInflater) + } + + override fun initView() { + viewModel.initStationId(getStationId()) { + initViewPager() + } + } + + override fun initData() { + + } + + private fun initViewPager() { + fragments.add(StationSettingHeightFragment()) + fragments.add(StationSettingEnvironmentFragment()) + fragments.add(StationSettingSettingFragment()) + + mBinding.vp.offscreenPageLimit = 3 + mBinding.vp.adapter = MyPagerAdapter(supportFragmentManager) + mBinding.tabLayout.setViewPager(mBinding.vp) + mBinding.vp.addOnPageChangeListener(object : OnPageChangeListener { + override fun onPageScrolled( + position: Int, + positionOffset: Float, + positionOffsetPixels: Int + ) { + } + + override fun onPageSelected(position: Int) { + + } + + override fun onPageScrollStateChanged(state: Int) { + + } + }) + +// //设置当前tab为仪高镜高 +// mBinding.vp.currentItem = 1 + } + + + private inner class MyPagerAdapter(fm: FragmentManager) : FragmentStatePagerAdapter(fm) { + override fun getCount(): Int { + return fragments.size + } + + override fun getPageTitle(position: Int): CharSequence { + return fragmentTitleList[position] + } + + override fun getItem(position: Int): Fragment { + return fragments[position] + } + + override fun getItemPosition(`object`: Any): Int { + return POSITION_NONE + } + } + + private fun getStationId(): String { + return intent.getStringExtra(BundleConstants.KEY_SURVEYOR_STATION_ID)!! + } + + override fun onCreateOptionsMenu(menu: Menu?): Boolean { + menuInflater.inflate(R.menu.menu_save, menu) + return super.onCreateOptionsMenu(menu) + } + + override fun onOptionsItemSelected(item: MenuItem): Boolean { + if (item.itemId == R.id.menuSave) { + FastClickUtil.click { + KeyboardUtil.hideSoftInput() + startSave() + } + } + return super.onOptionsItemSelected(item) + } + + private fun startSave() { + //检查未完成的选项 + for (fragment in fragments) { + val operate = fragment as IStationSettingOperate + if (operate.checkSaveNot()) { + val fragmentNotFinishPos = fragments.indexOf(fragment) + if (mBinding.vp.currentItem != fragmentNotFinishPos) { + mBinding.tabLayout.currentTab = fragmentNotFinishPos + } + return + } + } + //赋值 + for (fragment in fragments) { + val operate = fragment as IStationSettingOperate + operate.setDataToStation() + } + + viewModel.saveToDataBase { +// EventBus.getDefault().post(ReplaceSurveyorFragmentEvent()) + ToastUtils.showShort(R.string.save_success) + } + + } + + override fun onBackPressed() { + if (isFinishAtOnce()) { + super.onBackPressed() + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/stationsetting/model/StationSettingEnvironmentData.kt b/app/src/main/java/com/bingce/controlnetwork/newui/stationsetting/model/StationSettingEnvironmentData.kt new file mode 100644 index 0000000..b2839f5 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/stationsetting/model/StationSettingEnvironmentData.kt @@ -0,0 +1,38 @@ +package com.bingce.controlnetwork.newui.stationsetting.model + +import androidx.annotation.WorkerThread +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory +import com.bingce.controlapphelper.datasource.database.config.ConfigConstants +import com.bingce.controlapphelper.surveyor.method.model.MeasureConstant + +class StationSettingEnvironmentData { + var temperature: String? = null + var humidity: String? = null + var airPress: String? = null + + + /** + * 获取上次数据 + */ + @WorkerThread + fun getLastData() { + val configDataSource = SurveyorDatabaseFactory.instance.getConfigDataSource() + val temperature = configDataSource.getByKeySync(ConfigConstants.KEY_LAST_TEMPERATURE) + val humidity = configDataSource.getByKeySync(ConfigConstants.KEY_LAST_HUMIDITY) + val airPress = configDataSource.getByKeySync(ConfigConstants.KEY_LAST_AIR_PRESSURE) + + this.temperature = temperature?.configValue + this.humidity = humidity?.configValue + this.airPress = airPress?.configValue + } + + /** + * 获取标准气象数据 + */ + fun getStandardData() { + this.temperature = MeasureConstant.DEFAULT_TEMPERATURE + this.humidity = MeasureConstant.DEFAULT_HUMIDITY + this.airPress = MeasureConstant.DEFAULT_AIR_PRESSURE + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/stationsetting/model/StationSettingHeightData.kt b/app/src/main/java/com/bingce/controlnetwork/newui/stationsetting/model/StationSettingHeightData.kt new file mode 100644 index 0000000..e49a96b --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/stationsetting/model/StationSettingHeightData.kt @@ -0,0 +1,58 @@ +package com.bingce.controlnetwork.newui.stationsetting.model + +import androidx.annotation.WorkerThread +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord +import com.bingce.controlapphelper.datasource.database.surveyorstation.model.SurveyorPoint + + +/** + * 高度tab相关数据 + */ +class StationSettingHeightData { + + private var instrumentHeight: String? = null + val pointList = mutableListOf() + + private val pointNameMap = hashMapOf() + private val pointHeightMap = hashMapOf() + + @WorkerThread + fun initData(stationRecord: SurveyorStationRecord?) { + if (stationRecord?.items == null) return + instrumentHeight = stationRecord.instrumentHeight + + for (point in stationRecord.items) { + if (point.type == SurveyorPoint.TYPE_STATION || point.isWellSteel) { + //忽略站点和钢丝点 + continue + } + pointList.add(point) + val pointRecord = + SurveyorDatabaseFactory.instance.getPointDataSource().findByIdSync(point.originalPointId) + pointNameMap[point.originalPointId] = pointRecord.name + pointHeightMap[point.originalPointId] = point.prismHeight + } + } + + fun getPointName(pointId: String) = pointNameMap[pointId] + fun getPointHeight(pointId: String): String { + return pointHeightMap[pointId] ?: "0" + } + + fun getInstrumentHeight(): String { + return instrumentHeight ?: "0" + } + + /** + * 保存时 + */ + fun updatePointData(pointIndex: Int, pointHeight: String) { + val surveyorPoint = pointList[pointIndex] + //点高 + surveyorPoint.prismHeight = pointHeight + } + +} + + diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/stationsetting/model/StationSettingSettingData.kt b/app/src/main/java/com/bingce/controlnetwork/newui/stationsetting/model/StationSettingSettingData.kt new file mode 100644 index 0000000..2289daa --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/stationsetting/model/StationSettingSettingData.kt @@ -0,0 +1,88 @@ +package com.bingce.controlnetwork.newui.stationsetting.model + +import androidx.annotation.WorkerThread +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory +import com.bingce.controlapphelper.datasource.database.prism.PrismRecord +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord +import com.bingce.controlapphelper.datasource.database.surveyorstation.model.SurveyorPoint + + +class StationSettingSettingData { + + val pointList = mutableListOf() + private val pointNameMap = hashMapOf() + + private val pointPrismMap = hashMapOf() + private lateinit var prismAllList: List + private val prismAllTypeNameList = mutableListOf() + + + @WorkerThread + fun initData(stationRecord: SurveyorStationRecord?) { + if (stationRecord?.items == null) return + + prismAllList = SurveyorDatabaseFactory.instance.getPrismManagerDataSource().allRecordSync + for (prism in prismAllList) { + prismAllTypeNameList.add(prism.prismTypeName) + } + + for (point in stationRecord.items) { + if (point.type == SurveyorPoint.TYPE_STATION || point.isWellSteel) { + //忽略站点 + continue + } + pointList.add(point) + val pointRecord = + SurveyorDatabaseFactory.instance.getPointDataSource() + .findByIdSync(point.originalPointId) + pointNameMap[point.originalPointId] = pointRecord.name + + pointPrismMap[point.originalPointId] = PrismRecord().apply { + prismType = point.prismType + prismTypeName = point.prismTypeName + prismTypeConstant = point.prismTypeConstant + } + } + } + + fun getPointName(pointId: String) = pointNameMap[pointId] + + fun getPointPrismSelection(pointId: String): Int { + val prismRecord = pointPrismMap[pointId] + for ((index, record) in prismAllList.withIndex()) { + if (record.prismTypeName.equals(prismRecord?.prismTypeName)) { + return index + } + } + return -1 + } + + fun getAllPrismNameList(): List { + return prismAllTypeNameList + } + + /** + * 保存时 + */ + fun updatePointSettingData( + pointIndex: Int, + aloneMeasureDistance: Boolean, + selectionPosPrismType: Int, + isOpenAtrNot: Boolean + ) { + val surveyorPoint = pointList[pointIndex] + surveyorPoint.isAloneDistance = aloneMeasureDistance + //棱镜类型相关 + val prismRecord = getPrismRecord(selectionPosPrismType) + surveyorPoint.prismType = prismRecord.prismType + surveyorPoint.prismTypeLarge = prismRecord.prismTypeLarge + surveyorPoint.prismTypeConstant = prismRecord.prismTypeConstant + surveyorPoint.prismTypeName = prismRecord.prismTypeName + //openAtr + surveyorPoint.isOpenAtrNot = isOpenAtrNot + } + + fun getPrismRecord(selectionPosPrismType: Int) = prismAllList[selectionPosPrismType] + + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/viewholder/PointListViewHolder.java b/app/src/main/java/com/bingce/controlnetwork/newui/viewholder/PointListViewHolder.java new file mode 100644 index 0000000..9e44d5e --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/viewholder/PointListViewHolder.java @@ -0,0 +1,15 @@ +package com.bingce.controlnetwork.newui.viewholder; + +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlnetwork.databinding.NewItemPointListBinding; + + +public class PointListViewHolder extends RecyclerView.ViewHolder { + public final NewItemPointListBinding mBinding; + + public PointListViewHolder(NewItemPointListBinding binding) { + super(binding.getRoot()); + mBinding = binding; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/viewholder/ProjectListViewHolder.java b/app/src/main/java/com/bingce/controlnetwork/newui/viewholder/ProjectListViewHolder.java new file mode 100644 index 0000000..f0c4b29 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/viewholder/ProjectListViewHolder.java @@ -0,0 +1,15 @@ +package com.bingce.controlnetwork.newui.viewholder; + +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlnetwork.databinding.NewItemProjectListBinding; + + +public class ProjectListViewHolder extends RecyclerView.ViewHolder { + public final NewItemProjectListBinding mBinding; + + public ProjectListViewHolder(NewItemProjectListBinding binding) { + super(binding.getRoot()); + mBinding = binding; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/viewholder/StationListViewHolder.java b/app/src/main/java/com/bingce/controlnetwork/newui/viewholder/StationListViewHolder.java new file mode 100644 index 0000000..aab5c7a --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/viewholder/StationListViewHolder.java @@ -0,0 +1,15 @@ +package com.bingce.controlnetwork.newui.viewholder; + +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlnetwork.databinding.NewItemStationListBinding; + + +public class StationListViewHolder extends RecyclerView.ViewHolder { + public final NewItemStationListBinding mBinding; + + public StationListViewHolder(NewItemStationListBinding binding) { + super(binding.getRoot()); + mBinding = binding; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/widget/selectitem/BaseSelectItemFragment.kt b/app/src/main/java/com/bingce/controlnetwork/newui/widget/selectitem/BaseSelectItemFragment.kt new file mode 100644 index 0000000..ffa39cd --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/widget/selectitem/BaseSelectItemFragment.kt @@ -0,0 +1,179 @@ +package com.bingce.controlnetwork.newui.widget.selectitem + +import android.graphics.Color +import android.graphics.drawable.ColorDrawable +import android.os.Bundle +import android.view.Gravity +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.view.ViewGroup.MarginLayoutParams +import androidx.fragment.app.DialogFragment +import androidx.fragment.app.FragmentManager +import androidx.lifecycle.LifecycleOwner +import androidx.recyclerview.widget.RecyclerView + +import com.bingce.controlapphelper.model.IUniversalListItem +import com.bingce.controlnetwork.R +import com.bingce.controlnetwork.databinding.NewFragmentBaseSelectItemBinding +import com.bingce.controlnetwork.databinding.NewItemSelectItemBinding +import com.bingce.utils.ScreenUtil + + +/** + * 类似选择项目类型的底部弹框 + */ +abstract class BaseSelectItemFragment : DialogFragment() { + + private var _binding: NewFragmentBaseSelectItemBinding? = null + private val mBinding get() = _binding!! + + private val dataList = mutableListOf>() + + + companion object { + private const val KEY_REQUEST_SELECT = "__SELECT__" + private const val KEY_TYPE = "__SELECT_TYPE__" + + @JvmStatic + fun select( + fragment: BaseSelectItemFragment, + fragmentManager: FragmentManager, + lifecycleOwner: LifecycleOwner, + callback: ISelectItem + ) { + fragmentManager + .setFragmentResultListener( + KEY_REQUEST_SELECT, + lifecycleOwner + ) { requestKey: String, result: Bundle -> + if (KEY_REQUEST_SELECT == requestKey) { + callback.onBack(result.getString(KEY_TYPE)!!) + } + } + fragment.show(fragmentManager, null) + } + } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + _binding = NewFragmentBaseSelectItemBinding.inflate(inflater, container, false) + return mBinding.root + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) +// addMargin(view) + mBinding.tvTitle.text = getTitle() + initAdapter() + initListener() + } + + private fun initListener() { + mBinding.cancel.setOnClickListener { + dismissDialog() + } + } + + private fun dismissDialog() { + dismissAllowingStateLoss() + } + + override fun onStart() { + super.onStart() + dialog?.window?.run { + setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT)) + val params = attributes + params.gravity = Gravity.BOTTOM + params.width = ScreenUtil.getScreenWidth(requireContext()) - ScreenUtil.dp2px( + requireContext(), + 24f + ) + params.y = ScreenUtil.dp2px( + requireContext(), + 12f + ) + + setWindowAnimations(R.style.BottomDialogAnimation) + //最后设置参数 + attributes = params + } + + } + + private fun addMargin(view: View) { + val layoutParams = view.layoutParams as MarginLayoutParams + val margin = ScreenUtil.dp2px(requireContext(), 16f) + layoutParams.setMargins(margin, margin, margin, margin) + view.setLayoutParams(layoutParams) + view.requestLayout() + } + + private fun initAdapter() { + dataList.addAll(getDataList()) + mBinding.recyclerView.addItemDecoration( + HorDividerDecoration(requireContext()) + ) + mBinding.recyclerView.adapter = Adapter() + } + + abstract fun getDataList(): List> + + abstract fun getTitle(): String + + + private inner class Adapter : RecyclerView.Adapter() { + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + return ViewHolder( + NewItemSelectItemBinding.inflate( + layoutInflater, + parent, + false + ) + ) + } + + override fun getItemCount(): Int { + return dataList.size + } + + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + val item = dataList[position] + holder.binding.tv.text = item.name + + holder.itemView.setOnClickListener { + backData(item.value) + } + } + + } + + private class ViewHolder(val binding: NewItemSelectItemBinding) : + RecyclerView.ViewHolder(binding.root) + + private fun backData(value: String) { + val args = Bundle() + args.putString(KEY_TYPE, value) + getParentFragmentManager().setFragmentResult( + KEY_REQUEST_SELECT, + args + ) + dismissDialog() + } + + + interface ISelectItem { + fun onBack(value: String) + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/widget/selectitem/HorDividerDecoration.kt b/app/src/main/java/com/bingce/controlnetwork/newui/widget/selectitem/HorDividerDecoration.kt new file mode 100644 index 0000000..d28b37e --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/widget/selectitem/HorDividerDecoration.kt @@ -0,0 +1,11 @@ +package com.bingce.controlnetwork.newui.widget.selectitem + +import android.content.Context +import androidx.core.content.ContextCompat +import com.bingce.controlnetwork.R +import com.bingce.controlapphelper.widget.swiperecyclerview.widget.DefaultItemDecoration + +class HorDividerDecoration(context: Context) : DefaultItemDecoration( + ContextCompat.getColor(context, R.color.hor_line), + 1, 1 +) \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/widget/selectitem/SelectIDetectionStationFragment.kt b/app/src/main/java/com/bingce/controlnetwork/newui/widget/selectitem/SelectIDetectionStationFragment.kt new file mode 100644 index 0000000..7ba1286 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/widget/selectitem/SelectIDetectionStationFragment.kt @@ -0,0 +1,42 @@ +package com.bingce.controlnetwork.newui.widget.selectitem + +import com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant +import com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant.STATION_TYPE_0 +import com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant.STATION_TYPE_1 +import com.bingce.controlapphelper.model.IUniversalListItem + +class SelectIDetectionStationFragment : BaseSelectItemFragment() { + override fun getDataList(): List> { + return listOf( + Bean( + LevelIDetectionConstant.getStationTypeShow(STATION_TYPE_0), + STATION_TYPE_0.toString() + ), + Bean( + LevelIDetectionConstant.getStationTypeShow(STATION_TYPE_1), + STATION_TYPE_1.toString() + ), + ) + } + + override fun getTitle(): String { + return "选择测站" + } + + class Bean(private val name: String, private val type: String) : + IUniversalListItem { + override fun getName(): String { + return name + } + + override fun getId(): String { + return "" + } + + override fun getValue(): String { + return type + } + + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/widget/selectitem/SelectIDetectionStationMeasureTypeFragment.kt b/app/src/main/java/com/bingce/controlnetwork/newui/widget/selectitem/SelectIDetectionStationMeasureTypeFragment.kt new file mode 100644 index 0000000..f7009ed --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/widget/selectitem/SelectIDetectionStationMeasureTypeFragment.kt @@ -0,0 +1,38 @@ +package com.bingce.controlnetwork.newui.widget.selectitem + +import com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant.A_I_B_I +import com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant.A_I_I_B +import com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant.I_A_B_I +import com.bingce.controlapphelper.datasource.database.leveling.idetection.constants.LevelIDetectionConstant.getMeasureTypeShowLong +import com.bingce.controlapphelper.model.IUniversalListItem + +class SelectIDetectionStationMeasureTypeFragment : BaseSelectItemFragment() { + override fun getDataList(): List> { + return listOf( + Bean(getMeasureTypeShowLong(I_A_B_I), I_A_B_I), + Bean(getMeasureTypeShowLong(A_I_I_B), A_I_I_B), + Bean(getMeasureTypeShowLong(A_I_B_I), A_I_B_I), + ) + } + + override fun getTitle(): String { + return "选择检测方法" + } + + class Bean(private val name: String, private val type: String) : + IUniversalListItem { + override fun getName(): String { + return name + } + + override fun getId(): String { + return "" + } + + override fun getValue(): String { + return type + } + + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/widget/selectitem/SelectProjectTypeFragment.kt b/app/src/main/java/com/bingce/controlnetwork/newui/widget/selectitem/SelectProjectTypeFragment.kt new file mode 100644 index 0000000..2178344 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/widget/selectitem/SelectProjectTypeFragment.kt @@ -0,0 +1,37 @@ +package com.bingce.controlnetwork.newui.widget.selectitem + +import com.bingce.controlapphelper.datasource.database.ProjectTypeValue +import com.bingce.controlapphelper.model.IUniversalListItem +import com.bingce.controlnetwork.R + +class SelectProjectTypeFragment : BaseSelectItemFragment() { + override fun getDataList(): List> { + return listOf( + Bean(getString(R.string.triangular_wire), ProjectTypeValue.TRIANGLE), +// Bean(getString(R.string.contact_measurement), ProjectTypeValue.CONNECTION), + Bean(getString(R.string.elevation_wire), ProjectTypeValue.HEIGHT_TRAVERSE), + Bean(getString(R.string.level), ProjectTypeValue.LEVEL) + ) + } + + override fun getTitle(): String { + return getString(R.string.new_project) + } + + class Bean(private val projectTypeName: String, private val projectType: String) : + IUniversalListItem { + override fun getName(): String { + return projectTypeName + } + + override fun getId(): String { + return "" + } + + override fun getValue(): String { + return projectType + } + + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/widget/swipemenu/SwipeMenuDelete.kt b/app/src/main/java/com/bingce/controlnetwork/newui/widget/swipemenu/SwipeMenuDelete.kt new file mode 100644 index 0000000..3f5f31e --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/widget/swipemenu/SwipeMenuDelete.kt @@ -0,0 +1,42 @@ +package com.bingce.controlnetwork.newui.widget.swipemenu + +import android.content.Context +import android.view.ViewGroup +import com.bingce.controlapphelper.util.Tools + +import com.bingce.controlapphelper.widget.swiperecyclerview.SwipeMenu +import com.bingce.controlapphelper.widget.swiperecyclerview.SwipeMenuCreator +import com.bingce.controlapphelper.widget.swiperecyclerview.SwipeMenuItem +import com.bingce.controlnetwork.R +import com.bingce.utils.ScreenUtil + +class SwipeMenuDelete(val context: Context) : SwipeMenuCreator { + + companion object { + @JvmStatic + fun isDeleteMenu(menuPos: Int) = menuPos == 0 + } + + override fun onCreateMenu(leftMenu: SwipeMenu, rightMenu: SwipeMenu, position: Int) { + val width = ScreenUtil.dp2px(context, 70f) + + // 1. MATCH_PARENT 自适应高度,保持和Item一样高; + // 2. 指定具体的高,比如80; + // 3. WRAP_CONTENT,自身高度,不推荐; + val height = ViewGroup.LayoutParams.MATCH_PARENT + + // 添加右侧的,如果不添加,则右侧不会出现菜单。 + val deleteItem: SwipeMenuItem = + SwipeMenuItem(context) + .setWidth(width) + .setHeight(height) + .setBackgroundColor(Tools.getColor(R.color.md_red_400)) + .setText("删除") + .setTextSize(14) + .setTextColorResource(R.color.white) + //添加右侧菜单 + rightMenu.addMenuItem(deleteItem) + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/widget/swipemenu/SwipeMenuEditDelete.kt b/app/src/main/java/com/bingce/controlnetwork/newui/widget/swipemenu/SwipeMenuEditDelete.kt new file mode 100644 index 0000000..727ac62 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/widget/swipemenu/SwipeMenuEditDelete.kt @@ -0,0 +1,54 @@ +package com.bingce.controlnetwork.newui.widget.swipemenu + +import android.content.Context +import android.view.ViewGroup +import com.bingce.controlapphelper.util.Tools +import com.bingce.controlapphelper.widget.swiperecyclerview.SwipeMenu +import com.bingce.controlapphelper.widget.swiperecyclerview.SwipeMenuCreator +import com.bingce.controlapphelper.widget.swiperecyclerview.SwipeMenuItem +import com.bingce.controlnetwork.R +import com.bingce.utils.ScreenUtil + +class SwipeMenuEditDelete(val context: Context) : SwipeMenuCreator { + + companion object { + @JvmStatic + fun isEditMenu(menuPos: Int) = menuPos == 0 + + @JvmStatic + fun isDeleteMenu(menuPos: Int) = menuPos == 1 + } + + override fun onCreateMenu(leftMenu: SwipeMenu, rightMenu: SwipeMenu, position: Int) { + val width = ScreenUtil.dp2px(context, 70f) + + // 1. MATCH_PARENT 自适应高度,保持和Item一样高; + // 2. 指定具体的高,比如80; + // 3. WRAP_CONTENT,自身高度,不推荐; + val height = ViewGroup.LayoutParams.MATCH_PARENT + + // 添加右侧的,如果不添加,则右侧不会出现菜单。 + val eidtItem: SwipeMenuItem = + SwipeMenuItem(context) + .setWidth(width) + .setHeight(height) + .setBackgroundColor(Tools.getColor(R.color.md_blue_400)) + .setText("编辑") + .setTextSize(14) + .setTextColorResource(R.color.white) + + val deleteItem: SwipeMenuItem = + SwipeMenuItem(context) + .setWidth(width) + .setHeight(height) + .setBackgroundColor(Tools.getColor(R.color.md_red_400)) + .setText("删除") + .setTextSize(14) + .setTextColorResource(R.color.white) + //添加右侧菜单 + rightMenu.addMenuItem(eidtItem) + rightMenu.addMenuItem(deleteItem) + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/newui/widget/switchtext/SwitchWithText.java b/app/src/main/java/com/bingce/controlnetwork/newui/widget/switchtext/SwitchWithText.java new file mode 100644 index 0000000..71e1436 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/newui/widget/switchtext/SwitchWithText.java @@ -0,0 +1,97 @@ +package com.bingce.controlnetwork.newui.widget.switchtext; + +import android.content.Context; +import android.content.res.TypedArray; +import android.util.AttributeSet; +import android.view.LayoutInflater; +import android.widget.LinearLayout; +import android.widget.TextView; + +import androidx.annotation.Nullable; +import androidx.appcompat.widget.SwitchCompat; + +import com.bingce.controlnetwork.R; + + +public class SwitchWithText extends LinearLayout { + + private String name; + private String onText; + private String offText; + private boolean checked; + private SwitchCompat switchButton; + private TextView tvDesc; + + public SwitchWithText(Context context) { + super(context); + init(context, null); + } + + public SwitchWithText(Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + init(context, attrs); + } + + public SwitchWithText(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + init(context, attrs); + } + + private void init(Context context, AttributeSet attrs) { + LayoutInflater inflater = LayoutInflater.from(context); + inflater.inflate(R.layout.new_switch_with_layout, this); + + switchButton = findViewById(R.id.switchButton); + tvDesc = findViewById(R.id.tvDesc); + + //获取属性 + if (attrs != null) { + TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SwitchWithText); + name = a.getString(R.styleable.SwitchWithText_name); + onText = a.getString(R.styleable.SwitchWithText_onText); + offText = a.getString(R.styleable.SwitchWithText_offText); + checked = a.getBoolean(R.styleable.SwitchWithText_onChecked, false); + a.recycle(); + } + + switchButton.setChecked(checked); + switchButton.setText(name); + refreshDescText(); + + switchButton.setOnCheckedChangeListener((buttonView, isChecked) -> { + checked = isChecked; + refreshDescText(); + if (checkChangeListener != null) { + checkChangeListener.onCheck(isChecked); + } + }); + + } + + public void setChecked(boolean checked) { + switchButton.setChecked(checked); + } + + public boolean isChecked() { + return switchButton.isChecked(); + } + + private void refreshDescText() { + if (checked) { + tvDesc.setText(onText); + } else { + tvDesc.setText(offText); + } + } + + private ICheckChangeListener checkChangeListener; + + public void setOnCheckChangeListener(ICheckChangeListener checkChangeListener) { + this.checkChangeListener = checkChangeListener; + } + + public interface ICheckChangeListener { + void onCheck(boolean checked); + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/method/ExportContants.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/method/ExportContants.java new file mode 100644 index 0000000..dedfe48 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/method/ExportContants.java @@ -0,0 +1,10 @@ +package com.bingce.controlnetwork.surveyor.method; + +public class ExportContants { + /** + * 天津导出常量 0-已知点 1-未知点 + */ + public static final int TYPE_KNOWN_POINT = 0; + public static final int TYPE_UNKNOWN_POINT = 1; + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/method/ExportUtilsPla.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/method/ExportUtilsPla.java new file mode 100644 index 0000000..3dba98a --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/method/ExportUtilsPla.java @@ -0,0 +1,1597 @@ +package com.bingce.controlnetwork.surveyor.method; + +import android.content.Context; +import android.os.Environment; +import android.text.TextUtils; + +import androidx.annotation.WorkerThread; + +import com.bingce.controlapphelper.datasource.database.ProjectType; +import com.bingce.controlapphelper.datasource.database.ProjectTypeValue; +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.line.ILineRecordDataSource; +import com.bingce.controlapphelper.datasource.database.line.LineRecord; +import com.bingce.controlapphelper.datasource.database.point.IPointDataSource; +import com.bingce.controlapphelper.datasource.database.point.PointRecord; +import com.bingce.controlapphelper.datasource.database.project.IProjectDataSource; +import com.bingce.controlapphelper.datasource.database.project.ProjectRecord; +import com.bingce.controlapphelper.datasource.database.schedule.ISurveyorScheduleDataSource; +import com.bingce.controlapphelper.datasource.database.surveyorstation.ISurveyorStationDataSource; +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.model.SurveyorPoint; +import com.bingce.controlapphelper.datasource.database.tolerance.detail.IToleranceDetailDataSource; +import com.bingce.controlapphelper.datasource.database.tolerance.detail.ToleranceDetailRecord; +import com.bingce.controlapphelper.datasource.database.tolerance.group.ToleranceGroupRecord; +import com.bingce.controlapphelper.datasource.database.tolerance.level.ToleranceLevelRecord; +import com.bingce.controlapphelper.surveyor.data.CachedData; +import com.bingce.controlapphelper.surveyor.data.CachedDataAloneDistance; +import com.bingce.controlapphelper.surveyor.method.ExportStationMethod; +import com.bingce.controlapphelper.surveyor.method.ExportUtils; +import com.bingce.controlapphelper.surveyor.method.SurveyorAdjustMethod; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.App; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.newui.configfragment.SelectExportType; +import com.bingce.utils.DateUtils; +import com.bingce.utils.Util; +import com.bingce.utils.VipManager; +import com.bingce.zip.ZipUtil; + +import org.jetbrains.annotations.NotNull; + +import java.io.File; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; + +import blankj.utilcode.util.FileUtils; +import blankj.utilcode.util.ToastUtils; + + +public class ExportUtilsPla { + private final static String NEW_LINE = "\r\n"; + private final static String SPACE = "\t"; + + private final static int ANGLE_DECIMALS = 5; //保留小数位数 + public final static int DISTANCE_DECIMALS = 5; //距离保留小数位数 + public final static int PPM_DECIMALS = 8; //ppm保留小数位数 + + public static String getExportFirstDirectory() { + return App.getApp().getString(R.string.app_name) + "导出文件"; + } + + public static String getExportSecondDirectory() { + return getExportFirstDirectory() + File.separator + "导线文件导出"; + } + + /** + * 收集需要导出的测站、测期、项目相关信息 + */ + @WorkerThread + private static Collection collect(List exportItems) { + Map projectMap = new HashMap<>(); + for (ExportItem exportItem : exportItems) { + Project project; + if (!projectMap.containsKey(exportItem.projectId)) { + project = new Project(exportItem.projectId, exportItem.projectType, exportItem.projectName); + projectMap.put(exportItem.projectId, project); + } else { + project = projectMap.get(exportItem.projectId); + } + if (project == null) { + continue; + } + SurveyorPeriod cycle; + if (!project.surveyorPeriodMap.containsKey(exportItem.cycleId)) { + cycle = new SurveyorPeriod(exportItem.cycleId, exportItem.cycleName); + project.surveyorPeriodMap.put(exportItem.cycleId, cycle); + } else { + cycle = project.surveyorPeriodMap.get(exportItem.cycleId); + } + + if (cycle == null) { + continue; + } + if (!cycle.stationMap.containsKey(exportItem.stationId)) { + Station station = new Station(exportItem.stationId, exportItem.stationPointName); + cycle.stationMap.put(exportItem.stationId, station); + } + } + return projectMap.values(); + } + + protected static List surveyorPointRecordListInAllPeriods(Project project) { + //收集所有测期下所有测站的测量点记录,用于后面导出控制点 + List surveyorPointRecordListInAllPeriods = new ArrayList<>(); + for (Map.Entry surveyorPeriodEntry : project.surveyorPeriodMap.entrySet()) { + //遍历每个测期 + SurveyorPeriod surveyorPeriod = surveyorPeriodEntry.getValue(); + for (Map.Entry stationEntry : surveyorPeriod.stationMap.entrySet()) { + ISurveyorStationDataSource stationDataSource = SurveyorDatabaseFactory.instance.getSurveyorStation(); + SurveyorStationRecord stationRecord = stationDataSource.getRecordSync(stationEntry.getValue().stationId); + if (stationRecord == null) { + continue; + } + //收集测站中的测点记录 + List surveyorPointListInSingleStation = ExportStationMethod.surveyorPointRecordInSingleStation(stationRecord); + for (PointRecord record : surveyorPointListInSingleStation) { + //去重.检测对应测点是否已经记录到列表中 + boolean hasRecord = false; + for (PointRecord savedRecord : surveyorPointRecordListInAllPeriods) { + if (record.id.equals(savedRecord.id)) { + hasRecord = true; + break; + } + } + if (hasRecord) { + continue; + } + surveyorPointRecordListInAllPeriods.add(record); + } + } + } + return surveyorPointRecordListInAllPeriods; + } + + @WorkerThread + private static List collectPointFromProject(Project project) { + IPointDataSource pointDataSource = SurveyorDatabaseFactory.instance.getPointDataSource(); + List pointList = pointDataSource.findByProjectIdSync(project.projectId); + //按照已知点在前未知点在后排序 + Collections.sort(pointList, (current, Other) -> { + if ((PointRecord.TYPE_KNOWN_POINT.equals(current.pointType) || PointRecord.TYPE_GLOBAL_POINT.equals(current.pointType)) + && PointRecord.TYPE_UNKNOWN_POINT.equals(Other.pointType)) { + //当前是已知点 比较是未知点 + return 1; + } else if (PointRecord.TYPE_UNKNOWN_POINT.equals(current.pointType) + && (PointRecord.TYPE_KNOWN_POINT.equals(Other.pointType) || PointRecord.TYPE_GLOBAL_POINT.equals(Other.pointType))) { + //当前是未知点,比较是已知点 + return -1; + } + return 0; + }); + return pointList; + } + + /** + * 导出冰测数据 + */ + @WorkerThread + private static void exportBingCe(Project project, ToleranceDetailRecord toleranceRecord, File projectCachedDir) { + + String controlPointTxtPrint = getControlPointTxtPrint(project); + String projectTxtPrint = getProjectTxtPrint(project); + + //读取「限差」信息 + //二级 + ToleranceLevelRecord toleranceLevelRecord = null; + if (toleranceRecord.levelId != null) { + toleranceLevelRecord = SurveyorDatabaseFactory.instance.getToleranceLevelDataSource().getRecordSync(toleranceRecord.levelId); + } + //一级 + ToleranceGroupRecord toleranceGroupRecord = null; + if (toleranceRecord.groupId != null) { + toleranceGroupRecord = SurveyorDatabaseFactory.instance.getToleranceGroupDataSource().getRecordSync(toleranceRecord.groupId); + } + + //遍历每个测期 + for (Map.Entry surveyorPeriodEntry : project.surveyorPeriodMap.entrySet()) { + //初始化天津水平角,垂直角和距离 + StringBuilder horSbTianjinOne = new StringBuilder(); + StringBuilder verSbTianjinOne = new StringBuilder(); + StringBuilder disSbTianjinOne = new StringBuilder(); + + SurveyorPeriod surveyorPeriod = surveyorPeriodEntry.getValue(); + //测站文件夹和测站文件的名称暂存map + Map stationFileNameMap = new HashMap<>(); + //创建测期文件夹 + File periodFolder = ExportStationMethod.initPeriodFolder(projectCachedDir, surveyorPeriod.periodName); + + for (Map.Entry stationEntry : surveyorPeriod.stationMap.entrySet()) { + String stationName = stationEntry.getValue().stationName; + String stationFileName = getStationFileName(stationFileNameMap, stationName); + + ISurveyorStationDataSource stationDataSource = SurveyorDatabaseFactory.instance.getSurveyorStation(); + SurveyorStationRecord stationRecord = stationDataSource.getRecordSync(stationEntry.getValue().stationId); + if (stationRecord == null) { + continue; + } + //创建测站文件夹 + File stationFolder = ExportStationMethod.initStationFolder(periodFolder, stationFileName); + + //2.导出单个测站的数据 + ExportStationMethod.exportBingCeSingleStationSurveyorData( + stationFolder, + toleranceRecord, toleranceLevelRecord, toleranceGroupRecord, + stationFileName, stationName, stationRecord); + //天津收集方向值,垂直角,边长文件的数据 + collectCustomTj61365(stationName, stationRecord, toleranceRecord, horSbTianjinOne, verSbTianjinOne, disSbTianjinOne); + } + + //输出文件 + if (horSbTianjinOne.length() > 0) { + horSbTianjinOne.append("END"); + ExportStationMethod.save(horSbTianjinOne.toString(), periodFolder, "方向值.TXT"); + } else { + ExportStationMethod.save(" ", periodFolder, "方向值.TXT"); + } + if (verSbTianjinOne.length() > 0) { + ExportStationMethod.save(verSbTianjinOne.toString(), periodFolder, "垂直角.TXT"); + } else { + ExportStationMethod.save(" ", periodFolder, "垂直角.TXT"); + } + if (disSbTianjinOne.length() > 0) { + disSbTianjinOne.append("END"); + ExportStationMethod.save(disSbTianjinOne.toString(), periodFolder, "边长.TXT"); + } else { + ExportStationMethod.save(" ", periodFolder, "边长.TXT"); + } + + //导出控制点文件 + exportControlTxt(periodFolder, controlPointTxtPrint); + //导出项目文件 + exportProjectTxt(periodFolder, projectTxtPrint); + + } + + } + + private static void exportProjectTxt(File exportFolder, String data) { + ExportStationMethod.save(data, exportFolder, "project.TXT"); + } + + private static void exportControlTxt(File exportFolder, String data) { + ExportStationMethod.save(data, exportFolder, "controlpoint.TXT"); + } + + private static String getControlPointTxtPrint(Project project) { + List surveyorPointRecordListInAllPeriods = collectPointFromProject(project); + StringBuilder pointStringBuilder = new StringBuilder(); + + for (PointRecord pointRecord : surveyorPointRecordListInAllPeriods) { + if (pointRecord == null) { + continue; + } + + pointStringBuilder + .append(pointRecord.getName()) + .append(",") + .append("") + .append(",") + .append(ExportStationMethod.getXyzFormat(pointRecord.getX())) + .append(",") + .append(ExportStationMethod.getXyzFormat(pointRecord.getY())) + .append(",") + .append(ExportStationMethod.getXyzFormat(pointRecord.getZ())) + .append(",") + .append(pointRecord.getLongitude()) + .append(",") + .append(pointRecord.getLatitude()) + .append(",") + .append(getPointTypeForTianjin(pointRecord.getPointType())); + + pointStringBuilder.append("\n"); + } + return pointStringBuilder.toString(); + } + + @WorkerThread + private static String getProjectTxtPrint(Project project) { + IProjectDataSource projectDataSource = SurveyorDatabaseFactory.instance.getProjectDataSource(); +// ProjectRecord projectRecord = projectDataSource.getRecord(project.projectId); + + return project.projectName + + "," + + getProjectTypeForTianjin(project.projectType) + + "\n"; + + } + + + /** + * nameMap主要是为了避免同一测期下测站重复的问题 + * 比如闭合导线,存在某点充当多次站点的情况 + * 通过nameMap为后面的station添加一个'-x'后缀 + * + * @param nameMap + * @param stationName + * @return + */ + private static String getStationFileName(Map nameMap, String stationName) { + if (nameMap.containsKey(stationName)) { + Integer obj = nameMap.get(stationName); + if (obj != null) { + int count = obj + 1; + nameMap.put(stationName, count); + stationName = stationName + "_" + count; + } + } else { + nameMap.put(stationName, 0); + } + return stationName; + } + + /** + * 收集边长,垂直角,方向值文件的数据 + * + * @param stationName + * @param stationRecord + * @param toleranceRecord + * @param horSbTianjinOne + * @param verSbTianjinOne + * @param disSbTianjinOne + */ + @WorkerThread + private static void collectCustomTj61365(String stationName, SurveyorStationRecord stationRecord, ToleranceDetailRecord toleranceRecord, + StringBuilder horSbTianjinOne, StringBuilder verSbTianjinOne, + StringBuilder disSbTianjinOne) { +// if (stationRecord.isSeparateObservation()) { +// collectAloneHorAngleTjUnique(stationName, stationRecord, toleranceRecord, horSbTianjinOne); +// } else { +// collectCombineAngleDistanceTjUnique(stationName, stationRecord, toleranceRecord, horSbTianjinOne, verSbTianjinOne, disSbTianjinOne); +// } + collectCombineAngleDistanceTjUnique(stationName, stationRecord, toleranceRecord, horSbTianjinOne, verSbTianjinOne, disSbTianjinOne); + collectAloneDistanceTjUnique(stationName, stationRecord, toleranceRecord, disSbTianjinOne); + } + + /** + * 收集合并观测的水平角,垂直角和距离 + * 距离可能存在单独测距 + */ + private static void collectCombineAngleDistanceTjUnique(String stationName, SurveyorStationRecord stationRecord, ToleranceDetailRecord toleranceRecord, + StringBuilder horSbTianjinOne, StringBuilder verSbTianjinOne, + StringBuilder disSbTianjinOne) { + CachedData cachedData = + CachedData.newInstance(stationRecord.isAutoClose(), + stationRecord.isLeftAndRightSurveyor(), + stationRecord.getId(), toleranceRecord); + + //测距测角的平差结果 + SurveyorAdjustMethod.AdjustResult adjustResult = SurveyorAdjustMethod.calStationAdjust(stationRecord, cachedData); + if (adjustResult.errorString == null || adjustResult.errorString.isEmpty()) { + //水平角 + horSbTianjinOne.append(stationName).append(SPACE).append(formatHeight(Double.parseDouble(stationRecord.getInstrumentHeight()))).append(SPACE); + + StringBuilder verSbTianjinEveryStation = new StringBuilder(); + int verEverySurveyorPoint = 0; + //遍历测站测点 + for (int i = 0; i < adjustResult.result.size(); i++) { + SurveyorAdjustMethod.Item item = adjustResult.result.get(i); + //水平角 + String exportHorAngle = ExportStationMethod.radianToDmsForTj61365(item.getHorAngle(), true); + if (i != 0) { + horSbTianjinOne.append(SPACE).append(SPACE); + } + horSbTianjinOne.append(item.getPointName()).append(SPACE).append(exportHorAngle).append(SPACE).append(formatHeight(item.getPrismHeight())); + horSbTianjinOne.append(NEW_LINE); + + verEverySurveyorPoint++; + String exportVerAngle = ExportStationMethod.radianToDmsForTj61365(item.getVerAngle(), false); + verSbTianjinEveryStation.append(item.getPointName()).append(SPACE).append(exportVerAngle).append(SPACE).append(formatHeight(Double.parseDouble(stationRecord.getInstrumentHeight()))) + .append(SPACE).append(formatHeight(item.getPrismHeight())); + verSbTianjinEveryStation.append(NEW_LINE); + + double distance = item.getDistance(); + if (distance > 0) { + appendAloneDistance(disSbTianjinOne, stationName, item.getPointName(), distance, + Double.parseDouble(stationRecord.getInstrumentHeightDeal()), String.valueOf(item.getPrismHeight())); + } + } + + if (verEverySurveyorPoint > 0) { + verSbTianjinOne.append(stationName).append(SPACE).append(verEverySurveyorPoint).append(NEW_LINE); + verSbTianjinOne.append(verSbTianjinEveryStation); + } + + } + } + + /** + * 收集天津边长数据 + * 合并观测和分开观测的单独测距 + */ + private static void collectAloneDistanceTjUnique(String stationName, SurveyorStationRecord stationRecord, + ToleranceDetailRecord toleranceRecord, StringBuilder disSbTianjinOne) { + SurveyorAdjustMethod.calAloneDistance(stationRecord.getId(), + CachedDataAloneDistance.newInstance(stationRecord.getId()), new SurveyorAdjustMethod.ICallback() { + @Override + public void onGet(ArrayList adjustResult, Boolean isShowSlopDistance) { + if (!adjustResult.isEmpty()) { + for (SurveyorAdjustMethod.Item item : adjustResult) { + appendAloneDistance(disSbTianjinOne, stationName, item.getPointName(), item.getDistance(), + Double.parseDouble(stationRecord.getInstrumentHeightDeal()), String.valueOf(item.getPrismHeight())); + } + } + } + + @Override + public void onFailure(String error) { + + } + }); + } + + private static void appendAloneDistance(StringBuilder disSbTianjinOne, String stationName, String pointName, double distance, + double instrumentHeight, String prismHeight) { + disSbTianjinOne.append(stationName).append(SPACE).append(pointName).append(SPACE) + .append(Tools.formatDouble2String(distance, 4)) + .append(SPACE).append(formatHeight(instrumentHeight)) + .append(SPACE).append(formatHeight(Double.parseDouble(prismHeight))); + disSbTianjinOne.append(NEW_LINE); + } + + /** + * 导出科傻数据 + */ + @WorkerThread + private static void exportKeSha(Project project, + ToleranceDetailRecord toleranceRecord, File projectCachedDir) { + ISurveyorStationDataSource stationDataSource = SurveyorDatabaseFactory.instance.getSurveyorStation(); + StringBuilder ksStringBuilder = new StringBuilder(); + ksStringBuilder.append("3.5,5,5").append(NEW_LINE);//限差使用默认值 + + //存储已知点 + List surveyorPointRecordListInAllPeriods = surveyorPointRecordListInAllPeriods(project); + for (PointRecord pointRecord : surveyorPointRecordListInAllPeriods) { + if (pointRecord == null) { + continue; + } + if (PointRecord.TYPE_KNOWN_POINT.equals(pointRecord.pointType) || + PointRecord.TYPE_GLOBAL_POINT.equals(pointRecord.pointType)) { + ksStringBuilder + .append(pointRecord.getName()) + .append(",") + .append(pointRecord.getX()) + .append(",") + .append(pointRecord.getY()) + .append(NEW_LINE); + } + } + //存储其他数据 + for (Map.Entry cycleEntry : project.surveyorPeriodMap.entrySet()) { + SurveyorPeriod cycle = cycleEntry.getValue(); + String cycleName = cycle.periodName.replace(":", "_"); + File cycleDir = new File(projectCachedDir, cycleName); + try { + if (!cycleDir.exists()) { + cycleDir.mkdir(); + } + } catch (Exception ignore) { + continue; + } + for (Map.Entry stationEntry : cycle.stationMap.entrySet()) { + String stationId = stationEntry.getValue().stationId; + String stationName = stationEntry.getValue().stationName; + //读取测站信息 + SurveyorStationRecord stationRecord = stationDataSource.getRecordSync(stationId); + + //创建缓存数据 + CachedData cachedData = + CachedData.newInstance(stationRecord.isAutoClose(), + stationRecord.isLeftAndRightSurveyor(), + stationId, toleranceRecord); + if (cachedData == null) { + continue; + } + cachedData.onShowSlopDistance(false);//平距 + + //计算平差数据 + SurveyorAdjustMethod.AdjustResult adjustResult = SurveyorAdjustMethod.calStationAdjust(stationRecord, cachedData); + if (TextUtils.isEmpty(adjustResult.errorString)) { + ksStringBuilder.append(stationName).append(NEW_LINE); + for (SurveyorAdjustMethod.Item item : adjustResult.result) { + ksStringBuilder + .append(item.getPointName()) + .append(",L,") + .append(ExportStationMethod.radianToDmsDouble(item.getHorAngle())) + .append(NEW_LINE); + } + + for (SurveyorAdjustMethod.Item item : adjustResult.result) { + //这里兼容下钢丝测距的距离 + String pointName = item.getPointName(); + + double distance = 0; + + if (!TextUtils.equals(ProjectTypeValue.CONNECTION, stationRecord.projectType)) { + distance = item.getDistance(); + } else { + Map wellAverageDistanceMap = ExportStationMethod.getWellAverageDistanceFromStation(stationRecord); + if (wellAverageDistanceMap != null && wellAverageDistanceMap.containsKey(pointName)) { + distance = wellAverageDistanceMap.get(pointName); + } + if (distance == 0) { + distance = item.getDistance(); + } + } + + ksStringBuilder + .append(pointName) + .append(",S,") + .append(distance) + .append(NEW_LINE); + } + } + + + } + ExportStationMethod.save(ksStringBuilder.toString(), cycleDir, cycleName + ".in2"); + } + } + + /** + * 导出南方平差仪数据 .txt文件 + */ + @WorkerThread + private static void exportSouthAdjustment(Project project, + ToleranceDetailRecord toleranceRecord, File projectCachedDir) { + ISurveyorStationDataSource stationDataSource = SurveyorDatabaseFactory.instance.getSurveyorStation(); + StringBuilder printSb = new StringBuilder(); + + //[NET]部分 + printSb.append(NEW_LINE); + printSb.append("[NET]"); + printSb.append("Name:" + project.projectName); + printSb.append(NEW_LINE); + printSb.append("Organ:SOUTH SURVEY"); + printSb.append(NEW_LINE); + printSb.append("Obser:SOUTH"); + printSb.append(NEW_LINE); + printSb.append("Computer:SOUTH"); + printSb.append(NEW_LINE); + printSb.append("Recorder:SOUTH"); + printSb.append(NEW_LINE); + printSb.append("Remark:" + project.projectName); + printSb.append(NEW_LINE); + printSb.append("Software:南方平差易2002"); + printSb.append(NEW_LINE); + //[PARA]部分 + printSb.append("[PARA]"); + printSb.append(NEW_LINE); + printSb.append("MO:2.5"); + printSb.append(NEW_LINE); + printSb.append("MS:5.0"); + printSb.append(NEW_LINE); + printSb.append("MR:5.0"); + printSb.append(NEW_LINE); + printSb.append("DistanceError:0.0000"); + printSb.append(NEW_LINE); + printSb.append("DistanceMethod:0"); + printSb.append(NEW_LINE); + printSb.append("LevelMethod:0"); + printSb.append(NEW_LINE); + printSb.append("Mothed:1"); + printSb.append(NEW_LINE); + printSb.append("LevelTrigon:0"); + printSb.append(NEW_LINE); + printSb.append("TrigonObser:1"); + printSb.append(NEW_LINE); + printSb.append("Times:1"); + printSb.append(NEW_LINE); + printSb.append("Level:4"); + printSb.append(NEW_LINE); + printSb.append("Level1:2"); + printSb.append(NEW_LINE); + printSb.append("Limit:3"); + printSb.append(NEW_LINE); + printSb.append("Format:1"); + printSb.append(NEW_LINE); + //[STATION]部分 + printSb.append("[STATION]"); + printSb.append(NEW_LINE); + //存储已知点 + List surveyorPointRecordListInAllPeriods = surveyorPointRecordListInAllPeriods(project); + for (PointRecord pointRecord : surveyorPointRecordListInAllPeriods) { + if (pointRecord == null) { + continue; + } + + printSb.append(pointRecord.getName() + ","); + + switch (pointRecord.pointType) { + case PointRecord.TYPE_KNOWN_POINT: + printSb.append("10"); + break; + default: + printSb.append("00"); + break; + } + printSb.append(","); + printSb.append(ExportStationMethod.getXyzFormat(pointRecord.getX())); + printSb.append(","); + printSb.append(ExportStationMethod.getXyzFormat(pointRecord.getY())); + printSb.append(",,,,"); + printSb.append(NEW_LINE); + } + //[OBSER]部分 + printSb.append("[OBSER]"); + printSb.append(NEW_LINE); + + for (Map.Entry cycleEntry : project.surveyorPeriodMap.entrySet()) { + SurveyorPeriod cycle = cycleEntry.getValue(); + String cycleName = cycle.periodName.replace(":", "_"); + File cycleDir = new File(projectCachedDir, cycleName); + try { + if (!cycleDir.exists()) { + cycleDir.mkdir(); + } + } catch (Exception ignore) { + continue; + } + + StringBuilder stationSb = new StringBuilder(); + + for (Map.Entry stationEntry : cycle.stationMap.entrySet()) { + String stationId = stationEntry.getValue().stationId; + String stationName = stationEntry.getValue().stationName; + //读取测站信息 + SurveyorStationRecord stationRecord = stationDataSource.getRecordSync(stationId); + + //创建缓存数据 + CachedData cachedData = + CachedData.newInstance(stationRecord.isAutoClose(), + stationRecord.isLeftAndRightSurveyor(), + stationId, toleranceRecord); + if (cachedData == null) { + continue; + } + cachedData.onShowSlopDistance(false); + + //计算平差数据 + SurveyorAdjustMethod.AdjustResult adjustResult = SurveyorAdjustMethod.calStationAdjust(stationRecord, cachedData); + if (TextUtils.isEmpty(adjustResult.errorString)) { + for (SurveyorAdjustMethod.Item item : adjustResult.result) { + //这里兼容下钢丝测距的距离 + String pointName = item.getPointName(); + + double distance = 0; + + if (!TextUtils.equals(ProjectTypeValue.CONNECTION, stationRecord.projectType)) { + distance = item.getDistance(); + } else { + Map wellAverageDistanceMap = ExportStationMethod.getWellAverageDistanceFromStation(stationRecord); + if (wellAverageDistanceMap != null && wellAverageDistanceMap.containsKey(pointName)) { + distance = wellAverageDistanceMap.get(pointName); + } + if (distance == 0) { + distance = item.getDistance(); + } + } + + stationSb.append(stationName).append(",") + .append(item.getPointName()).append(",") + .append(ExportStationMethod.radianToDmsDouble(item.getHorAngle())) + .append(",") + .append(distance) + .append(",,,,,,,") + .append(NEW_LINE); + } + } + + } + + printSb.append(stationSb); + + ExportStationMethod.save(printSb.toString(), cycleDir, cycleName + ".txt"); + } + } + + /** + * 导出启飞数据 .kzw文件 + */ + @WorkerThread + private static void exportOpenFly(Project project, + ToleranceDetailRecord toleranceRecord, File projectCachedDir) { + ISurveyorStationDataSource stationDataSource = SurveyorDatabaseFactory.instance.getSurveyorStation(); + StringBuilder printSb = new StringBuilder(); + + printSb.append("控制测量优化设计与平差计算文件"); + printSb.append(NEW_LINE); + printSb.append("300"); + printSb.append(NEW_LINE); + printSb.append("[全网属性]"); + printSb.append(NEW_LINE); + printSb.append("网名:" + project.projectName); + printSb.append(NEW_LINE); + printSb.append("是否优化:0"); + printSb.append(NEW_LINE); + printSb.append("HELMERT定权:0"); + printSb.append(NEW_LINE); + printSb.append("测角中误差:2.500000"); + printSb.append(NEW_LINE); + printSb.append("测距定权方式:0"); + printSb.append(NEW_LINE); + printSb.append("测距A值:50.000000"); + printSb.append(NEW_LINE); + printSb.append("测距B值:0.000000"); + printSb.append(NEW_LINE); + printSb.append("高程类型:0"); + printSb.append(NEW_LINE); + printSb.append("水准定权方式:0"); + printSb.append(NEW_LINE); + printSb.append("三角高程测距形式:0"); + printSb.append(NEW_LINE); + printSb.append("是否由斜距计算平距:1"); + printSb.append(NEW_LINE); + printSb.append("大气折光:0.140000"); + printSb.append(NEW_LINE); + printSb.append("高程单位权:10.000000"); + printSb.append(NEW_LINE); + printSb.append("坐标系:0"); + printSb.append(NEW_LINE); + printSb.append("是否含500:0"); + printSb.append(NEW_LINE); + printSb.append("是否高程归化:0"); + printSb.append(NEW_LINE); + printSb.append("归算高程面:0.000000"); + printSb.append(NEW_LINE); + printSb.append("图数更新方式:0"); + printSb.append(NEW_LINE); + printSb.append("平面网等级:2"); + printSb.append(NEW_LINE); + printSb.append("高程网等级:2"); + printSb.append(NEW_LINE); + printSb.append("三角形限差:9.000000"); + printSb.append(NEW_LINE); + printSb.append("方位角限差:5.000000"); + printSb.append(NEW_LINE); + printSb.append("导线段相对闭合差限差:35000"); + printSb.append(NEW_LINE); + printSb.append("高差闭合差限差:20.000000"); + printSb.append(NEW_LINE); + printSb.append("角度取位:1"); + printSb.append(NEW_LINE); + printSb.append("边长取位:3"); + printSb.append(NEW_LINE); + printSb.append("高差取位:3"); + printSb.append(NEW_LINE); + printSb.append("坐标取位:3"); + printSb.append(NEW_LINE); + printSb.append("高程取位:3"); + printSb.append(NEW_LINE); + printSb.append("已知点类型:0"); + printSb.append(NEW_LINE); + printSb.append("未知点类型:3"); + printSb.append(NEW_LINE); + printSb.append("图形比例:1000.000000"); + printSb.append(NEW_LINE); + printSb.append("椭圆比例:5.000000"); + printSb.append(NEW_LINE); + printSb.append("END"); + printSb.append(NEW_LINE); + //获取点记录 + List surveyorPointRecordListInAllPeriods = surveyorPointRecordListInAllPeriods(project); + //已知点 + printSb.append("[已知点]"); + printSb.append(NEW_LINE); + StringBuilder sbKnow = new StringBuilder(); + int knowCount = 0; + for (PointRecord pointRecord : surveyorPointRecordListInAllPeriods) { + if (pointRecord == null || !TextUtils.equals(pointRecord.pointType, PointRecord.TYPE_KNOWN_POINT)) { + continue; + } + ++knowCount; + sbKnow.append(pointRecord.getName() + ","); + sbKnow.append(ExportStationMethod.getXyzFormat(pointRecord.getX())); + sbKnow.append(","); + sbKnow.append(ExportStationMethod.getXyzFormat(pointRecord.getY())); + sbKnow.append(",,"); + sbKnow.append(NEW_LINE); + } + printSb.append(knowCount); + printSb.append(NEW_LINE); + printSb.append(sbKnow); + printSb.append("END"); + printSb.append(NEW_LINE); + //固定条件 + printSb.append("[固定条件]"); + printSb.append(NEW_LINE); + printSb.append("0"); + printSb.append(NEW_LINE); + printSb.append("END"); + printSb.append(NEW_LINE); + //控制点 + printSb.append("[控制点]"); + printSb.append(NEW_LINE); + StringBuilder sbControl = new StringBuilder(); + int controlCount = 0; + for (PointRecord pointRecord : surveyorPointRecordListInAllPeriods) { + if (pointRecord == null) { + continue; + } + ++controlCount; + sbControl.append(pointRecord.getName() + ","); + sbControl.append(ExportStationMethod.getXyzFormat(pointRecord.getX())); + sbControl.append(","); + sbControl.append(ExportStationMethod.getXyzFormat(pointRecord.getY())); + sbControl.append(","); + sbControl.append(NEW_LINE); + } + printSb.append(controlCount); + printSb.append(NEW_LINE); + printSb.append(sbControl); + printSb.append("END"); + printSb.append(NEW_LINE); + //[测站数据] + printSb.append("[测站数据]"); + printSb.append(NEW_LINE); + + for (Map.Entry cycleEntry : project.surveyorPeriodMap.entrySet()) { + SurveyorPeriod cycle = cycleEntry.getValue(); + String cycleName = cycle.periodName.replace(":", "_"); + File cycleDir = new File(projectCachedDir, cycleName); + try { + if (!cycleDir.exists()) { + cycleDir.mkdir(); + } + } catch (Exception ignore) { + continue; + } + + StringBuilder stationSb = new StringBuilder(); + Map> tempDataMap = new LinkedHashMap<>(); + + for (Map.Entry stationEntry : cycle.stationMap.entrySet()) { + String stationId = stationEntry.getValue().stationId; + String stationName = stationEntry.getValue().stationName; + //读取测站信息 + SurveyorStationRecord stationRecord = stationDataSource.getRecordSync(stationId); + + //创建缓存数据 + CachedData cachedData = + CachedData.newInstance(stationRecord.isAutoClose(), + stationRecord.isLeftAndRightSurveyor(), + stationId, toleranceRecord); + if (cachedData == null) { + continue; + } + cachedData.onShowSlopDistance(false); + + //计算平差数据 + SurveyorAdjustMethod.AdjustResult adjustResult = SurveyorAdjustMethod.calStationAdjust(stationRecord, cachedData); + if (TextUtils.isEmpty(adjustResult.errorString)) { + stationSb.append(cycle.stationMap.keySet().size()); + stationSb.append(NEW_LINE); + + stationSb.append(stationName).append(",").append(adjustResult.result.size()).append(",").append(NEW_LINE); + stationSb.append("照准点").append(NEW_LINE); + + for (SurveyorAdjustMethod.Item item : adjustResult.result) { + //这里兼容下钢丝测距的距离 + String pointName = item.getPointName(); + + double distance = 0; + + if (!TextUtils.equals(ProjectTypeValue.CONNECTION, stationRecord.projectType)) { + distance = item.getDistance(); + } else { + Map wellAverageDistanceMap = ExportStationMethod.getWellAverageDistanceFromStation(stationRecord); + if (wellAverageDistanceMap != null && wellAverageDistanceMap.containsKey(pointName)) { + distance = wellAverageDistanceMap.get(pointName); + } + if (distance == 0) { + distance = item.getDistance(); + } + } + + stationSb + .append(item.getPointName()).append(",") + .append(Tools.radianToDmsString(item.getHorAngle(), 2, true)) + .append(",") + .append(distance) + .append(",,,,") + .append(NEW_LINE); + + } + + stationSb.append("照准点结束").append(NEW_LINE); + } + } + + stationSb.append("END").append(NEW_LINE); + printSb.append(stationSb); + + printSb.append("[点间数据]"); + printSb.append(NEW_LINE); + printSb.append("0"); + printSb.append(NEW_LINE); + printSb.append("END"); + printSb.append(NEW_LINE); + printSb.append("[导线段数据]"); + printSb.append(NEW_LINE); + printSb.append("0"); + printSb.append(NEW_LINE); + printSb.append("END"); + + ExportStationMethod.save(printSb.toString(), cycleDir, cycleName + ".kzw"); + } + } + + + @WorkerThread + private static File exportSingleProject(Context context, Project project, ArrayList selectExportTypeList) { + //读取项目信息 + IProjectDataSource projectDataSource = SurveyorDatabaseFactory.instance.getProjectDataSource(); + ProjectRecord projectRecord = projectDataSource.getRecord(project.projectId); + if (projectRecord == null) { + return null; + } + //读取限差信息 + String toleranceId = projectRecord.getToleranceId(); + IToleranceDetailDataSource toleranceDataSource = SurveyorDatabaseFactory.instance.getToleranceDetailDataSource(); + ToleranceDetailRecord toleranceRecord = toleranceDataSource.getRecordSync(toleranceId); + if (toleranceRecord == null) { + return null; + } + + //需要导出的project目录 + File projectDir = new File(context.getExternalCacheDir(), projectRecord.getProjectName()); + if (!projectDir.exists()) { + if (!projectDir.mkdir()) { + return null; + } + } + + if (selectExportTypeList == null) { + return null; + } + + for (SelectExportType exportType : selectExportTypeList) { + if (SelectExportType.TYPE_CONTROL.equals(exportType.getType())) { + exportBingCe(project, toleranceRecord, projectDir); + } else if (SelectExportType.TYPE_KE_SHA.equals(exportType.getType())) { + exportKeSha(project, toleranceRecord, projectDir); + } else if (SelectExportType.TYPE_NAN_FANG.equals(exportType.getType())) { + exportSouthAdjustment(project, toleranceRecord, projectDir); + } else if (SelectExportType.TYPE_QI_FEI.equals(exportType.getType())) { + exportOpenFly(project, toleranceRecord, projectDir); + } else if (SelectExportType.TYPE_PING_CHA_ZHI_XING.equals(exportType.getType())) { + exportPingChaZhiXing(project, toleranceRecord, projectDir); + } + } + + ExportStationMethod.save( + DateUtils.toFull(new Date()) + "\n" + Tools.getVersionName(), + projectDir, + ".bc"); + + return projectDir; + } + + @WorkerThread + private static File exportSingleHeightTraverseProject(Context context, Project project) { + //读取项目信息 + IProjectDataSource projectDataSource = SurveyorDatabaseFactory.instance.getProjectDataSource(); + ProjectRecord projectRecord = projectDataSource.getRecord(project.projectId); + if (projectRecord == null) { + return null; + } + //读取限差信息 + String toleranceId = projectRecord.getToleranceId(); + IToleranceDetailDataSource toleranceDataSource = SurveyorDatabaseFactory.instance.getToleranceDetailDataSource(); + ToleranceDetailRecord toleranceRecord = toleranceDataSource.getRecordSync(toleranceId); + if (toleranceRecord == null) { + return null; + } + + //需要导出的project目录 + File projectDir = new File(context.getExternalCacheDir(), projectRecord.getProjectName()); + if (!projectDir.exists()) { + if (!projectDir.mkdirs()) { + return null; + } + } + + //高程导线 + exportBingceHeightTraverse(project, toleranceRecord, projectDir); + return projectDir; + } + + @WorkerThread + private static void exportBingceHeightTraverse(Project project, ToleranceDetailRecord toleranceRecord, File projectDir) { + try { + StringBuilder dxrBuilder = new StringBuilder(); + //遍历每个路线 + for (Map.Entry surveyorPeriodEntry : project.surveyorPeriodMap.entrySet()) { + ExportUtilsPla.SurveyorPeriod surveyorPeriod = surveyorPeriodEntry.getValue(); + ExportStationMethod.exportBingCeSingleStationSurveyorDataHeightTraverse( + projectDir, + toleranceRecord, + project.projectId, + surveyorPeriod.periodId, surveyorPeriod.periodName); + + StringBuilder dxrBuilderEveryRoute = ExportStationMethod.exportRouteDxrData(toleranceRecord, project.projectId, surveyorPeriod.periodId); + dxrBuilder.append(dxrBuilderEveryRoute).append(NEW_LINE); + } + //存储dxr + ExportStationMethod.save(dxrBuilder.toString(), projectDir, project.projectName + ".dxr"); + exportProjectAndControlPoint(project, projectDir); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * 导出项目和控制点文件 + * + * @param project + * @param projectDir + */ + private static void exportProjectAndControlPoint(Project project, File projectDir) { + //存储已知点 + List surveyorPointRecordListInAllPeriods = surveyorPointRecordListInAllPeriods(project); + StringBuilder pointStringBuilder = new StringBuilder(); + for (PointRecord pointRecord : surveyorPointRecordListInAllPeriods) { + if (pointRecord == null) { + continue; + } + if (PointRecord.TYPE_KNOWN_POINT.equals(pointRecord.pointType) || + PointRecord.TYPE_GLOBAL_POINT.equals(pointRecord.pointType)) { + pointStringBuilder + .append(pointRecord.getName()) + .append(",") + .append(pointRecord.getXFormat(4)) + .append(",") + .append(pointRecord.getYFormat(4)) + .append(",") + .append(pointRecord.getZFormat(4)) + .append("\n"); + } + } + //导出控制点文件 + ExportStationMethod.save(pointStringBuilder.toString(), projectDir, "controlpoint.TXT"); + //导出项目名称和项目类型文件 + ExportStationMethod.save(project.projectName + "," + project.projectType + "\n", projectDir, "project.TXT"); + + } + + /** + * 导出平差之星 + */ + private static void exportPingChaZhiXing(Project project, ToleranceDetailRecord toleranceRecord, File projectDir) { + //读取「限差」信息 + //二级 + ToleranceLevelRecord toleranceLevelRecord = null; + if (toleranceRecord.levelId != null) { + toleranceLevelRecord = SurveyorDatabaseFactory.instance.getToleranceLevelDataSource().getRecordSync(toleranceRecord.levelId); + } + //一级 + ToleranceGroupRecord toleranceGroupRecord = null; + if (toleranceRecord.groupId != null) { + toleranceGroupRecord = SurveyorDatabaseFactory.instance.getToleranceGroupDataSource().getRecordSync(toleranceRecord.groupId); + } + + //遍历每个测期 + for (Map.Entry surveyorPeriodEntry : project.surveyorPeriodMap.entrySet()) { + //初始化天津水平角,垂直角和距离 + StringBuilder horSbTianjinOne = new StringBuilder(); + StringBuilder verSbTianjinOne = new StringBuilder(); + StringBuilder disSbTianjinOne = new StringBuilder(); + + SurveyorPeriod surveyorPeriod = surveyorPeriodEntry.getValue(); + //测站文件夹和测站文件的名称暂存map + Map stationFileNameMap = new HashMap<>(); + //创建测期文件夹 + File periodFolder = ExportStationMethod.initPeriodFolder(projectDir, surveyorPeriod.periodName); + + for (Map.Entry stationEntry : surveyorPeriod.stationMap.entrySet()) { + String stationName = stationEntry.getValue().stationName; + String stationFileName = getStationFileName(stationFileNameMap, stationName); + + ISurveyorStationDataSource stationDataSource = SurveyorDatabaseFactory.instance.getSurveyorStation(); + SurveyorStationRecord stationRecord = stationDataSource.getRecordSync(stationEntry.getValue().stationId); + if (stationRecord == null) { + continue; + } + //创建测站文件夹 + File stationFolder = ExportStationMethod.initStationFolder(periodFolder, stationFileName); + + //2.导出单个测站的数据 + ExportStationMethod.exportBingCeSingleStationSurveyorData( + stationFolder, + toleranceRecord, toleranceLevelRecord, toleranceGroupRecord, + stationFileName, stationName, stationRecord); + //天津收集方向值,垂直角,边长文件的数据 + collectCustomTj61365(stationName, stationRecord, toleranceRecord, horSbTianjinOne, verSbTianjinOne, disSbTianjinOne); + } + + //输出文件 + if (horSbTianjinOne.length() > 0) { + horSbTianjinOne.append("END"); + ExportStationMethod.save(horSbTianjinOne.toString(), periodFolder, "方向值.TXT"); + } else { + ExportStationMethod.save(" ", periodFolder, "方向值.TXT"); + } + if (verSbTianjinOne.length() > 0) { + ExportStationMethod.save(verSbTianjinOne.toString(), periodFolder, "垂直角.TXT"); + } else { + ExportStationMethod.save(" ", periodFolder, "垂直角.TXT"); + } + if (disSbTianjinOne.length() > 0) { + disSbTianjinOne.append("END"); + ExportStationMethod.save(disSbTianjinOne.toString(), periodFolder, "边长.TXT"); + } else { + ExportStationMethod.save(" ", periodFolder, "边长.TXT"); + } + } + } + + /** + * 根据项目列表导出测量数据,所有文件导出到一个zip文件中 + */ + @WorkerThread + private static File exportAllProject(Context context, Collection projects, ArrayList selectExportTypeList) { + List zipList = new ArrayList<>(); + for (Project project : projects) { + File zip = exportSingleProject(context, project, selectExportTypeList); + if (zip == null) { + continue; + } + zipList.add(zip); + } + //将文件存储到一个zip中 + File fileParent = Environment.getExternalStorageDirectory(); + File fileOutput = new File(fileParent, getExportFirstDirectory()); + if (!fileOutput.exists()) { + fileOutput.mkdir(); + } +// File fileOutput = PathManager.shareFolder(); + Date date = new Date(); + SimpleDateFormat format = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss", Locale.getDefault()); + String dateString = format.format(date); + File zip = new File(fileOutput, dateString + ".zip"); + if (!ZipUtil.zip(zip, zipList)) { + ToastUtils.showShort(R.string.export_failure); + zip = null; + } + //存储成功,删除被压缩的文件 + for (File file : zipList) { + if (file == null) { + continue; + } + try { + if (file.isDirectory()) { + FileUtils.delete(file); + } else if (file.isFile()) { + file.delete(); + } + } catch (Exception ignored) { + } + } + return zip; + } + + /** + * 根据项目列表导出测量数据,所有文件导出到一个zip文件中 + */ + @WorkerThread + private static File exportAllHeightTraverseProject(Context context, Collection projects) { + List zipList = new ArrayList<>(); + for (Project project : projects) { + File zip = exportSingleHeightTraverseProject(context, project); + if (zip == null) { + continue; + } + zipList.add(zip); + } + //将文件存储到一个zip中 + File fileParent = Environment.getExternalStorageDirectory(); + File fileOutput = new File(fileParent, getExportFirstDirectory()); + if (!fileOutput.exists()) { + fileOutput.mkdir(); + } +// File fileOutput = PathManager.shareFolder(); + Date date = new Date(); + SimpleDateFormat format = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss", Locale.getDefault()); + String dateString = format.format(date); + File zip = new File(fileOutput, dateString + ".zip"); + if (!ZipUtil.zip(zip, zipList)) { + ToastUtils.showShort(R.string.export_failure); + zip = null; + } + //存储成功,删除被压缩的文件 + for (File file : zipList) { + if (file == null) { + continue; + } + try { + if (file.isDirectory()) { + FileUtils.delete(file); + } else if (file.isFile()) { + file.delete(); + } + } catch (Exception ignored) { + } + } + return zip; + } + + /** + * 根据从UI收集的数据,执行导出操作,所有数据导出到一个zip文件中 + */ + @WorkerThread + public static File doExport(Context context, List exportItems, ArrayList selectExportTypeList) { + Collection projects = collect(exportItems); + return exportAllProject(context, projects, selectExportTypeList); + } + + /** + * 根据从UI收集的数据,执行导出操作,所有数据导出到一个zip文件中 + */ + @WorkerThread + public static File doExportHeightTraverse(Context context, List exportItems) { + Collection projects = collect(exportItems); + return exportAllHeightTraverseProject(context, projects); + } + + /** + * 导线文件导出 + * 一个项目测期的导线对应一个文件 + */ + @WorkerThread + public static List doExportWire(Context context, List exportItems, String exportFolder) { + List exportList = new ArrayList<>(); + if (exportItems == null || exportItems.isEmpty()) { + return exportList; + } + IProjectDataSource projectDataSource = SurveyorDatabaseFactory.instance.getProjectDataSource(); + IToleranceDetailDataSource toleranceDetailDataSource = SurveyorDatabaseFactory.instance.getToleranceDetailDataSource(); + ISurveyorStationDataSource surveyorStationDataSource = SurveyorDatabaseFactory.instance.getSurveyorStation(); + ISurveyorScheduleDataSource surveyorScheduleDataSource = SurveyorDatabaseFactory.instance.getScheduleDataSource(); + IPointDataSource pointDataSource = SurveyorDatabaseFactory.instance.getPointDataSource(); + ILineRecordDataSource lineRecordDatabase = SurveyorDatabaseFactory.instance.getLineRecordDatabase(); + + + //一个导线一个文件 + boolean isExportSuccess = false; + + for (ExportItem exportItem : exportItems) { + + //校验只能导出导线 + LineRecord lineRecord = lineRecordDatabase.findById(exportItem.stationId);//exportItem.stationId指的的线id + if (TextUtils.equals(lineRecord.type, LineRecord.TYPE_MUL_ANGLE)) { + continue; + } + + //exportItem.stationId这里的id是导线的id 为了复用之前的数据模型 + List stationRecordList = surveyorStationDataSource.getDataListByLine(exportItem.stationId); + + List unknowPointList = pointDataSource.getListByProjectId(exportItem.projectId, PointRecord.TYPE_UNKNOWN_POINT); + List knowPointList = pointDataSource.getListByProjectId(exportItem.projectId, PointRecord.TYPE_KNOWN_POINT); + + StringBuilder printSb = new StringBuilder(); + printSb.append("[PARA]"); + printSb.append(NEW_LINE); + + switch (lineRecord.type) { + case LineRecord.TYPE_LINE_SINGLE: + printSb.append("支导线,0,"); + break; + case LineRecord.TYPE_LINE_ATTACH: + printSb.append("附合导线,2,"); + break; + case LineRecord.TYPE_LINE_CLOSE: + printSb.append("闭合导线,1,"); + break; + case LineRecord.TYPE_LINE_RANDOM: + printSb.append("无定向导线,3,"); + break; + default: + break; + } + printSb.append(unknowPointList.size()); + printSb.append(NEW_LINE); + printSb.append("[CONTROL]"); + printSb.append(NEW_LINE); + + for (int i = 0; i < knowPointList.size(); i++) { + PointRecord knowPoint = knowPointList.get(i); + printSb.append(knowPoint.name + "," + + ExportStationMethod.getXyzFormat(knowPoint.getX()) + "," + + ExportStationMethod.getXyzFormat(knowPoint.getY()) + "," + + ExportStationMethod.getXyzFormat(knowPoint.getZ())); + printSb.append(NEW_LINE); + } + + printSb.append("[OBSER]"); + printSb.append(NEW_LINE); + + //遍历测站 + for (int i = 0; i < stationRecordList.size(); i++) { + SurveyorStationRecord stationRecord = stationRecordList.get(i); + + List items = stationRecord.getItems(); + + double stationDeviceHeight = SurveyorPoint.getDoubleValueFromString(stationRecord.instrumentHeight); + SurveyorPoint lookPoint = items.get(items.size() - 1); + double prismHeight = SurveyorPoint.getDoubleValueFromString(lookPoint.getPrismHeight()); + + PointRecord pointRecord = pointDataSource.findByIdSync(items.get(0).getPointId()); + + + ProjectRecord projectRecord = projectDataSource.getRecord(exportItem.projectId); + ToleranceDetailRecord toleranceRecord = toleranceDetailDataSource.getRecordSync(projectRecord.getToleranceId()); + + //创建缓存数据 + CachedData cachedData = + CachedData.newInstance(stationRecord.isAutoClose(), + stationRecord.isLeftAndRightSurveyor(), + stationRecord.getId(), toleranceRecord); + + + final double[] horAngle = new double[1]; + final double[] verAngle = new double[1]; + final double[] distance = new double[1]; + + SurveyorAdjustMethod.AdjustResult adjustResult = SurveyorAdjustMethod.calStationAdjust(stationRecord, cachedData); + if (TextUtils.isEmpty(adjustResult.errorString)) { + //展示结果数据 + //检测归零值是否为负,如果是需要+2PI + for (SurveyorAdjustMethod.Item item : adjustResult.result) { + if (item.getHorAngle() < 0) { + item.setHorAngle(Math.PI * 2 + item.getHorAngle()); + } + } + SurveyorAdjustMethod.Item item = adjustResult.result.get(adjustResult.result.size() - 1); + horAngle[0] = item.getHorAngle(); + verAngle[0] = item.getVerAngle(); + distance[0] = item.getDistance(); + } + + //水平角 保留5位小数 + String horAngleOutPut = Util.formatDouble2String(Util.radianToDmsDouble(horAngle[0]), ANGLE_DECIMALS); + + printSb + .append(pointRecord.getName()) + .append(","); + + + if (i == 0 || i != stationRecordList.size() - 1) { + //平距 + double horDistance = getHorDistance(verAngle[0], distance[0]); + String horDistanceOutput = Util.formatDouble2String(horDistance, ANGLE_DECIMALS); + //高差 + double altitudeDifference = getAltitudeDifference(verAngle[0], distance[0], stationDeviceHeight, prismHeight); + String altitudeDifferenceOutput = Util.formatDouble2String(altitudeDifference, ANGLE_DECIMALS); + + appendHorAngle(printSb, horAngleOutPut); + printSb + .append(",") + .append(horDistanceOutput) //斜距distance[0] 改为平距 + .append(",") + .append(altitudeDifferenceOutput) //高差 + .append(",") + .append(horDistanceOutput); //平距 + } else { + //最后一个 + if (TextUtils.equals(lineRecord.type, LineRecord.TYPE_LINE_CLOSE) + || TextUtils.equals(lineRecord.type, LineRecord.TYPE_LINE_ATTACH)) { + appendHorAngle(printSb, horAngleOutPut); + } + printSb.append(",,,"); + } + + printSb.append(NEW_LINE); + + if (TextUtils.equals(lineRecord.type, LineRecord.TYPE_LINE_SINGLE)) { + PointRecord pointRecordLast = pointDataSource.findByIdSync(items.get(2).getPointId()); + printSb.append(pointRecordLast.getName()) + .append(",,,,"); + printSb.append(NEW_LINE); + } + + + } + + printSb.append("[END]"); + + String absolutePath = Environment.getExternalStorageDirectory().getAbsolutePath(); + File fileDir = new File(absolutePath, exportFolder); + + String exportFirstName = exportItem.projectName + "_" + exportItem.cycleName + "_" + exportItem.stationName; + + String fileName = exportFirstName + ".dxp"; + fileName = fileName.replaceAll(":", "_"); +// FileUtil.writeString(printSb.toString(), new File(FileUtil.getSDPath()+"/234/"+fileName)); + + ExportStationMethod.save(printSb.toString(), fileDir, fileName); + + File fileHint = new File(fileDir, fileName); + if (fileHint.exists() && fileHint.length() > 0) { + //一个文件导出成功就算成功了 + exportList.add(fileHint); + isExportSuccess = true; + } + } + + return exportList; + + } + + /** + * 添加水平角 + * + * @param sb + * @param horAngleOutPut + */ + private static void appendHorAngle(StringBuilder sb, String horAngleOutPut) { + if (!TextUtils.isEmpty(horAngleOutPut) && !TextUtils.equals("0.00000", horAngleOutPut)) { + sb.append(horAngleOutPut); + } + } + + /** + * 返回平距 + * + * @param verAngle + * @param distance + * @return + */ + private static double getHorDistance(double verAngle, double distance) { + return Math.abs(distance * Math.cos(Math.PI / 2 - verAngle)); + } + + /** + * 返回高差 + * + * @param verAngle + * @param distance + * @param stationDeviceHeight + * @param prismHeight + * @return + */ + private static double getAltitudeDifference(double verAngle, double distance, double stationDeviceHeight, double prismHeight) { + return distance * Math.sin(Math.PI / 2 - verAngle) - prismHeight + stationDeviceHeight; + } + + static class Station { + final String stationId; + final String stationName; + + Station(String id, String name) { + stationId = id; + stationName = name; + } + } + + static class SurveyorPeriod { + final String periodId; + final String periodName; + final Map stationMap = new LinkedHashMap<>();//key stationId + + public SurveyorPeriod(String id, String name) { + periodId = id; + periodName = name; + } + } + + static class Project { + final String projectId; + final String projectType; + final String projectName; + final Map surveyorPeriodMap = new LinkedHashMap<>();//key 测期id + + public Project(String id, String projectType, String name) { + projectId = id; + this.projectType = projectType; + projectName = name; + } + } + + public static class ExportItem { + final String projectName; + final String projectId; + final String projectType; + final String cycleId; + final String cycleName; + final String stationId; + final String stationName; + final String stationPointName; + + public ExportItem(String projectName, String projectId, String projectType, + String cycleId, String cycleName, + String stationId, String stationName, String stationPointName) { + this.projectName = projectName; + this.projectId = projectId; + this.projectType = projectType; + this.cycleId = cycleId; + this.cycleName = cycleName; + this.stationId = stationId; + this.stationName = stationName; + this.stationPointName = stationPointName; + } + + @Override + public @NotNull String toString() { + return stationName; + } + } + + /** + * 获取天津导出的项目类型 + * + * @param projectType + * @return 0 三角 1 联系 3 高程 4 水准 + */ + public static int getProjectTypeForTianjin(String projectType) { + switch (projectType) { + case ProjectTypeValue.TRIANGLE: + return 0; + case ProjectTypeValue.CONNECTION: + return 1; + case ProjectTypeValue.HEIGHT_TRAVERSE: + return 2; + case ProjectTypeValue.LEVEL: + return 3; + default: + break; + } + return -1; + } + + /** + * 获取天津导出的点类型 + * + * @param pointType + * @return 0 已知点 1 未知点 + */ + public static int getPointTypeForTianjin(String pointType) { + switch (pointType) { + case PointRecord.TYPE_KNOWN_POINT: + case PointRecord.TYPE_GLOBAL_POINT: + return ExportContants.TYPE_KNOWN_POINT; + case PointRecord.TYPE_UNKNOWN_POINT: + return ExportContants.TYPE_UNKNOWN_POINT; + default: + break; + } + return -1; + } + + /** + * 格式化仪器高或者棱镜高 + * + * @param height + * @return + */ + private static String formatHeight(double height) { + return Tools.formatDouble2String(height, 3); + } + + public static boolean isCanExport() { + if (VipManager.getInstance().checkVipReg()) { + return true; + } + ToastUtils.showShort("您暂无使用权限,请联系客服"); + return false; + } + + /** + * 格式化仪器高或者棱镜高 + * + * @param distance + * @return + */ + public static String formatDistance(double distance) { + return Tools.formatDouble2String(distance, DISTANCE_DECIMALS); + } + + /** + * 格式化ppm + * + * @param distance + * @return + */ + public static String formatPPM(double distance) { + return Tools.formatDouble2String(distance, PPM_DECIMALS); + } + + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/method/SingleCycleTipsMethod.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/method/SingleCycleTipsMethod.java new file mode 100644 index 0000000..6d87248 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/method/SingleCycleTipsMethod.java @@ -0,0 +1,102 @@ +package com.bingce.controlnetwork.surveyor.method; + +import androidx.annotation.WorkerThread; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.point.IPointDataSource; +import com.bingce.controlapphelper.datasource.database.point.PointRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.ISurveyorStationDataSource; +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.model.SurveyorPoint; +import com.bingce.controlapphelper.surveyor.method.model.IStateDelegate; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.fragment.SelectReSurveyorPointFragment; +import com.bingce.utils.ThreadPoolUtil; + +import java.util.ArrayList; +import java.util.List; + +import com.bingce.controlnetwork.R; + +public class SingleCycleTipsMethod { + /* + * todo 如果没有对单测回内错误处理,后面该怎么办?? + * */ + public static void showTips(String msg, String stationId, + int currentCycleIndex, IStateDelegate delegate, + FragmentManager fragmentManager, LifecycleOwner lifecycleOwner) { + //取消 + delegate.onOptionTips(msg, + Tools.getString(R.string.retest_direction), + Tools.getString(R.string.retest_cycle), + () -> {//选择重测方向 + ThreadPoolUtil.execute(() -> reSurveyorPoint(stationId, delegate, + fragmentManager, lifecycleOwner)); + }, + () -> {//选择重测测回 + reSurveyorCycle(msg, stationId, currentCycleIndex, + delegate, fragmentManager, lifecycleOwner); + }, + delegate::resetSurveyorStateAndKeepPosition); + } + + @WorkerThread + private static void reSurveyorPoint(String stationId, IStateDelegate delegate, + FragmentManager fragmentManager, LifecycleOwner lifecycleOwner) { + //弹框提示选择重测数据 + ISurveyorStationDataSource dataSource = SurveyorDatabaseFactory.instance.getSurveyorStation(); + SurveyorStationRecord instance = dataSource.getRecordSync(stationId); + IPointDataSource pointDataSource = SurveyorDatabaseFactory.instance.getPointDataSource(); + List stationItems = instance.getItems(); + ArrayList ids = new ArrayList<>(); + ArrayList names = new ArrayList<>(); + for (SurveyorPoint item : stationItems) { + if (item.isAbandon()) { + continue; + } + + if (!SurveyorPoint.TYPE_POINT.equals(item.getType())) { + continue; + } + PointRecord pointRecord = pointDataSource.findByIdSync(item.getPointId()); + if (pointRecord == null) { + continue; + } + ids.add(pointRecord.id); + names.add(pointRecord.name); + } + ThreadPoolUtil.executeInMain(() -> SelectReSurveyorPointFragment.pick( + fragmentManager, + lifecycleOwner, + instance.leftAndRightSurveyor, + ids, + names, + (cycleIndex, pointIds) -> { + if (pointIds == null || pointIds.isEmpty()) { + //没有选择,退出 + delegate.resetSurveyorStateAndKeepPosition(); + } else { + delegate.resurveyPoints(cycleIndex, pointIds); + } + } + )); + } + + private static void reSurveyorCycle(String msg, String stationId, + int currentCycleIndex, IStateDelegate delegate, + FragmentManager fragmentManager, LifecycleOwner lifecycleOwner) { + delegate.onOptionTips(Tools.getString(R.string.tips_delete_current_cycle_surveyor_record), + null, null, + () -> { + delegate.deleteSingleCycleData(currentCycleIndex); + }, + () -> { + //循环显示 + showTips(msg, stationId, currentCycleIndex, delegate, + fragmentManager, lifecycleOwner); + }, + delegate::resetSurveyorStateAndKeepPosition); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/AutoModeType.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/AutoModeType.java new file mode 100644 index 0000000..9dc0e26 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/AutoModeType.java @@ -0,0 +1,10 @@ +package com.bingce.controlnetwork.surveyor.state; + +/** + * 自动测量相关的状态 + */ +public enum AutoModeType { + unknown,//未指定是否开启自动测量 + start,//开启了自动测量 + stop,//主动关闭了自动测量 +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/IScrollDelegate.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/IScrollDelegate.java new file mode 100644 index 0000000..907a77c --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/IScrollDelegate.java @@ -0,0 +1,10 @@ +package com.bingce.controlnetwork.surveyor.state; + +/** + * 测量过程中,将跳转到当前item处 + *

+ * 这个委托就是做这项任务 + */ +public interface IScrollDelegate { + void onScrollTo(int index); +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/StateConstants.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/StateConstants.java new file mode 100644 index 0000000..a1e1604 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/StateConstants.java @@ -0,0 +1,18 @@ +package com.bingce.controlnetwork.surveyor.state; + +public class StateConstants { + + /** + * measureWhat + */ + public static final int VALUE_MEASURE_WHAT_ANGLE_DISTANCE = 0;// 测角测距 + public static final int VALUE_MEASURE_WHAT_DISTANCE = 1;//单独测距 + + /** + * key 当前是否是旋转到位状态 + */ + public static final String KEY_IS_ROTATION_READY_STATE = "KEY_IS_ROTATION_READY_STATE"; + public static final String KEY_ROTATION_STATE_FROM_WHERE = "KEY_ROTATION_STATE_FROM_WHERE"; + public static final String ROTATION_STATE_FROM_WHERE_MEASURE = "1"; + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/StateManagerAloneDistance.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/StateManagerAloneDistance.java new file mode 100644 index 0000000..1d05490 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/StateManagerAloneDistance.java @@ -0,0 +1,498 @@ +package com.bingce.controlnetwork.surveyor.state.alonedistance; + +import android.content.Context; +import android.os.Bundle; + +import androidx.annotation.NonNull; +import androidx.annotation.WorkerThread; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.alonedistance.AloneDistanceRecord; +import com.bingce.controlapphelper.datasource.database.point.PointRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.model.SurveyorPoint; +import com.bingce.controlapphelper.datasource.database.tolerance.detail.ToleranceDetailRecord; +import com.bingce.controlapphelper.event.RefreshGoBackButtonAloneDistance; +import com.bingce.controlapphelper.model.LeftOrRight; +import com.bingce.controlapphelper.surveyor.data.CachedDataAloneDistance; +import com.bingce.controlapphelper.surveyor.data.ICycleRecorder; +import com.bingce.controlapphelper.surveyor.data.ISurveyorData; +import com.bingce.controlapphelper.surveyor.method.AutoSurveyorMethod; +import com.bingce.controlapphelper.surveyor.state.IAutoModeSwitcher; +import com.bingce.controlapphelper.surveyor.state.IStateType; +import com.bingce.controlapphelper.surveyor.state.ISurveyState; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlapphelper.surveyor.surveyor.ISurveyor; +import com.bingce.controlapphelper.surveyor.surveyor.ISurveyorListener; +import com.bingce.controlapphelper.surveyor.surveyor.ISurveyorRemindListener; +import com.bingce.controlapphelper.surveyor.surveyor.RequestSurveyorParamAuto; +import com.bingce.controlapphelper.surveyor.surveyor.SurveyorAutoImpl; +import com.bingce.controlapphelper.surveyor.surveyor.SurveyorMock; +import com.bingce.controlapphelper.surveyor.surveyor.SurveyorMockAuto; +import com.bingce.controlapphelper.surveyor.surveyor.SurveyorSingleImpl; +import com.bingce.controlapphelper.surveyor.test.Test; +import com.bingce.controlapphelper.util.DigitalUtil; +import com.bingce.controlapphelper.util.IUIRunner; +import com.bingce.controlapphelper.util.IdUtil; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.fragment.stationsurvey.angledistance.MeasureVm; +import com.bingce.controlnetwork.surveyor.state.AutoModeType; +import com.bingce.controlnetwork.surveyor.state.IScrollDelegate; +import com.bingce.controlnetwork.surveyor.state.StateConstants; +import com.bingce.coordlib.model.Coordinate; +import com.bingce.totalstation.ControlSurveyData; +import com.bingce.totalstation.ControlSurveyResult; +import com.bingce.utils.ThreadPoolUtil; +import com.bingce.utils.VipManager; + +import org.greenrobot.eventbus.EventBus; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import blankj.utilcode.util.ToastUtils; + +public class StateManagerAloneDistance implements IAutoModeSwitcher, ISurveyState, IStateType { + + //单独测距代码里的cycleIndex只有一个测回 + public static final int CYCLE_INDEX_DEFAULT = 0; + + private final Map stateMap = new HashMap<>(); + private StateType currentStateType = StateType.idle; + private final FragmentManager fragmentManager; + private final LifecycleOwner lifecycleOwner; + private final IUIRunner iuiRunner; + final IScrollDelegate scrollDelegate; + + @NonNull + SurveyorStationRecord stationRecord; + @NonNull + final CachedDataAloneDistance cachedData; + final @NonNull + ToleranceDetailRecord toleranceRecord; + final @NonNull + ISurveyorData surveyorData; + final @NonNull + MeasureVm measureVm; + final @NonNull + ICycleRecorder cycleRecorder; + final @NonNull + Context context; + private AutoModeType autoMode = AutoModeType.unknown; + @NonNull + final ISurveyor surveyor; + final PointRecord stationPointRecord; + + final boolean supportAutoSurvey; + + + private StateManagerAloneDistance(final boolean supportAutoSurvey,//是否支持自动测量 + final @NonNull SurveyorStationRecord stationRecord, + final @NonNull PointRecord stationPointRecord, + final @NonNull ToleranceDetailRecord toleranceRecord, + final @NonNull Context context, + final @NonNull ISurveyorData surveyorData, + final @NonNull ICycleRecorder cycleRecorder, + final @NonNull CachedDataAloneDistance cachedData, + final @NonNull MeasureVm measureVm, + final @NonNull IScrollDelegate scrollDelegate, + FragmentManager fragmentManager, + LifecycleOwner lifecycleOwner, + IUIRunner iuiRunner) { + this.supportAutoSurvey = supportAutoSurvey; + + this.stationRecord = stationRecord; + this.stationPointRecord = stationPointRecord; + this.fragmentManager = fragmentManager; + this.lifecycleOwner = lifecycleOwner; + this.iuiRunner = iuiRunner; + this.scrollDelegate = scrollDelegate; + + this.context = context; + this.toleranceRecord = toleranceRecord; + this.surveyorData = surveyorData; + this.cachedData = cachedData; + this.measureVm = measureVm; + this.cycleRecorder = cycleRecorder; + + if (Test.DEBUG) { + surveyor = new SurveyorMockAuto(StateConstants.VALUE_MEASURE_WHAT_DISTANCE, + this.stationRecord.getId(), + this.stationRecord.isAutoClose(), + toleranceRecord.getCycleCount(), + cachedData, surveyorData, cycleRecorder, this, this); + } else { + if (supportAutoSurvey) { + surveyor = new SurveyorAutoImpl(StateConstants.VALUE_MEASURE_WHAT_DISTANCE, this); + } else { + surveyor = new SurveyorSingleImpl(StateConstants.VALUE_MEASURE_WHAT_DISTANCE); + } + } + _DoSurveyorState doSurveyorState = new _DoSurveyorState(this, this); + surveyor.register((ISurveyorListener) doSurveyorState); + surveyor.register((ISurveyorRemindListener) doSurveyorState); + + stateMap.put(StateType.doSurveyor, doSurveyorState); + stateMap.put(StateType.doAutoSurveyor, new _DoAutoSurveyorState(this, this)); + stateMap.put(StateType.SurveyorFailure, new _SurveyorFailureState(this)); + stateMap.put(StateType.doMove2NextValidate, new _DoMove2NextValidateState(this)); + stateMap.put(StateType.doMoveBack, new _DoMoveBackState(this)); + stateMap.put(StateType.checkReadData, new _CheckReadDataState(this, this)); + stateMap.put(StateType.isSingleCycleCompleted, new _IsSingleCycleCompletedState(this)); + stateMap.put(StateType.isAllCycleCompleted, new _IsAllCycleCompletedState(this, this)); + stateMap.put(StateType.checkSingleCycle, new _CheckSingleCycleState(this)); + stateMap.put(StateType.checkStation, new _CheckStationState(this)); + stateMap.put(StateType.stationCheckedSuccess, new _CheckStationSuccessState(this)); + + stateMap.put(StateType.doDeleteAllCycle, new _DoDeleteAllCycleState(this)); + stateMap.put(StateType.doDeleteCurrentCycle, new _DoDeleteCurrentCycleState(this)); + + stateMap.put(StateType.doCalScheduleSingleCycle, new _DoCalScheduleInSingleCycleState(this, this)); + stateMap.put(StateType.doCalAdjust, new _DoCalAdjustState(this)); + stateMap.put(StateType.idle, new _IdleState(this, this)); + stateMap.put(StateType.doWellMeasureRotationReady, new _DoWellMeasureRotationReadyState(this)); + + } + + public void updateStationRecord(SurveyorStationRecord stationRecord) { + this.stationRecord = stationRecord; + ThreadPoolUtil.execute(() -> { + cachedData.updateDataSouce(stationRecord); + if (Test.DEBUG && surveyor instanceof SurveyorMock) { + ((SurveyorMock) surveyor).updateData(); + } + _DoCalScheduleInSingleCycleState.enter(this, CYCLE_INDEX_DEFAULT); + + //最后刷新下页面 + runOnUI(cachedData::notifyDateChange); + }); + +// //更新测点棱镜信息 +// if (stationRecord.getItems() != null) { +// for (SurveyorPoint item : stationRecord.getItems()) { +// if (item == null || !SurveyorPoint.TYPE_POINT.equals(item.getType())) { +// continue; +// } +// cachedData.updateSurveyPointParams(item); +// } +// } + } + + String stationId() { + return stationRecord.getId(); + } + + @Override + public void enter(StateType type, Bundle args) { + __BaseState baseState = stateMap.get(type); + if (baseState != null) { + this.currentStateType = type; + runOnUI(() -> baseState.enter(args)); + } + } + + @Override + public void enter(StateType type) { + enter(type, null); + } + + void runOnUI(Runnable action) { + if (iuiRunner != null) { + iuiRunner.runOnUI(action); + } + } + + public void doSurveyor() { + boolean inValidate = isInValidate(); + + if (inValidate) { + return; + } + + int pointCount = cachedData.pointCount(); + if (pointCount == 0) { + ToastUtils.showShort(R.string.no_data_available_yet); + return; + } + + Bundle bundle = null; + if (isRotationReadyState()) { + //当前是旋转到位状态 + bundle = new Bundle(); + bundle.putBoolean(StateConstants.KEY_IS_ROTATION_READY_STATE, true); + } + + enter(StateType.doSurveyor, bundle); + + } + + private boolean isRotationReadyState() { + return currentStateType == StateType.doWellMeasureRotationReady; + } + + public void doAutoSurveyor() { + if (isInValidate()) { + return; + } + enter(StateType.doAutoSurveyor); + } + + /** + * 删除站的所有测回记录 + */ + public void deleteCurrentStationSurveyorData() { + if (isInValidate()) { + return; + } + enter(StateType.doDeleteAllCycle, _DoDeleteAllCycleState.args(stationId())); + } + + public void deleteCurrentStationSurveyorData(int cycleIndex) { + if (isInValidate()) { + return; + } + enter(StateType.doDeleteCurrentCycle, _DoDeleteCurrentCycleState.args(stationId(), cycleIndex)); + } + + public void stationCheck() { + if (isInValidate()) { + return; + } + enter(StateType.checkStation); + } + + public void stationAdjust() { + if (isInValidate()) { + return; + } + enter(StateType.doCalAdjust); + } + + /** + * 切换测回时触发 + * + * @param cycleIndex + */ + public void switch2Cycle(int cycleIndex) { + //由于井定向的距离测量是不用切换测回的,在一个页面展示了两个测回 +// if (isInValidate()) { +// return; +// } +// _DoCalScheduleInSingleCycleState.enter(this, cycleIndex); + } + + /** + * 进入开始测量的时候触发 + * + * @param cycleIndex + */ + public void calScheduleWhenEnterSurveyFragment(int cycleIndex) { + if (isInValidate()) { + return; + } + _DoCalScheduleInSingleCycleState.enter(this, cycleIndex); + } + + public void moveBack() { + if (isInValidate()) { + return; + } + enter(StateType.doMoveBack); + } + + //检测当前状态是否支持从外界主动改变状态 + //如果是空闲或者是测站通过检测是有效的状态 + private boolean isInValidate() { + return currentStateType != StateType.idle + && StateType.stationCheckedSuccess != currentStateType + && !isRotationReadyState(); + } + + + FragmentManager fragmentManager() { + return this.fragmentManager; + } + + LifecycleOwner lifecycleOwner() { + return this.lifecycleOwner; + } + + final boolean isStationAutoClosed() { + return stationRecord.isAutoClose(); + } + + @WorkerThread + public static StateManagerAloneDistance newInstance( + boolean isSupportAutoMode, + @NonNull SurveyorStationRecord stationRecord, + @NonNull Context context, + @NonNull FragmentManager fragmentManager, + @NonNull LifecycleOwner lifecycleOwner, + @NonNull ToleranceDetailRecord toleranceRecord, + @NonNull ISurveyorData surveyorData, + @NonNull ICycleRecorder cycleRecorder, + @NonNull CachedDataAloneDistance cachedData, + @NonNull MeasureVm measureVm, + IScrollDelegate scrollDelegate, + IUIRunner runner) { + //读取测点record + String stationPointId = null; + if (stationRecord.getItems() != null) { + for (SurveyorPoint stationItem : stationRecord.getItems()) { + if (SurveyorPoint.TYPE_STATION.equals(stationItem.getType())) { + stationPointId = stationItem.getPointId(); + break; + } + } + } + PointRecord stationPointRecord = null; + if (stationPointId != null) { + stationPointRecord = SurveyorDatabaseFactory + .instance + .getPointDataSource() + .findByIdSync(stationPointId); + } + if (stationPointRecord == null) { + return null; + } + boolean supportAuto = Test.DEBUG; + //App.isDebug() + if (isSupportAutoMode && + (VipManager.getInstance().checkReg() || VipManager.getInstance().checkControlProLevel())) { + supportAuto = true; + } + StateManagerAloneDistance manager = new StateManagerAloneDistance(supportAuto, + stationRecord, + stationPointRecord, + toleranceRecord, + context, + surveyorData, + cycleRecorder, + cachedData, + measureVm, + scrollDelegate, + fragmentManager, lifecycleOwner, runner); + return manager; + } + + @Override + public boolean isAutoModeOpen() { + return autoMode == AutoModeType.start; + } + + @Override + public boolean isAutoModeClose() { + return autoMode == AutoModeType.stop; + } + + @Override + public boolean isAutoModeNotSpecial() { + return autoMode == AutoModeType.unknown; + } + + @Override + public void openAutoMode() { + autoMode = AutoModeType.start; + } + + @Override + public void closeAutoMode() { + autoMode = AutoModeType.stop; + } + + @Override + public void resetAutoMode() { + autoMode = AutoModeType.unknown; + } + + @Override + public int isReadyAutoSurvey() { + if (!supportAutoSurvey) { + return ControlSurveyResult.CODE_ERROR; + } + if (!surveyor.isReady()) { + return ControlSurveyResult.CODE_ERROR; + } + if (getRequestSurveyorParamAuto() == null) { + return ControlSurveyResult.CODE_ERROR; + } + + double instrumentHeight = getInsturmentHeight(); + Coordinate stationBasePoint = getStationCoord(); + + return getRequestSurveyorParamAuto().checkAutoCondition(getCachedData(), stationBasePoint, instrumentHeight); + } + + @Override + public String isMeasuredValueMatchDesign() { + if (!supportAutoSurvey) return null; + + double instrumentHeight = getInsturmentHeight(); + Coordinate stationBasePoint = getStationCoord(); + + List originMeasureList = getRequestSurveyorParamAuto().getOriginMeasureList(getCachedData()); + + return AutoSurveyorMethod.checkAutoSurveyorMeasuredValue(stationBasePoint, instrumentHeight, originMeasureList); + } + + @Override + public boolean isSurveying() { + return currentStateType == StateType.doSurveyor || currentStateType == StateType.doAutoSurveyor; + } + + @Override + public boolean isAutoSurveying() { + return isAutoModeOpen(); + } + + public void switchCurrentMeasurePosition(int position) { + if (currentStateType == StateType.idle) { + __BaseState baseState = stateMap.get(currentStateType); + if (baseState != null) { + baseState.setSurveyPosition(position, LeftOrRight.left); + } + } + } + + public CachedDataAloneDistance getCachedData() { + return cachedData; + } + + @NonNull + public ToleranceDetailRecord getToleranceRecord() { + return toleranceRecord; + } + + + private Coordinate getStationCoord() { + if (PointRecord.TYPE_KNOWN_POINT.equals(stationPointRecord.getPointType())) { + return new Coordinate( + stationPointRecord.getX(), + stationPointRecord.getY(), + stationPointRecord.getZ()); + } + return null; + } + + public double getInsturmentHeight() { + return DigitalUtil.valueOfDoubleString(stationRecord.getInstrumentHeight(), 0); + } + + public RequestSurveyorParamAuto getRequestSurveyorParamAuto() { + return measureVm.getRequestSurveyorParamAuto(); + } + + + public void refreshGoBackBtnEnable() { + CachedDataAloneDistance cachedData = getCachedData(); + int currentCycle = cycleRecorder.currentCycleIndex(); + String pointId = getCachedData().pointId(currentCycle, 0); + String cacheKey = IdUtil.createSurveyorRecordId(stationId(), currentCycle, pointId, LeftOrRight.left); + AloneDistanceRecord aloneDistanceRecord = cachedData.getAloneDistanceRecord(cacheKey); + boolean isRollBackBtnEnable = aloneDistanceRecord != null && !aloneDistanceRecord.distanceValues.isEmpty(); + EventBus.getDefault().post(new RefreshGoBackButtonAloneDistance(isRollBackBtnEnable)); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_CheckReadDataState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_CheckReadDataState.java new file mode 100644 index 0000000..6ab37f0 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_CheckReadDataState.java @@ -0,0 +1,75 @@ +package com.bingce.controlnetwork.surveyor.state.alonedistance; + +import android.os.Bundle; + +import com.bingce.controlapphelper.surveyor.state.IAutoModeSwitcher; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; + +import net.tatans.tensorflowtts.tts.TtsManager; + +/** + * 检测当前测量数据读数互差 + */ +class _CheckReadDataState extends __BaseState { + private static final int RESULT_SUCCESS = 0; + private static final int RESULT_FAILURE_HOR = 1; + private static final int RESULT_FAILURE_VER = 2; + private static final int RESULT_FAILURE_DISTANCE = 3; + private final IAutoModeSwitcher autoModeSwitcher; + + public _CheckReadDataState(StateManagerAloneDistance stateManager, IAutoModeSwitcher autoModeSwitcher) { + super(StateType.checkReadData, stateManager); + this.autoModeSwitcher = autoModeSwitcher; + } + + @Override + public void enter(Bundle args) { + //先检测测量值和设计值是否匹配(仅在自动测量打开下检测) + String error = autoModeSwitcher.isMeasuredValueMatchDesign(); + if (error != null) { + failureTipsWithAutoStandStill(error); + return; + } + + onCompleted(RESULT_SUCCESS); + } + + private void onCompleted(int result) { + if (RESULT_SUCCESS == result) { + navigation2(StateType.checkSingleCycle); + } else { + String msg = ""; + switch (result) { + case RESULT_FAILURE_HOR: + msg = Tools.getString(R.string.hor_angle_read_data_limit); + break; + case RESULT_FAILURE_VER: + msg = Tools.getString(R.string.ver_angle_read_data_limit); + break; + case RESULT_FAILURE_DISTANCE: + msg = Tools.getString(R.string.distance_read_data_limit); + break; + default: + navigation2(StateType.idle); + return; + } + if (isAutoSurveyOpen()) { + TtsManager.getInstance().speak(msg); + } + failureTipsWithAutoStandStill(msg); + } + } + + /** + * 斜距两次读数差 + * + * @param distance1 读数1 + * @param distance2 读数2 + * @return 读数差(单位毫米) + */ + public static double distanceReadDiff(double distance1, double distance2) { + return Math.abs(distance1 - distance2) * 1000; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_CheckSingleCycleState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_CheckSingleCycleState.java new file mode 100644 index 0000000..6e3d607 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_CheckSingleCycleState.java @@ -0,0 +1,90 @@ +package com.bingce.controlnetwork.surveyor.state.alonedistance; + +import android.os.Bundle; + +import com.bingce.controlapphelper.datasource.database.alonedistance.AloneDistanceRecord; +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.datasource.database.tolerance.detail.ToleranceDetailRecord; +import com.bingce.controlapphelper.model.LeftOrRight; +import com.bingce.controlapphelper.surveyor.data.CachedDataAloneDistance; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; + +import java.util.List; + +/** + * 测回内不同方向2c、方向i互差检测 + */ +class _CheckSingleCycleState extends __BaseState { + + public _CheckSingleCycleState(StateManagerAloneDistance stateManager) { + super(StateType.checkSingleCycle, stateManager); + } + + @Override + public void enter(Bundle args) { + doCheck(); + } + + private void doCheck() { + ToleranceDetailRecord toleranceRecord = getToleranceRecord(); + CachedDataAloneDistance cachedData = getCachedData(); + int surveyorCount = getSurveyorCount(); + int cycleIndex = getCycleRecorder().currentCycleIndex(); + int currentIndex = getCurrentIndex(); + double distCyclesDifference = toleranceRecord.getSlopeCycleDistanceDifference()/*slopeCycleDistanceDifference*/; + AloneDistanceRecord aloneDistanceRecord = getAloneDistanceRecord(currentIndex); + if (aloneDistanceRecord == null || aloneDistanceRecord.distanceValues.size() < surveyorCount * 2) { + //进入旋转到位状态等待点击继续测量 + navigation2(StateType.doWellMeasureRotationReady); + return; + } + + List valuesFirst = aloneDistanceRecord.distanceValues.subList(0, surveyorCount); + List valuesSecond = aloneDistanceRecord.distanceValues.subList(surveyorCount, surveyorCount * 2); + + + Double averageFirst = Tools.calculateCollectionDoubleAverage(valuesFirst); + Double averageSecond = Tools.calculateCollectionDoubleAverage(valuesSecond); + + double compareValue = Math.abs(averageFirst - averageSecond); + + if (compareValue * 1000 > distCyclesDifference) { + optionTips(Tools.getString(R.string.cycle_between_distance_limit) + distCyclesDifference, + Tools.getString(R.string.retest_cycle), + Tools.getString(R.string.retest_point), + () -> { + cachedData.deleteAloneDistanceRecord(stationId(), cycleIndex, currentIndex, LeftOrRight.left, true); + //更新进度 + setCurrentCycle(cycleIndex); + setSingleCycleSchedule(cycleIndex, SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + setAllCycleSchedule(SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + findTargetFromBeginInCurrentCycle(false); + }, + () -> { + //重测目标 + cachedData.deleteAloneDistanceRecord(stationId(), cycleIndex, currentIndex, LeftOrRight.left, false); + //更新进度 + setCurrentCycle(cycleIndex); + setSingleCycleSchedule(cycleIndex, SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + setAllCycleSchedule(SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + findTargetFromBeginInCurrentCycle(false); + }, + () -> { + enterIdleAndClearSurveyStateAndResetAutoMode(true); + }); + + } else { + onSuccess(); + } + } + + private void onSuccess() { + //更新测量进度 + setSingleCycleSchedule(getCycleRecorder().currentCycleIndex(), + SurveyorScheduleConstants.STATUE_VALUE_CHECKED); + //跳转 + navigation2(StateType.isSingleCycleCompleted); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_CheckStationState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_CheckStationState.java new file mode 100644 index 0000000..983335c --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_CheckStationState.java @@ -0,0 +1,195 @@ +package com.bingce.controlnetwork.surveyor.state.alonedistance; + +import android.os.Bundle; + +import com.bingce.controlapphelper.datasource.database.tolerance.detail.ToleranceDetailRecord; +import com.bingce.controlapphelper.surveyor.data.CachedDataAloneDistance; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlapphelper.util.SurveyorCycleUtil; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.utils.Util; + +import java.util.ArrayList; +import java.util.List; + +/** + * 执行「测站检测」 + *

+ * 前置条件: + * 所有测回都完成测量,并且通过「测回内检测」 + */ +public class _CheckStationState extends __BaseState { + + public _CheckStationState(StateManagerAloneDistance stateManager) { + super(StateType.checkStation, stateManager); + } + + @Override + public void enter(Bundle args) { + //执行测站检测 + String error = _stationCheckAloneDistance(stationId(), getToleranceRecord(), getCachedData()); + if (error == null || error.isEmpty()) { + //进入finish状态 + navigation2(StateType.stationCheckedSuccess); + } else { + failureTipsWithAutoStandStill(error); + } + } + + public static String _stationCheckAloneDistance(final String stationId, + final ToleranceDetailRecord toleranceRecord, + final CachedDataAloneDistance cachedDataSource) { + + final int cycleCount = ToleranceDetailRecord.ALONE_DISTANCE_CYCLE_COUNT; + final int surveyorCount = toleranceRecord.getSurveyorCount(); + + + //测回间斜距互差 + double distCyclesDifference = toleranceRecord.getSlopeCycleDistanceDifference()/*slopeCycleDistanceDifference*/; + List<_ErrorItem> distError = new ArrayList<>(); + + List<_Point> pointArrayList = new ArrayList<>(); + //遍历第一测回,收集所有待测点id + for (int index = 0; index < cachedDataSource.pointCount(); index++) { + pointArrayList.add(new _Point(cachedDataSource.pointId(0, index), cachedDataSource.pointName(0, index))); + } + // if (!distError.isEmpty()) { +// stringBuilder.append("测回间距离较差超限(限差:") +// .append(Util.formatDouble2String(distLimit, 1)) +// .append("'')"); +// for (_ErrorItem item : distError) { +// stringBuilder +// .append("\n ") +// .append(item.pointName) +// .append(":\n") +// .append(" |") +// .append(SurveyorCycleUtil.cycleName(item.cycleIndex1)) +// .append("-") +// .append(SurveyorCycleUtil.cycleName(item.cycleIndex2)) +// .append("| = ") +// .append(Util.formatDouble2String(item.difference, 1)) +// .append("'')"); +// } +// } + return ""; + } + + /** + * 根据超限信息生成错误描述 + * + * @param horValueError 水平角同方向值互差 + * @param verValueError 垂直角同方向值互差 + */ + private static String _errorString(double horLimit, double verLimit, double verILimit, double distLimit, + List<_ErrorItem> horValueError, List<_ErrorItem> verValueError, List<_ErrorItem> verIError, List<_ErrorItem> distError) { + if (horValueError.isEmpty() && verValueError.isEmpty()) { + return null; + } + StringBuilder stringBuilder = new StringBuilder(); + if (!horValueError.isEmpty()) { + stringBuilder.append(Tools.getString(R.string.cycle_between_same_direction_value_limit)) + .append(Util.formatDouble2String(horLimit, 1)) + .append("'')"); + for (_ErrorItem item : horValueError) { + stringBuilder + .append("\n ") + .append(item.pointName) + .append(":\n") + .append(" |") + .append(SurveyorCycleUtil.cycleName(item.cycleIndex1)) + .append("-") + .append(SurveyorCycleUtil.cycleName(item.cycleIndex2)) + .append("| = ") + .append(Util.formatDouble2String(item.difference, 1)) + .append("'')"); + } + } + + if (!verValueError.isEmpty()) { + stringBuilder.append("\n").append(Tools.getString(R.string.cycle_between_ver_angle_limit)) + .append(Util.formatDouble2String(verLimit, 1)) + .append("'')"); + for (_ErrorItem item : verValueError) { + stringBuilder + .append("\n ") + .append(item.pointName) + .append(":\n") + .append(" |") + .append(SurveyorCycleUtil.cycleName(item.cycleIndex1)) + .append("-") + .append(SurveyorCycleUtil.cycleName(item.cycleIndex2)) + .append("| = ") + .append(Util.formatDouble2String(item.difference, 1)) + .append("'')"); + } + } + + if (!verIError.isEmpty()) { + stringBuilder.append("\n").append(Tools.getString(R.string.ver_angle_i_same_direction_each_cycle)) + .append(Util.formatDouble2String(verILimit, 1)) + .append("'')"); + for (_ErrorItem item : verIError) { + stringBuilder + .append("\n ") + .append(item.pointName) + .append(":\n") + .append(" |") + .append(SurveyorCycleUtil.cycleName(item.cycleIndex1)) + .append("-") + .append(SurveyorCycleUtil.cycleName(item.cycleIndex2)) + .append("| = ") + .append(Util.formatDouble2String(item.difference, 1)) + .append("'')"); + } + } + + if (!distError.isEmpty()) { + stringBuilder.append("\n").append(Tools.getString(R.string.cycle_between_distance_limit_brackets)) + .append(Util.formatDouble2String(distLimit, 1)) + .append("'')"); + for (_ErrorItem item : distError) { + stringBuilder + .append("\n ") + .append(item.pointName) + .append(":\n") + .append(" |") + .append(SurveyorCycleUtil.cycleName(item.cycleIndex1)) + .append("-") + .append(SurveyorCycleUtil.cycleName(item.cycleIndex2)) + .append("| = ") + .append(Util.formatDouble2String(item.difference, 1)) + .append("'')"); + } + } + + return stringBuilder.toString(); + } + + /** + * 存储错误信息的item + */ + private static class _ErrorItem { + final String pointName; + final int cycleIndex1; + final int cycleIndex2; + final double difference; + + public _ErrorItem(String pointName, int cycleIndex1, int cycleIndex2, double difference) { + this.pointName = pointName; + this.cycleIndex1 = cycleIndex1; + this.cycleIndex2 = cycleIndex2; + this.difference = difference; + } + } + + private static class _Point { + final String pointId; + final String pointName; + + _Point(String pointId, String pointName) { + this.pointId = pointId; + this.pointName = pointName; + } + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_CheckStationSuccessState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_CheckStationSuccessState.java new file mode 100644 index 0000000..f120c55 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_CheckStationSuccessState.java @@ -0,0 +1,33 @@ +package com.bingce.controlnetwork.surveyor.state.alonedistance; + +import android.os.Bundle; + +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.surveyor.data.ISurveyorData; +import com.bingce.controlapphelper.surveyor.state.StateType; + +import net.tatans.tensorflowtts.tts.TtsManager; + +import com.bingce.controlnetwork.R; + +class _CheckStationSuccessState extends __BaseState { + + public _CheckStationSuccessState(StateManagerAloneDistance stateManager) { + super(StateType.stationCheckedSuccess, stateManager); + } + + @Override + public void enter(Bundle args) { + ISurveyorData surveyorData = getSurveyorData(); + surveyorData.clearSurveyStateAndPosition(); + //设置测量进度(数据库存储) + setAllCycleSchedule(SurveyorScheduleConstants.STATUE_VALUE_CHECKED); + //通知刷新 + tips(getContext().getString(R.string.tips_all_cycle_has_finish_and_checked), null); + if (isAutoSurveyOpen()) { + runOnUI(() -> TtsManager.getInstance().speak(getContext().getString(R.string.tips_all_cycle_has_finish_and_checked))); + } + //清除测量状态,进入idle,停止自动测量 + enterIdleAndClearSurveyStateAndResetAutoMode(true); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_DoAutoSurveyorState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_DoAutoSurveyorState.java new file mode 100644 index 0000000..2ca12da --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_DoAutoSurveyorState.java @@ -0,0 +1,32 @@ +package com.bingce.controlnetwork.surveyor.state.alonedistance; + +import android.os.Bundle; + +import com.bingce.controlapphelper.surveyor.state.IAutoModeSwitcher; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.totalstation.ControlSurveyResult; + +import net.tatans.tensorflowtts.tts.TtsManager; + +/** + * 先检测是否有其他未完成测回,继续本次测量将删除其他测回数据 + */ +class _DoAutoSurveyorState extends __BaseState { + private final IAutoModeSwitcher autoModeSwitcher; + + public _DoAutoSurveyorState(StateManagerAloneDistance stateManager, IAutoModeSwitcher autoModeSwitcher) { + super(StateType.doAutoSurveyor, stateManager); + this.autoModeSwitcher = autoModeSwitcher; + } + + @Override + public void enter(Bundle args) { + if (autoModeSwitcher.isReadyAutoSurvey() == ControlSurveyResult.CODE_SUCCESS) { + autoModeSwitcher.openAutoMode(); + navigation2(StateType.doMove2NextValidate); + TtsManager.getInstance().speak(Tools.getString(R.string.start_auto_measure)); + } + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_DoCalAdjustState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_DoCalAdjustState.java new file mode 100644 index 0000000..e62f793 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_DoCalAdjustState.java @@ -0,0 +1,74 @@ +package com.bingce.controlnetwork.surveyor.state.alonedistance; + +import android.content.Context; +import android.os.Bundle; + +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleRecord; +import com.bingce.controlapphelper.surveyor.data.CachedDataAloneDistance; +import com.bingce.controlapphelper.surveyor.method.SurveyorAdjustMethod; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlnetwork.fragment.StationDataAdjustDialogFragment; +import com.bingce.controlnetwork.fragment.TipsFragment; +import com.bingce.utils.ThreadPoolUtil; + +import java.util.ArrayList; + +/** + * 平差计算 + */ +public class _DoCalAdjustState extends __BaseState { + + public _DoCalAdjustState(StateManagerAloneDistance stateManager) { + super(StateType.doCalAdjust, stateManager); + } + + @Override + public void enter(Bundle args) { + + } + + public static void doCalAdjust(String stationId, CachedDataAloneDistance cachedData, Context context, FragmentManager fragmentManager + , LifecycleOwner lifecycleOwner) { + ThreadPoolUtil.execute(() -> { + SurveyorAdjustMethod.calAloneDistance( + stationId, cachedData, new SurveyorAdjustMethod.ICallback() { + @Override + public void onGet(ArrayList finalItemList, Boolean isShowSlopDistance) { +// //清除测量状态,进入idle,停止自动测量 +// enterIdleAndClearSurveyStateAndResetAutoMode(true); + //展示结果数据 + //检测归零值是否为负,如果是需要+2PI + for (SurveyorAdjustMethod.Item item : finalItemList) { + if (item.getHorAngle() < 0) { + item.setHorAngle(Math.PI * 2 + item.getHorAngle()); + } + } + StationDataAdjustDialogFragment.showDialog(StationDataAdjustDialogFragment.TYPE_ALONE_DISTANCE, finalItemList, isShowSlopDistance, fragmentManager); + } + + @Override + public void onFailure(String error) { + ThreadPoolUtil.executeInMain(() -> { + TipsFragment.tipsOnly(fragmentManager, lifecycleOwner, context, error); + }); + } + }); + + //伴随平差 设置进度为通过检测 + SurveyorDatabaseFactory + .instance + .getScheduleDataSource() + .record( + new SurveyorScheduleRecord( + SurveyorScheduleConstants.getAllCycleScheduleKey(stationId, SurveyorScheduleConstants.SCHEDULE_OR_CYCLE_TYPE_ALONE_DISTANCE), + SurveyorScheduleConstants.STATUE_VALUE_CHECKED)); + + }); + + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_DoCalScheduleInSingleCycleState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_DoCalScheduleInSingleCycleState.java new file mode 100644 index 0000000..ff1e497 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_DoCalScheduleInSingleCycleState.java @@ -0,0 +1,108 @@ +package com.bingce.controlnetwork.surveyor.state.alonedistance; + +import android.os.Bundle; + +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.event.SurveyStateEvent; +import com.bingce.controlapphelper.surveyor.data.ICycleRecorder; +import com.bingce.controlapphelper.surveyor.state.IAutoModeSwitcher; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlnetwork.fragment.stationsurvey.angledistance.MeasureFragment; + +import com.bingce.controlnetwork.fragment.stationsurvey.angledistance.MeasureFragment; + +/** + * 在单个测回内计算当前测量进度。 + *

+ * 1.如果有没有完成测量,则跳转到相应位置。 + * 2.如果测量完成,检测数据限差 + * 3.进入idle + */ +class _DoCalScheduleInSingleCycleState extends __BaseState { + private final IAutoModeSwitcher autoModeSwitcher; + + public _DoCalScheduleInSingleCycleState(StateManagerAloneDistance stateManager, IAutoModeSwitcher autoModeSwitcher) { + super(StateType.doCalScheduleSingleCycle, stateManager); + this.autoModeSwitcher = autoModeSwitcher; + } + + @Override + final public void enter(Bundle args) { + + int pointCount = getCachedData().pointCount(); + if (pointCount == 0) { + postBtnEvent(); + return; + } + + //重置自动测量状态 + if (autoModeSwitcher.isAutoModeClose()) { + autoModeSwitcher.resetAutoMode(); + } + //计算状态之前,重置测量状态 + getSurveyorData().clearSurveyStateAndPosition(); + + ICycleRecorder cycleRecorder = getCycleRecorder(); + cycleRecorder.changeCycleIndex(args.getInt(KEY_CYCLE_INDEX, 0)); + setCurrentCycle(cycleRecorder.currentCycleIndex()); + + //1.检测当前cycle是否完成测量 + boolean completed = _IsSingleCycleCompletedState.isSingleCycleCompleted( + stationId(), + getCycleRecorder().currentCycleIndex(), + getCachedData(), getSurveyorCount()); + //2.如果当前测回还有待测数据,则执行测量 + if (!completed) { + //从当前测回开始处查找目标并执行测量 + findTargetFromBeginInCurrentCycle(false); + return; + } + //3.如果当前测回结束测量,判断是否通过检测 +// ToleranceDetailRecord toleranceDetailRecord = getToleranceRecord(); +// double horCycle2CDiff = toleranceDetailRecord.getHorCycleDirect2CDifference(); +// double verCycle2CDiff = toleranceDetailRecord.getVerCycleDirectIDifference(); +// String error = SingleCycleCheckMethod.check( +// horCycle2CDiff, +// verCycle2CDiff, +// stationId(), +// getCycleRecorder().currentCycleIndex(), +// getSurveyorData(), +// getCachedData()); +// if (error != null && !error.isEmpty()) { +// SingleCycleTipsMethod.showTips(error, +// stationId(), +// getCycleRecorder().currentCycleIndex(), +// stateDelegate(), +// fragmentManager(), +// lifecycleOwner()); +// return; +// } + //4.更新测站状态,在当前测回经过检测 + setSingleCycleSchedule(getCycleRecorder().currentCycleIndex(), + SurveyorScheduleConstants.STATUE_VALUE_CHECKED); + + //6.清空测量状态 + onCompletedCheck(); + } + + protected void onCompletedCheck() { + enterIdleAndClearSurveyStateAndResetAutoMode(true); + } + + protected static final String KEY_CYCLE_INDEX = "___cycle__index__"; + + static void enter(StateManagerAloneDistance stateManager, int cycleIndex) { + Bundle args = new Bundle(); + args.putInt(KEY_CYCLE_INDEX, cycleIndex); + stateManager.enter(StateType.doCalScheduleSingleCycle, args); + } + + private void postBtnEvent() { + int pointCount = getCachedData().pointCount(); + if (pointCount == 0) { + SurveyStateEvent.postCompleted(MeasureFragment.POSITION_DISTANCE_MEASURE); + } else { + SurveyStateEvent.postIdle(MeasureFragment.POSITION_DISTANCE_MEASURE); + } + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_DoDeleteAllCycleState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_DoDeleteAllCycleState.java new file mode 100644 index 0000000..1e49e92 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_DoDeleteAllCycleState.java @@ -0,0 +1,63 @@ +package com.bingce.controlnetwork.surveyor.state.alonedistance; + +import android.os.Bundle; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.config.ConfigConstants; +import com.bingce.controlapphelper.datasource.database.config.IConfigDataSource; +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.utils.ThreadPoolUtil; + +import com.bingce.controlnetwork.R; + +/** + * 删除本测站所有测回数据 + * 对于钢丝测距 所有两测回数据都在一个view里显示了,不用切换 + */ +class _DoDeleteAllCycleState extends __BaseState { + + private static final String KEY_STATION_ID = "__station_id"; + + static Bundle args(String stationId) { + Bundle args = new Bundle(); + args.putString(KEY_STATION_ID, stationId); + return args; + } + + public _DoDeleteAllCycleState(StateManagerAloneDistance stateManager) { + super(StateType.doDeleteAllCycle, stateManager); + } + + @Override + public void enter(Bundle args) { + String stationId = args.getString(KEY_STATION_ID); + + optionTipsWithStandStill(getContext().getString(R.string.tips_delete_station_all_surveyor_records), + () -> deleteAllCycleData(stationId)); + } + + private void deleteAllCycleData(String stationId) { + ThreadPoolUtil.execute(() -> { + //删除数据 + getCachedData().deleteAloneDistanceRecord(stationId); + + //清除已经提示测站可以检测标识 + IConfigDataSource configDataSource = + SurveyorDatabaseFactory.instance.getConfigDataSource(); + String key = ConfigConstants.KEY_CONFIG_STATION_CHECK_REMINDED + stationId; + configDataSource.setSync(key, ConfigConstants.VALUE_NO); + + //重置所有测回进度 + setAllCycleScheduleSync(SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + setSingleCycleScheduleSync(cycleIndexDefault, SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + + //从第一测回开始 + setCurrentCycle(cycleIndexDefault); + //重新测量,并刷新 + findTargetFromBeginInCurrentCycle(true); + }); + } + + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_DoDeleteCurrentCycleState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_DoDeleteCurrentCycleState.java new file mode 100644 index 0000000..0c07e34 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_DoDeleteCurrentCycleState.java @@ -0,0 +1,55 @@ +package com.bingce.controlnetwork.surveyor.state.alonedistance; + +import android.os.Bundle; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.config.ConfigConstants; +import com.bingce.controlapphelper.datasource.database.config.IConfigDataSource; +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.surveyor.state.StateType; + +import com.bingce.controlnetwork.R; + +class _DoDeleteCurrentCycleState extends __BaseState { + public _DoDeleteCurrentCycleState(StateManagerAloneDistance stateManager) { + super(StateType.doDeleteCurrentCycle, stateManager); + } + + @Override + public void enter(Bundle args) { + String stationId = args.getString(KEY_STATION_ID); + int cycleIndex = args.getInt(KEY_PERIOD_INDEX); + + optionTipsWithStandStill(getContext().getString(R.string.tips_delete_current_cycle_surveyor_record), + () -> { + //删除数据 + getCachedData().deleteAloneDistanceRecord(stationId, cycleIndex); + + //清除已经提示测站可以检测标识 + IConfigDataSource configDataSource = + SurveyorDatabaseFactory.instance.getConfigDataSource(); + String key = ConfigConstants.KEY_CONFIG_STATION_CHECK_REMINDED + stationId; + configDataSource.set(key, ConfigConstants.VALUE_NO); + + //重置进度 + //当前测回 + setCurrentCycle(cycleIndex); + //所有测回未完成 + setAllCycleSchedule(SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + //单个测回未完成 + setSingleCycleSchedule(cycleIndex, SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + //重新测量,并刷新 + findTargetFromBeginInCurrentCycle(true); + }); + } + + private static final String KEY_STATION_ID = "__station_id"; + private static final String KEY_PERIOD_INDEX = "__period_index__"; + + static Bundle args(String stationId, int periodIndex) { + Bundle args = new Bundle(); + args.putString(KEY_STATION_ID, stationId); + args.putInt(KEY_PERIOD_INDEX, periodIndex); + return args; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_DoMove2NextValidateState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_DoMove2NextValidateState.java new file mode 100644 index 0000000..c0cff3c --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_DoMove2NextValidateState.java @@ -0,0 +1,72 @@ +package com.bingce.controlnetwork.surveyor.state.alonedistance; + +import android.os.Bundle; + +import com.bingce.controlapphelper.model.LeftOrRight; +import com.bingce.controlapphelper.surveyor.data.CachedDataAloneDistance; +import com.bingce.controlapphelper.surveyor.data.ICycleRecorder; +import com.bingce.controlapphelper.surveyor.data.ISurveyorData; +import com.bingce.controlapphelper.surveyor.method.FindTargetMethod; +import com.bingce.controlapphelper.surveyor.state.StateType; + +/** + * 移动到一个待测量位置 + *

+ * 不会跳转到其他测期 + *

+ * 可能涉及转向(盘左->盘右) + */ +class _DoMove2NextValidateState extends __BaseState { + + public _DoMove2NextValidateState(StateManagerAloneDistance stateManager) { + super(StateType.doMove2NextValidate, stateManager); + } + + @Override + public void enter(Bundle args) { + CachedDataAloneDistance cachedData = getCachedData(); + ISurveyorData surveyorData = getSurveyorData(); + ICycleRecorder cycleRecorder = getCycleRecorder(); + + int pointCount = cachedData.pointCount(); + int currentIndex = surveyorData.currentIndex(); + if (currentIndex < 0) { + currentIndex = 0; + } + final int currentCycleIndex = cycleRecorder.currentCycleIndex(); + final LeftOrRight currentSurveyorState = surveyorData.leftOrRight(); + + + FindTargetMethod.Target needMeasureForAloneDistanceTarget = FindTargetMethod.findNeedMeasureTargetInSingleCycleForAloneDistance(stationId(), currentCycleIndex, + currentIndex, + currentSurveyorState, + pointCount, + true, + cachedData); + + if (needMeasureForAloneDistanceTarget != null) { + navigation2(needMeasureForAloneDistanceTarget.itemIndex, needMeasureForAloneDistanceTarget.leftOrRight); + return; + } + + + //3.当前测回完成测量,停留状态 + //重置标识 + enterIdleAndClearSurveyorStatePosition(); + } + + /** + * 跳转到下一目标点 + * + * @param targetIndex 目标点索引 + * @param targetSurveyorState 测量状态(盘左or盘右) + */ + private void navigation2(int targetIndex, LeftOrRight targetSurveyorState) { + //更新测量进度 + setSurveyPosition(targetIndex, targetSurveyorState); + //清除测量状态,进入idle,但是不停止自动测量 + enterIdleAndClearSurveyStateAndResetAutoMode(false); + //滚动 + scroll2(targetIndex); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_DoMoveBackState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_DoMoveBackState.java new file mode 100644 index 0000000..0f87315 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_DoMoveBackState.java @@ -0,0 +1,85 @@ +package com.bingce.controlnetwork.surveyor.state.alonedistance; + +import android.os.Bundle; + +import com.bingce.controlapphelper.datasource.database.alonedistance.AloneDistanceRecord; +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.model.LeftOrRight; +import com.bingce.controlapphelper.surveyor.data.CachedDataAloneDistance; +import com.bingce.controlapphelper.surveyor.data.ICycleRecorder; +import com.bingce.controlapphelper.surveyor.data.ISurveyorData; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; + +import blankj.utilcode.util.ToastUtils; + +/** + * 移动到上一测量结点,伴随删除上次测量数据 + */ +public class _DoMoveBackState extends __BaseState { + + public _DoMoveBackState(StateManagerAloneDistance stateManager) { + super(StateType.doMoveBack, stateManager); + } + + @Override + public void enter(Bundle args) { + CachedDataAloneDistance cachedDataSource = getCachedData(); + ISurveyorData surveyorDataSource = getSurveyorData(); + ICycleRecorder cycleRecorder = getCycleRecorder(); + + final int pointCount = cachedDataSource.pointCount(); + final int currentCycle = cycleRecorder.currentCycleIndex(); + final int currentIndex = surveyorDataSource.currentIndex(); + final LeftOrRight leftOrRight = surveyorDataSource.leftOrRight(); + + int targetIndex = currentIndex; + if (targetIndex < 0) { + //如果测量结束,直接使用0号点盘右 + targetIndex = pointCount - 1; + } + warningWithStandStill(cachedDataSource, currentCycle, targetIndex, LeftOrRight.left); + } + + private void warningWithStandStill( + CachedDataAloneDistance cachedDataSource, + int currentCycle, int itemIndex, LeftOrRight leftOrRight) { + optionTipsWithStandStill(Tools.getString(R.string.roll_back_node_data), + () -> { + //删除当前数据 + int nextSurveyorPointIndex = cachedDataSource.deleteAloneDistanceRecord(stationId(), + currentCycle, itemIndex, leftOrRight, true); + + if (nextSurveyorPointIndex == -1) { + ToastUtils.showShort(R.string.roll_back_failed); + navigation2(StateType.idle); + return; + } + + AloneDistanceRecord aloneDistanceRecord = getAloneDistanceRecord(nextSurveyorPointIndex); + if (aloneDistanceRecord != null && aloneDistanceRecord.distanceValues.size() == getSurveyorCount()) { + navigation2(StateType.doWellMeasureRotationReady); + } else { + navigation2(StateType.idle); + } + + //重置进度 + setCurrentCycle(nextSurveyorPointIndex); + setSingleCycleSchedule(currentCycle, SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + setAllCycleSchedule(SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + + resetSchedule(this, nextSurveyorPointIndex, leftOrRight); + }); + } + + private void resetSchedule(__BaseState state, + int targetIndex, + LeftOrRight leftOrRight) { + //设置测量目标点 + state.setSurveyPosition(targetIndex, leftOrRight); + + state.scroll2(targetIndex); + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_DoSurveyorState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_DoSurveyorState.java new file mode 100644 index 0000000..d02be7c --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_DoSurveyorState.java @@ -0,0 +1,181 @@ +package com.bingce.controlnetwork.surveyor.state.alonedistance; + +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; + +import com.bingce.controlapphelper.datasource.database.alonedistance.AloneDistanceRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.model.SurveyorPoint; +import com.bingce.controlapphelper.event.SurveyStateEvent; +import com.bingce.controlapphelper.surveyor.data.ISurveyorData; +import com.bingce.controlapphelper.surveyor.state.ISurveyState; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlapphelper.surveyor.surveyor.ISurveyorListener; +import com.bingce.controlapphelper.surveyor.surveyor.ISurveyorRemindListener; +import com.bingce.controlapphelper.surveyor.surveyor.RequestSurveyorParam; +import com.bingce.controlapphelper.util.DebugMsgUtil; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.surveyor.state.StateConstants; +import com.bingce.device.Device; +import com.bingce.totalstation.TotalStation; +import com.bingce.totalstation.protocol.south.SouthAndroidBtInterface; +import com.bingce.totalstation.protocol.topcon.TopconInterface; + +import net.tatans.tensorflowtts.tts.TtsManager; + +import blankj.utilcode.util.ToastUtils; +import blankj.utilcode.util.Utils; + +/** + * 先检测是否有其他未完成测回,继续本次测量将删除其他测回数据 + */ +class _DoSurveyorState extends __BaseState implements ISurveyorListener, ISurveyorRemindListener { + private final ISurveyState surveyState; + //最多测量次数,如果5次测量都没有获取正常数据,则跳过 + private static final int MAX_SURVEYOR_COUNT = 3; + private static int failureCount = 0; + private static final int RESULT_SUCCESS = 0; + private static final int RESULT_FAILURE_EXCEED_MAX = 1;//测量失败次数超出最大限制 + private static final int RESULT_FAILURE_ERROR = 2;//测量失败,又没有允许重复尝试 + private static final boolean allowTryWhenFailure = true;//在测量失败的时候,是否允许重新测量 + + private int measureTimeIndex = 0; + private boolean isAlreadyRemindUserAimingAtWire = false; + + private final Handler handler; + + public _DoSurveyorState(StateManagerAloneDistance stateManager, ISurveyState surveyState) { + super(StateType.doSurveyor, stateManager); + this.surveyState = surveyState; + handler = new Handler(Looper.getMainLooper()); + } + + @Override + public void enter(Bundle args) { + measureTimeIndex = 0; + + isAlreadyRemindUserAimingAtWire = false; + if (args != null) { + isAlreadyRemindUserAimingAtWire = args.getBoolean(StateConstants.KEY_IS_ROTATION_READY_STATE); + } + + //3.其他测回没有正在测量数据,则在当前测回执行测量 + doSurveyor(); + } + + private void doSurveyor() { + failureCount = 0; + //判断设备是否连接 + if (surveyorImpl().isReady()) { + //发送测量信号 + SurveyStateEvent.postSurveying(positionFragment); + //注册接收测量数据 + surveyorImpl().prepareSurveyor(); + sendSurveyRequest(); + } else { + enterIdleAndClearSurveyStateAndResetAutoMode(true); + Device.getInstance().remindConnectDevice(); + } + } + + @Override + public void onReceive(double originalHa, double originalVa, double sd, double clockwiseHa, double topVa, double hd, double vd) { + //重置错误读数 + failureCount = 0; + AloneDistanceRecord aloneDistanceRecord + = getCachedData().cacheAloneDistance(stationId(), StateManagerAloneDistance.CYCLE_INDEX_DEFAULT, getCurrentIndex(), sd, hd); + + //刷新页面 + refreshUI(); + int surveyorCount = getCachedData().getSurveyorCount(); + if (aloneDistanceRecord.distanceValues.size() == surveyorCount) { + ToastUtils.showShort(Utils.getApp().getString(R.string.alone_distance_first_round_measure_finish)); + onSuccess(); + } else if (aloneDistanceRecord.distanceValues.size() >= surveyorCount * 2) { + onSuccess(); + } else { + //当数据不够的时候 继续发送指令 + measureTimeIndex++; + if (TotalStation.getInstance() instanceof TopconInterface) { + //这个仪器需要延迟500毫秒发送指令 + handler.postDelayed(this::sendSurveyRequest, 500); + } else if (TotalStation.getInstance() instanceof SouthAndroidBtInterface) { + handler.postDelayed(this::sendSurveyRequest, 100); + } else { + sendSurveyRequest(); + } + } + } + + @Override + public void onError(String errorMsg) { + TtsManager.getInstance().speak(errorMsg); + if (allowTryWhenFailure) {//允许重新测量 + //测量出现异常,需要处理 + failureCount++; + if (failureCount >= MAX_SURVEYOR_COUNT) { + if (isAutoSurveyOpen()) { + TtsManager.getInstance().speak(Tools.getString(R.string.many_measure_failed)); + } + onCompleted(RESULT_FAILURE_EXCEED_MAX, Tools.getString(R.string.many_measure_failed_1)); + } else { + //再次尝试 + DebugMsgUtil.canWrite("仪器返回错误信息:" + errorMsg); + DebugMsgUtil.canWrite("开始再次测量"); + + sendSurveyRequest(); + ToastUtils.showShort(R.string.receive_data_time_out); + } + } else { + onCompleted(RESULT_FAILURE_ERROR, errorMsg); + } + } + + private void sendSurveyRequest() { + SurveyorPoint surveyorPoint = getCachedData().getSurveyorPoint(getCycleRecorder().currentCycleIndex(), getCurrentIndex()); + + ISurveyorData surveyorData = getSurveyorData(); + int measureTimeIndex = 0; + surveyorImpl().requestSurveyor(new RequestSurveyorParam(getRequestSurveyorParamAuto(), getInsturmentHeight(), surveyorPoint, measureTimeIndex, + surveyorData.currentIndex(), surveyorData.leftOrRight(), isAlreadyRemindUserAimingAtWire)); + } + + private void onSuccess() { + onCompleted(RESULT_SUCCESS, ""); + } + + private void onCompleted(int result, String msg) { + //退出测量 + surveyorImpl().exitSurveyor(); + switch (result) { + case RESULT_SUCCESS://进入读数检测状态 + //检测是否处于「自动测量」 + if (!surveyState.isAutoSurveying()) { + SurveyStateEvent.postSuccess(positionFragment); + } + navigation2(StateType.checkReadData); + break; + case RESULT_FAILURE_EXCEED_MAX: + case RESULT_FAILURE_ERROR: { + SurveyStateEvent.postFailure(positionFragment); + //进入失败状态 + Bundle args = _SurveyorFailureState.args(msg); + navigation2(StateType.SurveyorFailure, args); + } + break; + default: + throw new RuntimeException("un reached state -- surveyor"); + } + } + + @Override + public void remindUserAimingAtWire() { + //退出测量 + surveyorImpl().exitSurveyor(); + + Bundle bundle = new Bundle(); + bundle.putString(StateConstants.KEY_ROTATION_STATE_FROM_WHERE, StateConstants.ROTATION_STATE_FROM_WHERE_MEASURE); + navigation2(StateType.doWellMeasureRotationReady, bundle); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_DoWellMeasureRotationReadyState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_DoWellMeasureRotationReadyState.java new file mode 100644 index 0000000..be6c86a --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_DoWellMeasureRotationReadyState.java @@ -0,0 +1,41 @@ +package com.bingce.controlnetwork.surveyor.state.alonedistance; + +import android.os.Bundle; +import android.text.TextUtils; + +import com.bingce.controlapphelper.event.AutoSurveyorButtonVisibleEvent; +import com.bingce.controlapphelper.event.SurveyStateEvent; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.surveyor.state.StateConstants; + +import net.tatans.tensorflowtts.tts.TtsManager; + +import org.greenrobot.eventbus.EventBus; + +import com.bingce.controlnetwork.surveyor.state.StateConstants; + +/** + * 钢丝测量旋转到位状态 + */ +class _DoWellMeasureRotationReadyState extends __BaseState { + + public _DoWellMeasureRotationReadyState(StateManagerAloneDistance stateManager) { + super(StateType.doWellMeasureRotationReady, stateManager); + } + + @Override + public void enter(Bundle args) { + if (args != null) { + String fromWhere = args.getString(StateConstants.KEY_ROTATION_STATE_FROM_WHERE); + if (TextUtils.equals(fromWhere, StateConstants.ROTATION_STATE_FROM_WHERE_MEASURE)) { + runOnUI(() -> TtsManager.getInstance().speak(getContext().getString(R.string.please_aiming_at_alone_distance_point_then_measure))); + } + } + //更新回退按钮状态 + refreshGoBack(); + SurveyStateEvent.postIdle(positionFragment); + EventBus.getDefault().post(new AutoSurveyorButtonVisibleEvent(positionFragment, false, true)); + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_IdleState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_IdleState.java new file mode 100644 index 0000000..4fa88a0 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_IdleState.java @@ -0,0 +1,64 @@ +package com.bingce.controlnetwork.surveyor.state.alonedistance; + +import android.os.Bundle; + +import androidx.annotation.NonNull; + +import com.bingce.controlapphelper.datasource.database.tolerance.detail.ToleranceDetailRecord; +import com.bingce.controlapphelper.event.AutoSurveyorButtonVisibleEvent; +import com.bingce.controlapphelper.event.SurveyStateEvent; +import com.bingce.controlapphelper.surveyor.state.IAutoModeSwitcher; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.totalstation.ControlSurveyResult; +import com.bingce.utils.ThreadPoolUtil; + +import org.greenrobot.eventbus.EventBus; + +/** + * 空闲状态 + *

+ * 将刷新界面 + */ +class _IdleState extends __BaseState { + private final @NonNull + IAutoModeSwitcher autoModeSwitcher; + + public _IdleState(StateManagerAloneDistance stateManager, @NonNull IAutoModeSwitcher autoModeSwitcher) { + super(StateType.idle, stateManager); + this.autoModeSwitcher = autoModeSwitcher; + } + + @Override + public void enter(Bundle args) { + + refreshGoBack(); + + ThreadPoolUtil.execute(() -> { + boolean completed = _IsSingleCycleCompletedState.isSingleCycleCompleted( + stationId(), + StateManagerAloneDistance.CYCLE_INDEX_DEFAULT, + getCachedData(), ToleranceDetailRecord.ALONE_DISTANCE_MEASURE_COUNT); + + //判断当前条件是否满足自动测量 + boolean haveAutoCondition = autoModeSwitcher.isReadyAutoSurvey() == ControlSurveyResult.CODE_SUCCESS; + + //自动测量是否显示 + EventBus.getDefault().post(new AutoSurveyorButtonVisibleEvent(positionFragment, haveAutoCondition, autoModeSwitcher.isAutoModeOpen())); + + if (haveAutoCondition && autoModeSwitcher.isAutoModeOpen()) { + //继续自动测量 + navigation2(StateType.doSurveyor); + } else { + if (autoModeSwitcher.isAutoModeOpen()) { + autoModeSwitcher.resetAutoMode(); + } + if (completed) { + SurveyStateEvent.postCompleted(positionFragment); + } else { + SurveyStateEvent.postIdle(positionFragment); + } + } + }); + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_IsAllCycleCompletedState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_IsAllCycleCompletedState.java new file mode 100644 index 0000000..701fae1 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_IsAllCycleCompletedState.java @@ -0,0 +1,54 @@ +package com.bingce.controlnetwork.surveyor.state.alonedistance; + +import android.os.Bundle; + +import androidx.annotation.NonNull; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.config.ConfigConstants; +import com.bingce.controlapphelper.datasource.database.config.ConfigRecord; +import com.bingce.controlapphelper.datasource.database.config.IConfigDataSource; +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.surveyor.state.IAutoModeSwitcher; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.utils.ThreadPoolUtil; + +import net.tatans.tensorflowtts.tts.TtsManager; + +/* + * 检测是否所有 测期都完成了测量 + * + * 只有在当前测期完成测量之后,才会进入当前状态 + * */ +public class _IsAllCycleCompletedState extends __BaseState { + private final IAutoModeSwitcher autoModeSwitcher; + + public _IsAllCycleCompletedState(@NonNull StateManagerAloneDistance stateManager, IAutoModeSwitcher autoModeSwitcher) { + super(StateType.isAllCycleCompleted, stateManager); + this.autoModeSwitcher = autoModeSwitcher; + } + + @Override + public void enter(Bundle args) { + if (isAutoSurveyOpen()) { + //检测是否已经提示 + //检测是否需要提示测站检测 + IConfigDataSource configDataSource = + SurveyorDatabaseFactory.instance.getConfigDataSource(); + ThreadPoolUtil.execute(() -> { + String key = ConfigConstants.KEY_CONFIG_STATION_CHECK_REMINDED + stationId(); + ConfigRecord record = configDataSource.getByKeySync(key); + if (record == null || ConfigConstants.VALUE_NO.equals(record.getConfigValue())) { + runOnUI(() -> TtsManager.getInstance().speak(Tools.getString(R.string.all_cycle_completed))); + } + }); + } + //标识测站完成测量(数据库存储) + setAllCycleSchedule(SurveyorScheduleConstants.STATUE_VALUE_COMPLETED); + //进入idle状态 + //清除测量状态,进入测站检测,停止自动测量 + enterStationCheckAndClearSurveyStateAndResetAutoMode(); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_IsSingleCycleCompletedState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_IsSingleCycleCompletedState.java new file mode 100644 index 0000000..ca23390 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_IsSingleCycleCompletedState.java @@ -0,0 +1,61 @@ +package com.bingce.controlnetwork.surveyor.state.alonedistance; + +import android.os.Bundle; + +import com.bingce.controlapphelper.datasource.database.alonedistance.AloneDistanceRecord; +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.model.LeftOrRight; +import com.bingce.controlapphelper.surveyor.data.CachedDataAloneDistance; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlapphelper.util.IdUtil; + +public class _IsSingleCycleCompletedState extends __BaseState { + private static final int RESULT_YES = 0;//测回结束 + private static final int RESULT_NO = 1;//测回未结束 + + public _IsSingleCycleCompletedState(StateManagerAloneDistance stateManager) { + super(StateType.isSingleCycleCompleted, stateManager); + } + + @Override + public void enter(Bundle args) { + onCompleted( + isSingleCycleCompleted(stationId(), + getCycleRecorder().currentCycleIndex(), + getCachedData(), getSurveyorCount())); + } + + private void onCompleted(boolean completed) { + if (completed) { + //这里先刷新下UI,不然弹窗后面的list不显示最后一条数据 + getSurveyorData().clearSurveyStateAndPosition(); + refreshUI(); + + int cycleIndex = getCycleRecorder().currentCycleIndex(); + //更新单测回测量进度 + setSingleCycleSchedule(cycleIndex, SurveyorScheduleConstants.STATUE_VALUE_COMPLETED); + //状态切换 + navigation2(StateType.isAllCycleCompleted); + } else { + findTargetFromBeginInCurrentCycle(false); + } + } + + /** + * 判断单个测回是否测量完成(不要求通过检测) + */ + public static boolean isSingleCycleCompleted(String stationId, int cycleIndex, CachedDataAloneDistance cachedData, int surveyCount) { + int result = RESULT_YES; + for (int index = 0; index < cachedData.pointCount(); index++) { + String pointId = cachedData.pointId(cycleIndex, index); + String leftOrRightKey = IdUtil.createSurveyorRecordId(stationId, cycleIndex, pointId, LeftOrRight.left); + AloneDistanceRecord aloneDistanceRecord = cachedData.getAloneDistanceRecord(leftOrRightKey); + if (aloneDistanceRecord == null || aloneDistanceRecord.distanceValues == null || + aloneDistanceRecord.distanceValues.size() < surveyCount * 2) { + result = RESULT_NO; + break; + } + } + return RESULT_YES == result; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_SurveyorFailureState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_SurveyorFailureState.java new file mode 100644 index 0000000..0d532bb --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/_SurveyorFailureState.java @@ -0,0 +1,36 @@ +package com.bingce.controlnetwork.surveyor.state.alonedistance; + +import android.os.Bundle; + +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; + +/* + * 仪器导致的测量失败 + * + * 全站仪多次测量失败,进入该状态 + * */ +class _SurveyorFailureState extends __BaseState { + + public _SurveyorFailureState(StateManagerAloneDistance stateManager) { + super(StateType.SurveyorFailure, stateManager); + } + + @Override + public void enter(Bundle args) { + String error = ""; + if (args != null) { + error = args.getString(KEY); + } + failureTipsWithAutoStandStill(error + Tools.getString(R.string.please_observe_target)); + } + + private static final String KEY = "error"; + + public static Bundle args(String error) { + Bundle args = new Bundle(); + args.putString(KEY, error); + return args; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/__BaseState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/__BaseState.java new file mode 100644 index 0000000..2c94cf3 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/alonedistance/__BaseState.java @@ -0,0 +1,395 @@ +package com.bingce.controlnetwork.surveyor.state.alonedistance; + +import android.content.Context; +import android.os.Bundle; + +import androidx.annotation.NonNull; +import androidx.annotation.StringRes; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.alonedistance.AloneDistanceRecord; +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleRecord; +import com.bingce.controlapphelper.datasource.database.tolerance.detail.ToleranceDetailRecord; +import com.bingce.controlapphelper.model.LeftOrRight; +import com.bingce.controlapphelper.surveyor.data.CachedDataAloneDistance; +import com.bingce.controlapphelper.surveyor.data.ICycleRecorder; +import com.bingce.controlapphelper.surveyor.data.ISurveyorData; +import com.bingce.controlapphelper.surveyor.state.IAutoModeSwitcher; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlapphelper.surveyor.surveyor.ISurveyor; +import com.bingce.controlapphelper.surveyor.surveyor.RequestSurveyorParamAuto; +import com.bingce.controlapphelper.util.IdUtil; +import com.bingce.controlnetwork.fragment.TipsFragment; +import com.bingce.controlnetwork.fragment.TipsWith2OptionFragment; +import com.bingce.controlnetwork.fragment.stationsurvey.angledistance.MeasureFragment; + +import blankj.utilcode.util.ToastUtils; + +import com.bingce.controlnetwork.fragment.TipsFragment; +import com.bingce.controlnetwork.fragment.TipsWith2OptionFragment; +import com.bingce.controlnetwork.fragment.stationsurvey.angledistance.MeasureFragment; + +abstract class __BaseState { + private final StateType type; + private final StateManagerAloneDistance stateManager; + + protected final int positionFragment = MeasureFragment.POSITION_DISTANCE_MEASURE; + + /** + * 判断常量 + */ + private final int DEFAULT_AUTO_MODE = 0; + private final int RESET_AUTO_MODE = 1; + private final int CLOSE_AUTO_MODE = 2; + + protected final int cycleIndexDefault = StateManagerAloneDistance.CYCLE_INDEX_DEFAULT; + + public __BaseState(final StateType stateType, final StateManagerAloneDistance stateManager) { + this.type = stateType; + this.stateManager = stateManager; + } + + final protected StateType getType() { + return type; + } + + final protected @NonNull + ToleranceDetailRecord getToleranceRecord() { + return stateManager.toleranceRecord; + } + + final protected @NonNull + ISurveyorData getSurveyorData() { + return stateManager.surveyorData; + } + + private @NonNull + IAutoModeSwitcher autoModeRecorder() { + return stateManager; + } + + /** + * 设置测量位置 + */ + final protected void setSurveyPosition(int index, LeftOrRight leftOrRight) { + stateManager.surveyorData.setCurrentIndex(index); + stateManager.surveyorData.setLeftOrRight(leftOrRight); + } + + protected int getCurrentIndex() { + return stateManager.surveyorData.currentIndex(); + } + + protected AloneDistanceRecord getAloneDistanceRecord(int surveyorPointIndex) { + int cycleIndex = getCycleRecorder().currentCycleIndex(); + String pointId = getCachedData().pointId(cycleIndex, surveyorPointIndex); + String cacheKey = IdUtil.createSurveyorRecordId(stationId(), cycleIndex, pointId, LeftOrRight.left); + return getCachedData().getAloneDistanceRecord(cacheKey); + } + + final protected ISurveyor surveyorImpl() { + return stateManager.surveyor; + } + + + @NonNull + final protected CachedDataAloneDistance getCachedData() { + return stateManager.cachedData; + } + + @NonNull + final protected ICycleRecorder getCycleRecorder() { + return stateManager.cycleRecorder; + } + + @NonNull + final protected Context getContext() { + return stateManager.context; + } + + final protected void scroll2(int itemIndex) { + stateManager.scrollDelegate.onScrollTo(itemIndex); + } + + + final protected void toast(String warning) { + ToastUtils.showShort(warning); + } + + final protected void toast(@StringRes int warning) { + ToastUtils.showShort(warning); + } + + public abstract void enter(Bundle args);//进入状态 + + final protected void navigation2(StateType stateType) { + stateManager.enter(stateType); + } + + final protected void navigation2(StateType stateType, Bundle args) { + stateManager.enter(stateType, args); + } + + final protected String stationId() { + return stateManager.stationId(); + } + + protected int getSurveyorCount() { + return stateManager.surveyorData.surveyorCount(); + } + + final protected FragmentManager fragmentManager() { + return stateManager.fragmentManager(); + } + + final protected LifecycleOwner lifecycleOwner() { + return stateManager.lifecycleOwner(); + } + + final protected void tips(String msg, Runnable runnable) { + TipsFragment.noCancelAbleTips(stateManager.fragmentManager(), stateManager.lifecycleOwner(), + getContext(), + msg, + -1, + () -> { + if (runnable != null) { + runnable.run(); + } + }); + } + + /** + * 错误提示 + *

+ * 用户不能忽略,点击确定后自动「停留原地」 + */ + final protected void failureTipsWithAutoStandStill(String msg) { + TipsFragment.noCancelAbleTips(stateManager.fragmentManager(), stateManager.lifecycleOwner(), + getContext(), + msg, + -1, + () -> enterIdleAndClearSurveyStateAndResetAutoMode(true)); + } + + final protected void failureTipsWithAutoStandStill(String msg, Runnable runnable) { + TipsFragment.noCancelAbleTips(stateManager.fragmentManager(), stateManager.lifecycleOwner(), + getContext(), + msg, + -1, + () -> { + runnable.run(); + enterIdleAndClearSurveyStateAndResetAutoMode(true); + }); + } + + final protected void optionTipsWithStandStill(String msg, Runnable confirmCallback) { + optionTips(msg, null, null, + confirmCallback, + () -> enterIdleAndClearSurveyStateAndResetAutoMode(true), + () -> enterIdleAndClearSurveyStateAndResetAutoMode(true)); + } + + final protected void optionTips(String msg, + String confirmButton, + String cancelButton, + Runnable confirmCallback, + Runnable cancelCallback, + Runnable ignoreCallback) { + TipsWith2OptionFragment.tips( + stateManager.fragmentManager(), + stateManager.lifecycleOwner(), + confirmButton, + cancelButton, + null, + msg, + new TipsWith2OptionFragment.IOperatorCallback() { + @Override + public void onConfirm() { + if (confirmCallback == null) { + return; + } + confirmCallback.run(); + } + + @Override + public void onCancel() { + if (cancelCallback == null) { + return; + } + cancelCallback.run(); + } + + @Override + public void onIgnore() { + if (ignoreCallback == null) { + return; + } + ignoreCallback.run(); + } + + @Override + public void onOption() { + } + }); + } + + final protected void runOnUI(Runnable runnable) { + stateManager.runOnUI(runnable); + } + + final protected void setCurrentCycle(int cycle) { + SurveyorDatabaseFactory + .instance + .getScheduleDataSource() + .record( + new SurveyorScheduleRecord( + SurveyorScheduleConstants.getCurrentCycleKey(stationId(), SurveyorScheduleConstants.SCHEDULE_OR_CYCLE_TYPE_ALONE_DISTANCE), + String.valueOf(cycle))); + } + + final protected void setCurrentCycleSync(int cycle) { + SurveyorDatabaseFactory + .instance + .getScheduleDataSource() + .recordSync( + new SurveyorScheduleRecord( + SurveyorScheduleConstants.getCurrentCycleKey(stationId(), SurveyorScheduleConstants.SCHEDULE_OR_CYCLE_TYPE_ALONE_DISTANCE), + String.valueOf(cycle))); + } + + final protected void setSingleCycleSchedule(int cycleIndex, String statue) { + SurveyorDatabaseFactory + .instance + .getScheduleDataSource() + .record( + new SurveyorScheduleRecord( + SurveyorScheduleConstants.getSingleCycleScheduleKey(stationId(), SurveyorScheduleConstants.SCHEDULE_OR_CYCLE_TYPE_ALONE_DISTANCE, cycleIndex), + statue)); + } + + final protected void setSingleCycleScheduleSync(int cycleIndex, String statue) { + SurveyorDatabaseFactory + .instance + .getScheduleDataSource() + .recordSync( + new SurveyorScheduleRecord( + SurveyorScheduleConstants.getSingleCycleScheduleKey(stationId(), SurveyorScheduleConstants.SCHEDULE_OR_CYCLE_TYPE_ALONE_DISTANCE, cycleIndex), + statue)); + } + + final protected void setAllCycleSchedule(String statue) { + SurveyorDatabaseFactory + .instance + .getScheduleDataSource() + .record( + new SurveyorScheduleRecord( + SurveyorScheduleConstants.getAllCycleScheduleKey(stationId(), SurveyorScheduleConstants.SCHEDULE_OR_CYCLE_TYPE_ALONE_DISTANCE), + statue)); + } + + final protected void setAllCycleScheduleSync(String statue) { + SurveyorDatabaseFactory + .instance + .getScheduleDataSource() + .recordSync( + new SurveyorScheduleRecord( + SurveyorScheduleConstants.getAllCycleScheduleKey(stationId(), SurveyorScheduleConstants.SCHEDULE_OR_CYCLE_TYPE_ALONE_DISTANCE), + statue)); + } + + /** + * 如果resetAutoSurveyState为true,将重置autoSurvey状态为unknown + */ + final protected void findTargetFromBeginInCurrentCycle(boolean resetAutoSurveyState) { + getSurveyorData().clearSurveyStateAndPosition(); + if (resetAutoSurveyState) { + autoModeRecorder().resetAutoMode(); + } + navigation2(StateType.doMove2NextValidate); + } + + final protected void enterIdleAndClearSurveyState() { + clearSurveyStateAndCloseAutoModeAndStandStill(DEFAULT_AUTO_MODE, + false, StateType.idle); + } + + final protected void enterIdleAndClearSurveyorStatePosition() { + clearSurveyStateAndCloseAutoModeAndStandStill(DEFAULT_AUTO_MODE, + true, StateType.idle); + } + + /** + * 取消测量,会停在当前位置(索引+盘左or盘右),并进入idle + */ + final protected void enterIdleAndClearSurveyStateAndResetAutoMode(boolean resetAutoMode) { + clearSurveyStateAndCloseAutoModeAndStandStill(resetAutoMode ? RESET_AUTO_MODE : DEFAULT_AUTO_MODE, + false, StateType.idle); + } + + + final protected void enterStationCheckAndClearSurveyStateAndResetAutoMode() { + clearSurveyStateAndCloseAutoModeAndStandStill(RESET_AUTO_MODE, + false, StateType.checkStation); + } + + /** + * 原_Check2CState 使用这个方法 + */ + final protected void enterIdleAndClearSurveyStateAndCloseAutoMode() { + clearSurveyStateAndCloseAutoModeAndStandStill(CLOSE_AUTO_MODE, false, StateType.idle); + } + + /** + * @param autoMode + * @param clearPosition + * @param stateType + */ + private void clearSurveyStateAndCloseAutoModeAndStandStill(int autoMode, boolean clearPosition, StateType stateType) { + //重置或者关闭自动模式 + if (autoMode == RESET_AUTO_MODE) { + autoModeRecorder().resetAutoMode(); + } else if (autoMode == CLOSE_AUTO_MODE) { + autoModeRecorder().closeAutoMode(); + } + //更新测量进度标识 + if (clearPosition) { + getSurveyorData().clearSurveyStateAndPosition(); + } else { + getSurveyorData().clearSurveyState(); + } + //进入某个状态 + navigation2(stateType); + } + + + /** + * 更新UI + */ + final protected void refreshUI() { + runOnUI(() -> getCachedData().notifyDateChange()); + } + + protected boolean isAutoSurveyOpen() { + return stateManager.isAutoModeOpen(); + } + + protected boolean isAutoSurveyClosed() { + return stateManager.isAutoModeClose(); + } + + double getInsturmentHeight() { + return stateManager.getInsturmentHeight(); + } + + RequestSurveyorParamAuto getRequestSurveyorParamAuto() { + return stateManager.getRequestSurveyorParamAuto(); + } + + protected void refreshGoBack() { + stateManager.refreshGoBackBtnEnable(); + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/StateManager.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/StateManager.java new file mode 100644 index 0000000..4ecd238 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/StateManager.java @@ -0,0 +1,539 @@ +package com.bingce.controlnetwork.surveyor.state.angledistance; + +import android.content.Context; +import android.os.Bundle; + +import androidx.annotation.NonNull; +import androidx.annotation.WorkerThread; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.point.PointRecord; +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.model.SurveyorPoint; +import com.bingce.controlapphelper.datasource.database.tolerance.detail.ToleranceDetailRecord; +import com.bingce.controlapphelper.event.RefreshGoBackButton; +import com.bingce.controlapphelper.model.DataCategory; +import com.bingce.controlapphelper.model.LeftOrRight; +import com.bingce.controlapphelper.surveyor.data.ICachedData; +import com.bingce.controlapphelper.surveyor.data.ICycleRecorder; +import com.bingce.controlapphelper.surveyor.data.ISurveyorData; +import com.bingce.controlapphelper.surveyor.method.AutoSurveyorMethod; +import com.bingce.controlapphelper.surveyor.method.SurveyorAdjustMethod; +import com.bingce.controlapphelper.surveyor.state.IAutoModeSwitcher; +import com.bingce.controlapphelper.surveyor.state.IStateType; +import com.bingce.controlapphelper.surveyor.state.ISurveyState; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlapphelper.surveyor.surveyor.ISurveyor; +import com.bingce.controlapphelper.surveyor.surveyor.ISurveyorListener; +import com.bingce.controlapphelper.surveyor.surveyor.ISurveyorRemindListener; +import com.bingce.controlapphelper.surveyor.surveyor.RequestSurveyorParamAuto; +import com.bingce.controlapphelper.surveyor.surveyor.SurveyorAutoImpl; +import com.bingce.controlapphelper.surveyor.surveyor.SurveyorMockAuto; +import com.bingce.controlapphelper.surveyor.surveyor.SurveyorSingleImpl; +import com.bingce.controlapphelper.surveyor.test.Test; +import com.bingce.controlapphelper.util.DigitalUtil; +import com.bingce.controlapphelper.util.IUIRunner; +import com.bingce.controlapphelper.util.IdUtil; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.fragment.StationDataAdjustDialogFragment; +import com.bingce.controlnetwork.fragment.TipsFragment; +import com.bingce.controlnetwork.surveyor.state.AutoModeType; +import com.bingce.controlnetwork.surveyor.state.IScrollDelegate; +import com.bingce.controlnetwork.surveyor.state.StateConstants; +import com.bingce.controlnetwork.surveyor.util.checkadjust.AngleDistanceCheckAdjust; +import com.bingce.controlnetwork.surveyor.util.checkadjust.IStationCheck; +import com.bingce.coordlib.model.Coordinate; +import com.bingce.totalstation.ControlSurveyData; +import com.bingce.totalstation.ControlSurveyResult; +import com.bingce.utils.ThreadPoolUtil; +import com.bingce.utils.VipManager; + +import org.greenrobot.eventbus.EventBus; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import blankj.utilcode.util.ToastUtils; + +public class StateManager implements IAutoModeSwitcher, ISurveyState, IStateType { + private final Map stateMap = new HashMap<>(); + private StateType currentStateType = StateType.idle; + private final FragmentManager fragmentManager; + private final LifecycleOwner lifecycleOwner; + private final IUIRunner iuiRunner; + final IScrollDelegate scrollDelegate; + + @NonNull + SurveyorStationRecord stationRecord; + final @NonNull + RequestSurveyorParamAuto requestSurveyorParamAuto; + final @NonNull + ToleranceDetailRecord toleranceRecord; + final @NonNull + ISurveyorData surveyorData; + final @NonNull + ICachedData cachedData; + final @NonNull + ICycleRecorder cycleRecorder; + final @NonNull + Context context; + private AutoModeType autoMode = AutoModeType.unknown; + @NonNull + final ISurveyor surveyor; + private final PointRecord stationPointRecord; + final boolean supportAutoSurvey; + + private final IStationCheck stationCheck = new AngleDistanceCheckAdjust(); + + private StateManager(final boolean supportAutoSurvey,//是否支持自动测量 + final @NonNull RequestSurveyorParamAuto requestSurveyorParamAuto, + final @NonNull SurveyorStationRecord stationRecord, + final @NonNull PointRecord stationPointRecord, + final @NonNull ToleranceDetailRecord toleranceRecord, + final @NonNull Context context, + final @NonNull ISurveyorData surveyorData, + final @NonNull ICycleRecorder cycleRecorder, + final @NonNull ICachedData cachedData, + final @NonNull IScrollDelegate scrollDelegate, + FragmentManager fragmentManager, + LifecycleOwner lifecycleOwner, + IUIRunner iuiRunner) { + this.supportAutoSurvey = supportAutoSurvey; + + this.requestSurveyorParamAuto = requestSurveyorParamAuto; + this.stationRecord = stationRecord; + this.fragmentManager = fragmentManager; + this.lifecycleOwner = lifecycleOwner; + this.iuiRunner = iuiRunner; + this.scrollDelegate = scrollDelegate; + + this.context = context; + this.toleranceRecord = toleranceRecord; + this.surveyorData = surveyorData; + this.cachedData = cachedData; + this.cycleRecorder = cycleRecorder; + + this.stationPointRecord = stationPointRecord; + + if (Test.DEBUG) { + surveyor = new SurveyorMockAuto(StateConstants.VALUE_MEASURE_WHAT_ANGLE_DISTANCE, this.stationRecord.getId(), + this.stationRecord.isAutoClose(), + toleranceRecord.getCycleCount(), + cachedData, surveyorData, cycleRecorder, this, this); + } else { + if (supportAutoSurvey) { + surveyor = new SurveyorAutoImpl(StateConstants.VALUE_MEASURE_WHAT_ANGLE_DISTANCE, this); + } else { + surveyor = new SurveyorSingleImpl(StateConstants.VALUE_MEASURE_WHAT_ANGLE_DISTANCE); + } + } + _DoSurveyorState doSurveyorState = new _DoSurveyorState(this, this); + //注册接收数据的状态 + surveyor.register((ISurveyorListener) doSurveyorState); + surveyor.register((ISurveyorRemindListener) doSurveyorState); + + stateMap.put(StateType.doSurveyor, doSurveyorState); + stateMap.put(StateType.doAutoSurveyor, new _DoAutoSurveyorState(this, this)); + stateMap.put(StateType.SurveyorFailure, new _SurveyorFailureState(this)); + stateMap.put(StateType.doMove2NextValidate, new _DoMove2NextValidateState(this)); + stateMap.put(StateType.doMoveBack, new _DoMoveBackState(this)); + stateMap.put(StateType.doRecordClean, new _DoRecordCleanState(this)); + stateMap.put(StateType.checkReadData, new _CheckReadDataState(this, this)); + stateMap.put(StateType.isHalfCycleZeroCheckReady, new _IsHalfCycleZeroCheckReadyState(this)); + stateMap.put(StateType.checkHalfCycleZero, new _CheckHalfCycleZeroState(this)); + stateMap.put(StateType.isReady2CCheck, new _Is2CCheckReadyState(this)); + stateMap.put(StateType.check2C, new _Check2CState(this)); + stateMap.put(StateType.isSingleCycleCompleted, new _IsSingleCycleCompletedState(this)); + stateMap.put(StateType.isAllCycleCompleted, new _IsAllCycleCompletedState(this, this)); + stateMap.put(StateType.checkSingleCycle, new _CheckSingleCycleState(this)); + stateMap.put(StateType.checkStation, new _CheckStationState(this)); + stateMap.put(StateType.stationCheckedSuccess, new _CheckStationSuccessState(this)); + + stateMap.put(StateType.doDeleteAllCycle, new _DoDeleteAllCycleState(this)); + stateMap.put(StateType.doDeleteCurrentCycle, new _DoDeleteCurrentCycleState(this)); + + stateMap.put(StateType.doCalScheduleSingleCycle, new _DoCalScheduleInSingleCycleState(this, this)); + stateMap.put(StateType.doCalScheduleAllCycle, new _DoCalScheduleInAllCycleState(this, this)); + stateMap.put(StateType.doCalAdjust, new _DoCalAdjustState(this)); + stateMap.put(StateType.idle, new _IdleState(this, this)); + stateMap.put(StateType.doWellMeasureRotationReady, new _DoWellMeasureRotationReadyState(this)); + + //监听测站数据变化 + runOnUI(() -> SurveyorDatabaseFactory + .instance + .getSurveyorStation() + .getLiveDataRecord(stationRecord.getId()) + .observe(lifecycleOwner, record -> { + if (record == null || !stationRecord.getId().equals(record.getId())) { + return; + } + updateSurveyorStationRecord(record); + })); + } + + private void updateSurveyorStationRecord(SurveyorStationRecord record) { + this.stationRecord = record; + //更新测点信息 + if (stationRecord.getItems() != null) { + for (SurveyorPoint item : stationRecord.getItems()) { + if (item == null || !SurveyorPoint.TYPE_POINT.equals(item.getType())) { + //排除非测点 + continue; + } + cachedData.updateSurveyPointParams(item); + } + } + cachedData.notifyDateChange(); + } + + String stationId() { + return stationRecord.getId(); + } + + + @Override + public void enter(StateType type, Bundle args) { + if (isDead()) { + return; + } + __BaseState baseState = stateMap.get(type); + if (baseState != null) { + this.currentStateType = type; + runOnUI(() -> baseState.enter(args)); + } + } + + @Override + public void enter(StateType type) { + enter(type, null); + } + + void runOnUI(Runnable action) { + if (iuiRunner != null) { + iuiRunner.runOnUI(action); + } + } + + public void doSurveyor() { + boolean inValidate = isInValidate(); + + if (inValidate) { + return; + } + + int pointCount = cachedData.pointCount(); + if (pointCount == 0) { + ToastUtils.showShort(R.string.no_data_available_yet); + return; + } + + Bundle bundle = null; + if (isRotationReadyState()) { + //当前是旋转到位状态 + bundle = new Bundle(); + bundle.putBoolean(StateConstants.KEY_IS_ROTATION_READY_STATE, true); + } + + enter(StateType.doSurveyor, bundle); + } + + public void doAutoSurveyor() { + if (isInValidate()) { + return; + } + enter(StateType.doAutoSurveyor); + } + + public void deleteCurrentStationSurveyorData() { + if (isInValidate()) { + return; + } + enter(StateType.doDeleteAllCycle, _DoDeleteAllCycleState.args(stationId())); + } + + public void deleteCurrentStationSurveyorData(int cycleIndex) { + if (isInValidate()) { + return; + } + enter(StateType.doDeleteCurrentCycle, _DoDeleteCurrentCycleState.args(stationId(), cycleIndex)); + } + + public void stationCheck() { + if (isInValidate()) { + return; + } + enter(StateType.checkStation); + } + + public String stationCheckOnly() { + return stationCheck.check(stationId(), toleranceRecord, cachedData); + } + + public void stationAdjustOnly(String showType) { + ThreadPoolUtil.execute(() -> { + SurveyorAdjustMethod.AdjustResult adjustResult = SurveyorAdjustMethod.calStationAdjust(stationRecord, cachedData); + if (adjustResult.isError()) { + runOnUI(() -> TipsFragment.tipsOnly(fragmentManager, lifecycleOwner, context, adjustResult.errorString)); + return; + } + //显示平差结果 + StationDataAdjustDialogFragment.showDialog(showType, adjustResult.result, adjustResult.showSlopDistance, fragmentManager()); + + //伴随平差 设置进度为通过检测 + SurveyorDatabaseFactory + .instance + .getScheduleDataSource() + .record( + new SurveyorScheduleRecord( + SurveyorScheduleConstants.getAllCycleScheduleKey(stationId(), null), + SurveyorScheduleConstants.STATUE_VALUE_CHECKED)); + }); + } + + public void stationAdjust(String type) { + if (isInValidate()) { + return; + } + Bundle bundle = new Bundle(); + bundle.putString(StationDataAdjustDialogFragment.KEY_SHOW_TYPE, type); + enter(StateType.doCalAdjust, bundle); + } + + public void switch2Cycle(int cycleIndex) { + if (isInValidate()) { + return; + } + _DoCalScheduleInSingleCycleState.enter(this, cycleIndex); + } + + public void calScheduleWhenEnterSurveyFragment(int cycleIndex) { + if (isInValidate()) { + return; + } + _DoCalScheduleInAllCycleState.enter(this, cycleIndex); + } + + public void moveBack() { + if (isInValidate()) { + return; + } + enter(StateType.doMoveBack); + } + + //检测当前状态是否支持从外界主动改变状态 + //如果是空闲或者是测站通过检测是有效的状态 + private boolean isInValidate() { + return currentStateType != StateType.idle + && StateType.stationCheckedSuccess != currentStateType + && !isRotationReadyState(); + } + + private boolean isRotationReadyState() { + return currentStateType == StateType.doWellMeasureRotationReady; + } + + public void quite() { + _live = false; + for (Map.Entry entry : stateMap.entrySet()) { + entry.getValue().quite(); + } + //进入idle状态 + this.currentStateType = StateType.idle; + } + + private boolean _live = true; + + boolean isDead() { + return !_live; + } + + public void resume() { + _live = true; + for (Map.Entry entry : stateMap.entrySet()) { + entry.getValue().resume(); + } + } + + FragmentManager fragmentManager() { + return this.fragmentManager; + } + + LifecycleOwner lifecycleOwner() { + return this.lifecycleOwner; + } + + final boolean isStationAutoClosed() { + return stationRecord.isAutoClose(); + } + + @WorkerThread + public static StateManager newInstance( + boolean isSupportAutoMode, + @NonNull RequestSurveyorParamAuto requestSurveyorParamAuto, + @NonNull SurveyorStationRecord stationRecord, + @NonNull Context context, + @NonNull FragmentManager fragmentManager, + @NonNull LifecycleOwner lifecycleOwner, + @NonNull ToleranceDetailRecord toleranceRecord, + @NonNull ISurveyorData surveyorData, + @NonNull ICycleRecorder cycleRecorder, + @NonNull ICachedData cachedData, + IScrollDelegate scrollDelegate, + IUIRunner runner) { + //读取测点record + String stationPointId = null; + if (stationRecord.getItems() != null) { + for (SurveyorPoint stationItem : stationRecord.getItems()) { + if (SurveyorPoint.TYPE_STATION.equals(stationItem.getType())) { + stationPointId = stationItem.getPointId(); + break; + } + } + } + PointRecord stationPointRecord = null; + if (stationPointId != null) { + stationPointRecord = SurveyorDatabaseFactory + .instance + .getPointDataSource() + .findByIdSync(stationPointId); + } + if (stationPointRecord == null) { + return null; + } + boolean supportAuto = Test.DEBUG; + //AppUtils.isAppDebug() + if (isSupportAutoMode && + (VipManager.getInstance().checkReg() || VipManager.getInstance().checkControlProLevel())) { + supportAuto = true; + } + StateManager manager = new StateManager(supportAuto, + requestSurveyorParamAuto, + stationRecord, + stationPointRecord, + toleranceRecord, + context, + surveyorData, + cycleRecorder, + cachedData, + scrollDelegate, + fragmentManager, lifecycleOwner, runner); + return manager; + } + + @Override + public boolean isAutoModeOpen() { + return autoMode == AutoModeType.start; + } + + @Override + public boolean isAutoModeClose() { + return autoMode == AutoModeType.stop; + } + + @Override + public boolean isAutoModeNotSpecial() { + return autoMode == AutoModeType.unknown; + } + + @Override + public void openAutoMode() { + autoMode = AutoModeType.start; + } + + @Override + public void closeAutoMode() { + autoMode = AutoModeType.stop; + } + + @Override + public void resetAutoMode() { + autoMode = AutoModeType.unknown; + } + + + @Override + public int isReadyAutoSurvey() { + if (!supportAutoSurvey) { + return ControlSurveyResult.CODE_ERROR; + } + if (!surveyor.isReady()) {//仪器连接上才算ready + return ControlSurveyResult.CODE_ERROR; + } + + Coordinate stationBasePoint = getStationCoord(); + double instrumentHeight = getInsturmentHeight(); + + return requestSurveyorParamAuto.checkAutoCondition(getCachedData(), stationBasePoint, instrumentHeight); + } + + @Override + public String isMeasuredValueMatchDesign() { + if (!supportAutoSurvey) { + return null; + } + Coordinate stationBasePoint = getStationCoord(); + double instrumentHeight = getInsturmentHeight(); + List originMeasureList = requestSurveyorParamAuto.getOriginMeasureList(getCachedData()); + return AutoSurveyorMethod.checkAutoSurveyorMeasuredValue(stationBasePoint, instrumentHeight, originMeasureList); + } + + @Override + public boolean isSurveying() { + return currentStateType == StateType.doSurveyor || currentStateType == StateType.doAutoSurveyor; + } + + @Override + public boolean isAutoSurveying() { + return isAutoModeOpen(); + } + + + public ICachedData getCachedData() { + return cachedData; + } + + /** + * 获取当前测回 + * + * @return + */ + public int getCurrentCycle() { + return cycleRecorder.currentCycleIndex(); + } + + public int getCurrentIndex() { + return surveyorData.currentIndex(); + } + + private Coordinate getStationCoord() { + if (PointRecord.TYPE_KNOWN_POINT.equals(stationPointRecord.getPointType())) { + return new Coordinate( + stationPointRecord.getX(), + stationPointRecord.getY(), + stationPointRecord.getZ()); + } + return null; + } + + public double getInsturmentHeight() { + return DigitalUtil.valueOfDoubleString(stationRecord.getInstrumentHeight(), 0); + } + + @NonNull + public RequestSurveyorParamAuto getRequestSurveyorParamAuto() { + return requestSurveyorParamAuto; + } + + public void refreshGoBackBtnEnable() { + int currentCycle = cycleRecorder.currentCycleIndex(); + String pointId = getCachedData().pointId(currentCycle, 0); + DataCategory dataCategory = getCachedData().valueState( + IdUtil.createSurveyorRecordId(stationId(), currentCycle, pointId, LeftOrRight.left), 0); + EventBus.getDefault().post(new RefreshGoBackButton(!dataCategory.isEmptyData())); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_Check2CState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_Check2CState.java new file mode 100644 index 0000000..a1d2566 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_Check2CState.java @@ -0,0 +1,113 @@ +package com.bingce.controlnetwork.surveyor.state.angledistance; + +import android.os.Bundle; + +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.datasource.database.tolerance.detail.ToleranceDetailRecord; +import com.bingce.controlapphelper.surveyor.data.ICachedData; +import com.bingce.controlapphelper.surveyor.data.ISurveyorData; +import com.bingce.controlapphelper.surveyor.method.ValueOf2cMethod; +import com.bingce.controlapphelper.surveyor.method.model.CacheResult; +import com.bingce.controlapphelper.surveyor.method.model.SdAngleValueType; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.utils.Util; + +import net.tatans.tensorflowtts.tts.TtsManager; + +/* + * 检测2c + * */ +class _Check2CState extends __BaseState { + + public _Check2CState(StateManager stateManager) { + super(StateType.check2C, stateManager); + } + + @Override + public void enter(Bundle args) { + String error = _check2C(stationId(), getToleranceRecord(), + getSurveyorData(), + getCycleRecorder().currentCycleIndex(), + getCachedData()); + if (error.isEmpty()) { + navigation2(StateType.doRecordClean); + } else { + if (isAutoSurveyOpen()) { + TtsManager.getInstance().speak(Tools.getString(R.string.erxi_is_over_limit_please_check)); + } + optionTips(error, + Tools.getString(R.string.retest_cycle), + Tools.getString(R.string.retest_point), + () -> optionTipsWithStandStill(Tools.getString(R.string.tips_delete_current_cycle_surveyor_record), + () -> { + String stationId = stationId(); + int currentCycleIndex = getCycleRecorder().currentCycleIndex(); + //删除数据 + ICachedData cachedData = getCachedData(); + cachedData.deleteSurveyorRecord(stationId, currentCycleIndex); + //更新进度 + setSingleCycleSchedule(currentCycleIndex, SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + setAllCycleSchedule(SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + //重新查找目标开启测量 + findTargetFromBeginInCurrentCycle(true); + }), + this::enterIdleAndClearSurveyState, + this::enterIdleAndClearSurveyStateAndCloseAutoMode); + } + } + + private static String _check2C(String stationId, + ToleranceDetailRecord toleranceRecord, + ISurveyorData surveyorData, + int cycleIndex, + ICachedData cachedData) { + StringBuilder stringBuilder = new StringBuilder(); + + int currentIndex = surveyorData.currentIndex(); + + CacheResult value2C = ValueOf2cMethod.valueOf2C(SdAngleValueType.horAngle, currentIndex, stationId, + surveyorData, cycleIndex, cachedData); + + if (!value2C.validate || toleranceRecord.getHor2C() < Math.abs(value2C.value)) { + stringBuilder.append(Tools.getString(R.string.hor_angle_2c_limit)) + .append(toleranceRecord.getHor2C()) + .append("'')\n") + .append(" ") + .append(Tools.getString(R.string.measurements)) + .append(Util.formatDouble2String(Math.abs(value2C.value), 1)) + .append("''"); + } + + value2C = ValueOf2cMethod.valueOf2C(SdAngleValueType.verAngle, currentIndex, stationId, + surveyorData, cycleIndex, cachedData); + if (!value2C.validate || toleranceRecord.getVerI() < Math.abs(value2C.value)) { + stringBuilder.append("\n") + .append(Tools.getString(R.string.ver_angle_i_limit)) + .append(toleranceRecord.getVerI()) + .append("'')\n") + .append(" ") + .append(Tools.getString(R.string.measurements)) + .append(Util.formatDouble2String(Math.abs(value2C.value), 1)) + .append("''"); + } + + if (!cachedData.isAloneDistance(cycleIndex, surveyorData.currentIndex())) { + value2C = ValueOf2cMethod.valueOf2C(SdAngleValueType.distance, currentIndex, stationId, + surveyorData, cycleIndex, cachedData); + if (!value2C.validate || toleranceRecord.getSlopeLensDistanceDifference() < Math.abs(value2C.value)) { + stringBuilder.append("\n") + .append(Tools.getString(R.string.distance_positive_and_negative_mirror_limit)) + .append(toleranceRecord.getSlopeLensDistanceDifference()) + .append("mm)\n") + .append(" ") + .append(Tools.getString(R.string.measurements)) + .append(Util.formatDouble2String(Math.abs(value2C.value), 1)) + .append("mm"); + } + } + + return stringBuilder.toString(); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_CheckHalfCycleZeroState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_CheckHalfCycleZeroState.java new file mode 100644 index 0000000..156a56b --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_CheckHalfCycleZeroState.java @@ -0,0 +1,81 @@ +package com.bingce.controlnetwork.surveyor.state.angledistance; + +import android.os.Bundle; + +import com.bingce.controlapphelper.datasource.database.tolerance.detail.ToleranceDetailRecord; +import com.bingce.controlapphelper.model.LeftOrRight; +import com.bingce.controlapphelper.surveyor.data.ICachedData; +import com.bingce.controlapphelper.surveyor.data.ISurveyorData; +import com.bingce.controlapphelper.surveyor.method.AverageValueMethod; +import com.bingce.controlapphelper.surveyor.method.DeviationValueOfRadianMethod; +import com.bingce.controlapphelper.surveyor.method.model.CacheResult; +import com.bingce.controlapphelper.surveyor.method.model.SdAngleValueType; +import com.bingce.controlapphelper.surveyor.state.StateType; + +import net.tatans.tensorflowtts.tts.TtsManager; + +import com.bingce.controlnetwork.R; + +/* + * 半测回归零检测 --- 只检测水平角 + * */ +class _CheckHalfCycleZeroState extends __BaseState { + private final static int RESULT_SUCCESS = 0; + private final static int RESULT_FAILURE = 1; + + public _CheckHalfCycleZeroState(StateManager stateManager) { + super(StateType.checkHalfCycleZero, stateManager); + } + + @Override + public void enter(Bundle args) { + if (isStationClosed()) { + ISurveyorData surveyorDataSource = getSurveyorData(); + int cycleIndex = getCycleRecorder().currentCycleIndex(); + ICachedData stationSurveyorDataSource = getCachedData(); + ToleranceDetailRecord toleranceRecord = getToleranceRecord(); + int pointCount = stationSurveyorDataSource.pointCount(); + LeftOrRight leftOrRight = surveyorDataSource.leftOrRight(); + + CacheResult angleHorFirst = AverageValueMethod.leftOrRightValue(SdAngleValueType.horAngle, + stationId(), + 0, + leftOrRight, + surveyorDataSource, + cycleIndex, + stationSurveyorDataSource); + CacheResult angleHorEnd = AverageValueMethod.leftOrRightValue(SdAngleValueType.horAngle, + stationId(), + pointCount - 1, + leftOrRight, + surveyorDataSource, + cycleIndex, + stationSurveyorDataSource); + if (!angleHorFirst.validate || !angleHorEnd.validate) { + onCompleted(RESULT_FAILURE); + } else { + double diff = DeviationValueOfRadianMethod.similarRadianDiff(angleHorFirst.value, angleHorEnd.value); + if (toleranceRecord.getHorHalfReturnZeroDifference() < Math.toDegrees(diff) * 3600) { + onCompleted(RESULT_FAILURE); + } else { + onCompleted(RESULT_SUCCESS); + } + } + } else { + onCompleted(RESULT_SUCCESS); + } + } + + private void onCompleted(int result) { + if (RESULT_SUCCESS == result) { + navigation2(StateType.isReady2CCheck); + } else if (RESULT_FAILURE == result) { + if (isAutoSurveyOpen()) { + TtsManager.getInstance().speak(getContext().getString(R.string.tips_error_half_cycle_zero_stop_survey)); + } + failureTipsWithAutoStandStill(getContext().getString(R.string.tips_error_half_cycle_zero_stop_survey)); + } else { + throw new RuntimeException("半测回归零差 failure"); + } + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_CheckReadDataState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_CheckReadDataState.java new file mode 100644 index 0000000..4d64557 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_CheckReadDataState.java @@ -0,0 +1,126 @@ +package com.bingce.controlnetwork.surveyor.state.angledistance; + +import android.os.Bundle; + +import com.bingce.controlapphelper.model.LeftOrRight; +import com.bingce.controlapphelper.surveyor.data.ISurveyorData; +import com.bingce.controlapphelper.surveyor.method.DeviationValueOfRadianMethod; +import com.bingce.controlapphelper.surveyor.method.RadianMethod; +import com.bingce.controlapphelper.surveyor.state.IAutoModeSwitcher; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.totalstation.TotalStation; + +import net.tatans.tensorflowtts.tts.TtsManager; + + +/* + * 检测当前测量数据读数互差 + * */ +class _CheckReadDataState extends __BaseState { + private static final int RESULT_SUCCESS = 0; + private static final int RESULT_FAILURE_HOR = 1; + private static final int RESULT_FAILURE_VER = 2; + private static final int RESULT_FAILURE_DISTANCE = 3; + private final IAutoModeSwitcher autoModeSwitcher; + + public _CheckReadDataState(StateManager stateManager, IAutoModeSwitcher autoModeSwitcher) { + super(StateType.checkReadData, stateManager); + this.autoModeSwitcher = autoModeSwitcher; + } + + @Override + public void enter(Bundle args) { + //先检测测量值和设计值是否匹配(仅在自动测量打开下检测) + String error = autoModeSwitcher.isMeasuredValueMatchDesign(); + if (error != null) { + failureTipsWithAutoStandStill(error); + return; + } + int surveyorCount = getToleranceRecord().getSurveyorCount(); + if (surveyorCount <= 1) {//单次测量,直接通过检测 + onCompleted(RESULT_SUCCESS); + } else {//多次测量,执行检测 + ISurveyorData surveyorDataSource = getSurveyorData(); + double horDifference = getToleranceRecord().getHorReadDifference(); + double verDifference = getToleranceRecord().getVerReadDifference(); + double distanceDifference = getToleranceRecord().getSlopeReadDifference(); + double horDiffRadian = DeviationValueOfRadianMethod.similarRadianDiff(surveyorDataSource.getAngleHor1(), surveyorDataSource.getAngleHor2()); + double verDiffRadian = DeviationValueOfRadianMethod.similarRadianDiff(surveyorDataSource.getAngleVer1(), surveyorDataSource.getAngleVer2()); + + int resultCode = RESULT_SUCCESS; + if (horDifference < RadianMethod.radian2S(horDiffRadian)) { + resultCode = RESULT_FAILURE_HOR; + } else if (verDifference < RadianMethod.radian2S(verDiffRadian)) { + resultCode = RESULT_FAILURE_VER; + } else if (!isAloneDistance()//增加单独测距判断 + && distanceDifference < distanceReadDiff(surveyorDataSource.getDistance1(), surveyorDataSource.getDistance2())) { + resultCode = RESULT_FAILURE_DISTANCE; + } + onCompleted(resultCode); + } + } + + private void onCompleted(int result) { + if (RESULT_SUCCESS == result) { + checkLeft(); + } else { + String msg = ""; + switch (result) { + case RESULT_FAILURE_HOR: + msg = Tools.getString(R.string.hor_angle_read_data_limit); + break; + case RESULT_FAILURE_VER: + msg = Tools.getString(R.string.ver_angle_read_data_limit); + break; + case RESULT_FAILURE_DISTANCE: + msg = Tools.getString(R.string.distance_read_data_limit); + break; + default: + navigation2(StateType.idle); + return; + } + if (isAutoSurveyOpen()) { + TtsManager.getInstance().speak(msg); + } + failureTipsWithAutoStandStill(msg); + } + } + + /** + * 如果是测回内首次测量,需要判断是否是盘左 + */ + private void checkLeft() { + int currentItem = getSurveyorData().currentIndex(); + LeftOrRight leftOrRight = getSurveyorData().leftOrRight(); + if (leftOrRight == LeftOrRight.left) { + //如果是首次测量,强制要求使用盘左 + double vAngle = getSurveyorData().getAngleVer(); + if (!isFirstValidate(vAngle)) { + failureTipsWithAutoStandStill( + getContext().getString(R.string.error_tips_please_start_from_left), + () -> { + TotalStation.getInstance().requestChangeFace(); + }); + return; + } + } + navigation2(StateType.isHalfCycleZeroCheckReady); + } + + private boolean isFirstValidate(double vAngle) { + return vAngle >= 0 && vAngle <= Math.PI; + } + + /** + * 斜距两次读数差 + * + * @param distance1 读数1 + * @param distance2 读数2 + * @return 读数差(单位毫米) + */ + public static double distanceReadDiff(double distance1, double distance2) { + return Math.abs(distance1 - distance2) * 1000; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_CheckSingleCycleState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_CheckSingleCycleState.java new file mode 100644 index 0000000..d1f154a --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_CheckSingleCycleState.java @@ -0,0 +1,102 @@ +package com.bingce.controlnetwork.surveyor.state.angledistance; + +import android.os.Bundle; + +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.datasource.database.surveyorrecord.SurveyorRecord; +import com.bingce.controlapphelper.datasource.database.tolerance.detail.ToleranceDetailRecord; +import com.bingce.controlapphelper.model.DataCategory; +import com.bingce.controlapphelper.model.LeftOrRight; +import com.bingce.controlapphelper.surveyor.data.ICachedData; +import com.bingce.controlapphelper.surveyor.data.ICycleRecorder; +import com.bingce.controlapphelper.surveyor.data.ISurveyorData; +import com.bingce.controlapphelper.surveyor.method.SingleCycleCheckMethod; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlapphelper.util.IdUtil; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.surveyor.method.SingleCycleTipsMethod; + +import net.tatans.tensorflowtts.tts.TtsManager; + +/** + * 测回内不同方向2c、方向i互差检测 + */ +class _CheckSingleCycleState extends __BaseState { + + public _CheckSingleCycleState(StateManager stateManager) { + super(StateType.checkSingleCycle, stateManager); + } + + @Override + public void enter(Bundle args) { + //1.先将该测回内所有补测数据设置为正常数据,再进行检测 + ICachedData cachedDataSource = getCachedData(); + ICycleRecorder cycleRecorder = getCycleRecorder(); + int pointCount = cachedDataSource.pointCount(); + int currentCycleIndex = cycleRecorder.currentCycleIndex(); + String stationId = stationId(); + + for (int index = 0; index < pointCount; index++) { + String pointId = cachedDataSource.pointId(currentCycleIndex, index); + String keyLeft = IdUtil.createSurveyorRecordId(stationId, currentCycleIndex, pointId, LeftOrRight.left); + SurveyorRecord left = cachedDataSource.getSurveyorRecord(keyLeft); + _changeDirtyRecord2NormalBeforeCheck(left, cachedDataSource); + String keyRight = IdUtil.createSurveyorRecordId(stationId, currentCycleIndex, pointId, LeftOrRight.right); + SurveyorRecord right = cachedDataSource.getSurveyorRecord(keyRight); + _changeDirtyRecord2NormalBeforeCheck(right, cachedDataSource); + } + //2.执行检测 + doCheck(); + } + + private static void _changeDirtyRecord2NormalBeforeCheck( + SurveyorRecord record, ICachedData cachedDataSource) { + if (record == null) { + return; + } + if (record.value1Status.isResurveyed() || record.value2Status.isResurveyed()) { + if (record.value1Status.isResurveyed()) { + record.value1Status = DataCategory.normalCategory(); + } + if (record.value2Status.isResurveyed()) { + record.value2Status = DataCategory.normalCategory(); + } + + cachedDataSource.updateCache(record); + } + } + + private void doCheck() { + ToleranceDetailRecord toleranceRecord = getToleranceRecord(); + ISurveyorData surveyorDataSource = getSurveyorData(); + ICycleRecorder cycleRecorder = getCycleRecorder(); + ICachedData stationSurveyorDataSource = getCachedData(); + + //1.执行单测回内检测 + String error = SingleCycleCheckMethod.check( + toleranceRecord.getHorCycleDirect2CDifference(), toleranceRecord.getVerCycleDirectIDifference(), + stationId(), cycleRecorder.currentCycleIndex(), surveyorDataSource, stationSurveyorDataSource); + if (error != null) { + if (isAutoSurveyOpen()) { + TtsManager.getInstance().speak(Tools.getString(R.string.check_cycle_inner_failed)); + } + //TODO 这里可能存在不对测回内错误处理的情况,后面应该兼容处理下 + SingleCycleTipsMethod.showTips(error, stationId(), cycleRecorder.currentCycleIndex(), + stateDelegate(), + fragmentManager(), + lifecycleOwner()); + } else { + onSuccess(); + } + } + + private void onSuccess() { + //更新测量进度 + setSingleCycleSchedule(getCycleRecorder().currentCycleIndex(), + SurveyorScheduleConstants.STATUE_VALUE_CHECKED); + + //跳转 + navigation2(StateType.isAllCycleCompleted); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_CheckStationState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_CheckStationState.java new file mode 100644 index 0000000..75e2aaa --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_CheckStationState.java @@ -0,0 +1,173 @@ +package com.bingce.controlnetwork.surveyor.state.angledistance; + +import android.os.Bundle; + +import androidx.annotation.WorkerThread; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.point.IPointDataSource; +import com.bingce.controlapphelper.datasource.database.point.PointRecord; +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.datasource.database.surveyorstation.ISurveyorStationDataSource; +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.model.SurveyorPoint; +import com.bingce.controlapphelper.surveyor.data.ICachedData; +import com.bingce.controlapphelper.surveyor.data.ICycleRecorder; +import com.bingce.controlapphelper.surveyor.data.ISurveyorData; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.fragment.SelectReSurveyorPointFragment; +import com.bingce.controlnetwork.surveyor.util.checkadjust.AngleDistanceCheckAdjust; +import com.bingce.controlnetwork.surveyor.util.checkadjust.IStationCheck; +import com.bingce.utils.ThreadPoolUtil; + +import java.util.ArrayList; +import java.util.List; + +/** + * 执行「测站检测」 + *

+ * 前置条件: + * 所有测回都完成测量,并且通过「测回内检测」 + */ +class _CheckStationState extends __BaseState { + + private final IStationCheck stationCheck = new AngleDistanceCheckAdjust(); + + public _CheckStationState(StateManager stateManager) { + super(StateType.checkStation, stateManager); + } + + @Override + public void enter(Bundle args) { + //执行测站检测 + String error = stationCheck.check(stationId(), getToleranceRecord(), getCachedData()); + if (error == null || error.isEmpty()) { + //进入finish状态 + navigation2(StateType.stationCheckedSuccess); + } else { + showErrorTips(error, stationId(), getToleranceRecord().getCycleCount(), + getSurveyorData(), getCycleRecorder(), getCachedData(), + this, + fragmentManager(), + lifecycleOwner()); + } + } + + /** + * 提示错误信息,并让用户选择下一步操作 + */ + static void showErrorTips(String msg, String stationId, int cycleCount, + ISurveyorData surveyorDataSource, + ICycleRecorder cycleRecorder, + ICachedData stationSurveyorDataSource, + __BaseState state, + FragmentManager fragmentManager, LifecycleOwner lifecycleOwner) { + state.optionTips(msg, + Tools.getString(R.string.retest_direction), + Tools.getString(R.string.retest_station), + () -> state.runOnBackground(() -> reSurveyorPoint(stationId, cycleCount, + cycleRecorder, stationSurveyorDataSource, + state, fragmentManager, lifecycleOwner)), + () -> reSurveyorStation(msg, stationId, cycleCount, + surveyorDataSource, cycleRecorder, stationSurveyorDataSource, + state, fragmentManager, lifecycleOwner), + () -> state.enterIdleAndClearSurveyStateAndResetAutoMode(true)); + } + + @WorkerThread + static void reSurveyorPoint(String stationId, int cycleCount, + ICycleRecorder cycleRecorder, + ICachedData cachedData, + __BaseState state, + FragmentManager fragmentManager, LifecycleOwner lifecycleOwner) { + //弹框提示选择重测数据 + ISurveyorStationDataSource dataSource = SurveyorDatabaseFactory.instance.getSurveyorStation(); + SurveyorStationRecord instance = dataSource.getRecordSync(stationId); + if (instance == null) { + state.enterIdleAndClearSurveyStateAndResetAutoMode(true); + return; + } + IPointDataSource pointDataSource = SurveyorDatabaseFactory.instance.getPointDataSource(); + List stationItems = instance.getItems(); + ArrayList ids = new ArrayList<>(); + ArrayList names = new ArrayList<>(); + for (SurveyorPoint item : stationItems) { + if (item.isAbandon()) { + continue; + } + + if (!SurveyorPoint.TYPE_POINT.equals(item.getType())) { + continue; + } + PointRecord pointRecord = pointDataSource.findByIdSync(item.getPointId()); + if (pointRecord == null) { + continue; + } + ids.add(pointRecord.id); + names.add(pointRecord.name); + } + state.runOnUI(() -> SelectReSurveyorPointFragment.pick( + fragmentManager, + lifecycleOwner, + cycleCount, + instance.leftAndRightSurveyor, + ids, + names, + (cycleIndex, pointIds) -> { + if (pointIds == null || pointIds.isEmpty()) { + state.enterIdleAndClearSurveyStateAndResetAutoMode(true); + } else { + //记录补测数据类型,切换测回 + cachedData.markReSurveyor(stationId, cycleIndex, pointIds); + cycleRecorder.changeCycleIndex(cycleIndex); + + //更新测量状态 + state.setCurrentCycle(cycleIndex); + state.setAllCycleSchedule(SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + state.setSingleCycleSchedule(cycleIndex, SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + + //查找新测量目标 + state.findTargetFromBeginInCurrentCycle(true); + } + } + )); + } + + static void reSurveyorStation(String msg, String stationId, int cycleCount, + ISurveyorData surveyorData, + ICycleRecorder cycleRecorder, + ICachedData cachedData, + __BaseState state, + FragmentManager fragmentManager, LifecycleOwner lifecycleOwner) { + state.optionTips(Tools.getString(R.string.is_delete_all_station_data), null, null, + () -> {//1.选择删除测站所有数据,则执行相应逻辑 + ThreadPoolUtil.execute(() -> { + //删除数据 + cachedData.deleteSurveyorRecord(stationId); + + //更新测量进度 + state.setAllCycleSchedule(SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + for (int index = 0; index < cycleCount; index++) { + state.setSingleCycleSchedule(index, SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + } + + state.resetLearnDataTag(); + + //重新测量 + state.findTargetFromBeginInCurrentCycle(true); + }); + }, + () -> {//2.如果用户不选择删除,则循环提示,让他重新在重测和删除做选择 + //循环显示 + showErrorTips(msg, stationId, cycleCount, + surveyorData, cycleRecorder, cachedData, state, + fragmentManager, lifecycleOwner); + }, + () -> state.enterIdleAndClearSurveyStateAndResetAutoMode(true));//3.如果用户忽略,则停留在当前位置 + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_CheckStationSuccessState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_CheckStationSuccessState.java new file mode 100644 index 0000000..ffe951f --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_CheckStationSuccessState.java @@ -0,0 +1,33 @@ +package com.bingce.controlnetwork.surveyor.state.angledistance; + +import android.os.Bundle; + +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.surveyor.data.ISurveyorData; +import com.bingce.controlapphelper.surveyor.state.StateType; + +import net.tatans.tensorflowtts.tts.TtsManager; + +import com.bingce.controlnetwork.R; + +class _CheckStationSuccessState extends __BaseState { + + public _CheckStationSuccessState(StateManager stateManager) { + super(StateType.stationCheckedSuccess, stateManager); + } + + @Override + public void enter(Bundle args) { + ISurveyorData surveyorData = getSurveyorData(); + surveyorData.clearSurveyStateAndPosition(); + //设置测量进度(数据库存储) + setAllCycleSchedule(SurveyorScheduleConstants.STATUE_VALUE_CHECKED); + //通知刷新 + tips(getContext().getString(R.string.tips_all_cycle_has_finish_and_checked), null); + if (isAutoSurveyOpen()) { + runOnUI(() -> TtsManager.getInstance().speak(getContext().getString(R.string.tips_all_cycle_has_finish_and_checked))); + } + //清除测量状态,进入idle,停止自动测量 + enterIdleAndClearSurveyStateAndResetAutoMode(true); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoAutoSurveyorState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoAutoSurveyorState.java new file mode 100644 index 0000000..499830a --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoAutoSurveyorState.java @@ -0,0 +1,32 @@ +package com.bingce.controlnetwork.surveyor.state.angledistance; + +import android.os.Bundle; + +import com.bingce.controlapphelper.surveyor.state.IAutoModeSwitcher; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.totalstation.ControlSurveyResult; + +import net.tatans.tensorflowtts.tts.TtsManager; + +/** + * 先检测是否有其他未完成测回,继续本次测量将删除其他测回数据 + */ +class _DoAutoSurveyorState extends __BaseState { + private final IAutoModeSwitcher autoModeSwitcher; + + public _DoAutoSurveyorState(StateManager stateManager, IAutoModeSwitcher autoModeSwitcher) { + super(StateType.doAutoSurveyor, stateManager); + this.autoModeSwitcher = autoModeSwitcher; + } + + @Override + public void enter(Bundle args) { + if (autoModeSwitcher.isReadyAutoSurvey() == ControlSurveyResult.CODE_SUCCESS) { + autoModeSwitcher.openAutoMode(); + navigation2(StateType.doMove2NextValidate); + TtsManager.getInstance().speak(Tools.getString(R.string.start_auto_measure)); + } + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoCalAdjustState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoCalAdjustState.java new file mode 100644 index 0000000..bbbabf6 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoCalAdjustState.java @@ -0,0 +1,44 @@ +package com.bingce.controlnetwork.surveyor.state.angledistance; + +import android.os.Bundle; + +import com.bingce.controlapphelper.surveyor.method.SurveyorAdjustMethod; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlnetwork.fragment.StationDataAdjustDialogFragment; + +/** + * 平差计算 + */ +public class _DoCalAdjustState extends __BaseState { + + public _DoCalAdjustState(StateManager stateManager) { + super(StateType.doCalAdjust, stateManager); + } + + @Override + public void enter(Bundle args) { + String showType = null; + if (args != null) { + showType = args.getString(StationDataAdjustDialogFragment.KEY_SHOW_TYPE); + } + startCalAdjust(showType); + } + + private void startCalAdjust(String showType) { + runOnBackground(() -> { + SurveyorAdjustMethod.AdjustResult adjustResult = SurveyorAdjustMethod.calStationAdjust(getStation(), getCachedData()); + if (adjustResult.isError()) { + runOnUI(() -> _CheckStationState.showErrorTips(adjustResult.errorString, stationId(), getToleranceRecord().getCycleCount(), + getSurveyorData(), getCycleRecorder(), getCachedData(), + _DoCalAdjustState.this, + fragmentManager(), + lifecycleOwner())); + return; + } + //清除测量状态,进入idle,停止自动测量 + enterIdleAndClearSurveyStateAndResetAutoMode(true); + StationDataAdjustDialogFragment.showDialog(showType, adjustResult.result, adjustResult.showSlopDistance, fragmentManager()); + } + ); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoCalScheduleInAllCycleState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoCalScheduleInAllCycleState.java new file mode 100644 index 0000000..a28e35e --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoCalScheduleInAllCycleState.java @@ -0,0 +1,134 @@ +package com.bingce.controlnetwork.surveyor.state.angledistance; + +import android.os.Bundle; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.schedule.ISurveyorScheduleDataSource; +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleRecord; +import com.bingce.controlapphelper.datasource.database.tolerance.detail.ToleranceDetailRecord; +import com.bingce.controlapphelper.model.DataCategory; +import com.bingce.controlapphelper.model.LeftOrRight; +import com.bingce.controlapphelper.surveyor.data.ICachedData; +import com.bingce.controlapphelper.surveyor.method.FindTargetMethod; +import com.bingce.controlapphelper.surveyor.method.SingleCycleCheckMethod; +import com.bingce.controlapphelper.surveyor.state.IAutoModeSwitcher; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlnetwork.surveyor.method.SingleCycleTipsMethod; +import com.bingce.utils.ThreadPoolUtil; + +/** + * 在所有测回范围计算测量进度。 + *

+ * 1.检测当前测回,如果有没有完成测量,则跳转到相应位置。 + * 2.如果测量完成,检测数据限差。 + * 3.检测其他测回是否有待测数据 + * A.优先考虑dirty数据 + * B.其次考虑empty数据 + * 发现目标,执行跳转 + * 4.如果其他测回也完成测量,检测其限差 + * 发现超限,则立即返回true + * 5.如果其他测回限差通过检测,设置标识测站可以执行检测 + */ +class _DoCalScheduleInAllCycleState extends _DoCalScheduleInSingleCycleState { + + public _DoCalScheduleInAllCycleState(StateManager stateManager, IAutoModeSwitcher autoModeSwitcher) { + super(StateType.doCalScheduleAllCycle, stateManager, autoModeSwitcher); + } + + @Override + protected boolean isNeedCancelEnterIdle(int currentCycle) { + ICachedData cachedData = getCachedData(); + int pointCount = cachedData.pointCount(); + ToleranceDetailRecord toleranceDetailRecord = getToleranceRecord(); + //5.当前测回完成且通过检测,则对其他测回执行检测 + FindTargetMethod.Target resurveyTarget = null; + int emptyCycleIndex = -1; + for (int cycleIndex = 0; cycleIndex < toleranceDetailRecord.getCycleCount(); cycleIndex++) { + if (cycleIndex == getCycleRecorder().currentCycleIndex()) { + continue; + } + + if (_IsSingleCycleCompletedState.isSingleCycleCompleted(stationId(), cycleIndex, getCachedData())) { + //更新该测回进度 + setSingleCycleSchedule(cycleIndex, SurveyorScheduleConstants.STATUE_VALUE_COMPLETED); + continue; + } + //从0号位置盘左开始向后查询,找到需要补测位置 + resurveyTarget = FindTargetMethod.findTargetInSingleCycle( + stationId(), cycleIndex, 0, LeftOrRight.left, pointCount, true, + DataCategory.needResurvey(), cachedData); + if (resurveyTarget != null) { + break; + } + //测量没有完成,且没有补测数据,说明有空数据 + if (emptyCycleIndex < 0) { + emptyCycleIndex = cycleIndex; + } + } + + //6.如果有需要补测数据,优先处理 + if (resurveyTarget != null) { + option4Jump2OtherCycle4Resurvey(resurveyTarget.cycleIndex); + return true; + } + //7.如果其他测回有empty数据,提示 + if (emptyCycleIndex >= 0) { + option4Jump2OtherEmptyCycle(emptyCycleIndex); + return true; + } + //8.所有测回都完成测量(当前测回完成检测),执行检测 + double horCycle2CDiff = toleranceDetailRecord.getHorCycleDirect2CDifference(); + double verCycle2CDiff = toleranceDetailRecord.getVerCycleDirectIDifference(); + for (int cycleIndex = 0; cycleIndex < toleranceDetailRecord.getCycleCount(); cycleIndex++) { + if (cycleIndex == getCycleRecorder().currentCycleIndex()) { + continue; + } + String result = SingleCycleCheckMethod.check( + horCycle2CDiff, + verCycle2CDiff, + stationId(), + cycleIndex, + getSurveyorData(), + getCachedData()); + if (result != null && !result.isEmpty()) { + SingleCycleTipsMethod.showTips(result, + stationId(), + cycleIndex, + stateDelegate(), + fragmentManager(), + lifecycleOwner()); + return true; + } + //更新该测回进度 + setSingleCycleSchedule(cycleIndex, SurveyorScheduleConstants.STATUE_VALUE_CHECKED); + } + //9.所有测回都通过检测,可以执行「测站检测」 + //设置测量进度,但是需要注意,如果station已经通过检测,则不需要设置为completed + ThreadPoolUtil.execute(() -> { + ISurveyorScheduleDataSource scheduleDataSource = + SurveyorDatabaseFactory.instance.getScheduleDataSource(); + String key = SurveyorScheduleConstants.getAllCycleScheduleKey(stationId(), null); + SurveyorScheduleRecord scheduleRecord = scheduleDataSource.findScheduleSync(key); + if (scheduleRecord != null) { + String statue = scheduleRecord.getStatue(); + if (SurveyorScheduleConstants.STATUE_VALUE_CHECKED.equals(statue)) { + onCompletedCheck(); + return; + } + } + scheduleDataSource.record(new SurveyorScheduleRecord(key, + SurveyorScheduleConstants.STATUE_VALUE_COMPLETED)); + + //如果测量完成,则进入测站检测界面 + navigation2(StateType.checkStation); + }); + return true; + } + + static void enter(StateManager stateManager, int cycleIndex) { + Bundle args = new Bundle(); + args.putInt(KEY_CYCLE_INDEX, cycleIndex); + stateManager.enter(StateType.doCalScheduleAllCycle, args); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoCalScheduleInSingleCycleState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoCalScheduleInSingleCycleState.java new file mode 100644 index 0000000..527ced4 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoCalScheduleInSingleCycleState.java @@ -0,0 +1,110 @@ +package com.bingce.controlnetwork.surveyor.state.angledistance; + +import android.os.Bundle; + +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.datasource.database.tolerance.detail.ToleranceDetailRecord; +import com.bingce.controlapphelper.surveyor.data.ICycleRecorder; +import com.bingce.controlapphelper.surveyor.method.SingleCycleCheckMethod; +import com.bingce.controlapphelper.surveyor.state.IAutoModeSwitcher; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlnetwork.surveyor.method.SingleCycleTipsMethod; + +/** + * 在单个测回内计算当前测量进度。 + *

+ * 1.如果有没有完成测量,则跳转到相应位置。 + * 2.如果测量完成,检测数据限差 + * 3.进入idle + */ +class _DoCalScheduleInSingleCycleState extends __BaseState { + private final IAutoModeSwitcher autoModeSwitcher; + + public _DoCalScheduleInSingleCycleState(StateManager stateManager, IAutoModeSwitcher autoModeSwitcher) { + super(StateType.doCalScheduleSingleCycle, stateManager); + this.autoModeSwitcher = autoModeSwitcher; + } + + protected _DoCalScheduleInSingleCycleState(StateType stateType, final StateManager stateManager, IAutoModeSwitcher autoModeSwitcher) { + super(stateType, stateManager); + this.autoModeSwitcher = autoModeSwitcher; + } + + /** + * 在其他测回是否包含需要测量的数据 + *

+ * 当前类默认返回false,不检测其他测回 + */ + protected boolean isNeedCancelEnterIdle(int currentCycle) { + return false; + } + + @Override + final public void enter(Bundle args) { + //重置自动测量状态 + if (autoModeSwitcher.isAutoModeClose()) { + autoModeSwitcher.resetAutoMode(); + } + //计算状态之前,重置测量状态 + getSurveyorData().clearSurveyStateAndPosition(); + + ICycleRecorder cycleRecorder = getCycleRecorder(); + cycleRecorder.changeCycleIndex(args.getInt(KEY_CYCLE_INDEX, 0)); + setCurrentCycle(cycleRecorder.currentCycleIndex()); + + //1.检测当前cycle是否完成测量 + boolean completed = _IsSingleCycleCompletedState.isSingleCycleCompleted( + stationId(), + getCycleRecorder().currentCycleIndex(), + getCachedData()); + //2.如果当前测回还有待测数据,则执行测量 + if (!completed) { + //从当前测回开始处查找目标并执行测量 + findTargetFromBeginInCurrentCycle(false); + return; + } + //3.如果当前测回结束测量,判断是否通过检测 + ToleranceDetailRecord toleranceDetailRecord = getToleranceRecord(); + double horCycle2CDiff = toleranceDetailRecord.getHorCycleDirect2CDifference(); + double verCycle2CDiff = toleranceDetailRecord.getVerCycleDirectIDifference(); + String error = SingleCycleCheckMethod.check( + horCycle2CDiff, + verCycle2CDiff, + stationId(), + getCycleRecorder().currentCycleIndex(), + getSurveyorData(), + getCachedData()); + if (error != null && !error.isEmpty()) { + SingleCycleTipsMethod.showTips(error, + stationId(), + getCycleRecorder().currentCycleIndex(), + stateDelegate(), + fragmentManager(), + lifecycleOwner()); + return; + } + //4.更新测站状态 + setSingleCycleSchedule(getCycleRecorder().currentCycleIndex(), + SurveyorScheduleConstants.STATUE_VALUE_CHECKED); + + //5.检测其他测回状态 + if (isNeedCancelEnterIdle(getCycleRecorder().currentCycleIndex())) { + return; + } + + //6.清空测量状态 + onCompletedCheck(); + } + + protected void onCompletedCheck() { + enterIdleAndClearSurveyStateAndResetAutoMode(true); + } + + protected static final String KEY_CYCLE_INDEX = "___cycle__index__"; + + static void enter(StateManager stateManager, int cycleIndex) { + Bundle args = new Bundle(); + args.putInt(KEY_CYCLE_INDEX, cycleIndex); + stateManager.enter(StateType.doCalScheduleSingleCycle, args); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoDeleteAllCycleState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoDeleteAllCycleState.java new file mode 100644 index 0000000..c687f54 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoDeleteAllCycleState.java @@ -0,0 +1,70 @@ +package com.bingce.controlnetwork.surveyor.state.angledistance; + +import android.os.Bundle; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.config.ConfigConstants; +import com.bingce.controlapphelper.datasource.database.config.IConfigDataSource; +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.surveyor.data.ICachedData; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.utils.ThreadPoolUtil; + +import com.bingce.controlnetwork.R; + +/* + * 删除本测站所有测回数据 + * */ +class _DoDeleteAllCycleState extends __BaseState { + + private static final String KEY_STATION_ID = "__station_id"; + + static Bundle args(String stationId) { + Bundle args = new Bundle(); + args.putString(KEY_STATION_ID, stationId); + return args; + } + + public _DoDeleteAllCycleState(StateManager stateManager) { + super(StateType.doDeleteAllCycle, stateManager); + } + + @Override + public void enter(Bundle args) { + String stationId = args.getString(KEY_STATION_ID); + + optionTipsWithStandStill(getContext().getString(R.string.tips_delete_station_all_surveyor_records), + () -> deleteAllCycleData(stationId)); + } + + private void deleteAllCycleData(String stationId) { + ThreadPoolUtil.execute(() -> { + //删除数据 + ICachedData cachedData = getCachedData(); + cachedData.deleteSurveyorRecord(stationId); + + //清除已经提示测站可以检测标识 + IConfigDataSource configDataSource = + SurveyorDatabaseFactory.instance.getConfigDataSource(); + String key = ConfigConstants.KEY_CONFIG_STATION_CHECK_REMINDED + stationId; + configDataSource.setSync(key, ConfigConstants.VALUE_NO); + + //重置进度 + setAllCycleScheduleSync(SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + for (int cycleIndex = 0; cycleIndex < getToleranceRecord().getCycleCount(); cycleIndex++) { + setSingleCycleScheduleSync(cycleIndex, SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + } + + //重置学习测量的标志 + resetLearnDataTag(); + + //从第一测回开始 + setCurrentCycleSync(0); + + //重新测量,并刷新 + findTargetFromBeginInCurrentCycle(true); + }); + } + + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoDeleteCurrentCycleState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoDeleteCurrentCycleState.java new file mode 100644 index 0000000..6fa1af8 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoDeleteCurrentCycleState.java @@ -0,0 +1,69 @@ +package com.bingce.controlnetwork.surveyor.state.angledistance; + +import android.os.Bundle; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.config.ConfigConstants; +import com.bingce.controlapphelper.datasource.database.config.IConfigDataSource; +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.surveyor.data.ICachedData; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.utils.ThreadPoolUtil; + +import com.bingce.controlnetwork.R; + +class _DoDeleteCurrentCycleState extends __BaseState { + + private static final String KEY_STATION_ID = "__station_id"; + private static final String KEY_PERIOD_INDEX = "__period_index__"; + + static Bundle args(String stationId, int periodIndex) { + Bundle args = new Bundle(); + args.putString(KEY_STATION_ID, stationId); + args.putInt(KEY_PERIOD_INDEX, periodIndex); + return args; + } + + public _DoDeleteCurrentCycleState(StateManager stateManager) { + super(StateType.doDeleteCurrentCycle, stateManager); + } + + @Override + public void enter(Bundle args) { + String stationId = args.getString(KEY_STATION_ID); + int cycleIndex = args.getInt(KEY_PERIOD_INDEX); + + optionTipsWithStandStill(getContext().getString(R.string.tips_delete_current_cycle_surveyor_record), + () -> deleteSingleCycle(stationId, cycleIndex)); + } + + private void deleteSingleCycle(String stationId, int cycleIndex) { + ThreadPoolUtil.execute(() -> { + //删除数据 + ICachedData stationSurveyorDataSource = getCachedData(); + stationSurveyorDataSource.deleteSurveyorRecordSync(stationId, cycleIndex); + + //清除已经提示测站可以检测标识 + IConfigDataSource configDataSource = SurveyorDatabaseFactory.instance.getConfigDataSource(); + String key = ConfigConstants.KEY_CONFIG_STATION_CHECK_REMINDED + stationId; + configDataSource.setSync(key, ConfigConstants.VALUE_NO); + + //设置当前测回 + setCurrentCycleSync(cycleIndex); + //重置所有测回和当次测回进度 + setAllCycleScheduleSync(SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + setSingleCycleScheduleSync(cycleIndex, SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + + if (cycleIndex == 0) { + //当第一测回 + //重置学习测量的标志 + resetLearnDataTag(); + } + + //重新测量,并刷新 + findTargetFromBeginInCurrentCycle(true); + }); + + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoMove2NextValidateState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoMove2NextValidateState.java new file mode 100644 index 0000000..7afaeb3 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoMove2NextValidateState.java @@ -0,0 +1,95 @@ +package com.bingce.controlnetwork.surveyor.state.angledistance; + +import android.os.Bundle; + +import com.bingce.controlapphelper.model.LeftOrRight; +import com.bingce.controlapphelper.surveyor.data.ICachedData; +import com.bingce.controlapphelper.surveyor.data.ICycleRecorder; +import com.bingce.controlapphelper.surveyor.data.ISurveyorData; +import com.bingce.controlapphelper.surveyor.method.FindTargetMethod; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; + +import net.tatans.tensorflowtts.tts.TtsManager; + +/** + * 移动到一个待测量位置 + *

+ * 不会跳转到其他测期 + *

+ * 可能涉及转向(盘左->盘右) + */ +class _DoMove2NextValidateState extends __BaseState { + + public _DoMove2NextValidateState(StateManager stateManager) { + super(StateType.doMove2NextValidate, stateManager); + } + + @Override + public void enter(Bundle args) { + ICachedData cachedData = getCachedData(); + ISurveyorData surveyorData = getSurveyorData(); + ICycleRecorder cycleRecorder = getCycleRecorder(); + + int pointCount = cachedData.pointCount(); + int currentIndex = surveyorData.currentIndex(); + if (currentIndex < 0) { + currentIndex = 0; + } + final int currentCycleIndex = cycleRecorder.currentCycleIndex(); + final LeftOrRight currentSurveyorState = surveyorData.leftOrRight(); + + //1.先查找补测数据 + FindTargetMethod.Target surveyorTarget = FindTargetMethod.findDirtyTargetInSingleCycle(stationId(), currentCycleIndex, + currentIndex, + currentSurveyorState, + pointCount, + true, + cachedData); + //如果在当前测回找到待被测数据,立刻跳转到相应位置 + if (surveyorTarget != null) { + navigation2(surveyorTarget.itemIndex, surveyorTarget.leftOrRight); + return; + } + //2.查找empty数据 + FindTargetMethod.Target emptyTarget = FindTargetMethod.findEmptyTargetInSingleCycle(stationId(), currentCycleIndex, + currentIndex, + currentSurveyorState, + pointCount, + true, + cachedData); + if (emptyTarget != null) { + if (isAutoSurveyOpen()) { + if (emptyTarget.itemIndex == getCachedData().pointCount() - 1 + && emptyTarget.leftOrRight == LeftOrRight.right) { + TtsManager.getInstance().speak(Tools.getString(R.string.start_face_right)); + } + } + //直接跳转到目标点,开启新测量 + navigation2(emptyTarget.itemIndex, emptyTarget.leftOrRight); + return; + } + //3.当前测回完成测量,停留状态 + //重置标识 +// quitSurveyStateAndStandStill(false); + enterIdleAndClearSurveyorStatePosition(); + } + + /** + * 跳转到下一目标点 + * + * @param targetIndex 目标点索引 + * @param targetSurveyorState 测量状态(盘左or盘右) + */ + private void navigation2(int targetIndex, LeftOrRight targetSurveyorState) { + //更新测量进度 + setSurveyPosition(targetIndex, targetSurveyorState); + + //清除测量状态,进入idle,但是不停止自动测量 + enterIdleAndClearSurveyStateAndResetAutoMode(false); + + //滚动 + scroll2(targetIndex); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoMoveBackState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoMoveBackState.java new file mode 100644 index 0000000..14b7152 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoMoveBackState.java @@ -0,0 +1,143 @@ +package com.bingce.controlnetwork.surveyor.state.angledistance; + +import android.os.Bundle; + +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.datasource.database.surveyorrecord.SurveyorRecord; +import com.bingce.controlapphelper.model.DataCategory; +import com.bingce.controlapphelper.model.LeftOrRight; +import com.bingce.controlapphelper.surveyor.data.ICachedData; +import com.bingce.controlapphelper.surveyor.data.ICycleRecorder; +import com.bingce.controlapphelper.surveyor.data.ISurveyorData; +import com.bingce.controlapphelper.surveyor.method.FindTargetMethod; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlapphelper.util.IdUtil; + +import com.bingce.controlnetwork.R; + +/** + * 移动到上一测量结点,伴随删除上次测量数据 + */ +public class _DoMoveBackState extends __BaseState { + + public _DoMoveBackState(StateManager stateManager) { + super(StateType.doMoveBack, stateManager); + } + + @Override + public void enter(Bundle args) { + ICachedData cachedDataSource = getCachedData(); + ISurveyorData surveyorDataSource = getSurveyorData(); + ICycleRecorder cycleRecorder = getCycleRecorder(); + + final int pointCount = cachedDataSource.pointCount(); + final int currentCycle = cycleRecorder.currentCycleIndex(); + final int currentIndex = surveyorDataSource.currentIndex(); + final LeftOrRight leftOrRight = surveyorDataSource.leftOrRight(); + + if (currentIndex < 0) { + //如果测量结束,直接使用0号点盘右 + int targetIndex = 0; + LeftOrRight targetState = LeftOrRight.right; + warningWithStandStill(cachedDataSource, currentCycle, targetIndex, targetState); + return; + } + String currentPointId = cachedDataSource.pointId(currentCycle, currentIndex); + String currentRecordKey = IdUtil.createSurveyorRecordId(stationId(), currentCycle, currentPointId, leftOrRight); + DataCategory dataCategory = cachedDataSource.valueState(currentRecordKey); + if (dataCategory.isNeedResurvey()) {//如果当前位置是脏数据(说明正在补测) + //回退到上一个脏数据位置 + back2LastDirtyPosition(currentCycle, currentIndex, leftOrRight, pointCount, cachedDataSource); + } else if (dataCategory.isEmptyData()) { + //如果是空数据,说明测量进行中,查找上一个数据即可 + //需要提醒用户数据会被删除 + back2LastVisiblePosition(currentCycle, currentIndex, leftOrRight, pointCount, cachedDataSource); + } else { + //bug,不应该有这个地方 + enterIdleAndClearSurveyStateAndResetAutoMode(true); + } + } + + private void back2LastDirtyPosition(int currentCycle, int currentIndex, LeftOrRight leftOrRight, + int pointCount, ICachedData cachedData) { + //反向查找,但是找到目标后不能删除其数据,否则会造成「数据空洞」 + FindTargetMethod.Target target = FindTargetMethod.findTargetInSingleCycle( + stationId(), currentCycle, currentIndex, leftOrRight, pointCount, false, + DataCategory.dirtyAndSurveyed, + cachedData); + if (target == null) { + //在dirtyAndNeedReSurveyor数据没有修复完成之前,不能回退正常数据 + enterIdleAndClearSurveyStateAndResetAutoMode(true); + } else { + //找到dirtyAndSurveyed数据, + //则将其校正为dirtyAndNeedReSurveyor + String pointId = cachedData.pointId(target.cycleIndex, target.itemIndex); + String recordKey = IdUtil.createSurveyorRecordId(stationId(), target.cycleIndex, pointId, target.leftOrRight); + SurveyorRecord surveyorRecord = cachedData.getSurveyorRecord(recordKey); + if (surveyorRecord != null) { + if (surveyorRecord.value1Status.isResurveyed()) { + surveyorRecord.value1Status = DataCategory.needResurvey(); + } + if (surveyorRecord.value2Status.isResurveyed()) { + surveyorRecord.value2Status = DataCategory.needResurvey(); + } + cachedData.updateCache(surveyorRecord); + //重置进度 + resetSchedule(_DoMoveBackState.this, + target.itemIndex, + target.leftOrRight); + } else { + enterIdleAndClearSurveyStateAndResetAutoMode(true); + } + } + } + + private void back2LastVisiblePosition(int currentCycle, int currentIndex, LeftOrRight leftOrRight, + int pointCount, + ICachedData cachedData) { + + //从当前开始,向上查找第一个normal数据 + FindTargetMethod.Target target = + FindTargetMethod.findTargetInSingleCycle( + stationId(), currentCycle, currentIndex, leftOrRight, pointCount, false, + DataCategory.normalCategory(), + cachedData); + if (target == null) { + failureTipsWithAutoStandStill(getContext().getString(R.string.tips_no_more_record_2_rollback)); + return; + } + + warningWithStandStill(cachedData, + currentCycle, + target.itemIndex, + target.leftOrRight); + } + + private void warningWithStandStill( + ICachedData cachedDataSource, + int currentCycle, int itemIndex, LeftOrRight leftOrRight) { + optionTipsWithStandStill(getContext().getString(R.string.tips_will_resurvey_last_record), + () -> { + //删除当前数据 + cachedDataSource.deleteSurveyorRecord(stationId(), + currentCycle, itemIndex, leftOrRight); + //重置进度 + setSingleCycleSchedule(currentCycle, SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + setAllCycleSchedule(SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + + resetSchedule(this, itemIndex, leftOrRight); + }); + } + + private static void resetSchedule(__BaseState state, + int targetIndex, + LeftOrRight leftOrRight) { + //设置测量目标点 + state.setSurveyPosition(targetIndex, leftOrRight); + //清除测量状态,进入idle + //如果当前已经关闭自动测量,就不重置自动测量开关(用户已经表示不想自动测量) + state.enterIdleAndClearSurveyStateAndResetAutoMode(!state.isAutoSurveyClosed()); + + state.scroll2(targetIndex); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoRecordCleanState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoRecordCleanState.java new file mode 100644 index 0000000..222fbc8 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoRecordCleanState.java @@ -0,0 +1,32 @@ +package com.bingce.controlnetwork.surveyor.state.angledistance; + +import android.os.Bundle; + +import com.bingce.controlapphelper.model.DataCategory; +import com.bingce.controlapphelper.surveyor.data.ICachedData; +import com.bingce.controlapphelper.surveyor.data.ICycleRecorder; +import com.bingce.controlapphelper.surveyor.data.ISurveyorData; +import com.bingce.controlapphelper.surveyor.state.StateType; + +/** + * 记录测量数据 + */ +class _DoRecordCleanState extends __BaseState { + public _DoRecordCleanState(StateManager stateManager) { + super(StateType.doRecordClean, stateManager); + } + + @Override + public void enter(Bundle args) { + ICachedData cacheData = getCachedData(); + ISurveyorData surveyorData = getSurveyorData(); + ICycleRecorder cycleRecorder = getCycleRecorder(); + //设置数据正常 + surveyorData.setDataCategory(DataCategory.normalCategory()); + //存储(缓存+数据库) + cacheData.cache(cycleRecorder.currentCycleIndex(), surveyorData); + + //检测单测回是否完成 + navigation2(StateType.isSingleCycleCompleted); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoSurveyorState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoSurveyorState.java new file mode 100644 index 0000000..a04047a --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoSurveyorState.java @@ -0,0 +1,298 @@ +package com.bingce.controlnetwork.surveyor.state.angledistance; + +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; + +import com.bingce.controlapphelper.datasource.database.surveyorstation.model.SurveyorPoint; +import com.bingce.controlapphelper.datasource.database.tolerance.detail.ToleranceDetailRecord; +import com.bingce.controlapphelper.event.SurveyStateEvent; +import com.bingce.controlapphelper.model.DataCategory; +import com.bingce.controlapphelper.model.LeftOrRight; +import com.bingce.controlapphelper.surveyor.data.ICachedData; +import com.bingce.controlapphelper.surveyor.data.ICycleRecorder; +import com.bingce.controlapphelper.surveyor.data.ISurveyorData; +import com.bingce.controlapphelper.surveyor.state.ISurveyState; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlapphelper.surveyor.surveyor.ISurveyorListener; +import com.bingce.controlapphelper.surveyor.surveyor.ISurveyorRemindListener; +import com.bingce.controlapphelper.surveyor.surveyor.RequestSurveyorParam; +import com.bingce.controlapphelper.util.DebugMsgUtil; +import com.bingce.controlapphelper.util.IdUtil; +import com.bingce.controlapphelper.util.SettingValueUtil; +import com.bingce.controlapphelper.util.SurveyorCycleUtil; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.surveyor.state.StateConstants; +import com.bingce.device.Device; +import com.bingce.totalstation.TotalStation; +import com.bingce.totalstation.protocol.south.SouthAndroidBtInterface; +import com.bingce.totalstation.protocol.topcon.TopconInterface; + +import net.tatans.tensorflowtts.tts.TtsManager; + +import blankj.utilcode.util.ToastUtils; + +/** + * 先检测是否有其他未完成测回,继续本次测量将删除其他测回数据 + */ +class _DoSurveyorState extends __BaseState implements ISurveyorListener, ISurveyorRemindListener { + private final ISurveyState surveyState; + //最多测量次数,如果3次测量都没有获取正常数据,则跳过 + private static final int MAX_SURVEYOR_COUNT = 3; + private static int failureCount = 0; + private static final int RESULT_SUCCESS = 0; + private static final int RESULT_FAILURE_EXCEED_MAX = 1;//测量失败次数超出最大限制 + private static final int RESULT_FAILURE_ERROR = 2;//测量失败,又没有允许重复尝试 + private static final boolean allowTryWhenFailure = true;//在测量失败的时候,是否允许重新测量 + + private int measureTimeIndex = 0;//当前测点是第几次测量 + private boolean isAlreadyRemindUserAimingAtWire = false; + + private final Handler handler; + + public _DoSurveyorState(StateManager stateManager, ISurveyState surveyState) { + super(StateType.doSurveyor, stateManager); + this.surveyState = surveyState; + handler = new Handler(Looper.getMainLooper()); + } + + @Override + public void enter(Bundle args) { + measureTimeIndex = 0; + + isAlreadyRemindUserAimingAtWire = false; + if (args != null) { + isAlreadyRemindUserAimingAtWire = args.getBoolean(StateConstants.KEY_IS_ROTATION_READY_STATE); + } + + ToleranceDetailRecord toleranceRecord = getToleranceRecord(); + ICycleRecorder cycleRecorder = getCycleRecorder(); + ICachedData cachedDataSource = getCachedData(); + + int currentCycleIndex = cycleRecorder.currentCycleIndex(); + int cycleCount = toleranceRecord.getCycleCount(); + int pointCount = cachedDataSource.pointCount(); + + int otherCycle = -1; + //1.先检测其他测回是否有正在测量数据 + for (int cycleIndex = 0; cycleIndex < cycleCount; cycleIndex++) { + if (cycleIndex == currentCycleIndex) { + continue; + } + //遍历该测回内所有点,检测是否有测量数据 + for (int itemIndex = 0; itemIndex < pointCount; itemIndex++) { + String pointId = cachedDataSource.pointId(cycleIndex, 0); + String key = IdUtil.createSurveyorRecordId(stationId(), cycleIndex, pointId, LeftOrRight.left); + //检测该测回是否有数据,目前应该只需要检测盘左0就可以了,因为一个测回内数据不能跳过 + DataCategory dataCategory = cachedDataSource.valueState(key); + if (dataCategory.hasData()) { + //说明该测回有数据,则进一步检测是否完成 + if (!cachedDataSource.isSingleCycleAllDataValidate(cycleIndex)) { + //已经测量但是没有完成,则提示 + otherCycle = cycleIndex; + break; + } + } + } + //如果当前遍历到的测回有数据,则退出遍历,提醒用户 + if (otherCycle >= 0) { + break; + } + } + //2.如果其他测回有正在测量数据,且没有完成测量,提示用户继续测量将会删除其数据 + if (otherCycle != -1) { + final int targetCycleIndex = otherCycle; + optionTipsWithStandStill( + SurveyorCycleUtil.cycleName(otherCycle) + Tools.getString(R.string.unfinished_measurements_starting_this_measurement_will_delete), + () -> optionTipsWithStandStill( + Tools.getString(R.string.confirm_delete) + SurveyorCycleUtil.cycleName(targetCycleIndex) + Tools.getString(R.string.data_ask), + () -> { + String stationId = stationId(); + //删除数据 + cachedDataSource.deleteSurveyorRecord(stationId, targetCycleIndex); +// isAlreadyRemindUserAimingAtWire = false; + //执行测量 + doSurveyor(); + })); + return; + } + + //3.其他测回没有正在测量数据,则在当前测回执行测量 + doSurveyor(); + } + + private void doSurveyor() { + failureCount = 0; + //判断设备是否连接 + if (surveyorImpl().isReady()) { + //发送测量信号 + SurveyStateEvent.postSurveying(positionFragment); + //注册接收测量数据 + surveyorImpl().prepareSurveyor(); + sendSurveyRequest(); + } else { + enterIdleAndClearSurveyStateAndResetAutoMode(true); + Device.getInstance().remindConnectDevice(); + } + } + + @Override + public void onReceive(double originalHa, double originalVa, double sd, double clockwiseHa, double topVa, double hd, double vd) { + //重置错误读数 + failureCount = 0; + if (getSurveyorData().onSurveyor(originalHa, originalVa, sd, hd)) { + //测量数据成功,可以退出测量状态 + onSuccess(); + } else {//测量数据不完全,需要继续测量 + measureTimeIndex = 1;//更新测量索引 + refreshUI(); + + if (TotalStation.getInstance() instanceof TopconInterface) { + //这个仪器需要延迟500毫秒发送指令 + handler.postDelayed(this::sendSurveyRequest, 500); + } else if (TotalStation.getInstance() instanceof SouthAndroidBtInterface) { + handler.postDelayed(this::sendSurveyRequest, 100); + } else { + sendSurveyRequest(); + } + } + } + + @Override + public void onError(String errorMsg) { + TtsManager.getInstance().speak(errorMsg); + if (allowTryWhenFailure) {//允许重新测量 + if (!isLive()) { + return; + } + //测量出现异常,需要处理 + failureCount++; + if (failureCount >= MAX_SURVEYOR_COUNT) { + if (isAutoSurveyOpen()) { + TtsManager.getInstance().speak(Tools.getString(R.string.many_measure_failed)); + } + onCompleted(RESULT_FAILURE_EXCEED_MAX, Tools.getString(R.string.many_measure_failed_1)); + } else { + //再次尝试 + DebugMsgUtil.canWrite("仪器返回错误信息:" + errorMsg); + DebugMsgUtil.canWrite("开始再次测量"); + + sendSurveyRequest(); + ToastUtils.showShort(R.string.receive_data_time_out); + } + } else { + onCompleted(RESULT_FAILURE_ERROR, errorMsg); + } + } + + private void sendSurveyRequest() { + int currentIndex = getCurrentIndex(); + if (currentIndex < 0) { + currentIndex = 0; + } + + SurveyorPoint surveyorPoint = getCachedData().getSurveyorPoint(getCycleRecorder().currentCycleIndex(), currentIndex); + ISurveyorData surveyorData = getSurveyorData(); + + surveyorImpl().requestSurveyor(new RequestSurveyorParam(getRequestSurveyorParamAuto(), getInstrumentHeight(), surveyorPoint, measureTimeIndex, + surveyorData.currentIndex(), surveyorData.leftOrRight(), isAlreadyRemindUserAimingAtWire)); + } + + private void onSuccess() { + onCompleted(RESULT_SUCCESS, ""); + } + + private void onCompleted(int result, String msg) { + //退出测量 + surveyorImpl().exitSurveyor(); + switch (result) { + case RESULT_SUCCESS://进入读数检测状态 + //检测是否处于「自动测量」 + if (!surveyState.isAutoSurveying()) { + SurveyStateEvent.postSuccess(positionFragment); + } + navigation2(StateType.checkReadData); + break; + case RESULT_FAILURE_EXCEED_MAX: +// boolean allowAbandon = getStation().isAllowAbandon(); + if (SettingValueUtil.isAbandonPoint() && isAllowAbandonForVarifyIndex()) { + dealErrorDataSkip(msg); + } else { + dealErrorDataNormal(msg); + } + break; + case RESULT_FAILURE_ERROR: + dealErrorDataNormal(msg); + break; + default: + throw new RuntimeException("un reached state -- surveyor"); + } + } + + @Override + protected void quite() { + super.quite(); + surveyorImpl().exitSurveyor(); + } + + @Override + protected void resume() { + getSurveyorData().clearSurveyState(); + } + + @Override + public void remindUserAimingAtWire() { + //退出测量 + surveyorImpl().exitSurveyor(); + navigation2(StateType.doWellMeasureRotationReady); + } + + private void dealErrorDataNormal(String msg) { + SurveyStateEvent.postFailure(positionFragment); + //进入失败状态 + Bundle args = _SurveyorFailureState.args(msg); + navigation2(StateType.SurveyorFailure, args); + } + + private void dealErrorDataNormal(String msg, boolean isShowDialog) { + SurveyStateEvent.postFailure(positionFragment); + //进入失败状态 + Bundle args = _SurveyorFailureState.args(msg, isShowDialog); + navigation2(StateType.SurveyorFailure, args); + } + + private void dealErrorDataSkip(String msg) { + optionTipsCountDown(msg + Tools.getString(R.string.is_it_abandoned), + Tools.getString(R.string.switch_abandon), + Tools.getString(R.string.ignore), + () -> { + changeSkip(getCycleRecorder().currentCycleIndex(), getCurrentIndex()); + navigation2(StateType.isSingleCycleCompleted); + }, + () -> dealErrorDataNormal(msg, false), + () -> dealErrorDataNormal(msg, false)); + } + + /** + * 针对第一个点和闭合是否废弃验证 + * + * @return + */ + private boolean isAllowAbandonForVarifyIndex() { + boolean autoClose = getStation().isAutoClose(); + int pointCount = getCachedData().pointCount(); + boolean abandon = true; + int currentIndex = getCurrentIndex(); + if (autoClose) { + if (currentIndex == 0 || currentIndex == pointCount - 1) { + abandon = false; + } + } else { + if (currentIndex == 0) { + abandon = false; + } + } + return abandon; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoWellMeasureRotationReadyState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoWellMeasureRotationReadyState.java new file mode 100644 index 0000000..9bdbde8 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_DoWellMeasureRotationReadyState.java @@ -0,0 +1,30 @@ +package com.bingce.controlnetwork.surveyor.state.angledistance; + +import android.os.Bundle; + +import com.bingce.controlapphelper.event.AutoSurveyorButtonVisibleEvent; +import com.bingce.controlapphelper.event.SurveyStateEvent; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlnetwork.R; + +import net.tatans.tensorflowtts.tts.TtsManager; + +import org.greenrobot.eventbus.EventBus; + +/** + * 钢丝测量旋转到位状态 + */ +class _DoWellMeasureRotationReadyState extends __BaseState { + + public _DoWellMeasureRotationReadyState(StateManager stateManager) { + super(StateType.doWellMeasureRotationReady, stateManager); + } + + @Override + public void enter(Bundle args) { + runOnUI(() -> TtsManager.getInstance().speak(getContext().getString(R.string.please_aiming_at_alone_distance_point_then_measure))); + SurveyStateEvent.postIdle(positionFragment); + EventBus.getDefault().post(new AutoSurveyorButtonVisibleEvent(positionFragment, false, true)); + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_IdleState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_IdleState.java new file mode 100644 index 0000000..0606880 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_IdleState.java @@ -0,0 +1,134 @@ +package com.bingce.controlnetwork.surveyor.state.angledistance; + +import android.os.Bundle; + +import androidx.annotation.NonNull; + +import com.bingce.controlapphelper.event.AutoSurveyorButtonVisibleEvent; +import com.bingce.controlapphelper.event.SurveyStateEvent; +import com.bingce.controlapphelper.surveyor.state.IAutoModeSwitcher; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.totalstation.ControlSurveyResult; +import com.bingce.utils.ThreadPoolUtil; + +import net.tatans.tensorflowtts.tts.TtsManager; + +import org.greenrobot.eventbus.EventBus; + +import com.bingce.controlnetwork.fragment.TipsWith2OptionFragment; + +/** + * 空闲状态 + *

+ * 将刷新界面 + */ +class _IdleState extends __BaseState { + private final @NonNull + IAutoModeSwitcher autoModeSwitcher; + + public _IdleState(StateManager stateManager, @NonNull IAutoModeSwitcher autoModeSwitcher) { + super(StateType.idle, stateManager); + this.autoModeSwitcher = autoModeSwitcher; + } + + @Override + public void enter(Bundle args) { + //1.刷新界面 + refreshUI(); + + refreshGoBackBtnEnable(); + + //3.当前cycle是否完成测量 + boolean completed = _IsSingleCycleCompletedState.isSingleCycleCompleted( + stationId(), + getCycleRecorder().currentCycleIndex(), + getCachedData()); + //4.检测是否满足自动测量条件 + ThreadPoolUtil.execute(() -> { + //判断当前条件是否满足自动测量 + + boolean haveAutoCondition = haveAutoCondition(); + + if (haveAutoCondition && autoModeSwitcher.isAutoModeOpen() && isLive()) { + navigation2(StateType.doSurveyor); + } else if (haveAutoCondition && autoModeSwitcher.isAutoModeNotSpecial() && !completed) { + //用户选择后会发送通知,更新测量按钮UI + tips4StartAutoSurvey(); + } else { +// ControlSurveyResult.isAbandon(autoMeasureReadyCode) != null//这个错误 + if (autoModeSwitcher.isAutoModeOpen()) { + autoModeSwitcher.resetAutoMode(); + } + postEvent(haveAutoCondition, autoModeSwitcher.isAutoModeOpen(), completed); + } + + }); + } + + /** + * 弹框提示用户是否开启自动测量 + */ + private void tips4StartAutoSurvey() { + runOnUI(() -> + TipsWith2OptionFragment.hardTips( + fragmentManager(), + lifecycleOwner(), + getContext().getString(R.string.tips_finish_study_should_auto_survey), + new TipsWith2OptionFragment.SimpleCallback() { + @Override + public void onConfirm() { + TtsManager.getInstance().speak(Tools.getString(R.string.start_auto_measure)); + autoModeSwitcher.openAutoMode(); + navigation2(StateType.doSurveyor); + + postEvent(true, true, false); + } + + @Override + public void onCancel() { + autoModeSwitcher.closeAutoMode(); + + postEvent(true, false, false); + } + + @Override + public void onIgnore() { + autoModeSwitcher.closeAutoMode(); + + postEvent(true, false, false); + } + } + )); + } + + private void postEvent(boolean isReadyAutoSurvey, boolean isOpenAutoSurvey, boolean isSingleCompleted) { + EventBus.getDefault().post(new AutoSurveyorButtonVisibleEvent(positionFragment, isReadyAutoSurvey, isOpenAutoSurvey)); + if (isSingleCompleted) { + SurveyStateEvent.postCompleted(positionFragment); + } else if (!isOpenAutoSurvey) { + SurveyStateEvent.postIdle(positionFragment); + } + } + + @Override + protected void resume() { + autoModeSwitcher.resetAutoMode(); + //刷新测量按钮 + boolean completed = _IsSingleCycleCompletedState.isSingleCycleCompleted( + stationId(), + getCycleRecorder().currentCycleIndex(), + getCachedData()); + boolean isReady = autoModeSwitcher.isReadyAutoSurvey() == ControlSurveyResult.CODE_SUCCESS; + + postEvent(isReady, false, completed); + } + + private boolean haveAutoCondition() { + int autoMeasureReadyCode = autoModeSwitcher.isReadyAutoSurvey(); + return autoMeasureReadyCode == ControlSurveyResult.CODE_SUCCESS; + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_Is2CCheckReadyState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_Is2CCheckReadyState.java new file mode 100644 index 0000000..4b17c04 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_Is2CCheckReadyState.java @@ -0,0 +1,55 @@ +package com.bingce.controlnetwork.surveyor.state.angledistance; + +import android.os.Bundle; + +import com.bingce.controlapphelper.model.DataCategory; +import com.bingce.controlapphelper.model.LeftOrRight; +import com.bingce.controlapphelper.surveyor.data.ICachedData; +import com.bingce.controlapphelper.surveyor.data.ICycleRecorder; +import com.bingce.controlapphelper.surveyor.data.ISurveyorData; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlapphelper.util.IdUtil; + +/** + * 判断是否满足「2C」检测条件 + */ +class _Is2CCheckReadyState extends __BaseState { + private static final int RESULT_YES = 0;//可以检测「2C」 + private static final int RESULT_NO = 1;//不可以检测「2C」 + + public _Is2CCheckReadyState(StateManager stateManager) { + super(StateType.isReady2CCheck, stateManager); + } + + @Override + public void enter(Bundle args) { + ISurveyorData surveyorDataSource = getSurveyorData(); + ICycleRecorder cycleRecorder = getCycleRecorder(); + ICachedData cachedData = getCachedData(); + + int currentIndex = surveyorDataSource.currentIndex(); + int currentCycleIndex = cycleRecorder.currentCycleIndex(); + LeftOrRight currentLeftOrRight = surveyorDataSource.leftOrRight(); + + //只需要对面位置有「新鲜数据」,就能执行2c + //当前位置正处于测量,数据还没有缓存,所以不需要检测数据合法性 + String pointId = cachedData.pointId(currentCycleIndex, currentIndex); + DataCategory oppositeCategory = cachedData.valueState( + IdUtil.createSurveyorRecordId(stationId(), currentCycleIndex, pointId, currentLeftOrRight.opposite())); + if (oppositeCategory.isFreshData()) { + onCompleted(RESULT_YES); + } else { + onCompleted(RESULT_NO); + } + } + + private void onCompleted(int result) { + if (RESULT_YES == result) { + navigation2(StateType.check2C); + } else if (RESULT_NO == result) { + navigation2(StateType.doRecordClean); + } else { + throw new RuntimeException("error half cycle complete check"); + } + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_IsAllCycleCompletedState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_IsAllCycleCompletedState.java new file mode 100644 index 0000000..01a20e4 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_IsAllCycleCompletedState.java @@ -0,0 +1,90 @@ +package com.bingce.controlnetwork.surveyor.state.angledistance; + +import android.os.Bundle; + +import androidx.annotation.NonNull; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.config.ConfigConstants; +import com.bingce.controlapphelper.datasource.database.config.ConfigRecord; +import com.bingce.controlapphelper.datasource.database.config.IConfigDataSource; +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.surveyor.data.SpeakCache; +import com.bingce.controlapphelper.surveyor.state.IAutoModeSwitcher; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlapphelper.util.SurveyorCycleUtil; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.utils.ThreadPoolUtil; + +import net.tatans.tensorflowtts.tts.TtsManager; + +/* + * 检测是否所有 测期都完成了测量 + * + * 只有在当前测期完成测量之后,才会进入当前状态 + * */ +public class _IsAllCycleCompletedState extends __BaseState { + private static final int INVALIDATE_CYCLE = -1; + private final IAutoModeSwitcher autoModeSwitcher; + + public _IsAllCycleCompletedState(@NonNull StateManager stateManager, IAutoModeSwitcher autoModeSwitcher) { + super(StateType.isAllCycleCompleted, stateManager); + this.autoModeSwitcher = autoModeSwitcher; + } + + @Override + public void enter(Bundle args) { + int cycleCount = getToleranceRecord().getCycleCount(); + + int theCycleNotAllDataIsValidate = INVALIDATE_CYCLE; + //查找数据不全的测回 + for (int cycleIndex = 0; cycleIndex < cycleCount; cycleIndex++) { + if (!getCachedData().isSingleCycleAllDataValidate(cycleIndex)) { + //对不全数据的测回赋值 + theCycleNotAllDataIsValidate = cycleIndex; + break; + } + } + + boolean completed = INVALIDATE_CYCLE == theCycleNotAllDataIsValidate; + + if (completed) { + if (isAutoSurveyOpen()) { + //检测是否已经提示 + //检测是否需要提示测站检测 + IConfigDataSource configDataSource = + SurveyorDatabaseFactory.instance.getConfigDataSource(); + ThreadPoolUtil.execute(() -> { + String key = ConfigConstants.KEY_CONFIG_STATION_CHECK_REMINDED + stationId(); + ConfigRecord record = configDataSource.getByKeySync(key); + if (record == null || ConfigConstants.VALUE_NO.equals(record.getConfigValue())) { + runOnUI(() -> TtsManager.getInstance().speak(Tools.getString(R.string.all_cycle_completed))); + } + }); + } + //标识测站完成测量(数据库存储) + setAllCycleSchedule(SurveyorScheduleConstants.STATUE_VALUE_COMPLETED); + //进入idle状态 + //清除测量状态,进入测站检测,停止自动测量 + enterStationCheckAndClearSurveyStateAndResetAutoMode(); + } else { + if (autoModeSwitcher.isAutoModeOpen()) { + //直接切换测回 + //切换测回 + getCycleRecorder().changeCycleIndex(theCycleNotAllDataIsValidate); + //修改当前测回 + setCurrentCycle(theCycleNotAllDataIsValidate); + //存储一下已经播放切换测回的的节点 + SpeakCache.getInstance().saveSpeakSwitchCycle(); + //查找测量目标 + findTargetFromBeginInCurrentCycle(false); + //播报 + TtsManager.getInstance().speak(Tools.getString(R.string.current_cycle_complete_start_surveyor) + SurveyorCycleUtil.cycleName(theCycleNotAllDataIsValidate)); + } else { + //提示是否进入其他未完成测回继续测量 + option4Jump2OtherEmptyCycle(theCycleNotAllDataIsValidate); + } + } + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_IsHalfCycleZeroCheckReadyState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_IsHalfCycleZeroCheckReadyState.java new file mode 100644 index 0000000..cfdc465 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_IsHalfCycleZeroCheckReadyState.java @@ -0,0 +1,68 @@ +package com.bingce.controlnetwork.surveyor.state.angledistance; + +import android.os.Bundle; + +import com.bingce.controlapphelper.model.DataCategory; +import com.bingce.controlapphelper.model.LeftOrRight; +import com.bingce.controlapphelper.surveyor.data.ICachedData; +import com.bingce.controlapphelper.surveyor.data.ICycleRecorder; +import com.bingce.controlapphelper.surveyor.data.ISurveyorData; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlapphelper.util.IdUtil; + +/* + * 判断是否需要检测「半测回归零差」 + * */ +class _IsHalfCycleZeroCheckReadyState extends __BaseState { + private static final int RESULT_ERROR = -1;//状态错误 + private static final int RESULT_YES = 0;//可以检测「半测回归零差」 + private static final int RESULT_NO = 1;//不可以检测「半测回归零差」 + + public _IsHalfCycleZeroCheckReadyState(StateManager stateManager) { + super(StateType.isHalfCycleZeroCheckReady, stateManager); + } + + + @Override + public void enter(Bundle args) { + if (isStationClosed()) { + ICachedData cachedData = getCachedData(); + ISurveyorData surveyorData = getSurveyorData(); + int pointCount = cachedData.pointCount(); + int currentItemIndex = surveyorData.currentIndex(); + + //检测target处数据类型,如果存在dirty或empty数据,则不进行半测回归零 + //当前位置不需要检测,因为下处于测量中 + int result = RESULT_NO; + if (currentItemIndex == 0 || currentItemIndex == pointCount - 1) { + ICycleRecorder cycleRecorder = getCycleRecorder(); + int cycleIndex = cycleRecorder.currentCycleIndex(); + String stationId = stationId(); + LeftOrRight leftOrRight = surveyorData.leftOrRight(); + int targetIndex = pointCount - 1 - currentItemIndex; + + String targetPointId = cachedData.pointId(cycleRecorder.currentCycleIndex(), targetIndex); + String targetKey = IdUtil.createSurveyorRecordId(stationId, cycleIndex, targetPointId, leftOrRight); + DataCategory targetDataCategory = cachedData.valueState(targetKey); + //对面数据正常,可以执行半测回归零 + if (targetDataCategory.isFreshData()) { + result = RESULT_YES; + } + } + onCompleted(result); + } else { + onCompleted(RESULT_ERROR); + } + + } + + private void onCompleted(int result) { + if (RESULT_YES == result) {//检测半测回归零 + navigation2(StateType.checkHalfCycleZero); + } else if (RESULT_NO == result || RESULT_ERROR == result) { + navigation2(StateType.isReady2CCheck); + } else { + throw new RuntimeException("error half cycle complete check"); + } + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_IsSingleCycleCompletedState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_IsSingleCycleCompletedState.java new file mode 100644 index 0000000..e54e20c --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_IsSingleCycleCompletedState.java @@ -0,0 +1,75 @@ +package com.bingce.controlnetwork.surveyor.state.angledistance; + +import android.os.Bundle; + +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.model.DataCategory; +import com.bingce.controlapphelper.model.LeftOrRight; +import com.bingce.controlapphelper.surveyor.data.ICachedData; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlapphelper.util.IdUtil; + + +public class _IsSingleCycleCompletedState extends __BaseState { + private static final int RESULT_YES = 0;//测回结束 + private static final int RESULT_NO = 1;//测回未结束 + + public _IsSingleCycleCompletedState(StateManager stateManager) { + super(StateType.isSingleCycleCompleted, stateManager); + } + + @Override + public void enter(Bundle args) { + onCompleted( + isSingleCycleCompleted(stationId(), + getCycleRecorder().currentCycleIndex(), + getCachedData())); + } + + private void onCompleted(boolean completed) { + if (completed) { + //这里先刷新下UI,不然弹窗后面的list不显示最后一条数据 + getSurveyorData().clearSurveyStateAndPosition(); + refreshUI(); + + int cycleIndex = getCycleRecorder().currentCycleIndex(); + //更新测回测量进度 + setSingleCycleSchedule(cycleIndex, SurveyorScheduleConstants.STATUE_VALUE_COMPLETED); + //状态切换 + navigation2(StateType.checkSingleCycle); + } else { + findTargetFromBeginInCurrentCycle(false); + } + } + + /** + * 判断单个测回是否测量完成(不要求通过检测) + */ + public static boolean isSingleCycleCompleted(String stationId, int cycleIndex, ICachedData cachedData) { + int result = RESULT_YES; + + //测回内所有数据都是「新鲜数据」才能执行「测回内检测」 + for (int index = 0; index < cachedData.pointCount(); index++) { + + if (cachedData.isPointAbandon(cycleIndex, index)) { + continue; + } + + String pointId = cachedData.pointId(cycleIndex, index); + + String leftKey = IdUtil.createSurveyorRecordId(stationId, cycleIndex, pointId, LeftOrRight.left); + String rightKey = IdUtil.createSurveyorRecordId(stationId, cycleIndex, pointId, LeftOrRight.right); + + DataCategory leftDataCategory = cachedData.valueState(leftKey); + DataCategory rightDataCategory = cachedData.valueState(rightKey); + + if (leftDataCategory.isFreshData() && rightDataCategory.isFreshData()) { + continue; + } + result = RESULT_NO; + break; + } + + return RESULT_YES == result; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_SurveyorFailureState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_SurveyorFailureState.java new file mode 100644 index 0000000..9135bf6 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/_SurveyorFailureState.java @@ -0,0 +1,52 @@ +package com.bingce.controlnetwork.surveyor.state.angledistance; + +import android.os.Bundle; + +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; + +/* + * 仪器导致的测量失败 + * + * 全站仪多次测量失败,进入该状态 + * */ +class _SurveyorFailureState extends __BaseState { + + public _SurveyorFailureState(StateManager stateManager) { + super(StateType.SurveyorFailure, stateManager); + } + + @Override + public void enter(Bundle args) { + String error = ""; + boolean isShowDialog = true; + if (args != null) { + error = args.getString(KEY); + isShowDialog = args.getBoolean(KEY_IS_SHOW_DIALOG, true); + } + + if (isShowDialog) { + failureTipsWithAutoStandStill(error + Tools.getString(R.string.please_observe_target)); + } else { + enterIdleAndClearSurveyStateAndResetAutoMode(true); + } + + } + + private static final String KEY = "error"; + private static final String KEY_IS_SHOW_DIALOG = "KEY_IS_SHOW_DIALOG"; + + public static Bundle args(String error) { + Bundle args = new Bundle(); + args.putString(KEY, error); + return args; + } + + public static Bundle args(String error, boolean isShowDialog) { + Bundle args = new Bundle(); + args.putString(KEY, error); + args.putBoolean(KEY_IS_SHOW_DIALOG, isShowDialog); + return args; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/__BaseState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/__BaseState.java new file mode 100644 index 0000000..a4dfef3 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/angledistance/__BaseState.java @@ -0,0 +1,586 @@ +package com.bingce.controlnetwork.surveyor.state.angledistance; + +import android.content.Context; +import android.os.Bundle; +import android.text.TextUtils; + +import androidx.annotation.NonNull; +import androidx.annotation.StringRes; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.model.SurveyorPoint; +import com.bingce.controlapphelper.datasource.database.tolerance.detail.ToleranceDetailRecord; +import com.bingce.controlapphelper.model.LeftOrRight; +import com.bingce.controlapphelper.surveyor.data.ICachedData; +import com.bingce.controlapphelper.surveyor.data.ICycleRecorder; +import com.bingce.controlapphelper.surveyor.data.ISurveyorData; +import com.bingce.controlapphelper.surveyor.method.model.IStateDelegate; +import com.bingce.controlapphelper.surveyor.state.IAutoModeSwitcher; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlapphelper.surveyor.surveyor.ISurveyor; +import com.bingce.controlapphelper.surveyor.surveyor.RequestSurveyorParamAuto; +import com.bingce.controlapphelper.util.SurveyorCycleUtil; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.fragment.TipsFragment; +import com.bingce.controlnetwork.fragment.TipsWith2OptionFragment; +import com.bingce.controlnetwork.fragment.stationsurvey.angledistance.MeasureFragment; +import com.bingce.utils.ThreadPoolUtil; + +import java.util.List; + +import blankj.utilcode.util.ToastUtils; + +public abstract class __BaseState { + private final StateType type; + private final StateManager stateManager; + + protected final int positionFragment = MeasureFragment.POSITION_DIRECTION_MEASURE; + + /** + * 判断常量 + */ + private final int DEFAULT_AUTO_MODE = 0; + private final int RESET_AUTO_MODE = 1; + private final int CLOSE_AUTO_MODE = 2; + + public __BaseState(final StateType stateType, final StateManager stateManager) { + this.type = stateType; + this.stateManager = stateManager; + } + + final protected StateType getType() { + return type; + } + + final protected @NonNull + ToleranceDetailRecord getToleranceRecord() { + return stateManager.toleranceRecord; + } + + final protected @NonNull + ISurveyorData getSurveyorData() { + return stateManager.surveyorData; + } + + private @NonNull + IAutoModeSwitcher autoModeRecorder() { + return stateManager; + } + + /** + * 设置测量位置 + */ + final protected void setSurveyPosition(int index, LeftOrRight leftOrRight) { + stateManager.surveyorData.setCurrentIndex(index); + stateManager.surveyorData.setLeftOrRight(leftOrRight); + //新增 + if (isAloneDistance()) + ToastUtils.showShort(getContext().getString(R.string.attention_point_is_alone_distance)); + } + + final protected ISurveyor surveyorImpl() { + return stateManager.surveyor; + } + + final protected @NonNull + ICachedData getCachedData() { + return stateManager.cachedData; + } + + SurveyorStationRecord getStation() { + return stateManager.stationRecord; + } + + RequestSurveyorParamAuto getRequestSurveyorParamAuto() { + return stateManager.getRequestSurveyorParamAuto(); + } + + void changeSkip(int cycleIndex, int index) { + SurveyorStationRecord station = getStation(); + //缓存点 + getCachedData().setPointAbandon(cycleIndex, index); + //数据库点 + String pointId = getCachedData().originalPointId(cycleIndex, index); + for (SurveyorPoint surveyorPoint : station.items) { + if (TextUtils.equals(pointId, surveyorPoint.getOriginalPointId())) { + surveyorPoint.setAbandon(true); + break; + } + } + ThreadPoolUtil.execute(() -> { + SurveyorDatabaseFactory.instance.getSurveyorStation().update(station); + }); + } + + final protected @NonNull + ICycleRecorder getCycleRecorder() { + return stateManager.cycleRecorder; + } + + final protected @NonNull + Context getContext() { + return stateManager.context; + } + + final protected void scroll2(int itemIndex) { + stateManager.scrollDelegate.onScrollTo(itemIndex); + } + + final protected void toast(String warning) { + ToastUtils.showShort(warning); + } + + final protected void toast(@StringRes int warning) { + ToastUtils.showShort(warning); + } + + public abstract void enter(Bundle args);//进入状态 + + final protected void navigation2(StateType stateType) { + stateManager.enter(stateType); + } + + final protected void navigation2(StateType stateType, Bundle args) { + stateManager.enter(stateType, args); + } + + final boolean isStationClosed() { + return stateManager.isStationAutoClosed(); + } + + final protected String stationId() { + return stateManager.stationId(); + } + + final protected FragmentManager fragmentManager() { + return stateManager.fragmentManager(); + } + + final protected LifecycleOwner lifecycleOwner() { + return stateManager.lifecycleOwner(); + } + + final protected void tips(String msg, Runnable runnable) { + if (stateManager.isDead()) { + return; + } + TipsFragment.noCancelAbleTips(stateManager.fragmentManager(), stateManager.lifecycleOwner(), + getContext(), + msg, + -1, + () -> { + if (runnable != null) { + runnable.run(); + } + }); + } + + /** + * 错误提示 + *

+ * 用户不能忽略,点击确定后自动「停留原地」 + */ + final protected void failureTipsWithAutoStandStill(String msg) { + if (stateManager.isDead()) { + return; + } + TipsFragment.noCancelAbleTips(stateManager.fragmentManager(), stateManager.lifecycleOwner(), + getContext(), + msg, + -1, + () -> enterIdleAndClearSurveyStateAndResetAutoMode(true)); + } + + final protected void failureTipsWithAutoStandStill(String msg, Runnable runnable) { + if (stateManager.isDead()) { + return; + } + TipsFragment.noCancelAbleTips(stateManager.fragmentManager(), stateManager.lifecycleOwner(), + getContext(), + msg, + -1, + () -> { + runnable.run(); + enterIdleAndClearSurveyStateAndResetAutoMode(true); + }); + } + + final protected void optionTipsWithStandStill(String msg, Runnable confirmCallback) { + optionTips(msg, null, null, + confirmCallback, + () -> enterIdleAndClearSurveyStateAndResetAutoMode(true), + () -> enterIdleAndClearSurveyStateAndResetAutoMode(true)); + } + + final protected void optionTips(String msg, + String confirmButton, + String cancelButton, + Runnable confirmCallback, + Runnable cancelCallback, + Runnable ignoreCallback) { + if (stateManager.isDead()) { + return; + } + TipsWith2OptionFragment.tips( + stateManager.fragmentManager(), + stateManager.lifecycleOwner(), + confirmButton, + cancelButton, + null, + msg, + new TipsWith2OptionFragment.IOperatorCallback() { + @Override + public void onConfirm() { + if (confirmCallback == null) { + return; + } + confirmCallback.run(); + } + + @Override + public void onCancel() { + if (cancelCallback == null) { + return; + } + cancelCallback.run(); + } + + @Override + public void onIgnore() { + if (ignoreCallback == null) { + return; + } + ignoreCallback.run(); + } + + @Override + public void onOption() { + } + }); + } + + final protected void optionTipsCountDown(String msg, + String confirmButton, + String cancelButton, + Runnable confirmCallback, + Runnable cancelCallback, + Runnable ignoreCallback) { + if (stateManager.isDead()) { + return; + } + + TipsWith2OptionFragment.tipsCountDownTime( + stateManager.fragmentManager(), + stateManager.lifecycleOwner(), + confirmButton, + cancelButton, + null, + msg, + new TipsWith2OptionFragment.IOperatorCallback() { + @Override + public void onConfirm() { + if (confirmCallback == null) { + return; + } + confirmCallback.run(); + } + + @Override + public void onCancel() { + if (cancelCallback == null) { + return; + } + cancelCallback.run(); + } + + @Override + public void onIgnore() { + if (ignoreCallback == null) { + return; + } + ignoreCallback.run(); + } + + @Override + public void onOption() { + } + }); + } + + protected final void option4Jump2OtherCycle4Resurvey(int cycleIndex) { + option4Jump2OtherCycle(cycleIndex, true); + } + + protected final void option4Jump2OtherEmptyCycle(int cycleIndex) { + option4Jump2OtherCycle(cycleIndex, false); + } + + private void option4Jump2OtherCycle(int cycleIndex, boolean resurveyOrEmpty) { + String msg = Tools.getString(R.string.there_is_empty_data_to_be_tested_hint); + if (resurveyOrEmpty) { + msg = Tools.getString(R.string.there_is_supplementary_data_to_be_tested_hint); + } + optionTips(Tools.getString(R.string.at) + SurveyorCycleUtil.cycleName(cycleIndex) + msg, + null, + null, + () -> { + //切换测回 + getCycleRecorder().changeCycleIndex(cycleIndex); + //数据库存储修改当前测回 + setCurrentCycle(cycleIndex); + //查找测量目标 + findTargetFromBeginInCurrentCycle(false); + }, + () -> enterIdleAndClearSurveyStateAndResetAutoMode(true), + () -> enterIdleAndClearSurveyStateAndResetAutoMode(true)); + } + + final protected void runOnUI(Runnable runnable) { + stateManager.runOnUI(runnable); + } + + final protected void runOnBackground(Runnable runnable) { + ThreadPoolUtil.execute(runnable); + } + + /** + * 设置测站的测回 + * + * @param cycle + */ + final protected void setCurrentCycle(int cycle) { + getCycleRecorder().changeCycleIndex(cycle); + SurveyorDatabaseFactory + .instance + .getScheduleDataSource() + .record( + new SurveyorScheduleRecord( + SurveyorScheduleConstants.getCurrentCycleKey(stationId(), null), + String.valueOf(cycle))); + } + + final protected void setCurrentCycleSync(int cycle) { + getCycleRecorder().changeCycleIndex(cycle); + SurveyorDatabaseFactory + .instance + .getScheduleDataSource() + .recordSync( + new SurveyorScheduleRecord( + SurveyorScheduleConstants.getCurrentCycleKey(stationId(), null), + String.valueOf(cycle))); + } + + final protected void setSingleCycleSchedule(int cycleIndex, String schedule) { + SurveyorDatabaseFactory + .instance + .getScheduleDataSource() + .record( + new SurveyorScheduleRecord( + SurveyorScheduleConstants.getSingleCycleScheduleKey(stationId(), null, cycleIndex), + schedule)); + } + + final protected void setSingleCycleScheduleSync(int cycleIndex, String schedule) { + SurveyorDatabaseFactory + .instance + .getScheduleDataSource() + .recordSync( + new SurveyorScheduleRecord( + SurveyorScheduleConstants.getSingleCycleScheduleKey(stationId(), null, cycleIndex), + schedule)); + } + + final protected void setAllCycleSchedule(String schedule) { + SurveyorDatabaseFactory + .instance + .getScheduleDataSource() + .record( + new SurveyorScheduleRecord( + SurveyorScheduleConstants.getAllCycleScheduleKey(stationId(), null), + schedule)); + } + + final protected void setAllCycleScheduleSync(String schedule) { + SurveyorDatabaseFactory + .instance + .getScheduleDataSource() + .recordSync( + new SurveyorScheduleRecord( + SurveyorScheduleConstants.getAllCycleScheduleKey(stationId(), null), + schedule)); + } + + /** + * 如果resetAutoSurveyState为true,将重置autoSurvey状态为unknown + */ + final protected void findTargetFromBeginInCurrentCycle(boolean resetAutoSurveyState) { + getSurveyorData().clearSurveyStateAndPosition(); + if (resetAutoSurveyState) { + autoModeRecorder().resetAutoMode(); + } + navigation2(StateType.doMove2NextValidate); + } + + final protected void enterIdleAndClearSurveyState() { + clearSurveyStateAndCloseAutoModeAndStandStill(DEFAULT_AUTO_MODE, + false, StateType.idle); + } + + /** + * 取消测量,会停在当前位置(索引+盘左or盘右),并进入idle + */ + final protected void enterIdleAndClearSurveyStateAndResetAutoMode(boolean resetAutoMode) { + clearSurveyStateAndCloseAutoModeAndStandStill(resetAutoMode ? RESET_AUTO_MODE : DEFAULT_AUTO_MODE, + false, StateType.idle); + } + + final protected void enterIdleAndClearSurveyorStatePosition() { + clearSurveyStateAndCloseAutoModeAndStandStill(DEFAULT_AUTO_MODE, + true, StateType.idle); + } + + final protected void enterStationCheckAndClearSurveyStateAndResetAutoMode() { + clearSurveyStateAndCloseAutoModeAndStandStill(RESET_AUTO_MODE, + false, StateType.checkStation); + } + + final protected void enterIdleAndClearSurveyStateAndCloseAutoMode() { + clearSurveyStateAndCloseAutoModeAndStandStill(CLOSE_AUTO_MODE, false, StateType.idle); + } + + /** + * @param autoMode + * @param clearPosition + * @param stateType + */ + private void clearSurveyStateAndCloseAutoModeAndStandStill(int autoMode, boolean clearPosition, StateType stateType) { + //重置或者关闭自动模式 + if (autoMode == RESET_AUTO_MODE) { + autoModeRecorder().resetAutoMode(); + } else if (autoMode == CLOSE_AUTO_MODE) { + autoModeRecorder().closeAutoMode(); + } + //更新测量进度标识 + if (clearPosition) { + getSurveyorData().clearSurveyStateAndPosition(); + } else { + getSurveyorData().clearSurveyState(); + } + //进入某个状态 + navigation2(stateType); + } + + + /** + * 更新UI + */ + final protected void refreshUI() { + runOnUI(() -> getCachedData().notifyDateChange()); + } + + protected void quite() { + } + + protected void resume() { + } + + protected boolean isLive() { + return !stateManager.isDead(); + } + + protected boolean isAutoSurveyOpen() { + return stateManager.isAutoModeOpen(); + } + + protected boolean isAutoSurveyClosed() { + return stateManager.isAutoModeClose(); + } + + protected IStateDelegate stateDelegate() { + return new IStateDelegate() { + @Override + public void onOptionTips( + String msg, String confirmButton, String cancelButton, + Runnable confirmCallback, Runnable cancelCallback, Runnable ignoreCallback) { + optionTips( + msg, confirmButton, cancelButton, + confirmCallback, cancelCallback, ignoreCallback); + } + + @Override + public void resetSurveyorStateAndKeepPosition() { + //关闭自动测量 + autoModeRecorder().resetAutoMode(); + //更新测量进度标识 + getSurveyorData().clearSurveyState(); + //进入空闲状态 + navigation2(StateType.idle); + } + + @Override + public void resurveyPoints(int cycleIndex, List pointIds) { + if (cycleIndex == -1) { + cycleIndex = getCycleRecorder().currentCycleIndex(); + } + + //更新记录数据,包括将数据置为dirty和切换cycle + getCachedData().markReSurveyor(stationId(), cycleIndex, pointIds); + getCycleRecorder().changeCycleIndex(cycleIndex); + + //根据当前状态,查找一个目标 + findTargetFromBeginInCurrentCycle(true); + + //更新数据库标识 + setCurrentCycle(cycleIndex); + setAllCycleSchedule(SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + setSingleCycleSchedule(cycleIndex, SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + } + + @Override + public void deleteSingleCycleData(int cycleIndex) { + //删除数据 + getCachedData().deleteSurveyorRecord(stationId(), cycleIndex); + //切换测回--一般不用,但是这里为了保险 + getCycleRecorder().changeCycleIndex(cycleIndex); + //查找一个新目标开启测量 + findTargetFromBeginInCurrentCycle(true); + + //更新数据库标识 + setCurrentCycle(cycleIndex); + setAllCycleSchedule(SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + setSingleCycleSchedule(cycleIndex, SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + } + }; + } + + protected int getCurrentIndex() { + return stateManager.surveyorData.currentIndex(); + } + + protected int getCurrentCycleIndex() { + return stateManager.cycleRecorder.currentCycleIndex(); + } + + protected boolean isAloneDistance() { + return stateManager.getCachedData().isAloneDistance(stateManager.getCurrentCycle(), getCurrentIndex()); + } + + protected double getInstrumentHeight() { + return stateManager.getInsturmentHeight(); + } + + protected void refreshGoBackBtnEnable() { + stateManager.refreshGoBackBtnEnable(); + } + + protected void resetLearnDataTag() { + getRequestSurveyorParamAuto().resetCodeAutoMeasureCondition(); + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/ILookCase.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/ILookCase.java new file mode 100644 index 0000000..2c74b90 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/ILookCase.java @@ -0,0 +1,9 @@ +package com.bingce.controlnetwork.surveyor.state.heighttraverse; + + +import com.bingce.controlapphelper.model.DataCategory; + +public interface ILookCase { + boolean whichCase(DataCategory dataCategory); +} + diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/StateManagerHeightTraverse.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/StateManagerHeightTraverse.java new file mode 100644 index 0000000..4704a51 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/StateManagerHeightTraverse.java @@ -0,0 +1,541 @@ +package com.bingce.controlnetwork.surveyor.state.heighttraverse; + +import android.content.Context; +import android.os.Bundle; + +import androidx.annotation.NonNull; +import androidx.annotation.WorkerThread; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.point.PointRecord; +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.model.SurveyorPoint; +import com.bingce.controlapphelper.datasource.database.tolerance.detail.ToleranceDetailRecord; +import com.bingce.controlapphelper.event.RefreshGoBackButton; +import com.bingce.controlapphelper.surveyor.data.ICachedData; +import com.bingce.controlapphelper.surveyor.data.ICycleRecorder; +import com.bingce.controlapphelper.surveyor.data.ISurveyorData; +import com.bingce.controlapphelper.surveyor.method.AutoSurveyorMethod; +import com.bingce.controlapphelper.surveyor.method.FindTargetMethod; +import com.bingce.controlapphelper.surveyor.method.SurveyorAdjustMethod; +import com.bingce.controlapphelper.surveyor.state.IAutoModeSwitcher; +import com.bingce.controlapphelper.surveyor.state.IStateType; +import com.bingce.controlapphelper.surveyor.state.ISurveyState; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlapphelper.surveyor.surveyor.ISurveyor; +import com.bingce.controlapphelper.surveyor.surveyor.ISurveyorListener; +import com.bingce.controlapphelper.surveyor.surveyor.ISurveyorRemindListener; +import com.bingce.controlapphelper.surveyor.surveyor.RequestSurveyorParamAuto; +import com.bingce.controlapphelper.surveyor.surveyor.SurveyorAutoImpl; +import com.bingce.controlapphelper.surveyor.surveyor.SurveyorMockAuto; +import com.bingce.controlapphelper.surveyor.surveyor.SurveyorSingleImpl; +import com.bingce.controlapphelper.surveyor.test.Test; +import com.bingce.controlapphelper.util.DigitalUtil; +import com.bingce.controlapphelper.util.IUIRunner; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.fragment.StationDataAdjustDialogFragment; +import com.bingce.controlnetwork.fragment.TipsFragment; +import com.bingce.controlnetwork.surveyor.state.AutoModeType; +import com.bingce.controlnetwork.surveyor.state.IScrollDelegate; +import com.bingce.controlnetwork.surveyor.state.StateConstants; +import com.bingce.coordlib.model.Coordinate; +import com.bingce.totalstation.ControlSurveyData; +import com.bingce.totalstation.ControlSurveyResult; +import com.bingce.utils.ThreadPoolUtil; +import com.bingce.utils.VipManager; + +import org.greenrobot.eventbus.EventBus; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import blankj.utilcode.util.ToastUtils; + +public class StateManagerHeightTraverse implements IAutoModeSwitcher, ISurveyState, IStateType { + private final Map stateMap = new HashMap<>(); + private StateType currentStateType = StateType.idle; + private final FragmentManager fragmentManager; + private final LifecycleOwner lifecycleOwner; + private final IUIRunner iuiRunner; + final IScrollDelegate scrollDelegate; + + @NonNull + SurveyorStationRecord stationRecord; + final @NonNull + RequestSurveyorParamAuto requestSurveyorParamAuto; + final @NonNull + ToleranceDetailRecord toleranceRecord; + final @NonNull + ISurveyorData surveyorData; + final @NonNull + ICachedData cachedData; + final @NonNull + ICycleRecorder cycleRecorder; + final @NonNull + Context context; + private AutoModeType autoMode = AutoModeType.unknown; + @NonNull + final ISurveyor surveyor; + private final PointRecord stationPointRecord; + private final int positionFragment; + final boolean supportAutoSurvey; + + private StateManagerHeightTraverse( + final int positionFragment, + final boolean supportAutoSurvey,//是否支持自动测量 + final @NonNull RequestSurveyorParamAuto requestSurveyorParamAuto, + final @NonNull SurveyorStationRecord stationRecord, + final @NonNull PointRecord stationPointRecord, + final @NonNull ToleranceDetailRecord toleranceRecord, + final @NonNull Context context, + final @NonNull ISurveyorData surveyorData, + final @NonNull ICycleRecorder cycleRecorder, + final @NonNull ICachedData cachedData, + final @NonNull IScrollDelegate scrollDelegate, + FragmentManager fragmentManager, + LifecycleOwner lifecycleOwner, + IUIRunner iuiRunner) { + this.positionFragment = positionFragment; + this.supportAutoSurvey = supportAutoSurvey; + + this.requestSurveyorParamAuto = requestSurveyorParamAuto; + this.stationRecord = stationRecord; + this.fragmentManager = fragmentManager; + this.lifecycleOwner = lifecycleOwner; + this.iuiRunner = iuiRunner; + this.scrollDelegate = scrollDelegate; + + this.context = context; + this.toleranceRecord = toleranceRecord; + this.surveyorData = surveyorData; + this.cachedData = cachedData; + this.cycleRecorder = cycleRecorder; + + this.stationPointRecord = stationPointRecord; + + if (Test.DEBUG) { + surveyor = new SurveyorMockAuto(StateConstants.VALUE_MEASURE_WHAT_ANGLE_DISTANCE, this.stationRecord.getId(), + this.stationRecord.isAutoClose(), + toleranceRecord.getCycleCount(), + cachedData, surveyorData, cycleRecorder, this, this); + } else { + if (supportAutoSurvey) { + surveyor = new SurveyorAutoImpl(StateConstants.VALUE_MEASURE_WHAT_ANGLE_DISTANCE, this); + } else { + surveyor = new SurveyorSingleImpl(StateConstants.VALUE_MEASURE_WHAT_ANGLE_DISTANCE); + } + } + _DoSurveyorState doSurveyorState = new _DoSurveyorState(positionFragment, this, this); + //注册接收数据的状态 + surveyor.register((ISurveyorListener) doSurveyorState); + surveyor.register((ISurveyorRemindListener) doSurveyorState); + + stateMap.put(StateType.init, new _Init(positionFragment, this)); + stateMap.put(StateType.doSurveyor, doSurveyorState); + stateMap.put(StateType.doAutoSurveyor, new _DoAutoSurveyorState(positionFragment, this, this)); + stateMap.put(StateType.SurveyorFailure, new _SurveyorFailureState(positionFragment, this)); + stateMap.put(StateType.doMove2NextValidate, new _DoMove2NextValidateState(positionFragment, this)); + stateMap.put(StateType.doMoveBack, new _DoMoveBackState(positionFragment, this)); + stateMap.put(StateType.checkStation, new _CheckStationState(positionFragment, this)); + + stateMap.put(StateType.doDeleteAllCycle, new _DoDeleteAllCycleState(positionFragment, this)); + stateMap.put(StateType.doDeleteCurrentCycle, new _DoDeleteCurrentCycleState(positionFragment, this)); + stateMap.put(StateType.doCalAdjust, new _DoCalAdjustState(positionFragment, this)); + stateMap.put(StateType.idle, new _IdleState(positionFragment, this, this)); + stateMap.put(StateType.doWellMeasureRotationReady, new _DoWellMeasureRotationReadyState(positionFragment, this)); + stateMap.put(StateType.checkTolerance, new _CheckToleranceState(positionFragment, this)); + + //监听测站数据变化 + runOnUI(() -> SurveyorDatabaseFactory + .instance + .getSurveyorStation() + .getLiveDataRecord(stationRecord.getId()) + .observe(lifecycleOwner, record -> { + if (record == null || !stationRecord.getId().equals(record.getId())) { + return; + } + updateSurveyorStationRecord(record); + })); + } + + private void updateSurveyorStationRecord(SurveyorStationRecord record) { + this.stationRecord = record; + //更新测点信息 + if (stationRecord.getItems() != null) { + for (SurveyorPoint item : stationRecord.getItems()) { + if (item == null || !SurveyorPoint.TYPE_POINT.equals(item.getType())) { + //排除非测点 + continue; + } + cachedData.updateSurveyPointParams(item); + } + } + + cachedData.notifyDateChange(); + } + + String stationId() { + return stationRecord.getId(); + } + + + @Override + public void enter(StateType type, Bundle args) { + if (isDead()) { + return; + } + __BaseState baseState = stateMap.get(type); + if (baseState != null) { + this.currentStateType = type; + runOnUI(() -> baseState.enter(args)); + } + } + + @Override + public void enter(StateType type) { + enter(type, null); + } + + void runOnUI(Runnable action) { + if (iuiRunner != null) { + iuiRunner.runOnUI(action); + } + } + + public void doSurveyor() { + boolean inValidate = isInValidate(); + + if (inValidate) { + return; + } + + int pointCount = cachedData.pointCount(); + if (pointCount == 0) { + ToastUtils.showShort(Tools.getString(R.string.no_data_available_yet)); + return; + } + + Bundle bundle = null; + if (isRotationReadyState()) { + //当前是旋转到位状态 + bundle = new Bundle(); + bundle.putBoolean(StateConstants.KEY_IS_ROTATION_READY_STATE, true); + } + + enter(StateType.doSurveyor, bundle); + } + + public void doAutoSurveyor() { + if (isInValidate()) { + return; + } + enter(StateType.doAutoSurveyor); + } + + public void deleteCurrentStationSurveyorData() { + if (isInValidate()) { + return; + } + enter(StateType.doDeleteAllCycle, _DoDeleteAllCycleState.args(stationId())); + } + + /** + * 删除当前测回记录(删除后视或前视的所有记录) + * + * @param cycleIndex + */ + public void deleteCurrentStationSurveyorData(int positionFragment) { + if (isInValidate()) { + return; + } + enter(StateType.doDeleteCurrentCycle, _DoDeleteCurrentCycleState.args(stationId(), positionFragment)); + } + + public void stationCheck() { + if (isInValidate()) { + return; + } + enter(StateType.checkStation); + } + + public String stationCheckOnly() { + return _CheckStationState._stationCheck(stationId(), toleranceRecord, cachedData); + } + + public void stationAdjustOnly(String showType) { + ThreadPoolUtil.execute(() -> { + SurveyorAdjustMethod.AdjustResult adjustResult = SurveyorAdjustMethod.calStationAdjust(stationRecord, cachedData); + if (adjustResult.isError()) { + runOnUI(() -> TipsFragment.tipsOnly(fragmentManager, lifecycleOwner, context, adjustResult.errorString)); + return; + } + + ArrayList adjustList = new ArrayList<>(); + if (adjustResult.result != null && !adjustResult.result.isEmpty()) { + adjustList.add(adjustResult.result.get(0)); + } + StationDataAdjustDialogFragment.showDialog(showType, adjustList, adjustResult.showSlopDistance, fragmentManager()); + + //伴随平差 设置进度为通过检测 + SurveyorDatabaseFactory + .instance + .getScheduleDataSource() + .record( + new SurveyorScheduleRecord( + __BaseState.getScheduleKey(positionFragment), + SurveyorScheduleConstants.STATUE_VALUE_CHECKED)); + }); + + } + + + public void stationAdjust(String type) { + if (isInValidate()) { + return; + } + Bundle bundle = new Bundle(); + bundle.putString(StationDataAdjustDialogFragment.KEY_SHOW_TYPE, type); + enter(StateType.doCalAdjust, bundle); + } + + public void switch2Cycle(int cycleIndex) { + if (isInValidate()) { + } +// _DoCalScheduleInSingleCycleState.enter(this, cycleIndex); + } + + public void calScheduleWhenEnterSurveyFragment(int cycleIndex) { + if (isInValidate()) { + return; + } + _Init.enter(this, cycleIndex); + } + + public void moveBack() { + if (isInValidate()) { + return; + } + enter(StateType.doMoveBack); + } + + //检测当前状态是否支持从外界主动改变状态 + //如果是空闲或者是测站通过检测是有效的状态 + public boolean isInValidate() { + return currentStateType != StateType.idle + && StateType.stationCheckedSuccess != currentStateType + && !isRotationReadyState(); + } + + private boolean isRotationReadyState() { + return currentStateType == StateType.doWellMeasureRotationReady; + } + + public void quite() { + _live = false; + for (Map.Entry entry : stateMap.entrySet()) { + entry.getValue().quite(); + } + //进入idle状态 + this.currentStateType = StateType.idle; + } + + private boolean _live = true; + + public boolean isDead() { + return !_live; + } + + public void resume() { + _live = true; + for (Map.Entry entry : stateMap.entrySet()) { + entry.getValue().resume(); + } + } + + FragmentManager fragmentManager() { + return this.fragmentManager; + } + + LifecycleOwner lifecycleOwner() { + return this.lifecycleOwner; + } + + final boolean isStationAutoClosed() { + return stationRecord.isAutoClose(); + } + + @WorkerThread + public static StateManagerHeightTraverse newInstance( + int positionFragment, + boolean isSupportAutoMode, + @NonNull RequestSurveyorParamAuto requestSurveyorParamAuto, + @NonNull SurveyorStationRecord stationRecord, + @NonNull Context context, + @NonNull FragmentManager fragmentManager, + @NonNull LifecycleOwner lifecycleOwner, + @NonNull ToleranceDetailRecord toleranceRecord, + @NonNull ISurveyorData surveyorData, + @NonNull ICycleRecorder cycleRecorder, + @NonNull ICachedData cachedData, + IScrollDelegate scrollDelegate, + IUIRunner runner) { + //读取测点record + String stationPointId = null; + if (stationRecord.getItems() != null) { + for (SurveyorPoint stationItem : stationRecord.getItems()) { + if (SurveyorPoint.TYPE_STATION.equals(stationItem.getType())) { + stationPointId = stationItem.getPointId(); + break; + } + } + } + PointRecord stationPointRecord = null; + if (stationPointId != null) { + stationPointRecord = SurveyorDatabaseFactory + .instance + .getPointDataSource() + .findByIdSync(stationPointId); + } + if (stationPointRecord == null) { + return null; + } + boolean supportAuto = Test.DEBUG; + if (isSupportAutoMode && + (VipManager.getInstance().checkReg() || VipManager.getInstance().checkControlProLevel())) { + supportAuto = true; + } + return new StateManagerHeightTraverse( + positionFragment, + supportAuto, + requestSurveyorParamAuto, + stationRecord, + stationPointRecord, + toleranceRecord, + context, + surveyorData, + cycleRecorder, + cachedData, + scrollDelegate, + fragmentManager, lifecycleOwner, runner); + } + + @Override + public boolean isAutoModeOpen() { + return autoMode == AutoModeType.start; + } + + @Override + public boolean isAutoModeClose() { + return autoMode == AutoModeType.stop; + } + + @Override + public boolean isAutoModeNotSpecial() { + return autoMode == AutoModeType.unknown; + } + + @Override + public void openAutoMode() { + autoMode = AutoModeType.start; + } + + @Override + public void closeAutoMode() { + autoMode = AutoModeType.stop; + } + + @Override + public void resetAutoMode() { + autoMode = AutoModeType.unknown; + } + + + @Override + public int isReadyAutoSurvey() { + if (!supportAutoSurvey) { + return ControlSurveyResult.CODE_ERROR; + } + if (!surveyor.isReady()) {//仪器连接上才算ready + return ControlSurveyResult.CODE_ERROR; + } + + Coordinate stationBasePoint = getStationCoord(); + double instrumentHeight = getInsturmentHeight(); + + return requestSurveyorParamAuto.checkAutoCondition(getCachedData(), stationBasePoint, instrumentHeight); + } + + @Override + public String isMeasuredValueMatchDesign() { + if (!supportAutoSurvey) { + return null; + } + Coordinate stationBasePoint = getStationCoord(); + double instrumentHeight = getInsturmentHeight(); + List originMeasureList = requestSurveyorParamAuto.getOriginMeasureList(getCachedData()); + return AutoSurveyorMethod.checkAutoSurveyorMeasuredValue(stationBasePoint, instrumentHeight, originMeasureList); + } + + @Override + public boolean isSurveying() { + return currentStateType == StateType.doSurveyor || currentStateType == StateType.doAutoSurveyor; + } + + @Override + public boolean isAutoSurveying() { + return isAutoModeOpen(); + } + + + @NonNull + public ICachedData getCachedData() { + return cachedData; + } + + /** + * 获取当前测回 + * + * @return + */ + public int getCurrentCycle() { + return cycleRecorder.currentCycleIndex(); + } + + public int getCurrentIndex() { + return surveyorData.currentIndex(); + } + + private Coordinate getStationCoord() { + if (PointRecord.TYPE_KNOWN_POINT.equals(stationPointRecord.getPointType())) { + return new Coordinate( + stationPointRecord.getX(), + stationPointRecord.getY(), + stationPointRecord.getZ()); + } + return null; + } + + public double getInsturmentHeight() { + return DigitalUtil.valueOfDoubleString(stationRecord.getInstrumentHeight(), 0); + } + + @NonNull + public RequestSurveyorParamAuto getRequestSurveyorParamAuto() { + return requestSurveyorParamAuto; + } + + public void refreshGoBackBtnEnable() { + FindTargetMethod.Target deleteTartget = _DoMove2NextValidateState.findTarget(stationId(), cachedData.pointCount(), cachedData, + surveyorData.currentIndex(), false, + dataCategory -> !dataCategory.isEmptyData()); + EventBus.getDefault().post(new RefreshGoBackButton(deleteTartget != null)); + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_CheckStationState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_CheckStationState.java new file mode 100644 index 0000000..8b2ae0d --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_CheckStationState.java @@ -0,0 +1,343 @@ +package com.bingce.controlnetwork.surveyor.state.heighttraverse; + +import android.os.Bundle; + +import androidx.annotation.WorkerThread; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord; +import com.bingce.controlapphelper.datasource.database.tolerance.detail.ToleranceDetailRecord; +import com.bingce.controlapphelper.model.LeftOrRight; +import com.bingce.controlapphelper.surveyor.data.ICachedData; +import com.bingce.controlapphelper.surveyor.method.AverageValueMethod; +import com.bingce.controlapphelper.surveyor.method.DeviationValueOfRadianMethod; +import com.bingce.controlapphelper.surveyor.method.RadianMethod; +import com.bingce.controlapphelper.surveyor.method.ValueOf2cMethod; +import com.bingce.controlapphelper.surveyor.method.model.CacheResult; +import com.bingce.controlapphelper.surveyor.method.model.SdAngleValueType; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlapphelper.util.IdUtil; +import com.bingce.controlapphelper.util.SurveyorCycleUtil; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.fragment.SelectReSurveyorCycleFragment; +import com.bingce.utils.ThreadPoolUtil; +import com.bingce.utils.Util; + +import java.util.ArrayList; +import java.util.List; + +/** + * 执行「测站检测」 + *

+ * 前置条件: + * 所有测回都完成测量,并且通过「测回内检测」 + */ +class _CheckStationState extends __BaseState { + + public _CheckStationState(int positionFragment, StateManagerHeightTraverse stateManager) { + super(StateType.checkStation, positionFragment, stateManager); + } + + @Override + public void enter(Bundle args) { + //执行测站检测 + String error = _stationCheck(stationId(), getToleranceRecord(), getCachedData()); + if (error.isEmpty()) { + //进入finish状态 + navigation2(StateType.stationCheckedSuccess); + } else { + showErrorTips(error, stationId(), getToleranceRecord().getCycleCount(), + getCachedData(), + this, + fragmentManager(), + lifecycleOwner()); + } + } + + /** + * 提示错误信息,并让用户选择下一步操作 + */ + public static void showErrorTips(String msg, String stationId, int cycleCount, + ICachedData stationSurveyorDataSource, + __BaseState state, + FragmentManager fragmentManager, LifecycleOwner lifecycleOwner) { + state.optionTips(msg, + Tools.getString(R.string.retest_cycle), + Tools.getString(R.string.retest_station), + () -> state.runOnBackground(() -> reSurveyorCycle(stationId, cycleCount, + stationSurveyorDataSource, + state, fragmentManager, lifecycleOwner)), + () -> reSurveyorStation(msg, stationId, cycleCount, + stationSurveyorDataSource, + state, fragmentManager, lifecycleOwner), + () -> state.enterIdleAndClearSurveyStateAndResetAutoMode(true)); + } + + + @WorkerThread + private static void reSurveyorCycle(String stationId, int cycleCount, + ICachedData cachedData, + __BaseState state, + FragmentManager fragmentManager, LifecycleOwner lifecycleOwner) { + SurveyorStationRecord stationRecord = SurveyorDatabaseFactory.instance.getSurveyorStation().getRecordSync(stationId); + if (stationRecord == null) { + state.enterIdleAndClearSurveyStateAndResetAutoMode(true); + return; + } + state.runOnUI(() -> SelectReSurveyorCycleFragment.start( + fragmentManager, + lifecycleOwner, + cycleCount, + (cycleIndex) -> { + if (cycleIndex == -1) { + state.enterIdleAndClearSurveyStateAndResetAutoMode(true); + } else { + //记录补测数据类型 + List pointIds = new ArrayList<>(); + pointIds.add(cachedData.pointId(cycleIndex, cycleIndex)); + cachedData.markReSurveyor(stationId, cycleIndex, pointIds); + //更新测量状态 + state.setCurrentCycle(cycleIndex); + state.setAllCycleSchedule(SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + state.setSingleCycleSchedule(cycleIndex, SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + + //查找新测量目标 + state.findTargetFromBeginInCurrentCycle(true, cycleIndex); + } + } + )); + } + + static void reSurveyorStation(String msg, String stationId, int cycleCount, + ICachedData cachedData, + __BaseState state, + FragmentManager fragmentManager, LifecycleOwner lifecycleOwner) { + state.optionTips(Tools.getString(R.string.is_delete_all_station_data), null, null, + () -> {//1.选择删除测站所有数据,则执行相应逻辑 + ThreadPoolUtil.execute(() -> { + //删除数据 + cachedData.deleteSurveyorRecord(stationId); + //更新测量进度 + state.setAllCycleSchedule(SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + for (int index = 0; index < cycleCount; index++) { + state.setSingleCycleSchedule(index, SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + } + + state.resetLearnDataTag(); + + //重新测量 + state.findTargetFromBeginInCurrentCycle(true, 0); + }); + }, + () -> {//2.如果用户不选择删除,则循环提示,让他重新在重测和删除做选择 + //循环显示 + showErrorTips(msg, stationId, cycleCount, + cachedData, state, + fragmentManager, lifecycleOwner); + }, + () -> state.enterIdleAndClearSurveyStateAndResetAutoMode(true));//3.如果用户忽略,则停留在当前位置 + } + + + //检测合法性 + + /** + * 检测所有测回数据 + *

+ * 在「无自动闭合」情况下,为了兼容「左右角」测量结果,根据pointId将所有测量数据存入map中 + * 根据「左角」测量来检测「测回间同方向值互差」,所有测回的归零值使用「左角」第一个point来做0点 + *

+ * 如果是「自动闭合」情况,则忽略「左右角」测量,直接按照itemIndex依次计算,第个测回的归零值, + * 使用每次循环的itemIndex=0做0点 + * + * @param toleranceRecord 限差 + * @param cachedDataSource 缓存的测量数据 + * @return 错误信息,如果为null或空,说明没有错误 + */ + public static String _stationCheck(final String stationId, + final ToleranceDetailRecord toleranceRecord, + final ICachedData cachedDataSource) { + final int cycleCount = toleranceRecord.getCycleCount(); + final int surveyorCount = toleranceRecord.getSurveyorCount(); + + //*****测回间垂直角互差(垂直角) + double verCyclesAngleDifference = toleranceRecord.getVerCyclesAngleDifference()/*verCyclesAngleDifference*/; + List<_ErrorItem> verValueError = new ArrayList<>(); + + //执行计算 + for (int cycleI = 0; cycleI < cycleCount; cycleI++) { + List valuesI = + DeviationValueOfRadianMethod.zeroValueOfSingleCycleInLeftOrientation(stationId, cycleI, surveyorCount, cachedDataSource); + for (int cycleJ = cycleI + 1; cycleJ < cycleCount; cycleJ++) { + List valuesJ = + DeviationValueOfRadianMethod.zeroValueOfSingleCycleInLeftOrientation(stationId, cycleJ, surveyorCount, cachedDataSource); + if (valuesI.size() != valuesJ.size()) { + return Tools.getString(R.string.please_complete_all_retest_data); + } + int size = valuesI.size(); + for (int index = 0; index < 1; index++) { + double diff = Math.abs(DeviationValueOfRadianMethod + .similarRadianDiff(valuesI.get(index).verRadian, valuesJ.get(index).verRadian)); + if (verCyclesAngleDifference < RadianMethod.radian2S(diff)) { + verValueError.add(new _ErrorItem(valuesI.get(index).pointName, + cycleI, cycleJ, RadianMethod.radian2S(diff))); + } + } + } + } + //*****测回间垂直角I互差(垂直角) + double verCyclesIDifference = toleranceRecord.getVerCyclesIDifference()/*verCyclesIDifference*/; + List<_ErrorItem> verIError = new ArrayList<>(); + //*****测回间斜距互差(距离) + double distCyclesDifference = toleranceRecord.getSlopeCycleDistanceDifference()/*slopeCycleDistanceDifference*/; + List<_ErrorItem> distError = new ArrayList<>(); + + List<_Point> pointArrayList = new ArrayList<>(); + //遍历第一测回,收集所有待测点id + for (int index = 0; index < 1; index++) { + if (cachedDataSource.isPointAbandon(0, index)) { + continue; + } + pointArrayList.add(new _Point(cachedDataSource.pointId(0, index), + cachedDataSource.pointName(0, index), + cachedDataSource.isAloneDistance(0, index))); + } + //检测所有待测点i互差 + for (_Point point : pointArrayList) { + for (int cycleI = 0; cycleI < cycleCount; cycleI++) { + String leftRecordId_I = IdUtil.createSurveyorRecordId(stationId, cycleI, point.pointId, LeftOrRight.left); + String rightRecordId_I = IdUtil.createSurveyorRecordId(stationId, cycleI, point.pointId, LeftOrRight.right); + CacheResult value2C_I = ValueOf2cMethod.valueOf2C(SdAngleValueType.verAngle, leftRecordId_I, rightRecordId_I, + toleranceRecord.getSurveyorCount(), cachedDataSource); + CacheResult distanceLeftAndRightAverageValue_I = AverageValueMethod.leftAndRightValue(SdAngleValueType.distance, + leftRecordId_I, + rightRecordId_I, surveyorCount, cachedDataSource); + for (int cycleJ = cycleI + 1; cycleJ < cycleCount; cycleJ++) { + String leftRecordId_J = IdUtil.createSurveyorRecordId(stationId, cycleJ, point.pointId, LeftOrRight.left); + String rightRecordId_J = IdUtil.createSurveyorRecordId(stationId, cycleJ, point.pointId, LeftOrRight.right); + CacheResult value2C_J = ValueOf2cMethod.valueOf2C(SdAngleValueType.verAngle, leftRecordId_J, rightRecordId_J, + toleranceRecord.getSurveyorCount(), cachedDataSource); + CacheResult distanceLeftAndRightAverageValue_J = AverageValueMethod.leftAndRightValue(SdAngleValueType.distance, + leftRecordId_J, + rightRecordId_J, surveyorCount, cachedDataSource); + double verI = Math.abs(value2C_I.value - value2C_J.value); + if (verCyclesIDifference < verI) { + verIError.add(new _ErrorItem(point.pointName, cycleI, cycleJ, verI)); + } + + if (!point.aloneDistance) { + double distance = Math.abs(distanceLeftAndRightAverageValue_I.value - distanceLeftAndRightAverageValue_J.value); + if (distCyclesDifference < distance * 1000) { + distError.add(new _ErrorItem(point.pointName, cycleI, cycleJ, distance * 1000)); + } + } + + } + } + } + + return _errorString(verCyclesAngleDifference, verCyclesIDifference, distCyclesDifference, + verValueError, verIError, distError); + } + + /** + * 根据超限信息生成错误描述 + * + * @param verValueError 垂直角同方向值互差 + */ + private static String _errorString(double verLimit, double verILimit, double distLimit + , List<_ErrorItem> verValueError, List<_ErrorItem> verIError, List<_ErrorItem> distError) { + StringBuilder stringBuilder = new StringBuilder(); + if (!verValueError.isEmpty()) { + stringBuilder.append("\n").append(Tools.getString(R.string.cycle_between_ver_angle_limit)) + .append(Util.formatDouble2String(verLimit, 1)) + .append("'')"); + for (_ErrorItem item : verValueError) { + stringBuilder + .append("\n ") + .append(item.pointName) + .append(":\n") + .append(" |") + .append(SurveyorCycleUtil.cycleName(item.cycleIndex1)) + .append("-") + .append(SurveyorCycleUtil.cycleName(item.cycleIndex2)) + .append("| = ") + .append(Util.formatDouble2String(item.difference, 1)) + .append("'')"); + } + } + + if (!verIError.isEmpty()) { + stringBuilder.append("\n").append(Tools.getString(R.string.ver_angle_i_same_direction_each_cycle)) + .append(Util.formatDouble2String(verILimit, 1)) + .append("'')"); + for (_ErrorItem item : verIError) { + stringBuilder + .append("\n ") + .append(item.pointName) + .append(":\n") + .append(" |") + .append(SurveyorCycleUtil.cycleName(item.cycleIndex1)) + .append("-") + .append(SurveyorCycleUtil.cycleName(item.cycleIndex2)) + .append("| = ") + .append(Util.formatDouble2String(item.difference, 1)) + .append("'')"); + } + } + + if (!distError.isEmpty()) { + stringBuilder.append("\n").append(Tools.getString(R.string.cycle_between_distance_limit_brackets)) + .append(Util.formatDouble2String(distLimit, 1)) + .append("'')"); + for (_ErrorItem item : distError) { + stringBuilder + .append("\n ") + .append(item.pointName) + .append(":\n") + .append(" |") + .append(SurveyorCycleUtil.cycleName(item.cycleIndex1)) + .append("-") + .append(SurveyorCycleUtil.cycleName(item.cycleIndex2)) + .append("| = ") + .append(Util.formatDouble2String(item.difference, 1)) + .append("'')"); + } + } + + return stringBuilder.toString(); + } + + /** + * 存储错误信息的item + */ + private static class _ErrorItem { + final String pointName; + final int cycleIndex1; + final int cycleIndex2; + final double difference; + + public _ErrorItem(String pointName, int cycleIndex1, int cycleIndex2, double difference) { + this.pointName = pointName; + this.cycleIndex1 = cycleIndex1; + this.cycleIndex2 = cycleIndex2; + this.difference = difference; + } + } + + private static class _Point { + final String pointId; + final String pointName; + final boolean aloneDistance; + + _Point(String pointId, String pointName, boolean aloneDistance) { + this.pointId = pointId; + this.pointName = pointName; + this.aloneDistance = aloneDistance; + } + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_CheckToleranceState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_CheckToleranceState.java new file mode 100644 index 0000000..96dd47b --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_CheckToleranceState.java @@ -0,0 +1,313 @@ +package com.bingce.controlnetwork.surveyor.state.heighttraverse; + +import android.os.Bundle; +import android.text.TextUtils; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.config.ConfigConstants; +import com.bingce.controlapphelper.datasource.database.config.ConfigRecord; +import com.bingce.controlapphelper.datasource.database.config.IConfigDataSource; +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.datasource.database.surveyorrecord.SurveyorRecord; +import com.bingce.controlapphelper.datasource.database.tolerance.detail.ToleranceDetailRecord; +import com.bingce.controlapphelper.model.DataCategory; +import com.bingce.controlapphelper.model.LeftOrRight; +import com.bingce.controlapphelper.surveyor.data.ICachedData; +import com.bingce.controlapphelper.surveyor.data.ISurveyorData; +import com.bingce.controlapphelper.surveyor.data.SpeakCache; +import com.bingce.controlapphelper.surveyor.method.DeviationValueOfRadianMethod; +import com.bingce.controlapphelper.surveyor.method.SingleCycleCheckMethod; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlapphelper.util.IdUtil; +import com.bingce.controlapphelper.util.SurveyorCycleUtil; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.surveyor.state.AutoModeType; +import com.bingce.totalstation.TotalStation; +import com.bingce.utils.ThreadPoolUtil; + +import net.tatans.tensorflowtts.tts.TtsManager; + +/** + * 检测限差 + */ +public class _CheckToleranceState extends __BaseState { + + public _CheckToleranceState(int positionFragment, + StateManagerHeightTraverse stateManager) { + super(StateType.checkTolerance, positionFragment, stateManager); + } + + @Override + public void enter(Bundle args) { + //检测读数 + if (!checkReadData()) { + return; + } + + ICachedData cacheData = getCachedData(); + ISurveyorData surveyorData = getSurveyorData(); + + + //设置数据正常 + surveyorData.setDataCategory(DataCategory.normalCategory()); + //存储(缓存+数据库) + cacheData.cache(getCurrentCycleIndex(), surveyorData); + + if (isSingleCycleCompleted(stationId(), getCurrentCycleIndex(), cacheData)) { + refreshUI(); + //更新测回测量进度 + setSingleCycleSchedule(getCurrentCycleIndex(), SurveyorScheduleConstants.STATUE_VALUE_COMPLETED); + boolean singleSuccess = checkSingleCycle(); + if (singleSuccess) { + checkAllCycle(); + } + } else { + findNextSurveyorPoint(); + } + + } + + private void checkAllCycle() { + int cycleCount = getToleranceRecord().getCycleCount(); + int nextCycleIndex = -1; + //查找数据不全的测回 + for (int cycleIndex = 0; cycleIndex < cycleCount; cycleIndex++) { + if (!getCachedData().isSingleCycleAllDataValidate(cycleIndex)) { + //对不全数据的测回赋值 + nextCycleIndex = cycleIndex; + break; + } + } + + if (nextCycleIndex != -1) { + //有其他测回数据没有测完 + if (isAutoSurveyOpen()) { + //修改当前测回 + setCurrentCycle(nextCycleIndex); + //存储一下已经播放切换测回的的节点 + SpeakCache.getInstance().saveSpeakSwitchCycle(); + //播报 + TtsManager.getInstance().speak(Tools.getString(R.string.current_cycle_complete_start_surveyor) + SurveyorCycleUtil.cycleName(nextCycleIndex)); + //查找测量目标 + findNextSurveyorPoint(); + } else { +// //提示是否进入其他未完成测回继续测量 +// option4Jump2OtherEmptyCycle(nextCycleIndex); + //查找测量目标 + findNextSurveyorPoint(); + } + return; + } + + if (isAutoSurveyOpen()) { + //检测是否已经提示 + //检测是否需要提示测站检测 + IConfigDataSource configDataSource = + SurveyorDatabaseFactory.instance.getConfigDataSource(); + ThreadPoolUtil.execute(() -> { + String key = ConfigConstants.KEY_CONFIG_STATION_CHECK_REMINDED + stationId(); + ConfigRecord record = configDataSource.getByKeySync(key); + if (record == null || ConfigConstants.VALUE_NO.equals(record.getConfigValue())) { + runOnUI(() -> TtsManager.getInstance().speak(Tools.getString(R.string.all_cycle_completed))); + } + }); + } + //标识测站完成测量(数据库存储) + setAllCycleSchedule(SurveyorScheduleConstants.STATUE_VALUE_COMPLETED); + //进入idle状态 + //清除测量状态,进入测站检测,停止自动测量 + setAutoAndSurveyorState(AutoModeType.unknown, false); + + String error = _CheckStationState._stationCheck(stationId(), getToleranceRecord(), getCachedData()); + if (error.isEmpty()) { + //进入finish状态 + ISurveyorData surveyorData = getSurveyorData(); + surveyorData.clearSurveyStateAndPosition(); + //设置测量进度(数据库存储) + setAllCycleSchedule(SurveyorScheduleConstants.STATUE_VALUE_CHECKED); + //通知刷新 + tips(getContext().getString(R.string.tips_all_cycle_has_finish_and_checked), null); + if (isAutoSurveyOpen()) { + runOnUI(() -> TtsManager.getInstance().speak(getContext().getString(R.string.tips_all_cycle_has_finish_and_checked))); + } + //清除测量状态,进入idle,停止自动测量 + enterIdleAndClearSurveyStateAndResetAutoMode(true); + } else { + _CheckStationState.showErrorTips(error, stationId(), getToleranceRecord().getCycleCount(), + getCachedData(), + this, + fragmentManager(), + lifecycleOwner()); + } + + } + + private boolean checkSingleCycle() { + ICachedData cachedData = getCachedData(); + String stationId = stationId(); + ISurveyorData surveyorData = getSurveyorData(); + int currentCycleIndex = surveyorData.currentIndex(); + ToleranceDetailRecord toleranceRecord = getToleranceRecord(); + int cycleCount = toleranceRecord.cycleCount; + + //预处理 + for (int index = 0; index < cachedData.pointCount(); index++) { + String pointId = cachedData.pointId(currentCycleIndex, index); + String keyLeft = IdUtil.createSurveyorRecordId(stationId, currentCycleIndex, pointId, LeftOrRight.left); + SurveyorRecord left = cachedData.getSurveyorRecord(keyLeft); + _changeDirtyRecord2NormalBeforeCheck(left, cachedData); + String keyRight = IdUtil.createSurveyorRecordId(stationId, currentCycleIndex, pointId, LeftOrRight.right); + SurveyorRecord right = cachedData.getSurveyorRecord(keyRight); + _changeDirtyRecord2NormalBeforeCheck(right, cachedData); + } + + //执行单测回内检测 + String error = SingleCycleCheckMethod.checkVerI( + toleranceRecord.getVerCycleDirectIDifference(), + stationId(), currentCycleIndex, surveyorData, cachedData); + if (error != null) { + if (isAutoSurveyOpen()) { + TtsManager.getInstance().speak(Tools.getString(R.string.check_cycle_inner_failed)); + } + _CheckStationState.showErrorTips(error, stationId(), cycleCount, cachedData, this, fragmentManager(), lifecycleOwner()); + return false; + } + + //更新测量进度 + setSingleCycleSchedule(currentCycleIndex, + SurveyorScheduleConstants.STATUE_VALUE_CHECKED); + + return true; + } + + private void _changeDirtyRecord2NormalBeforeCheck( + SurveyorRecord record, ICachedData cachedDataSource) { + if (record == null) { + return; + } + if (record.value1Status.isResurveyed() || record.value2Status.isResurveyed()) { + if (record.value1Status.isResurveyed()) { + record.value1Status = DataCategory.normalCategory(); + } + if (record.value2Status.isResurveyed()) { + record.value2Status = DataCategory.normalCategory(); + } + + cachedDataSource.updateCache(record); + } + } + + private boolean checkReadData() { + int surveyorCount = getToleranceRecord().getSurveyorCount(); + if (surveyorCount > 1) {//单次测量,直接通过检测 + //多次测量,执行检测 + ISurveyorData surveyorDataSource = getSurveyorData(); + double horDifference = getToleranceRecord().getHorReadDifference(); + double verDifference = getToleranceRecord().getVerReadDifference(); + double distanceDifference = getToleranceRecord().getSlopeReadDifference(); + double horDiffRadian = DeviationValueOfRadianMethod.similarRadianDiff(surveyorDataSource.getAngleHor1(), surveyorDataSource.getAngleHor2()); + double verDiffRadian = DeviationValueOfRadianMethod.similarRadianDiff(surveyorDataSource.getAngleVer1(), surveyorDataSource.getAngleVer2()); + + String msg = null; +// if (verDifference < RadianMethod.radian2S(verDiffRadian)) { +// msg = "垂直角读数超限,请重新观测该目标."; +// } else + if (!isAloneDistance()//增加单独测距判断 + && distanceDifference < distanceReadDiff(surveyorDataSource.getDistance1(), surveyorDataSource.getDistance2())) { + msg = Tools.getString(R.string.distance_read_data_limit); + } + + if (!TextUtils.isEmpty(msg)) { + failureTipsWithAutoStandStill(msg); + return false; + } + } + + return checkLeft(); + } + + /** + * 如果是测回内首次测量,需要判断是否是盘左 + */ + private boolean checkLeft() { + LeftOrRight leftOrRight = getSurveyorData().leftOrRight(); + if (leftOrRight == LeftOrRight.left) { + //如果是首次测量,强制要求使用盘左 + double vAngle = getSurveyorData().getAngleVer(); + if (!isFaceLeft(vAngle)) { + failureTipsWithAutoStandStill( + getContext().getString(R.string.error_tips_please_start_from_left), + () -> { + TotalStation.getInstance().requestChangeFace(); + }); + return false; + } + } + return true; + } + + /** + * 是否是盘左 + * + * @param vAngle + * @return + */ + private boolean isFaceLeft(double vAngle) { + return vAngle >= 0 && vAngle <= Math.PI; + } + + /** + * 斜距两次读数差 + * + * @param distance1 读数1 + * @param distance2 读数2 + * @return 读数差(单位毫米) + */ + public double distanceReadDiff(double distance1, double distance2) { + return Math.abs(distance1 - distance2) * 1000; + } + + /** + * 判断单个测回是否测量完成(不要求通过检测) + */ + public static boolean isSingleCycleCompleted(String stationId, int cycleIndex, ICachedData cachedData) { + if (cachedData.pointCount() == 0) { + return false; + } + if (cycleIndex == -1) { + cycleIndex = 0; + } + + boolean isCompleted = true; + + //测回内所有数据都是「新鲜数据」才能执行「测回内检测」 + for (int index = 0; index < cachedData.pointCountReal(); index++) { + + if (cachedData.isPointAbandon(cycleIndex, index)) { + continue; + } + + String pointId = cachedData.pointId(cycleIndex, index); + + String leftKey = IdUtil.createSurveyorRecordId(stationId, cycleIndex, pointId, LeftOrRight.left); + String rightKey = IdUtil.createSurveyorRecordId(stationId, cycleIndex, pointId, LeftOrRight.right); + + DataCategory leftDataCategory = cachedData.valueState(leftKey); + DataCategory rightDataCategory = cachedData.valueState(rightKey); + + if (leftDataCategory.isFreshData() && rightDataCategory.isFreshData()) { + continue; + } + isCompleted = false; + break; + } + + return isCompleted; + } + + private void findNextSurveyorPoint() { + findTargetFromBeginInCurrentCycle(false, 0); + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_DoAutoSurveyorState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_DoAutoSurveyorState.java new file mode 100644 index 0000000..4e366b2 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_DoAutoSurveyorState.java @@ -0,0 +1,32 @@ +package com.bingce.controlnetwork.surveyor.state.heighttraverse; + +import android.os.Bundle; + +import com.bingce.controlapphelper.surveyor.state.IAutoModeSwitcher; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.totalstation.ControlSurveyResult; + +import net.tatans.tensorflowtts.tts.TtsManager; + +/** + * 先检测是否有其他未完成测回,继续本次测量将删除其他测回数据 + */ +class _DoAutoSurveyorState extends __BaseState { + private final IAutoModeSwitcher autoModeSwitcher; + + public _DoAutoSurveyorState(int positionFragment, StateManagerHeightTraverse stateManager, IAutoModeSwitcher autoModeSwitcher) { + super(StateType.doAutoSurveyor, positionFragment, stateManager); + this.autoModeSwitcher = autoModeSwitcher; + } + + @Override + public void enter(Bundle args) { + if (autoModeSwitcher.isReadyAutoSurvey() == ControlSurveyResult.CODE_SUCCESS) { + autoModeSwitcher.openAutoMode(); + navigation2(StateType.doMove2NextValidate); + TtsManager.getInstance().speak(Tools.getString(R.string.start_auto_measure)); + } + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_DoCalAdjustState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_DoCalAdjustState.java new file mode 100644 index 0000000..da5f28c --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_DoCalAdjustState.java @@ -0,0 +1,45 @@ +package com.bingce.controlnetwork.surveyor.state.heighttraverse; + +import android.os.Bundle; + +import com.bingce.controlapphelper.surveyor.method.SurveyorAdjustMethod; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlnetwork.fragment.StationDataAdjustDialogFragment; + +/** + * 平差计算 + */ +public class _DoCalAdjustState extends __BaseState { + + public _DoCalAdjustState(int positionFragment, StateManagerHeightTraverse stateManager) { + super(StateType.doCalAdjust, positionFragment, stateManager); + } + + @Override + public void enter(Bundle args) { + String showType = null; + if (args != null) { + showType = args.getString(StationDataAdjustDialogFragment.KEY_SHOW_TYPE); + } + startCalAdjust(showType); + } + + private void startCalAdjust(String showType) { + runOnBackground(() -> { + SurveyorAdjustMethod.AdjustResult adjustResult = SurveyorAdjustMethod.calStationAdjust(getStation(), getCachedData()); + if (adjustResult.isError()) { + runOnUI(() -> _CheckStationState.showErrorTips(adjustResult.errorString, stationId(), getToleranceRecord().getCycleCount(), + getCachedData(), + _DoCalAdjustState.this, + fragmentManager(), + lifecycleOwner())); + return; + } + //清除测量状态,进入idle,停止自动测量 + enterIdleAndClearSurveyStateAndResetAutoMode(true); + + StationDataAdjustDialogFragment.showDialog(showType, adjustResult.result, adjustResult.showSlopDistance, fragmentManager()); + } + ); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_DoDeleteAllCycleState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_DoDeleteAllCycleState.java new file mode 100644 index 0000000..af296b3 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_DoDeleteAllCycleState.java @@ -0,0 +1,73 @@ +package com.bingce.controlnetwork.surveyor.state.heighttraverse; + +import android.os.Bundle; + +import androidx.annotation.WorkerThread; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.config.ConfigConstants; +import com.bingce.controlapphelper.datasource.database.config.IConfigDataSource; +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.surveyor.data.ICachedData; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.utils.ThreadPoolUtil; + +/* + * 删除本测站所有测回数据 + * */ +class _DoDeleteAllCycleState extends __BaseState { + + private static final String KEY_STATION_ID = "__station_id"; + + static Bundle args(String stationId) { + Bundle args = new Bundle(); + args.putString(KEY_STATION_ID, stationId); + return args; + } + + public _DoDeleteAllCycleState(int positionFragment, StateManagerHeightTraverse stateManager) { + super(StateType.doDeleteAllCycle, positionFragment, stateManager); + } + + @Override + public void enter(Bundle args) { + String stationId = args.getString(KEY_STATION_ID); + + ThreadPoolUtil.execute(() -> deleteAllCycleData(stationId)); +// optionTipsWithStandStill(getContext().getString(R.string.tips_delete_station_all_surveyor_records), +// () -> deleteAllCycleData(stationId)); + } + + @WorkerThread + private void deleteAllCycleData(String stationId) { + //删除数据 + ICachedData cachedData = getCachedData(); + cachedData.deleteSurveyorRecord(stationId); + + //清除已经提示测站可以检测标识 + IConfigDataSource configDataSource = + SurveyorDatabaseFactory.instance.getConfigDataSource(); + String key = ConfigConstants.KEY_CONFIG_STATION_CHECK_REMINDED + stationId; + configDataSource.setSync(key, ConfigConstants.VALUE_NO); + + //重置进度 + setAllCycleScheduleSync(SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + for (int cycleIndex = 0; cycleIndex < getToleranceRecord().getCycleCount(); cycleIndex++) { + setSingleCycleScheduleSync(cycleIndex, SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + } + + //重置学习测量的标志 + resetLearnDataTag(); + + //从第一测回开始 + setCurrentCycleSync(0); + + //重新测量,并刷新 + findTargetFromBeginInCurrentCycle(true, 0); + + refreshUI(); + + } + + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_DoDeleteCurrentCycleState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_DoDeleteCurrentCycleState.java new file mode 100644 index 0000000..559c32b --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_DoDeleteCurrentCycleState.java @@ -0,0 +1,106 @@ +package com.bingce.controlnetwork.surveyor.state.heighttraverse; + +import android.os.Bundle; + +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.model.LeftOrRight; +import com.bingce.controlapphelper.surveyor.data.ICachedData; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlnetwork.fragment.stationsurvey.heighttraverse.MeasureHeightTraverseFragment; +import com.bingce.utils.ThreadPoolUtil; + +class _DoDeleteCurrentCycleState extends __BaseState { + + private static final String KEY_STATION_ID = "__station_id"; + private static final String KEY_POSITION_FRAGMENT_INDEX = "__period_index__"; + + static Bundle args(String stationId, int periodIndex) { + Bundle args = new Bundle(); + args.putString(KEY_STATION_ID, stationId); + args.putInt(KEY_POSITION_FRAGMENT_INDEX, periodIndex); + return args; + } + + public _DoDeleteCurrentCycleState(int positionFragment, StateManagerHeightTraverse stateManager) { + super(StateType.doDeleteCurrentCycle, positionFragment, stateManager); + } + + @Override + public void enter(Bundle args) { + String stationId = args.getString(KEY_STATION_ID); + int positionFragment = args.getInt(KEY_POSITION_FRAGMENT_INDEX); + String msg; + if (positionFragment == MeasureHeightTraverseFragment.POSITION_BACK_PAGE) { + msg = "是否确定删除后视的所有测回数据?"; + } else { + msg = "是否确定删除前视的所有测回数据?"; + } + optionTipsWithStandStill(msg, + () -> deleteSingleCycle(stationId, positionFragment)); + } + + private void deleteSingleCycle(String stationId, int positionFragment) { + ThreadPoolUtil.execute(() -> { + ICachedData cachedData = getCachedData(); + + int cycleCount = getToleranceRecord().cycleCount; + + for (int cycleIndex = 0; cycleIndex < cycleCount; cycleIndex++) { + cachedData.deleteSurveyorRecord(stationId, cycleIndex, 0, LeftOrRight.left); + cachedData.deleteSurveyorRecord(stationId, cycleIndex, 0, LeftOrRight.right); + } + //重置学习测量的标志 + resetLearnDataTag(); + + //重置所有测回和当次测回进度 + setAllCycleScheduleSync(SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + //设置当前测回 + setCurrentCycleSync(0); + + //重新测量,并刷新 + findTargetFromBeginInCurrentCycle(true, 0); + + refreshUI(); + +// +// int pointIndex = getCurrentIndex(); +// +// +// FindTargetMethod.Target target = _DoMove2NextValidateState.getTargetAscOrDesc(stationId, pointIndex, cachedData, +// false, dataCategory -> !dataCategory.isEmptyData()); +// +// if (target == null) { +// navigation2(StateType.idle); +// return; +// } +// +// int deleteCycleIndex = target.cycleIndex; +// //删除数据 +// ICachedData stationSurveyorDataSource = getCachedData(); +// stationSurveyorDataSource.deleteSurveyorRecordSync(stationId, deleteCycleIndex); +// +// //清除已经提示测站可以检测标识 +// IConfigDataSource configDataSource = SurveyorDatabaseFactory.instance.getConfigDataSource(); +// String key = ConfigConstants.KEY_CONFIG_STATION_CHECK_REMINDED + stationId; +// configDataSource.setSync(key, ConfigConstants.VALUE_NO); +// +// if (deleteCycleIndex == 0) { +// //当第一测回 +// //重置学习测量的标志 +// resetLearnDataTag(); +// } +// +// //重置所有测回和当次测回进度 +// setAllCycleScheduleSync(SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); +// setSingleCycleScheduleSync(deleteCycleIndex, SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); +// +// //设置当前测回 +// setCurrentCycleSync(deleteCycleIndex); +// +// //重新测量,并刷新 +// findTargetFromBeginInCurrentCycle(true, 0); + }); + + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_DoMove2NextValidateState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_DoMove2NextValidateState.java new file mode 100644 index 0000000..c476e4e --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_DoMove2NextValidateState.java @@ -0,0 +1,122 @@ +package com.bingce.controlnetwork.surveyor.state.heighttraverse; + +import android.os.Bundle; + +import androidx.annotation.NonNull; + +import com.bingce.controlapphelper.model.BundleConstants; +import com.bingce.controlapphelper.model.DataCategory; +import com.bingce.controlapphelper.model.LeftOrRight; +import com.bingce.controlapphelper.surveyor.data.ICachedData; +import com.bingce.controlapphelper.surveyor.method.FindTargetMethod; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlapphelper.util.IdUtil; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; + +import net.tatans.tensorflowtts.tts.TtsManager; + +/** + * 移动到一个待测量位置 + *

+ * 不会跳转到其他测期 + *

+ * 可能涉及转向(盘左->盘右) + */ +class _DoMove2NextValidateState extends __BaseState { + + public _DoMove2NextValidateState(int positionFragment, StateManagerHeightTraverse stateManager) { + super(StateType.doMove2NextValidate, positionFragment, stateManager); + } + + @Override + public void enter(Bundle args) { + ICachedData cachedData = getCachedData(); + + int pointCount = cachedData.pointCount(); + + int cycle = 0; + if (args != null) { + cycle = args.getInt(BundleConstants.KEY_CYCLE_INDEX, 0); + } + + //1.先查找补测数据 + FindTargetMethod.Target surveyorTarget = findTarget(stationId(), pointCount, cachedData, cycle, true, + dataCategory -> DataCategory.dirtyAndNeedReSurveyor == dataCategory); + + + //如果在当前测回找到待被测数据,立刻跳转到相应位置 + if (surveyorTarget != null) { + lookTargetAfter(surveyorTarget.itemIndex, surveyorTarget.leftOrRight); + return; + } + //2.查找empty数据 + FindTargetMethod.Target emptyTarget = findTarget(stationId(), pointCount, cachedData, cycle, true, + dataCategory -> DataCategory.empty == dataCategory); + + if (emptyTarget != null) { + if (isAutoSurveyOpen()) { + if (emptyTarget.itemIndex == getCachedData().pointCount() - 1 + && emptyTarget.leftOrRight == LeftOrRight.right) { + TtsManager.getInstance().speak(Tools.getString(R.string.start_face_right)); + } + } + //直接跳转到目标点,开启新测量 + lookTargetAfter(emptyTarget.itemIndex, emptyTarget.leftOrRight); + return; + } + + enterIdleAndClearSurveyorStatePosition(); + + } + + public static FindTargetMethod.Target findTarget(final String stationId, + final int pointCount, + final @NonNull ICachedData cachedData, + int startLookPosition, + boolean isAscLook, + ILookCase lookCase) { + if (isAscLook) { + for (int i = startLookPosition; i < pointCount; i++) { + FindTargetMethod.Target targetAscOrDesc = getTargetAscOrDesc(stationId, i, cachedData, true, lookCase); + if (targetAscOrDesc != null) { + return targetAscOrDesc; + } + } + } else { + for (int j = startLookPosition; j >= 0; j--) { + FindTargetMethod.Target targetAscOrDesc = getTargetAscOrDesc(stationId, j, cachedData, false, lookCase); + if (targetAscOrDesc != null) { + return targetAscOrDesc; + } + } + } + return null; + } + + public static FindTargetMethod.Target getTargetAscOrDesc(String stationId, int pointIndex, ICachedData cachedData, boolean isAscLook, ILookCase lookCase) { + FindTargetMethod.Target target; + if (isAscLook) { + target = getTarget(stationId, pointIndex, cachedData, LeftOrRight.left, lookCase); + if (target != null) return target; + target = getTarget(stationId, pointIndex, cachedData, LeftOrRight.right, lookCase); + } else { + target = getTarget(stationId, pointIndex, cachedData, LeftOrRight.right, lookCase); + if (target != null) return target; + target = getTarget(stationId, pointIndex, cachedData, LeftOrRight.left, lookCase); + } + return target; + } + + private static FindTargetMethod.Target getTarget(String stationId, int pointIndex, ICachedData cachedData, LeftOrRight leftOrRight, ILookCase lookCase) { + String pointId = cachedData.pointId(pointIndex, pointIndex); + String leftKey = IdUtil.createSurveyorRecordId(stationId, pointIndex, pointId, leftOrRight); + DataCategory dataCategory = cachedData.valueState(leftKey); + if (lookCase.whichCase(dataCategory)) { + return new FindTargetMethod.Target(pointIndex, pointIndex, leftOrRight); + } + return null; + } + + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_DoMoveBackState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_DoMoveBackState.java new file mode 100644 index 0000000..fdec5ca --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_DoMoveBackState.java @@ -0,0 +1,161 @@ +package com.bingce.controlnetwork.surveyor.state.heighttraverse; + +import android.os.Bundle; + +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.datasource.database.surveyorrecord.SurveyorRecord; +import com.bingce.controlapphelper.model.DataCategory; +import com.bingce.controlapphelper.model.LeftOrRight; +import com.bingce.controlapphelper.surveyor.data.ICachedData; +import com.bingce.controlapphelper.surveyor.method.FindTargetMethod; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlapphelper.util.IdUtil; + +import com.bingce.controlnetwork.R; + +/** + * 回退 + * 移动到上一测量结点,伴随删除上次测量数据 + */ +public class _DoMoveBackState extends __BaseState { + + public _DoMoveBackState(int positionFragment, StateManagerHeightTraverse stateManager) { + super(StateType.doMoveBack, positionFragment, stateManager); + } + + @Override + public void enter(Bundle args) { + ICachedData cachedData = getCachedData(); + + final int pointCount = cachedData.pointCount(); + +// if (currentIndex < 0) { +// //如果测量结束,直接使用0号点盘右 +// int targetIndex = 0; +// LeftOrRight targetState = LeftOrRight.right; +// warningWithStandStill(cachedDataSource, currentCycle, targetIndex, targetState); +// return; +// } + + FindTargetMethod.Target deleteTartget = _DoMove2NextValidateState.findTarget(stationId(), pointCount, cachedData, + getCurrentIndex(), false, dataCategory -> !dataCategory.isEmptyData()); + + if (deleteTartget == null) { + goIdle(); + return; + } + + cachedData.deleteSurveyorRecord(stationId(), deleteTartget.itemIndex, deleteTartget.itemIndex, deleteTartget.leftOrRight); + + setAllCycleSchedule(SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + + + //直接跳转到目标点,开启新测量 + //更新测量进度 + setSurveyPosition(deleteTartget.itemIndex, deleteTartget.leftOrRight); + //清除测量状态,进入idle,但是不停止自动测量 + goIdle(); + //滚动 + scroll2(deleteTartget.itemIndex); + + +// if (dataCategory.isNeedResurvey()) {//如果当前位置是脏数据(说明正在补测) +// //回退到上一个脏数据位置 +// back2LastDirtyPosition(currentCycle, currentIndex, leftOrRight, pointCount, cachedDataSource); +// } else if (dataCategory.isEmptyData()) { +// //如果是空数据,说明测量进行中,查找上一个数据即可 +// //需要提醒用户数据会被删除 +// back2LastVisiblePosition(currentCycle, currentIndex, leftOrRight, pointCount, cachedDataSource); +// } else { +// //bug,不应该有这个地方 +// enterIdleAndClearSurveyStateAndResetAutoMode(true); +// } + } + + private void goIdle() { + enterIdleAndClearSurveyStateAndResetAutoMode(false); + } + + private void back2LastDirtyPosition(int currentCycle, int currentIndex, LeftOrRight leftOrRight, + int pointCount, ICachedData cachedData) { + //反向查找,但是找到目标后不能删除其数据,否则会造成「数据空洞」 + FindTargetMethod.Target target = FindTargetMethod.findTargetInSingleCycle( + stationId(), currentCycle, currentIndex, leftOrRight, pointCount, false, + DataCategory.dirtyAndSurveyed, + cachedData); + if (target == null) { + //在dirtyAndNeedReSurveyor数据没有修复完成之前,不能回退正常数据 + enterIdleAndClearSurveyStateAndResetAutoMode(true); + } else { + //找到dirtyAndSurveyed数据, + //则将其校正为dirtyAndNeedReSurveyor + String pointId = cachedData.pointId(target.cycleIndex, target.itemIndex); + String recordKey = IdUtil.createSurveyorRecordId(stationId(), target.cycleIndex, pointId, target.leftOrRight); + SurveyorRecord surveyorRecord = cachedData.getSurveyorRecord(recordKey); + if (surveyorRecord != null) { + if (surveyorRecord.value1Status.isResurveyed()) { + surveyorRecord.value1Status = DataCategory.needResurvey(); + } + if (surveyorRecord.value2Status.isResurveyed()) { + surveyorRecord.value2Status = DataCategory.needResurvey(); + } + cachedData.updateCache(surveyorRecord); + //重置进度 + resetSchedule(_DoMoveBackState.this, + target.itemIndex, + target.leftOrRight); + } else { + enterIdleAndClearSurveyStateAndResetAutoMode(true); + } + } + } + + private void back2LastVisiblePosition(int currentCycle, int currentIndex, LeftOrRight leftOrRight, + int pointCount, + ICachedData cachedData) { + + //从当前开始,向上查找第一个normal数据 + FindTargetMethod.Target target = + FindTargetMethod.findTargetInSingleCycle( + stationId(), currentCycle, currentIndex, leftOrRight, pointCount, false, + DataCategory.normalCategory(), + cachedData); + if (target == null) { + failureTipsWithAutoStandStill(getContext().getString(R.string.tips_no_more_record_2_rollback)); + return; + } + + warningWithStandStill(cachedData, + currentCycle, + target.itemIndex, + target.leftOrRight); + } + + private void warningWithStandStill( + ICachedData cachedDataSource, + int currentCycle, int itemIndex, LeftOrRight leftOrRight) { + optionTipsWithStandStill(getContext().getString(R.string.tips_will_resurvey_last_record), + () -> { + //删除当前数据 + cachedDataSource.deleteSurveyorRecord(stationId(), + currentCycle, itemIndex, leftOrRight); + //重置进度 + setSingleCycleSchedule(currentCycle, SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + setAllCycleSchedule(SurveyorScheduleConstants.STATUE_VALUE_NO_COMPLETED); + + resetSchedule(this, itemIndex, leftOrRight); + }); + } + + private static void resetSchedule(__BaseState state, + int targetIndex, + LeftOrRight leftOrRight) { + //设置测量目标点 + state.setSurveyPosition(targetIndex, leftOrRight); + //清除测量状态,进入idle + //如果当前已经关闭自动测量,就不重置自动测量开关(用户已经表示不想自动测量) + state.enterIdleAndClearSurveyStateAndResetAutoMode(!state.isAutoSurveyClosed()); + + state.scroll2(targetIndex); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_DoSurveyorState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_DoSurveyorState.java new file mode 100644 index 0000000..44a28cb --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_DoSurveyorState.java @@ -0,0 +1,246 @@ +package com.bingce.controlnetwork.surveyor.state.heighttraverse; + +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; + +import com.bingce.controlapphelper.datasource.database.surveyorstation.model.SurveyorPoint; +import com.bingce.controlapphelper.datasource.database.tolerance.detail.ToleranceDetailRecord; +import com.bingce.controlapphelper.event.SurveyStateEvent; +import com.bingce.controlapphelper.surveyor.data.ICachedData; +import com.bingce.controlapphelper.surveyor.data.ICycleRecorder; +import com.bingce.controlapphelper.surveyor.data.ISurveyorData; +import com.bingce.controlapphelper.surveyor.state.ISurveyState; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlapphelper.surveyor.surveyor.ISurveyorListener; +import com.bingce.controlapphelper.surveyor.surveyor.ISurveyorRemindListener; +import com.bingce.controlapphelper.surveyor.surveyor.RequestSurveyorParam; +import com.bingce.controlapphelper.util.DebugMsgUtil; +import com.bingce.controlapphelper.util.SettingValueUtil; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.surveyor.state.StateConstants; +import com.bingce.device.Device; +import com.bingce.totalstation.TotalStation; +import com.bingce.totalstation.protocol.south.SouthAndroidBtInterface; +import com.bingce.totalstation.protocol.topcon.TopconInterface; + +import net.tatans.tensorflowtts.tts.TtsManager; + +import blankj.utilcode.util.ToastUtils; + +/** + * 先检测是否有其他未完成测回,继续本次测量将删除其他测回数据 + */ +class _DoSurveyorState extends __BaseState implements ISurveyorListener, ISurveyorRemindListener { + private final ISurveyState surveyState; + //最多测量次数,如果3次测量都没有获取正常数据,则跳过 + private static final int MAX_SURVEYOR_COUNT = 3; + private static int failureCount = 0; + private static final int RESULT_SUCCESS = 0; + private static final int RESULT_FAILURE_EXCEED_MAX = 1;//测量失败次数超出最大限制 + private static final int RESULT_FAILURE_ERROR = 2;//测量失败,又没有允许重复尝试 + private static final boolean allowTryWhenFailure = true;//在测量失败的时候,是否允许重新测量 + + private int measureTimeIndex = 0;//当前测点是第几次测量 + private boolean isAlreadyRemindUserAimingAtWire = false; + + private final Handler handler; + + public _DoSurveyorState(int positionFragment, StateManagerHeightTraverse stateManager, ISurveyState surveyState) { + super(StateType.doSurveyor, positionFragment, stateManager); + this.surveyState = surveyState; + handler = new Handler(Looper.getMainLooper()); + } + + @Override + public void enter(Bundle args) { + measureTimeIndex = 0; + + isAlreadyRemindUserAimingAtWire = false; + if (args != null) { + isAlreadyRemindUserAimingAtWire = args.getBoolean(StateConstants.KEY_IS_ROTATION_READY_STATE); + } + + ToleranceDetailRecord toleranceRecord = getToleranceRecord(); + ICycleRecorder cycleRecorder = getCycleRecorder(); + ICachedData cachedDataSource = getCachedData(); + + //3.其他测回没有正在测量数据,则在当前测回执行测量 + doSurveyor(); + } + + private void doSurveyor() { + failureCount = 0; + //判断设备是否连接 + if (surveyorImpl().isReady()) { + //发送测量信号 + SurveyStateEvent.postSurveying(positionFragment); + //注册接收测量数据 + surveyorImpl().prepareSurveyor(); + sendSurveyRequest(); + } else { + enterIdleAndClearSurveyStateAndResetAutoMode(true); + Device.getInstance().remindConnectDevice(); + } + } + + + @Override + public void onReceive(double originalHa, double originalVa, double sd, double clockwiseHa, double topVa, double hd, double vd) { + //重置错误读数 + failureCount = 0; + if (getSurveyorData().onSurveyor(originalHa, originalVa, sd, hd)) { + //测量数据成功,可以退出测量状态 + onSuccess(); + } else {//测量数据不完全,需要继续测量 + measureTimeIndex = 1;//更新测量索引 + refreshUI(); + + if (TotalStation.getInstance() instanceof TopconInterface) { + //这个仪器需要延迟500毫秒发送指令 + handler.postDelayed(this::sendSurveyRequest, 500); + } else if (TotalStation.getInstance() instanceof SouthAndroidBtInterface) { + handler.postDelayed(this::sendSurveyRequest, 100); + } else { + sendSurveyRequest(); + } + } + } + + @Override + public void onError(String errorMsg) { + TtsManager.getInstance().speak(errorMsg); + if (allowTryWhenFailure) {//允许重新测量 + if (!isLive()) { + return; + } + //测量出现异常,需要处理 + failureCount++; + if (failureCount >= MAX_SURVEYOR_COUNT) { + if (isAutoSurveyOpen()) { + TtsManager.getInstance().speak(Tools.getString(R.string.many_measure_failed)); + } + onCompleted(RESULT_FAILURE_EXCEED_MAX, Tools.getString(R.string.many_measure_failed_1)); + } else { + //再次尝试 + DebugMsgUtil.canWrite("仪器返回错误信息:" + errorMsg); + DebugMsgUtil.canWrite("开始再次测量"); + sendSurveyRequest(); + ToastUtils.showShort(Tools.getString(R.string.receive_data_time_out)); + } + } else { + onCompleted(RESULT_FAILURE_ERROR, errorMsg); + } + } + + private void sendSurveyRequest() { + int currentIndex = getCurrentIndex(); + if (currentIndex < 0) { + currentIndex = 0; + } + + SurveyorPoint surveyorPoint = getCachedData().getSurveyorPoint(getCycleRecorder().currentCycleIndex(), currentIndex); + ISurveyorData surveyorData = getSurveyorData(); + + surveyorImpl().requestSurveyor(new RequestSurveyorParam(getRequestSurveyorParamAuto(), getInstrumentHeight(), surveyorPoint, measureTimeIndex, + surveyorData.currentIndex(), surveyorData.leftOrRight(), isAlreadyRemindUserAimingAtWire)); + } + + private void onSuccess() { + onCompleted(RESULT_SUCCESS, ""); + } + + private void onCompleted(int result, String msg) { + //退出测量 + surveyorImpl().exitSurveyor(); + switch (result) { + case RESULT_SUCCESS://进入读数检测状态 + //检测是否处于「自动测量」 + if (!surveyState.isAutoSurveying()) { + SurveyStateEvent.postSuccess(positionFragment); + } + navigation2(StateType.checkTolerance); + break; + case RESULT_FAILURE_EXCEED_MAX: +// boolean allowAbandon = getStation().isAllowAbandon(); + if (SettingValueUtil.isAbandonPoint() && isAllowAbandonForVarifyIndex()) { + dealErrorDataSkip(msg); + } else { + dealErrorDataNormal(msg); + } + break; + case RESULT_FAILURE_ERROR: + dealErrorDataNormal(msg); + break; + default: + throw new RuntimeException("un reached state -- surveyor"); + } + } + + @Override + protected void quite() { + super.quite(); + surveyorImpl().exitSurveyor(); + } + + @Override + protected void resume() { + getSurveyorData().clearSurveyState(); + } + + @Override + public void remindUserAimingAtWire() { + //退出测量 + surveyorImpl().exitSurveyor(); + navigation2(StateType.doWellMeasureRotationReady); + } + + private void dealErrorDataNormal(String msg) { + SurveyStateEvent.postFailure(positionFragment); + //进入失败状态 + Bundle args = _SurveyorFailureState.args(msg); + navigation2(StateType.SurveyorFailure, args); + } + + private void dealErrorDataNormal(String msg, boolean isShowDialog) { + SurveyStateEvent.postFailure(positionFragment); + //进入失败状态 + Bundle args = _SurveyorFailureState.args(msg, isShowDialog); + navigation2(StateType.SurveyorFailure, args); + } + + private void dealErrorDataSkip(String msg) { + optionTipsCountDown(msg + Tools.getString(R.string.is_it_abandoned), + Tools.getString(R.string.switch_abandon), + Tools.getString(R.string.ignore), + () -> { + changeSkip(getCycleRecorder().currentCycleIndex(), getCurrentIndex()); + navigation2(StateType.isSingleCycleCompleted); + }, + () -> dealErrorDataNormal(msg, false), + () -> dealErrorDataNormal(msg, false)); + } + + /** + * 针对第一个点和闭合是否废弃验证 + * + * @return + */ + private boolean isAllowAbandonForVarifyIndex() { + boolean autoClose = getStation().isAutoClose(); + int pointCount = getCachedData().pointCount(); + boolean abandon = true; + int currentIndex = getCurrentIndex(); + if (autoClose) { + if (currentIndex == 0 || currentIndex == pointCount - 1) { + abandon = false; + } + } else { + if (currentIndex == 0) { + abandon = false; + } + } + return abandon; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_DoWellMeasureRotationReadyState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_DoWellMeasureRotationReadyState.java new file mode 100644 index 0000000..0a98059 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_DoWellMeasureRotationReadyState.java @@ -0,0 +1,30 @@ +package com.bingce.controlnetwork.surveyor.state.heighttraverse; + +import android.os.Bundle; + +import com.bingce.controlapphelper.event.AutoSurveyorButtonVisibleEvent; +import com.bingce.controlapphelper.event.SurveyStateEvent; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlnetwork.R; + +import net.tatans.tensorflowtts.tts.TtsManager; + +import org.greenrobot.eventbus.EventBus; + +/** + * 钢丝测量旋转到位状态 + */ +class _DoWellMeasureRotationReadyState extends __BaseState { + + public _DoWellMeasureRotationReadyState(int positionFragment, StateManagerHeightTraverse stateManager) { + super(StateType.doWellMeasureRotationReady, positionFragment, stateManager); + } + + @Override + public void enter(Bundle args) { + runOnUI(() -> TtsManager.getInstance().speak(getContext().getString(R.string.please_aiming_at_alone_distance_point_then_measure))); + SurveyStateEvent.postIdle(positionFragment); + EventBus.getDefault().post(new AutoSurveyorButtonVisibleEvent(positionFragment, false, true)); + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_IdleState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_IdleState.java new file mode 100644 index 0000000..0fe1e91 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_IdleState.java @@ -0,0 +1,135 @@ +package com.bingce.controlnetwork.surveyor.state.heighttraverse; + +import android.os.Bundle; + +import androidx.annotation.NonNull; + +import com.bingce.controlapphelper.event.AutoSurveyorButtonVisibleEvent; +import com.bingce.controlapphelper.event.SurveyStateEvent; +import com.bingce.controlapphelper.surveyor.state.IAutoModeSwitcher; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.totalstation.ControlSurveyResult; +import com.bingce.utils.ThreadPoolUtil; + +import net.tatans.tensorflowtts.tts.TtsManager; + +import org.greenrobot.eventbus.EventBus; + +import com.bingce.controlnetwork.fragment.TipsWith2OptionFragment; + +/** + * 空闲状态 + *

+ * 将刷新界面 + */ +class _IdleState extends __BaseState { + private final @NonNull + IAutoModeSwitcher autoModeSwitcher; + + public _IdleState(int positionFragment, StateManagerHeightTraverse stateManager, @NonNull IAutoModeSwitcher autoModeSwitcher) { + super(StateType.idle, positionFragment, stateManager); + this.autoModeSwitcher = autoModeSwitcher; + } + + @Override + public void enter(Bundle args) { + //1.刷新界面 + refreshUI(); + + refreshGoBackBtnEnable(); + + //3.当前cycle是否完成测量 + boolean completed = _CheckToleranceState.isSingleCycleCompleted( + stationId(), + getCurrentCycleIndex(), + getCachedData()); + + //4.检测是否满足自动测量条件 + ThreadPoolUtil.execute(() -> { + //判断当前条件是否满足自动测量 + + boolean haveAutoCondition = haveAutoCondition(); + + if (haveAutoCondition && autoModeSwitcher.isAutoModeOpen() && isLive()) { + navigation2(StateType.doSurveyor); + } else if (haveAutoCondition && autoModeSwitcher.isAutoModeNotSpecial() && !completed) { + //用户选择后会发送通知,更新测量按钮UI + tips4StartAutoSurvey(); + } else { +// ControlSurveyResult.isAbandon(autoMeasureReadyCode) != null//这个错误 + if (autoModeSwitcher.isAutoModeOpen()) { + autoModeSwitcher.resetAutoMode(); + } + postEvent(haveAutoCondition, autoModeSwitcher.isAutoModeOpen(), completed); + } + + }); + } + + /** + * 弹框提示用户是否开启自动测量 + */ + private void tips4StartAutoSurvey() { + runOnUI(() -> + TipsWith2OptionFragment.hardTips( + fragmentManager(), + lifecycleOwner(), + getContext().getString(R.string.tips_finish_study_should_auto_survey), + new TipsWith2OptionFragment.SimpleCallback() { + @Override + public void onConfirm() { + TtsManager.getInstance().speak(Tools.getString(R.string.start_auto_measure)); + autoModeSwitcher.openAutoMode(); + navigation2(StateType.doSurveyor); + + postEvent(true, true, false); + } + + @Override + public void onCancel() { + autoModeSwitcher.closeAutoMode(); + + postEvent(true, false, false); + } + + @Override + public void onIgnore() { + autoModeSwitcher.closeAutoMode(); + + postEvent(true, false, false); + } + } + )); + } + + private void postEvent(boolean isReadyAutoSurvey, boolean isOpenAutoSurvey, boolean isSingleCompleted) { + EventBus.getDefault().post(new AutoSurveyorButtonVisibleEvent(positionFragment, isReadyAutoSurvey, isOpenAutoSurvey)); + if (isSingleCompleted) { + SurveyStateEvent.postCompleted(positionFragment); + } else if (!isOpenAutoSurvey) { + SurveyStateEvent.postIdle(positionFragment); + } + } + + @Override + protected void resume() { + autoModeSwitcher.resetAutoMode(); + //刷新测量按钮 + boolean completed = _CheckToleranceState.isSingleCycleCompleted( + stationId(), + getCurrentCycleIndex(), + getCachedData()); + boolean isReady = autoModeSwitcher.isReadyAutoSurvey() == ControlSurveyResult.CODE_SUCCESS; + + postEvent(isReady, false, completed); + } + + private boolean haveAutoCondition() { + int autoMeasureReadyCode = autoModeSwitcher.isReadyAutoSurvey(); + return autoMeasureReadyCode == ControlSurveyResult.CODE_SUCCESS; + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_Init.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_Init.java new file mode 100644 index 0000000..a7508f2 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_Init.java @@ -0,0 +1,69 @@ +package com.bingce.controlnetwork.surveyor.state.heighttraverse; + +import android.os.Bundle; + +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.model.BundleConstants; +import com.bingce.controlapphelper.model.DataCategory; +import com.bingce.controlapphelper.surveyor.method.FindTargetMethod; +import com.bingce.controlapphelper.surveyor.state.StateType; + +public class _Init extends __BaseState { + + public _Init(int positionFragment, StateManagerHeightTraverse stateManager) { + super(StateType.init, positionFragment, stateManager); + } + + @Override + public void enter(Bundle args) { + + if (getCachedData().pointCount() == 0) { + navigation2(StateType.idle); + return; + } + + //计算状态之前,重置测量状态 + getSurveyorData().clearSurveyStateAndPosition(); + + //1.先查找补测数据 + FindTargetMethod.Target target = lookTarget(dataCategory -> DataCategory.dirtyAndNeedReSurveyor == dataCategory); + if (target != null) { + lookTargetAfter(target.itemIndex, target.leftOrRight); + return; + } + //2.查找empty数据 + target = lookTarget(dataCategory -> DataCategory.empty == dataCategory); + if (target != null) { + //直接跳转到目标点,开启新测量 + lookTargetAfter(target.itemIndex, target.leftOrRight); + return; + } + //3. + String error = _CheckStationState._stationCheck(stationId(), getToleranceRecord(), getCachedData()); + if (error.isEmpty()) { + //设置测量进度(数据库存储) + setAllCycleSchedule(SurveyorScheduleConstants.STATUE_VALUE_CHECKED); + + //清除测量状态,进入idle,停止自动测量 + enterIdleAndClearSurveyStateAndResetAutoMode(true); + } else { + _CheckStationState.showErrorTips(error, stationId(), getToleranceRecord().getCycleCount(), + getCachedData(), + this, + fragmentManager(), + lifecycleOwner()); + } + } + + private FindTargetMethod.Target lookTarget(ILookCase lookCase) { + return _DoMove2NextValidateState.findTarget(stationId(), + getCachedData().pointCount(), getCachedData(), 0, true, + lookCase); + } + + static void enter(StateManagerHeightTraverse stateManager, int cycleIndex) { + Bundle args = new Bundle(); + args.putInt(BundleConstants.KEY_CYCLE_INDEX, cycleIndex); + stateManager.enter(StateType.init, args); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_SurveyorFailureState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_SurveyorFailureState.java new file mode 100644 index 0000000..43527b3 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/_SurveyorFailureState.java @@ -0,0 +1,52 @@ +package com.bingce.controlnetwork.surveyor.state.heighttraverse; + +import android.os.Bundle; + +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; + +/* + * 仪器导致的测量失败 + * + * 全站仪多次测量失败,进入该状态 + * */ +class _SurveyorFailureState extends __BaseState { + + public _SurveyorFailureState(int positionFragment, StateManagerHeightTraverse stateManager) { + super(StateType.SurveyorFailure, positionFragment, stateManager); + } + + @Override + public void enter(Bundle args) { + String error = ""; + boolean isShowDialog = true; + if (args != null) { + error = args.getString(KEY); + isShowDialog = args.getBoolean(KEY_IS_SHOW_DIALOG, true); + } + + if (isShowDialog) { + failureTipsWithAutoStandStill(error + Tools.getString(R.string.please_observe_target)); + } else { + enterIdleAndClearSurveyStateAndResetAutoMode(true); + } + + } + + private static final String KEY = "error"; + private static final String KEY_IS_SHOW_DIALOG = "KEY_IS_SHOW_DIALOG"; + + public static Bundle args(String error) { + Bundle args = new Bundle(); + args.putString(KEY, error); + return args; + } + + public static Bundle args(String error, boolean isShowDialog) { + Bundle args = new Bundle(); + args.putString(KEY, error); + args.putBoolean(KEY_IS_SHOW_DIALOG, isShowDialog); + return args; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/__BaseState.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/__BaseState.java new file mode 100644 index 0000000..a26c1e6 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/state/heighttraverse/__BaseState.java @@ -0,0 +1,572 @@ +package com.bingce.controlnetwork.surveyor.state.heighttraverse; + +import android.content.Context; +import android.os.Bundle; +import android.text.TextUtils; + +import androidx.annotation.NonNull; +import androidx.annotation.StringRes; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleConstants; +import com.bingce.controlapphelper.datasource.database.schedule.SurveyorScheduleRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.model.SurveyorPoint; +import com.bingce.controlapphelper.datasource.database.tolerance.detail.ToleranceDetailRecord; +import com.bingce.controlapphelper.model.BundleConstants; +import com.bingce.controlapphelper.model.LeftOrRight; +import com.bingce.controlapphelper.surveyor.data.ICachedData; +import com.bingce.controlapphelper.surveyor.data.ICycleRecorder; +import com.bingce.controlapphelper.surveyor.data.ISurveyorData; +import com.bingce.controlapphelper.surveyor.state.IAutoModeSwitcher; +import com.bingce.controlapphelper.surveyor.state.StateType; +import com.bingce.controlapphelper.surveyor.surveyor.ISurveyor; +import com.bingce.controlapphelper.surveyor.surveyor.RequestSurveyorParamAuto; +import com.bingce.controlapphelper.util.SurveyorCycleUtil; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.fragment.TipsFragment; +import com.bingce.controlnetwork.fragment.TipsWith2OptionFragment; +import com.bingce.controlnetwork.fragment.stationsurvey.heighttraverse.MeasureHeightTraverseFragment; +import com.bingce.controlnetwork.surveyor.state.AutoModeType; +import com.bingce.utils.ThreadPoolUtil; + +import blankj.utilcode.util.ToastUtils; + +public abstract class __BaseState { + private final StateType type; + private final StateManagerHeightTraverse stateManager; + + protected final int positionFragment; + + /** + * 判断常量 + */ + private final int DEFAULT_AUTO_MODE = 0; + private final int RESET_AUTO_MODE = 1; + private final int CLOSE_AUTO_MODE = 2; + + public __BaseState(final StateType stateType, final int positionFragment, final StateManagerHeightTraverse stateManager) { + this.type = stateType; + this.positionFragment = positionFragment; + this.stateManager = stateManager; + } + + final protected StateType getType() { + return type; + } + + final protected @NonNull + ToleranceDetailRecord getToleranceRecord() { + return stateManager.toleranceRecord; + } + + final protected @NonNull + ISurveyorData getSurveyorData() { + return stateManager.surveyorData; + } + + private @NonNull + IAutoModeSwitcher autoModeRecorder() { + return stateManager; + } + + protected void lookTargetAfter(int targetIndex, LeftOrRight targetSurveyorState) { + //更新测量进度 + setSurveyPosition(targetIndex, targetSurveyorState); + + //清除测量状态,进入idle,但是不停止自动测量 + enterIdleAndClearSurveyStateAndResetAutoMode(false); + + //滚动 + scroll2(targetIndex); + } + + /** + * 设置测量位置 + */ + final protected void setSurveyPosition(int index, LeftOrRight leftOrRight) { + stateManager.surveyorData.setCurrentIndex(index); + stateManager.surveyorData.setLeftOrRight(leftOrRight); + //新增 + if (isAloneDistance()) + ToastUtils.showShort(getContext().getString(R.string.attention_point_is_alone_distance)); + } + + final protected ISurveyor surveyorImpl() { + return stateManager.surveyor; + } + + final protected @NonNull + ICachedData getCachedData() { + return stateManager.cachedData; + } + + SurveyorStationRecord getStation() { + return stateManager.stationRecord; + } + + RequestSurveyorParamAuto getRequestSurveyorParamAuto() { + return stateManager.getRequestSurveyorParamAuto(); + } + + void changeSkip(int cycleIndex, int index) { + SurveyorStationRecord station = getStation(); + //缓存点 + getCachedData().setPointAbandon(cycleIndex, index); + //数据库点 + String pointId = getCachedData().originalPointId(cycleIndex, index); + for (SurveyorPoint surveyorPoint : station.items) { + if (TextUtils.equals(pointId, surveyorPoint.getOriginalPointId())) { + surveyorPoint.setAbandon(true); + break; + } + } + ThreadPoolUtil.execute(() -> { + SurveyorDatabaseFactory.instance.getSurveyorStation().update(station); + }); + } + + final protected @NonNull + ICycleRecorder getCycleRecorder() { + return stateManager.cycleRecorder; + } + + final protected @NonNull + Context getContext() { + return stateManager.context; + } + + final protected void scroll2(int itemIndex) { + stateManager.scrollDelegate.onScrollTo(itemIndex); + } + + final protected void toast(String warning) { + ToastUtils.showShort(warning); + } + + final protected void toast(@StringRes int warning) { + ToastUtils.showShort(warning); + } + + public abstract void enter(Bundle args);//进入状态 + + final protected void navigation2(StateType stateType) { + stateManager.enter(stateType); + } + + final protected void navigation2(StateType stateType, Bundle args) { + stateManager.enter(stateType, args); + } + + final boolean isStationClosed() { + return stateManager.isStationAutoClosed(); + } + + final protected String stationId() { + return stateManager.stationId(); + } + + final protected FragmentManager fragmentManager() { + return stateManager.fragmentManager(); + } + + final protected LifecycleOwner lifecycleOwner() { + return stateManager.lifecycleOwner(); + } + + final protected void tips(String msg, Runnable runnable) { + if (stateManager.isDead()) { + return; + } + TipsFragment.noCancelAbleTips(stateManager.fragmentManager(), stateManager.lifecycleOwner(), + getContext(), + msg, + -1, + () -> { + if (runnable != null) { + runnable.run(); + } + }); + } + + /** + * 错误提示 + *

+ * 用户不能忽略,点击确定后自动「停留原地」 + */ + final protected void failureTipsWithAutoStandStill(String msg) { + if (stateManager.isDead()) { + return; + } + TipsFragment.noCancelAbleTips(stateManager.fragmentManager(), stateManager.lifecycleOwner(), + getContext(), + msg, + -1, + () -> enterIdleAndClearSurveyStateAndResetAutoMode(true)); + } + + final protected void failureTipsWithAutoStandStill(String msg, Runnable runnable) { + if (stateManager.isDead()) { + return; + } + TipsFragment.noCancelAbleTips(stateManager.fragmentManager(), stateManager.lifecycleOwner(), + getContext(), + msg, + -1, + () -> { + if (runnable != null) + runnable.run(); + enterIdleAndClearSurveyStateAndResetAutoMode(true); + }); + } + + final protected void optionTipsWithStandStill(String msg, Runnable confirmCallback) { + optionTips(msg, null, null, + confirmCallback, + () -> enterIdleAndClearSurveyStateAndResetAutoMode(true), + () -> enterIdleAndClearSurveyStateAndResetAutoMode(true)); + } + + final protected void optionTips(String msg, + String confirmButton, + String cancelButton, + Runnable confirmCallback, + Runnable cancelCallback, + Runnable ignoreCallback) { + if (stateManager.isDead()) { + return; + } + TipsWith2OptionFragment.tips( + stateManager.fragmentManager(), + stateManager.lifecycleOwner(), + confirmButton, + cancelButton, + null, + msg, + new TipsWith2OptionFragment.IOperatorCallback() { + @Override + public void onConfirm() { + if (confirmCallback == null) { + return; + } + confirmCallback.run(); + } + + @Override + public void onCancel() { + if (cancelCallback == null) { + return; + } + cancelCallback.run(); + } + + @Override + public void onIgnore() { + if (ignoreCallback == null) { + return; + } + ignoreCallback.run(); + } + + @Override + public void onOption() { + } + }); + } + + final protected void optionTipsCountDown(String msg, + String confirmButton, + String cancelButton, + Runnable confirmCallback, + Runnable cancelCallback, + Runnable ignoreCallback) { + if (stateManager.isDead()) { + return; + } + + TipsWith2OptionFragment.tipsCountDownTime( + stateManager.fragmentManager(), + stateManager.lifecycleOwner(), + confirmButton, + cancelButton, + null, + msg, + new TipsWith2OptionFragment.IOperatorCallback() { + @Override + public void onConfirm() { + if (confirmCallback == null) { + return; + } + confirmCallback.run(); + } + + @Override + public void onCancel() { + if (cancelCallback == null) { + return; + } + cancelCallback.run(); + } + + @Override + public void onIgnore() { + if (ignoreCallback == null) { + return; + } + ignoreCallback.run(); + } + + @Override + public void onOption() { + } + }); + } + + protected final void option4Jump2OtherCycle4Resurvey(int cycleIndex) { + option4Jump2OtherCycle(cycleIndex, true); + } + + protected final void option4Jump2OtherEmptyCycle(int cycleIndex) { + option4Jump2OtherCycle(cycleIndex, false); + } + + private void option4Jump2OtherCycle(int cycleIndex, boolean resurveyOrEmpty) { + String msg = Tools.getString(R.string.there_is_empty_data_to_be_tested_hint); + if (resurveyOrEmpty) { + msg = Tools.getString(R.string.there_is_supplementary_data_to_be_tested_hint); + } + optionTips(Tools.getString(R.string.at) + SurveyorCycleUtil.cycleName(cycleIndex) + msg, + null, + null, + () -> { + //切换测回 + getCycleRecorder().changeCycleIndex(cycleIndex); + //数据库存储修改当前测回 + setCurrentCycle(cycleIndex); + //查找测量目标 + findTargetFromBeginInCurrentCycle(false, 0); + }, + () -> enterIdleAndClearSurveyStateAndResetAutoMode(true), + () -> enterIdleAndClearSurveyStateAndResetAutoMode(true)); + } + + final protected void runOnUI(Runnable runnable) { + stateManager.runOnUI(runnable); + } + + final protected void runOnBackground(Runnable runnable) { + ThreadPoolUtil.execute(runnable); + } + + /** + * 设置测站的测回 + * + * @param cycle + */ + final protected void setCurrentCycle(int cycle) { + getCycleRecorder().changeCycleIndex(cycle); + SurveyorDatabaseFactory + .instance + .getScheduleDataSource() + .record( + new SurveyorScheduleRecord( + SurveyorScheduleConstants.getCurrentCycleKey(stationId(), getScheduleKey(positionFragment)), + String.valueOf(cycle))); + } + + final protected void setCurrentCycleSync(int cycle) { + getCycleRecorder().changeCycleIndex(cycle); + SurveyorDatabaseFactory + .instance + .getScheduleDataSource() + .recordSync( + new SurveyorScheduleRecord( + SurveyorScheduleConstants.getCurrentCycleKey(stationId(), getScheduleKey(positionFragment)), + String.valueOf(cycle))); + } + + final protected void setSingleCycleSchedule(int cycleIndex, String schedule) { + SurveyorDatabaseFactory + .instance + .getScheduleDataSource() + .record( + new SurveyorScheduleRecord( + SurveyorScheduleConstants.getSingleCycleScheduleKey(stationId(), getScheduleKey(positionFragment), cycleIndex), + schedule)); + } + + final protected void setSingleCycleScheduleSync(int cycleIndex, String schedule) { + SurveyorDatabaseFactory + .instance + .getScheduleDataSource() + .recordSync( + new SurveyorScheduleRecord( + SurveyorScheduleConstants.getSingleCycleScheduleKey(stationId(), getScheduleKey(positionFragment), cycleIndex), + schedule)); + } + + final protected void setAllCycleSchedule(String schedule) { + SurveyorDatabaseFactory + .instance + .getScheduleDataSource() + .record( + new SurveyorScheduleRecord( + SurveyorScheduleConstants.getAllCycleScheduleKey(stationId(), getScheduleKey(positionFragment)), + schedule)); + } + + final protected void setAllCycleScheduleSync(String schedule) { + SurveyorDatabaseFactory + .instance + .getScheduleDataSource() + .recordSync( + new SurveyorScheduleRecord( + SurveyorScheduleConstants.getAllCycleScheduleKey(stationId(), getScheduleKey(positionFragment)), + schedule)); + } + + /** + * 如果resetAutoSurveyState为true,将重置autoSurvey状态为unknown + */ + final protected void findTargetFromBeginInCurrentCycle(boolean resetAutoSurveyState, int startLookCycleIndex) { +// getSurveyorData().clearSurveyStateAndPosition(); + if (resetAutoSurveyState) { + autoModeRecorder().resetAutoMode(); + } + if (startLookCycleIndex != -1) { + Bundle bundle = new Bundle(); + bundle.putInt(BundleConstants.KEY_CYCLE_INDEX, startLookCycleIndex); + navigation2(StateType.doMove2NextValidate, bundle); + } else { + navigation2(StateType.doMove2NextValidate); + } + } + + final protected void enterIdleAndClearSurveyState() { + clearSurveyStateAndCloseAutoModeAndStandStill(DEFAULT_AUTO_MODE, + false, StateType.idle); + } + + /** + * 取消测量,会停在当前位置(索引+盘左or盘右),并进入idle + */ + final protected void enterIdleAndClearSurveyStateAndResetAutoMode(boolean resetAutoMode) { + clearSurveyStateAndCloseAutoModeAndStandStill(resetAutoMode ? RESET_AUTO_MODE : DEFAULT_AUTO_MODE, + false, StateType.idle); + } + + final protected void enterIdleAndClearSurveyorStatePosition() { + clearSurveyStateAndCloseAutoModeAndStandStill(DEFAULT_AUTO_MODE, + true, StateType.idle); + } + + final protected void enterStationCheckAndClearSurveyStateAndResetAutoMode() { + clearSurveyStateAndCloseAutoModeAndStandStill(RESET_AUTO_MODE, + false, StateType.checkStation); + } + + final protected void enterIdleAndClearSurveyStateAndCloseAutoMode() { + clearSurveyStateAndCloseAutoModeAndStandStill(CLOSE_AUTO_MODE, false, StateType.idle); + } + + /** + * @param autoMode + * @param clearPosition + * @param stateType + */ + private void clearSurveyStateAndCloseAutoModeAndStandStill(int autoMode, boolean clearPosition, StateType stateType) { + //重置或者关闭自动模式 + if (autoMode == RESET_AUTO_MODE) { + autoModeRecorder().resetAutoMode(); + } else if (autoMode == CLOSE_AUTO_MODE) { + autoModeRecorder().closeAutoMode(); + } + //更新测量进度标识 + if (clearPosition) { + getSurveyorData().clearSurveyStateAndPosition(); + } else { + getSurveyorData().clearSurveyState(); + } + //进入某个状态 + navigation2(stateType); + } + + protected void setAutoAndSurveyorState(AutoModeType autoModeType, boolean clearPosition) { + if (autoModeType == AutoModeType.start) { + autoModeRecorder().openAutoMode(); + } else if (autoModeType == AutoModeType.stop) { + autoModeRecorder().closeAutoMode(); + } else if (autoModeType == AutoModeType.unknown) { + autoModeRecorder().resetAutoMode(); + } + + if (clearPosition) { + getSurveyorData().clearSurveyStateAndPosition(); + } else { + getSurveyorData().clearSurveyState(); + } + } + + + /** + * 更新UI + */ + final protected void refreshUI() { + runOnUI(() -> getCachedData().notifyDateChange()); + } + + protected void quite() { + } + + protected void resume() { + } + + protected boolean isLive() { + return !stateManager.isDead(); + } + + protected boolean isAutoSurveyOpen() { + return stateManager.isAutoModeOpen(); + } + + protected boolean isAutoSurveyClosed() { + return stateManager.isAutoModeClose(); + } + + protected int getCurrentIndex() { + return stateManager.surveyorData.currentIndex(); + } + + protected int getCurrentCycleIndex() { +// return stateManager.cycleRecorder.currentCycleIndex(); + return getCurrentIndex(); + } + + protected boolean isAloneDistance() { + return stateManager.getCachedData().isAloneDistance(stateManager.getCurrentCycle(), getCurrentIndex()); + } + + protected double getInstrumentHeight() { + return stateManager.getInsturmentHeight(); + } + + protected void refreshGoBackBtnEnable() { + stateManager.refreshGoBackBtnEnable(); + } + + protected void resetLearnDataTag() { + getRequestSurveyorParamAuto().resetCodeAutoMeasureCondition(); + } + + public static String getScheduleKey(int positionFragment) { + if (positionFragment == MeasureHeightTraverseFragment.POSITION_BACK_PAGE) { + return SurveyorScheduleConstants.STATION_TYPE_HEIGHT_TRAVERSE_BACK; + } + return SurveyorScheduleConstants.STATION_TYPE_HEIGHT_TRAVERSE_FRONT; + } + + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/surveyor/TestDataSelectFragment.java b/app/src/main/java/com/bingce/controlnetwork/surveyor/surveyor/TestDataSelectFragment.java new file mode 100644 index 0000000..c8f1a2b --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/surveyor/TestDataSelectFragment.java @@ -0,0 +1,74 @@ +package com.bingce.controlnetwork.surveyor.surveyor; + +import android.app.Dialog; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.Window; +import android.view.WindowManager; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.DialogFragment; +import androidx.fragment.app.FragmentManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.surveyor.test.Test; + +import org.jetbrains.annotations.NotNull; + +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.adapter.IndexWithTextAdapter; +import com.bingce.controlnetwork.adapter.IndexWithTextAdapter; + +public class TestDataSelectFragment extends DialogFragment { + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.fragment_single_list_layout, container, false); + + // Set the adapter + if (view instanceof RecyclerView) { + RecyclerView recyclerView = (RecyclerView) view; + refreshRecyclerView(recyclerView); + } + + return view; + } + + @Override + public void onViewCreated(@NonNull @NotNull View view, @Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + Dialog dialog = getDialog(); + if (dialog == null) { + return; + } + Window window = dialog.getWindow(); + if (window == null) { + return; + } + window.setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT); + WindowManager.LayoutParams lps = window.getAttributes(); + lps.verticalMargin = 0.4F; + lps.horizontalMargin = 0.4F; + window.setAttributes(lps); + } + + protected void refreshRecyclerView(RecyclerView recyclerView) { + IndexWithTextAdapter adapter = new IndexWithTextAdapter<>(Test.items, new IndexWithTextAdapter.IOnItemClick() { + @Override + public void onItemClick(Test.Item item) { + Test.type = item; + dismiss(); + } + }); + recyclerView.setAdapter(adapter); + } + + public static void show(FragmentManager fragmentManager) { + TestDataSelectFragment fragment = new TestDataSelectFragment(); + fragment.show(fragmentManager, TestDataSelectFragment.class.getName()); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/util/checkadjust/AngleDistanceCheckAdjust.kt b/app/src/main/java/com/bingce/controlnetwork/surveyor/util/checkadjust/AngleDistanceCheckAdjust.kt new file mode 100644 index 0000000..2315ed8 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/util/checkadjust/AngleDistanceCheckAdjust.kt @@ -0,0 +1,320 @@ +package com.bingce.controlnetwork.surveyor.util.checkadjust + +import com.bingce.controlapphelper.datasource.database.tolerance.detail.ToleranceDetailRecord +import com.bingce.controlapphelper.model.LeftOrRight +import com.bingce.controlapphelper.surveyor.data.ICachedData +import com.bingce.controlapphelper.surveyor.data.IMeasureCache +import com.bingce.controlapphelper.surveyor.method.AverageValueMethod +import com.bingce.controlapphelper.surveyor.method.DeviationValueOfRadianMethod +import com.bingce.controlapphelper.surveyor.method.RadianMethod +import com.bingce.controlapphelper.surveyor.method.ValueOf2cMethod +import com.bingce.controlapphelper.surveyor.method.model.SdAngleValueType +import com.bingce.controlapphelper.util.IdUtil +import com.bingce.controlapphelper.util.SurveyorCycleUtil +import com.bingce.utils.Util +import kotlin.math.abs + +/** + * 常规三角导线测站检测 + * 检测所有测回数据 + *

+ * 在「无自动闭合」情况下,为了兼容「左右角」测量结果,根据pointId将所有测量数据存入map中 + * 根据「左角」测量来检测「测回间同方向值互差」,所有测回的归零值使用「左角」第一个point来做0点 + *

+ * 如果是「自动闭合」情况,则忽略「左右角」测量,直接按照itemIndex依次计算,第个测回的归零值, + * 使用每次循环的itemIndex=0做0点 + * + * @param toleranceRecord 限差 + * @param cachedDataSource 缓存的测量数据 + * @return 错误信息,如果为null或空,说明没有错误 + */ +class AngleDistanceCheckAdjust : IStationCheck { + override fun check( + stationId: String, + toleranceRecord: ToleranceDetailRecord, + measureCache: IMeasureCache + ): String? { + val cacheData = measureCache as ICachedData + + val cycleCount = toleranceRecord.getCycleCount() + val surveyorCount = toleranceRecord.surveyorCount + + //*****测回间同方向值互差(水平角) + val horCyclesDirectValueDifference = + toleranceRecord.getHorCyclesDirectValueDifference() /*horCyclesDirectValueDifference*/ + val horValueError: MutableList<_ErrorItem> = ArrayList() + + //*****测回间垂直角互差(垂直角) + val verCyclesAngleDifference = + toleranceRecord.getVerCyclesAngleDifference() /*verCyclesAngleDifference*/ + val verValueError: MutableList<_ErrorItem> = ArrayList() + + + //执行计算 + for (cycleI in 0 until cycleCount) { + val valuesI = + DeviationValueOfRadianMethod.zeroValueOfSingleCycleInLeftOrientation( + stationId, + cycleI, + surveyorCount, + cacheData + ) + for (cycleJ in cycleI + 1 until cycleCount) { + val valuesJ = + DeviationValueOfRadianMethod.zeroValueOfSingleCycleInLeftOrientation( + stationId, + cycleJ, + surveyorCount, + cacheData + ) + if (valuesI.size != valuesJ.size) { + return "请完成所有重测后再检测测站数据!" + } + val size = valuesI.size + for (index in 0 until size) { + var diff = abs( + DeviationValueOfRadianMethod + .similarRadianDiff( + valuesI[index].horRadian, + valuesJ[index].horRadian + ) + ) + if (horCyclesDirectValueDifference < RadianMethod.radian2S(diff)) { + horValueError.add( + _ErrorItem( + valuesI[index].pointName, + cycleI, cycleJ, RadianMethod.radian2S(diff) + ) + ) + } + + diff = abs( + DeviationValueOfRadianMethod + .similarRadianDiff(valuesI[index].verRadian, valuesJ[index].verRadian) + ) + if (verCyclesAngleDifference < RadianMethod.radian2S(diff)) { + verValueError.add( + _ErrorItem( + valuesI[index].pointName, + cycleI, cycleJ, RadianMethod.radian2S(diff) + ) + ) + } + } + } + } + + //*****测回间垂直角I互差(垂直角) + val verCyclesIDifference = + toleranceRecord.getVerCyclesIDifference() /*verCyclesIDifference*/ + val verIError: MutableList<_ErrorItem> = ArrayList() + + //*****测回间斜距互差(距离) + val distCyclesDifference = + toleranceRecord.getSlopeCycleDistanceDifference() /*slopeCycleDistanceDifference*/ + val distError: MutableList<_ErrorItem> = ArrayList() + + val pointArrayList: MutableList<_Point> = ArrayList() + + //遍历第一测回,收集所有待测点id + for (index in 0 until cacheData.pointCount()) { + if (cacheData.isPointAbandon(0, index)) { + continue + } + pointArrayList.add( + _Point( + cacheData.pointId(0, index), + cacheData.pointName(0, index), + cacheData.isAloneDistance(0, index) + ) + ) + } + + //检测所有待测点i互差 + for (point in pointArrayList) { + for (cycleI in 0 until cycleCount) { + val leftRecordId_I = IdUtil.createSurveyorRecordId( + stationId, + cycleI, + point.pointId, + LeftOrRight.left + ) + val rightRecordId_I = IdUtil.createSurveyorRecordId( + stationId, + cycleI, + point.pointId, + LeftOrRight.right + ) + val value2C_I = ValueOf2cMethod.valueOf2C( + SdAngleValueType.verAngle, leftRecordId_I, rightRecordId_I, + toleranceRecord.surveyorCount, cacheData + ) + val distanceLeftAndRightAverageValue_I = AverageValueMethod.leftAndRightValue( + SdAngleValueType.distance, + leftRecordId_I, + rightRecordId_I, surveyorCount, cacheData + ) + for (cycleJ in cycleI + 1 until cycleCount) { + val leftRecordId_J = IdUtil.createSurveyorRecordId( + stationId, + cycleJ, + point.pointId, + LeftOrRight.left + ) + val rightRecordId_J = IdUtil.createSurveyorRecordId( + stationId, + cycleJ, + point.pointId, + LeftOrRight.right + ) + val value2C_J = ValueOf2cMethod.valueOf2C( + SdAngleValueType.verAngle, leftRecordId_J, rightRecordId_J, + toleranceRecord.surveyorCount, cacheData + ) + val distanceLeftAndRightAverageValue_J = AverageValueMethod.leftAndRightValue( + SdAngleValueType.distance, + leftRecordId_J, + rightRecordId_J, surveyorCount, cacheData + ) + val verI = abs(value2C_I.value - value2C_J.value) + if (verCyclesIDifference < verI) { + verIError.add( + _ErrorItem( + point.pointName, + cycleI, + cycleJ, + verI + ) + ) + } + + if (!point.aloneDistance) { + val distance = + abs(distanceLeftAndRightAverageValue_I.value - distanceLeftAndRightAverageValue_J.value) + if (distCyclesDifference < distance * 1000) { + distError.add( + _ErrorItem( + point.pointName, + cycleI, + cycleJ, + distance * 1000 + ) + ) + } + } + } + } + } + + return _errorString( + horCyclesDirectValueDifference, + verCyclesAngleDifference, + verCyclesIDifference, + distCyclesDifference, + horValueError, + verValueError, + verIError, + distError + ) + + } + + /** + * 根据超限信息生成错误描述 + * + * @param horValueError 水平角同方向值互差 + * @param verValueError 垂直角同方向值互差 + */ + private fun _errorString( + horLimit: Double, + verLimit: Double, + verILimit: Double, + distLimit: Double, + horValueError: List<_ErrorItem>, + verValueError: List<_ErrorItem>, + verIError: List<_ErrorItem>, + distError: List<_ErrorItem> + ): String? { + if (horValueError.isEmpty() && verValueError.isEmpty()) { + return null + } + val stringBuilder = StringBuilder() + if (horValueError.isNotEmpty()) { + stringBuilder.append("测回间同方向值互差超限(限差:") + .append(Util.formatDouble2String(horLimit, 1)) + .append("'')") + for (item in horValueError) { + stringBuilder + .append("\n ") + .append(item.pointName) + .append(":\n") + .append(" |") + .append(SurveyorCycleUtil.cycleName(item.cycleIndex1)) + .append("-") + .append(SurveyorCycleUtil.cycleName(item.cycleIndex2)) + .append("| = ") + .append(Util.formatDouble2String(item.difference, 1)) + .append("'')") + } + } + + if (verValueError.isNotEmpty()) { + stringBuilder.append("\n测回间垂直角互差超限(限差:") + .append(Util.formatDouble2String(verLimit, 1)) + .append("'')") + for (item in verValueError) { + stringBuilder + .append("\n ") + .append(item.pointName) + .append(":\n") + .append(" |") + .append(SurveyorCycleUtil.cycleName(item.cycleIndex1)) + .append("-") + .append(SurveyorCycleUtil.cycleName(item.cycleIndex2)) + .append("| = ") + .append(Util.formatDouble2String(item.difference, 1)) + .append("'')") + } + } + + if (verIError.isNotEmpty()) { + stringBuilder.append("\n垂直角i指标同方向各测回较差超限(限差:") + .append(Util.formatDouble2String(verILimit, 1)) + .append("'')") + for (item in verIError) { + stringBuilder + .append("\n ") + .append(item.pointName) + .append(":\n") + .append(" |") + .append(SurveyorCycleUtil.cycleName(item.cycleIndex1)) + .append("-") + .append(SurveyorCycleUtil.cycleName(item.cycleIndex2)) + .append("| = ") + .append(Util.formatDouble2String(item.difference, 1)) + .append("'')") + } + } + + if (distError.isNotEmpty()) { + stringBuilder.append("\n测回间距离较差超限(限差:") + .append(Util.formatDouble2String(distLimit, 1)) + .append("'')") + for (item in distError) { + stringBuilder + .append("\n ") + .append(item.pointName) + .append(":\n") + .append(" |") + .append(SurveyorCycleUtil.cycleName(item.cycleIndex1)) + .append("-") + .append(SurveyorCycleUtil.cycleName(item.cycleIndex2)) + .append("| = ") + .append(Util.formatDouble2String(item.difference, 1)) + .append("'')") + } + } + + return stringBuilder.toString() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/util/checkadjust/CheckAdjustBean.kt b/app/src/main/java/com/bingce/controlnetwork/surveyor/util/checkadjust/CheckAdjustBean.kt new file mode 100644 index 0000000..0fb3424 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/util/checkadjust/CheckAdjustBean.kt @@ -0,0 +1,17 @@ +package com.bingce.controlnetwork.surveyor.util.checkadjust + +/** + * 存储错误信息的item + */ +class _ErrorItem( + val pointName: String, + val cycleIndex1: Int, + val cycleIndex2: Int, + val difference: Double +) + +class _Point( + val pointId: String, + val pointName: String, + val aloneDistance: Boolean +) \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/surveyor/util/checkadjust/IStationCheck.kt b/app/src/main/java/com/bingce/controlnetwork/surveyor/util/checkadjust/IStationCheck.kt new file mode 100644 index 0000000..3651bbb --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/surveyor/util/checkadjust/IStationCheck.kt @@ -0,0 +1,12 @@ +package com.bingce.controlnetwork.surveyor.util.checkadjust + +import com.bingce.controlapphelper.datasource.database.tolerance.detail.ToleranceDetailRecord +import com.bingce.controlapphelper.surveyor.data.IMeasureCache + +interface IStationCheck { + fun check( + stationId: String, + toleranceRecord: ToleranceDetailRecord, + measureCache: IMeasureCache + ): String? +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/ViewUtil.java b/app/src/main/java/com/bingce/controlnetwork/ui/ViewUtil.java new file mode 100644 index 0000000..944b6e4 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/ViewUtil.java @@ -0,0 +1,18 @@ +package com.bingce.controlnetwork.ui; + +import android.app.Activity; +import android.view.View; + +public class ViewUtil { + public static void setOnClick(View view, View.OnClickListener listener) { + if (view == null) { + return; + } + view.setOnClickListener(listener); + } + + public static void setOnClick(Activity activity, int view, View.OnClickListener listener) { + View v = activity.findViewById(view); + setOnClick(v, listener); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/WechatImagePicker.java b/app/src/main/java/com/bingce/controlnetwork/ui/WechatImagePicker.java new file mode 100644 index 0000000..9d47f67 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/WechatImagePicker.java @@ -0,0 +1,21 @@ +package com.bingce.controlnetwork.ui; + +import android.content.Context; + +import com.qingmei2.rximagepicker.entity.Result; +import com.qingmei2.rximagepicker.entity.sources.Camera; +import com.qingmei2.rximagepicker.entity.sources.Gallery; +import com.qingmei2.rximagepicker.ui.ICustomPickerConfiguration; +import com.qingmei2.rximagepicker_extension_wechat.ui.WechatImagePickerActivity; + +import io.reactivex.Observable; + +public interface WechatImagePicker { + + @Gallery(componentClazz = WechatImagePickerActivity.class, + openAsFragment = false) + Observable openGallery(Context context, ICustomPickerConfiguration config); + + @Camera + Observable openCamera(Context context); +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/helper/OnActivityTouchListener.java b/app/src/main/java/com/bingce/controlnetwork/ui/helper/OnActivityTouchListener.java new file mode 100644 index 0000000..419c603 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/helper/OnActivityTouchListener.java @@ -0,0 +1,7 @@ +package com.bingce.controlnetwork.ui.helper; + +import android.view.MotionEvent; + +public interface OnActivityTouchListener { + void getTouchCoordinates(MotionEvent ev); +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/helper/RecyclerTouchListener.java b/app/src/main/java/com/bingce/controlnetwork/ui/helper/RecyclerTouchListener.java new file mode 100644 index 0000000..6687e8c --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/helper/RecyclerTouchListener.java @@ -0,0 +1,918 @@ +package com.bingce.controlnetwork.ui.helper; + +import android.animation.Animator; +import android.animation.ObjectAnimator; +import android.app.Activity; +import android.graphics.Rect; +import android.os.Handler; +import android.util.DisplayMetrics; +import android.util.Log; +import android.view.MotionEvent; +import android.view.VelocityTracker; +import android.view.View; +import android.view.ViewConfiguration; +import android.view.animation.DecelerateInterpolator; +import android.widget.ListView; + +import androidx.recyclerview.widget.RecyclerView; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class RecyclerTouchListener implements RecyclerView.OnItemTouchListener, OnActivityTouchListener { + private static final String TAG = "RecyclerTouchListener"; + final Handler handler = new Handler(); + Activity act; + List unSwipeableRows; + /* + * independentViews are views on the foreground layer which when clicked, act "independent" from the foreground + * ie, they are treated separately from the "row click" action + */ + List independentViews; + List unClickableRows; + List optionViews; + Set ignoredViewTypes; + // Cached ViewConfiguration and system-wide constant values + private final int touchSlop; + private final int minFlingVel; + private final int maxFlingVel; + private final long ANIMATION_STANDARD = 300; + private final long ANIMATION_CLOSE = 150; + // Fixed properties + private final RecyclerView rView; + // private SwipeListener mSwipeListener; + private int bgWidth = 1; + private final int bgWidthLeft = 1; // 1 and not 0 to prevent dividing by zero + // Transient properties + // private List mPendingDismisses = new ArrayList<>(); + private int mDismissAnimationRefCount = 0; + private float touchedX; + private float touchedY; + private boolean isFgSwiping; + private int mSwipingSlop; + private VelocityTracker mVelocityTracker; + private int touchedPosition; + private View touchedView; + private boolean mPaused; + private boolean bgVisible, fgPartialViewClicked; + private int bgVisiblePosition; + private View bgVisibleView; + private boolean isRViewScrolling; + private int heightOutsideRView, screenHeight; + private boolean mLongClickPerformed; + // Foreground view (to be swiped), Background view (to show) + private View fgView; + private View bgView; + //view ID + private int fgViewID; + private int bgViewID, bgViewIDLeft; + private ArrayList fadeViews; + private OnRowClickListener mRowClickListener; + private OnRowLongClickListener mRowLongClickListener; + private OnSwipeOptionsClickListener mBgClickListener, mBgClickListenerLeft; + // user choices + private boolean clickable = false; + private boolean longClickable = false; + private boolean swipeable = false; + private final boolean swipeableLeftOptions = false; + private final int LONG_CLICK_DELAY = 800; + private boolean longClickVibrate; + Runnable mLongPressed = new Runnable() { + public void run() { + if (!longClickable) + return; + + mLongClickPerformed = true; + + if (!bgVisible && touchedPosition >= 0 && !unClickableRows.contains(touchedPosition) && !isRViewScrolling) { + if (longClickVibrate) { +// Vibrator vibe = (Vibrator) act.getSystemService(Context.VIBRATOR_SERVICE); +// vibe.vibrate(100); // do we really need to add vibrate service + } + mRowLongClickListener.onRowLongClicked(touchedPosition); + } + } + }; + + public RecyclerTouchListener(Activity a, RecyclerView recyclerView) { + this.act = a; + ViewConfiguration vc = ViewConfiguration.get(recyclerView.getContext()); + touchSlop = vc.getScaledTouchSlop(); + minFlingVel = vc.getScaledMinimumFlingVelocity() * 16; + maxFlingVel = vc.getScaledMaximumFlingVelocity(); + rView = recyclerView; + bgVisible = false; + bgVisiblePosition = -1; + bgVisibleView = null; + fgPartialViewClicked = false; + unSwipeableRows = new ArrayList<>(); + unClickableRows = new ArrayList<>(); + ignoredViewTypes = new HashSet<>(); + independentViews = new ArrayList<>(); + optionViews = new ArrayList<>(); + fadeViews = new ArrayList<>(); + isRViewScrolling = false; + +// mSwipeListener = listener; + + rView.addOnScrollListener(new RecyclerView.OnScrollListener() { + @Override + public void onScrollStateChanged(RecyclerView recyclerView, int newState) { + /** + * This will ensure that this RecyclerTouchListener is paused during recycler view scrolling. + * If a scroll listener is already assigned, the caller should still pass scroll changes through + * to this listener. + */ + setEnabled(newState != RecyclerView.SCROLL_STATE_DRAGGING); + + /** + * This is used so that clicking a row cannot be done while scrolling + */ + isRViewScrolling = newState != RecyclerView.SCROLL_STATE_IDLE; + } + + @Override + public void onScrolled(RecyclerView recyclerView, int dx, int dy) { + + } + }); + } + + /** + * Enables or disables (pauses or resumes) watching for swipe-to-dismiss gestures. + * + * @param enabled Whether or not to watch for gestures. + */ + public void setEnabled(boolean enabled) { + mPaused = !enabled; + } + + @Override + public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent motionEvent) { + return handleTouchEvent(motionEvent); + } + + @Override + public void onTouchEvent(RecyclerView rv, MotionEvent motionEvent) { + handleTouchEvent(motionEvent); + } + + /*////////////// Clickable ////////////////////*/ + + public RecyclerTouchListener setClickable(OnRowClickListener listener) { + this.clickable = true; + this.mRowClickListener = listener; + return this; + } + + public RecyclerTouchListener setClickable(boolean clickable) { + this.clickable = clickable; + return this; + } + + public RecyclerTouchListener setLongClickable(boolean vibrate, OnRowLongClickListener listener) { + this.longClickable = true; + this.mRowLongClickListener = listener; + this.longClickVibrate = vibrate; + return this; + } + + public RecyclerTouchListener setLongClickable(boolean longClickable) { + this.longClickable = longClickable; + return this; + } + + public RecyclerTouchListener setIndependentViews(Integer... viewIds) { + this.independentViews = new ArrayList<>(Arrays.asList(viewIds)); + return this; + } + + public RecyclerTouchListener setUnClickableRows(Integer... rows) { + this.unClickableRows = new ArrayList<>(Arrays.asList(rows)); + return this; + } + + public RecyclerTouchListener setIgnoredViewTypes(Integer... viewTypes) { + ignoredViewTypes.clear(); + ignoredViewTypes.addAll(Arrays.asList(viewTypes)); + return this; + } + + //////////////// Swipeable //////////////////// + + public RecyclerTouchListener setSwipeable(int foregroundID, int backgroundID, OnSwipeOptionsClickListener listener) { + this.swipeable = true; + if (fgViewID != 0 && foregroundID != fgViewID) + throw new IllegalArgumentException("foregroundID does not match previously set ID"); + fgViewID = foregroundID; + bgViewID = backgroundID; + this.mBgClickListener = listener; + + if (act instanceof RecyclerTouchListenerHelper) + ((RecyclerTouchListenerHelper) act).setOnActivityTouchListener(this); + + DisplayMetrics displaymetrics = new DisplayMetrics(); + act.getWindowManager().getDefaultDisplay().getMetrics(displaymetrics); + screenHeight = displaymetrics.heightPixels; + + return this; + } + + public RecyclerTouchListener setSwipeable(boolean value) { + this.swipeable = value; + if (!value) + invalidateSwipeOptions(); + return this; + } + + public RecyclerTouchListener setSwipeOptionViews(Integer... viewIds) { + this.optionViews = new ArrayList<>(Arrays.asList(viewIds)); + return this; + } + + public RecyclerTouchListener setUnSwipeableRows(Integer... rows) { + this.unSwipeableRows = new ArrayList<>(Arrays.asList(rows)); + return this; + } + + //////////////// Fade Views //////////////////// + + // Set views which are faded out as fg is opened + public RecyclerTouchListener setViewsToFade(Integer... viewIds) { + this.fadeViews = new ArrayList<>(Arrays.asList(viewIds)); + return this; + } + + // the entire foreground is faded out as it is opened + public RecyclerTouchListener setFgFade() { + if (!fadeViews.contains(fgViewID)) + this.fadeViews.add(fgViewID); + return this; + } + + //-------------- Checkers for preventing ---------------// + + private boolean isIndependentViewClicked(MotionEvent motionEvent) { + for (int i = 0; i < independentViews.size(); i++) { + if (touchedView != null) { + Rect rect = new Rect(); + int x = (int) motionEvent.getRawX(); + int y = (int) motionEvent.getRawY(); + touchedView.findViewById(independentViews.get(i)).getGlobalVisibleRect(rect); + if (rect.contains(x, y)) { + return false; + } + } + } + return true; + } + + private int getOptionViewID(MotionEvent motionEvent) { + for (int i = 0; i < optionViews.size(); i++) { + if (touchedView != null) { + Rect rect = new Rect(); + int x = (int) motionEvent.getRawX(); + int y = (int) motionEvent.getRawY(); + touchedView.findViewById(optionViews.get(i)).getGlobalVisibleRect(rect); + if (rect.contains(x, y)) { + return optionViews.get(i); + } + } + } + return -1; + } + + private int getIndependentViewID(MotionEvent motionEvent) { + for (int i = 0; i < independentViews.size(); i++) { + if (touchedView != null) { + Rect rect = new Rect(); + int x = (int) motionEvent.getRawX(); + int y = (int) motionEvent.getRawY(); + touchedView.findViewById(independentViews.get(i)).getGlobalVisibleRect(rect); + if (rect.contains(x, y)) { + return independentViews.get(i); + } + } + } + return -1; + } + + @Override + public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) { + + } + + public void invalidateSwipeOptions() { + bgWidth = 1; + } + + public void openSwipeOptions(int position) { + if (!swipeable || rView.getChildAt(position) == null + || unSwipeableRows.contains(position) || shouldIgnoreAction(position)) + return; + if (bgWidth < 2) { + if (act.findViewById(bgViewID) != null) + bgWidth = act.findViewById(bgViewID).getWidth(); + heightOutsideRView = screenHeight - rView.getHeight(); + } + touchedPosition = position; + touchedView = rView.getChildAt(position); + fgView = touchedView.findViewById(fgViewID); + bgView = touchedView.findViewById(bgViewID); + bgView.setMinimumHeight(fgView.getHeight()); + + closeVisibleBG(null); + animateFG(touchedView, Animation.OPEN, ANIMATION_STANDARD); + bgVisible = true; + bgVisibleView = fgView; + bgVisiblePosition = touchedPosition; + } + + @Deprecated + public void closeVisibleBG() { + if (bgVisibleView == null) { + Log.e(TAG, "No rows found for which background options are visible"); + return; + } + bgVisibleView.animate() + .translationX(0) + .setDuration(ANIMATION_CLOSE) + .setListener(null); + + animateFadeViews(bgVisibleView, 1f, ANIMATION_CLOSE); + bgVisible = false; + bgVisibleView = null; + bgVisiblePosition = -1; + } + + public void closeVisibleBG(final OnSwipeListener mSwipeCloseListener) { + if (bgVisibleView == null) { + Log.e(TAG, "No rows found for which background options are visible"); + return; + } + final ObjectAnimator translateAnimator = ObjectAnimator.ofFloat(bgVisibleView, + View.TRANSLATION_X, 0f); + translateAnimator.setDuration(ANIMATION_CLOSE); + translateAnimator.addListener(new Animator.AnimatorListener() { + @Override + public void onAnimationStart(Animator animation) { + } + + @Override + public void onAnimationEnd(Animator animation) { + if (mSwipeCloseListener != null) + mSwipeCloseListener.onSwipeOptionsClosed(); + translateAnimator.removeAllListeners(); + } + + @Override + public void onAnimationCancel(Animator animation) { + } + + @Override + public void onAnimationRepeat(Animator animation) { + } + }); + translateAnimator.start(); + + animateFadeViews(bgVisibleView, 1f, ANIMATION_CLOSE); + bgVisible = false; + bgVisibleView = null; + bgVisiblePosition = -1; + } + + private void animateFadeViews(View downView, float alpha, long duration) { + if (fadeViews != null) { + for (final int viewID : fadeViews) { + downView.findViewById(viewID).animate() + .alpha(alpha) + .setDuration(duration); + } + } + } + + private void animateFG(View downView, Animation animateType, long duration) { + if (animateType == Animation.OPEN) { + ObjectAnimator translateAnimator = ObjectAnimator.ofFloat( + fgView, View.TRANSLATION_X, -bgWidth); + translateAnimator.setDuration(duration); + translateAnimator.setInterpolator(new DecelerateInterpolator(1.5f)); + translateAnimator.start(); + animateFadeViews(downView, 0f, duration); + } else if (animateType == Animation.CLOSE) { + ObjectAnimator translateAnimator = ObjectAnimator.ofFloat( + fgView, View.TRANSLATION_X, 0f); + translateAnimator.setDuration(duration); + translateAnimator.setInterpolator(new DecelerateInterpolator(1.5f)); + translateAnimator.start(); + animateFadeViews(downView, 1f, duration); + } + } + + private void animateFG(View downView, final Animation animateType, long duration, + final OnSwipeListener mSwipeCloseListener) { + final ObjectAnimator translateAnimator; + if (animateType == Animation.OPEN) { + translateAnimator = ObjectAnimator.ofFloat(fgView, View.TRANSLATION_X, -bgWidth); + translateAnimator.setDuration(duration); + translateAnimator.setInterpolator(new DecelerateInterpolator(1.5f)); + translateAnimator.start(); + animateFadeViews(downView, 0f, duration); + } else /*if (animateType == Animation.CLOSE)*/ { + translateAnimator = ObjectAnimator.ofFloat(fgView, View.TRANSLATION_X, 0f); + translateAnimator.setDuration(duration); + translateAnimator.setInterpolator(new DecelerateInterpolator(1.5f)); + translateAnimator.start(); + animateFadeViews(downView, 1f, duration); + } + + translateAnimator.addListener(new Animator.AnimatorListener() { + @Override + public void onAnimationStart(Animator animation) { + } + + @Override + public void onAnimationEnd(Animator animation) { + if (mSwipeCloseListener != null) { + if (animateType == Animation.OPEN) + mSwipeCloseListener.onSwipeOptionsOpened(); + else if (animateType == Animation.CLOSE) + mSwipeCloseListener.onSwipeOptionsClosed(); + } + translateAnimator.removeAllListeners(); + } + + @Override + public void onAnimationCancel(Animator animation) { + } + + @Override + public void onAnimationRepeat(Animator animation) { + } + }); + } + + private boolean handleTouchEvent(MotionEvent motionEvent) { + if (swipeable && bgWidth < 2) { +// bgWidth = rView.getWidth(); + if (act.findViewById(bgViewID) != null) + bgWidth = act.findViewById(bgViewID).getWidth(); + + heightOutsideRView = screenHeight - rView.getHeight(); + } + + switch (motionEvent.getActionMasked()) { + + // When finger touches screen + case MotionEvent.ACTION_DOWN: { + if (mPaused) { + break; + } + + // Find the child view that was touched (perform a hit test) + Rect rect = new Rect(); + int childCount = rView.getChildCount(); + int[] listViewCoords = new int[2]; + rView.getLocationOnScreen(listViewCoords); + // x and y values respective to the recycler view + int x = (int) motionEvent.getRawX() - listViewCoords[0]; + int y = (int) motionEvent.getRawY() - listViewCoords[1]; + View child; + + /* + * check for every child (row) in the recycler view whether the touched co-ordinates belong to that + * respective child and if it does, register that child as the touched view (touchedView) + */ + for (int i = 0; i < childCount; i++) { + child = rView.getChildAt(i); + child.getHitRect(rect); + if (rect.contains(x, y)) { + touchedView = child; + break; + } + } + + if (touchedView != null) { + touchedX = motionEvent.getRawX(); + touchedY = motionEvent.getRawY(); + touchedPosition = rView.getChildAdapterPosition(touchedView); + + if (shouldIgnoreAction(touchedPosition)) { + touchedPosition = ListView.INVALID_POSITION; + return false; // <-- guard here allows for ignoring events, allowing more than one view type and preventing NPE + } + + if (longClickable) { + mLongClickPerformed = false; + handler.postDelayed(mLongPressed, LONG_CLICK_DELAY); + } + if (swipeable) { + mVelocityTracker = VelocityTracker.obtain(); + mVelocityTracker.addMovement(motionEvent); + fgView = touchedView.findViewById(fgViewID); + bgView = touchedView.findViewById(bgViewID); +// bgView.getLayoutParams().height = fgView.getHeight(); + bgView.setMinimumHeight(fgView.getHeight()); + + /* + * bgVisible is true when the options menu is opened + * This block is to register fgPartialViewClicked status - Partial view is the view that is still + * shown on the screen if the options width is < device width + */ + if (bgVisible && fgView != null) { + handler.removeCallbacks(mLongPressed); + x = (int) motionEvent.getRawX(); + y = (int) motionEvent.getRawY(); + fgView.getGlobalVisibleRect(rect); + fgPartialViewClicked = rect.contains(x, y); + } else { + fgPartialViewClicked = false; + } + } + } + + /* + * If options menu is shown and the touched position is not the same as the row for which the + * options is displayed - close the options menu for the row which is displaying it + * (bgVisibleView and bgVisiblePosition is used for this purpose which registers which view and + * which position has it's options menu opened) + */ + x = (int) motionEvent.getRawX(); + y = (int) motionEvent.getRawY(); + rView.getHitRect(rect); + if (swipeable && bgVisible && touchedPosition != bgVisiblePosition) { + handler.removeCallbacks(mLongPressed); + closeVisibleBG(null); + } + break; + } + + case MotionEvent.ACTION_CANCEL: { + handler.removeCallbacks(mLongPressed); + if (mLongClickPerformed) + break; + + if (mVelocityTracker == null) { + break; + } + if (swipeable) { + if (touchedView != null && isFgSwiping) { + // cancel + animateFG(touchedView, Animation.CLOSE, ANIMATION_STANDARD); + } + mVelocityTracker.recycle(); + mVelocityTracker = null; + isFgSwiping = false; + bgView = null; + } + touchedX = 0; + touchedY = 0; + touchedView = null; + touchedPosition = ListView.INVALID_POSITION; + break; + } + + // When finger is lifted off the screen (after clicking, flinging, swiping, etc..) + case MotionEvent.ACTION_UP: { + handler.removeCallbacks(mLongPressed); + if (mLongClickPerformed) + break; + + if (mVelocityTracker == null && swipeable) { + break; + } + if (touchedPosition < 0) + break; + + // swipedLeft and swipedRight are true if the user swipes in the respective direction (no conditions) + boolean swipedLeft = false; + boolean swipedRight = false; + /* + * swipedLeftProper and swipedRightProper are true if user swipes in the respective direction + * and if certain conditions are satisfied (given some few lines below) + */ + boolean swipedLeftProper = false; + boolean swipedRightProper = false; + + float mFinalDelta = motionEvent.getRawX() - touchedX; + + // if swiped in a direction, make that respective variable true + if (isFgSwiping) { + swipedLeft = mFinalDelta < 0; + swipedRight = mFinalDelta > 0; + } + + /* + * If the user has swiped more than half of the width of the options menu, or if the + * velocity of swiping is between min and max fling values + * "proper" variable are set true + */ + if (Math.abs(mFinalDelta) > bgWidth / 2 && isFgSwiping) { + swipedLeftProper = mFinalDelta < 0; + swipedRightProper = mFinalDelta > 0; + } else if (swipeable) { + mVelocityTracker.addMovement(motionEvent); + mVelocityTracker.computeCurrentVelocity(1000); + float velocityX = mVelocityTracker.getXVelocity(); + float absVelocityX = Math.abs(velocityX); + float absVelocityY = Math.abs(mVelocityTracker.getYVelocity()); + if (minFlingVel <= absVelocityX && absVelocityX <= maxFlingVel + && absVelocityY < absVelocityX && isFgSwiping) { + // dismiss only if flinging in the same direction as dragging + swipedLeftProper = (velocityX < 0) == (mFinalDelta < 0); + swipedRightProper = (velocityX > 0) == (mFinalDelta > 0); + } + } + + ///////// Manipulation of view based on the 4 variables mentioned above /////////// + + // if swiped left properly and options menu isn't already visible, animate the foreground to the left + if (swipeable && !swipedRight && swipedLeftProper && touchedPosition != RecyclerView.NO_POSITION + && !unSwipeableRows.contains(touchedPosition) && !bgVisible) { + + final View downView = touchedView; // touchedView gets null'd before animation ends + final int downPosition = touchedPosition; + ++mDismissAnimationRefCount; + //TODO - speed + animateFG(touchedView, Animation.OPEN, ANIMATION_STANDARD); + bgVisible = true; + bgVisibleView = fgView; + bgVisiblePosition = downPosition; + } + // else if swiped right properly when options menu is visible, close the menu and bring the foreground + // to it's original position + else if (swipeable && !swipedLeft && swipedRightProper && touchedPosition != RecyclerView.NO_POSITION + && !unSwipeableRows.contains(touchedPosition) && bgVisible) { + // dismiss + final View downView = touchedView; // touchedView gets null'd before animation ends + final int downPosition = touchedPosition; + + ++mDismissAnimationRefCount; + //TODO - speed + animateFG(touchedView, Animation.CLOSE, ANIMATION_STANDARD); + bgVisible = false; + bgVisibleView = null; + bgVisiblePosition = -1; + } + // else if swiped left incorrectly (not satisfying the above conditions), animate the foreground back to + // it's original position (spring effect) + else if (swipeable && swipedLeft && !bgVisible) { + // cancel + final View tempBgView = bgView; + animateFG(touchedView, Animation.CLOSE, ANIMATION_STANDARD, new OnSwipeListener() { + @Override + public void onSwipeOptionsClosed() { + if (tempBgView != null) + tempBgView.setVisibility(View.VISIBLE); + } + + @Override + public void onSwipeOptionsOpened() { + + } + }); + + bgVisible = false; + bgVisibleView = null; + bgVisiblePosition = -1; + } + // else if swiped right incorrectly (not satisfying the above conditions), animate the foreground to + // it's open position (spring effect) + else if (swipeable && swipedRight && bgVisible) { + // cancel + animateFG(touchedView, Animation.OPEN, ANIMATION_STANDARD); + bgVisible = true; + bgVisibleView = fgView; + bgVisiblePosition = touchedPosition; + } + // This case deals with an error where the user can swipe left, then right + // really fast and the fg is stuck open - so in that case we close the fg + else if (swipeable && swipedRight && !bgVisible) { + // cancel + animateFG(touchedView, Animation.CLOSE, ANIMATION_STANDARD); + bgVisible = false; + bgVisibleView = null; + bgVisiblePosition = -1; + } + // This case deals with an error where the user can swipe right, then left + // really fast and the fg is stuck open - so in that case we open the fg + else if (swipeable && swipedLeft && bgVisible) { + // cancel + animateFG(touchedView, Animation.OPEN, ANIMATION_STANDARD); + bgVisible = true; + bgVisibleView = fgView; + bgVisiblePosition = touchedPosition; + } + + // if clicked + else if (!swipedRight && !swipedLeft) { + // if partial foreground view is clicked (see ACTION_DOWN) bring foreground back to original position + // bgVisible is true automatically since it's already checked in ACTION_DOWN block + if (swipeable && fgPartialViewClicked) { + animateFG(touchedView, Animation.CLOSE, ANIMATION_STANDARD); + bgVisible = false; + bgVisibleView = null; + bgVisiblePosition = -1; + } + // On Click listener for rows + else if (clickable && !bgVisible && touchedPosition >= 0 && !unClickableRows.contains(touchedPosition) + && isIndependentViewClicked(motionEvent) && !isRViewScrolling) { + mRowClickListener.onRowClicked(touchedPosition); + } + // On Click listener for independent views inside the rows + else if (clickable && !bgVisible && touchedPosition >= 0 && !unClickableRows.contains(touchedPosition) + && !isIndependentViewClicked(motionEvent) && !isRViewScrolling) { + final int independentViewID = getIndependentViewID(motionEvent); + if (independentViewID >= 0) + mRowClickListener.onIndependentViewClicked(independentViewID, touchedPosition); + } + // On Click listener for background options + else if (swipeable && bgVisible && !fgPartialViewClicked) { + final int optionID = getOptionViewID(motionEvent); + if (optionID >= 0 && touchedPosition >= 0) { + final int downPosition = touchedPosition; + closeVisibleBG(new OnSwipeListener() { + @Override + public void onSwipeOptionsClosed() { + mBgClickListener.onSwipeOptionClicked(optionID, downPosition); + } + + @Override + public void onSwipeOptionsOpened() { + + } + }); + } + } + } + } + // if clicked and not swiped + + if (swipeable) { + mVelocityTracker.recycle(); + mVelocityTracker = null; + } + touchedX = 0; + touchedY = 0; + touchedView = null; + touchedPosition = ListView.INVALID_POSITION; + isFgSwiping = false; + bgView = null; + break; + + // when finger is moving across the screen (and not yet lifted) + case MotionEvent.ACTION_MOVE: { + if (mLongClickPerformed) + break; + if (mVelocityTracker == null || mPaused || !swipeable) { + break; + } + + mVelocityTracker.addMovement(motionEvent); + float deltaX = motionEvent.getRawX() - touchedX; + float deltaY = motionEvent.getRawY() - touchedY; + + /* + * isFgSwiping variable which is set to true here is used to alter the swipedLeft, swipedRightProper + * variables in "ACTION_UP" block by checking if user is actually swiping at present or not + */ + if (!isFgSwiping && Math.abs(deltaX) > touchSlop && Math.abs(deltaY) < Math.abs(deltaX) / 2) { + handler.removeCallbacks(mLongPressed); + isFgSwiping = true; + mSwipingSlop = (deltaX > 0 ? touchSlop : -touchSlop); + } + + // This block moves the foreground along with the finger when swiping + if (swipeable && isFgSwiping && !unSwipeableRows.contains(touchedPosition)) { + if (bgView == null) { + bgView = touchedView.findViewById(bgViewID); + bgView.setVisibility(View.VISIBLE); + } + // if fg is being swiped left + if (deltaX < touchSlop && !bgVisible) { + float translateAmount = deltaX - mSwipingSlop; +// if ((Math.abs(translateAmount) > bgWidth ? -bgWidth : translateAmount) <= 0) { + // swipe fg till width of bg. If swiped further, nothing happens (stalls at width of bg) + fgView.setTranslationX(Math.abs(translateAmount) > bgWidth ? -bgWidth : translateAmount); + if (fgView.getTranslationX() > 0) fgView.setTranslationX(0); +// } + + // fades all the fadeViews gradually to 0 alpha as dragged + if (fadeViews != null) { + for (int viewID : fadeViews) { + touchedView.findViewById(viewID).setAlpha(1 - (Math.abs(translateAmount) / bgWidth)); + } + } + } + // if fg is being swiped right + else if (deltaX > 0 && bgVisible) { + // for closing rightOptions + if (bgVisible) { + float translateAmount = (deltaX - mSwipingSlop) - bgWidth; + + // swipe fg till it reaches original position. If swiped further, nothing happens (stalls at 0) + fgView.setTranslationX(translateAmount > 0 ? 0 : translateAmount); + + // fades all the fadeViews gradually to 0 alpha as dragged + if (fadeViews != null) { + for (int viewID : fadeViews) { + touchedView.findViewById(viewID).setAlpha(1 - (Math.abs(translateAmount) / bgWidth)); + } + } + } + // for opening leftOptions + else { + float translateAmount = (deltaX - mSwipingSlop) - bgWidth; + + // swipe fg till it reaches original position. If swiped further, nothing happens (stalls at 0) + fgView.setTranslationX(translateAmount > 0 ? 0 : translateAmount); + + // fades all the fadeViews gradually to 0 alpha as dragged + if (fadeViews != null) { + for (int viewID : fadeViews) { + touchedView.findViewById(viewID).setAlpha(1 - (Math.abs(translateAmount) / bgWidth)); + } + } + } + } + return true; + } + // moves the fg slightly to give the illusion of an "unswipeable" row + else if (swipeable && isFgSwiping && unSwipeableRows.contains(touchedPosition)) { + if (deltaX < touchSlop && !bgVisible) { + float translateAmount = deltaX - mSwipingSlop; + if (bgView == null) + bgView = touchedView.findViewById(bgViewID); + + if (bgView != null) + bgView.setVisibility(View.GONE); + + // swipe fg till width of bg. If swiped further, nothing happens (stalls at width of bg) + fgView.setTranslationX(translateAmount / 5); + if (fgView.getTranslationX() > 0) fgView.setTranslationX(0); + + // fades all the fadeViews gradually to 0 alpha as dragged +// if (fadeViews != null) { +// for (int viewID : fadeViews) { +// touchedView.findViewById(viewID).setAlpha(1 - (Math.abs(translateAmount) / bgWidth)); +// } +// } + } + return true; + } + break; + } + } + return false; + } + + /** + * Gets coordinates from Activity and closes any + * swiped rows if touch happens outside the recycler view + */ + @Override + public void getTouchCoordinates(MotionEvent ev) { + int y = (int) ev.getRawY(); + if (swipeable && bgVisible && ev.getActionMasked() == MotionEvent.ACTION_DOWN + && y < heightOutsideRView) closeVisibleBG(null); + } + + private boolean shouldIgnoreAction(int touchedPosition) { + return rView == null || ignoredViewTypes.contains(rView.getAdapter().getItemViewType(touchedPosition)); + } + + private enum Animation { + OPEN, CLOSE + } + + /////////////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////// Interfaces ///////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////// + + public interface OnRowClickListener { + void onRowClicked(int position); + + void onIndependentViewClicked(int independentViewID, int position); + } + + public interface OnRowLongClickListener { + void onRowLongClicked(int position); + } + + public interface OnSwipeOptionsClickListener { + void onSwipeOptionClicked(int viewID, int position); + } + + public interface RecyclerTouchListenerHelper { + void setOnActivityTouchListener(OnActivityTouchListener listener); + } + + public interface OnSwipeListener { + void onSwipeOptionsClosed(); + + void onSwipeOptionsOpened(); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/vh/DraggableTextViewHolder.java b/app/src/main/java/com/bingce/controlnetwork/ui/vh/DraggableTextViewHolder.java new file mode 100644 index 0000000..81db07d --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/vh/DraggableTextViewHolder.java @@ -0,0 +1,32 @@ +package com.bingce.controlnetwork.ui.vh; + +import android.view.View; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.model.StationDetailItem; + +import com.bingce.controlnetwork.R; + +public class DraggableTextViewHolder extends RecyclerView.ViewHolder { + public final TextView title; + public final ImageView dragBar; + + public DraggableTextViewHolder(@NonNull View itemView) { + super(itemView); + title = itemView.findViewById(R.id.title); + dragBar = itemView.findViewById(R.id.drag_bar); + } + + public static void update(DraggableTextViewHolder draggableTextViewHolder, StationDetailItem item, boolean editable) { + draggableTextViewHolder.title.setText(item.getName()); + if (StationDetailItem.ITEM_TYPE_STATION_ITEM.equals(item.getType()) || !editable) { + draggableTextViewHolder.dragBar.setVisibility(View.GONE); + } else { + draggableTextViewHolder.dragBar.setVisibility(View.VISIBLE); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/vh/DraggableViewHolder.java b/app/src/main/java/com/bingce/controlnetwork/ui/vh/DraggableViewHolder.java new file mode 100644 index 0000000..d8b69f7 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/vh/DraggableViewHolder.java @@ -0,0 +1,14 @@ +package com.bingce.controlnetwork.ui.vh; + +import android.view.View; + +import androidx.annotation.NonNull; + +import org.jetbrains.annotations.NotNull; + +public class DraggableViewHolder extends IndexTextViewHolder { + + public DraggableViewHolder(@NonNull @NotNull View itemView) { + super(itemView); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/vh/GroupParentViewHolder.java b/app/src/main/java/com/bingce/controlnetwork/ui/vh/GroupParentViewHolder.java new file mode 100644 index 0000000..3daafea --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/vh/GroupParentViewHolder.java @@ -0,0 +1,21 @@ +package com.bingce.controlnetwork.ui.vh; + +import android.view.View; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlnetwork.R; + +public class GroupParentViewHolder extends RecyclerView.ViewHolder { + public final TextView name; + public final ImageView expandIcon; + + public GroupParentViewHolder(@NonNull View itemView) { + super(itemView); + expandIcon = itemView.findViewById(R.id.expand_icon); + name = itemView.findViewById(R.id.groupName); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/vh/IndexTextSelectableViewHolder.java b/app/src/main/java/com/bingce/controlnetwork/ui/vh/IndexTextSelectableViewHolder.java new file mode 100644 index 0000000..ed8705b --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/vh/IndexTextSelectableViewHolder.java @@ -0,0 +1,21 @@ +package com.bingce.controlnetwork.ui.vh; + +import android.view.View; +import android.widget.ImageView; + +import androidx.annotation.NonNull; + +import com.bingce.controlnetwork.R; + +public class IndexTextSelectableViewHolder extends IndexTextViewHolder { + public final ImageView status; + public final View mask; + public final View item; + + public IndexTextSelectableViewHolder(@NonNull View itemView) { + super(itemView); + status = itemView.findViewById(R.id.status); + mask = itemView.findViewById(R.id.mask); + item = itemView.findViewById(R.id.item); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/vh/IndexTextViewHolder.java b/app/src/main/java/com/bingce/controlnetwork/ui/vh/IndexTextViewHolder.java new file mode 100644 index 0000000..1231cb8 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/vh/IndexTextViewHolder.java @@ -0,0 +1,20 @@ +package com.bingce.controlnetwork.ui.vh; + +import android.view.View; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlnetwork.R; + +public class IndexTextViewHolder extends RecyclerView.ViewHolder { + public final TextView index; + public final TextView name; + + public IndexTextViewHolder(@NonNull View itemView) { + super(itemView); + index = itemView.findViewById(R.id.index); + name = itemView.findViewById(R.id.text); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/vh/IndexTextWithPrefixViewHolder.java b/app/src/main/java/com/bingce/controlnetwork/ui/vh/IndexTextWithPrefixViewHolder.java new file mode 100644 index 0000000..a979be9 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/vh/IndexTextWithPrefixViewHolder.java @@ -0,0 +1,17 @@ +package com.bingce.controlnetwork.ui.vh; + +import android.view.View; +import android.widget.TextView; + +import androidx.annotation.NonNull; + +import com.bingce.controlnetwork.R; + +public class IndexTextWithPrefixViewHolder extends IndexTextViewHolder { + public final TextView prefix; + + public IndexTextWithPrefixViewHolder(@NonNull View itemView) { + super(itemView); + prefix = itemView.findViewById(R.id.prefix); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/vh/ItemWellViewHolder.java b/app/src/main/java/com/bingce/controlnetwork/ui/vh/ItemWellViewHolder.java new file mode 100644 index 0000000..b35ec36 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/vh/ItemWellViewHolder.java @@ -0,0 +1,40 @@ +package com.bingce.controlnetwork.ui.vh; + +import android.view.View; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.model.StationDetailItem; + +import com.bingce.controlnetwork.R; + +public class ItemWellViewHolder extends RecyclerView.ViewHolder { + public final TextView title; + public final ImageView dragBar; + + public ItemWellViewHolder(@NonNull View itemView) { + super(itemView); + title = itemView.findViewById(R.id.title); + dragBar = itemView.findViewById(R.id.drag_bar); + } + + public static void update(ItemWellViewHolder holder, StationDetailItem item, boolean editable, IUIBuilderDelegate iuiBuilderDelegate) { + holder.title.setText(item.getName()); + if (StationDetailItem.ITEM_TYPE_STATION_ITEM.equals(item.getType()) || !editable) { + holder.dragBar.setVisibility(View.GONE); + } else { + holder.dragBar.setVisibility(View.VISIBLE); + } + + if (iuiBuilderDelegate != null) { + iuiBuilderDelegate.build(item.getType(), holder); + } + } + + public interface IUIBuilderDelegate { + void build(String itemType, ItemWellViewHolder holder); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/vh/KeyBoolViewHolder.java b/app/src/main/java/com/bingce/controlnetwork/ui/vh/KeyBoolViewHolder.java new file mode 100644 index 0000000..078fd4c --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/vh/KeyBoolViewHolder.java @@ -0,0 +1,21 @@ +package com.bingce.controlnetwork.ui.vh; + +import android.view.View; +import android.widget.CheckBox; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlnetwork.R; + +public class KeyBoolViewHolder extends RecyclerView.ViewHolder { + public final TextView key; + public final CheckBox checkBox; + + public KeyBoolViewHolder(@NonNull View itemView) { + super(itemView); + key = itemView.findViewById(R.id.name); + checkBox = itemView.findViewById(R.id.checkBox); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/vh/KeyValueViewHolder.java b/app/src/main/java/com/bingce/controlnetwork/ui/vh/KeyValueViewHolder.java new file mode 100644 index 0000000..e31e537 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/vh/KeyValueViewHolder.java @@ -0,0 +1,20 @@ +package com.bingce.controlnetwork.ui.vh; + +import android.view.View; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlnetwork.R; + +public class KeyValueViewHolder extends RecyclerView.ViewHolder { + public final TextView key; + public final TextView value; + + public KeyValueViewHolder(@NonNull View itemView) { + super(itemView); + key = itemView.findViewById(R.id.name); + value = itemView.findViewById(R.id.value); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/vh/PrismManageViewHolder.java b/app/src/main/java/com/bingce/controlnetwork/ui/vh/PrismManageViewHolder.java new file mode 100644 index 0000000..255fe93 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/vh/PrismManageViewHolder.java @@ -0,0 +1,22 @@ +package com.bingce.controlnetwork.ui.vh; + +import android.view.View; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlnetwork.R; + +public class PrismManageViewHolder extends RecyclerView.ViewHolder { + public final TextView tvName; + public final TextView tvType; + public final TextView tvConstant; + + public PrismManageViewHolder(@NonNull View itemView) { + super(itemView); + tvName = itemView.findViewById(R.id.tvName); + tvType = itemView.findViewById(R.id.tvType); + tvConstant = itemView.findViewById(R.id.tvConstant); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/vh/StationAdjustItemViewHolder.java b/app/src/main/java/com/bingce/controlnetwork/ui/vh/StationAdjustItemViewHolder.java new file mode 100644 index 0000000..1b25b39 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/vh/StationAdjustItemViewHolder.java @@ -0,0 +1,24 @@ +package com.bingce.controlnetwork.ui.vh; + +import android.view.View; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlnetwork.R; + +public class StationAdjustItemViewHolder extends RecyclerView.ViewHolder { + public final TextView pointName; + public final TextView horAngle; + public final TextView verAngle; + public final TextView distance; + + public StationAdjustItemViewHolder(@NonNull View itemView) { + super(itemView); + pointName = itemView.findViewById(R.id.point_name); + horAngle = itemView.findViewById(R.id.hor_angle); + verAngle = itemView.findViewById(R.id.ver_angle); + distance = itemView.findViewById(R.id.distance); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/vh/StationGroupItemViewHolder.java b/app/src/main/java/com/bingce/controlnetwork/ui/vh/StationGroupItemViewHolder.java new file mode 100644 index 0000000..f504ac0 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/vh/StationGroupItemViewHolder.java @@ -0,0 +1,46 @@ +package com.bingce.controlnetwork.ui.vh; + +import android.view.View; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.model.StationDetailItem; + +import org.jetbrains.annotations.NotNull; + +import com.bingce.controlnetwork.R; + +public class StationGroupItemViewHolder extends RecyclerView.ViewHolder { + public final TextView title; + public final View pick; + public final View switchView; + + public StationGroupItemViewHolder(@NonNull @NotNull View itemView) { + super(itemView); + title = itemView.findViewById(R.id.groupName); + pick = itemView.findViewById(R.id.pick_station_point); + switchView = itemView.findViewById(R.id.switch_station_point); + } + + public static void update(StationGroupItemViewHolder surveyorStationSetupGroupParentViewHolder, + StationDetailItem item, + boolean adjustable, + IUIBuilderDelegate builderDelegate) { + surveyorStationSetupGroupParentViewHolder.title.setText(item.getName()); + //判断是否需要un enable添加按钮 + if (!adjustable) { + surveyorStationSetupGroupParentViewHolder.pick.setVisibility(View.GONE); + surveyorStationSetupGroupParentViewHolder.switchView.setVisibility(View.GONE); + } else { + if (builderDelegate != null) { + builderDelegate.build(item.getType(), surveyorStationSetupGroupParentViewHolder); + } + } + } + + public interface IUIBuilderDelegate { + void build(String itemType, StationGroupItemViewHolder surveyorStationSetupGroupParentViewHolder); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/vh/SurveyorDataAloneDistanceViewHolder.java b/app/src/main/java/com/bingce/controlnetwork/ui/vh/SurveyorDataAloneDistanceViewHolder.java new file mode 100644 index 0000000..2b3524a --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/vh/SurveyorDataAloneDistanceViewHolder.java @@ -0,0 +1,243 @@ +package com.bingce.controlnetwork.ui.vh; + +import android.content.Context; +import android.view.View; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.datasource.database.alonedistance.AloneDistanceRecord; +import com.bingce.controlapphelper.model.LeftOrRight; +import com.bingce.controlapphelper.surveyor.data.CachedDataAloneDistance; +import com.bingce.controlapphelper.surveyor.data.ICycleRecorder; +import com.bingce.controlapphelper.surveyor.data.ISurveyorData; +import com.bingce.controlapphelper.util.IdUtil; +import com.bingce.controlapphelper.util.SettingValueUtil; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.utils.Util; + +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +public class SurveyorDataAloneDistanceViewHolder extends RecyclerView.ViewHolder { + private final Context context; + private final TextView leftLabel;//平距或斜距 + + private final TextView pointName; + private final TextView heightValue; + private final TextView prismValue; + + private final List distanceViews; + private final TextView tvFirstRound1, tvFirstRound2, tvFirstRound3, tvFirstRound4; + private final TextView tvSecondRound1, tvSecondRound2, tvSecondRound3, tvSecondRound4; + + private final TextView tvFirstRoundAverageDistance, tvSecondRoundAverageDistance;//第一,第二测回中值 + private final TextView tvFirstRound2D, tvSecondRound2D;//第一,第二测回2D + + private final View selectMask;//黄框 + + private final int ROUND_NUM = 2; + private final int EVERY_ROUND_NUM = 4; + + private final List realDistanceValues = new ArrayList<>(); + + public SurveyorDataAloneDistanceViewHolder(Context context, @NonNull @NotNull View itemView) { + super(itemView); + this.context = context; + + pointName = itemView.findViewById(R.id.pointName); + heightValue = itemView.findViewById(R.id.height_value); + prismValue = itemView.findViewById(R.id.prism_value); + + leftLabel = itemView.findViewById(R.id.left_label); + + tvFirstRound1 = itemView.findViewById(R.id.tvFirstRound1); + tvFirstRound2 = itemView.findViewById(R.id.tvFirstRound2); + tvFirstRound3 = itemView.findViewById(R.id.tvFirstRound3); + tvFirstRound4 = itemView.findViewById(R.id.tvFirstRound4); + tvSecondRound1 = itemView.findViewById(R.id.tvSecondRound1); + tvSecondRound2 = itemView.findViewById(R.id.tvSecondRound2); + tvSecondRound3 = itemView.findViewById(R.id.tvSecondRound3); + tvSecondRound4 = itemView.findViewById(R.id.tvSecondRound4); + + distanceViews = new ArrayList<>(); + distanceViews.add(tvFirstRound1); + distanceViews.add(tvFirstRound2); + distanceViews.add(tvFirstRound3); + distanceViews.add(tvFirstRound4); + distanceViews.add(tvSecondRound1); + distanceViews.add(tvSecondRound2); + distanceViews.add(tvSecondRound3); + distanceViews.add(tvSecondRound4); + + + tvFirstRoundAverageDistance = itemView.findViewById(R.id.tvFirstRoundAverageDistance); + tvSecondRoundAverageDistance = itemView.findViewById(R.id.tvSecondRoundAverageDistance); + tvFirstRound2D = itemView.findViewById(R.id.tvFirstRound2D); + tvSecondRound2D = itemView.findViewById(R.id.tvSecondRound2D); + + selectMask = itemView.findViewById(R.id.mask); + } + + public void setup(int itemIndex, + String stationId, + boolean showSlopDistance, + CachedDataAloneDistance cachedData, + ICycleRecorder cycleRecorder, + ISurveyorData surveyorData) { + if (showSlopDistance) { + leftLabel.setText(R.string.distance_slope); + } else { + leftLabel.setText(R.string.distance_horizontal); + } + int currentCycleIndex = cycleRecorder.currentCycleIndex(); + int currentSurveyorIndex = surveyorData.currentIndex(); + //设置当前测量状态标识 + if (currentSurveyorIndex == itemIndex) { + selectMask.setVisibility(View.VISIBLE); + } else { + selectMask.setVisibility(View.GONE); + } + + //初始化 + initDefault(); + + //设置值 + pointName.setText(cachedData.pointName(currentCycleIndex, itemIndex)); + heightValue.setText(cachedData.getPrismHeight(currentCycleIndex, itemIndex)); + prismValue.setText(cachedData.getPrismTypeName(currentCycleIndex, itemIndex)); + + //先清空下realDistanceValues保证数据不错乱,注意位置在前面 + clearRealDistanceValues(); + List distanceDatas = getDistanceDataFromCacheData(cachedData, stationId, currentCycleIndex, itemIndex); + setDistanceViewData(distanceDatas, currentSurveyorIndex == itemIndex); + + //设置中值和2d + if (!realDistanceValues.isEmpty()) { + int distanceSize = realDistanceValues.size(); + int hanNum = distanceSize / EVERY_ROUND_NUM; + if (hanNum >= 1) { + //有可以显示的中值 + if (hanNum == ROUND_NUM) { + //当满足两测回都可以显示中值和2d的时候 + setFirstRound2DAndAverageDistance(); + setSecondRound2DAndAverageDistance(); + } else { + //当满足第一测回可以显示中值和2d的时候 + setFirstRound2DAndAverageDistance(); + } + } + } + + } + + /** + * 从缓存数据中读取距离数据 + * + * @param cachedData + * @param stationId + * @param currentCycleIndex + * @param itemIndex + * @return + */ + private List getDistanceDataFromCacheData(CachedDataAloneDistance cachedData, String stationId, int currentCycleIndex, int itemIndex) { + List distanceValues = null; + String pointId = cachedData.pointId(currentCycleIndex, itemIndex); + String recordId = IdUtil.createSurveyorRecordId(stationId, currentCycleIndex, pointId, LeftOrRight.left); + AloneDistanceRecord aloneDistanceRecord = cachedData.getAloneDistanceRecord(recordId); + if (aloneDistanceRecord != null) { + distanceValues = aloneDistanceRecord.distanceValues; + } + return distanceValues; + } + + private void setFirstRound2DAndAverageDistance() { + List doubles1 = realDistanceValues.subList(0, EVERY_ROUND_NUM); + Double averageFirstRound = Tools.calculateCollectionDoubleAverage(doubles1); + Double maxSubMinFirstRound = Tools.calculateCollectionMaxSubMin(doubles1); + setAverageDistanceText(tvFirstRoundAverageDistance, averageFirstRound); + set2DText(tvFirstRound2D, maxSubMinFirstRound); + } + + private void setSecondRound2DAndAverageDistance() { + List doubles2 = realDistanceValues.subList(EVERY_ROUND_NUM, realDistanceValues.size()); + Double averageSecondRound = Tools.calculateCollectionDoubleAverage(doubles2); + Double maxSubMinSecondRound = Tools.calculateCollectionMaxSubMin(doubles2); + setAverageDistanceText(tvSecondRoundAverageDistance, averageSecondRound); + set2DText(tvSecondRound2D, maxSubMinSecondRound); + } + + + private void setTextColor(TextView tv, int value) { + tv.setTextColor(context.getResources().getColor(value)); + } + + private void setDistance(TextView tv, double distance) { + String distanceS; + if (distance == 0) { + distanceS = ORIGINAL_VALUE; + } else { + distanceS = Util.formatDouble2String(distance, SettingValueUtil.getLengthDecimalPoint()); + } + tv.setText(distanceS); + } + + private void set2DText(TextView tv, double value) { + tv.setText(String.format("%smm", Util.formatDouble2String(value * 1000, 1))); + } + + private void setAverageDistanceText(TextView tv, double value) { + tv.setText(Util.formatDouble2String(value, SettingValueUtil.getLengthDecimalPoint())); + } + + /** + * 初始化 + */ + private void initDefault() { + leftLabel.setTextColor(context.getResources().getColor(R.color.value_1_normal)); + + initDefaultDistanceViewsData(); + + tvFirstRoundAverageDistance.setText(ORIGINAL_VALUE); + tvSecondRoundAverageDistance.setText(ORIGINAL_VALUE); + + tvFirstRound2D.setText(ORIGINAL_VALUE); + tvSecondRound2D.setText(ORIGINAL_VALUE); + } + + private void initDefaultDistanceViewsData() { + for (TextView textView : distanceViews) { + setDistance(textView, 0); + setTextColor(textView, R.color.value_1_normal); + } + } + + /** + * 设置view的数据 + * + * @param aloneDistanceValues + * @param isSelected + */ + private void setDistanceViewData(List aloneDistanceValues, boolean isSelected) { + if (aloneDistanceValues == null) return; + for (int i = 0; i < aloneDistanceValues.size(); i++) { + Double aDouble = aloneDistanceValues.get(i); + TextView textView = distanceViews.get(i); + setDistance(textView, aDouble); + setTextColor(textView, isSelected ? R.color.value_1_selected : R.color.value_1_normal); + //存一下 + realDistanceValues.add(aDouble); + } + } + + private void clearRealDistanceValues() { + realDistanceValues.clear(); + } + + + private static final String ORIGINAL_VALUE = "-"; +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/vh/SurveyorDataViewHolder.java b/app/src/main/java/com/bingce/controlnetwork/ui/vh/SurveyorDataViewHolder.java new file mode 100644 index 0000000..744c8f8 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/vh/SurveyorDataViewHolder.java @@ -0,0 +1,408 @@ +package com.bingce.controlnetwork.ui.vh; + +import android.content.Context; +import android.view.View; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.model.DataCategory; +import com.bingce.controlapphelper.model.LeftOrRight; +import com.bingce.controlapphelper.surveyor.data.ICachedData; +import com.bingce.controlapphelper.surveyor.data.ICycleRecorder; +import com.bingce.controlapphelper.surveyor.data.ISurveyorData; +import com.bingce.controlapphelper.surveyor.method.AverageValueMethod; +import com.bingce.controlapphelper.surveyor.method.RadianMethod; +import com.bingce.controlapphelper.surveyor.method.ValueOf2cMethod; +import com.bingce.controlapphelper.surveyor.method.model.CacheResult; +import com.bingce.controlapphelper.surveyor.method.model.SdAngleValueType; +import com.bingce.controlapphelper.util.IdUtil; +import com.bingce.controlapphelper.util.SettingValueUtil; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.utils.Util; + +import org.jetbrains.annotations.NotNull; + +public class SurveyorDataViewHolder extends RecyclerView.ViewHolder { + private final Context context; + private final TextView leftLabel; + private final TextView rightLabel; + + public final TextView pointName; + public final TextView heightValue; + public final TextView prismValue; + + public final TextView leftAngleHor1; + public final TextView leftAngleHor2; + public final TextView leftAngleVer1; + public final TextView leftAngleVer2; + public final TextView leftDistance1; + public final TextView leftDistance2; + + public final TextView rightAngleHor1; + public final TextView rightAngleHor2; + public final TextView rightAngleVer1; + public final TextView rightAngleVer2; + public final TextView rightDistance1; + public final TextView rightDistance2; + + public final TextView averageHorAngle; + public final TextView averageVerAngle; + public final TextView averageDistance; + + public final View selectMask; + + public final TextView _2c; + public final TextView _i; + public final TextView _2d; + + public final TextView distanceTitle; + private final View itemView; + + public SurveyorDataViewHolder(Context context, @NonNull @NotNull View itemView) { + super(itemView); + this.context = context; + leftLabel = itemView.findViewById(R.id.left_label); + rightLabel = itemView.findViewById(R.id.right_label); + + pointName = itemView.findViewById(R.id.pointName); + heightValue = itemView.findViewById(R.id.height_value); + prismValue = itemView.findViewById(R.id.prism_value); + + leftAngleHor1 = itemView.findViewById(R.id.left_angle_hor_1); + leftAngleHor2 = itemView.findViewById(R.id.left_angle_hor_2); + leftAngleVer1 = itemView.findViewById(R.id.left_angle_ver_1); + leftAngleVer2 = itemView.findViewById(R.id.left_angle_ver_2); + leftDistance1 = itemView.findViewById(R.id.left_distance_1); + leftDistance2 = itemView.findViewById(R.id.left_distance_2); + + rightAngleHor1 = itemView.findViewById(R.id.right_angle_hor_1); + rightAngleHor2 = itemView.findViewById(R.id.right_angle_hor_2); + rightAngleVer1 = itemView.findViewById(R.id.right_angle_ver_1); + rightAngleVer2 = itemView.findViewById(R.id.right_angle_ver_2); + rightDistance1 = itemView.findViewById(R.id.right_distance_1); + rightDistance2 = itemView.findViewById(R.id.right_distance_2); + + averageHorAngle = itemView.findViewById(R.id.average_angle_hor); + averageVerAngle = itemView.findViewById(R.id.average_angle_ver); + averageDistance = itemView.findViewById(R.id.average_distance); + + selectMask = itemView.findViewById(R.id.mask); + + _2c = itemView.findViewById(R.id.value_2c); + _i = itemView.findViewById(R.id.value_i); + _2d = itemView.findViewById(R.id.value_2d); + + distanceTitle = itemView.findViewById(R.id.distance_title); + this.itemView = itemView; + } + + public void setup(int itemIndex, + String stationId, + boolean showSlopDistance, + ICachedData cachedData, + ICycleRecorder cycleRecorder, + ISurveyorData surveyorData) { + if (showSlopDistance) { + distanceTitle.setText(R.string.distance_slope); + } else { + distanceTitle.setText(R.string.distance_horizontal); + } + int currentCycleIndex = cycleRecorder.currentCycleIndex(); + int currentSurveyorIndex = surveyorData.currentIndex(); + //设置当前测量状态标识 + if (currentSurveyorIndex == itemIndex) { + //当前非跳过点背景黄边白色 + selectMask.setBackground(Tools.getDrawable(R.drawable.select_mask)); + } else { + if (cachedData.isPointAbandon(currentCycleIndex, itemIndex)) { + selectMask.setBackground(Tools.getDrawable(R.drawable.bg_gray_3)); + } else { + selectMask.setBackgroundColor(Tools.getColor(R.color.white)); + } + } + + //初始化 + setValue(TYPE_LEFT1, ORIGINAL_VALUE, ORIGINAL_VALUE, ORIGINAL_VALUE); + setValue(TYPE_LEFT2, ORIGINAL_VALUE, ORIGINAL_VALUE, ORIGINAL_VALUE); + setValue(TYPE_RIGHT1, ORIGINAL_VALUE, ORIGINAL_VALUE, ORIGINAL_VALUE); + setValue(TYPE_RIGHT2, ORIGINAL_VALUE, ORIGINAL_VALUE, ORIGINAL_VALUE); + leftLabel.setTextColor(context.getResources().getColor(R.color.value_1_normal)); + setTextColor(TYPE_LEFT1, R.color.value_1_normal); + setTextColor(TYPE_LEFT2, R.color.value_2_normal); + rightLabel.setTextColor(context.getResources().getColor(R.color.value_1_normal)); + setTextColor(TYPE_RIGHT1, R.color.value_1_normal); + setTextColor(TYPE_RIGHT2, R.color.value_2_normal); + + averageHorAngle.setText(ORIGINAL_VALUE); + averageVerAngle.setText(ORIGINAL_VALUE); + averageDistance.setText(ORIGINAL_VALUE); + + _2c.setText(ORIGINAL_VALUE); + _i.setText(ORIGINAL_VALUE); + _2d.setText(ORIGINAL_VALUE); + + boolean aloneDistance = cachedData.isAloneDistance(currentCycleIndex, itemIndex); + + //如果当前正在测量,使用缓存数据设置相应信息 + LeftOrRight surveyorState = surveyorData.leftOrRight(); + if (currentSurveyorIndex == itemIndex) { + if (surveyorState == LeftOrRight.left) { + if (surveyorData.hasSurveyor1()) { + setValue(aloneDistance, TYPE_LEFT1, surveyorData.getAngleHor1(), surveyorData.getAngleVer1(), surveyorData.getDistance1()); + } + if (surveyorData.hasSurveyor2()) { + setValue(aloneDistance, TYPE_LEFT2, surveyorData.getAngleHor2(), surveyorData.getAngleVer2(), surveyorData.getDistance2()); + } + //设置颜色 + setTextColor(TYPE_LEFT1, R.color.value_1_selected); + setTextColor(TYPE_LEFT2, R.color.value_2_selected); + leftLabel.setTextColor(context.getResources().getColor(R.color.value_1_selected)); + } else if (surveyorState == LeftOrRight.right) { + if (surveyorData.hasSurveyor1()) { + setValue(aloneDistance, TYPE_RIGHT1, surveyorData.getAngleHor1(), surveyorData.getAngleVer1(), surveyorData.getDistance1()); + } + if (surveyorData.hasSurveyor2()) { + setValue(aloneDistance, TYPE_RIGHT2, surveyorData.getAngleHor2(), surveyorData.getAngleVer2(), surveyorData.getDistance2()); + } + //设置颜色 + setTextColor(TYPE_RIGHT1, R.color.value_1_selected); + setTextColor(TYPE_RIGHT2, R.color.value_2_selected); + rightLabel.setTextColor(context.getResources().getColor(R.color.value_1_selected)); + } + } + + //根据测量次数,控制数据显示 + setValue2Visibility(surveyorData.surveyorCount() > 1); + + pointName.setText(cachedData.pointName(currentCycleIndex, itemIndex)); + heightValue.setText(cachedData.getPrismHeight(currentCycleIndex, itemIndex)); + prismValue.setText(cachedData.getPrismTypeName(currentCycleIndex, itemIndex)); + + //重新监听observe---但是根据当前测量状态,需要排除一些数据监听 + boolean skipLeft1 = false, skipLeft2 = false, skipRight1 = false, skipRight2 = false; + //根据内存缓存排除 + if (currentSurveyorIndex == itemIndex) { + if (surveyorState == LeftOrRight.left) { + if (surveyorData.hasSurveyor1()) { + skipLeft1 = true; + } + if (surveyorData.hasSurveyor2() || surveyorData.surveyorCount() == 1) { + skipLeft2 = true; + } + } else if (surveyorState == LeftOrRight.right) { + if (surveyorData.hasSurveyor1()) { + skipRight1 = true; + } + if (surveyorData.hasSurveyor2() || surveyorData.surveyorCount() == 1) { + skipRight2 = true; + } + } + } + + String pointId = cachedData.pointId(currentCycleIndex, itemIndex); + String leftRecordId = IdUtil.createSurveyorRecordId(stationId, currentCycleIndex, pointId, LeftOrRight.left); + if (!skipLeft1) { + DataCategory dataCategory = cachedData.valueState(leftRecordId, 0); + if (!dataCategory.isEmptyData()) { + setValue(aloneDistance, TYPE_LEFT1, + cachedData.angleHor1(leftRecordId), + cachedData.angleVer1(leftRecordId), + cachedData.distance1(leftRecordId)); + } + if (dataCategory.isNeedResurvey()) { + setTextColor(TYPE_LEFT1, R.color.value_dirty); + } else if (dataCategory == DataCategory.dirtyAndSurveyed) { + setTextColor(TYPE_LEFT1, R.color.value_resurveyed); + } + } + if (!skipLeft2) { + DataCategory dataCategory = cachedData.valueState(leftRecordId, 1); + if (!dataCategory.isEmptyData()) { + setValue(aloneDistance, TYPE_LEFT2, + cachedData.angleHor2(leftRecordId), + cachedData.angleVer2(leftRecordId), + cachedData.distance2(leftRecordId)); + } + if (dataCategory.isNeedResurvey()) { + setTextColor(TYPE_LEFT2, R.color.value_dirty); + } else if (dataCategory == DataCategory.dirtyAndSurveyed) { + setTextColor(TYPE_LEFT2, R.color.value_resurveyed); + } + } + String rightRecordId = IdUtil.createSurveyorRecordId(stationId, currentCycleIndex, pointId, LeftOrRight.right); + if (!skipRight1) { + DataCategory dataCategory = cachedData.valueState(rightRecordId, 0); + if (!dataCategory.isEmptyData()) { + setValue(aloneDistance, TYPE_RIGHT1, + cachedData.angleHor1(rightRecordId), + cachedData.angleVer1(rightRecordId), + cachedData.distance1(rightRecordId)); + } + if (dataCategory.isNeedResurvey()) { + setTextColor(TYPE_RIGHT1, R.color.value_dirty); + } else if (dataCategory == DataCategory.dirtyAndSurveyed) { + setTextColor(TYPE_RIGHT1, R.color.value_resurveyed); + } + } + if (!skipRight2) { + DataCategory dataCategory = cachedData.valueState(rightRecordId, 1); + if (!dataCategory.isEmptyData()) { + setValue(aloneDistance, TYPE_RIGHT2, + cachedData.angleHor2(rightRecordId), + cachedData.angleVer2(rightRecordId), + cachedData.distance2(rightRecordId)); + } + if (dataCategory.isNeedResurvey()) { + setTextColor(TYPE_RIGHT2, R.color.value_dirty); + } else if (dataCategory == DataCategory.dirtyAndSurveyed) { + setTextColor(TYPE_RIGHT2, R.color.value_resurveyed); + } + } + + + //均值(中值) + int surveyorCount = surveyorData.surveyorCount(); + CacheResult horAngleLeftAndRightAverageValue = AverageValueMethod.leftAndRightValue(SdAngleValueType.horAngle, + leftRecordId, + rightRecordId, surveyorCount, cachedData); + + if (horAngleLeftAndRightAverageValue.validate) { + double radian = RadianMethod.formatRadian(horAngleLeftAndRightAverageValue.value); + averageHorAngle.setText(RadianMethod.dmsStringOf(radian)); + } else { + averageHorAngle.setText(ORIGINAL_VALUE); + } + + + CacheResult verAngleLeftAndRightAverageValue = AverageValueMethod.leftAndRightValue(SdAngleValueType.verAngle, + leftRecordId, + rightRecordId, surveyorCount, cachedData); + if (verAngleLeftAndRightAverageValue.validate) {//显示天顶距 + averageVerAngle.setText(RadianMethod.dmsStringOf(Math.PI / 2 - verAngleLeftAndRightAverageValue.value)); + } else { + averageVerAngle.setText(ORIGINAL_VALUE); + } + + CacheResult distanceLeftAndRightAverageValue = AverageValueMethod.leftAndRightValue(SdAngleValueType.distance, + leftRecordId, + rightRecordId, surveyorCount, cachedData); + if (aloneDistance) { + averageDistance.setText(ORIGINAL_VALUE); + } else { + if (distanceLeftAndRightAverageValue.validate) { + averageDistance.setText(Util.formatDouble2String(distanceLeftAndRightAverageValue.value, + SettingValueUtil.getLengthDecimalPoint())); + } else { + averageDistance.setText(ORIGINAL_VALUE); + } + } + + //设置2c、i、2d + CacheResult value2C = ValueOf2cMethod.valueOf2C(SdAngleValueType.horAngle, + itemIndex, stationId, surveyorData, currentCycleIndex, cachedData); + if (value2C.validate && horAngleLeftAndRightAverageValue.validate) { + _2c.setText(String.format("%s″", Util.formatDouble2String(value2C.value, 1))); + } else { + _2c.setText(ORIGINAL_VALUE); + } + CacheResult valueI = ValueOf2cMethod.valueOf2C(SdAngleValueType.verAngle, + itemIndex, stationId, surveyorData, currentCycleIndex, cachedData); + if (valueI.validate && verAngleLeftAndRightAverageValue.validate) { + _i.setText(String.format("%s″", Util.formatDouble2String(valueI.value, 1))); + } else { + _i.setText(ORIGINAL_VALUE); + } + + CacheResult value2D = ValueOf2cMethod.valueOf2C(SdAngleValueType.distance, + itemIndex, stationId, surveyorData, currentCycleIndex, cachedData); + if (aloneDistance) { + _2d.setText(ORIGINAL_VALUE); + } else { + if (value2D.validate && distanceLeftAndRightAverageValue.validate) { + _2d.setText(String.format("%smm", Util.formatDouble2String(value2D.value, 1))); + } else { + _2d.setText(ORIGINAL_VALUE); + } + } + + } + + private void setTextColor(int type, int value) { + angleHor(type).setTextColor(context.getResources().getColor(value)); + angleVer(type).setTextColor(context.getResources().getColor(value)); + distance(type).setTextColor(context.getResources().getColor(value)); + } + + private void setValue(boolean aloneDistance, int type, double angleHor, double angleVer, double distance) { + //判断是否测水平角 + String angleVerS = RadianMethod.dmsStringOf(angleVer); + String distanceS = ORIGINAL_VALUE; + if (!aloneDistance) { + distanceS = Util.formatDouble2String(distance, + SettingValueUtil.getLengthDecimalPoint()); + } + setValue(type, + RadianMethod.dmsStringOf(angleHor), + angleVerS, + distanceS); + } + + private void setValue(int type, String angleHor, String angleVer, String distance) { + angleHor(type).setText(angleHor); + angleVer(type).setText(angleVer); + distance(type).setText(distance); + } + + private void setValue2Visibility(boolean visibility) { + leftAngleHor2.setVisibility(visibility ? View.VISIBLE : View.GONE); + leftAngleVer2.setVisibility(visibility ? View.VISIBLE : View.GONE); + leftDistance2.setVisibility(visibility ? View.VISIBLE : View.GONE); + rightAngleHor2.setVisibility(visibility ? View.VISIBLE : View.GONE); + rightAngleVer2.setVisibility(visibility ? View.VISIBLE : View.GONE); + rightDistance2.setVisibility(visibility ? View.VISIBLE : View.GONE); + } + + private TextView angleHor(int type) { + if (TYPE_LEFT1 == type) { + return leftAngleHor1; + } else if (TYPE_LEFT2 == type) { + return leftAngleHor2; + } else if (TYPE_RIGHT1 == type) { + return rightAngleHor1; + } + return rightAngleHor2; + } + + private TextView angleVer(int type) { + if (TYPE_LEFT1 == type) { + return leftAngleVer1; + } else if (TYPE_LEFT2 == type) { + return leftAngleVer2; + } else if (TYPE_RIGHT1 == type) { + return rightAngleVer1; + } + return rightAngleVer2; + } + + + private TextView distance(int type) { + if (TYPE_LEFT1 == type) { + return leftDistance1; + } else if (TYPE_LEFT2 == type) { + return leftDistance2; + } else if (TYPE_RIGHT1 == type) { + return rightDistance1; + } + return rightDistance2; + } + + private static final int TYPE_LEFT1 = 1; + private static final int TYPE_LEFT2 = 2; + private static final int TYPE_RIGHT1 = 3; + private static final int TYPE_RIGHT2 = 4; + private static final String ORIGINAL_VALUE = "-"; + private static final String SKIP_VALUE = "*"; +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/vh/SurveyorDataViewHolderHeightTraverse.java b/app/src/main/java/com/bingce/controlnetwork/ui/vh/SurveyorDataViewHolderHeightTraverse.java new file mode 100644 index 0000000..6a989bf --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/vh/SurveyorDataViewHolderHeightTraverse.java @@ -0,0 +1,366 @@ +package com.bingce.controlnetwork.ui.vh; + +import android.content.Context; +import android.view.View; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.model.DataCategory; +import com.bingce.controlapphelper.model.LeftOrRight; +import com.bingce.controlapphelper.surveyor.data.ICachedData; +import com.bingce.controlapphelper.surveyor.data.ICycleRecorder; +import com.bingce.controlapphelper.surveyor.data.ISurveyorData; +import com.bingce.controlapphelper.surveyor.method.AverageValueMethod; +import com.bingce.controlapphelper.surveyor.method.RadianMethod; +import com.bingce.controlapphelper.surveyor.method.ValueOf2cMethod; +import com.bingce.controlapphelper.surveyor.method.model.CacheResult; +import com.bingce.controlapphelper.surveyor.method.model.SdAngleValueType; +import com.bingce.controlapphelper.util.IdUtil; +import com.bingce.controlapphelper.util.SettingValueUtil; +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.utils.Util; + +import org.jetbrains.annotations.NotNull; + +public class SurveyorDataViewHolderHeightTraverse extends RecyclerView.ViewHolder { + private final Context context; + private final TextView leftLabel; + private final TextView rightLabel; + + public final TextView pointName; + public final TextView heightValue; + public final TextView prismValue; + + public final TextView leftAngleVer1; + public final TextView leftAngleVer2; + public final TextView leftDistance1; + public final TextView leftDistance2; + + public final TextView rightAngleVer1; + public final TextView rightAngleVer2; + public final TextView rightDistance1; + public final TextView rightDistance2; + + public final TextView averageVerAngle; + public final TextView averageDistance; + + public final View selectMask; + + public final TextView _i; + public final TextView _2d; + + public final TextView distanceTitle; + public final TextView tvCycleNum; + private final View itemView; + + public SurveyorDataViewHolderHeightTraverse(Context context, @NonNull @NotNull View itemView) { + super(itemView); + this.context = context; + leftLabel = itemView.findViewById(R.id.left_label); + rightLabel = itemView.findViewById(R.id.right_label); + + pointName = itemView.findViewById(R.id.pointName); + heightValue = itemView.findViewById(R.id.height_value); + prismValue = itemView.findViewById(R.id.prism_value); + + leftAngleVer1 = itemView.findViewById(R.id.left_angle_ver_1); + leftAngleVer2 = itemView.findViewById(R.id.left_angle_ver_2); + leftDistance1 = itemView.findViewById(R.id.left_distance_1); + leftDistance2 = itemView.findViewById(R.id.left_distance_2); + + rightAngleVer1 = itemView.findViewById(R.id.right_angle_ver_1); + rightAngleVer2 = itemView.findViewById(R.id.right_angle_ver_2); + rightDistance1 = itemView.findViewById(R.id.right_distance_1); + rightDistance2 = itemView.findViewById(R.id.right_distance_2); + + averageVerAngle = itemView.findViewById(R.id.average_angle_ver); + averageDistance = itemView.findViewById(R.id.average_distance); + + selectMask = itemView.findViewById(R.id.mask); + + _i = itemView.findViewById(R.id.value_i); + _2d = itemView.findViewById(R.id.value_2d); + + distanceTitle = itemView.findViewById(R.id.distance_title); + tvCycleNum = itemView.findViewById(R.id.tvCycleNum); + + this.itemView = itemView; + } + + public void setup(int itemIndex, + String stationId, + boolean showSlopDistance, + ICachedData cachedData, + ICycleRecorder cycleRecorder, + ISurveyorData surveyorData) { + if (showSlopDistance) { + distanceTitle.setText(R.string.distance_slope); + } else { + distanceTitle.setText(R.string.distance_horizontal); + } +// int currentCycleIndex = cycleRecorder.currentCycleIndex(); + int currentCycleIndex = itemIndex; + int currentSurveyorIndex = surveyorData.currentIndex(); + //设置当前测量状态标识 + if (currentSurveyorIndex == itemIndex) { + //当前非跳过点背景黄边白色 + selectMask.setBackground(Tools.getDrawable(R.drawable.select_mask)); + } else { + if (cachedData.isPointAbandon(currentCycleIndex, itemIndex)) { + selectMask.setBackground(Tools.getDrawable(R.drawable.bg_gray_3)); + } else { + selectMask.setBackgroundColor(Tools.getColor(R.color.white)); + } + } + tvCycleNum.setText(Tools.getString(R.string.test_n_cycle, (itemIndex + 1))); + + //初始化 + setValue(TYPE_LEFT1, ORIGINAL_VALUE, ORIGINAL_VALUE, ORIGINAL_VALUE); + setValue(TYPE_LEFT2, ORIGINAL_VALUE, ORIGINAL_VALUE, ORIGINAL_VALUE); + setValue(TYPE_RIGHT1, ORIGINAL_VALUE, ORIGINAL_VALUE, ORIGINAL_VALUE); + setValue(TYPE_RIGHT2, ORIGINAL_VALUE, ORIGINAL_VALUE, ORIGINAL_VALUE); + leftLabel.setTextColor(context.getResources().getColor(R.color.value_1_normal)); + setTextColor(TYPE_LEFT1, R.color.value_1_normal); + setTextColor(TYPE_LEFT2, R.color.value_2_normal); + rightLabel.setTextColor(context.getResources().getColor(R.color.value_1_normal)); + setTextColor(TYPE_RIGHT1, R.color.value_1_normal); + setTextColor(TYPE_RIGHT2, R.color.value_2_normal); + + averageVerAngle.setText(ORIGINAL_VALUE); + averageDistance.setText(ORIGINAL_VALUE); + + _i.setText(ORIGINAL_VALUE); + _2d.setText(ORIGINAL_VALUE); + + boolean aloneDistance = cachedData.isAloneDistance(currentCycleIndex, itemIndex); + + //如果当前正在测量,使用缓存数据设置相应信息 + LeftOrRight surveyorState = surveyorData.leftOrRight(); + if (currentSurveyorIndex == itemIndex) { + if (surveyorState == LeftOrRight.left) { + if (surveyorData.hasSurveyor1()) { + setValue(aloneDistance, TYPE_LEFT1, surveyorData.getAngleHor1(), surveyorData.getAngleVer1(), surveyorData.getDistance1()); + } + if (surveyorData.hasSurveyor2()) { + setValue(aloneDistance, TYPE_LEFT2, surveyorData.getAngleHor2(), surveyorData.getAngleVer2(), surveyorData.getDistance2()); + } + //设置颜色 + setTextColor(TYPE_LEFT1, R.color.value_1_selected); + setTextColor(TYPE_LEFT2, R.color.value_2_selected); + leftLabel.setTextColor(context.getResources().getColor(R.color.value_1_selected)); + } else if (surveyorState == LeftOrRight.right) { + if (surveyorData.hasSurveyor1()) { + setValue(aloneDistance, TYPE_RIGHT1, surveyorData.getAngleHor1(), surveyorData.getAngleVer1(), surveyorData.getDistance1()); + } + if (surveyorData.hasSurveyor2()) { + setValue(aloneDistance, TYPE_RIGHT2, surveyorData.getAngleHor2(), surveyorData.getAngleVer2(), surveyorData.getDistance2()); + } + //设置颜色 + setTextColor(TYPE_RIGHT1, R.color.value_1_selected); + setTextColor(TYPE_RIGHT2, R.color.value_2_selected); + rightLabel.setTextColor(context.getResources().getColor(R.color.value_1_selected)); + } + } + + //根据测量次数,控制数据显示 + setValue2Visibility(surveyorData.surveyorCount() > 1); + + pointName.setText(cachedData.pointName(currentCycleIndex, itemIndex)); + heightValue.setText(cachedData.getPrismHeight(currentCycleIndex, itemIndex)); + prismValue.setText(cachedData.getPrismTypeName(currentCycleIndex, itemIndex)); + + //重新监听observe---但是根据当前测量状态,需要排除一些数据监听 + boolean skipLeft1 = false, skipLeft2 = false, skipRight1 = false, skipRight2 = false; + //根据内存缓存排除 + if (currentSurveyorIndex == itemIndex) { + if (surveyorState == LeftOrRight.left) { + if (surveyorData.hasSurveyor1()) { + skipLeft1 = true; + } + if (surveyorData.hasSurveyor2() || surveyorData.surveyorCount() == 1) { + skipLeft2 = true; + } + } else if (surveyorState == LeftOrRight.right) { + if (surveyorData.hasSurveyor1()) { + skipRight1 = true; + } + if (surveyorData.hasSurveyor2() || surveyorData.surveyorCount() == 1) { + skipRight2 = true; + } + } + } + + String pointId = cachedData.pointId(currentCycleIndex, itemIndex); + String leftRecordId = IdUtil.createSurveyorRecordId(stationId, currentCycleIndex, pointId, LeftOrRight.left); + if (!skipLeft1) { + DataCategory dataCategory = cachedData.valueState(leftRecordId, 0); + if (!dataCategory.isEmptyData()) { + setValue(aloneDistance, TYPE_LEFT1, + cachedData.angleHor1(leftRecordId), + cachedData.angleVer1(leftRecordId), + cachedData.distance1(leftRecordId)); + } + if (dataCategory.isNeedResurvey()) { + setTextColor(TYPE_LEFT1, R.color.value_dirty); + } else if (dataCategory == DataCategory.dirtyAndSurveyed) { + setTextColor(TYPE_LEFT1, R.color.value_resurveyed); + } + } + if (!skipLeft2) { + DataCategory dataCategory = cachedData.valueState(leftRecordId, 1); + if (!dataCategory.isEmptyData()) { + setValue(aloneDistance, TYPE_LEFT2, + cachedData.angleHor2(leftRecordId), + cachedData.angleVer2(leftRecordId), + cachedData.distance2(leftRecordId)); + } + if (dataCategory.isNeedResurvey()) { + setTextColor(TYPE_LEFT2, R.color.value_dirty); + } else if (dataCategory == DataCategory.dirtyAndSurveyed) { + setTextColor(TYPE_LEFT2, R.color.value_resurveyed); + } + } + String rightRecordId = IdUtil.createSurveyorRecordId(stationId, currentCycleIndex, pointId, LeftOrRight.right); + if (!skipRight1) { + DataCategory dataCategory = cachedData.valueState(rightRecordId, 0); + if (!dataCategory.isEmptyData()) { + setValue(aloneDistance, TYPE_RIGHT1, + cachedData.angleHor1(rightRecordId), + cachedData.angleVer1(rightRecordId), + cachedData.distance1(rightRecordId)); + } + if (dataCategory.isNeedResurvey()) { + setTextColor(TYPE_RIGHT1, R.color.value_dirty); + } else if (dataCategory == DataCategory.dirtyAndSurveyed) { + setTextColor(TYPE_RIGHT1, R.color.value_resurveyed); + } + } + if (!skipRight2) { + DataCategory dataCategory = cachedData.valueState(rightRecordId, 1); + if (!dataCategory.isEmptyData()) { + setValue(aloneDistance, TYPE_RIGHT2, + cachedData.angleHor2(rightRecordId), + cachedData.angleVer2(rightRecordId), + cachedData.distance2(rightRecordId)); + } + if (dataCategory.isNeedResurvey()) { + setTextColor(TYPE_RIGHT2, R.color.value_dirty); + } else if (dataCategory == DataCategory.dirtyAndSurveyed) { + setTextColor(TYPE_RIGHT2, R.color.value_resurveyed); + } + } + + + //均值(中值) + int surveyorCount = surveyorData.surveyorCount(); + + CacheResult verAngleLeftAndRightAverageValue = AverageValueMethod.leftAndRightValue(SdAngleValueType.verAngle, + leftRecordId, + rightRecordId, surveyorCount, cachedData); + if (verAngleLeftAndRightAverageValue.validate) {//显示天顶距 + averageVerAngle.setText(RadianMethod.dmsStringOf(Math.PI / 2 - verAngleLeftAndRightAverageValue.value)); + } else { + averageVerAngle.setText(ORIGINAL_VALUE); + } + + CacheResult distanceLeftAndRightAverageValue = AverageValueMethod.leftAndRightValue(SdAngleValueType.distance, + leftRecordId, + rightRecordId, surveyorCount, cachedData); + if (aloneDistance) { + averageDistance.setText(ORIGINAL_VALUE); + } else { + if (distanceLeftAndRightAverageValue.validate) { + averageDistance.setText(Util.formatDouble2String(distanceLeftAndRightAverageValue.value, + SettingValueUtil.getLengthDecimalPoint())); + } else { + averageDistance.setText(ORIGINAL_VALUE); + } + } + + //设置2c、i、2d + CacheResult valueI = ValueOf2cMethod.valueOf2C(SdAngleValueType.verAngle, + itemIndex, stationId, surveyorData, currentCycleIndex, cachedData); + if (valueI.validate && verAngleLeftAndRightAverageValue.validate) { + _i.setText(String.format("%s″", Util.formatDouble2String(valueI.value, 1))); + } else { + _i.setText(ORIGINAL_VALUE); + } + + CacheResult value2D = ValueOf2cMethod.valueOf2C(SdAngleValueType.distance, + itemIndex, stationId, surveyorData, currentCycleIndex, cachedData); + if (aloneDistance) { + _2d.setText(ORIGINAL_VALUE); + } else { + if (value2D.validate && distanceLeftAndRightAverageValue.validate) { + _2d.setText(String.format("%smm", Util.formatDouble2String(value2D.value, 1))); + } else { + _2d.setText(ORIGINAL_VALUE); + } + } + + } + + private void setTextColor(int type, int value) { + angleVer(type).setTextColor(context.getResources().getColor(value)); + distance(type).setTextColor(context.getResources().getColor(value)); + } + + private void setValue(boolean aloneDistance, int type, double angleHor, double angleVer, double distance) { + //判断是否测水平角 + String angleVerS = RadianMethod.dmsStringOf(angleVer); + String distanceS = ORIGINAL_VALUE; + if (!aloneDistance) { + distanceS = Util.formatDouble2String(distance, + SettingValueUtil.getLengthDecimalPoint()); + } + setValue(type, + RadianMethod.dmsStringOf(angleHor), + angleVerS, + distanceS); + } + + private void setValue(int type, String angleHor, String angleVer, String distance) { + angleVer(type).setText(angleVer); + distance(type).setText(distance); + } + + private void setValue2Visibility(boolean visibility) { + leftAngleVer2.setVisibility(visibility ? View.VISIBLE : View.GONE); + leftDistance2.setVisibility(visibility ? View.VISIBLE : View.GONE); + rightAngleVer2.setVisibility(visibility ? View.VISIBLE : View.GONE); + rightDistance2.setVisibility(visibility ? View.VISIBLE : View.GONE); + } + + private TextView angleVer(int type) { + if (TYPE_LEFT1 == type) { + return leftAngleVer1; + } else if (TYPE_LEFT2 == type) { + return leftAngleVer2; + } else if (TYPE_RIGHT1 == type) { + return rightAngleVer1; + } + return rightAngleVer2; + } + + + private TextView distance(int type) { + if (TYPE_LEFT1 == type) { + return leftDistance1; + } else if (TYPE_LEFT2 == type) { + return leftDistance2; + } else if (TYPE_RIGHT1 == type) { + return rightDistance1; + } + return rightDistance2; + } + + private static final int TYPE_LEFT1 = 1; + private static final int TYPE_LEFT2 = 2; + private static final int TYPE_RIGHT1 = 3; + private static final int TYPE_RIGHT2 = 4; + private static final String ORIGINAL_VALUE = "-"; + private static final String SKIP_VALUE = "*"; +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/vh/TextSelectableViewHolder.java b/app/src/main/java/com/bingce/controlnetwork/ui/vh/TextSelectableViewHolder.java new file mode 100644 index 0000000..cfd15ae --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/vh/TextSelectableViewHolder.java @@ -0,0 +1,21 @@ +package com.bingce.controlnetwork.ui.vh; + +import android.view.View; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlnetwork.R; + +public class TextSelectableViewHolder extends RecyclerView.ViewHolder { + public final ImageView status; + public final TextView name; + + public TextSelectableViewHolder(@NonNull View itemView) { + super(itemView); + status = itemView.findViewById(R.id.status); + name = itemView.findViewById(R.id.text); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/vh/TitleWithSubtitleViewHolder.java b/app/src/main/java/com/bingce/controlnetwork/ui/vh/TitleWithSubtitleViewHolder.java new file mode 100644 index 0000000..14d7e98 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/vh/TitleWithSubtitleViewHolder.java @@ -0,0 +1,20 @@ +package com.bingce.controlnetwork.ui.vh; + +import android.view.View; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlnetwork.R; + +public class TitleWithSubtitleViewHolder extends RecyclerView.ViewHolder { + public final TextView title; + public final TextView subTitle; + + public TitleWithSubtitleViewHolder(@NonNull View itemView) { + super(itemView); + title = itemView.findViewById(R.id.title); + subTitle = itemView.findViewById(R.id.sub_title); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/CommentListTextView.java b/app/src/main/java/com/bingce/controlnetwork/ui/widget/CommentListTextView.java new file mode 100644 index 0000000..5b873e3 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/CommentListTextView.java @@ -0,0 +1,380 @@ +package com.bingce.controlnetwork.ui.widget; + +import android.content.Context; +import android.graphics.Color; +import android.text.SpannableString; +import android.text.SpannableStringBuilder; +import android.text.Spanned; +import android.text.TextPaint; +import android.text.method.LinkMovementMethod; +import android.text.style.ClickableSpan; +import android.text.style.ForegroundColorSpan; +import android.util.AttributeSet; +import android.view.View; + +import androidx.appcompat.widget.AppCompatTextView; + +import java.util.List; + +/** + * Created by lujianchao on 2017/1/19. + * + * @author lujianchao + */ + +public class CommentListTextView extends AppCompatTextView { + /** + * 所有评论数据 + */ + private List mInfos; + private onCommentListener mListener; + + /** + * 点击文字会触发两个回调,用这个变量控制屏蔽掉一个 + */ + private boolean isNickNameClick = false; + + + /** + * 最大显示行数,超过指定行数多一行显示为查看更多文本,可设置文本 + */ + private int mMaxlines = 6; + /** + * 当超过n行后,n+1行显示为这个文本; + */ + private String mMoreStr = "查看全部评论"; + /** + * 谁回复谁中回复字符串,可以变成别的 + */ + private String mTalkStr = "回复"; + /** + * 人名称颜色 + */ + private int mNameColor = Color.parseColor("#00376a"); + private int mCommentColor = Color.parseColor("#2d2d2d"); + private int mTalkColor = Color.parseColor("#2d2d2d"); + + public int getTalkColor() { + return mTalkColor; + } + + public CommentListTextView setTalkColor(final int mTalkColor) { + this.mTalkColor = mTalkColor; + return this; + } + + public int getMaxlines() { + return mMaxlines; + } + + public CommentListTextView setMaxlines(final int mMaxlines) { + this.mMaxlines = mMaxlines; + return this; + } + + public String getMoreStr() { + return mMoreStr; + } + + public CommentListTextView setMoreStr(final String mMoreStr) { + this.mMoreStr = mMoreStr; + return this; + } + + public String getTalkStr() { + return mTalkStr; + } + + public CommentListTextView setTalkStr(final String mTalkStr) { + this.mTalkStr = mTalkStr; + return this; + } + + public int getNameColor() { + return mNameColor; + } + + public CommentListTextView setNameColor(final int mNameColor) { + this.mNameColor = mNameColor; + return this; + } + + public int getCommentColor() { + return mCommentColor; + } + + public CommentListTextView setCommentColor(final int mCommentColor) { + this.mCommentColor = mCommentColor; + return this; + } + + public CommentListTextView(final Context context) { + super(context); + } + + + public CommentListTextView(final Context context, final AttributeSet attrs) { + super(context, attrs); + } + + public CommentListTextView setonCommentListener(final onCommentListener mListener) { + this.mListener = mListener; + return this; + } + + public void setData(List mInfos) { + this.mInfos = mInfos; + /** + * textview必须设置,否则自定义点击事件没响应 + */ + setMovementMethod(LinkMovementMethod.getInstance()); + setHighlightColor(Color.TRANSPARENT); + setText(getCommentString()); + setOnClickListener(new OnClickListener() { + @Override + public void onClick(final View v) { + if (isNickNameClick) { + isNickNameClick = false; + return; + } + if (mListener != null) { + mListener.onOtherClick(); + } + } + }); + } + + private SpannableStringBuilder getCommentString() { + SpannableStringBuilder mStringBuilder = new SpannableStringBuilder(); + /** + * 对评论数据进行处理,默认超过mMaxlines条则第mMaxlines+1条显示查看全部 + */ + for (int mI = 0; mI < mInfos.size(); mI++) { + final CommentInfo mInfo = mInfos.get(mI); + /** + * 拼接成“张三:今天天气真好”这种形式,就是一行显示的文本。 + * 或者为张三 回复 李四:今天天气真好 + */ + String mS = null; + if (mInfo.getTonickname() == null || mInfo.getTonickname().equals("")) { + mS = mInfo.getNickname() + ":" + mInfo.getComment(); + } else { + mS = mInfo.getNickname() + mTalkStr + mInfo.getTonickname() + ":" + mInfo.getComment(); + } + /** + * 获得一个SpannableString文本的对象 + */ + SpannableString mString = new SpannableString(mS); + /** + * 我们假设“张三:今天天气真好”这句话中“张三:”这三个字符为橘红色字体并且添加点击事件,其余评论内容单独添加事件,一般业务需求是点击人名跳到个人主页或者聊天,点击评论内容是对这条评论进行评论。 + * 谁回复谁同理,就不写了 + */ + int start = 0; + int end = (mInfo.getNickname()).length(); + final int finalMI = mI; + /** + * 处理第一个人名 + * 设置文本从第0个开始到end位置具有点击事件,点击后回调,updateDrawState中设置文本从第0个到第end位置的文本前景色就是文字颜色为橘红色 + */ + mString.setSpan(new ClickableSpan() { + + @Override + public void updateDrawState(TextPaint ds) { + /** + * 是否有下划线 + */ + ds.setUnderlineText(false); + /** + * 橘红色字体 + */ + ds.setColor(mNameColor); + } + + @Override + public void onClick(final View widget) { + isNickNameClick = true; + if (mListener != null) { + mListener.onNickNameClick(finalMI, mInfos.get(finalMI)); + } + } + }, 0, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + mString.setSpan(new ForegroundColorSpan(mTalkColor), mInfo.getNickname().length(), mInfo.getNickname().length() + mTalkStr.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + + /** + * 处理第二个人名 + */ + if (mInfo.getTonickname() != null && !mInfo.getTonickname().equals("")) { + start = mInfo.getNickname().length() + mTalkStr.length(); + end = mInfo.getNickname().length() + mTalkStr.length() + mInfo.getTonickname().length(); + mString.setSpan(new ClickableSpan() { + @Override + public void updateDrawState(TextPaint ds) { + /** + * 是否有下划线 + */ + ds.setUnderlineText(false); + /** + * 橘红色字体 + */ + ds.setColor(mNameColor); + } + + @Override + public void onClick(final View widget) { + isNickNameClick = true; + if (mListener != null) { + mListener.onToNickNameClick(finalMI, mInfos.get(finalMI)); + } + } + }, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + } + + /** + * 设置文本从第end个开始到最后位置具有点击事件,点击后回调,updateDrawState中设置文本从第end个到最后的文本前景色就是文字颜色为黑色 + */ + + mString.setSpan(new ClickableSpan() { + + @Override + public void updateDrawState(TextPaint ds) { + /** + * 是否有下划线 + */ + ds.setUnderlineText(false); + /** + * 黑色字体 + */ + ds.setColor(mCommentColor); + } + + @Override + public void onClick(final View widget) { + isNickNameClick = true; + if (mListener != null) { + mListener.onCommentItemClick(finalMI, mInfos.get(finalMI)); + } + } + }, end, mS.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + /** + * 设置文本从第end个到最后的文本前景色就是文字颜色为黑色,即评论内容为黑色 + */ + + mStringBuilder.append(mString); + mStringBuilder.append("\r\n"); + if (mI == (mMaxlines - 1)) { + break; + } + } + if (mInfos.size() > mMaxlines) { + mStringBuilder.append("查看全部评论"); + } else { + /** + * 如果不大于3条,则删除最后的换行 + */ + mStringBuilder.delete(mStringBuilder.length() - 2, mStringBuilder.length()); + } + return mStringBuilder; + } + + + public interface onCommentListener { + /** + * 点击人名的回调 + * + * @param position 第几条评论 从0开始 + * @param mInfo 评论相关信息 + */ + void onNickNameClick(int position, CommentInfo mInfo); + + /** + * 点击被评论人名的回调 + * + * @param position 第几条评论 从0开始 + * @param mInfo 评论相关信息 + */ + void onToNickNameClick(int position, CommentInfo mInfo); + + /** + * 点击评论文本回调,主要针对对谁回复操作 + * + * @param position + * @param mInfo + */ + void onCommentItemClick(int position, CommentInfo mInfo); + + /** + * 点击非文字部分 + */ + void onOtherClick(); + } + + public static class CommentInfo { + /** + * 评论ID + */ + private int ID; + /** + * 评论人名称 + */ + private String nickname; + /** + * 评论内容 + */ + private String comment; + /** + * 被评论人名称 + */ + private String tonickname; + + @Override + public String toString() { + return "CommentInfo{" + + "ID=" + ID + + ", nickname='" + nickname + '\'' + + ", comment='" + comment + '\'' + + ", tonickname='" + tonickname + '\'' + + '}'; + } + + /** + * 下面可以继续写自定义需要的属性,需要传什么写什么 + */ + + + public int getID() { + return ID; + } + + public CommentInfo setID(final int mID) { + ID = mID; + return this; + } + + public String getNickname() { + return nickname; + } + + public CommentInfo setNickname(final String mNickname) { + nickname = mNickname; + return this; + } + + public String getComment() { + return comment; + } + + public CommentInfo setComment(final String mComment) { + comment = mComment; + return this; + } + + public String getTonickname() { + return tonickname; + } + + public CommentInfo setTonickname(final String mTonickname) { + tonickname = mTonickname; + return this; + } + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/ItemWithEditText.java b/app/src/main/java/com/bingce/controlnetwork/ui/widget/ItemWithEditText.java new file mode 100644 index 0000000..22f114a --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/ItemWithEditText.java @@ -0,0 +1,25 @@ +package com.bingce.controlnetwork.ui.widget; + +import android.content.Context; +import android.util.AttributeSet; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +public class ItemWithEditText extends TextItem { + public ItemWithEditText(@NonNull Context context) { + super(context); + } + + public ItemWithEditText(@NonNull Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + } + + public ItemWithEditText(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + public ItemWithEditText(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/MyDrawerBuilder.java b/app/src/main/java/com/bingce/controlnetwork/ui/widget/MyDrawerBuilder.java new file mode 100644 index 0000000..b3b6cc7 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/MyDrawerBuilder.java @@ -0,0 +1,27 @@ +package com.bingce.controlnetwork.ui.widget; + +import android.app.Activity; + +import androidx.annotation.LayoutRes; +import androidx.annotation.NonNull; + +import com.mikepenz.materialdrawer.DrawerBuilder; + +public class MyDrawerBuilder extends DrawerBuilder { + + public MyDrawerBuilder(@NonNull Activity activity) { + super(activity); + } + + public MyDrawerBuilder withCustomLayout(@LayoutRes int resLayout) { + if (mActivity == null) { + throw new RuntimeException("please pass an activity first to use this call"); + } + + if (resLayout != -1) { + this.mCustomView = mActivity.getLayoutInflater().inflate(resLayout, mRootView, false); + } + + return this; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/NoScrollView.java b/app/src/main/java/com/bingce/controlnetwork/ui/widget/NoScrollView.java new file mode 100644 index 0000000..af386e6 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/NoScrollView.java @@ -0,0 +1,39 @@ +package com.bingce.controlnetwork.ui.widget; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.MotionEvent; +import android.widget.ScrollView; + +public class NoScrollView extends ScrollView { + private boolean noScroll = false; + + public NoScrollView(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public NoScrollView(Context context) { + super(context); + } + + public void setNoScroll(boolean noScroll) { + this.noScroll = noScroll; + } + + @Override + public boolean onTouchEvent(MotionEvent arg0) { + /* return false;//super.onTouchEvent(arg0); */ + if (noScroll) + return false; + else + return super.onTouchEvent(arg0); + } + + @Override + public boolean onInterceptTouchEvent(MotionEvent arg0) { + if (noScroll) + return false; + else + return super.onInterceptTouchEvent(arg0); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/NoScrollViewPager.java b/app/src/main/java/com/bingce/controlnetwork/ui/widget/NoScrollViewPager.java new file mode 100644 index 0000000..39b651a --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/NoScrollViewPager.java @@ -0,0 +1,56 @@ +package com.bingce.controlnetwork.ui.widget; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.MotionEvent; + +import androidx.viewpager.widget.ViewPager; + +public class NoScrollViewPager extends ViewPager { + private boolean noScroll = false; + + public NoScrollViewPager(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public NoScrollViewPager(Context context) { + super(context); + } + + public void setNoScroll(boolean noScroll) { + this.noScroll = noScroll; + } + + @Override + public void scrollTo(int x, int y) { + super.scrollTo(x, y); + } + + @Override + public boolean onTouchEvent(MotionEvent arg0) { + /* return false;//super.onTouchEvent(arg0); */ + if (noScroll) + return false; + else + return super.onTouchEvent(arg0); + } + + @Override + public boolean onInterceptTouchEvent(MotionEvent arg0) { + if (noScroll) + return false; + else + return super.onInterceptTouchEvent(arg0); + } + + @Override + public void setCurrentItem(int item, boolean smoothScroll) { + super.setCurrentItem(item, smoothScroll); + } + + @Override + public void setCurrentItem(int item) { + super.setCurrentItem(item); + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/RotateLayout.java b/app/src/main/java/com/bingce/controlnetwork/ui/widget/RotateLayout.java new file mode 100644 index 0000000..1ef42a7 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/RotateLayout.java @@ -0,0 +1,189 @@ +package com.bingce.controlnetwork.ui.widget; + +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Canvas; +import android.graphics.Matrix; +import android.graphics.Rect; +import android.graphics.RectF; +import android.util.AttributeSet; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewGroup; +import android.view.ViewParent; + +import com.bingce.controlnetwork.R; + +import static java.lang.Math.PI; + +/** + * Rotates first view in this layout by specified angle. + *

+ * This layout is supposed to have only one view. Behaviour of the views after the first one + * is not defined. + *

+ * XML attributes + * See com.github.rongi.rotate_layout.R.styleable#RotateLayout RotateLayout Attributes, + */ +public class RotateLayout extends ViewGroup { + private float angle; + + private final Matrix rotateMatrix = new Matrix(); + + private final Rect viewRectRotated = new Rect(); + + private final RectF tempRectF1 = new RectF(); + private final RectF tempRectF2 = new RectF(); + + private final float[] viewTouchPoint = new float[2]; + private final float[] childTouchPoint = new float[2]; + + private boolean angleChanged = true; + + public RotateLayout(Context context) { + this(context, null); + } + + public RotateLayout(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public RotateLayout(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs); + + final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RotateLayout); + angle = a.getInt(R.styleable.RotateLayout_rotate_angle, 0); + a.recycle(); + + setWillNotDraw(false); + } + + /** + * Returns current angle of this layout + */ + public float getAngle() { + return angle; + } + + /** + * Sets current angle of this layout. + */ + public void setAngle(float angle) { + if (this.angle != angle) { + this.angle = angle; + angleChanged = true; + requestLayout(); + invalidate(); + } + } + + /** + * Returns this layout's child or null if there is no any + */ + public View getView() { + if (getChildCount() > 0) { + return getChildAt(0); + } else { + return null; + } + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + final View child = getView(); + if (child != null) { + measureChild(child, widthMeasureSpec, heightMeasureSpec); + setMeasuredDimension( + resolveSize(child.getMeasuredWidth(), widthMeasureSpec), + resolveSize(child.getMeasuredHeight(), heightMeasureSpec)); +// if (abs(angle % 180) == 90) { +// //noinspection SuspiciousNameCombination +// measureChild(child, heightMeasureSpec, widthMeasureSpec); +// setMeasuredDimension( +// resolveSize(child.getMeasuredHeight(), widthMeasureSpec), +// resolveSize(child.getMeasuredWidth(), heightMeasureSpec)); +// } else if (abs(angle % 180) == 0) { +// measureChild(child, widthMeasureSpec, heightMeasureSpec); +// setMeasuredDimension( +// resolveSize(child.getMeasuredWidth(), widthMeasureSpec), +// resolveSize(child.getMeasuredHeight(), heightMeasureSpec)); +// } else { +// int childWithMeasureSpec = MeasureSpec.makeMeasureSpec(0, UNSPECIFIED); +// int childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(0, UNSPECIFIED); +// measureChild(child, childWithMeasureSpec, childHeightMeasureSpec); +// +// int measuredWidth = (int) ceil(child.getMeasuredWidth() * abs(cos(angle_c())) + child.getMeasuredHeight() * abs(sin(angle_c()))); +// int measuredHeight = (int) ceil(child.getMeasuredWidth() * abs(sin(angle_c())) + child.getMeasuredHeight() * abs(cos(angle_c()))); +// +// setMeasuredDimension( +// resolveSize(measuredWidth, widthMeasureSpec), +// resolveSize(measuredHeight, heightMeasureSpec)); +// } + } else { + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + } + } + + @Override + protected void onLayout(boolean changed, int l, int t, int r, int b) { + int layoutWidth = r - l; + int layoutHeight = b - t; + + if (angleChanged || changed) { + final RectF layoutRect = tempRectF1; + layoutRect.set(0, 0, layoutWidth, layoutHeight); + final RectF layoutRectRotated = tempRectF2; + rotateMatrix.setRotate(angle, layoutRect.centerX(), layoutRect.centerY()); + rotateMatrix.mapRect(layoutRectRotated, layoutRect); + layoutRectRotated.round(viewRectRotated); + angleChanged = false; + } + + final View child = getView(); + if (child != null) { + int childLeft = (layoutWidth - child.getMeasuredWidth()) / 2; + int childTop = (layoutHeight - child.getMeasuredHeight()) / 2; + int childRight = childLeft + child.getMeasuredWidth(); + int childBottom = childTop + child.getMeasuredHeight(); + child.layout(childLeft, childTop, childRight, childBottom); + } + } + + @Override + protected void dispatchDraw(Canvas canvas) { + canvas.save(); + canvas.rotate(angle, getWidth() / 2f, getHeight() / 2f); + super.dispatchDraw(canvas); + canvas.restore(); + } + + @Override + public ViewParent invalidateChildInParent(int[] location, Rect dirty) { + invalidate(); + return super.invalidateChildInParent(location, dirty); + } + + @Override + public boolean dispatchTouchEvent(MotionEvent event) { + viewTouchPoint[0] = event.getX(); + viewTouchPoint[1] = event.getY(); + + rotateMatrix.mapPoints(childTouchPoint, viewTouchPoint); + + event.setLocation(childTouchPoint[0], childTouchPoint[1]); + boolean result = super.dispatchTouchEvent(event); + event.setLocation(viewTouchPoint[0], viewTouchPoint[1]); + + return result; + } + + /** + * Circle angle, from 0 to TAU + */ + private Double angle_c() { + // True circle constant, not that petty imposter known as "PI" + double TAU = 2 * PI; + return TAU * angle / 360; + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/TextItem.java b/app/src/main/java/com/bingce/controlnetwork/ui/widget/TextItem.java new file mode 100644 index 0000000..b73b2f2 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/TextItem.java @@ -0,0 +1,100 @@ +package com.bingce.controlnetwork.ui.widget; + +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Color; +import android.util.AttributeSet; +import android.util.TypedValue; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.FrameLayout; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.bingce.controlnetwork.R; + +public class TextItem extends FrameLayout { + public final static int GRAVITY_TEXT_START = 0; + public final static int GRAVITY_TEXT_CENTER = 1; + public final static int GRAVITY_TEXT_END = 2; + + public final static int DIVIDER_VISIBLE = 0; + public final static int DIVIDER_INVISIBLE = 1; + + public TextItem(@NonNull Context context) { + super(context); + init(context, null); + } + + public TextItem(@NonNull Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + init(context, attrs); + } + + public TextItem(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + init(context, attrs); + } + + public TextItem(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + init(context, attrs); + } + + protected int contentLayout() { + return R.layout.item_with_text_layout; + } + + void init(Context context, AttributeSet attrs) { + String string = "TEXT"; + int color = Color.BLACK; + int size = -1; + int gravity = GRAVITY_TEXT_START; + int divider = DIVIDER_VISIBLE; + if (attrs != null) { + final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TextItem); + string = a.getString(R.styleable.TextItem_text); + color = a.getColor(R.styleable.TextItem_text_color, Color.BLACK); + size = a.getDimensionPixelSize(R.styleable.TextItem_text_size, -1); + gravity = a.getInt(R.styleable.TextItem_text_gravity, GRAVITY_TEXT_START); + divider = a.getInt(R.styleable.TextItem_dividerVisible, DIVIDER_VISIBLE); + a.recycle(); + } + View content = LayoutInflater.from(context).inflate(contentLayout(), null, false); + addView(content); + View text = content.findViewById(R.id.text); + if (text instanceof TextView) { + TextView textView = (TextView) text; + textView.setText(string); + textView.setTextColor(color); + if (size > 0) { + textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, size); + } + switch (gravity) { + case GRAVITY_TEXT_CENTER: + textView.setGravity(Gravity.CENTER); + break; + case GRAVITY_TEXT_END: + textView.setGravity(Gravity.END | Gravity.CENTER_VERTICAL); + break; + default: + textView.setGravity(Gravity.START | Gravity.CENTER_VERTICAL); + break; + } + } + View dividerView = content.findViewById(R.id.divider); + if (dividerView != null) { + dividerView.setVisibility(divider == DIVIDER_VISIBLE ? VISIBLE : GONE); + } + } + + public void setText(String string) { + View text = findViewById(R.id.text); + if (text instanceof TextView) { + ((TextView) text).setText(string); + } + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/TextItemWithDescribe.java b/app/src/main/java/com/bingce/controlnetwork/ui/widget/TextItemWithDescribe.java new file mode 100644 index 0000000..b91a92a --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/TextItemWithDescribe.java @@ -0,0 +1,58 @@ +package com.bingce.controlnetwork.ui.widget; + +import android.content.Context; +import android.content.res.TypedArray; +import android.util.AttributeSet; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.bingce.controlnetwork.R; + +public class TextItemWithDescribe extends TextItem { + public TextItemWithDescribe(@NonNull Context context) { + super(context); + } + + public TextItemWithDescribe(@NonNull Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + } + + public TextItemWithDescribe(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + public TextItemWithDescribe(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + } + + @Override + void init(Context context, AttributeSet attrs) { + super.init(context, attrs); + String describe = ""; + if (attrs != null) { + final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TextItemWithDescribe); + describe = a.getString(R.styleable.TextItemWithDescribe_describeValue); + a.recycle(); + } + setDescribeText(describe); + } + + @Override + protected int contentLayout() { + return super.contentLayout(); + } + + public void setDescribeText(String text) { + TextView describe = findViewById(R.id.describe); + if (describe != null) { + if (text == null || text.isEmpty()) { + describe.setVisibility(GONE); + } else { + describe.setVisibility(VISIBLE); + describe.setText(text); + } + } + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/TextItemWithMore.java b/app/src/main/java/com/bingce/controlnetwork/ui/widget/TextItemWithMore.java new file mode 100644 index 0000000..edc6592 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/TextItemWithMore.java @@ -0,0 +1,32 @@ +package com.bingce.controlnetwork.ui.widget; + +import android.content.Context; +import android.util.AttributeSet; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.bingce.controlnetwork.R; + +public class TextItemWithMore extends TextItemWithDescribe { + public TextItemWithMore(@NonNull Context context) { + super(context); + } + + public TextItemWithMore(@NonNull Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + } + + public TextItemWithMore(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + public TextItemWithMore(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + } + + @Override + protected int contentLayout() { + return R.layout.item_with_more_layout; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/ViewFactory.java b/app/src/main/java/com/bingce/controlnetwork/ui/widget/ViewFactory.java new file mode 100644 index 0000000..25c8ffe --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/ViewFactory.java @@ -0,0 +1,125 @@ +package com.bingce.controlnetwork.ui.widget; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.model.ViewItemType; + +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.ui.vh.DraggableTextViewHolder; +import com.bingce.controlnetwork.ui.vh.GroupParentViewHolder; +import com.bingce.controlnetwork.ui.vh.IndexTextSelectableViewHolder; +import com.bingce.controlnetwork.ui.vh.IndexTextViewHolder; +import com.bingce.controlnetwork.ui.vh.IndexTextWithPrefixViewHolder; +import com.bingce.controlnetwork.ui.vh.ItemWellViewHolder; +import com.bingce.controlnetwork.ui.vh.KeyBoolViewHolder; +import com.bingce.controlnetwork.ui.vh.KeyValueViewHolder; +import com.bingce.controlnetwork.ui.vh.StationAdjustItemViewHolder; +import com.bingce.controlnetwork.ui.vh.StationGroupItemViewHolder; +import com.bingce.controlnetwork.ui.vh.SurveyorDataAloneDistanceViewHolder; +import com.bingce.controlnetwork.ui.vh.SurveyorDataViewHolder; +import com.bingce.controlnetwork.ui.vh.SurveyorDataViewHolderHeightTraverse; +import com.bingce.controlnetwork.ui.vh.TextSelectableViewHolder; +import com.bingce.controlnetwork.ui.vh.TitleWithSubtitleViewHolder; +import com.bingce.controlnetwork.ui.vh.DraggableTextViewHolder; +import com.bingce.controlnetwork.ui.vh.GroupParentViewHolder; +import com.bingce.controlnetwork.ui.vh.IndexTextSelectableViewHolder; +import com.bingce.controlnetwork.ui.vh.IndexTextViewHolder; +import com.bingce.controlnetwork.ui.vh.IndexTextWithPrefixViewHolder; +import com.bingce.controlnetwork.ui.vh.ItemWellViewHolder; +import com.bingce.controlnetwork.ui.vh.KeyBoolViewHolder; +import com.bingce.controlnetwork.ui.vh.KeyValueViewHolder; +import com.bingce.controlnetwork.ui.vh.StationAdjustItemViewHolder; +import com.bingce.controlnetwork.ui.vh.StationGroupItemViewHolder; +import com.bingce.controlnetwork.ui.vh.SurveyorDataAloneDistanceViewHolder; +import com.bingce.controlnetwork.ui.vh.SurveyorDataViewHolder; +import com.bingce.controlnetwork.ui.vh.SurveyorDataViewHolderHeightTraverse; +import com.bingce.controlnetwork.ui.vh.TextSelectableViewHolder; +import com.bingce.controlnetwork.ui.vh.TitleWithSubtitleViewHolder; + + +public class ViewFactory { + + //生成对应的配置view + public static View generatorView(Context context, ViewGroup parent, ViewItemType viewType) { + switch (viewType) { + case indexWithName: + return LayoutInflater.from(context).inflate(R.layout.list_item_index_text_layout, parent, false); + case indexWithNameAndPrefix: + return LayoutInflater.from(context).inflate(R.layout.list_item_index_text_with_prefix_layout, parent, false); + case indexWithNameSelectable: + return LayoutInflater.from(context).inflate(R.layout.list_item_index_text_selectable_layout, parent, false); + case groupParent: + return LayoutInflater.from(context).inflate(R.layout.list_item_group_parent_layout, parent, false); + case nameWithText: + return LayoutInflater.from(context).inflate(R.layout.list_item_text_value_layout, parent, false); + case nameWithBool: + return LayoutInflater.from(context).inflate(R.layout.list_item_text_boolen_layout, parent, false); + case titleWithSubtitle: + return LayoutInflater.from(context).inflate(R.layout.list_item_title_subtitle_layout, parent, false); + case draggableItem: + return LayoutInflater.from(context).inflate(R.layout.list_item_draggable_layout, parent, false); + case surveyorStationCreateStationGroupItem: + return LayoutInflater.from(context).inflate(R.layout.list_item_surveyor_station_group_parent_with_add_layout, parent, false); + case textSelectable: + return LayoutInflater.from(context).inflate(R.layout.list_item_text_selectable_layout, parent, false); + case surveyorStationPointItem: + return LayoutInflater.from(context).inflate(R.layout.list_item_surveyor_station_point_layout, parent, false); + case stationAdjust: + return LayoutInflater.from(context).inflate(R.layout.list_item_station_adjust_layout, parent, false); + case wellItem: + return LayoutInflater.from(context).inflate(R.layout.list_item_well, parent, false); + case aloneDistanceMeasure: + return LayoutInflater.from(context).inflate(R.layout.list_item_well_measure_distance, parent, false); + case heightTraverseSurveyor: + return LayoutInflater.from(context).inflate(R.layout.list_item_surveyor_station_height_traverse, parent, false); + default: + return null; + } + } + + public static RecyclerView.ViewHolder generatorViewHolder(Context context, ViewGroup parent, ViewItemType viewType) { + View view = generatorView(context, parent, viewType); + if (view == null) { + return null; + } + switch (viewType) { + case indexWithName: + return new IndexTextViewHolder(view); + case indexWithNameAndPrefix: + return new IndexTextWithPrefixViewHolder(view); + case indexWithNameSelectable: + return new IndexTextSelectableViewHolder(view); + case groupParent: + return new GroupParentViewHolder(view); + case nameWithText: + return new KeyValueViewHolder(view); + case nameWithBool: + return new KeyBoolViewHolder(view); + case titleWithSubtitle: + return new TitleWithSubtitleViewHolder(view); + case draggableItem: + return new DraggableTextViewHolder(view); + case surveyorStationCreateStationGroupItem: + return new StationGroupItemViewHolder(view); + case textSelectable: + return new TextSelectableViewHolder(view); + case surveyorStationPointItem: + return new SurveyorDataViewHolder(context, view); + case stationAdjust: + return new StationAdjustItemViewHolder(view); + case wellItem: + return new ItemWellViewHolder(view); + case aloneDistanceMeasure: + return new SurveyorDataAloneDistanceViewHolder(context, view); + case heightTraverseSurveyor: + return new SurveyorDataViewHolderHeightTraverse(context, view); + default: + return null; + } + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/dialog/LoadingDialog.java b/app/src/main/java/com/bingce/controlnetwork/ui/widget/dialog/LoadingDialog.java new file mode 100644 index 0000000..21fda4d --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/dialog/LoadingDialog.java @@ -0,0 +1,86 @@ +package com.bingce.controlnetwork.ui.widget.dialog; + +import android.app.Dialog; +import android.content.Context; +import android.text.TextUtils; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.TextView; + +import com.bingce.controlnetwork.R; + + +public class LoadingDialog extends Dialog { + + public LoadingDialog(Context context) { + super(context, R.style.loading_dialog); + } + + public static class Builder { + + private final Context context; + private String message; + private boolean isCancelable = false; + private boolean isCancelOutside = false; + + + public Builder(Context context) { + this.context = context; + } + + /** + * 设置提示信息 + * + * @param message + * @return + */ + + public Builder setMessage(String message) { + this.message = message; + return this; + } + + /** + * 设置是否可以按返回键取消 + * + * @param isCancelable + * @return + */ + + public Builder setCancelable(boolean isCancelable) { + this.isCancelable = isCancelable; + return this; + } + + /** + * 设置是否可以取消 + * + * @param isCancelOutside + * @return + */ + public Builder setCancelOutside(boolean isCancelOutside) { + this.isCancelOutside = isCancelOutside; + return this; + } + + public LoadingDialog create() { + LayoutInflater inflater = LayoutInflater.from(context); + View view = inflater.inflate(R.layout.loading_dialog, null); + LoadingDialog loadingDailog = new LoadingDialog(context); + TextView msgText = view.findViewById(R.id.tipTextView); + if (TextUtils.isEmpty(message)) { + msgText.setVisibility(View.GONE); + } else { + msgText.setText(message); + msgText.setVisibility(View.VISIBLE); + } + loadingDailog.setContentView(view); + loadingDailog.setCancelable(isCancelable); + loadingDailog.setCanceledOnTouchOutside(isCancelOutside); + return loadingDailog; + + } + } + + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/dialog/LoadingUtil.java b/app/src/main/java/com/bingce/controlnetwork/ui/widget/dialog/LoadingUtil.java new file mode 100644 index 0000000..1b60e30 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/dialog/LoadingUtil.java @@ -0,0 +1,32 @@ +package com.bingce.controlnetwork.ui.widget.dialog; + +import android.content.Context; + +import androidx.annotation.MainThread; + +public class LoadingUtil { + private static LoadingDialog loadingDialog; + + @MainThread + public static void show(Context context, String msg) { + LoadingDialog.Builder loadBuilder = new LoadingDialog.Builder(context) + .setMessage(msg) + .setCancelable(true)//返回键是否可点击 + .setCancelOutside(false);//窗体外是否可点击 + loadingDialog = loadBuilder.create(); + loadingDialog.show(); + } + + @MainThread + public static void dismiss() { + try { + if (loadingDialog != null && loadingDialog.isShowing()) { + loadingDialog.dismiss(); + } + loadingDialog = null; + } catch (Exception e) { + e.printStackTrace(); + } + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/dialog/LoadingUtilKt.kt b/app/src/main/java/com/bingce/controlnetwork/ui/widget/dialog/LoadingUtilKt.kt new file mode 100644 index 0000000..4f75437 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/dialog/LoadingUtilKt.kt @@ -0,0 +1,33 @@ +package com.bingce.controlnetwork.ui.widget.dialog + +import android.content.Context + +object LoadingUtilKt { + + private var loadingDialog: LoadingDialog? = null + + + fun show(context: Context, msg: String?) { + val loadBuilder = LoadingDialog.Builder(context) + .setMessage(msg) + .setCancelable(true) //返回键是否可点击 + .setCancelOutside(false) //窗体外是否可点击 + + loadingDialog = loadBuilder.create() + loadingDialog!!.show() + } + + fun dismiss() { + try { + loadingDialog?.let { + if (it.isShowing) { + it.dismiss() + } + loadingDialog = null + } + } catch (e: Exception) { + } + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/recyclerview/AbstractDraggableRecycleViewAdapter.java b/app/src/main/java/com/bingce/controlnetwork/ui/widget/recyclerview/AbstractDraggableRecycleViewAdapter.java new file mode 100644 index 0000000..2362dc5 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/recyclerview/AbstractDraggableRecycleViewAdapter.java @@ -0,0 +1,173 @@ +package com.bingce.controlnetwork.ui.widget.recyclerview; + +import android.annotation.SuppressLint; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlapphelper.model.ViewItemType; + +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Objects; + +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.ui.widget.ViewFactory; +import com.bingce.controlnetwork.ui.widget.ViewFactory; + +public abstract class AbstractDraggableRecycleViewAdapter + extends RecyclerView.Adapter + implements IDragSwipeChecker { + private final List items = new ArrayList<>(); + private @Nullable + IViewHolderDragDelegate viewHolderDragDelegate; + + public AbstractDraggableRecycleViewAdapter(List itemList) { + if (itemList != null) { + this.items.addAll(itemList); + } + } + + protected void replace(int start, List data) { + if (getItemCount() > start) { + items.subList(start, getItemCount()).clear(); + } + items.addAll(data); + } + + protected int indexOf(T item) { + return items.indexOf(item); + } + + protected void remove(T item) { + items.remove(item); + } + + protected void removeAll(List item) { + items.removeAll(item); + } + + protected void insert(int index, T item) { + if (items.size() <= index) { + return; + } + items.add(index, item); + } + + protected void insertAll(List item) { + items.addAll(item); + } + + protected void refreshAll(List item) { + items.clear(); + items.addAll(item); + notifyDataSetChanged(); + } + + /** + * 一井定向使用 + * + * @param index 要插入的位置 + * @param item + */ + protected void insertForWell(int index, List item) { + if (index < 0) { + return; + } + if (index == items.size()) { + items.addAll(item); + } else if (index < items.size()) { + items.addAll(index, item); + } + } + + final protected T getItem(int position) { + if (position >= items.size()) { + return null; + } + return items.get(position); + } + + final protected void setItem(int position, T item) { + if (position >= items.size() || position < 0) { + return; + } + items.set(position, item); + } + + public List getItems() { + return Collections.unmodifiableList(items); + } + + public void setViewHolderDragDelegate(@Nullable IViewHolderDragDelegate viewHolderDragDelegate) { + this.viewHolderDragDelegate = viewHolderDragDelegate; + } + + @Override + public int getItemViewType(int position) { + return ViewItemType.draggableItem.ordinal(); + } + + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull @NotNull ViewGroup parent, int viewType) { + return Objects.requireNonNull(ViewFactory.generatorViewHolder(parent.getContext(), parent, ViewItemType.values()[viewType])); + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public void onBindViewHolder(@NonNull @NotNull RecyclerView.ViewHolder holder, int position) { + bindItem(items.get(position), holder); + View dragBar = holder.itemView.findViewById(R.id.drag_bar); + if (dragBar != null) { + dragBar.setOnTouchListener((v, event) -> { + if (event.getAction() == MotionEvent.ACTION_DOWN) { + if (viewHolderDragDelegate != null) { + viewHolderDragDelegate.startDrag(holder); + } + } + return true; + }); + } + //原先代码注释 +// if (holder instanceof DraggableTextViewHolder) { +// DraggableTextViewHolder draggableTextViewHolder = (DraggableTextViewHolder) holder; +// draggableTextViewHolder.dragBar.setOnTouchListener((v, event) -> { +// if (event.getAction() == MotionEvent.ACTION_DOWN) { +// if (viewHolderDragDelegate != null) { +// viewHolderDragDelegate.startDrag(holder); +// } +// } +// return true; +// }); +// } + } + + @Override + public int getItemCount() { + return items.size(); + } + + //交换 + public void onItemSwap(int from, int target) { + T s = items.get(from); + items.remove(from); + items.add(target, s); + notifyItemMoved(from, target); + } + + //滑动 + public void onItemRemoved(int position) { + items.remove(position); + notifyItemRemoved(position); + } + + protected abstract void bindItem(T item, RecyclerView.ViewHolder viewHolder); +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/recyclerview/IDragActionDelegate.java b/app/src/main/java/com/bingce/controlnetwork/ui/widget/recyclerview/IDragActionDelegate.java new file mode 100644 index 0000000..dc5d902 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/recyclerview/IDragActionDelegate.java @@ -0,0 +1,5 @@ +package com.bingce.controlnetwork.ui.widget.recyclerview; + +public interface IDragActionDelegate { + void startDragAction(); +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/recyclerview/IDragSwipeActionListener.java b/app/src/main/java/com/bingce/controlnetwork/ui/widget/recyclerview/IDragSwipeActionListener.java new file mode 100644 index 0000000..f4ddadb --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/recyclerview/IDragSwipeActionListener.java @@ -0,0 +1,23 @@ +package com.bingce.controlnetwork.ui.widget.recyclerview; + +public interface IDragSwipeActionListener { + /** + * 左右滑动删除操作 + * + * @param adapterPosition --被滑动的item索引 + */ + void onItemSwiped(int adapterPosition); + + /** + * 上下拖拽操作进行中,没有完成,用户手指还没离开屏幕 + * + * @param from 被拖拽item原来索引 + * @param to 被拖拽item目标索引 + */ + void onItemDragging(int from, int to); + + /** + * 上下拖拽操作完成,用户手指离开屏幕 + */ + void onItemDragCompleted(); +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/recyclerview/IDragSwipeChecker.java b/app/src/main/java/com/bingce/controlnetwork/ui/widget/recyclerview/IDragSwipeChecker.java new file mode 100644 index 0000000..b1e1bbe --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/recyclerview/IDragSwipeChecker.java @@ -0,0 +1,7 @@ +package com.bingce.controlnetwork.ui.widget.recyclerview; + +public interface IDragSwipeChecker { + boolean isItemSwipeAble(int position); + + boolean isItemDragAble(int position); +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/recyclerview/ISwipeDragListener.java b/app/src/main/java/com/bingce/controlnetwork/ui/widget/recyclerview/ISwipeDragListener.java new file mode 100644 index 0000000..ae1d0a6 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/recyclerview/ISwipeDragListener.java @@ -0,0 +1,7 @@ +package com.bingce.controlnetwork.ui.widget.recyclerview; + +public interface ISwipeDragListener { + void onItemSwap(int from, int target); + + void onItemMoved(int position); +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/recyclerview/IViewHolderDragDelegate.java b/app/src/main/java/com/bingce/controlnetwork/ui/widget/recyclerview/IViewHolderDragDelegate.java new file mode 100644 index 0000000..fa903e1 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/recyclerview/IViewHolderDragDelegate.java @@ -0,0 +1,7 @@ +package com.bingce.controlnetwork.ui.widget.recyclerview; + +import androidx.recyclerview.widget.RecyclerView; + +public interface IViewHolderDragDelegate { + void startDrag(RecyclerView.ViewHolder viewHolder); +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/recyclerview/ItemTouchHelperCallbackImpl.java b/app/src/main/java/com/bingce/controlnetwork/ui/widget/recyclerview/ItemTouchHelperCallbackImpl.java new file mode 100644 index 0000000..992731d --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/recyclerview/ItemTouchHelperCallbackImpl.java @@ -0,0 +1,105 @@ +package com.bingce.controlnetwork.ui.widget.recyclerview; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.ItemTouchHelper; +import androidx.recyclerview.widget.RecyclerView; + +import org.jetbrains.annotations.NotNull; + +public class ItemTouchHelperCallbackImpl extends ItemTouchHelper.Callback { + private final IDragSwipeActionListener listener; + private final IDragSwipeChecker dragSwipeChecker; + + public ItemTouchHelperCallbackImpl(IDragSwipeChecker dragSwipeChecker, + IDragSwipeActionListener listener) { + this.dragSwipeChecker = dragSwipeChecker; + this.listener = listener; + } + + @Override + public int getMovementFlags(@NonNull @NotNull RecyclerView recyclerView, @NonNull @NotNull RecyclerView.ViewHolder viewHolder) { + int dragFlag; //拖动标记 + int swipeFlags; //滑动标记 + //如果是表格布局,则可以上下左右的拖动,但是不能滑动 + if (recyclerView.getLayoutManager() instanceof GridLayoutManager) { + dragFlag = ItemTouchHelper.UP | + ItemTouchHelper.DOWN | + ItemTouchHelper.LEFT | + ItemTouchHelper.RIGHT; + swipeFlags = 0; + } else {//如果是线性布局,那么只能上下拖动,只能左右滑动 + dragFlag = ItemTouchHelper.UP | ItemTouchHelper.DOWN; + swipeFlags = ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT; + } + + int position = viewHolder.getAdapterPosition(); + if (dragSwipeChecker != null && !dragSwipeChecker.isItemDragAble(position)) { + dragFlag = 0; + } + if (dragSwipeChecker != null && !dragSwipeChecker.isItemSwipeAble(position)) { + swipeFlags = 0; + } + + //通过makeMovementFlags生成最终结果 + return makeMovementFlags(dragFlag, swipeFlags); + } + + + @Override + public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) { + //被拖动的item位置 + int fromPosition = viewHolder.getLayoutPosition(); + //他的目标位置 + int targetPosition = target.getLayoutPosition(); + if (!isDragValidate(recyclerView, targetPosition, fromPosition)) { + return false; + } + if (listener != null) { + listener.onItemDragging(fromPosition, targetPosition); + } + return true; + } + + final protected boolean isDragValidate(@NonNull RecyclerView recyclerView, int targetPosition, int fromPosition) { + RecyclerView.Adapter adapter = recyclerView.getAdapter(); + if (adapter != null) { + int targetType = adapter.getItemViewType(targetPosition); + int fromType = adapter.getItemViewType(fromPosition); + return targetType == fromType && targetPosition > 1; + } + return true; + } + + @Override + public void onSwiped(@NonNull @NotNull RecyclerView.ViewHolder viewHolder, int direction) { + if (listener != null) { + listener.onItemSwiped(viewHolder.getAdapterPosition()); + } + } + + @Override + public boolean isLongPressDragEnabled() { + return false; + } + + private boolean listener2DragComplete = false; + + @Override + public void onSelectedChanged(@Nullable RecyclerView.ViewHolder viewHolder, int actionState) { + super.onSelectedChanged(viewHolder, actionState); + if (actionState == ItemTouchHelper.ACTION_STATE_DRAG) { + listener2DragComplete = true; + } else if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) { + listener2DragComplete = false; + } else if (actionState == ItemTouchHelper.ACTION_STATE_IDLE) { + if (listener2DragComplete) { + if (listener != null) { + listener.onItemDragCompleted(); + } + } + listener2DragComplete = false; + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/recyclerview/SwipeDraggableRecyclerViewUtil.java b/app/src/main/java/com/bingce/controlnetwork/ui/widget/recyclerview/SwipeDraggableRecyclerViewUtil.java new file mode 100644 index 0000000..2a8f8b4 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/recyclerview/SwipeDraggableRecyclerViewUtil.java @@ -0,0 +1,79 @@ +package com.bingce.controlnetwork.ui.widget.recyclerview; + +import android.content.Context; + +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; +import androidx.recyclerview.widget.ItemTouchHelper; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.fragment.TipsWith2OptionFragment; + +public class SwipeDraggableRecyclerViewUtil { + public static void setup(AbstractDraggableRecycleViewAdapter adapter, + RecyclerView recyclerView, + FragmentManager fragmentManager, + LifecycleOwner lifecycleOwner, + IStationPointOperatorListener operatorListener, + Context context) { + ItemTouchHelperCallbackImpl callback = new ItemTouchHelperCallbackImpl(adapter, new IDragSwipeActionListener() { + @Override + public void onItemSwiped(int adapterPosition) { + TipsWith2OptionFragment.tips(fragmentManager, lifecycleOwner, + null, null, + context.getString(R.string.tips_r_u_sure_delete_item), + new TipsWith2OptionFragment.IOperatorCallback() { + @Override + public void onConfirm() { + if (adapter != null) { + adapter.onItemRemoved(adapterPosition); + } + if (operatorListener != null) { + operatorListener.onItemRemoved(adapterPosition); + } + } + + @Override + public void onOption() { + } + + @Override + public void onCancel() { + if (adapter != null) { + adapter.notifyItemChanged(adapterPosition); + } + } + + @Override + public void onIgnore() { + if (adapter != null) { + adapter.notifyItemChanged(adapterPosition); + } + } + }); + } + + @Override + public void onItemDragging(int from, int to) { + adapter.onItemSwap(from, to); + } + + @Override + public void onItemDragCompleted() { + if (operatorListener != null) { + operatorListener.onItemDragCompleted(); + } + } + }); + ItemTouchHelper helper = new ItemTouchHelper(callback); + adapter.setViewHolderDragDelegate(helper::startDrag); + helper.attachToRecyclerView(recyclerView); + } + + public interface IStationPointOperatorListener { + void onItemRemoved(int adapterPosition); + + void onItemDragCompleted(); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/TreeNode.java b/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/TreeNode.java new file mode 100644 index 0000000..af8c986 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/TreeNode.java @@ -0,0 +1,231 @@ +/* + * Copyright 2016 - 2017 ShineM (Xinyuan) + * + * 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. + */ + +package com.bingce.controlnetwork.ui.widget.treeview; + +import com.bingce.controlnetwork.ui.widget.treeview.helper.TreeHelper; + +import java.util.ArrayList; +import java.util.List; + +import com.bingce.controlnetwork.ui.widget.treeview.helper.TreeHelper; + + +/** + * Created by xinyuanzhong on 2017/4/20. + */ + +public class TreeNode { + private int level; + + private Value value; + + private TreeNode parent; + + private List children; + + private int index; + + private boolean expanded; + + private boolean selected; + + private boolean itemClickEnable = true; + + private boolean enable = true; + + public TreeNode(Value value) { + this.value = value; + this.children = new ArrayList<>(); + } + + public TreeNode(Value value, int level) { + this(value); + setLevel(level); + } + + public static TreeNode root() { + TreeNode treeNode = new TreeNode(null); + return treeNode; + } + + public void addChild(TreeNode treeNode) { + if (treeNode == null) { + return; + } + children.add(treeNode); + treeNode.setIndex(getChildren().size()); + treeNode.setParent(this); + } + + + public void removeChild(TreeNode treeNode) { + if (treeNode == null || getChildren().size() < 1) { + return; + } + if (getChildren().contains(treeNode)) { + getChildren().remove(treeNode); + } + } + + public boolean isLastChild() { + if (parent == null) { + return false; + } + List children = parent.getChildren(); + return children.size() > 0 && children.indexOf(this) == children.size() - 1; + } + + public boolean isRoot() { + return parent == null; + } + + public int getLevel() { + return level; + } + + public void setLevel(int level) { + this.level = level; + } + + public Value getValue() { + return value; + } + + public void setValue(Value value) { + this.value = value; + } + + public TreeNode getParent() { + return parent; + } + + public void setParent(TreeNode parent) { + this.parent = parent; + } + + public List getChildren() { + if (children == null) { + return new ArrayList<>(); + } + return children; + } + + public List getSelectedChildren() { + List selectedChildren = new ArrayList<>(); + for (TreeNode child : getChildren()) { + if (child.isSelected()) { + selectedChildren.add(child); + } + } + return selectedChildren; + } + + public void setChildren(List children) { + if (children == null) { + return; + } + this.children = new ArrayList<>(); + for (TreeNode child : children) { + addChild(child); + } + } + + /** + * Updating the list of children while maintaining the tree structure + */ + public void updateChildren(List children) { + List expands = new ArrayList<>(); + List allNodesPre = TreeHelper.getAllNodes(this); + for (TreeNode node : allNodesPre) { + expands.add(node.isExpanded()); + } + + this.children = children; + List allNodes = TreeHelper.getAllNodes(this); + if (allNodes.size() == expands.size()) { + for (int i = 0; i < allNodes.size(); i++) { + allNodes.get(i).setExpanded(expands.get(i)); + } + } + } + + public void setExpanded(boolean expanded) { + this.expanded = expanded; + } + + public boolean isExpanded() { + return expanded; + } + + public boolean isEnable() { + return enable; + } + + public void setEnable(boolean enable) { + this.enable = enable; + } + + public boolean hasChild() { + return children.size() > 0; + } + + public boolean isItemClickEnable() { + return itemClickEnable; + } + + public void setItemClickEnable(boolean itemClickEnable) { + this.itemClickEnable = itemClickEnable; + } + + public String getId() { + return getLevel() + "," + getIndex(); + } + + public int getIndex() { + return index; + } + + public void setIndex(int index) { + this.index = index; + } + + public boolean isSelected() { + return selected; + } + + public void setSelected(boolean selected) { + this.selected = selected; + } + + + public static class Value { + private final Object value; + private final String id; + + public Value(Object value, String id) { + this.value = value; + this.id = id; + } + + public Object getValue() { + return value; + } + + public String getId() { + return id; + } + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/TreeView.java b/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/TreeView.java new file mode 100644 index 0000000..92aefa7 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/TreeView.java @@ -0,0 +1,214 @@ +/* + * Copyright 2016 - 2017 ShineM (Xinyuan) + * + * 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. + */ + +package com.bingce.controlnetwork.ui.widget.treeview; + +import android.content.Context; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; +import androidx.recyclerview.widget.SimpleItemAnimator; + +import com.bingce.controlnetwork.ui.widget.treeview.base.BaseNodeViewFactory; +import com.bingce.controlnetwork.ui.widget.treeview.base.SelectableTreeAction; +import com.bingce.controlnetwork.ui.widget.treeview.helper.TreeHelper; + +import java.util.List; + +import com.bingce.controlnetwork.ui.widget.treeview.base.BaseNodeViewFactory; +import com.bingce.controlnetwork.ui.widget.treeview.base.SelectableTreeAction; +import com.bingce.controlnetwork.ui.widget.treeview.helper.TreeHelper; + + +/** + * Created by xinyuanzhong on 2017/4/20. + */ + +public class TreeView implements SelectableTreeAction { + private final TreeNode root; + + private final Context context; + + private final BaseNodeViewFactory baseNodeViewFactory; + + private RecyclerView rootView; + + private TreeViewAdapter adapter; + + private boolean itemSelectable = true; + + public TreeView(@NonNull TreeNode root, @NonNull Context context, @NonNull BaseNodeViewFactory baseNodeViewFactory) { + this.root = root; + this.context = context; + this.baseNodeViewFactory = baseNodeViewFactory; + if (baseNodeViewFactory == null) { + throw new IllegalArgumentException("You must assign a BaseNodeViewFactory!"); + } + } + + // public View getView() { +// if (rootView == null) { +// this.rootView = buildRootView(); +// } +// +// return rootView; +// } + public void setup(RecyclerView recyclerView) { + buildRootView(recyclerView); + } + + @NonNull + private void buildRootView(RecyclerView recyclerView) { +// private RecyclerView buildRootView() { +// RecyclerView recyclerView = new RecyclerView(context); + /** + * disable multi touch event to prevent terrible data set error when calculate list. + */ + recyclerView.setMotionEventSplittingEnabled(false); + ((SimpleItemAnimator) recyclerView.getItemAnimator()).setSupportsChangeAnimations(false); +// recyclerView.setItemAnimator(null); + + recyclerView.setLayoutManager(new LinearLayoutManager(context, RecyclerView.VERTICAL, false)); + adapter = new TreeViewAdapter(context, root, baseNodeViewFactory); + adapter.setTreeView(this); + recyclerView.setAdapter(adapter); +// return recyclerView; + } + + @Override + public void expandAll() { + if (root == null) { + return; + } + TreeHelper.expandAll(root); + + refreshTreeView(); + } + + + public void refreshTreeView() { + if (rootView != null) { + ((TreeViewAdapter) rootView.getAdapter()).refreshView(); + } + } + + public void updateTreeView() { + if (rootView != null) { + rootView.getAdapter().notifyDataSetChanged(); + } + } + + @Override + public void expandNode(TreeNode treeNode) { + adapter.expandNode(treeNode); + } + + @Override + public void expandLevel(int level) { + TreeHelper.expandLevel(root, level); + + refreshTreeView(); + } + + @Override + public void collapseAll() { + if (root == null) { + return; + } + TreeHelper.collapseAll(root); + + refreshTreeView(); + } + + @Override + public void collapseNode(TreeNode treeNode) { + adapter.collapseNode(treeNode); + } + + @Override + public void collapseLevel(int level) { + TreeHelper.collapseLevel(root, level); + + refreshTreeView(); + } + + @Override + public void toggleNode(TreeNode treeNode) { + if (treeNode.isExpanded()) { + collapseNode(treeNode); + } else { + expandNode(treeNode); + } + } + + @Override + public void deleteNode(TreeNode node) { + adapter.deleteNode(node); + } + + @Override + public void addNode(TreeNode parent, TreeNode treeNode) { + parent.addChild(treeNode); + + refreshTreeView(); + } + + @Override + public List getAllNodes() { + return TreeHelper.getAllNodes(root); + } + + @Override + public void selectNode(TreeNode treeNode) { + if (treeNode != null) { + adapter.selectNode(true, treeNode); + } + } + + @Override + public void deselectNode(TreeNode treeNode) { + if (treeNode != null) { + adapter.selectNode(false, treeNode); + } + } + + @Override + public void selectAll() { + TreeHelper.selectNodeAndChild(root, true); + + refreshTreeView(); + } + + @Override + public void deselectAll() { + TreeHelper.selectNodeAndChild(root, false); + + refreshTreeView(); + } + + @Override + public List getSelectedNodes() { + return TreeHelper.getSelectedNodes(root); + } + + public boolean isItemSelectable() { + return itemSelectable; + } + + public void setItemSelectable(boolean itemSelectable) { + this.itemSelectable = itemSelectable; + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/TreeViewAdapter.java b/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/TreeViewAdapter.java new file mode 100644 index 0000000..cdd7558 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/TreeViewAdapter.java @@ -0,0 +1,286 @@ +/* + * Copyright 2016 - 2017 ShineM (Xinyuan) + * + * 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. + */ + +package com.bingce.controlnetwork.ui.widget.treeview; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Checkable; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlnetwork.ui.widget.treeview.base.BaseNodeViewBinder; +import com.bingce.controlnetwork.ui.widget.treeview.base.BaseNodeViewFactory; +import com.bingce.controlnetwork.ui.widget.treeview.base.CheckableNodeViewBinder; +import com.bingce.controlnetwork.ui.widget.treeview.helper.TreeHelper; + +import java.util.ArrayList; +import java.util.List; + +import com.bingce.controlnetwork.ui.widget.treeview.base.BaseNodeViewBinder; +import com.bingce.controlnetwork.ui.widget.treeview.base.BaseNodeViewFactory; +import com.bingce.controlnetwork.ui.widget.treeview.base.CheckableNodeViewBinder; +import com.bingce.controlnetwork.ui.widget.treeview.helper.TreeHelper; + +/** + * Created by xinyuanzhong on 2017/4/21. + */ + +public class TreeViewAdapter extends RecyclerView.Adapter { + + private final Context context; + + private final TreeNode root; + + private final List expandedNodeList; + + private final BaseNodeViewFactory baseNodeViewFactory; + + private TreeView treeView; + + TreeViewAdapter(Context context, TreeNode root, + @NonNull BaseNodeViewFactory baseNodeViewFactory) { + this.context = context; + this.root = root; + this.baseNodeViewFactory = baseNodeViewFactory; + + this.expandedNodeList = new ArrayList<>(); + + buildExpandedNodeList(); + } + + private void buildExpandedNodeList() { + expandedNodeList.clear(); + + for (TreeNode child : root.getChildren()) { + insertNode(expandedNodeList, child); + } + } + + private void insertNode(List nodeList, TreeNode treeNode) { + nodeList.add(treeNode); + + if (!treeNode.hasChild()) { + return; + } + if (treeNode.isExpanded()) { + for (TreeNode child : treeNode.getChildren()) { + insertNode(nodeList, child); + } + } + } + + @Override + public int getItemViewType(int position) { + // return expandedNodeList.get(position).getLevel(); // this old code row used to always return the level + TreeNode treeNode = expandedNodeList.get(position); + int viewType = this.baseNodeViewFactory.getViewType(treeNode); // default implementation returns the three node level but it can be overridden + return viewType; + } + + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int level) { + View view = LayoutInflater.from(context).inflate(baseNodeViewFactory.getNodeLayoutId(level), parent, false); + + BaseNodeViewBinder nodeViewBinder = baseNodeViewFactory.getNodeViewBinder(view, level); + nodeViewBinder.setTreeView(treeView); + return nodeViewBinder; + } + + @Override + public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder holder, final int position) { + final View nodeView = holder.itemView; + final TreeNode treeNode = expandedNodeList.get(position); + final BaseNodeViewBinder viewBinder = (BaseNodeViewBinder) holder; + + if (viewBinder.getToggleTriggerViewId() != 0) { + View triggerToggleView = nodeView.findViewById(viewBinder.getToggleTriggerViewId()); + + if (triggerToggleView != null) { + triggerToggleView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + onNodeToggled(treeNode); + viewBinder.onNodeToggled(treeNode, treeNode.isExpanded()); + } + }); + } + } else if (treeNode.isItemClickEnable()) { + nodeView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + onNodeToggled(treeNode); + viewBinder.onNodeToggled(treeNode, treeNode.isExpanded()); + } + }); + } + + if (viewBinder instanceof CheckableNodeViewBinder) { + setupCheckableItem(nodeView, treeNode, (CheckableNodeViewBinder) viewBinder); + } + + viewBinder.bindView(treeNode); + } + + private void setupCheckableItem(View nodeView, + final TreeNode treeNode, + final CheckableNodeViewBinder viewBinder) { + final View view = nodeView.findViewById(viewBinder.getCheckableViewId()); + + if (view instanceof Checkable) { + final Checkable checkableView = (Checkable) view; + + view.setEnabled(treeNode.isEnable()); + if (treeNode.isEnable()) { + checkableView.setChecked(treeNode.isSelected()); + + view.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + boolean checked = checkableView.isChecked(); + selectNode(checked, treeNode); + viewBinder.onNodeSelectedChanged(treeNode, checked); + } + }); + } + } else { + throw new ClassCastException("The getCheckableViewId() " + + "must return a CheckBox's id"); + } + } + + void selectNode(boolean checked, TreeNode treeNode) { + treeNode.setSelected(checked); + + selectChildren(treeNode, checked); + selectParentIfNeed(treeNode, checked); + } + + private void selectChildren(TreeNode treeNode, boolean checked) { + List impactedChildren = TreeHelper.selectNodeAndChild(treeNode, checked); + int index = expandedNodeList.indexOf(treeNode); + if (index != -1 && impactedChildren.size() > 0) { + notifyItemRangeChanged(index, impactedChildren.size() + 1); + } + } + + private void selectParentIfNeed(TreeNode treeNode, boolean checked) { + List impactedParents = TreeHelper.selectParentIfNeedWhenNodeSelected(treeNode, checked); + if (impactedParents.size() > 0) { + for (TreeNode parent : impactedParents) { + int position = expandedNodeList.indexOf(parent); + if (position != -1) notifyItemChanged(position); + } + } + } + + private void onNodeToggled(TreeNode treeNode) { + treeNode.setExpanded(!treeNode.isExpanded()); + + if (treeNode.isExpanded()) { + expandNode(treeNode); + } else { + collapseNode(treeNode); + } + } + + @Override + public int getItemCount() { + return expandedNodeList == null ? 0 : expandedNodeList.size(); + } + + /** + * Refresh all,this operation is only used for refreshing list when a large of nodes have + * changed value or structure because it take much calculation. + */ + void refreshView() { + buildExpandedNodeList(); + notifyDataSetChanged(); + } + + // Insert a node list after index. + private void insertNodesAtIndex(int index, List additionNodes) { + if (index < 0 || index > expandedNodeList.size() - 1 || additionNodes == null) { + return; + } + expandedNodeList.addAll(index + 1, additionNodes); + notifyItemRangeInserted(index + 1, additionNodes.size()); + } + + //Remove a node list after index. + private void removeNodesAtIndex(int index, List removedNodes) { + if (index < 0 || index > expandedNodeList.size() - 1 || removedNodes == null) { + return; + } + expandedNodeList.removeAll(removedNodes); + notifyItemRangeRemoved(index + 1, removedNodes.size()); + } + + /** + * Expand node. This operation will keep the structure of children(not expand children) + */ + void expandNode(TreeNode treeNode) { + if (treeNode == null) { + return; + } + List additionNodes = TreeHelper.expandNode(treeNode, false); + int index = expandedNodeList.indexOf(treeNode); + + insertNodesAtIndex(index, additionNodes); + } + + + /** + * Collapse node. This operation will keep the structure of children(not collapse children) + */ + void collapseNode(TreeNode treeNode) { + if (treeNode == null) { + return; + } + List removedNodes = TreeHelper.collapseNode(treeNode, false); + int index = expandedNodeList.indexOf(treeNode); + + removeNodesAtIndex(index, removedNodes); + } + + /** + * Delete a node from list.This operation will also delete its children. + */ + void deleteNode(TreeNode node) { + if (node == null || node.getParent() == null) { + return; + } + List allNodes = TreeHelper.getAllNodes(root); + if (allNodes.contains(node)) { + node.getParent().removeChild(node); + } + + //remove children form list before delete + collapseNode(node); + + int index = expandedNodeList.indexOf(node); + if (index != -1) { + expandedNodeList.remove(node); + } + notifyItemRemoved(index); + } + + void setTreeView(TreeView treeView) { + this.treeView = treeView; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/base/BaseNodeViewBinder.java b/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/base/BaseNodeViewBinder.java new file mode 100644 index 0000000..88cbd09 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/base/BaseNodeViewBinder.java @@ -0,0 +1,70 @@ +/* + * Copyright 2016 - 2017 ShineM (Xinyuan) + * + * 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. + */ + +package com.bingce.controlnetwork.ui.widget.treeview.base; + +import android.view.View; + +import androidx.recyclerview.widget.RecyclerView; + +import com.bingce.controlnetwork.ui.widget.treeview.TreeNode; +import com.bingce.controlnetwork.ui.widget.treeview.TreeView; + + +/** + * Created by zxy on 17/4/23. + */ + +public abstract class BaseNodeViewBinder extends RecyclerView.ViewHolder { + /** + * This reference of TreeView make BaseNodeViewBinder has the ability + * to expand node or select node. + */ + protected TreeView treeView; + + public BaseNodeViewBinder(View itemView) { + super(itemView); + } + + public void setTreeView(TreeView treeView) { + this.treeView = treeView; + } + + /** + * Bind your data to view,you can get the data from treeNode by getValue() + * + * @param treeNode Node data + */ + public abstract void bindView(TreeNode treeNode); + + /** + * if you do not want toggle the node when click whole item view,then you can assign a view to + * trigger the toggle action + * + * @return The assigned view id to trigger expand or collapse. + */ + public int getToggleTriggerViewId() { + return 0; + } + + /** + * Callback when a toggle action happened (only by clicked) + * + * @param treeNode The toggled node + * @param expand Expanded or collapsed + */ + public void onNodeToggled(TreeNode treeNode, boolean expand) { + //empty + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/base/BaseNodeViewFactory.java b/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/base/BaseNodeViewFactory.java new file mode 100644 index 0000000..9c016d5 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/base/BaseNodeViewFactory.java @@ -0,0 +1,58 @@ +/* + * Copyright 2016 - 2017 ShineM (Xinyuan) + * + * 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. + */ + +package com.bingce.controlnetwork.ui.widget.treeview.base; + +import android.view.View; + +import com.bingce.controlnetwork.ui.widget.treeview.TreeNode; + + +/** + * Created by zxy on 17/4/23. + */ + +public abstract class BaseNodeViewFactory { + + /** + * The default implementation below behaves as in previous version when TreeViewAdapter.getItemViewType always returned the level, + * but you can override it if you want some other viewType value to become the parameter to the method getNodeViewBinder. + * + * @param treeNode + * @return + */ + public int getViewType(TreeNode treeNode) { + return treeNode.getLevel(); + } + + /** + * If you want build a tree view,you must implement this factory method + * + * @param view The parameter for BaseNodeViewBinder's constructor, do not use this for other + * purpose! + * @param viewType The viewType value is the treeNode level in the default implementation. + * @return BaseNodeViewBinder + */ + public abstract BaseNodeViewBinder getNodeViewBinder(View view, int viewType); + + + /** + * If you want build a tree view,you must implement this factory method + * + * @param level Level of view, returned from {@link #getViewType} + * @return node layout id + */ + public abstract int getNodeLayoutId(int level); + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/base/BaseTreeAction.java b/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/base/BaseTreeAction.java new file mode 100644 index 0000000..7f18cdb --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/base/BaseTreeAction.java @@ -0,0 +1,50 @@ +/* + * Copyright 2016 - 2017 ShineM (Xinyuan) + * + * 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. + */ + +package com.bingce.controlnetwork.ui.widget.treeview.base; + +import java.util.List; + +import com.bingce.controlnetwork.ui.widget.treeview.TreeNode; + +/** + * Created by xinyuanzhong on 2017/4/20. + */ + +public interface BaseTreeAction { + void expandAll(); + + void expandNode(TreeNode treeNode); + + void expandLevel(int level); + + void collapseAll(); + + void collapseNode(TreeNode treeNode); + + void collapseLevel(int level); + + void toggleNode(TreeNode treeNode); + + void deleteNode(TreeNode node); + + void addNode(TreeNode parent, TreeNode treeNode); + + List getAllNodes(); + + // TODO: 17/4/30 + // 1.add node at position + // 2.add slide delete or other operations + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/base/CheckableNodeViewBinder.java b/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/base/CheckableNodeViewBinder.java new file mode 100644 index 0000000..1c80515 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/base/CheckableNodeViewBinder.java @@ -0,0 +1,47 @@ +/* + * Copyright 2016 - 2017 ShineM (Xinyuan) + * + * 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. + */ + +package com.bingce.controlnetwork.ui.widget.treeview.base; + +import android.view.View; + +import com.bingce.controlnetwork.ui.widget.treeview.TreeNode; + +/** + * Created by xinyuanzhong on 2017/4/27. + */ + +public abstract class CheckableNodeViewBinder extends BaseNodeViewBinder { + + public CheckableNodeViewBinder(View itemView) { + super(itemView); + } + + /** + * Get the checkable view id. MUST BE A Checkable type! + * + * @return + */ + public abstract int getCheckableViewId(); + + /** + * Do something when a node select or deselect(only triggered by clicked) + * + * @param treeNode + * @param selected + */ + public void onNodeSelectedChanged(TreeNode treeNode, boolean selected) { + /*empty*/ + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/base/SelectableTreeAction.java b/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/base/SelectableTreeAction.java new file mode 100644 index 0000000..1107280 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/base/SelectableTreeAction.java @@ -0,0 +1,35 @@ +/* + * Copyright 2016 - 2017 ShineM (Xinyuan) + * + * 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. + */ + +package com.bingce.controlnetwork.ui.widget.treeview.base; + +import java.util.List; + +import com.bingce.controlnetwork.ui.widget.treeview.TreeNode; + +/** + * Created by xinyuanzhong on 2017/4/27. + */ + +public interface SelectableTreeAction extends BaseTreeAction { + void selectNode(TreeNode treeNode); + + void deselectNode(TreeNode treeNode); + + void selectAll(); + + void deselectAll(); + + List getSelectedNodes(); +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/custom/FirstLevelNodeViewBinder.java b/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/custom/FirstLevelNodeViewBinder.java new file mode 100644 index 0000000..37bd6fd --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/custom/FirstLevelNodeViewBinder.java @@ -0,0 +1,45 @@ +package com.bingce.controlnetwork.ui.widget.treeview.custom; + +import android.view.View; +import android.widget.TextView; + +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.ui.widget.treeview.base.CheckableNodeViewBinder; +import com.bingce.controlnetwork.ui.widget.treeview.TreeNode; +import com.bingce.controlnetwork.ui.widget.treeview.base.CheckableNodeViewBinder; + +/** + * Created by zxy on 17/4/23. + */ + +public class FirstLevelNodeViewBinder extends CheckableNodeViewBinder { + TextView textView; + View imageView; + + public FirstLevelNodeViewBinder(View itemView) { + super(itemView); + textView = itemView.findViewById(R.id.node_name_view); + imageView = itemView.findViewById(R.id.arrow_img); + } + + @Override + public int getCheckableViewId() { + return R.id.checkBox; + } + + @Override + public void bindView(final TreeNode treeNode) { + textView.setText(treeNode.getValue().getValue().toString()); + imageView.setRotation(treeNode.isExpanded() ? 90 : 0); + imageView.setVisibility(treeNode.hasChild() ? View.VISIBLE : View.INVISIBLE); + } + + @Override + public void onNodeToggled(TreeNode treeNode, boolean expand) { + if (expand) { + imageView.animate().rotation(90).setDuration(200).start(); + } else { + imageView.animate().rotation(0).setDuration(200).start(); + } + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/custom/MyNodeViewFactory.java b/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/custom/MyNodeViewFactory.java new file mode 100644 index 0000000..383e451 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/custom/MyNodeViewFactory.java @@ -0,0 +1,43 @@ +package com.bingce.controlnetwork.ui.widget.treeview.custom; + +import android.view.View; + +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.ui.widget.treeview.base.BaseNodeViewBinder; +import com.bingce.controlnetwork.ui.widget.treeview.base.BaseNodeViewFactory; + + +/** + * Created by zxy on 17/4/23. + */ + +public class MyNodeViewFactory extends BaseNodeViewFactory { + + @Override + public BaseNodeViewBinder getNodeViewBinder(View view, int level) { + switch (level) { + case 0: + return new FirstLevelNodeViewBinder(view); + case 1: + return new SecondLevelNodeViewBinder(view); + case 2: + return new ThirdLevelNodeViewBinder(view); + default: + return null; + } + } + + @Override + public int getNodeLayoutId(int level) { + switch (level) { + case 0: + return R.layout.item_first_level; + case 1: + return R.layout.item_second_level; + case 2: + return R.layout.item_third_level; + default: + return 0; + } + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/custom/SecondLevelNodeViewBinder.java b/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/custom/SecondLevelNodeViewBinder.java new file mode 100644 index 0000000..9503e02 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/custom/SecondLevelNodeViewBinder.java @@ -0,0 +1,51 @@ +package com.bingce.controlnetwork.ui.widget.treeview.custom; + +import android.view.View; +import android.widget.TextView; + +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.ui.widget.treeview.base.CheckableNodeViewBinder; +import com.bingce.controlnetwork.ui.widget.treeview.TreeNode; +import com.bingce.controlnetwork.ui.widget.treeview.base.CheckableNodeViewBinder; + +/** + * Created by zxy on 17/4/23. + */ + +public class SecondLevelNodeViewBinder extends CheckableNodeViewBinder { + + TextView textView; + View imageView; + + public SecondLevelNodeViewBinder(View itemView) { + super(itemView); + textView = itemView.findViewById(R.id.node_name_view); + imageView = itemView.findViewById(R.id.arrow_img); + } + +// @Override +// public int getLayoutId() { +// return R.layout.item_second_level; +// } + + @Override + public int getCheckableViewId() { + return R.id.checkBox; + } + + @Override + public void bindView(final TreeNode treeNode) { + textView.setText(treeNode.getValue().getValue().toString()); + imageView.setRotation(treeNode.isExpanded() ? 90 : 0); + imageView.setVisibility(treeNode.hasChild() ? View.VISIBLE : View.INVISIBLE); + } + + @Override + public void onNodeToggled(TreeNode treeNode, boolean expand) { + if (expand) { + imageView.animate().rotation(90).setDuration(200).start(); + } else { + imageView.animate().rotation(0).setDuration(200).start(); + } + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/custom/ThirdLevelNodeViewBinder.java b/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/custom/ThirdLevelNodeViewBinder.java new file mode 100644 index 0000000..ae73150 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/custom/ThirdLevelNodeViewBinder.java @@ -0,0 +1,43 @@ +package com.bingce.controlnetwork.ui.widget.treeview.custom; + +import android.view.View; +import android.widget.Checkable; +import android.widget.TextView; + +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.ui.widget.treeview.base.CheckableNodeViewBinder; +import com.bingce.controlnetwork.ui.widget.treeview.TreeNode; +import com.bingce.controlnetwork.ui.widget.treeview.base.CheckableNodeViewBinder; + +/** + * Created by zxy on 17/4/23. + */ + +public class ThirdLevelNodeViewBinder extends CheckableNodeViewBinder { + TextView textView; + + public ThirdLevelNodeViewBinder(View itemView) { + super(itemView); + textView = itemView.findViewById(R.id.node_name_view); + } + + @Override + public int getCheckableViewId() { + return R.id.checkBox; + } + + @Override + public void bindView(TreeNode treeNode) { + textView.setText(treeNode.getValue().getValue().toString()); + } + + @Override + public void onNodeToggled(TreeNode treeNode, boolean expand) { + final View view = itemView.findViewById(getCheckableViewId()); + if (view instanceof Checkable && treeNode.isEnable()) { + final Checkable checkableView = (Checkable) view; + checkableView.setChecked(!checkableView.isChecked()); + treeNode.setSelected(checkableView.isChecked()); + } + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/helper/TreeHelper.java b/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/helper/TreeHelper.java new file mode 100644 index 0000000..ada7a75 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/ui/widget/treeview/helper/TreeHelper.java @@ -0,0 +1,290 @@ +/* + * Copyright 2016 - 2017 ShineM (Xinyuan) + * + * 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. + */ + +package com.bingce.controlnetwork.ui.widget.treeview.helper; + +import java.util.ArrayList; +import java.util.List; + +import com.bingce.controlnetwork.ui.widget.treeview.TreeNode; + +/** + * Created by xinyuanzhong on 2017/4/27. + */ + +public class TreeHelper { + + public static void expandAll(TreeNode node) { + if (node == null) { + return; + } + expandNode(node, true); + } + + /** + * Expand node and calculate the visible addition nodes. + * + * @param treeNode target node to expand + * @param includeChild should expand child + * @return the visible addition nodes + */ + public static List expandNode(TreeNode treeNode, boolean includeChild) { + List expandChildren = new ArrayList<>(); + + if (treeNode == null) { + return expandChildren; + } + + treeNode.setExpanded(true); + + if (!treeNode.hasChild()) { + return expandChildren; + } + + for (TreeNode child : treeNode.getChildren()) { + expandChildren.add(child); + + if (includeChild || child.isExpanded()) { + expandChildren.addAll(expandNode(child, includeChild)); + } + } + + return expandChildren; + } + + /** + * Expand the same deep(level) nodes. + * + * @param root the tree root + * @param level the level to expand + */ + public static void expandLevel(TreeNode root, int level) { + if (root == null) { + return; + } + + for (TreeNode child : root.getChildren()) { + if (child.getLevel() == level) { + expandNode(child, false); + } else { + expandLevel(child, level); + } + } + } + + public static void collapseAll(TreeNode node) { + if (node == null) { + return; + } + for (TreeNode child : node.getChildren()) { + performCollapseNode(child, true); + } + } + + /** + * Collapse node and calculate the visible removed nodes. + * + * @param node target node to collapse + * @param includeChild should collapse child + * @return the visible addition nodes before remove + */ + public static List collapseNode(TreeNode node, boolean includeChild) { + List treeNodes = performCollapseNode(node, includeChild); + node.setExpanded(false); + return treeNodes; + } + + private static List performCollapseNode(TreeNode node, boolean includeChild) { + List collapseChildren = new ArrayList<>(); + + if (node == null) { + return collapseChildren; + } + if (includeChild) { + node.setExpanded(false); + } + for (TreeNode child : node.getChildren()) { + collapseChildren.add(child); + + if (child.isExpanded()) { + collapseChildren.addAll(performCollapseNode(child, includeChild)); + } else if (includeChild) { + performCollapseNodeInner(child); + } + } + + return collapseChildren; + } + + /** + * Collapse all children node recursive + * + * @param node target node to collapse + */ + private static void performCollapseNodeInner(TreeNode node) { + if (node == null) { + return; + } + node.setExpanded(false); + for (TreeNode child : node.getChildren()) { + performCollapseNodeInner(child); + } + } + + public static void collapseLevel(TreeNode root, int level) { + if (root == null) { + return; + } + for (TreeNode child : root.getChildren()) { + if (child.getLevel() == level) { + collapseNode(child, false); + } else { + collapseLevel(child, level); + } + } + } + + public static List getAllNodes(TreeNode root) { + List allNodes = new ArrayList<>(); + + fillNodeList(allNodes, root); + allNodes.remove(root); + + return allNodes; + } + + private static void fillNodeList(List treeNodes, TreeNode treeNode) { + treeNodes.add(treeNode); + + if (treeNode.hasChild()) { + for (TreeNode child : treeNode.getChildren()) { + fillNodeList(treeNodes, child); + } + } + } + + /** + * Select the node and node's children,return the visible nodes + */ + public static List selectNodeAndChild(TreeNode treeNode, boolean select) { + List expandChildren = new ArrayList<>(); + + if (treeNode == null) { + return expandChildren; + } + + treeNode.setSelected(select); + + if (!treeNode.hasChild()) { + return expandChildren; + } + + if (treeNode.isExpanded()) { + for (TreeNode child : treeNode.getChildren()) { + expandChildren.add(child); + + if (child.isExpanded()) { + expandChildren.addAll(selectNodeAndChild(child, select)); + } else { + selectNodeInner(child, select); + } + } + } else { + selectNodeInner(treeNode, select); + } + return expandChildren; + } + + private static void selectNodeInner(TreeNode treeNode, boolean select) { + if (treeNode == null) { + return; + } + treeNode.setSelected(select); + if (treeNode.hasChild()) { + for (TreeNode child : treeNode.getChildren()) { + selectNodeInner(child, select); + } + } + } + + /** + * Select parent when all the brothers have been selected, otherwise deselect parent, + * and check the grand parent recursive. + */ + public static List selectParentIfNeedWhenNodeSelected(TreeNode treeNode, boolean select) { + List impactedParents = new ArrayList<>(); + if (treeNode == null) { + return impactedParents; + } + + //ensure that the node's level is bigger than 1(first level is 1) + TreeNode parent = treeNode.getParent(); + if (parent == null || parent.getParent() == null) { + return impactedParents; + } + + List brothers = parent.getChildren(); + int selectedBrotherCount = 0; + for (TreeNode brother : brothers) { + if (brother.isSelected()) selectedBrotherCount++; + } + + if (select && selectedBrotherCount == brothers.size()) { + parent.setSelected(true); + impactedParents.add(parent); + impactedParents.addAll(selectParentIfNeedWhenNodeSelected(parent, true)); + } else if (!select && selectedBrotherCount == brothers.size() - 1) { + // only the condition that the size of selected's brothers + // is one less than total count can trigger the deselect + parent.setSelected(false); + impactedParents.add(parent); + impactedParents.addAll(selectParentIfNeedWhenNodeSelected(parent, false)); + } + return impactedParents; + } + + /** + * Get the selected nodes under current node, include itself + */ + public static List getSelectedNodes(TreeNode treeNode) { + List selectedNodes = new ArrayList<>(); + if (treeNode == null) { + return selectedNodes; + } + + if (treeNode.isSelected() && treeNode.getParent() != null) selectedNodes.add(treeNode); + + for (TreeNode child : treeNode.getChildren()) { + selectedNodes.addAll(getSelectedNodes(child)); + } + return selectedNodes; + } + + /** + * Return true when the node has one selected child(recurse all children) at least, + * otherwise return false + */ + public static boolean hasOneSelectedNodeAtLeast(TreeNode treeNode) { + if (treeNode == null || treeNode.getChildren().size() == 0) { + return false; + } + List children = treeNode.getChildren(); + for (TreeNode child : children) { + if (child.isSelected() || hasOneSelectedNodeAtLeast(child)) { + return true; + } + } + return false; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/util/CheckControlUpdateUtil.java b/app/src/main/java/com/bingce/controlnetwork/util/CheckControlUpdateUtil.java new file mode 100644 index 0000000..2148a39 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/util/CheckControlUpdateUtil.java @@ -0,0 +1,97 @@ +package com.bingce.controlnetwork.util; + +import android.app.Activity; +import android.content.Context; + +import androidx.appcompat.app.AlertDialog; + +import com.bingce.AppChannel; +import com.bingce.BaseApp; +import com.bingce.data.sync.utils.LeanCloudConfigLoader; +import com.bingce.utils.StringUtil; +import com.bingce.utils.UpdateUtils; + +import blankj.utilcode.util.AppUtils; +import blankj.utilcode.util.Utils; + +import com.bingce.controlnetwork.R; + +public class CheckControlUpdateUtil { + public static void checkUpdate(Context context, boolean forceShow) { + String queryUrl = "latestVersionCodeUrlControl"; + if (AppChannel.customChannel == AppChannel.CUSTOM_CONTROL_PRO) { + queryUrl = "latestVersionCodeUrlControlPro"; + } + LeanCloudConfigLoader.findInBackground(queryUrl, instance -> { +// new LCQuery<>("Configuration") +// .whereEqualTo("name", queryUrl) +// .limit(1) +// .findInBackground().subscribe(new Observer>() { +// @Override +// public void onSubscribe(Disposable d) { +// +// } +// +// @Override +// public void onNext(List avObjects) { + if (context instanceof Activity && ((Activity) context).isFinishing()) return; + if (/*avObjects != null && !avObjects.isEmpty() && avObjects.get(0).getString("value") != null*/instance != null && StringUtil.isNotEmpty(instance.value)) { + String latestVersionCodeUrl = /*avObjects.get(0).getString("value")*/instance.value; + String updateLog = /*avObjects.get(0).getString("value2")*/instance.value2; + String specialVersions = instance.value3; + boolean isInSpecialVersions = false; + if (StringUtil.isNotEmpty(specialVersions)) { + String[] versionArr = specialVersions.split(",", -2); + int currentVersionCode = AppUtils.getAppVersionCode(); + for (String s : versionArr) { + String[] subVersionArr = s.split("-", -2); + if (subVersionArr.length == 2) { + int v1 = Integer.parseInt(subVersionArr[0]); + int v2 = Integer.parseInt(subVersionArr[1]); + if (currentVersionCode >= v1 && currentVersionCode <= v2) { + isInSpecialVersions = true; + break; + } + } + } + } + String[] arr = latestVersionCodeUrl.split(",", -2); + if (arr.length == 2 && updateLog != null && arr[1].endsWith(".apk")) { + try { + if (isInSpecialVersions) { + UpdateUtils.getInstance().showUpdate(context, updateLog, arr[0], arr[1], forceShow); + } else { + if (forceShow) { + if (Integer.parseInt(arr[0]) > AppUtils.getAppVersionCode()) { + UpdateUtils.getInstance().showUpdate(context, updateLog, arr[0], arr[1], forceShow); + } else { + new AlertDialog.Builder(context) + .setTitle(R.string.hint) + .setMessage(R.string.already_the_latest_version) + .setPositiveButton(R.string.close, null) + .show(); + } + } else { + if (Integer.parseInt(arr[0]) > AppUtils.getAppVersionCode() && Integer.parseInt(arr[0]) > ((BaseApp) Utils.getApp()).ignoredVersionCode) { + UpdateUtils.getInstance().showUpdate(context, updateLog, arr[0], arr[1], forceShow); + } + } + } + } catch (Exception ignored) { + } + } + } +// } +// +// @Override +// public void onError(Throwable e) { +// emergency();//后门,防止leancloud崩溃时会员无法登录 +// } +// +// @Override +// public void onComplete() { +// +// } + }); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/util/DefaultNameUtil.kt b/app/src/main/java/com/bingce/controlnetwork/util/DefaultNameUtil.kt new file mode 100644 index 0000000..52a0cd1 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/util/DefaultNameUtil.kt @@ -0,0 +1,29 @@ +package com.bingce.controlnetwork.util + +import com.bingce.controlapphelper.util.Tools +import com.bingce.controlnetwork.R +import java.text.SimpleDateFormat +import java.util.Date +import java.util.Locale + +object DefaultNameUtil { + /** + * DateUtils.ymdWithCharacter(Date()) + */ + @JvmStatic + fun getDefaultProjectName(): String { + val format = Tools.getString(R.string.default_project_format) + val simpleDateFormat = SimpleDateFormat(format, Locale.getDefault()) + return simpleDateFormat.format(Date()) + } + + /** + * DateUtils.ymdHMSWithCharacter(Date()) + */ + @JvmStatic + fun getDefaultPeriodName(): String { + val format = Tools.getString(R.string.default_period_format) + val simpleDateFormat = SimpleDateFormat(format, Locale.getDefault()) + return simpleDateFormat.format(Date()) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/util/DialogUtil.java b/app/src/main/java/com/bingce/controlnetwork/util/DialogUtil.java new file mode 100644 index 0000000..ffc393c --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/util/DialogUtil.java @@ -0,0 +1,128 @@ +package com.bingce.controlnetwork.util; + +import android.content.Context; + +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; + +import com.bingce.controlapphelper.util.Tools; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.fragment.TipsFragment; +import com.bingce.controlnetwork.fragment.TipsWith2OptionFragment; + + +public class DialogUtil { + public static void showDataLoseHintDialog(FragmentManager fragmentManager, LifecycleOwner lifecycleOwner, IConfirmBack callBack) { + showConfirmDialog(fragmentManager, lifecycleOwner, + Tools.getString(R.string.tips_station_data_will_lose), + Tools.getString(R.string.exit), callBack); + } + + public static void showConfirmDialog(FragmentManager fragmentManager, LifecycleOwner lifecycleOwner, + String hint, + String confirmText, + IConfirmBack callBack) { + TipsWith2OptionFragment + .tips( + fragmentManager, + lifecycleOwner, + confirmText, + Tools.getString(R.string.cancel), + hint, + new TipsWith2OptionFragment.SimpleCallback() { + @Override + public void onConfirm() { + if (callBack != null) { + callBack.onConfirm(); + } + } + } + ); + } + + public static void showConfirmCancleDialog(FragmentManager fragmentManager, LifecycleOwner lifecycleOwner, + String hint, + String confirmText, + String cancelText, + IConfirmCancelBack callBack) { + TipsWith2OptionFragment + .tips( + fragmentManager, + lifecycleOwner, + confirmText, + cancelText, + hint, + new TipsWith2OptionFragment.SimpleCallback() { + @Override + public void onConfirm() { + if (callBack != null) { + callBack.onConfirm(); + } + } + + @Override + public void onCancel() { + if (callBack != null) { + callBack.onCancel(); + } + } + } + ); + } + + public static void showAlertDialog(Context context, FragmentManager fragmentManager, LifecycleOwner lifecycleOwner, + String hint) { + TipsFragment.tipsOnly(fragmentManager, lifecycleOwner, context, hint); + } + + public static void showConfirmCountDownDialog(FragmentManager fragmentManager, LifecycleOwner lifecycleOwner, + String hint, + String confirmText, + IConfirmBack callBack) { + TipsWith2OptionFragment + .tipsCountDownTime( + fragmentManager, + lifecycleOwner, + confirmText, + Tools.getString(R.string.cancel), + null, + hint, + new TipsWith2OptionFragment.SimpleCallback() { + @Override + public void onConfirm() { + callBack.onConfirm(); + } + } + ); + } + + public static void showHighToNoHighConfirmDialog(FragmentManager fragmentManager, LifecycleOwner lifecycleOwner, + IConfirmBack callBack) { + TipsWith2OptionFragment + .tips( + fragmentManager, + lifecycleOwner, + Tools.getString(R.string.confirm), + Tools.getString(R.string.cancel), + "当前已有测量数据,切换后高精度气象数据将丢失", + new TipsWith2OptionFragment.SimpleCallback() { + @Override + public void onConfirm() { + callBack.onConfirm(); + } + } + ); + } + + + public interface IConfirmBack { + void onConfirm(); + } + + public interface IConfirmCancelBack { + void onConfirm(); + + void onCancel(); + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/util/KeyboardUtil.java b/app/src/main/java/com/bingce/controlnetwork/util/KeyboardUtil.java new file mode 100644 index 0000000..5c39306 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/util/KeyboardUtil.java @@ -0,0 +1,19 @@ +package com.bingce.controlnetwork.util; + +import android.app.Activity; +import android.view.inputmethod.InputMethodManager; + +import blankj.utilcode.util.ActivityUtils; + +public class KeyboardUtil { + public static void hideSoftInput() { + hideSoftInput(ActivityUtils.getTopActivity()); + } + + public static void hideSoftInput(Activity act) { + if (act != null && act.getCurrentFocus() != null) { + InputMethodManager inputMethodManager = (InputMethodManager) act.getSystemService(Activity.INPUT_METHOD_SERVICE); + inputMethodManager.hideSoftInputFromWindow(act.getCurrentFocus().getWindowToken(), 0); + } + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/util/SelectDeviceTypeUtil.java b/app/src/main/java/com/bingce/controlnetwork/util/SelectDeviceTypeUtil.java new file mode 100644 index 0000000..32cec2e --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/util/SelectDeviceTypeUtil.java @@ -0,0 +1,38 @@ +package com.bingce.controlnetwork.util; + +import android.content.Intent; +import android.view.View; + +import com.afollestad.materialdialogs.MaterialDialog; +import com.bingce.AppChannel; +import com.bingce.controlnetwork.R; +import com.bingce.device.ui.ConnectLevelActivity; +import com.bingce.device.ui.ConnectTSActivity; + +import blankj.utilcode.util.ActivityUtils; + +public class SelectDeviceTypeUtil { + public static void showDeviceTypeDialog() { + new MaterialDialog.Builder(ActivityUtils.getTopActivity()) + .title(R.string.choose_instrument_type) + .items(new String[]{ActivityUtils.getTopActivity().getString(R.string.total_station), ActivityUtils.getTopActivity().getString(R.string.device_type_level)}) + .itemsCallback(new MaterialDialog.ListCallback() { + @Override + public void onSelection(MaterialDialog dialog, View itemView, int which, CharSequence text) { + switch (which) { + case 0: + Intent intent = new Intent(ActivityUtils.getTopActivity(), ConnectTSActivity.class); + intent.putExtra("customChannel", AppChannel.customChannel); + ActivityUtils.getTopActivity().startActivity(intent); + break; + case 1: + Intent intent2 = new Intent(ActivityUtils.getTopActivity(), ConnectLevelActivity.class); + intent2.putExtra("customChannel", AppChannel.customChannel); + ActivityUtils.getTopActivity().startActivity(intent2); + break; + } + } + }).show(); + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/util/StationSettingCheckUtil.java b/app/src/main/java/com/bingce/controlnetwork/util/StationSettingCheckUtil.java new file mode 100644 index 0000000..6c7fb22 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/util/StationSettingCheckUtil.java @@ -0,0 +1,213 @@ +package com.bingce.controlnetwork.util; + +import android.content.Context; + +import androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatActivity; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.LifecycleOwner; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.leveling.LevelingDbFactory; +import com.bingce.controlapphelper.datasource.database.leveling.idetection.isetting.LevelIDetectionSetting; +import com.bingce.controlapphelper.datasource.database.leveling.station.LevelingStationRecord; +import com.bingce.controlapphelper.datasource.database.leveling.stationsetting.LevelingStationSettingRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.ISurveyorStationDataSource; +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.model.SurveyorPoint; +import com.bingce.controlapphelper.ui.fragment.TipsWith2OptionFragment; +import com.bingce.controlapphelper.util.IUIRunner; +import com.bingce.controlnetwork.func.level.activity.LevelStationSettingActivity; +import com.bingce.controlnetwork.newui.stationsetting.StationSettingsActivity; +import com.bingce.utils.ThreadPoolUtil; + +import java.util.List; + +import blankj.utilcode.util.ToastUtils; +import com.bingce.controlnetwork.func.level.idetection.LevelIDetectionStationSettingActivity; + + +public class StationSettingCheckUtil { + //请设置温度、成像、太阳方向等相关信息(App只对以上信息进行留存,不会依此对数据进行校正). + private static final String HINT = "开始测量前请先进行测站设置"; + private static final String HINT_LEVEL = "开始测量前请先进行测段设置"; + public static final String HINT_LEVEL_END = "测段结束前请先进行测段设置"; + + private boolean isCheckSuccess; + + /** + * 检测测站是否设置了棱镜相关属性,如果没有则跳转到设置界面 + */ + public void checkStationSettings(String stationId, + @NonNull Fragment fragment, + @NonNull IUIRunner runner, ICheckSuccess checkSuccess) { + if (isCheckSuccess) { + checkSuccess.onSuccess(); + return; + } + + ThreadPoolUtil.execute(() -> { + ISurveyorStationDataSource stationDataSource = + SurveyorDatabaseFactory.instance.getSurveyorStation(); + //检测温度、湿度、气压、棱镜是否设置 + SurveyorStationRecord stationRecord = stationDataSource.getRecordSync(stationId); + if (stationRecord == null) { + ToastUtils.showShort("stationRecord == null"); + return; + } + List stationItemList = stationRecord.getItems(); + if (stationItemList == null || stationItemList.isEmpty()) { + ToastUtils.showShort("stationItemList == null || stationItemList.isEmpty()"); + return; + } + boolean failure = false; + for (SurveyorPoint stationItem : stationItemList) { + if (SurveyorPoint.TYPE_STATION.equals(stationItem.getType())) { + continue; + } + if (stationItem.isWellSteel()) { + continue; + } + if (isEmpty(stationItem.getPrismHeight())) { + failure = true; + break; + } + } + if (!failure && (isEmpty(stationRecord.getTemperature()) || + isEmpty(stationRecord.getHumidity()) || + isEmpty(stationRecord.getAirPressure()) || + isEmpty(stationRecord.getInstrumentHeight()))) { + failure = true; + } + + if (failure) { + runner.runOnUI(() -> TipsWith2OptionFragment.hardTips( + fragment.getChildFragmentManager(), + fragment.getViewLifecycleOwner(), + HINT, + new TipsWith2OptionFragment.SimpleCallback() { + @Override + public void onConfirm() { +// StationSettingsFragment.start(fragment.getContext(), stationId); + StationSettingsActivity.start(fragment.requireContext(), stationId); + } + + @Override + public void onCancel() { +// if (fragment.getActivity() != null) { +// fragment.getActivity().finish(); +// } + } + })); + return; + } + + isCheckSuccess = true; + checkSuccess.onSuccess(); + + }); + + + } + + public static boolean isEmpty(String string) { + return string == null || string.isEmpty(); + } + + public interface ICheckSuccess { + void onSuccess(); + } + + /** + * 水准测站检测 + */ + public void checkStationSettingsLevel(String stationId, + FragmentManager fragmentManager, + LifecycleOwner lifecycleOwner, + Context context, + IUIRunner runner, ICheckSuccess checkSuccessListener) { + if (isCheckSuccess) { + checkSuccessListener.onSuccess(); + return; + } + ThreadPoolUtil.execute(() -> { + LevelingStationRecord stationRecord = LevelingDbFactory.instance.getStationDataSource().getRecordSync(stationId); + if (stationRecord == null) { + ToastUtils.showShort("stationRecord == null"); + return; + } + LevelingStationSettingRecord stationSettingLatest = LevelingDbFactory.instance.getStationSettingDataSource().getLatest(stationRecord.routeId); + + if (stationSettingLatest == null || stationSettingLatest.weather == null) { + //需要设置环境设置 + runner.runOnUI(() -> showLevelSetStationSetting(fragmentManager, + lifecycleOwner, context, + HINT_LEVEL, + stationRecord.routeId, stationId, false) + ); + return; + } + + isCheckSuccess = true; + checkSuccessListener.onSuccess(); + }); + + } + + /** + * i角检测的测站设置 + */ + public void checkStationSettingsIDetection(String iDetectionId, + @NonNull AppCompatActivity activity, + @NonNull IUIRunner runner, ICheckSuccess checkSuccessListener) { + if (isCheckSuccess) { + checkSuccessListener.onSuccess(); + return; + } + ThreadPoolUtil.execute(() -> { + LevelIDetectionSetting setting = LevelingDbFactory.instance.getIDetectionSettingDataSource().getByIDetectionId(iDetectionId); + if (setting == null) { + //需要设置环境设置 + runner.runOnUI(() -> TipsWith2OptionFragment.hardTips( + activity.getSupportFragmentManager(), + activity, + HINT, + new TipsWith2OptionFragment.SimpleCallback() { + @Override + public void onConfirm() { + LevelIDetectionStationSettingActivity.launch(activity, iDetectionId); + } + }) + ); + return; + } + isCheckSuccess = true; + checkSuccessListener.onSuccess(); + }); + + } + + /** + * 提示需要进行测站设置 + */ + public static void showLevelSetStationSetting(@NonNull FragmentManager fragmentManager, + @NonNull LifecycleOwner lifecycleOwner, + Context context, + String hint, + String routeId, + String stationId, + boolean isSaveEndStation) { + TipsWith2OptionFragment.hardTips( + fragmentManager, + lifecycleOwner, + hint, + new TipsWith2OptionFragment.SimpleCallback() { + @Override + public void onConfirm() { + LevelStationSettingActivity.start(context, routeId, stationId, isSaveEndStation); + } + }); + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/util/SurveyorOpenAtrUtil.java b/app/src/main/java/com/bingce/controlnetwork/util/SurveyorOpenAtrUtil.java new file mode 100644 index 0000000..0f4ddd9 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/util/SurveyorOpenAtrUtil.java @@ -0,0 +1,27 @@ +package com.bingce.controlnetwork.util; + +import com.bingce.controlapphelper.datasource.database.prism.PrismConstants; +import com.bingce.controlapphelper.datasource.database.surveyorstation.model.SurveyorPoint; + +/** + * 测量转换工具类 + */ +public class SurveyorOpenAtrUtil { + + public static boolean isOpenAtr(SurveyorPoint surveyorPoint) { + return isOpenAtr(surveyorPoint.getPrismType(), surveyorPoint.getPrismTypeLarge()) && !surveyorPoint.isOpenAtrNot(); + } + + public static boolean isOpenAtr(int prismType, String prismTypeLarge) { + switch (prismType) { + case PrismConstants.TYPE_PRISM_ROUND: + case PrismConstants.TYPE_PRISM_MINI: + return true; + case PrismConstants.TYPE_USER: + return PrismConstants.TYPE_PRISM_LARGE.equals(prismTypeLarge); + default: + return false; + } + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/util/SurveyorStationUtil.java b/app/src/main/java/com/bingce/controlnetwork/util/SurveyorStationUtil.java new file mode 100644 index 0000000..7e0d407 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/util/SurveyorStationUtil.java @@ -0,0 +1,126 @@ +package com.bingce.controlnetwork.util; + +import android.content.Context; + +import androidx.annotation.MainThread; + +import com.bingce.controlapphelper.datasource.database.SurveyorDatabaseFactory; +import com.bingce.controlapphelper.datasource.database.line.LineRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.SurveyorStationRecord; +import com.bingce.controlapphelper.datasource.database.surveyorstation.model.SurveyorPoint; +import com.bingce.controlapphelper.model.StationDetailItem; +import com.bingce.utils.IOnSingleGetCallback; +import com.bingce.utils.ThreadPoolUtil; + +import java.util.List; + +import com.bingce.controlnetwork.fragment.station.line.attached.LineStationAttachedSetupFragment; +import com.bingce.controlnetwork.fragment.station.line.close.LineStationCloseSetupFragment; +import com.bingce.controlnetwork.fragment.station.line.random.LineStationRandomSetupFragment; +import com.bingce.controlnetwork.fragment.station.line.single.LineStationSingleSetupFragment; +import com.bingce.controlnetwork.fragment.station.line.well.LineStationWellDoubleGroundSetupFragment; +import com.bingce.controlnetwork.fragment.station.line.well.LineStationWellDoubleUnderGroundSetupFragment; +import com.bingce.controlnetwork.fragment.station.line.well.LineStationWellSetupFragment; + +public class SurveyorStationUtil { + @MainThread + public static void editLine(Context context, String lineId) { + ThreadPoolUtil.execute(() -> { + LineRecord stationBatchRecord = + SurveyorDatabaseFactory.instance.getLineRecordDatabase().findById(lineId); + if (stationBatchRecord == null) { + return; + } +// //1.查询该线路下所有测站 +// List stationRecordList = +// SurveyorDatabaseFactory.instance.getSurveyorStation().getDataListByLine(stationBatchRecord.id); +// //2.遍历测站,检测是否有测量数据 +// if (stationRecordList != null) { +// for (SurveyorStationRecord record : stationRecordList) { +// if (record == null) { +// continue; +// } +// long count = SurveyorDatabaseFactory +// .instance +// .getSurveyorRecordDataSource() +// .recordCount(record.id); +// if (count > 0) {//如果有测量数据,则该导线不能编辑 +// ThreadPoolUtil.executeInMain(() -> TipsFragment.tipsOnly(fragmentManager, +// lifecycleOwner, +// context, +// context.getString(R.string.tips_forbid_edit_line_because_has_surveyor_record))); +// return; +// } +// } +// } + if (LineRecord.TYPE_LINE_SINGLE.equals(stationBatchRecord.type)) { + LineStationSingleSetupFragment.startEdit(context, stationBatchRecord.projectId, lineId); + } else if (LineRecord.TYPE_LINE_ATTACH.equals(stationBatchRecord.type)) { + LineStationAttachedSetupFragment.startEdit(context, stationBatchRecord.projectId, lineId); + } else if (LineRecord.TYPE_LINE_CLOSE.equals(stationBatchRecord.type)) { + LineStationCloseSetupFragment.startEdit(context, stationBatchRecord.projectId, lineId); + } else if (LineRecord.TYPE_LINE_RANDOM.equals(stationBatchRecord.type)) { + LineStationRandomSetupFragment.startEdit(context, stationBatchRecord.projectId, lineId); + } else if (LineRecord.TYPE_WELL.equals(stationBatchRecord.type)) { + LineStationWellSetupFragment.startEdit(context, stationBatchRecord.projectId, lineId); + } else if (LineRecord.TYPE_WELL_DOUBLE_GROUND.equals(stationBatchRecord.type)) { + LineStationWellDoubleGroundSetupFragment.startEdit(context, stationBatchRecord.projectId, lineId); + } else if (LineRecord.TYPE_WELL_DOUBLE_UNDERGROUND.equals(stationBatchRecord.type)) { + LineStationWellDoubleUnderGroundSetupFragment.startEdit(context, stationBatchRecord.projectId, lineId); + } + }); + } + + @MainThread + public static void getBatchItemList(String lineId, IOnSingleGetCallback callback) { + ThreadPoolUtil.execute(() -> { + LineRecord batchRecord = + SurveyorDatabaseFactory.instance.getLineRecordDatabase() + .findById(lineId); + if (batchRecord == null) { + return; + } + callback.onGet(batchRecord); + }); + } + + @MainThread + public static void updateLineRecord(LineRecord lineRecord) { + if (lineRecord == null) return; + SurveyorDatabaseFactory.instance.getLineRecordDatabase().update(lineRecord); + } + + @MainThread + public static void updateStationPointsMeasureHorAag(LineRecord lineRecord) { + if (lineRecord == null) return; + List stationDetailList = lineRecord.items; + if (stationDetailList == null) { + return; + } + + ThreadPoolUtil.execute(() -> { + List stationRecordList = SurveyorDatabaseFactory.instance.getSurveyorStation().getDataListByLine(lineRecord.id); + if (stationRecordList != null && !stationRecordList.isEmpty()) { + for (SurveyorStationRecord record : stationRecordList) { + List items = record.items; + if (items == null) { + continue; + } + for (SurveyorPoint point : items) { + for (StationDetailItem stationDetailItem : stationDetailList) { + if (point != null && point.getOriginalPointId().equals(stationDetailItem.getOriginalPointId()) + && point.isWellSteel() != point.isWellSteel()) { + // TODO: 2023/5/22 + point.setWellSteel(stationDetailItem.isWellSteel()); + SurveyorDatabaseFactory.instance.getSurveyorStation().update(record); + } + } + } + } + } + }); + + + } + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/util/config/AbstractSetConfigs.java b/app/src/main/java/com/bingce/controlnetwork/util/config/AbstractSetConfigs.java new file mode 100644 index 0000000..3399c69 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/util/config/AbstractSetConfigs.java @@ -0,0 +1,80 @@ +package com.bingce.controlnetwork.util.config; + +import java.util.LinkedHashMap; +import java.util.Map; + +public abstract class AbstractSetConfigs { + private final Map list = new LinkedHashMap<>(); + + protected AbstractSetConfigs() { + } + + public void foreach(IConfigItemCallback callback) { + if (callback == null) { + return; + } + for (ConfigItem configItem : list.values()) { + callback.on(configItem); + } + } + + public ConfigItem get(int id) { + return list.get(id); + } + + public String allIds() { + return ConfigItem.ids(list.values()); + } + + public String defaultIds() { + return allIds(); + } + +// private static AbstractSetConfigs instance = null; +// +// public static AbstractSetConfigs getInstance() { +// synchronized (ParameterSetConfigs.class) { +// if (instance == null) { +// instance = new ParameterSetConfigs(); +// init(); +// } +// } +// return instance; +// } + + public void init() { + init(list); + } + + protected abstract void init(final Map list);// { +// list.put(99, new ConfigItem(99, R.string.road_project_management, R.mipmap.icon_parameter_road_project, DragIconInfo.CATEGORY_ONLY)); +// list.put(100, new ConfigItem(100, R.string.road_parameter, R.mipmap.icon_parameter_road, DragIconInfo.CATEGORY_ONLY)); +// list.put(101, new ConfigItem(101, R.string.break_chain, R.mipmap.icon_parameter_breakchain, DragIconInfo.CATEGORY_ONLY)); +// list.put(102, new ConfigItem(102, R.string.hor_parameter, R.mipmap.icon_parameter_hor, DragIconInfo.CATEGORY_ONLY)); +// list.put(103, new ConfigItem(103, R.string.ver_parameter, R.mipmap.icon_parameter_ver, DragIconInfo.CATEGORY_ONLY)); +// list.put(104, new ConfigItem(104, R.string.standard_cross_section, R.mipmap.icon_parameter_stand_cross_section, DragIconInfo.CATEGORY_ONLY)); +// list.put(105, new ConfigItem(105, R.string.super_elevation, R.mipmap.icon_parameter_super, DragIconInfo.CATEGORY_ONLY)); +// list.put(106, new ConfigItem(106, R.string.widen_change, R.mipmap.icon_parameter_widen, DragIconInfo.CATEGORY_ONLY)); +// list.put(107, new ConfigItem(107, R.string.tunnel_section_library, R.mipmap.icon_parameter_tunnel_section_library, DragIconInfo.CATEGORY_ONLY)); +// list.put(108, new ConfigItem(108, R.string.tcs_matching, R.mipmap.icon_parameter_tunnel_section_matching, DragIconInfo.CATEGORY_ONLY)); +// list.put(109, new ConfigItem(109, R.string.middle_line_offset, R.mipmap.icon_parameter_middle_line_offset, DragIconInfo.CATEGORY_ONLY)); +// list.put(110, new ConfigItem(110, R.string.subway_center_up_down, R.mipmap.icon_parameter_subway_updown, DragIconInfo.CATEGORY_ONLY)); +// list.put(111, new ConfigItem(111, R.string.tcs_feature_point, R.mipmap.icon_parameter_tunnel_feanture_points, DragIconInfo.CATEGORY_ONLY)); +// list.put(112, new ConfigItem(112, R.string.tunnel_embedded_part, R.mipmap.icon_parameter_tunnel_embedded_part, DragIconInfo.CATEGORY_ONLY)); +// list.put(113, new ConfigItem(113, R.string.tcs_rotate, R.mipmap.icon_parameter_tunnel_rotate, DragIconInfo.CATEGORY_ONLY)); +// list.put(114, new ConfigItem(114, R.string.control_point, R.mipmap.icon_parameter_points, DragIconInfo.CATEGORY_ONLY)); +// list.put(115, new ConfigItem(115, R.string.side_section_library, R.mipmap.icon_parameter_side_library, DragIconInfo.CATEGORY_ONLY)); +// list.put(116, new ConfigItem(116, R.string.scs_matching, R.mipmap.icon_parameter_side_section_matching, DragIconInfo.CATEGORY_ONLY)); +// list.put(117, new ConfigItem(117, R.string.subway_common_parameters, R.mipmap.icon_parameter_subway_common_parameters, DragIconInfo.CATEGORY_ONLY)); +// list.put(118, new ConfigItem(118, R.string.tbm_reference_point, R.mipmap.icon_parameter_subway_tbm_reference_point, DragIconInfo.CATEGORY_ONLY)); +// list.put(119, new ConfigItem(119, R.string.staking_point_library, R.mipmap.icon_parameter_staking_point_library, DragIconInfo.CATEGORY_ONLY)); +// list.put(120, new ConfigItem(120, R.string.point_survey_point_library, R.mipmap.icon_program_point_survey, DragIconInfo.CATEGORY_ONLY)); +// list.put(121, new ConfigItem(121, R.string.pier_template_library, R.mipmap.icon_parameter_pier_template_library, DragIconInfo.CATEGORY_ONLY)); +// list.put(122, new ConfigItem(122, R.string.bridge_and_layout, R.mipmap.icon_parameter_pier_layout, DragIconInfo.CATEGORY_ONLY)); +// if (AppChannel.customChannel == AppChannel.CUSTOM_ZJYGJ) { +// list.put(123, new ConfigItem(123, R.string.menu_item_zjygj_project_list, R.mipmap.icon_road_project_list_zjygj, DragIconInfo.CATEGORY_ONLY)); +// } +// } + +// public abstract void onItemClick(int id, Fragment fragment); +} diff --git a/app/src/main/java/com/bingce/controlnetwork/util/config/ConfigItem.java b/app/src/main/java/com/bingce/controlnetwork/util/config/ConfigItem.java new file mode 100644 index 0000000..630759f --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/util/config/ConfigItem.java @@ -0,0 +1,86 @@ +package com.bingce.controlnetwork.util.config; + +import android.content.Context; + +import com.wedcel.dragexpandgrid.model.DragIconInfo; + +import java.util.ArrayList; +import java.util.Collection; + +public class ConfigItem { + public ConfigItem(int id, int title, int icon, int category) { + this.id = id; + this.title = title; + this.icon = icon; + this.category = category; + } + + private int id; + private int title; + private int icon; + int category; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public int getTitle() { + return title; + } + + public void setTitle(int title) { + this.title = title; + } + + public int getIcon() { + return icon; + } + + public void setIcon(int icon) { + this.icon = icon; + } + + public int getCategory() { + return category; + } + + public void setCategory(int category) { + this.category = category; + } + + private static int readStringResId(Context context, String name) { + return context.getResources().getIdentifier(name, "string", context.getPackageName()); + } + + private static int readMipmapResId(Context context, String name) { + return context.getResources().getIdentifier(name, "mipmap", context.getPackageName()); + } + + private static String readStringValue(Context context, String name) { + return context.getString(readStringResId(context, name)); + } + + public DragIconInfo convert(Context context) { + return new DragIconInfo( + getId(), + context.getString(getTitle()), + getIcon(), + DragIconInfo.CATEGORY_ONLY, + false, + new ArrayList<>()); + } + + public static String ids(Collection list) { + StringBuilder builder = new StringBuilder(); + for (ConfigItem item : list) { + builder + .append(item.getId()) + .append(","); + } + return builder.toString(); + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/util/config/ConfigsSetConfigs.java b/app/src/main/java/com/bingce/controlnetwork/util/config/ConfigsSetConfigs.java new file mode 100644 index 0000000..c3d761e --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/util/config/ConfigsSetConfigs.java @@ -0,0 +1,90 @@ +package com.bingce.controlnetwork.util.config; + +import android.content.Context; +import android.content.Intent; + +import com.bingce.AppChannel; +import com.bingce.controlnetwork.R; +import com.bingce.controlnetwork.fragment.ConfigFragment; +import com.bingce.controlnetwork.fragment.PointListFragment; +import com.bingce.controlnetwork.fragment.PrismManageFragment; +import com.bingce.controlnetwork.fragment.SelectExportHeightTraverseFragment; +import com.bingce.controlnetwork.fragment.SelectExportSurveyorRecordFragment; +import com.bingce.controlnetwork.fragment.SelectExportSurveyorRecordWireFileFragment; +import com.bingce.controlnetwork.fragment.ToleranceManageFragment; +import com.bingce.device.ui.ConnectTSActivity; +import com.wedcel.dragexpandgrid.model.DragIconInfo; + +import java.util.Map; + +public class ConfigsSetConfigs extends AbstractSetConfigs { + + private final static int FUC_INSTRUMENTMANAGEMENT = 101; //仪器管理 + private final static int FUC_GLOBAL_CONTROL_POINT = 102;//全局控制点 + private final static int FUC_EXPORT_STATION = 103; //观测数据导出 + private final static int FUC_EXPORT_WIRE_FILE = 104;//导线文件导出 + private final static int FUC_TOLERANCE_MANAGER = 105;//自定义限差管理 + private final static int FUC_PRISM_MANAGER = 106;//棱镜管理 + private final static int FUC_HEIGHT_TRAVERSE_EXPORT = 107;//高程导线数据导出 + + @Override + protected void init(Map list) { + list.put(FUC_INSTRUMENTMANAGEMENT, + new ConfigItem(FUC_INSTRUMENTMANAGEMENT, R.string.instrument_management, R.drawable.icon_ts_connecting, DragIconInfo.CATEGORY_ONLY)); + list.put(FUC_GLOBAL_CONTROL_POINT, + new ConfigItem(FUC_GLOBAL_CONTROL_POINT, R.string.global_control_point, R.drawable.icon_parameter_points, DragIconInfo.CATEGORY_ONLY)); + list.put(FUC_EXPORT_STATION, + new ConfigItem(FUC_EXPORT_STATION, R.string.export, R.drawable.ic_export, DragIconInfo.CATEGORY_ONLY)); + list.put(FUC_EXPORT_WIRE_FILE, + new ConfigItem(FUC_EXPORT_WIRE_FILE, R.string.export_wire_file, R.drawable.ic_export_wire, DragIconInfo.CATEGORY_ONLY)); + list.put(FUC_TOLERANCE_MANAGER, + new ConfigItem(FUC_TOLERANCE_MANAGER, R.string.name_custom_telorance_manager, R.drawable.ic_custom_tolerance, DragIconInfo.CATEGORY_ONLY)); + list.put(FUC_PRISM_MANAGER, + new ConfigItem(FUC_PRISM_MANAGER, R.string.prism_manager, R.drawable.icon_prism_manager, DragIconInfo.CATEGORY_ONLY)); + list.put(FUC_HEIGHT_TRAVERSE_EXPORT, + new ConfigItem(FUC_HEIGHT_TRAVERSE_EXPORT, R.string.export_height_traverse, R.drawable.ic_export_height_traverse, DragIconInfo.CATEGORY_ONLY)); + } + + private static ConfigsSetConfigs instance = null; + + public static ConfigsSetConfigs getInstance() { + if (instance == null) { + synchronized (ConfigsSetConfigs.class) { + if (instance == null) { + instance = new ConfigsSetConfigs(); + instance.init(); + } + } + } + return instance; + } + + public void onItemClick(int id, ConfigFragment fragment) { + Context context = fragment.requireContext(); + switch (id) { + case FUC_INSTRUMENTMANAGEMENT://仪器管理 + Intent intent = new Intent(context, ConnectTSActivity.class); + intent.putExtra("customChannel", AppChannel.customChannel); + context.startActivity(intent); + break; + case FUC_GLOBAL_CONTROL_POINT://全局控制点 + PointListFragment.go2GlobalPointList(context); + break; + case FUC_EXPORT_STATION://观测数据导出 + SelectExportSurveyorRecordFragment.start(context, null); + break; + case FUC_EXPORT_WIRE_FILE://导线文件导出 + SelectExportSurveyorRecordWireFileFragment.start(context); + break; + case FUC_TOLERANCE_MANAGER://自定义限差管理 + ToleranceManageFragment.start(context, null); + break; + case FUC_PRISM_MANAGER://棱镜管理 + PrismManageFragment.start(context); + break; + case FUC_HEIGHT_TRAVERSE_EXPORT://高程导线数据导出 + SelectExportHeightTraverseFragment.start(context); + break; + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/util/config/IConfigItemCallback.java b/app/src/main/java/com/bingce/controlnetwork/util/config/IConfigItemCallback.java new file mode 100644 index 0000000..4c23deb --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/util/config/IConfigItemCallback.java @@ -0,0 +1,5 @@ +package com.bingce.controlnetwork.util.config; + +public interface IConfigItemCallback { + void on(ConfigItem item); +} diff --git a/app/src/main/java/com/bingce/controlnetwork/util/tolerance/LevelToleranceOperate.kt b/app/src/main/java/com/bingce/controlnetwork/util/tolerance/LevelToleranceOperate.kt new file mode 100644 index 0000000..9115a0c --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/util/tolerance/LevelToleranceOperate.kt @@ -0,0 +1,40 @@ +package com.bingce.controlnetwork.util.tolerance + +import com.bingce.controlapphelper.datasource.database.leveling.LevelingDbFactory +import com.bingce.controlapphelper.datasource.database.leveling.tolerance.LevelingToleranceDetail +import com.bingce.controlapphelper.datasource.database.tolerance.detail.IToleranceDetail +import com.bingce.controlapphelper.datasource.database.tolerance.group.ToleranceGroupRecord +import com.bingce.controlapphelper.datasource.database.tolerance.level.ToleranceLevelRecord +import com.bingce.controlapphelper.datasource.database.tolerance.load.IToleranceOperate +import com.bingce.controlapphelper.datasource.database.tolerance.load.ToleranceLoadUtil +import com.bingce.utils.IOnSingleGetCallback + +class LevelToleranceOperate : IToleranceOperate { + override fun getIToleranceDetail(id: String): IToleranceDetail? { + return LevelingDbFactory.instance + .getToleranceDetailDataSource().getRecordSync(id) + } + + override fun saveToleranceDetail(bean: IToleranceDetail?) { + bean?.let { + LevelingDbFactory.instance + .getToleranceDetailDataSource().saveWithCallback(it as LevelingToleranceDetail) { + + } + } + } + + override fun getGroup(itoleranceDetail: IToleranceDetail): ToleranceGroupRecord? { + return ToleranceLoadUtil.getLevelToleranceLoad().groupOf(itoleranceDetail.groupId) + } + + override fun getLevel(itoleranceDetail: IToleranceDetail): ToleranceLevelRecord? { + return ToleranceLoadUtil.getLevelToleranceLoad().levelOf(itoleranceDetail.levelId) + } + + override fun getDefaultRecord(callback: IOnSingleGetCallback) { + LevelingDbFactory.instance + .getToleranceDetailDataSource().getDefaultRecord(callback) + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/util/tolerance/ToleranceOperateUtil.kt b/app/src/main/java/com/bingce/controlnetwork/util/tolerance/ToleranceOperateUtil.kt new file mode 100644 index 0000000..5154567 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/util/tolerance/ToleranceOperateUtil.kt @@ -0,0 +1,19 @@ +package com.bingce.controlnetwork.util.tolerance + +import com.bingce.controlapphelper.datasource.database.ProjectTypeValue +import com.bingce.controlapphelper.datasource.database.tolerance.load.IToleranceOperate +import com.bingce.controlapphelper.datasource.database.tolerance.load.BingceToleranceOperate + +object ToleranceOperateUtil { + + @JvmStatic + fun getOperate(toleranceId: String?): IToleranceOperate? { + return toleranceId?.let { + when { + toleranceId.contains(ProjectTypeValue.LEVEL) -> LevelToleranceOperate() + else -> BingceToleranceOperate() + } + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/viewmodel/MainActivityViewModel.kt b/app/src/main/java/com/bingce/controlnetwork/viewmodel/MainActivityViewModel.kt new file mode 100644 index 0000000..e3c5faf --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/viewmodel/MainActivityViewModel.kt @@ -0,0 +1,11 @@ +package com.bingce.controlnetwork.viewmodel + +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import com.bingce.controlnetwork.bean.MainUserBean + +class MainActivityViewModel : ViewModel() { + + val refreshLoginUserLiveData = MutableLiveData() + +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/widget/editspinner/BaseEditSpinnerAdapter.java b/app/src/main/java/com/bingce/controlnetwork/widget/editspinner/BaseEditSpinnerAdapter.java new file mode 100644 index 0000000..6b7d8c4 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/widget/editspinner/BaseEditSpinnerAdapter.java @@ -0,0 +1,27 @@ +package com.bingce.controlnetwork.widget.editspinner; + +import android.widget.BaseAdapter; + +/** + * BaseEditSpinnerAdapter + * + * @author WrBug + * @since 2017/2/25 + */ +public abstract class BaseEditSpinnerAdapter extends BaseAdapter { + /** + * editText输入监听 + * + * @return + */ + public abstract EditSpinnerFilter getEditSpinnerFilter(); + + /** + * 获取需要填入editText的字符串 + * + * @param position + * @return + */ + public abstract String getItemString(int position); + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/widget/editspinner/EditSpinner.java b/app/src/main/java/com/bingce/controlnetwork/widget/editspinner/EditSpinner.java new file mode 100644 index 0000000..d9207e6 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/widget/editspinner/EditSpinner.java @@ -0,0 +1,256 @@ +package com.bingce.controlnetwork.widget.editspinner; + +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.drawable.Drawable; +import android.text.Editable; +import android.text.TextWatcher; +import android.util.AttributeSet; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.WindowManager; +import android.view.animation.Animation; +import android.view.animation.RotateAnimation; +import android.widget.AdapterView; +import android.widget.BaseAdapter; +import android.widget.EditText; +import android.widget.ImageView; +import android.widget.ListPopupWindow; +import android.widget.PopupWindow; +import android.widget.RelativeLayout; + +import androidx.annotation.ColorInt; +import androidx.annotation.DrawableRes; + +import com.bingce.controlnetwork.R; + +import java.util.List; + + +/** + * Created by WrBug on 2017/2/26 0026. + */ +public class EditSpinner extends RelativeLayout implements View.OnClickListener, AdapterView.OnItemClickListener, TextWatcher { + private EditText editText; + private ImageView mRightIv; + private View mRightImageTopView; + private final Context mContext; + private ListPopupWindow popupWindow; + BaseEditSpinnerAdapter adapter; + private long popupWindowHideTime; + private Animation mAnimation; + private Animation mResetAnimation; + private AdapterView.OnItemClickListener mOnItemClickListener; + private int maxLine = 1; + + public EditSpinner(Context context, AttributeSet attrs) { + super(context, attrs); + this.mContext = context; + initView(attrs); + initAnimation(); + } + + + public void setItemData(List data) { + adapter = new SimpleAdapter(mContext, data); + setAdapter(adapter); + } + + public void setOnItemClickListener(AdapterView.OnItemClickListener listener) { + this.mOnItemClickListener = listener; + } + + public void setText(String text) { + editText.setText(text); + } + + public void setTextColor(@ColorInt int color) { + editText.setTextColor(color); + } + + public String getText() { + return editText.getText().toString(); + } + + public void setHint(String hint) { + editText.setHint(hint); + } + + public void setRightImageDrawable(Drawable drawable) { + mRightIv.setImageDrawable(drawable); + } + + public void setRightImageResource(@DrawableRes int res) { + mRightIv.setImageResource(res); + } + + public void setAdapter(BaseEditSpinnerAdapter adapter) { + this.adapter = adapter; + setBaseAdapter(this.adapter); + } + + public void setMaxLine(int maxLine) { + this.maxLine = maxLine; + editText.setMaxLines(this.maxLine); + } + + private void initAnimation() { + mAnimation = new RotateAnimation(0, -180, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); + mAnimation.setDuration(300); + mAnimation.setFillAfter(true); + mResetAnimation = new RotateAnimation(-180, 0, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); + mResetAnimation.setDuration(300); + mResetAnimation.setFillAfter(true); + } + + private void initView(AttributeSet attrs) { + LayoutInflater.from(mContext).inflate(R.layout.edit_spinner, this); + editText = (EditText) findViewById(R.id.edit_sipnner_edit); + mRightIv = (ImageView) findViewById(R.id.edit_spinner_expand); + mRightImageTopView = findViewById(R.id.edit_spinner_expand_above); + mRightImageTopView.setOnClickListener(this); + mRightImageTopView.setClickable(false); + mRightIv.setOnClickListener(this); +// mRightIv.setRotation(90); + editText.addTextChangedListener(this); + TypedArray tArray = mContext.obtainStyledAttributes(attrs, + R.styleable.EditSpinner); + editText.setHint(tArray.getString(R.styleable.EditSpinner_hint)); + int imageId = tArray.getResourceId(R.styleable.EditSpinner_rightImage, 0); + if (imageId != 0) { + mRightIv.setImageResource(imageId); + } + int bg = tArray.getResourceId(R.styleable.EditSpinner_Background, 0); + if (bg != 0) { + editText.setBackgroundResource(bg); + } + maxLine = tArray.getInt(R.styleable.EditSpinner_maxLine, 1); + editText.setMaxLines(maxLine); + tArray.recycle(); + } + + private final void setBaseAdapter(BaseAdapter adapter) { + if (popupWindow == null) { + initPopupWindow(); + } + popupWindow.setAdapter(adapter); + } + + private void initPopupWindow() { + popupWindow = new ListPopupWindow(mContext) { + + @Override + public void show() { + super.show(); + mRightImageTopView.setClickable(true); + mRightIv.startAnimation(mAnimation); + } + + @Override + public void dismiss() { + super.dismiss(); + } + + }; + popupWindow.setOnItemClickListener(this); + popupWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); + popupWindow.setPromptPosition(ListPopupWindow.POSITION_PROMPT_BELOW); + popupWindow.setWidth(ViewGroup.LayoutParams.WRAP_CONTENT); + popupWindow.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT); + popupWindow.setAnchorView(editText); + popupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() { + @Override + public void onDismiss() { + popupWindowHideTime = System.currentTimeMillis(); + mRightIv.startAnimation(mResetAnimation); + } + }); + } + + + @Override + public final void onClick(View v) { + togglePopupWindow(); + } + + private void togglePopupWindow() { + if (System.currentTimeMillis() - popupWindowHideTime > 200) { + if (adapter == null || popupWindow == null) { + return; + } + showFilterData(""); + } + } + + @Override + public final void onItemClick(AdapterView parent, View view, int position, long id) { + editText.setText(((BaseEditSpinnerAdapter) parent.getAdapter()).getItemString(position)); + mRightImageTopView.setClickable(false); + if (popupWindow != null) { + popupWindow.dismiss(); + } + if (mOnItemClickListener != null) { + mOnItemClickListener.onItemClick(parent, view, position, id); + } + } + + @Override + public final void beforeTextChanged(CharSequence s, int start, int count, int after) { + + } + + @Override + public final void onTextChanged(CharSequence s, int start, int before, int count) { + + } + + @Override + public final void afterTextChanged(Editable s) { + String key = s.toString(); + editText.setSelection(key.length()); +// if (!TextUtils.isEmpty(key)) { +// showFilterData(key); +// } else { +// if (popupWindow != null) { +// popupWindow.dismiss(); +// } +// } + if (popupWindow != null) { + popupWindow.dismiss(); + } + } + + private void showFilterData(String key) { + if (popupWindow == null || adapter == null || adapter.getEditSpinnerFilter() == null) { + if (popupWindow != null) { + popupWindow.dismiss(); + } + return; + } + if (adapter.getEditSpinnerFilter().onFilter(key)) { + if (popupWindow != null) { + popupWindow.dismiss(); + } + } else { + if (popupWindow != null) { + popupWindow.show(); + } + } + } + + public void setEtGravity(int gravity) { + if (editText != null) { + editText.setGravity(gravity); + } + } + + public void setCanEdit(boolean enable) { + if (editText != null) { + editText.setEnabled(enable); + mRightIv.setEnabled(enable); + } + } + + +} diff --git a/app/src/main/java/com/bingce/controlnetwork/widget/editspinner/EditSpinnerFilter.java b/app/src/main/java/com/bingce/controlnetwork/widget/editspinner/EditSpinnerFilter.java new file mode 100644 index 0000000..1692228 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/widget/editspinner/EditSpinnerFilter.java @@ -0,0 +1,17 @@ +package com.bingce.controlnetwork.widget.editspinner; + +/** + * EditSpinnerFilter + * + * @author WrBug + * @since 2017/2/25 + */ +public interface EditSpinnerFilter { + /** + * editText输入监听 + * + * @param keyword + * @return + */ + boolean onFilter(String keyword); +} diff --git a/app/src/main/java/com/bingce/controlnetwork/widget/editspinner/SimpleAdapter.java b/app/src/main/java/com/bingce/controlnetwork/widget/editspinner/SimpleAdapter.java new file mode 100644 index 0000000..faa9154 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/widget/editspinner/SimpleAdapter.java @@ -0,0 +1,98 @@ +package com.bingce.controlnetwork.widget.editspinner; + +import android.content.Context; +import android.text.Html; +import android.text.TextUtils; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import com.bingce.utils.ScreenUtil; + +import java.util.ArrayList; +import java.util.List; + +/** + * SimpleAdapter + * + * @author WrBug + * @since 2017/2/25 + */ +public class SimpleAdapter extends BaseEditSpinnerAdapter implements EditSpinnerFilter { + private final Context mContext; + private final List mSpinnerData; + private final List mCacheData; + private final int[] indexs; + + public SimpleAdapter(Context context, List spinnerData) { + this.mContext = context; + this.mSpinnerData = spinnerData; + mCacheData = new ArrayList<>(spinnerData); + indexs = new int[mSpinnerData.size()]; + } + + @Override + public EditSpinnerFilter getEditSpinnerFilter() { + return this; + } + + @Override + public String getItemString(int position) { + return mSpinnerData.get(indexs[position]); + } + + @Override + public int getCount() { + return mCacheData == null ? 0 : mCacheData.size(); + } + + @Override + public String getItem(int position) { + return mCacheData == null ? "" : mCacheData.get(position) == null ? "" : mCacheData.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + TextView textView = null; + if (convertView == null) { + textView = (TextView) LayoutInflater.from(mContext).inflate(android.R.layout.simple_spinner_item, null); + ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ScreenUtil.dp2px(parent.getContext(), 48f)); + textView.setLayoutParams(layoutParams); + textView.setGravity(Gravity.CENTER_VERTICAL); + } else { + textView = (TextView) convertView; + } + + textView.setText(Html.fromHtml(getItem(position))); + return textView; + } + + @Override + public boolean onFilter(String keyword) { + mCacheData.clear(); + if (TextUtils.isEmpty(keyword)) { + mCacheData.addAll(mSpinnerData); + for (int i = 0; i < indexs.length; i++) { + indexs[i] = i; + } + } else { + StringBuilder builder = new StringBuilder(); + builder.append("[^\\s]*").append(keyword).append("[^\\s]*"); + for (int i = 0; i < mSpinnerData.size(); i++) { + if (mSpinnerData.get(i).replaceAll("\\s+", "|").matches(builder.toString())) { + indexs[mCacheData.size()] = i; + mCacheData.add(mSpinnerData.get(i).replaceFirst(keyword, "" + keyword + "")); + } + } + } + notifyDataSetChanged(); + return mCacheData.size() <= 0; + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/wxapi/Constants.java b/app/src/main/java/com/bingce/controlnetwork/wxapi/Constants.java new file mode 100644 index 0000000..9e79cf1 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/wxapi/Constants.java @@ -0,0 +1,7 @@ +package com.bingce.controlnetwork.wxapi; + +public class Constants { + + //appid 微信分配的ID + public static final String APP_ID = "wx8b41ad369eba83a9"; +} diff --git a/app/src/main/java/com/bingce/controlnetwork/wxapi/MD5.java b/app/src/main/java/com/bingce/controlnetwork/wxapi/MD5.java new file mode 100644 index 0000000..3357702 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/wxapi/MD5.java @@ -0,0 +1,26 @@ +package com.bingce.controlnetwork.wxapi; + +import java.security.MessageDigest; + +public class MD5 { + + public static String getMessageDigest(byte[] buffer) { + char[] hexDigits = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; + try { + MessageDigest mdTemp = MessageDigest.getInstance("MD5"); + mdTemp.update(buffer); + byte[] md = mdTemp.digest(); + int j = md.length; + char[] str = new char[j * 2]; + int k = 0; + for (int i = 0; i < j; i++) { + byte byte0 = md[i]; + str[k++] = hexDigits[byte0 >>> 4 & 0xf]; + str[k++] = hexDigits[byte0 & 0xf]; + } + return new String(str); + } catch (Exception e) { + return null; + } + } +} diff --git a/app/src/main/java/com/bingce/controlnetwork/wxapi/WXEntryActivity.java b/app/src/main/java/com/bingce/controlnetwork/wxapi/WXEntryActivity.java new file mode 100644 index 0000000..545dc39 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/wxapi/WXEntryActivity.java @@ -0,0 +1,109 @@ +package com.bingce.controlnetwork.wxapi; + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; + +import com.bingce.controlnetwork.R; +import com.bingce.event.WxRespCodeEvent; +import com.tencent.mm.opensdk.constants.ConstantsAPI; +import com.tencent.mm.opensdk.modelbase.BaseReq; +import com.tencent.mm.opensdk.modelbase.BaseResp; +import com.tencent.mm.opensdk.modelmsg.SendAuth; +import com.tencent.mm.opensdk.openapi.IWXAPI; +import com.tencent.mm.opensdk.openapi.IWXAPIEventHandler; +import com.tencent.mm.opensdk.openapi.WXAPIFactory; + +import org.greenrobot.eventbus.EventBus; + +import blankj.utilcode.util.ToastUtils; +import cn.leancloud.LCObject; +import cn.leancloud.LCUser; + +public class WXEntryActivity extends Activity implements IWXAPIEventHandler { + // IWXAPI 是第三方app和微信通信的openapi接口 + private IWXAPI api; + public static final String APPID = "wx8b41ad369eba83a9"; + public static final String SECRET = "de5faa683f384095d79c6a75305c2bf0"; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + // 通过WXAPIFactory工厂,获取IWXAPI的实例 + api = WXAPIFactory.createWXAPI(this, APPID, false); + api.handleIntent(getIntent(), this); + } + + @Override + protected void onNewIntent(Intent intent) { + super.onNewIntent(intent); + setIntent(intent); + api.handleIntent(intent, this); + } + + // 微信发送请求到第三方应用时,会回调到该方法 + @Override + public void onReq(BaseReq req) { + } + + @Override + public void onResp(BaseResp resp) { + if (resp.getType() == ConstantsAPI.COMMAND_SENDAUTH) { + switch (resp.errCode) { + case BaseResp.ErrCode.ERR_OK: + String code = ((SendAuth.Resp) resp).code; + EventBus.getDefault().post(new WxRespCodeEvent(code)); + break; + case BaseResp.ErrCode.ERR_USER_CANCEL: + ToastUtils.showShort("User cancel"); + break; + case BaseResp.ErrCode.ERR_AUTH_DENIED: + ToastUtils.showShort("Auth denied"); + break; + case BaseResp.ErrCode.ERR_COMM: + ToastUtils.showShort("Error Comm"); + break; + case BaseResp.ErrCode.ERR_SENT_FAILED: + ToastUtils.showShort("Send failed"); + break; + case BaseResp.ErrCode.ERR_UNSUPPORT: + ToastUtils.showShort("Error unsupported"); + break; + case BaseResp.ErrCode.ERR_BAN: + ToastUtils.showShort("Error ban"); + break; + } + } else if (resp.getType() == ConstantsAPI.COMMAND_SENDMESSAGE_TO_WX) { + switch (resp.errCode) { + case BaseResp.ErrCode.ERR_OK: + ToastUtils.showShort(R.string.share_success); + if (LCUser.getCurrentUser() != null) { + LCObject shareLog = new LCObject("ShareLog"); + shareLog.put("user", LCUser.getCurrentUser()); + shareLog.put("shareType", "wechat"); + shareLog.saveInBackground().subscribe(); + } + break; + case BaseResp.ErrCode.ERR_USER_CANCEL: + ToastUtils.showShort(R.string.share_cancel); + break; + case BaseResp.ErrCode.ERR_AUTH_DENIED: + ToastUtils.showShort(R.string.share_denied); + break; + case BaseResp.ErrCode.ERR_COMM: + ToastUtils.showShort("Error Comm"); + break; + case BaseResp.ErrCode.ERR_SENT_FAILED: + ToastUtils.showShort("Send failed"); + break; + case BaseResp.ErrCode.ERR_UNSUPPORT: + ToastUtils.showShort("Error unsupported"); + break; + case BaseResp.ErrCode.ERR_BAN: + ToastUtils.showShort("Error ban"); + break; + } + } + finish(); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/bingce/controlnetwork/wxapi/WXPayEntryActivity.java b/app/src/main/java/com/bingce/controlnetwork/wxapi/WXPayEntryActivity.java new file mode 100644 index 0000000..c6b8fe5 --- /dev/null +++ b/app/src/main/java/com/bingce/controlnetwork/wxapi/WXPayEntryActivity.java @@ -0,0 +1,51 @@ +package com.bingce.controlnetwork.wxapi; + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import android.util.Log; + +import com.bingce.event.PayOverEvent; +import com.tencent.mm.opensdk.constants.ConstantsAPI; +import com.tencent.mm.opensdk.modelbase.BaseReq; +import com.tencent.mm.opensdk.modelbase.BaseResp; +import com.tencent.mm.opensdk.openapi.IWXAPI; +import com.tencent.mm.opensdk.openapi.IWXAPIEventHandler; +import com.tencent.mm.opensdk.openapi.WXAPIFactory; + +import org.greenrobot.eventbus.EventBus; + +public class WXPayEntryActivity extends Activity implements IWXAPIEventHandler { + private IWXAPI api; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + api = WXAPIFactory.createWXAPI(this, Constants.APP_ID); + api.handleIntent(getIntent(), this); + } + + @Override + protected void onNewIntent(Intent intent) { + super.onNewIntent(intent); + setIntent(intent); + api.handleIntent(intent, this); + } + + @Override + public void onReq(BaseReq req) { + } + + @Override + public void onResp(BaseResp resp) { + if (resp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX) { + if (resp.errCode == 0) { + Log.d("WXPayEntryActivity", "Wechat pay success"); + } else { + Log.d("WXPayEntryActivity", "Wechat pay failed,errorCode:" + resp.errCode); + } + EventBus.getDefault().post(new PayOverEvent()); + } + finish(); + } +} \ No newline at end of file diff --git a/app/src/main/res/anim/dialog_enter_bottom.xml b/app/src/main/res/anim/dialog_enter_bottom.xml new file mode 100644 index 0000000..8f95a9c --- /dev/null +++ b/app/src/main/res/anim/dialog_enter_bottom.xml @@ -0,0 +1,6 @@ + + diff --git a/app/src/main/res/anim/dialog_exit_bottom.xml b/app/src/main/res/anim/dialog_exit_bottom.xml new file mode 100644 index 0000000..ad6db02 --- /dev/null +++ b/app/src/main/res/anim/dialog_exit_bottom.xml @@ -0,0 +1,6 @@ + + diff --git a/app/src/main/res/anim/fade_in_quick.xml b/app/src/main/res/anim/fade_in_quick.xml new file mode 100644 index 0000000..d418d73 --- /dev/null +++ b/app/src/main/res/anim/fade_in_quick.xml @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/app/src/main/res/anim/fade_out_quick.xml b/app/src/main/res/anim/fade_out_quick.xml new file mode 100644 index 0000000..f7ebe07 --- /dev/null +++ b/app/src/main/res/anim/fade_out_quick.xml @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/app/src/main/res/anim/slide_in_left.xml b/app/src/main/res/anim/slide_in_left.xml new file mode 100644 index 0000000..3921f79 --- /dev/null +++ b/app/src/main/res/anim/slide_in_left.xml @@ -0,0 +1,9 @@ + + + \ No newline at end of file diff --git a/app/src/main/res/anim/slide_in_right.xml b/app/src/main/res/anim/slide_in_right.xml new file mode 100644 index 0000000..105e2df --- /dev/null +++ b/app/src/main/res/anim/slide_in_right.xml @@ -0,0 +1,9 @@ + + + \ No newline at end of file diff --git a/app/src/main/res/anim/slide_out_left.xml b/app/src/main/res/anim/slide_out_left.xml new file mode 100644 index 0000000..3375d2c --- /dev/null +++ b/app/src/main/res/anim/slide_out_left.xml @@ -0,0 +1,9 @@ + + + \ No newline at end of file diff --git a/app/src/main/res/anim/slide_out_right.xml b/app/src/main/res/anim/slide_out_right.xml new file mode 100644 index 0000000..1f58f97 --- /dev/null +++ b/app/src/main/res/anim/slide_out_right.xml @@ -0,0 +1,9 @@ + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-hdpi/icon_small.png b/app/src/main/res/drawable-hdpi/icon_small.png new file mode 100644 index 0000000..9b1f17e Binary files /dev/null and b/app/src/main/res/drawable-hdpi/icon_small.png differ diff --git a/app/src/main/res/drawable-v21/blue_bg.xml b/app/src/main/res/drawable-v21/blue_bg.xml new file mode 100644 index 0000000..c5476cd --- /dev/null +++ b/app/src/main/res/drawable-v21/blue_bg.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v21/fab_label_background.xml b/app/src/main/res/drawable-v21/fab_label_background.xml new file mode 100644 index 0000000..bd7694d --- /dev/null +++ b/app/src/main/res/drawable-v21/fab_label_background.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v21/ic_keyboard_arrow_right_white_24px.xml b/app/src/main/res/drawable-v21/ic_keyboard_arrow_right_white_24px.xml new file mode 100644 index 0000000..8ca5856 --- /dev/null +++ b/app/src/main/res/drawable-v21/ic_keyboard_arrow_right_white_24px.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable-v23/app_background.xml b/app/src/main/res/drawable-v23/app_background.xml new file mode 100644 index 0000000..0c6828d --- /dev/null +++ b/app/src/main/res/drawable-v23/app_background.xml @@ -0,0 +1,16 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v23/icon_control_logo.png b/app/src/main/res/drawable-v23/icon_control_logo.png new file mode 100644 index 0000000..7c6ad3b Binary files /dev/null and b/app/src/main/res/drawable-v23/icon_control_logo.png differ diff --git a/app/src/main/res/drawable-v23/icon_control_text.png b/app/src/main/res/drawable-v23/icon_control_text.png new file mode 100644 index 0000000..a59c39c Binary files /dev/null and b/app/src/main/res/drawable-v23/icon_control_text.png differ diff --git a/app/src/main/res/drawable-xxhdpi/efp__ic_file.png b/app/src/main/res/drawable-xxhdpi/efp__ic_file.png new file mode 100644 index 0000000..b16f633 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/efp__ic_file.png differ diff --git a/app/src/main/res/drawable-xxhdpi/efp__ic_folder.png b/app/src/main/res/drawable-xxhdpi/efp__ic_folder.png new file mode 100644 index 0000000..34d99b4 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/efp__ic_folder.png differ diff --git a/app/src/main/res/drawable-xxhdpi/efp__ic_up.png b/app/src/main/res/drawable-xxhdpi/efp__ic_up.png new file mode 100644 index 0000000..365dc98 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/efp__ic_up.png differ diff --git a/app/src/main/res/drawable-xxhdpi/efp_dark__ic_action_cancel.png b/app/src/main/res/drawable-xxhdpi/efp_dark__ic_action_cancel.png new file mode 100644 index 0000000..1882222 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/efp_dark__ic_action_cancel.png differ diff --git a/app/src/main/res/drawable-xxhdpi/efp_dark__ic_action_deselect.png b/app/src/main/res/drawable-xxhdpi/efp_dark__ic_action_deselect.png new file mode 100644 index 0000000..d584a20 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/efp_dark__ic_action_deselect.png differ diff --git a/app/src/main/res/drawable-xxhdpi/efp_dark__ic_action_grid.png b/app/src/main/res/drawable-xxhdpi/efp_dark__ic_action_grid.png new file mode 100644 index 0000000..7ba62af Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/efp_dark__ic_action_grid.png differ diff --git a/app/src/main/res/drawable-xxhdpi/efp_dark__ic_action_invert_selection.png b/app/src/main/res/drawable-xxhdpi/efp_dark__ic_action_invert_selection.png new file mode 100644 index 0000000..14a209d Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/efp_dark__ic_action_invert_selection.png differ diff --git a/app/src/main/res/drawable-xxhdpi/efp_dark__ic_action_list.png b/app/src/main/res/drawable-xxhdpi/efp_dark__ic_action_list.png new file mode 100644 index 0000000..1d49459 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/efp_dark__ic_action_list.png differ diff --git a/app/src/main/res/drawable-xxhdpi/efp_dark__ic_action_new_folder.png b/app/src/main/res/drawable-xxhdpi/efp_dark__ic_action_new_folder.png new file mode 100644 index 0000000..d40425b Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/efp_dark__ic_action_new_folder.png differ diff --git a/app/src/main/res/drawable-xxhdpi/efp_dark__ic_action_ok.png b/app/src/main/res/drawable-xxhdpi/efp_dark__ic_action_ok.png new file mode 100644 index 0000000..3121792 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/efp_dark__ic_action_ok.png differ diff --git a/app/src/main/res/drawable-xxhdpi/efp_dark__ic_action_select_all.png b/app/src/main/res/drawable-xxhdpi/efp_dark__ic_action_select_all.png new file mode 100644 index 0000000..001be8e Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/efp_dark__ic_action_select_all.png differ diff --git a/app/src/main/res/drawable-xxhdpi/efp_dark__ic_action_sort.png b/app/src/main/res/drawable-xxhdpi/efp_dark__ic_action_sort.png new file mode 100644 index 0000000..f5576db Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/efp_dark__ic_action_sort.png differ diff --git a/app/src/main/res/drawable-xxhdpi/efp_dark__ic_action_storage.png b/app/src/main/res/drawable-xxhdpi/efp_dark__ic_action_storage.png new file mode 100644 index 0000000..d361dd6 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/efp_dark__ic_action_storage.png differ diff --git a/app/src/main/res/drawable-xxhdpi/icon_back.png b/app/src/main/res/drawable-xxhdpi/icon_back.png new file mode 100644 index 0000000..85690e7 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/icon_back.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon.png b/app/src/main/res/drawable-xxxhdpi/icon.png new file mode 100644 index 0000000..c3623f3 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon.png differ diff --git a/app/src/main/res/drawable/app_background.xml b/app/src/main/res/drawable/app_background.xml new file mode 100644 index 0000000..c3a462d --- /dev/null +++ b/app/src/main/res/drawable/app_background.xml @@ -0,0 +1,21 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/app_logo.xml b/app/src/main/res/drawable/app_logo.xml new file mode 100644 index 0000000..d808488 --- /dev/null +++ b/app/src/main/res/drawable/app_logo.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/baseline_reorder_grey_600_24dp.xml b/app/src/main/res/drawable/baseline_reorder_grey_600_24dp.xml new file mode 100644 index 0000000..464d5c6 --- /dev/null +++ b/app/src/main/res/drawable/baseline_reorder_grey_600_24dp.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/app/src/main/res/drawable/bg_circle_gary_chatui.xml b/app/src/main/res/drawable/bg_circle_gary_chatui.xml new file mode 100644 index 0000000..b7f43ad --- /dev/null +++ b/app/src/main/res/drawable/bg_circle_gary_chatui.xml @@ -0,0 +1,16 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_circle_white_chatui.xml b/app/src/main/res/drawable/bg_circle_white_chatui.xml new file mode 100644 index 0000000..39f83b6 --- /dev/null +++ b/app/src/main/res/drawable/bg_circle_white_chatui.xml @@ -0,0 +1,16 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_gray_3.xml b/app/src/main/res/drawable/bg_gray_3.xml new file mode 100644 index 0000000..ef1e19d --- /dev/null +++ b/app/src/main/res/drawable/bg_gray_3.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_spinner.xml b/app/src/main/res/drawable/bg_spinner.xml new file mode 100644 index 0000000..4a104ec --- /dev/null +++ b/app/src/main/res/drawable/bg_spinner.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/bg_splash.xml b/app/src/main/res/drawable/bg_splash.xml new file mode 100644 index 0000000..5efe8a6 --- /dev/null +++ b/app/src/main/res/drawable/bg_splash.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_table_color1.xml b/app/src/main/res/drawable/bg_table_color1.xml new file mode 100644 index 0000000..0fba3fc --- /dev/null +++ b/app/src/main/res/drawable/bg_table_color1.xml @@ -0,0 +1,9 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_table_color2.xml b/app/src/main/res/drawable/bg_table_color2.xml new file mode 100644 index 0000000..4d3b839 --- /dev/null +++ b/app/src/main/res/drawable/bg_table_color2.xml @@ -0,0 +1,9 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_table_family.xml b/app/src/main/res/drawable/bg_table_family.xml new file mode 100644 index 0000000..c37ffc7 --- /dev/null +++ b/app/src/main/res/drawable/bg_table_family.xml @@ -0,0 +1,9 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_white_3.xml b/app/src/main/res/drawable/bg_white_3.xml new file mode 100644 index 0000000..d81ac0e --- /dev/null +++ b/app/src/main/res/drawable/bg_white_3.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/clickable_blue_bg.xml b/app/src/main/res/drawable/clickable_blue_bg.xml new file mode 100644 index 0000000..86ba277 --- /dev/null +++ b/app/src/main/res/drawable/clickable_blue_bg.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/corners_edit_chatui.xml b/app/src/main/res/drawable/corners_edit_chatui.xml new file mode 100644 index 0000000..12f1494 --- /dev/null +++ b/app/src/main/res/drawable/corners_edit_chatui.xml @@ -0,0 +1,16 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/corners_edit_white_chatui.xml b/app/src/main/res/drawable/corners_edit_white_chatui.xml new file mode 100644 index 0000000..fc471bd --- /dev/null +++ b/app/src/main/res/drawable/corners_edit_white_chatui.xml @@ -0,0 +1,16 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/drawer_header.jpg b/app/src/main/res/drawable/drawer_header.jpg new file mode 100644 index 0000000..f54a30e Binary files /dev/null and b/app/src/main/res/drawable/drawer_header.jpg differ diff --git a/app/src/main/res/drawable/edit_spinner_text_color.xml b/app/src/main/res/drawable/edit_spinner_text_color.xml new file mode 100644 index 0000000..f1b8303 --- /dev/null +++ b/app/src/main/res/drawable/edit_spinner_text_color.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/fab_label_background.xml b/app/src/main/res/drawable/fab_label_background.xml new file mode 100644 index 0000000..f0efb9c --- /dev/null +++ b/app/src/main/res/drawable/fab_label_background.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_arrow_down.xml b/app/src/main/res/drawable/ic_arrow_down.xml new file mode 100644 index 0000000..0cace5d --- /dev/null +++ b/app/src/main/res/drawable/ic_arrow_down.xml @@ -0,0 +1,12 @@ + + + diff --git a/app/src/main/res/drawable/ic_arrow_to_right_dark.xml b/app/src/main/res/drawable/ic_arrow_to_right_dark.xml new file mode 100644 index 0000000..c854061 --- /dev/null +++ b/app/src/main/res/drawable/ic_arrow_to_right_dark.xml @@ -0,0 +1,14 @@ + + + diff --git a/app/src/main/res/drawable/ic_arrow_up.xml b/app/src/main/res/drawable/ic_arrow_up.xml new file mode 100644 index 0000000..7ede1fd --- /dev/null +++ b/app/src/main/res/drawable/ic_arrow_up.xml @@ -0,0 +1,12 @@ + + + diff --git a/app/src/main/res/drawable/ic_backup.xml b/app/src/main/res/drawable/ic_backup.xml new file mode 100644 index 0000000..7f36a13 --- /dev/null +++ b/app/src/main/res/drawable/ic_backup.xml @@ -0,0 +1,24 @@ + + + + + diff --git a/app/src/main/res/drawable/ic_baseline_clear_all_24.xml b/app/src/main/res/drawable/ic_baseline_clear_all_24.xml new file mode 100644 index 0000000..54ca983 --- /dev/null +++ b/app/src/main/res/drawable/ic_baseline_clear_all_24.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/drawable/ic_close_black_24dp.xml b/app/src/main/res/drawable/ic_close_black_24dp.xml new file mode 100644 index 0000000..e700807 --- /dev/null +++ b/app/src/main/res/drawable/ic_close_black_24dp.xml @@ -0,0 +1,9 @@ + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_custom_tolerance.xml b/app/src/main/res/drawable/ic_custom_tolerance.xml new file mode 100644 index 0000000..7c5abcb --- /dev/null +++ b/app/src/main/res/drawable/ic_custom_tolerance.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_export.xml b/app/src/main/res/drawable/ic_export.xml new file mode 100644 index 0000000..81bf256 --- /dev/null +++ b/app/src/main/res/drawable/ic_export.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/app/src/main/res/drawable/ic_export_height_traverse.xml b/app/src/main/res/drawable/ic_export_height_traverse.xml new file mode 100644 index 0000000..7d86cf4 --- /dev/null +++ b/app/src/main/res/drawable/ic_export_height_traverse.xml @@ -0,0 +1,28 @@ + + + + + + + + diff --git a/app/src/main/res/drawable/ic_export_wire.xml b/app/src/main/res/drawable/ic_export_wire.xml new file mode 100644 index 0000000..dbd25fc --- /dev/null +++ b/app/src/main/res/drawable/ic_export_wire.xml @@ -0,0 +1,15 @@ + + + + + diff --git a/app/src/main/res/drawable/ic_indeterminate_check_box_black_24dp.xml b/app/src/main/res/drawable/ic_indeterminate_check_box_black_24dp.xml new file mode 100644 index 0000000..8eb1cdc --- /dev/null +++ b/app/src/main/res/drawable/ic_indeterminate_check_box_black_24dp.xml @@ -0,0 +1,5 @@ + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_known_point_24.xml b/app/src/main/res/drawable/ic_known_point_24.xml new file mode 100644 index 0000000..3958816 --- /dev/null +++ b/app/src/main/res/drawable/ic_known_point_24.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/drawable/ic_ruler_selected.xml b/app/src/main/res/drawable/ic_ruler_selected.xml new file mode 100644 index 0000000..89d5af7 --- /dev/null +++ b/app/src/main/res/drawable/ic_ruler_selected.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_ruler_unselected.xml b/app/src/main/res/drawable/ic_ruler_unselected.xml new file mode 100644 index 0000000..e752d51 --- /dev/null +++ b/app/src/main/res/drawable/ic_ruler_unselected.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_selected.xml b/app/src/main/res/drawable/ic_selected.xml new file mode 100644 index 0000000..1f7954f --- /dev/null +++ b/app/src/main/res/drawable/ic_selected.xml @@ -0,0 +1,12 @@ + + + diff --git a/app/src/main/res/drawable/ic_surveyor_24.xml b/app/src/main/res/drawable/ic_surveyor_24.xml new file mode 100644 index 0000000..42e97a5 --- /dev/null +++ b/app/src/main/res/drawable/ic_surveyor_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_switch.xml b/app/src/main/res/drawable/ic_switch.xml new file mode 100644 index 0000000..19c8834 --- /dev/null +++ b/app/src/main/res/drawable/ic_switch.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_tab_project_selected.xml b/app/src/main/res/drawable/ic_tab_project_selected.xml new file mode 100644 index 0000000..989b828 --- /dev/null +++ b/app/src/main/res/drawable/ic_tab_project_selected.xml @@ -0,0 +1,12 @@ + + + diff --git a/app/src/main/res/drawable/ic_tab_project_unselect.xml b/app/src/main/res/drawable/ic_tab_project_unselect.xml new file mode 100644 index 0000000..a00f0f2 --- /dev/null +++ b/app/src/main/res/drawable/ic_tab_project_unselect.xml @@ -0,0 +1,12 @@ + + + diff --git a/app/src/main/res/drawable/ic_tolerance_24.xml b/app/src/main/res/drawable/ic_tolerance_24.xml new file mode 100644 index 0000000..f6d7895 --- /dev/null +++ b/app/src/main/res/drawable/ic_tolerance_24.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_unknown_point_24.xml b/app/src/main/res/drawable/ic_unknown_point_24.xml new file mode 100644 index 0000000..3167e8a --- /dev/null +++ b/app/src/main/res/drawable/ic_unknown_point_24.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/drawable/icon_avatar.xml b/app/src/main/res/drawable/icon_avatar.xml new file mode 100644 index 0000000..0684437 --- /dev/null +++ b/app/src/main/res/drawable/icon_avatar.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + diff --git a/app/src/main/res/drawable/icon_control_logo.png b/app/src/main/res/drawable/icon_control_logo.png new file mode 100644 index 0000000..c21729a Binary files /dev/null and b/app/src/main/res/drawable/icon_control_logo.png differ diff --git a/app/src/main/res/drawable/icon_control_text.png b/app/src/main/res/drawable/icon_control_text.png new file mode 100644 index 0000000..6dc8030 Binary files /dev/null and b/app/src/main/res/drawable/icon_control_text.png differ diff --git a/app/src/main/res/drawable/icon_parameter_points.xml b/app/src/main/res/drawable/icon_parameter_points.xml new file mode 100644 index 0000000..557f883 --- /dev/null +++ b/app/src/main/res/drawable/icon_parameter_points.xml @@ -0,0 +1,15 @@ + + + + + diff --git a/app/src/main/res/drawable/icon_prism_manager.xml b/app/src/main/res/drawable/icon_prism_manager.xml new file mode 100644 index 0000000..8a822d5 --- /dev/null +++ b/app/src/main/res/drawable/icon_prism_manager.xml @@ -0,0 +1,28 @@ + + + + + + + + + + diff --git a/app/src/main/res/drawable/icon_ts_connecting.xml b/app/src/main/res/drawable/icon_ts_connecting.xml new file mode 100644 index 0000000..a1b4c8c --- /dev/null +++ b/app/src/main/res/drawable/icon_ts_connecting.xml @@ -0,0 +1,20 @@ + + + + + + diff --git a/app/src/main/res/drawable/img_request_android_data_access_permission.jpg b/app/src/main/res/drawable/img_request_android_data_access_permission.jpg new file mode 100644 index 0000000..8c01cad Binary files /dev/null and b/app/src/main/res/drawable/img_request_android_data_access_permission.jpg differ diff --git a/app/src/main/res/drawable/img_weixin_download_guide.jpg b/app/src/main/res/drawable/img_weixin_download_guide.jpg new file mode 100644 index 0000000..d29adfd Binary files /dev/null and b/app/src/main/res/drawable/img_weixin_download_guide.jpg differ diff --git a/app/src/main/res/drawable/iv_back_selector.xml b/app/src/main/res/drawable/iv_back_selector.xml new file mode 100644 index 0000000..b0d09d5 --- /dev/null +++ b/app/src/main/res/drawable/iv_back_selector.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/line_horizontal.xml b/app/src/main/res/drawable/line_horizontal.xml new file mode 100644 index 0000000..429565c --- /dev/null +++ b/app/src/main/res/drawable/line_horizontal.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/loading_circle.xml b/app/src/main/res/drawable/loading_circle.xml new file mode 100644 index 0000000..dce7824 --- /dev/null +++ b/app/src/main/res/drawable/loading_circle.xml @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/loading_dialog_bg_ll.xml b/app/src/main/res/drawable/loading_dialog_bg_ll.xml new file mode 100644 index 0000000..17072d0 --- /dev/null +++ b/app/src/main/res/drawable/loading_dialog_bg_ll.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/loading_dialog_bg_progress_bar.xml b/app/src/main/res/drawable/loading_dialog_bg_progress_bar.xml new file mode 100644 index 0000000..fdcbb79 --- /dev/null +++ b/app/src/main/res/drawable/loading_dialog_bg_progress_bar.xml @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/app/src/main/res/drawable/loading_dialog_pic.png b/app/src/main/res/drawable/loading_dialog_pic.png new file mode 100644 index 0000000..38151ee Binary files /dev/null and b/app/src/main/res/drawable/loading_dialog_pic.png differ diff --git a/app/src/main/res/drawable/msg_state_fail_resend.png b/app/src/main/res/drawable/msg_state_fail_resend.png new file mode 100644 index 0000000..0dca30d Binary files /dev/null and b/app/src/main/res/drawable/msg_state_fail_resend.png differ diff --git a/app/src/main/res/drawable/record_microphone_bj_chatui.xml b/app/src/main/res/drawable/record_microphone_bj_chatui.xml new file mode 100644 index 0000000..e280578 --- /dev/null +++ b/app/src/main/res/drawable/record_microphone_bj_chatui.xml @@ -0,0 +1,11 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/record_microphone_chatui.xml b/app/src/main/res/drawable/record_microphone_chatui.xml new file mode 100644 index 0000000..b4328ac --- /dev/null +++ b/app/src/main/res/drawable/record_microphone_chatui.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/recyclerview_divider.xml b/app/src/main/res/drawable/recyclerview_divider.xml new file mode 100644 index 0000000..111d79d --- /dev/null +++ b/app/src/main/res/drawable/recyclerview_divider.xml @@ -0,0 +1,24 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/round_btn_bg.xml b/app/src/main/res/drawable/round_btn_bg.xml new file mode 100644 index 0000000..dfdc7dd --- /dev/null +++ b/app/src/main/res/drawable/round_btn_bg.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/round_btn_bg_colormay_3.xml b/app/src/main/res/drawable/round_btn_bg_colormay_3.xml new file mode 100644 index 0000000..2d31948 --- /dev/null +++ b/app/src/main/res/drawable/round_btn_bg_colormay_3.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/round_btn_bg_gray_3.xml b/app/src/main/res/drawable/round_btn_bg_gray_3.xml new file mode 100644 index 0000000..4c90a6f --- /dev/null +++ b/app/src/main/res/drawable/round_btn_bg_gray_3.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/round_white.xml b/app/src/main/res/drawable/round_white.xml new file mode 100644 index 0000000..bf751de --- /dev/null +++ b/app/src/main/res/drawable/round_white.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/round_white_10.xml b/app/src/main/res/drawable/round_white_10.xml new file mode 100644 index 0000000..261d165 --- /dev/null +++ b/app/src/main/res/drawable/round_white_10.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/round_white_16.xml b/app/src/main/res/drawable/round_white_16.xml new file mode 100644 index 0000000..0229f6a --- /dev/null +++ b/app/src/main/res/drawable/round_white_16.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/select_mask.xml b/app/src/main/res/drawable/select_mask.xml new file mode 100644 index 0000000..99e9205 --- /dev/null +++ b/app/src/main/res/drawable/select_mask.xml @@ -0,0 +1,9 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/separator_table.xml b/app/src/main/res/drawable/separator_table.xml new file mode 100644 index 0000000..6101b0a --- /dev/null +++ b/app/src/main/res/drawable/separator_table.xml @@ -0,0 +1,8 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/separator_table_first.xml b/app/src/main/res/drawable/separator_table_first.xml new file mode 100644 index 0000000..fd06fa7 --- /dev/null +++ b/app/src/main/res/drawable/separator_table_first.xml @@ -0,0 +1,8 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/separator_table_header.xml b/app/src/main/res/drawable/separator_table_header.xml new file mode 100644 index 0000000..c18dbe2 --- /dev/null +++ b/app/src/main/res/drawable/separator_table_header.xml @@ -0,0 +1,8 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/separator_table_header_first.xml b/app/src/main/res/drawable/separator_table_header_first.xml new file mode 100644 index 0000000..37f083e --- /dev/null +++ b/app/src/main/res/drawable/separator_table_header_first.xml @@ -0,0 +1,8 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/tab_shadow.xml b/app/src/main/res/drawable/tab_shadow.xml new file mode 100644 index 0000000..6a01a85 --- /dev/null +++ b/app/src/main/res/drawable/tab_shadow.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/transparent_ripple_bg.xml b/app/src/main/res/drawable/transparent_ripple_bg.xml new file mode 100644 index 0000000..1898644 --- /dev/null +++ b/app/src/main/res/drawable/transparent_ripple_bg.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/voice_left_chatui.xml b/app/src/main/res/drawable/voice_left_chatui.xml new file mode 100644 index 0000000..0d40788 --- /dev/null +++ b/app/src/main/res/drawable/voice_left_chatui.xml @@ -0,0 +1,16 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/voice_right_chatui.xml b/app/src/main/res/drawable/voice_right_chatui.xml new file mode 100644 index 0000000..a1907ad --- /dev/null +++ b/app/src/main/res/drawable/voice_right_chatui.xml @@ -0,0 +1,16 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/white_ripple_bg.xml b/app/src/main/res/drawable/white_ripple_bg.xml new file mode 100644 index 0000000..b2b79f0 --- /dev/null +++ b/app/src/main/res/drawable/white_ripple_bg.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/wifi_chat_item_left_bg.9.png b/app/src/main/res/drawable/wifi_chat_item_left_bg.9.png new file mode 100644 index 0000000..ebbac7c Binary files /dev/null and b/app/src/main/res/drawable/wifi_chat_item_left_bg.9.png differ diff --git a/app/src/main/res/drawable/wifi_chat_item_right_bg.9.png b/app/src/main/res/drawable/wifi_chat_item_right_bg.9.png new file mode 100644 index 0000000..86fa7f7 Binary files /dev/null and b/app/src/main/res/drawable/wifi_chat_item_right_bg.9.png differ diff --git a/app/src/main/res/layout/activity_about.xml b/app/src/main/res/layout/activity_about.xml new file mode 100644 index 0000000..39beb62 --- /dev/null +++ b/app/src/main/res/layout/activity_about.xml @@ -0,0 +1,13 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_activate.xml b/app/src/main/res/layout/activity_activate.xml new file mode 100644 index 0000000..90b3ec2 --- /dev/null +++ b/app/src/main/res/layout/activity_activate.xml @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + +