diff --git a/.gitignore b/.gitignore index c730ec13..4e5df9bd 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,11 @@ /dist /coverage /playwright-report -/test-results \ No newline at end of file +/test-results + +# Flutter +mobile_app/build/ +mobile_app/.dart_tool/ +mobile_app/.flutter-plugins +mobile_app/.flutter-plugins-dependencies +mobile_app/assets/www/ diff --git a/mobile_app/.gitignore b/mobile_app/.gitignore new file mode 100644 index 00000000..3820a95c --- /dev/null +++ b/mobile_app/.gitignore @@ -0,0 +1,45 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.build/ +.buildlog/ +.history +.svn/ +.swiftpm/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins-dependencies +.pub-cache/ +.pub/ +/build/ +/coverage/ + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Android Studio will place build artifacts here +/android/app/debug +/android/app/profile +/android/app/release diff --git a/mobile_app/.metadata b/mobile_app/.metadata new file mode 100644 index 00000000..08c24780 --- /dev/null +++ b/mobile_app/.metadata @@ -0,0 +1,45 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: "3b62efc2a3da49882f43c372e0bc53daef7295a6" + channel: "stable" + +project_type: app + +# Tracks metadata for the flutter migrate command +migration: + platforms: + - platform: root + create_revision: 3b62efc2a3da49882f43c372e0bc53daef7295a6 + base_revision: 3b62efc2a3da49882f43c372e0bc53daef7295a6 + - platform: android + create_revision: 3b62efc2a3da49882f43c372e0bc53daef7295a6 + base_revision: 3b62efc2a3da49882f43c372e0bc53daef7295a6 + - platform: ios + create_revision: 3b62efc2a3da49882f43c372e0bc53daef7295a6 + base_revision: 3b62efc2a3da49882f43c372e0bc53daef7295a6 + - platform: linux + create_revision: 3b62efc2a3da49882f43c372e0bc53daef7295a6 + base_revision: 3b62efc2a3da49882f43c372e0bc53daef7295a6 + - platform: macos + create_revision: 3b62efc2a3da49882f43c372e0bc53daef7295a6 + base_revision: 3b62efc2a3da49882f43c372e0bc53daef7295a6 + - platform: web + create_revision: 3b62efc2a3da49882f43c372e0bc53daef7295a6 + base_revision: 3b62efc2a3da49882f43c372e0bc53daef7295a6 + - platform: windows + create_revision: 3b62efc2a3da49882f43c372e0bc53daef7295a6 + base_revision: 3b62efc2a3da49882f43c372e0bc53daef7295a6 + + # User provided section + + # List of Local paths (relative to this file) that should be + # ignored by the migrate tool. + # + # Files that are not part of the templates will be ignored by default. + unmanaged_files: + - 'lib/main.dart' + - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/mobile_app/README.md b/mobile_app/README.md new file mode 100644 index 00000000..1dfe8881 --- /dev/null +++ b/mobile_app/README.md @@ -0,0 +1,16 @@ +# mobile_app + +A new Flutter project. + +## Getting Started + +This project is a starting point for a Flutter application. + +A few resources to get you started if this is your first Flutter project: + +- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab) +- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook) + +For help getting started with Flutter development, view the +[online documentation](https://docs.flutter.dev/), which offers tutorials, +samples, guidance on mobile development, and a full API reference. diff --git a/mobile_app/analysis_options.yaml b/mobile_app/analysis_options.yaml new file mode 100644 index 00000000..0d290213 --- /dev/null +++ b/mobile_app/analysis_options.yaml @@ -0,0 +1,28 @@ +# This file configures the analyzer, which statically analyzes Dart code to +# check for errors, warnings, and lints. +# +# The issues identified by the analyzer are surfaced in the UI of Dart-enabled +# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be +# invoked from the command line by running `flutter analyze`. + +# The following line activates a set of recommended lints for Flutter apps, +# packages, and plugins designed to encourage good coding practices. +include: package:flutter_lints/flutter.yaml + +linter: + # The lint rules applied to this project can be customized in the + # section below to disable rules from the `package:flutter_lints/flutter.yaml` + # included above or to enable additional rules. A list of all available lints + # and their documentation is published at https://dart.dev/lints. + # + # Instead of disabling a lint rule for the entire project in the + # section below, it can also be suppressed for a single line of code + # or a specific dart file by using the `// ignore: name_of_lint` and + # `// ignore_for_file: name_of_lint` syntax on the line or in the file + # producing the lint. + rules: + # avoid_print: false # Uncomment to disable the `avoid_print` rule + # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/mobile_app/android/.gitignore b/mobile_app/android/.gitignore new file mode 100644 index 00000000..be3943c9 --- /dev/null +++ b/mobile_app/android/.gitignore @@ -0,0 +1,14 @@ +gradle-wrapper.jar +/.gradle +/captures/ +/gradlew +/gradlew.bat +/local.properties +GeneratedPluginRegistrant.java +.cxx/ + +# Remember to never publicly share your keystore. +# See https://flutter.dev/to/reference-keystore +key.properties +**/*.keystore +**/*.jks diff --git a/mobile_app/android/app/build.gradle.kts b/mobile_app/android/app/build.gradle.kts new file mode 100644 index 00000000..12c49539 --- /dev/null +++ b/mobile_app/android/app/build.gradle.kts @@ -0,0 +1,44 @@ +plugins { + id("com.android.application") + id("kotlin-android") + // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins. + id("dev.flutter.flutter-gradle-plugin") +} + +android { + namespace = "com.example.mobile_app" + compileSdk = flutter.compileSdkVersion + ndkVersion = flutter.ndkVersion + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 + } + + kotlinOptions { + jvmTarget = JavaVersion.VERSION_17.toString() + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId = "com.example.mobile_app" + // You can update the following values to match your application needs. + // For more information, see: https://flutter.dev/to/review-gradle-config. + minSdk = flutter.minSdkVersion + targetSdk = flutter.targetSdkVersion + versionCode = flutter.versionCode + versionName = flutter.versionName + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig = signingConfigs.getByName("debug") + } + } +} + +flutter { + source = "../.." +} diff --git a/mobile_app/android/app/src/debug/AndroidManifest.xml b/mobile_app/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 00000000..399f6981 --- /dev/null +++ b/mobile_app/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/mobile_app/android/app/src/main/AndroidManifest.xml b/mobile_app/android/app/src/main/AndroidManifest.xml new file mode 100644 index 00000000..8a6ec2a4 --- /dev/null +++ b/mobile_app/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/android/app/src/main/kotlin/com/example/mobile_app/MainActivity.kt b/mobile_app/android/app/src/main/kotlin/com/example/mobile_app/MainActivity.kt new file mode 100644 index 00000000..a7db5826 --- /dev/null +++ b/mobile_app/android/app/src/main/kotlin/com/example/mobile_app/MainActivity.kt @@ -0,0 +1,5 @@ +package com.example.mobile_app + +import io.flutter.embedding.android.FlutterActivity + +class MainActivity : FlutterActivity() diff --git a/mobile_app/android/app/src/main/res/drawable-v21/launch_background.xml b/mobile_app/android/app/src/main/res/drawable-v21/launch_background.xml new file mode 100644 index 00000000..f74085f3 --- /dev/null +++ b/mobile_app/android/app/src/main/res/drawable-v21/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/mobile_app/android/app/src/main/res/drawable/launch_background.xml b/mobile_app/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 00000000..304732f8 --- /dev/null +++ b/mobile_app/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/mobile_app/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/mobile_app/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 00000000..db77bb4b Binary files /dev/null and b/mobile_app/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/mobile_app/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/mobile_app/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 00000000..17987b79 Binary files /dev/null and b/mobile_app/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/mobile_app/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/mobile_app/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 00000000..09d43914 Binary files /dev/null and b/mobile_app/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/mobile_app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/mobile_app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 00000000..d5f1c8d3 Binary files /dev/null and b/mobile_app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/mobile_app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/mobile_app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 00000000..4d6372ee Binary files /dev/null and b/mobile_app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/mobile_app/android/app/src/main/res/values-night/styles.xml b/mobile_app/android/app/src/main/res/values-night/styles.xml new file mode 100644 index 00000000..06952be7 --- /dev/null +++ b/mobile_app/android/app/src/main/res/values-night/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/mobile_app/android/app/src/main/res/values/styles.xml b/mobile_app/android/app/src/main/res/values/styles.xml new file mode 100644 index 00000000..cb1ef880 --- /dev/null +++ b/mobile_app/android/app/src/main/res/values/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/mobile_app/android/app/src/profile/AndroidManifest.xml b/mobile_app/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 00000000..399f6981 --- /dev/null +++ b/mobile_app/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/mobile_app/android/build.gradle.kts b/mobile_app/android/build.gradle.kts new file mode 100644 index 00000000..dbee657b --- /dev/null +++ b/mobile_app/android/build.gradle.kts @@ -0,0 +1,24 @@ +allprojects { + repositories { + google() + mavenCentral() + } +} + +val newBuildDir: Directory = + rootProject.layout.buildDirectory + .dir("../../build") + .get() +rootProject.layout.buildDirectory.value(newBuildDir) + +subprojects { + val newSubprojectBuildDir: Directory = newBuildDir.dir(project.name) + project.layout.buildDirectory.value(newSubprojectBuildDir) +} +subprojects { + project.evaluationDependsOn(":app") +} + +tasks.register("clean") { + delete(rootProject.layout.buildDirectory) +} diff --git a/mobile_app/android/gradle.properties b/mobile_app/android/gradle.properties new file mode 100644 index 00000000..fbee1d8c --- /dev/null +++ b/mobile_app/android/gradle.properties @@ -0,0 +1,2 @@ +org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m -XX:+HeapDumpOnOutOfMemoryError +android.useAndroidX=true diff --git a/mobile_app/android/gradle/wrapper/gradle-wrapper.properties b/mobile_app/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..e4ef43fb --- /dev/null +++ b/mobile_app/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-all.zip diff --git a/mobile_app/android/settings.gradle.kts b/mobile_app/android/settings.gradle.kts new file mode 100644 index 00000000..ca7fe065 --- /dev/null +++ b/mobile_app/android/settings.gradle.kts @@ -0,0 +1,26 @@ +pluginManagement { + val flutterSdkPath = + run { + val properties = java.util.Properties() + file("local.properties").inputStream().use { properties.load(it) } + val flutterSdkPath = properties.getProperty("flutter.sdk") + require(flutterSdkPath != null) { "flutter.sdk not set in local.properties" } + flutterSdkPath + } + + includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") + + repositories { + google() + mavenCentral() + gradlePluginPortal() + } +} + +plugins { + id("dev.flutter.flutter-plugin-loader") version "1.0.0" + id("com.android.application") version "8.11.1" apply false + id("org.jetbrains.kotlin.android") version "2.2.20" apply false +} + +include(":app") diff --git a/mobile_app/assets/www/assets/engine-CK0IqSPu.js b/mobile_app/assets/www/assets/engine-CK0IqSPu.js new file mode 100644 index 00000000..3c747fef --- /dev/null +++ b/mobile_app/assets/www/assets/engine-CK0IqSPu.js @@ -0,0 +1,57 @@ +import"./modulepreload-polyfill-B5Qt9EMX.js";function u(h){window.MapController=h,console.log("MapController API initialized")}class f{x=0;y=0;zoom=1;worldWidth;worldHeight;canvas;constructor(t,e,r){this.canvas=t,this.worldWidth=e,this.worldHeight=r,this.x=e/2,this.y=r/2,this.attachControls()}getMatrix(){const t=this.canvas.width/this.canvas.height,e=this.worldWidth/this.zoom,r=e/t,i=2/e,s=2/r;return new Float32Array([i,0,0,0,-s,0,-this.x*i,this.y*s,1])}attachControls(){let t=!1,e=0,r=0;this.canvas.addEventListener("mousedown",i=>{t=!0,e=i.clientX,r=i.clientY}),window.addEventListener("mouseup",()=>{t=!1}),this.canvas.addEventListener("mousemove",i=>{if(!t)return;const s=i.clientX-e,o=i.clientY-r;e=i.clientX,r=i.clientY;const l=this.worldWidth/this.zoom/this.canvas.width;this.x-=s*l,this.y-=o*l}),this.canvas.addEventListener("wheel",i=>{i.preventDefault();const s=1.1,o=i.deltaY<0?s:1/s,a=Math.max(.1,Math.min(this.zoom*o,100));this.zoom=a},{passive:!1})}}class g{nodes=[];data;width;height;threshold;constructor(t,e,r,i=20){this.data=t,this.width=e,this.height=r,this.threshold=i}build(){return this.nodes=[],this.split(0,0,this.width),this.nodes}queryRange(t,e,r,i){const s=[];for(let o=0;ot&&a.ye&&s.push(a)}return s}split(t,e,r){if(r<=1){this.nodes.push({x:t,y:e,size:r});return}if(this.shouldSplit(t,e,r)){const i=r/2;this.split(t,e,i),this.split(t+i,e,i),this.split(t,e+i,i),this.split(t+i,e+i,i)}else this.nodes.push({x:t,y:e,size:r})}shouldSplit(t,e,r){if(t>=this.width||e>=this.height)return!1;let i=255,s=0;const o=Math.max(1,Math.floor(r/8));for(let a=e;a=this.height);a+=o)for(let l=t;l=this.width);l+=o){const d=(a*this.width+l)*4,c=this.data[d];if(cs&&(s=c),s-i>this.threshold)return!0}return!1}}class v{canvas;gl;program=null;quadBuffer=null;instanceBuffer=null;dataTexture=null;locations;instanceCount=0;constructor(t){this.canvas=t;const e=t.getContext("webgl2",{preserveDrawingBuffer:!0});if(!e)throw new Error("WebGL2 not supported");this.gl=e,this.initShaders(),this.initBuffers(),this.initTexture(),this.locations={a_position:0,a_instanceInfo:1,u_viewMatrix:null,u_gridSize:null,u_dataTexture:null},this.gl.enable(this.gl.BLEND),this.gl.blendFunc(this.gl.SRC_ALPHA,this.gl.ONE_MINUS_SRC_ALPHA)}initShaders(){const t=this.gl,e=`#version 300 es + layout(location=0) in vec2 a_position; // 0..1 quad + layout(location=1) in vec3 a_instanceInfo; // x, y, size + + uniform mat3 u_viewMatrix; + uniform vec2 u_gridSize; + + out vec2 v_uv; + out float v_height; + + void main() { + // Calculate world position of this pixel in the quad + float size = a_instanceInfo.z; + vec2 worldPos = a_instanceInfo.xy + a_position * size; + + vec2 viewPos = (u_viewMatrix * vec3(worldPos, 1.0)).xy; + + gl_Position = vec4(viewPos, 0.0, 1.0); + + // UV for texture lookup (normalized 0..1 relative to whole grid) + v_uv = worldPos / u_gridSize; + }`,r=`#version 300 es + precision highp float; + + uniform sampler2D u_dataTexture; + + in vec2 v_uv; + + out vec4 outColor; + + void main() { + vec4 data = texture(u_dataTexture, v_uv); + float height = data.r; + float moisture = data.g; + + vec3 color; + + if (height < 0.2) { + color = vec3(0.0, 0.2, 0.6); // Deep Ocean + } else if (height < 0.25) { + color = vec3(0.0, 0.4, 0.8); // Shallow Water + } else if (height < 0.28) { + color = vec3(0.9, 0.8, 0.6); // Beach + } else if (height < 0.6) { + // Land gradient based on moisture + color = mix(vec3(0.8, 0.7, 0.4), vec3(0.1, 0.6, 0.1), moisture); + } else if (height < 0.8) { + color = vec3(0.4, 0.4, 0.4); // Rock + } else { + color = vec3(1.0, 1.0, 1.0); // Snow + } + + // Debug: Use direct height if texture fetch is working + // color = vec3(height, height, height); + + outColor = vec4(color, 1.0); + }`,i=this.createShader(t.VERTEX_SHADER,e),s=this.createShader(t.FRAGMENT_SHADER,r);if(this.program=t.createProgram(),t.attachShader(this.program,i),t.attachShader(this.program,s),t.linkProgram(this.program),!t.getProgramParameter(this.program,t.LINK_STATUS))throw new Error(`Shader program link error: ${t.getProgramInfoLog(this.program)}`);this.locations={a_position:0,a_instanceInfo:1,u_viewMatrix:t.getUniformLocation(this.program,"u_viewMatrix"),u_gridSize:t.getUniformLocation(this.program,"u_gridSize"),u_dataTexture:t.getUniformLocation(this.program,"u_dataTexture")}}createShader(t,e){const r=this.gl.createShader(t);if(this.gl.shaderSource(r,e),this.gl.compileShader(r),!this.gl.getShaderParameter(r,this.gl.COMPILE_STATUS)){const i=this.gl.getShaderInfoLog(r);throw this.gl.deleteShader(r),new Error(`Shader compile error: ${i}`)}return r}initBuffers(){const t=this.gl,e=new Float32Array([0,0,1,0,0,1,1,0,1,1,0,1]);this.quadBuffer=t.createBuffer(),t.bindBuffer(t.ARRAY_BUFFER,this.quadBuffer),t.bufferData(t.ARRAY_BUFFER,e,t.STATIC_DRAW),this.instanceBuffer=t.createBuffer(),t.bindBuffer(t.ARRAY_BUFFER,this.instanceBuffer),t.bufferData(t.ARRAY_BUFFER,1e5*3*4,t.DYNAMIC_DRAW)}initTexture(){const t=this.gl;this.dataTexture=t.createTexture(),t.activeTexture(t.TEXTURE0),t.bindTexture(t.TEXTURE_2D,this.dataTexture),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE)}updateTexture(t,e,r){const i=this.gl;i.activeTexture(i.TEXTURE0),i.bindTexture(i.TEXTURE_2D,this.dataTexture),i.texImage2D(i.TEXTURE_2D,0,i.RGBA,e,r,0,i.RGBA,i.UNSIGNED_BYTE,t),i.useProgram(this.program),i.uniform1i(this.locations.u_dataTexture,0),i.uniform2f(this.locations.u_gridSize,e,r)}updateInstances(t,e){const r=this.gl;r.bindBuffer(r.ARRAY_BUFFER,this.instanceBuffer),r.bufferData(r.ARRAY_BUFFER,t,r.DYNAMIC_DRAW),this.instanceCount=e}render(t){const e=this.gl;e.clear(e.COLOR_BUFFER_BIT),e.useProgram(this.program),e.uniformMatrix3fv(this.locations.u_viewMatrix,!1,t),e.bindBuffer(e.ARRAY_BUFFER,this.quadBuffer),e.enableVertexAttribArray(this.locations.a_position),e.vertexAttribPointer(this.locations.a_position,2,e.FLOAT,!1,0,0),e.vertexAttribDivisor(this.locations.a_position,0),e.bindBuffer(e.ARRAY_BUFFER,this.instanceBuffer),e.enableVertexAttribArray(this.locations.a_instanceInfo),e.vertexAttribPointer(this.locations.a_instanceInfo,3,e.FLOAT,!1,0,0),e.vertexAttribDivisor(this.locations.a_instanceInfo,1),e.drawArraysInstanced(e.TRIANGLES,0,6,this.instanceCount),e.vertexAttribDivisor(this.locations.a_instanceInfo,0)}}function m(h){return new Worker(""+new URL("generation.worker-Cg35tNCA.js",import.meta.url).href,{name:h?.name})}console.log("Fantasy Map Engine Initialized");const n={width:1024,height:1024};class w{canvas;worker;sharedBuffer;dataView;renderer;quadtree=null;camera;isRendering=!1;frameCount=0;constructor(){this.canvas=document.getElementById("mapCanvas"),this.renderer=new v(this.canvas),this.camera=new f(this.canvas,n.width,n.height),this.resize(),window.addEventListener("resize",()=>this.resize());const t=n.width*n.height*4;try{this.sharedBuffer=new SharedArrayBuffer(t),console.log("SharedArrayBuffer created.")}catch(e){throw console.warn("SharedArrayBuffer not supported. Engine requires COOP/COEP headers."),e}this.dataView=new Uint8ClampedArray(this.sharedBuffer),this.worker=new m,this.worker.onmessage=this.handleWorkerMessage.bind(this),u({rebuildMap:e=>this.startGeneration(e),setWaterLevel:e=>{console.log("Water level set to:",e)}}),this.startGeneration("default-seed")}resize(){this.canvas&&(this.canvas.width=window.innerWidth,this.canvas.height=window.innerHeight,this.renderer.gl.viewport(0,0,this.canvas.width,this.canvas.height))}startGeneration(t){console.log("Starting generation...");const e={type:"init",buffer:this.sharedBuffer,width:n.width,height:n.height,seed:t};this.worker.postMessage(e)}handleWorkerMessage(t){if(t.data.type==="complete"){console.log("Generation complete!"),this.renderer.updateTexture(this.dataView,n.width,n.height),console.time("Build Quadtree"),this.quadtree=new g(this.dataView,n.width,n.height);const e=this.quadtree.build();console.timeEnd("Build Quadtree"),console.log(`Quadtree generated ${e.length} nodes`);const r=new Float32Array(e.length*3);for(let i=0;ithis.loop())}}new w; diff --git a/mobile_app/assets/www/assets/generation.worker-Cg35tNCA.js b/mobile_app/assets/www/assets/generation.worker-Cg35tNCA.js new file mode 100644 index 00000000..fc737f69 --- /dev/null +++ b/mobile_app/assets/www/assets/generation.worker-Cg35tNCA.js @@ -0,0 +1 @@ +(function(){"use strict";function g(u){return u&&u.__esModule&&Object.prototype.hasOwnProperty.call(u,"default")?u.default:u}var p={exports:{}},d=p.exports,x;function y(){return x||(x=1,(function(u,h){(function(i,s){u.exports=s()})(d,function(){return i.importState=function(t){var n=new i;return n.importState(t),n},i;function i(){return(function(t){var n=0,e=0,r=0,o=1;t.length==0&&(t=[+new Date]);var c=s();n=c(" "),e=c(" "),r=c(" ");for(var l=0;l>>0,o-=t,o*=t,t=o>>>0,o-=t,t+=o*4294967296}return(t>>>0)*23283064365386963e-26};return n.version="Mash 0.9",n}})})(p)),p.exports}var z=y(),M=g(z);class w{prng;map;size;constructor(h,i=256){this.prng=M(h),this.size=i,this.map=new Float32Array(i*i);for(let s=0;s{const{type:h}=u.data;if(h==="init"){const{buffer:i,width:s,height:t,seed:n}=u.data,e=new Uint8ClampedArray(i),r=new w(n);console.log(`Worker: Generating ${s}x${t} map with seed ${n}`);for(let o=0;o{for(const o of i)if(o.type==="childList")for(const s of o.addedNodes)s.tagName==="LINK"&&s.rel==="modulepreload"&&t(s)}).observe(document,{childList:!0,subtree:!0});function n(i){const o={};return i.integrity&&(o.integrity=i.integrity),i.referrerPolicy&&(o.referrerPolicy=i.referrerPolicy),i.crossOrigin==="use-credentials"?o.credentials="include":i.crossOrigin==="anonymous"?o.credentials="omit":o.credentials="same-origin",o}function t(i){if(i.ep)return;i.ep=!0;const o=n(i);fetch(i.href,o)}})();String.prototype.replaceAll===void 0&&(String.prototype.replaceAll=function(e,a){return Object.prototype.toString.call(e).toLowerCase()==="[object regexp]"?this.replace(e,a):this.replace(new RegExp(e,"g"),a)});Array.prototype.flat===void 0&&(Array.prototype.flat=function(e){return this.reduce((a,n)=>Array.isArray(n)?a.concat(n.flat(e)):a.concat(n),[])});Array.prototype.at===void 0&&(Array.prototype.at=function(e){if(e<0&&(e+=this.length),!(e<0||e>=this.length))return this[e]});ReadableStream.prototype[Symbol.asyncIterator]===void 0&&(ReadableStream.prototype[Symbol.asyncIterator]=async function*(){const e=this.getReader();try{for(;;){const{done:a,value:n}=await e.read();if(a)return;yield n}}finally{e.releaseLock()}});const N=(e,a=0)=>{const n=10**a;return Math.round(e*n)/n},ma=(e,a,n)=>Math.min(Math.max(e,a),n),V=e=>ma(e,0,100),ee=(e,a,n)=>ma((e-a)/(n-a),0,1),Ut=(e,a,n)=>e+(a-e)*n,Ea=e=>e[e.length-1],jn=e=>[...new Set(e)],Vt=e=>{const a=h=>h,n=h=>h.map(a),t=h=>Object.fromEntries(Object.entries(h).map(([u,l])=>[u,i(l)])),i=h=>h instanceof Object?(s.get(h.constructor)||a)(h):h,o=h=>[...h.entries()].map(([u,l])=>[u,i(l)]),s=new Map([[Int8Array,n],[Uint8Array,n],[Uint8ClampedArray,n],[Int16Array,n],[Uint16Array,n],[Int32Array,n],[Uint32Array,n],[Float32Array,n],[Float64Array,n],[BigInt64Array,n],[BigUint64Array,n],[Map,h=>new Map(o(h))],[WeakMap,h=>new WeakMap(o(h))],[Array,h=>h.map(i)],[Set,h=>[...h.values()].map(i)],[Date,h=>new Date(h.getTime())],[Object,t]]);return i(e)},Un=e=>(console.assert(Number.isInteger(e)&&e>=0&&e<=ea.UINT32_MAX,`Array maxValue must be an integer between 0 and ${ea.UINT32_MAX}, got ${e}`),e<=ea.UINT8_MAX?Uint8Array:e<=ea.UINT16_MAX?Uint16Array:(e<=ea.UINT32_MAX,Uint32Array)),pe=({maxValue:e,length:a,from:n})=>{const t=Un(e);return n?t.from(n):new t(a)},ea={INT8_MAX:127,UINT8_MAX:255,UINT16_MAX:65535,UINT32_MAX:4294967295};function Ft(e,a){return e==null||a==null?NaN:ea?1:e>=a?0:NaN}const Yt=Math.sqrt(50),$t=Math.sqrt(10),Wt=Math.sqrt(2);function ne(e,a,n){const t=(a-e)/Math.max(0,n),i=Math.floor(Math.log10(t)),o=t/Math.pow(10,i),s=o>=Yt?10:o>=$t?5:o>=Wt?2:1;let h,u,l;return i<0?(l=Math.pow(10,-i)/s,h=Math.round(e*l),u=Math.round(a*l),h/la&&--u,l=-l):(l=Math.pow(10,i)*s,h=Math.round(e/l),u=Math.round(a/l),h*la&&--u),u0))return[];if(e===a)return[e];const t=a=i))return[];const h=o-i+1,u=new Array(h);if(t)if(s<0)for(let l=0;l=t)&&(n=t);return n}function Ba(e,a){let n;for(const t of e)t!=null&&(n>t||n===void 0&&t>=t)&&(n=t);return n}function Jt(e,a){let n,t=-1,i=-1;if(a===void 0)for(const o of e)++i,o!=null&&(n>o||n===void 0&&o>=o)&&(n=o,t=i);else for(let o of e)(o=a(o,++i,e))!=null&&(n>o||n===void 0&&o>=o)&&(n=o,t=i);return t}function Ha(e,a){let n=0,t=0;for(let i of e)i!=null&&(i=+i)>=i&&(++n,t+=i);if(n)return t/n}function Ra(e,a,n){e=+e,a=+a,n=(i=arguments.length)<2?(a=e,e=0,1):i<3?1:+n;for(var t=-1,i=Math.max(0,Math.ceil((a-e)/n))|0,o=new Array(i);++t{}};function Fn(){for(var e=0,a=arguments.length,n={},t;e=0&&(t=n.slice(i+1),n=n.slice(0,i)),n&&!a.hasOwnProperty(n))throw new Error("unknown type: "+n);return{type:n,name:t}})}$a.prototype=Fn.prototype={constructor:$a,on:function(e,a){var n=this._,t=ni(e+"",n),i,o=-1,s=t.length;if(arguments.length<2){for(;++o0)for(var n=new Array(i),t=0,i,o;t=0&&(a=e.slice(0,n))!=="xmlns"&&(e=e.slice(n+1)),hn.hasOwnProperty(a)?{space:hn[a],local:e}:e}function ii(e){return function(){var a=this.ownerDocument,n=this.namespaceURI;return n===He&&a.documentElement.namespaceURI===He?a.createElement(e):a.createElementNS(n,e)}}function ri(e){return function(){return this.ownerDocument.createElementNS(e.space,e.local)}}function Yn(e){var a=ye(e);return(a.local?ri:ii)(a)}function oi(){}function Ve(e){return e==null?oi:function(){return this.querySelector(e)}}function si(e){typeof e!="function"&&(e=Ve(e));for(var a=this._groups,n=a.length,t=new Array(n),i=0;i=b&&(b=k+1);!(w=p[b])&&++b=0;)(s=t[i])&&(o&&s.compareDocumentPosition(o)^4&&o.parentNode.insertBefore(s,o),o=s);return this}function Bi(e){e||(e=Ei);function a(d,r){return d&&r?e(d.__data__,r.__data__):!d-!r}for(var n=this._groups,t=n.length,i=new Array(t),o=0;oa?1:e>=a?0:NaN}function Hi(){var e=arguments[0];return arguments[0]=this,e.apply(null,arguments),this}function Ri(){return Array.from(this)}function Li(){for(var e=this._groups,a=0,n=e.length;a1?this.each((a==null?Yi:typeof a=="function"?Wi:$i)(e,a,n??"")):Aa(this.node(),e)}function Aa(e,a){return e.style.getPropertyValue(a)||Jn(e).getComputedStyle(e,null).getPropertyValue(a)}function Qi(e){return function(){delete this[e]}}function Ji(e,a){return function(){this[e]=a}}function Xi(e,a){return function(){var n=a.apply(this,arguments);n==null?delete this[e]:this[e]=n}}function ar(e,a){return arguments.length>1?this.each((a==null?Qi:typeof a=="function"?Xi:Ji)(e,a)):this.node()[e]}function Xn(e){return e.trim().split(/^|\s+/)}function Fe(e){return e.classList||new at(e)}function at(e){this._node=e,this._names=Xn(e.getAttribute("class")||"")}at.prototype={add:function(e){var a=this._names.indexOf(e);a<0&&(this._names.push(e),this._node.setAttribute("class",this._names.join(" ")))},remove:function(e){var a=this._names.indexOf(e);a>=0&&(this._names.splice(a,1),this._node.setAttribute("class",this._names.join(" ")))},contains:function(e){return this._names.indexOf(e)>=0}};function et(e,a){for(var n=Fe(e),t=-1,i=a.length;++t=0&&(n=a.slice(t+1),a=a.slice(0,t)),{type:a,name:n}})}function xr(e){return function(){var a=this.__on;if(a){for(var n=0,t=-1,i=a.length,o;n>8&15|a>>4&240,a>>4&15|a&240,(a&15)<<4|a&15,1):n===8?Oa(a>>24&255,a>>16&255,a>>8&255,(a&255)/255):n===4?Oa(a>>12&15|a>>8&240,a>>8&15|a>>4&240,a>>4&15|a&240,((a&15)<<4|a&15)/255):null):(a=Ir.exec(e))?new P(a[1],a[2],a[3],1):(a=Dr.exec(e))?new P(a[1]*255/100,a[2]*255/100,a[3]*255/100,1):(a=Gr.exec(e))?Oa(a[1],a[2],a[3],a[4]):(a=Or.exec(e))?Oa(a[1]*255/100,a[2]*255/100,a[3]*255/100,a[4]):(a=qr.exec(e))?yn(a[1],a[2]/100,a[3]/100,1):(a=jr.exec(e))?yn(a[1],a[2]/100,a[3]/100,a[4]):cn.hasOwnProperty(e)?fn(cn[e]):e==="transparent"?new P(NaN,NaN,NaN,0):null}function fn(e){return new P(e>>16&255,e>>8&255,e&255,1)}function Oa(e,a,n,t){return t<=0&&(e=a=n=NaN),new P(e,a,n,t)}function it(e){return e instanceof za||(e=Z(e)),e?(e=e.rgb(),new P(e.r,e.g,e.b,e.opacity)):new P}function Re(e,a,n,t){return arguments.length===1?it(e):new P(e,a,n,t??1)}function P(e,a,n,t){this.r=+e,this.g=+a,this.b=+n,this.opacity=+t}ke(P,Re,Ye(za,{brighter(e){return e=e==null?Sa:Math.pow(Sa,e),new P(this.r*e,this.g*e,this.b*e,this.opacity)},darker(e){return e=e==null?ga:Math.pow(ga,e),new P(this.r*e,this.g*e,this.b*e,this.opacity)},rgb(){return this},clamp(){return new P(ca(this.r),ca(this.g),ca(this.b),ie(this.opacity))},displayable(){return-.5<=this.r&&this.r<255.5&&-.5<=this.g&&this.g<255.5&&-.5<=this.b&&this.b<255.5&&0<=this.opacity&&this.opacity<=1},hex:mn,formatHex:mn,formatHex8:Fr,formatRgb:pn,toString:pn}));function mn(){return`#${ha(this.r)}${ha(this.g)}${ha(this.b)}`}function Fr(){return`#${ha(this.r)}${ha(this.g)}${ha(this.b)}${ha((isNaN(this.opacity)?1:this.opacity)*255)}`}function pn(){const e=ie(this.opacity);return`${e===1?"rgb(":"rgba("}${ca(this.r)}, ${ca(this.g)}, ${ca(this.b)}${e===1?")":`, ${e})`}`}function ie(e){return isNaN(e)?1:Math.max(0,Math.min(1,e))}function ca(e){return Math.max(0,Math.min(255,Math.round(e)||0))}function ha(e){return e=ca(e),(e<16?"0":"")+e.toString(16)}function yn(e,a,n,t){return t<=0?e=a=n=NaN:n<=0||n>=1?e=a=NaN:a<=0&&(e=NaN),new F(e,a,n,t)}function rt(e){if(e instanceof F)return new F(e.h,e.s,e.l,e.opacity);if(e instanceof za||(e=Z(e)),!e)return new F;if(e instanceof F)return e;e=e.rgb();var a=e.r/255,n=e.g/255,t=e.b/255,i=Math.min(a,n,t),o=Math.max(a,n,t),s=NaN,h=o-i,u=(o+i)/2;return h?(a===o?s=(n-t)/h+(n0&&u<1?0:s,new F(s,h,u,e.opacity)}function Yr(e,a,n,t){return arguments.length===1?rt(e):new F(e,a,n,t??1)}function F(e,a,n,t){this.h=+e,this.s=+a,this.l=+n,this.opacity=+t}ke(F,Yr,Ye(za,{brighter(e){return e=e==null?Sa:Math.pow(Sa,e),new F(this.h,this.s,this.l*e,this.opacity)},darker(e){return e=e==null?ga:Math.pow(ga,e),new F(this.h,this.s,this.l*e,this.opacity)},rgb(){var e=this.h%360+(this.h<0)*360,a=isNaN(e)||isNaN(this.s)?0:this.s,n=this.l,t=n+(n<.5?n:1-n)*a,i=2*n-t;return new P(Ne(e>=240?e-240:e+120,i,t),Ne(e,i,t),Ne(e<120?e+240:e-120,i,t),this.opacity)},clamp(){return new F(kn(this.h),qa(this.s),qa(this.l),ie(this.opacity))},displayable(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1},formatHsl(){const e=ie(this.opacity);return`${e===1?"hsl(":"hsla("}${kn(this.h)}, ${qa(this.s)*100}%, ${qa(this.l)*100}%${e===1?")":`, ${e})`}`}}));function kn(e){return e=(e||0)%360,e<0?e+360:e}function qa(e){return Math.max(0,Math.min(1,e||0))}function Ne(e,a,n){return(e<60?a+(n-a)*e/60:e<180?n:e<240?a+(n-a)*(240-e)/60:a)*255}const $r=Math.PI/180,Wr=180/Math.PI;var ot=-.14861,$e=1.78277,We=-.29227,be=-.90649,Pa=1.97294,bn=Pa*be,vn=Pa*$e,wn=$e*We-be*ot;function Zr(e){if(e instanceof da)return new da(e.h,e.s,e.l,e.opacity);e instanceof P||(e=it(e));var a=e.r/255,n=e.g/255,t=e.b/255,i=(wn*t+bn*a-vn*n)/(wn+bn-vn),o=t-i,s=(Pa*(n-i)-We*o)/be,h=Math.sqrt(s*s+o*o)/(Pa*i*(1-i)),u=h?Math.atan2(s,o)*Wr-120:NaN;return new da(u<0?u+360:u,h,i,e.opacity)}function sa(e,a,n,t){return arguments.length===1?Zr(e):new da(e,a,n,t??1)}function da(e,a,n,t){this.h=+e,this.s=+a,this.l=+n,this.opacity=+t}ke(da,sa,Ye(za,{brighter(e){return e=e==null?Sa:Math.pow(Sa,e),new da(this.h,this.s,this.l*e,this.opacity)},darker(e){return e=e==null?ga:Math.pow(ga,e),new da(this.h,this.s,this.l*e,this.opacity)},rgb(){var e=isNaN(this.h)?0:(this.h+120)*$r,a=+this.l,n=isNaN(this.s)?0:this.s*a*(1-a),t=Math.cos(e),i=Math.sin(e);return new P(255*(a+n*(ot*t+$e*i)),255*(a+n*(We*t+be*i)),255*(a+n*(Pa*t)),this.opacity)}}));const ve=e=>()=>e;function st(e,a){return function(n){return e+n*a}}function Qr(e,a,n){return e=Math.pow(e,n),a=Math.pow(a,n)-e,n=1/n,function(t){return Math.pow(e+t*a,n)}}function Jr(e,a){var n=a-e;return n?st(e,n>180||n<-180?n-360*Math.round(n/360):n):ve(isNaN(e)?a:e)}function Xr(e){return(e=+e)==1?wa:function(a,n){return n-a?Qr(a,n,e):ve(isNaN(a)?n:a)}}function wa(e,a){var n=a-e;return n?st(e,n):ve(isNaN(e)?a:e)}const re=(function e(a){var n=Xr(a);function t(i,o){var s=n((i=Re(i)).r,(o=Re(o)).r),h=n(i.g,o.g),u=n(i.b,o.b),l=wa(i.opacity,o.opacity);return function(c){return i.r=s(c),i.g=h(c),i.b=u(c),i.opacity=l(c),i+""}}return t.gamma=e,t})(1);function ao(e,a){a||(a=[]);var n=e?Math.min(a.length,e.length):0,t=a.slice(),i;return function(o){for(i=0;in&&(o=a.slice(n,o),h[s]?h[s]+=o:h[++s]=o),(t=t[0])===(i=i[0])?h[s]?h[s]+=i:h[++s]=i:(h[++s]=null,u.push({i:s,x:aa(t,i)})),n=Ce.lastIndex;return n180?c+=360:c-l>180&&(l+=360),r.push({i:d.push(i(d)+"rotate(",null,t)-2,x:aa(l,c)})):c&&d.push(i(d)+"rotate("+c+t)}function h(l,c,d,r){l!==c?r.push({i:d.push(i(d)+"skewX(",null,t)-2,x:aa(l,c)}):c&&d.push(i(d)+"skewX("+c+t)}function u(l,c,d,r,g,m){if(l!==d||c!==r){var f=g.push(i(g)+"scale(",null,",",null,")");m.push({i:f-4,x:aa(l,d)},{i:f-2,x:aa(c,r)})}else(d!==1||r!==1)&&g.push(i(g)+"scale("+d+","+r+")")}return function(l,c){var d=[],r=[];return l=e(l),c=e(c),o(l.translateX,l.translateY,c.translateX,c.translateY,d,r),s(l.rotate,c.rotate,d,r),h(l.skewX,c.skewX,d,r),u(l.scaleX,l.scaleY,c.scaleX,c.scaleY,d,r),l=c=null,function(g){for(var m=-1,f=r.length,p;++m=0&&e._call.call(void 0,a),e=e._next;--_a}function Sn(){fa=(se=Ia.now())+Ae,_a=Na=0;try{fo()}finally{_a=0,po(),fa=0}}function mo(){var e=Ia.now(),a=e-se;a>gt&&(Ae-=a,se=e)}function po(){for(var e,a=oe,n,t=1/0;a;)a._call?(t>a._time&&(t=a._time),e=a,a=a._next):(n=a._next,a._next=null,a=e?e._next=n:oe=n);Ca=e,Ie(t)}function Ie(e){if(!_a){Na&&(Na=clearTimeout(Na));var a=e-fa;a>24?(e<1/0&&(Na=setTimeout(Sn,e-Ia.now()-Ae)),Ta&&(Ta=clearInterval(Ta))):(Ta||(se=Ia.now(),Ta=setInterval(mo,gt)),_a=1,ft(Sn))}}function _n(e,a,n){var t=new le;return a=a==null?0:+a,t.restart(i=>{t.stop(),e(i+a)},a,n),t}var yo=Fn("start","end","cancel","interrupt"),ko=[],pt=0,Mn=1,De=2,Wa=3,zn=4,Ge=5,Za=6;function Se(e,a,n,t,i,o){var s=e.__transition;if(!s)e.__transition={};else if(n in s)return;bo(e,n,{name:a,index:t,group:i,on:yo,tween:ko,time:o.time,delay:o.delay,duration:o.duration,ease:o.ease,timer:null,state:pt})}function Qe(e,a){var n=Q(e,a);if(n.state>pt)throw new Error("too late; already scheduled");return n}function ta(e,a){var n=Q(e,a);if(n.state>Wa)throw new Error("too late; already running");return n}function Q(e,a){var n=e.__transition;if(!n||!(n=n[a]))throw new Error("transition not found");return n}function bo(e,a,n){var t=e.__transition,i;t[a]=n,n.timer=mt(o,0,n.time);function o(l){n.state=Mn,n.timer.restart(s,n.delay,n.time),n.delay<=l&&s(l-n.delay)}function s(l){var c,d,r,g;if(n.state!==Mn)return u();for(c in t)if(g=t[c],g.name===n.name){if(g.state===Wa)return _n(s);g.state===zn?(g.state=Za,g.timer.stop(),g.on.call("interrupt",e,e.__data__,g.index,g.group),delete t[c]):+cDe&&t.state=0&&(a=a.slice(0,n)),!a||a==="start"})}function Zo(e,a,n){var t,i,o=Wo(a)?Qe:ta;return function(){var s=o(this,e),h=s.on;h!==t&&(i=(t=h).copy()).on(a,n),s.on=i}}function Qo(e,a){var n=this._id;return arguments.length<2?Q(this.node(),n).on.on(e):this.each(Zo(n,e,a))}function Jo(e){return function(){var a=this.parentNode;for(var n in this.__transition)if(+n!==e)return;a&&a.removeChild(this)}}function Xo(){return this.on("end.remove",Jo(this._id))}function as(e){var a=this._name,n=this._id;typeof e!="function"&&(e=Ve(e));for(var t=this._groups,i=t.length,o=new Array(i),s=0;s=0))throw new Error(`invalid digits: ${e}`);if(a>15)return vt;const n=10**a;return function(t){this._+=t[0];for(let i=1,o=t.length;ila)if(!(Math.abs(d*u-l*c)>la)||!o)this._append`L${this._x1=a},${this._y1=n}`;else{let g=t-s,m=i-h,f=u*u+l*l,p=g*g+m*m,y=Math.sqrt(f),k=Math.sqrt(r),b=o*Math.tan((Oe-Math.acos((f+r-p)/(2*y*k)))/2),v=b/k,w=b/y;Math.abs(v-1)>la&&this._append`L${a+v*c},${n+v*d}`,this._append`A${o},${o},0,0,${+(d*g>c*m)},${this._x1=a+w*u},${this._y1=n+w*l}`}}arc(a,n,t,i,o,s){if(a=+a,n=+n,t=+t,s=!!s,t<0)throw new Error(`negative radius: ${t}`);let h=t*Math.cos(i),u=t*Math.sin(i),l=a+h,c=n+u,d=1^s,r=s?i-o:o-i;this._x1===null?this._append`M${l},${c}`:(Math.abs(this._x1-l)>la||Math.abs(this._y1-c)>la)&&this._append`L${l},${c}`,t&&(r<0&&(r=r%qe+qe),r>Ms?this._append`A${t},${t},0,1,${d},${a-h},${n-u}A${t},${t},0,1,${d},${this._x1=l},${this._y1=c}`:r>la&&this._append`A${t},${t},0,${+(r>=Oe)},${d},${this._x1=a+t*Math.cos(o)},${this._y1=n+t*Math.sin(o)}`)}rect(a,n,t,i){this._append`M${this._x0=this._x1=+a},${this._y0=this._y1=+n}h${t=+t}v${+i}h${-t}Z`}toString(){return this._}}const ra=11102230246251565e-32,L=134217729,xs=(3+8*ra)*ra;function Ke(e,a,n,t,i){let o,s,h,u,l=a[0],c=t[0],d=0,r=0;c>l==c>-l?(o=l,l=a[++d]):(o=c,c=t[++r]);let g=0;if(dl==c>-l?(s=l+o,h=o-(s-l),l=a[++d]):(s=c+o,h=o-(s-c),c=t[++r]),o=s,h!==0&&(i[g++]=h);dl==c>-l?(s=o+l,u=s-o,h=o-(s-u)+(l-u),l=a[++d]):(s=o+c,u=s-o,h=o-(s-u)+(c-u),c=t[++r]),o=s,h!==0&&(i[g++]=h);for(;d=E||-C>=E||(d=e-S,h=e-(S+d)+(d-i),d=n-z,l=n-(z+d)+(d-i),d=a-A,u=a-(A+d)+(d-o),d=t-x,c=t-(x+d)+(d-o),h===0&&u===0&&l===0&&c===0)||(E=Bs*s+xs*Math.abs(C),C+=S*c+x*h-(A*l+z*u),C>=E||-C>=E))return C;v=h*x,r=L*h,g=r-(r-h),m=h-g,r=L*x,f=r-(r-x),p=x-f,w=m*p-(v-g*f-m*f-g*p),_=u*z,r=L*u,g=r-(r-u),m=u-g,r=L*z,f=r-(r-z),p=z-f,M=m*p-(_-g*f-m*f-g*p),y=w-M,d=w-y,I[0]=w-(y+d)+(d-M),k=v+y,d=k-v,b=v-(k-d)+(y-d),y=b-_,d=b-y,I[1]=b-(y+d)+(d-_),T=k+y,d=T-k,I[2]=k-(T-d)+(y-d),I[3]=T;const O=Ke(4,pa,4,I,Tn);v=S*c,r=L*S,g=r-(r-S),m=S-g,r=L*c,f=r-(r-c),p=c-f,w=m*p-(v-g*f-m*f-g*p),_=A*l,r=L*A,g=r-(r-A),m=A-g,r=L*l,f=r-(r-l),p=l-f,M=m*p-(_-g*f-m*f-g*p),y=w-M,d=w-y,I[0]=w-(y+d)+(d-M),k=v+y,d=k-v,b=v-(k-d)+(y-d),y=b-_,d=b-y,I[1]=b-(y+d)+(d-_),T=k+y,d=T-k,I[2]=k-(T-d)+(y-d),I[3]=T;const K=Ke(O,Tn,4,I,xn);v=h*c,r=L*h,g=r-(r-h),m=h-g,r=L*c,f=r-(r-c),p=c-f,w=m*p-(v-g*f-m*f-g*p),_=u*l,r=L*u,g=r-(r-u),m=u-g,r=L*l,f=r-(r-l),p=l-f,M=m*p-(_-g*f-m*f-g*p),y=w-M,d=w-y,I[0]=w-(y+d)+(d-M),k=v+y,d=k-v,b=v-(k-d)+(y-d),y=b-_,d=b-y,I[1]=b-(y+d)+(d-_),T=k+y,d=T-k,I[2]=k-(T-d)+(y-d),I[3]=T;const H=Ke(K,xn,4,I,Nn);return Nn[H-1]}function Ua(e,a,n,t,i,o){const s=(a-o)*(n-i),h=(e-i)*(t-o),u=s-h,l=Math.abs(s+h);return Math.abs(u)>=Cs*l?u:-Es(e,a,n,t,i,o,l)}const Cn=Math.pow(2,-52),Va=new Uint32Array(512);class Xe{static from(a,n=Is,t=Ds){const i=a.length,o=new Float64Array(i*2);for(let s=0;s>1;if(n>0&&typeof a[0]!="number")throw new Error("Expected coords to contain numbers.");this.coords=a;const t=Math.max(2*n-5,0);this._triangles=new Uint32Array(t*3),this._halfedges=new Int32Array(t*3),this._hashSize=Math.ceil(Math.sqrt(n)),this._hullPrev=new Uint32Array(n),this._hullNext=new Uint32Array(n),this._hullTri=new Uint32Array(n),this._hullHash=new Int32Array(this._hashSize),this._ids=new Uint32Array(n),this._dists=new Float64Array(n),this.update()}update(){const{coords:a,_hullPrev:n,_hullNext:t,_hullTri:i,_hullHash:o}=this,s=a.length>>1;let h=1/0,u=1/0,l=-1/0,c=-1/0;for(let S=0;Sl&&(l=z),A>c&&(c=A),this._ids[S]=S}const d=(h+l)/2,r=(u+c)/2;let g,m,f;for(let S=0,z=1/0;S0&&(m=S,z=A)}let k=a[2*m],b=a[2*m+1],v=1/0;for(let S=0;Sx&&(S[z++]=C,x=E)}this.hull=S.subarray(0,z),this.triangles=new Uint32Array(0),this.halfedges=new Uint32Array(0);return}if(Ua(p,y,k,b,w,_)<0){const S=m,z=k,A=b;m=f,k=w,b=_,f=S,w=z,_=A}const M=Ps(p,y,k,b,w,_);this._cx=M.x,this._cy=M.y;for(let S=0;S0&&Math.abs(C-z)<=Cn&&Math.abs(E-A)<=Cn||(z=C,A=E,x===g||x===m||x===f))continue;let O=0;for(let xe=0,jt=this._hashKey(C,E);xe=0;)if(K=H,K===O){K=-1;break}if(K===-1)continue;let U=this._addTriangle(K,x,t[K],-1,-1,i[K]);i[x]=this._legalize(U+2),i[K]=U,T++;let R=t[K];for(;H=t[R],Ua(C,E,a[2*R],a[2*R+1],a[2*H],a[2*H+1])<0;)U=this._addTriangle(R,x,H,i[x],-1,i[R]),i[x]=this._legalize(U+2),t[R]=R,T--,R=H;if(K===O)for(;H=n[K],Ua(C,E,a[2*H],a[2*H+1],a[2*K],a[2*K+1])<0;)U=this._addTriangle(H,x,K,-1,i[K],i[H]),this._legalize(U+2),i[H]=U,t[K]=K,T--,K=H;this._hullStart=n[x]=K,t[K]=n[R]=x,t[x]=R,o[this._hashKey(C,E)]=x,o[this._hashKey(a[2*K],a[2*K+1])]=K}this.hull=new Uint32Array(T);for(let S=0,z=this._hullStart;S0?3-n:1+n)/4}function Be(e,a,n,t){const i=e-n,o=a-t;return i*i+o*o}function Rs(e,a,n,t,i,o,s,h){const u=e-s,l=a-h,c=n-s,d=t-h,r=i-s,g=o-h,m=u*u+l*l,f=c*c+d*d,p=r*r+g*g;return u*(d*p-f*g)-l*(c*p-f*r)+m*(c*g-d*r)<0}function Ls(e,a,n,t,i,o){const s=n-e,h=t-a,u=i-e,l=o-a,c=s*s+h*h,d=u*u+l*l,r=.5/(s*l-h*u),g=(l*c-h*d)*r,m=(s*d-u*c)*r;return g*g+m*m}function Ps(e,a,n,t,i,o){const s=n-e,h=t-a,u=i-e,l=o-a,c=s*s+h*h,d=u*u+l*l,r=.5/(s*l-h*u),g=e+(l*c-h*d)*r,m=a+(s*d-u*c)*r;return{x:g,y:m}}function ka(e,a,n,t){if(t-n<=20)for(let i=n+1;i<=t;i++){const o=e[i],s=a[o];let h=i-1;for(;h>=n&&a[e[h]]>s;)e[h+1]=e[h--];e[h+1]=o}else{const i=n+t>>1;let o=n+1,s=t;xa(e,i,o),a[e[n]]>a[e[t]]&&xa(e,n,t),a[e[o]]>a[e[t]]&&xa(e,o,t),a[e[n]]>a[e[o]]&&xa(e,n,o);const h=e[o],u=a[h];for(;;){do o++;while(a[e[o]]u);if(s=s-n?(ka(e,a,o,t),ka(e,a,n,s-1)):(ka(e,a,n,s-1),ka(e,a,o,t))}}function xa(e,a,n){const t=e[a];e[a]=e[n],e[n]=t}function Is(e){return e[0]}function Ds(e){return e[1]}function Gs(e){const a=+this._x.call(null,e),n=+this._y.call(null,e);return wt(this.cover(a,n),a,n,e)}function wt(e,a,n,t){if(isNaN(a)||isNaN(n))return e;var i,o=e._root,s={data:t},h=e._x0,u=e._y0,l=e._x1,c=e._y1,d,r,g,m,f,p,y,k;if(!o)return e._root=s,e;for(;o.length;)if((f=a>=(d=(h+l)/2))?h=d:l=d,(p=n>=(r=(u+c)/2))?u=r:c=r,i=o,!(o=o[y=p<<1|f]))return i[y]=s,e;if(g=+e._x.call(null,o.data),m=+e._y.call(null,o.data),a===g&&n===m)return s.next=o,i?i[y]=s:e._root=s,e;do i=i?i[y]=new Array(4):e._root=new Array(4),(f=a>=(d=(h+l)/2))?h=d:l=d,(p=n>=(r=(u+c)/2))?u=r:c=r;while((y=p<<1|f)===(k=(m>=r)<<1|g>=d));return i[k]=o,i[y]=s,e}function Os(e){var a,n,t=e.length,i,o,s=new Array(t),h=new Array(t),u=1/0,l=1/0,c=-1/0,d=-1/0;for(n=0;nc&&(c=i),od&&(d=o));if(u>c||l>d)return this;for(this.cover(u,l).cover(c,d),n=0;ne||e>=i||t>a||a>=o;)switch(l=(ac||(h=m.y0)>d||(u=m.x1)=y)<<1|e>=p)&&(m=r[r.length-1],r[r.length-1]=r[r.length-1-f],r[r.length-1-f]=m)}else{var k=e-+this._x.call(null,g.data),b=a-+this._y.call(null,g.data),v=k*k+b*b;if(v=(r=(s+u)/2))?s=r:u=r,(f=d>=(g=(h+l)/2))?h=g:l=g,a=n,!(n=n[p=f<<1|m]))return this;if(!n.length)break;(a[p+1&3]||a[p+2&3]||a[p+3&3])&&(t=a,y=p)}for(;n.data!==e;)if(i=n,!(n=n.next))return this;return(o=n.next)&&delete n.next,i?(o?i.next=o:delete i.next,this):a?(o?a[p]=o:delete a[p],(n=a[0]||a[1]||a[2]||a[3])&&n===(a[3]||a[2]||a[1]||a[0])&&!n.length&&(t?t[y]=n:this._root=n),this):(this._root=o,this)}function Ys(e){for(var a=0,n=e.length;a=1e21?e.toLocaleString("en").replace(/,/g,""):e.toString(10)}function he(e,a){if((n=(e=a?e.toExponential(a-1):e.toExponential()).indexOf("e"))<0)return null;var n,t=e.slice(0,n);return[t.length>1?t[0]+t.slice(2):t,+e.slice(n+1)]}function Ma(e){return e=he(Math.abs(e)),e?e[1]:NaN}function tl(e,a){return function(n,t){for(var i=n.length,o=[],s=0,h=e[0],u=0;i>0&&h>0&&(u+h+1>t&&(h=Math.max(1,t-u)),o.push(n.substring(i-=h,i+h)),!((u+=h+1)>t));)h=e[s=(s+1)%e.length];return o.reverse().join(a)}}function il(e){return function(a){return a.replace(/[0-9]/g,function(n){return e[+n]})}}var rl=/^(?:(.)?([<>=^]))?([+\-( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?(~)?([a-z%])?$/i;function ce(e){if(!(a=rl.exec(e)))throw new Error("invalid format: "+e);var a;return new en({fill:a[1],align:a[2],sign:a[3],symbol:a[4],zero:a[5],width:a[6],comma:a[7],precision:a[8]&&a[8].slice(1),trim:a[9],type:a[10]})}ce.prototype=en.prototype;function en(e){this.fill=e.fill===void 0?" ":e.fill+"",this.align=e.align===void 0?">":e.align+"",this.sign=e.sign===void 0?"-":e.sign+"",this.symbol=e.symbol===void 0?"":e.symbol+"",this.zero=!!e.zero,this.width=e.width===void 0?void 0:+e.width,this.comma=!!e.comma,this.precision=e.precision===void 0?void 0:+e.precision,this.trim=!!e.trim,this.type=e.type===void 0?"":e.type+""}en.prototype.toString=function(){return this.fill+this.align+this.sign+this.symbol+(this.zero?"0":"")+(this.width===void 0?"":Math.max(1,this.width|0))+(this.comma?",":"")+(this.precision===void 0?"":"."+Math.max(0,this.precision|0))+(this.trim?"~":"")+this.type};function ol(e){a:for(var a=e.length,n=1,t=-1,i;n0&&(t=0);break}return t>0?e.slice(0,t)+e.slice(i+1):e}var At;function sl(e,a){var n=he(e,a);if(!n)return e+"";var t=n[0],i=n[1],o=i-(At=Math.max(-8,Math.min(8,Math.floor(i/3)))*3)+1,s=t.length;return o===s?t:o>s?t+new Array(o-s+1).join("0"):o>0?t.slice(0,o)+"."+t.slice(o):"0."+new Array(1-o).join("0")+he(e,Math.max(0,a+o-1))[0]}function Bn(e,a){var n=he(e,a);if(!n)return e+"";var t=n[0],i=n[1];return i<0?"0."+new Array(-i).join("0")+t:t.length>i+1?t.slice(0,i+1)+"."+t.slice(i+1):t+new Array(i-t.length+2).join("0")}const En={"%":(e,a)=>(e*100).toFixed(a),b:e=>Math.round(e).toString(2),c:e=>e+"",d:nl,e:(e,a)=>e.toExponential(a),f:(e,a)=>e.toFixed(a),g:(e,a)=>e.toPrecision(a),o:e=>Math.round(e).toString(8),p:(e,a)=>Bn(e*100,a),r:Bn,s:sl,X:e=>Math.round(e).toString(16).toUpperCase(),x:e=>Math.round(e).toString(16)};function Hn(e){return e}var Rn=Array.prototype.map,Ln=["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"];function ll(e){var a=e.grouping===void 0||e.thousands===void 0?Hn:tl(Rn.call(e.grouping,Number),e.thousands+""),n=e.currency===void 0?"":e.currency[0]+"",t=e.currency===void 0?"":e.currency[1]+"",i=e.decimal===void 0?".":e.decimal+"",o=e.numerals===void 0?Hn:il(Rn.call(e.numerals,String)),s=e.percent===void 0?"%":e.percent+"",h=e.minus===void 0?"−":e.minus+"",u=e.nan===void 0?"NaN":e.nan+"";function l(d){d=ce(d);var r=d.fill,g=d.align,m=d.sign,f=d.symbol,p=d.zero,y=d.width,k=d.comma,b=d.precision,v=d.trim,w=d.type;w==="n"?(k=!0,w="g"):En[w]||(b===void 0&&(b=12),v=!0,w="g"),(p||r==="0"&&g==="=")&&(p=!0,r="0",g="=");var _=f==="$"?n:f==="#"&&/[boxX]/.test(w)?"0"+w.toLowerCase():"",M=f==="$"?t:/[%p]/.test(w)?s:"",T=En[w],S=/[defgprs%]/.test(w);b=b===void 0?6:/[gprs]/.test(w)?Math.max(1,Math.min(21,b)):Math.max(0,Math.min(20,b));function z(A){var x=_,C=M,E,O,K;if(w==="c")C=T(A)+C,A="";else{A=+A;var H=A<0||1/A<0;if(A=isNaN(A)?u:T(Math.abs(A),b),v&&(A=ol(A)),H&&+A==0&&m!=="+"&&(H=!1),x=(H?m==="("?m:h:m==="-"||m==="("?"":m)+x,C=(w==="s"?Ln[8+At/3]:"")+C+(H&&m==="("?")":""),S){for(E=-1,O=A.length;++EK||K>57){C=(K===46?i+A.slice(E+1):A.slice(E))+C,A=A.slice(0,E);break}}}k&&!p&&(A=a(A,1/0));var U=x.length+A.length+C.length,R=U>1)+x+A+C+R.slice(U);break;default:A=R+x+A+C;break}return o(A)}return z.toString=function(){return d+""},z}function c(d,r){var g=l((d=ce(d),d.type="f",d)),m=Math.max(-8,Math.min(8,Math.floor(Ma(r)/3)))*3,f=Math.pow(10,-m),p=Ln[8+m/3];return function(y){return g(f*y)+p}}return{format:l,formatPrefix:c}}var Fa,St,_t;ul({thousands:",",grouping:[3],currency:["$",""]});function ul(e){return Fa=ll(e),St=Fa.format,_t=Fa.formatPrefix,Fa}function hl(e){return Math.max(0,-Ma(Math.abs(e)))}function cl(e,a){return Math.max(0,Math.max(-8,Math.min(8,Math.floor(Ma(a)/3)))*3-Ma(Math.abs(e)))}function dl(e,a){return e=Math.abs(e),a=Math.abs(a)-e,Math.max(0,Ma(a)-Ma(e))+1}function gl(e){for(var a=-1,n=e.length,t,i=e[n-1],o=0;++a1);return t+i*h*Math.sqrt(-2*Math.log(s)/s)}}return n.source=e,n})(fl);function pl(e,a){switch(arguments.length){case 0:break;case 1:{typeof e=="function"?this.interpolator(e):this.range(e);break}default:{this.domain(e),typeof a=="function"?this.interpolator(a):this.range(a);break}}return this}function Mt(e){return e}function yl(e,a,n,t){var i=Qt(e,a,n),o;switch(t=ce(t??",f"),t.type){case"s":{var s=Math.max(Math.abs(e),Math.abs(a));return t.precision==null&&!isNaN(o=cl(i,s))&&(t.precision=o),_t(t,s)}case"":case"e":case"g":case"p":case"r":{t.precision==null&&!isNaN(o=dl(i,Math.max(Math.abs(e),Math.abs(a))))&&(t.precision=o-(t.type==="e"));break}case"f":case"%":{t.precision==null&&!isNaN(o=hl(i))&&(t.precision=o-(t.type==="%")*2);break}}return St(t)}function kl(e){var a=e.domain;return e.ticks=function(n){var t=a();return Zt(t[0],t[t.length-1],n??10)},e.tickFormat=function(n,t){var i=a();return yl(i[0],i[i.length-1],n??10,t)},e.nice=function(n){n==null&&(n=10);var t=a(),i=0,o=t.length-1,s=t[i],h=t[o],u,l,c=10;for(h0;){if(l=Ee(s,h,n),l===u)return t[i]=s,t[o]=h,a(t);if(l>0)s=Math.floor(s/l)*l,h=Math.ceil(h/l)*l;else if(l<0)s=Math.ceil(s*l)/l,h=Math.floor(h*l)/l;else break;u=l}return e},e}function bl(){var e=0,a=1,n,t,i,o,s=Mt,h=!1,u;function l(d){return d==null||isNaN(d=+d)?u:s(i===0?.5:(d=(o(d)-n)*i,h?Math.max(0,Math.min(1,d)):d))}l.domain=function(d){return arguments.length?([e,a]=d,n=o(e=+e),t=o(a=+a),i=n===t?0:1/(t-n),l):[e,a]},l.clamp=function(d){return arguments.length?(h=!!d,l):h},l.interpolator=function(d){return arguments.length?(s=d,l):s};function c(d){return function(r){var g,m;return arguments.length?([g,m]=r,s=d(g,m),l):[s(0),s(1)]}}return l.range=c(we),l.rangeRound=c(so),l.unknown=function(d){return arguments.length?(u=d,l):u},function(d){return o=d,n=d(e),t=d(a),i=n===t?0:1/(t-n),l}}function vl(e,a){return a.domain(e.domain()).interpolator(e.interpolator()).clamp(e.clamp()).unknown(e.unknown())}function nn(){var e=kl(bl()(Mt));return e.copy=function(){return vl(e,nn())},pl.apply(e,arguments)}dt(sa(-100,.75,.35),sa(80,1.5,.8));dt(sa(260,.75,.35),sa(80,1.5,.8));var Ya=sa();function zt(e){(e<0||e>1)&&(e-=Math.floor(e));var a=Math.abs(e-.5);return Ya.h=360*e-100,Ya.s=1.5-1.5*a,Ya.l=.8-.9*a,Ya+""}function ya(e){return function(){return e}}const Pn=1e-12;function wl(e){let a=3;return e.digits=function(n){if(!arguments.length)return a;if(n==null)a=null;else{const t=Math.floor(n);if(!(t>=0))throw new RangeError(`invalid digits: ${n}`);a=t}return e},()=>new Ts(a)}function Al(e){return typeof e=="object"&&"length"in e?e:Array.from(e)}function Tt(e){this._context=e}Tt.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._point=0},lineEnd:function(){(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line},point:function(e,a){switch(e=+e,a=+a,this._point){case 0:this._point=1,this._line?this._context.lineTo(e,a):this._context.moveTo(e,a);break;case 1:this._point=2;default:this._context.lineTo(e,a);break}}};function Sl(e){return new Tt(e)}function _l(e){return e[0]}function Ml(e){return e[1]}function tn(e,a){var n=ya(!0),t=null,i=Sl,o=null,s=wl(h);e=typeof e=="function"?e:e===void 0?_l:ya(e),a=typeof a=="function"?a:a===void 0?Ml:ya(a);function h(u){var l,c=(u=Al(u)).length,d,r=!1,g;for(t==null&&(o=i(g=s())),l=0;l<=c;++l)!(l0)for(var t=e[0],i=a[0],o=e[n]-t,s=a[n]-i,h=-1,u;++h<=n;)u=h/n,this._basis.point(this._beta*e[h]+(1-this._beta)*(t+u*o),this._beta*a[h]+(1-this._beta)*(i+u*s));this._x=this._y=null,this._basis.lineEnd()},point:function(e,a){this._x.push(+e),this._y.push(+a)}};const xl=(function e(a){function n(t){return a===1?new _e(t):new Nt(t,a)}return n.beta=function(t){return e(+t)},n})(.85);function Dn(e,a,n){e._context.bezierCurveTo(e._x1+e._k*(e._x2-e._x0),e._y1+e._k*(e._y2-e._y0),e._x2+e._k*(e._x1-a),e._y2+e._k*(e._y1-n),e._x2,e._y2)}function rn(e,a){this._context=e,this._k=(1-a)/6}rn.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:Dn(this,this._x1,this._y1);break}(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line},point:function(e,a){switch(e=+e,a=+a,this._point){case 0:this._point=1,this._line?this._context.lineTo(e,a):this._context.moveTo(e,a);break;case 1:this._point=2,this._x1=e,this._y1=a;break;case 2:this._point=3;default:Dn(this,e,a);break}this._x0=this._x1,this._x1=this._x2,this._x2=e,this._y0=this._y1,this._y1=this._y2,this._y2=a}};(function e(a){function n(t){return new rn(t,a)}return n.tension=function(t){return e(+t)},n})(0);function Nl(e,a,n){var t=e._x1,i=e._y1,o=e._x2,s=e._y2;if(e._l01_a>Pn){var h=2*e._l01_2a+3*e._l01_a*e._l12_a+e._l12_2a,u=3*e._l01_a*(e._l01_a+e._l12_a);t=(t*h-e._x0*e._l12_2a+e._x2*e._l01_2a)/u,i=(i*h-e._y0*e._l12_2a+e._y2*e._l01_2a)/u}if(e._l23_a>Pn){var l=2*e._l23_2a+3*e._l23_a*e._l12_a+e._l12_2a,c=3*e._l23_a*(e._l23_a+e._l12_a);o=(o*l+e._x1*e._l23_2a-a*e._l12_2a)/c,s=(s*l+e._y1*e._l23_2a-n*e._l12_2a)/c}e._context.bezierCurveTo(t,i,o,s,e._x2,e._y2)}function Ct(e,a){this._context=e,this._alpha=a}Ct.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:this.point(this._x2,this._y2);break}(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line},point:function(e,a){if(e=+e,a=+a,this._point){var n=this._x2-e,t=this._y2-a;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(n*n+t*t,this._alpha))}switch(this._point){case 0:this._point=1,this._line?this._context.lineTo(e,a):this._context.moveTo(e,a);break;case 1:this._point=2;break;case 2:this._point=3;default:Nl(this,e,a);break}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=e,this._y0=this._y1,this._y1=this._y2,this._y2=a}};const Cl=(function e(a){function n(t){return a?new Ct(t,a):new rn(t,0)}return n.alpha=function(t){return e(+t)},n})(.5);function Ka(e,a,n){this.k=e,this.x=a,this.y=n}Ka.prototype={constructor:Ka,scale:function(e){return e===1?this:new Ka(this.k*e,this.x,this.y)},translate:function(e,a){return e===0&a===0?this:new Ka(this.k,this.x+this.k*e,this.y+this.k*a)},apply:function(e){return[e[0]*this.k+this.x,e[1]*this.k+this.y]},applyX:function(e){return e*this.k+this.x},applyY:function(e){return e*this.k+this.y},invert:function(e){return[(e[0]-this.x)/this.k,(e[1]-this.y)/this.k]},invertX:function(e){return(e-this.x)/this.k},invertY:function(e){return(e-this.y)/this.k},rescaleX:function(e){return e.copy().domain(e.range().map(this.invertX,this).map(e.invert,e))},rescaleY:function(e){return e.copy().domain(e.range().map(this.invertY,this).map(e.invert,e))},toString:function(){return"translate("+this.x+","+this.y+") scale("+this.k+")"}};Ka.prototype;const Y=(e,a)=>e===void 0&&a===void 0?Math.random():(a===void 0&&(a=e,e=0),Math.floor(Math.random()*(a-e+1))+e),B=e=>e>=1?!0:e<=0?!1:Math.random()a=>a%e===0,Qa=(e=100,a=30,n=0,t=300,i=0)=>N(ma(ml.source(()=>Math.random())(e,a)(),n,t),i),Kl=e=>~~e+ +B(e%1),Ja=e=>e[Math.floor(Math.random()*e.length)],de=e=>{const a=[];for(const n in e)for(let t=0;tMath.round(e+(a-e)*Math.random()**n),J=e=>{if(typeof e!="string")return 0;if(!Number.isNaN(+e))return~~e+ +B(+e-~~e);const a=e[0]==="-"?-1:1;Number.isNaN(+e[0])&&(e=e.slice(1));const n=e.includes("-")?e.split("-"):null;if(!n)return 0;const t=Y(parseFloat(n[0])*a,+parseFloat(n[1]));return Number.isNaN(t)||t<0?0:t},Bl=()=>String(Math.floor(Math.random()*1e9)),q=e=>"aeiouyɑ'əøɛœæɶɒɨɪɔɐʊɤɯаоиеёэыуюяàèìòùỳẁȁȅȉȍȕáéíóúýẃőűâêîôûŷŵäëïöüÿẅãẽĩõũỹąęįǫųāēīōūȳăĕĭŏŭǎěǐǒǔȧėȯẏẇạẹịọụỵẉḛḭṵṳ".includes(e),ua=(e,a=3)=>{for(;e.length>a&&q(Ea(Array.from(e)));)e=e.slice(0,-1);return e},El=e=>{const a=[{name:"guo",probability:1,condition:/ Guo$/,action:n=>n.slice(0,-4)},{name:"orszag",probability:1,condition:/orszag$/,action:n=>n.length<9?`${n}ian`:n.slice(0,-6)},{name:"stan",probability:1,condition:/stan$/,action:n=>n.length<9?`${n}i`:ua(n.slice(0,-4))},{name:"land",probability:1,condition:/land$/,action:n=>{if(n.length>9)return n.slice(0,-4);const t=ua(n.slice(0,-4),0);return t.length<3?`${n}ic`:t.length<4?`${t}lish`:`${t}ish`}},{name:"que",probability:1,condition:/que$/,action:n=>n.replace(/que$/,"can")},{name:"a",probability:1,condition:/a$/,action:n=>`${n}n`},{name:"o",probability:1,condition:/o$/,action:n=>n.replace(/o$/,"an")},{name:"u",probability:1,condition:/u$/,action:n=>`${n}an`},{name:"i",probability:1,condition:/i$/,action:n=>`${n}an`},{name:"e",probability:1,condition:/e$/,action:n=>`${n}an`},{name:"ay",probability:1,condition:/ay$/,action:n=>`${n}an`},{name:"os",probability:1,condition:/os$/,action:n=>{const t=ua(n.slice(0,-2),0);return t.length<4?n.slice(0,-1):`${t}ian`}},{name:"es",probability:1,condition:/es$/,action:n=>{const t=ua(n.slice(0,-2),0);return t.length>7?n.slice(0,-1):`${t}ian`}},{name:"l",probability:.8,condition:/l$/,action:n=>`${n}ese`},{name:"n",probability:.8,condition:/n$/,action:n=>`${n}ese`},{name:"ad",probability:.8,condition:/ad$/,action:n=>`${n}ian`},{name:"an",probability:.8,condition:/an$/,action:n=>`${n}ian`},{name:"ish",probability:.25,condition:/^[a-zA-Z]{6}$/,action:n=>`${ua(n.slice(0,-1))}ish`},{name:"an",probability:.5,condition:/^[a-zA-Z]{0,7}$/,action:n=>`${ua(n)}an`}];for(const n of a)if(B(n.probability)&&n.condition.test(e))return n.action(e);return e},Hl=e=>e+(["st","nd","rd"][((e+90)%100-10)%10-1]||"th"),Ue=(e,a=[])=>{const t=e.replace("Old ","O ").replace(/[()]/g,"").split(" "),i=t.join("");let o=t.length===2?t[0][0]+t[1][0]:i.slice(0,2);for(let s=1;sIntl.ListFormat?new Intl.ListFormat(document.documentElement.lang||"en",{style:"long",type:"conjunction"}).format(e):e.join(", "),Ll=(e,a="°C")=>({"°C":t=>`${N(t)}°C`,"°F":t=>`${N(t*9/5+32)}°F`,K:t=>`${N(t+273.15)}K`,"°R":t=>`${N((t+273.15)*9/5)}°R`,"°De":t=>`${N((100-t)*3/2)}°De`,"°N":t=>`${N(t*33/100)}°N`,"°Ré":t=>`${N(t*4/5)}°Ré`,"°Rø":t=>`${N(t*21/40+7.5)}°Rø`})[a](e),Pl=e=>e>=1e9?`${N(e/1e9,1)}B`:e>=1e8?`${N(e/1e6)}M`:e>=1e6?`${N(e/1e6,1)}M`:e>=1e4?`${N(e/1e3)}K`:e>=1e3?`${N(e/1e3,1)}K`:N(e).toString(),Il=e=>{const a=e.slice(-1);return a==="K"?parseInt(e.slice(0,-1),10)*1e3:a==="M"?parseInt(e.slice(0,-1),10)*1e6:a==="B"?parseInt(e.slice(0,-1),10)*1e9:parseInt(e,10)},Dl=e=>{if(e.charAt(0)==="#")return e;const a=e.match(/^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?/i);return a&&a.length===4?"#"+`0${parseInt(a[1],10).toString(16)}`.slice(-2)+`0${parseInt(a[2],10).toString(16)}`.slice(-2)+`0${parseInt(a[3],10).toString(16)}`.slice(-2):""},on=["#dababf","#fb8072","#80b1d3","#fdb462","#b3de69","#fccde5","#c6b9c1","#bc80bd","#ccebc5","#ffed6f","#8dd3c7","#eb8de7"],Bt=e=>{const a=nn(zt);return Xt(()=>Math.random())(Ra(e).map(i=>i<12?on[i]:Z(a((i-12)/(e-12)))?.formatHex())).filter(i=>typeof i=="string")},ge=()=>Z(nn(zt)(Math.random())).formatHex(),Gl=(e,a=.2,n=.3)=>{const t=e&&e[0]==="#"?e:ge();return Z(we(t,ge())(a)).brighter(n).formatHex()},Et=e=>{let a;return e.parentNode?a=e.parentNode:e.host?a=e.host:e.defaultView&&(a=e.defaultView),a!==void 0?[e].concat(Et(a)):[e]},Ol=(e,a=1)=>{for(;document.getElementById(e+a);)a++;return e+a},ql=(e,a,...n)=>jl(e,Array.from,a,n),jl=(e,a,n,t)=>(function i(o,s){if(s>=t.length)return n(o);const h=new Map,u=t[s++];let l=-1;for(const c of o){const d=u(c,++l,o),r=h.get(d);r?r.push(c):h.set(d,[c])}for(const[c,d]of h)h.set(c,i(d,s));return a(h)})(e,0),fe=([e,a],[n,t])=>(e-n)**2+(a-t)**2;class Ul{constructor(a=[],n=(t,i)=>ti?1:0){if(this.data=a,this.length=this.data.length,this.compare=n,this.length>0)for(let t=(this.length>>1)-1;t>=0;t--)this._down(t)}push(a){this.data.push(a),this._up(this.length++)}pop(){if(this.length===0)return;const a=this.data[0],n=this.data.pop();return--this.length>0&&(this.data[0]=n,this._down(0)),a}peek(){return this.data[0]}_up(a){const{data:n,compare:t}=this,i=n[a];for(;a>0;){const o=a-1>>1,s=n[o];if(t(i,s)>=0)break;n[a]=s,a=o}n[a]=i}_down(a){const{data:n,compare:t}=this,i=this.length>>1,o=n[a];for(;a=0)break;n[a]=n[s],a=s}n[a]=o}}function Vl(e,a=1,n=!1){let t=1/0,i=1/0,o=-1/0,s=-1/0;for(const[y,k]of e[0])yo&&(o=y),k>s&&(s=k);const h=o-t,u=s-i,l=Math.max(a,Math.min(h,u));if(l===a){const y=[t,i];return y.distance=0,y}const c=new Ul([],(y,k)=>k.max-y.max);let d=Yl(e);const r=new me(t+h/2,i+u/2,0,e);r.d>d.d&&(d=r);let g=2;function m(y,k,b){const v=new me(y,k,b,e);g++,v.max>d.d+a&&c.push(v),v.d>d.d&&(d=v,n&&console.log(`found best ${Math.round(1e4*v.d)/1e4} after ${g} probes`))}let f=l/2;for(let y=t;ya!=c[1]>a&&e<(c[0]-l[0])*(a-l[1])/(c[1]-l[1])+l[0]&&(t=!t),i=Math.min(i,$l(e,a,l,c))}return i===0?0:(t?1:-1)*Math.sqrt(i)}function Yl(e){let a=0,n=0,t=0;const i=e[0];for(let s=0,h=i.length,u=h-1;s1?(i=t[0],o=t[1]):u>0&&(i+=s*u,o+=h*u)}return s=e-i,h=a-o,s*s+h*h}const Ht=(e,a)=>{const n=a.map(i=>e.p[i]);return`M${n.shift()} L${n.join(" ")} Z`},Gn=(e,a,n)=>{let t=!0,i="";return a.map(s=>{if(n(s))return t=!0,"";const h=t?"M":"L";return t=!1,i=h,` ${h==="L"&&h===i?"":h}${e.p[s]}`}).join("").trim()},Wl=(e,a,n)=>{const t=[];let i=e,o=e;for(;i!==a;)t.push(i),o=n[i],i=o;return t.push(i),t.reverse()},Rt=(e,a,n={polygons:!1,fill:!1,halo:!1,waterGap:!1})=>{const{cells:t,vertices:i}=e,o={},s=new Uint8Array(t.i.length),h=c=>{s[c]=1},u=c=>s[c]===1;for(const c of t.i){if(u(c)||!a(c))continue;h(c);const d=a(c),r=k=>a(k)===d,g=k=>a(k)!==d,m=t.c[c].find(g);if(m===void 0)continue;const f=e.features[t.f[m]];if(f.type==="lake"&&f.shoreline?.every(r))continue;const p=t.v[c].find(k=>i.c[k].some(g));if(p===void 0)throw new Error(`Starting vertex for cell ${c} is not found`);const y=Me({vertices:i,startingVertex:p,ofSameType:r,addToChecked:h,closeRing:!0});y.length<3||l(d,i,y,o,n)}return o;function l(c,d,r,g,m){if(g[c]||(g[c]={}),m.polygons&&(g[c].polygons||(g[c].polygons=[]),g[c].polygons.push(r.map(f=>d.p[f]))),m.fill&&(g[c].fill||(g[c].fill=""),g[c].fill+=Ht(d,r)),m.waterGap){g[c].waterGap||(g[c].waterGap="");const f=p=>d.c[p].every(y=>t.h[y]>=20);g[c].waterGap+=Gn(d,r,f)}if(m.halo){g[c].halo||(g[c].halo="");const f=p=>d.c[p].some(y=>t.b[y]);g[c].halo+=Gn(d,r,f)}}},Zl=(e,a={})=>{const{cells:n,vertices:t}=a,i=Object.fromEntries(e.map(d=>[d,!0])),o=d=>i[d],s=d=>!i[d],h=new Uint8Array(n.c.length),u=d=>{h[d]=1},l=d=>h[d]===1;let c="";for(const d of e){if(l(d))continue;const r=n.c[d].find(s);if(r===void 0)continue;const g=a.features[n.f[r]];if(g.type==="lake"&&g.shoreline&&g.shoreline.every(o))continue;const m=n.v[d].find(p=>t.c[p].some(s));if(m===void 0)throw new Error(`Starting vertex for cell ${d} is not found`);const f=Me({vertices:t,startingVertex:m,ofSameType:o,addToChecked:u,closeRing:!0});f.length<3||(c+=Ht(t,f))}return c},Ql=(e,a)=>{const n=Rt(e,a,{polygons:!0}),t=Object.entries(n).map(([i,o])=>{const s=o.polygons.sort((l,c)=>c.length-l.length),[h,u]=Vl(s,20);return[i,[N(h),N(u)]]});return Object.fromEntries(t)},Me=({vertices:e,startingVertex:a,ofSameType:n,addToChecked:t,closeRing:i})=>{const o=e.c.length,s=[];let h=a;for(let u=0;u===0||h!==a;u++){const l=s.at(-1),c=h;s.push(c);const d=e.c[c];t&&d.filter(n).forEach(t);const[r,g,m]=d.map(n),[f,p,y]=e.v[c];if(f!==l&&r!==g?h=f:p!==l&&g!==m?h=p:y!==l&&r!==m&&(h=y),h>=e.c.length){window.ERROR&&console.error("ConnectVertices: next vertex is out of bounds");break}if(h===c){window.ERROR&&console.error("ConnectVertices: next vertex is not found");break}if(u===o){window.ERROR&&console.error("ConnectVertices: max iterations reached",o);break}}return i&&s.push(a),s},Jl=(e,a,n,t={})=>{if(a(e))return null;const i=[],o=[],s=new window.FlatQueue;for(s.push(e,0);s.length;){const h=s.peekValue(),u=s.pop();for(const l of t.cells.c[u]){if(a(l))return i[l]=u,Wl(l,e,i);const c=n(u,l);if(c===1/0)continue;const d=h+c;d>=o[l]||(i[l]=u,o[l]=d,s.push(l,d))}}return null},ze=(e="",a=1)=>e.replace(/[\d.-][\d.e-]*/g,n=>N(parseFloat(n),a).toString()),Lt=e=>e.charAt(0).toUpperCase()+e.slice(1),Xl=e=>{const a=e.length/2,n=e.split(" ");if(n.length<2)return n;let t="",i="",o="",s="";return n.forEach((h,u)=>{u+1!==n.length&&(h+=" "),s+=h,!t||s.length{if(!e)return[0,0,0,0,0,1];const a=e.replace(/[a-z()]/g,"").replace(/[ ]/g,",").split(",");return[a[0]||0,a[1]||0,a[2]||0,a[3]||0,a[4]||0,a[5]||1]},eu=e=>{try{return JSON.parse(e),!0}catch{return!1}},nu=e=>{try{return JSON.parse(e)}catch{return null}},tu=e=>{if(!e)throw new Error("No string provided");let a=e.toLowerCase().trim().replace(/[^a-z0-9-_]/g,"").replace(/\s+/g,"-");return a.match(/^\d/)&&(a=`_${a}`),a},j=document.getElementById.bind(document);function iu(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var Xa={exports:{}},ru=Xa.exports,On;function ou(){return On||(On=1,(function(e,a){(function(n,t){e.exports=t()})(ru,function(){return n.importState=function(i){var o=new n;return o.importState(i),o},n;function n(){return(function(i){var o=0,s=0,h=0,u=1;i.length==0&&(i=[+new Date]);var l=t();o=l(" "),s=l(" "),h=l(" ");for(var c=0;c>>0,u-=i,u*=i,i=u>>>0,u-=i,i+=u*4294967296}return(i>>>0)*23283064365386963e-26};return o.version="Mash 0.9",o}})})(Xa)),Xa.exports}var su=ou();const Te=iu(su);class lu{delaunay;points;pointsN;cells={v:[],c:[],b:[],i:new Uint32Array};vertices={p:[],v:[],c:[]};constructor(a,n,t){this.delaunay=a,this.points=n,this.pointsN=t,this.vertices;for(let i=0;ithis.triangleOfEdge(u)),this.cells.c[o]=h.map(u=>this.delaunay.triangles[u]).filter(u=>uthis.cells.c[o].length?1:0}const s=this.triangleOfEdge(i);this.vertices.p[s]||(this.vertices.p[s]=this.triangleCenter(s),this.vertices.v[s]=this.trianglesAdjacentToTriangle(s),this.vertices.c[s]=this.pointsOfTriangle(s))}}pointsOfTriangle(a){return this.edgesOfTriangle(a).map(n=>this.delaunay.triangles[n])}trianglesAdjacentToTriangle(a){const n=[];for(const t of this.edgesOfTriangle(a)){const i=this.delaunay.halfedges[t];n.push(this.triangleOfEdge(i))}return n}edgesAroundPoint(a){const n=[];let t=a;do{n.push(t);const i=this.nextHalfedge(t);t=this.delaunay.halfedges[i]}while(t!==-1&&t!==a&&n.length<20);return n}triangleCenter(a){const n=this.pointsOfTriangle(a).map(t=>this.points[t]);return this.circumcenter(n[0],n[1],n[2])}edgesOfTriangle(a){return[3*a,3*a+1,3*a+2]}triangleOfEdge(a){return Math.floor(a/3)}nextHalfedge(a){return a%3===2?a-2:a+1}circumcenter(a,n,t){const[i,o]=a,[s,h]=n,[u,l]=t,c=i*i+o*o,d=s*s+h*h,r=u*u+l*l,g=2*(i*(h-l)+s*(l-o)+u*(o-h));return[Math.floor(1/g*(c*(h-l)+d*(l-o)+r*(o-h))),Math.floor(1/g*(c*(u-s)+d*(i-u)+r*(s-i)))]}}const uu=(e,a,n)=>{const t=N(-1*n),i=n*2,o=e-t*2,s=a-t*2,h=Math.ceil(o/i)-1,u=Math.ceil(s/i)-1,l=[];for(let c=.5;c{const t=n/2,i=t*.9,o=i*2,s=()=>Math.random()*o-i,h=[];for(let u=t;u{TIME&&console.time("placePoints");const n=+(j("pointsInput")?.dataset.cells||0),t=N(Math.sqrt(e*a/n),2),i=uu(e,a,t),o=hu(e,a,t),s=Math.floor((e+.5*t-1e-10)/t),h=Math.floor((a+.5*t-1e-10)/t);return TIME&&console.timeEnd("placePoints"),{spacing:t,cellsDesired:n,boundary:i,points:o,cellsX:s,cellsY:h}},du=(e,a,n,t)=>{if(a&&a!==e.seed)return!0;const i=+(j("pointsInput")?.dataset?.cells||0);if(i!==e.cellsDesired)return!0;const o=N(Math.sqrt(n*t/i),2),s=Math.floor((n+.5*o-1e-10)/o),h=Math.floor((t+.5*o-1e-10)/o);return e.spacing!==o||e.cellsX!==s||e.cellsY!==h},gu=(e,a,n)=>{Math.random=Te(e);const{spacing:t,cellsDesired:i,boundary:o,points:s,cellsX:h,cellsY:u}=cu(a,n),{cells:l,vertices:c}=Pt(s,o);return{spacing:t,cellsDesired:i,boundary:o,points:s,cellsX:h,cellsY:u,cells:l,vertices:c,seed:e}},Pt=(e,a)=>{TIME&&console.time("calculateDelaunay");const n=e.concat(a),t=Xe.from(n);TIME&&console.timeEnd("calculateDelaunay"),TIME&&console.time("calculateVoronoi");const i=new lu(t,n,e.length),o=i.cells;o.i=pe({maxValue:e.length,length:e.length}).map((h,u)=>u);const s=i.vertices;return TIME&&console.timeEnd("calculateVoronoi"),{cells:o,vertices:s}},X=(e,a,n)=>Math.floor(Math.min(a/n.spacing,n.cellsY-1))*n.cellsX+Math.floor(Math.min(e/n.spacing,n.cellsX-1)),fu=(e,a,n,t)=>{const i=t.cells.c;let o=Math.floor(n/t.spacing),s=[X(e,a,t)];if(!o||n===1)return s;if(o>0&&(s=s.concat(i[s[0]])),o>1){let h=i[s[0]];for(;o>1;){const u=h.slice();h=[],u.forEach(l=>{i[l].forEach(c=>{s.indexOf(c)===-1&&(s.push(c),h.push(c))})}),o--}}return s},mu=(e,a,n=1/0,t)=>{if(!t.cells?.q)return;const i=t.cells.q.find(e,a,n);return i?i[2]:void 0},It=(e,a,n,t)=>{let i,o,s;const h=(d,r)=>{d.result=[],d.x0=d.x-r,d.y0=d.y-r,d.x3=d.x+r,d.y3=d.y+r,d.radius=r*r},u=(d,r)=>{if(d.node.data.scanned=!0,rc.x3||c.y1>c.y3||c.x2=r)<<1|+(e>=d),c.i&&(c.q=c.quads[c.quads.length-1],c.quads[c.quads.length-1]=c.quads[c.quads.length-1-c.i],c.quads[c.quads.length-1-c.i]=c.q)}else i=e-+t._x.call(null,c.node.data),o=a-+t._y.call(null,c.node.data),s=i*i+o*o,u(c,s);c.q=c.quads.pop()}return c.result},pu=(e,a,n,t)=>It(e,a,n,t.cells.q).map(o=>o[2]),yu=(e,a)=>a.cells.v[e].map(n=>a.vertices.p[n]),Dt=(e,a)=>a.cells.v[e].map(n=>a.vertices.p[n]);function*ku(e,a,n,t,i,o=3){if(!(n>=e)||!(t>=a)||!(i>0))throw new Error;const s=n-e,h=t-a,u=i*i,l=3*u,c=i*Math.SQRT1_2,d=Math.ceil(s/c),r=Math.ceil(h/c),g=new Array(d*r),m=[];function f(y,k){const b=y/c|0,v=k/c|0,w=Math.max(b-2,0),_=Math.max(v-2,0),M=Math.min(b+3,d),T=Math.min(v+3,r);for(let S=_;Sa.cells.h[e]>=20,Gt=(e,a)=>a.cells.h[e]<20,bu=({heights:e,width:a,height:n,scheme:t,renderOcean:i})=>{const o=document.createElement("canvas");o.width=a,o.height=n;const s=o.getContext("2d"),h=s.createImageData(a,n),u=l=>l<20?i?l:0:l;for(let l=0;le.length<2?e:e.some(i=>i===void 0)?(window.ERROR&&console.error("Undefined point in clipPoly",e),e):window.polygonclip(e,[0,0,a,n],t),vu=(e,a,n=10)=>{if(e.length===2)return 1;let t=1,i=1/0;for(let o=0;o=i||(i=f,t=o+1)}}return t},wu=(e,a)=>{let n=!1;return function(...t){n||(e.apply(this,t),n=!0,setTimeout(()=>{n=!1},a))}},Au=(e,a)=>{let n=!1,t=null,i=null;function o(...s){if(n){t=s,i=this;return}e.apply(this,s),n=!0,setTimeout(()=>{n=!1,t&&(o.apply(i,t),t=i=null)},a)}return o},Su=e=>{const n=navigator.userAgent.toLowerCase().indexOf("firefox")>-1?`${e.toString()} ${e.stack}`:e.stack||"",t=/(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#/%?=~_|!:,.;]*[-A-Z0-9+&@#/%=~_|])/gi;return n.replace(t,s=>`${Ea(s.split("/"))}`).replace(/at /gi,"
  at ")},_u=(e,a)=>{const n=new XMLHttpRequest;n.onload=()=>{const t=new FileReader;t.onloadend=()=>{a(t.result)},t.readAsDataURL(n.response)},n.open("GET",e),n.responseType="blob",n.send()},Mu=e=>{window.open(e,"_blank")},zu=e=>{window.open(`https://github.com/Azgaar/Fantasy-Map-Generator/wiki/${e}`,"_blank")},Tu=(e,a)=>`${a}`,xu=e=>e.ctrlKey||e.metaKey,Nu=(e=100,a=1e3)=>new Date(Y(e,a),Y(12),Y(31)).toLocaleDateString("en",{year:"numeric",month:"long",day:"numeric"}),Ot=(e,a,n,t=2)=>N(a.lonW+e/n*a.lonT,t),qt=(e,a,n,t=2)=>N(a.latN-e/n*a.latT,t),Cu=(e,a,n,t,i,o=2)=>[Ot(e,n,t,o),qt(a,n,i,o)],qn=()=>{const e=document.getElementById("prompt");if(!e)return;const a=e.querySelector("#promptForm");if(!a)return;const n="Please provide an input",t={default:1,step:.01,min:0,max:100,required:!0};window.prompt=(o=n,s=t,h)=>{if(s.default===void 0)return window.ERROR&&console.error("Prompt: options object does not have default value defined");const u=e.querySelector("#promptInput"),l=e.querySelector("#promptText");if(!u||!l)return;l.innerHTML=o;const c=typeof s.default=="number"?"number":"text";u.type=c,s.step!==void 0&&(u.step=s.step.toString()),s.min!==void 0&&(u.min=s.min.toString()),s.max!==void 0&&(u.max=s.max.toString()),u.required=s.required!==!1,u.placeholder=`type a ${c}`,u.value=s.default.toString(),u.style.width=o.length>10?"100%":"auto",e.style.display="block",a.addEventListener("submit",d=>{d.preventDefault(),e.style.display="none";const r=c==="number"?+u.value:u.value;h&&h(r)},{once:!0})};const i=e.querySelector("#promptCancel");i&&i.addEventListener("click",()=>{e.style.display="none"})},Ku=(e,a)=>{window.debug.selectAll("text").remove(),window.debug.selectAll("text").data(e).enter().append("text").attr("x",(n,t)=>a.cells.p[t][0]).attr("y",(n,t)=>a.cells.p[t][1]).text(n=>n)},Bu=(e,a,n)=>{const t=Vn(e),i=Ba(e),o=window.getColorScheme(a.select("#landHeights").attr("scheme"));e=e.map(s=>1-ee(s,i,t)),window.debug.selectAll("polygon").remove(),window.debug.selectAll("polygon").data(e).enter().append("polygon").attr("points",(s,h)=>Dt(h,n)).attr("fill",s=>o(s)).attr("stroke",s=>o(s))},Eu=e=>{window.debug.select("#connections").remove();const a=window.debug.append("g").attr("id","connections").attr("stroke-width",.8),n=e.cells.p,t=e.cells.routes;for(const i in t)for(const o in t[i]){const[s,h]=n[i],[u,l]=n[o],[c,d]=[(s+u)/2,(h+l)/2],r=t[i][o];a.append("line").attr("x1",s).attr("y1",h).attr("x2",c).attr("y2",d).attr("data-id",r).attr("stroke",on[r%12])}},Hu=([e,a],{color:n="red",radius:t=.5})=>{window.debug.append("circle").attr("cx",e).attr("cy",a).attr("r",t).attr("fill",n)},Ru=(e,{color:a="red",width:n=.5})=>{const t=tn().curve(xl);window.debug.append("path").attr("d",ze(t(e))).attr("stroke",a).attr("stroke-width",n).attr("fill","none")};window.rn=N;window.lim=V;window.minmax=ma;window.normalize=ee;window.lerp=Ut;window.vowel=q;window.trimVowels=ua;window.getAdjective=El;window.nth=Hl;window.abbreviate=Ue;window.list=Rl;window.last=Ea;window.unique=jn;window.deepCopy=Vt;window.getTypedArray=Un;window.createTypedArray=pe;window.INT8_MAX=ea.INT8_MAX;window.UINT8_MAX=ea.UINT8_MAX;window.UINT16_MAX=ea.UINT16_MAX;window.UINT32_MAX=ea.UINT32_MAX;window.rand=Y;window.P=B;window.each=ba;window.gauss=Qa;window.Pint=Kl;window.ra=Ja;window.rw=de;window.biased=Kt;window.getNumberInRange=J;window.generateSeed=Bl;window.convertTemperature=(e,a=window.temperatureScale.value||"°C")=>Ll(e,a);window.si=Pl;window.getInteger=Il;window.toHEX=Dl;window.getColors=Bt;window.getRandomColor=ge;window.getMixedColor=Gl;window.C_12=on;window.getComposedPath=Et;window.getNextId=Ol;window.rollups=ql;window.dist2=fe;window.getIsolines=Rt;window.getPolesOfInaccessibility=Ql;window.connectVertices=Me;window.findPath=(e,a,n)=>Jl(e,a,n,window.pack);window.getVertexPath=e=>Zl(e,window.pack);window.round=ze;window.capitalize=Lt;window.splitInTwo=Xl;window.parseTransform=au;window.sanitizeId=tu;JSON.isValid=eu;JSON.safeParse=nu;window.byId=j;Node.prototype.on=function(e,a,n){return this.addEventListener(e,a,n),this};Node.prototype.off=function(e,a){return this.removeEventListener(e,a),this};window.shouldRegenerateGrid=(e,a)=>du(e,a,window.graphWidth,window.graphHeight);window.generateGrid=()=>gu(window.seed,window.graphWidth,window.graphHeight);window.findGridAll=(e,a,n)=>fu(e,a,n,window.grid);window.findGridCell=(e,a)=>X(e,a,window.grid);window.findCell=(e,a,n)=>mu(e,a,n,window.pack);window.findAll=(e,a,n)=>pu(e,a,n,window.pack);window.getPackPolygon=e=>yu(e,window.pack);window.getGridPolygon=e=>Dt(e,window.grid);window.calculateVoronoi=Pt;window.poissonDiscSampler=ku;window.findAllInQuadtree=It;window.drawHeights=bu;window.isLand=e=>ae(e,window.pack);window.isWater=e=>Gt(e,window.pack);window.clipPoly=(e,a)=>sn(e,graphWidth,graphHeight,a);window.getSegmentId=vu;window.debounce=wu;window.throttle=Au;window.parseError=Su;window.getBase64=_u;window.openURL=Mu;window.wiki=zu;window.link=Tu;window.isCtrlClick=xu;window.generateDate=Nu;window.getLongitude=(e,a)=>Ot(e,mapCoordinates,graphWidth,a);window.getLatitude=(e,a)=>qt(e,mapCoordinates,graphHeight,a);window.getCoordinates=(e,a,n)=>Cu(e,a,mapCoordinates,graphWidth,graphHeight,n);document.readyState==="loading"?document.addEventListener("DOMContentLoaded",qn):qn();window.drawCellsValue=e=>Ku(e,window.pack);window.drawPolygons=e=>Bu(e,window.terrs,window.grid);window.drawRouteConnections=()=>Eu(window.packedGraph);window.drawPoint=Hu;window.drawPath=Ru;class Lu{grid=null;heights=null;blobPower=0;linePower=0;clearData(){this.heights=null,this.grid=null}getBlobPower(a){return{1e3:.93,2e3:.95,5e3:.97,1e4:.98,2e4:.99,3e4:.991,4e4:.993,5e4:.994,6e4:.995,7e4:.9955,8e4:.996,9e4:.9964,1e5:.9973}[a]||.98}getLinePower(a){return{1e3:.75,2e3:.77,5e3:.79,1e4:.81,2e4:.82,3e4:.83,4e4:.84,5e4:.86,6e4:.87,7e4:.88,8e4:.91,9e4:.92,1e5:.93}[a]||.81}getPointInRange(a,n){if(typeof a!="string"){window.ERROR&&console.error("Range should be a string");return}const t=parseInt(a.split("-")[0],10)/100||0,i=parseInt(a.split("-")[1],10)/100||t;return Y(t*n,i*n)}setGraph(a){const{cellsDesired:n,cells:t,points:i}=a;this.heights=t.h?Uint8Array.from(t.h):pe({maxValue:100,length:i.length}),this.blobPower=this.getBlobPower(n),this.linePower=this.getLinePower(n),this.grid=a}addHill(a,n,t,i){const o=()=>{if(!this.heights||!this.grid)return;const h=new Uint8Array(this.heights.length);let u=0,l;const c=V(J(n));do{const r=this.getPointInRange(t,graphWidth),g=this.getPointInRange(i,graphHeight);if(r===void 0||g===void 0)return;l=X(r,g,this.grid),u++}while(this.heights[l]+c>90&&u<50);h[l]=c;const d=[l];for(;d.length;){const r=d.shift();for(const g of this.grid.cells.c[r])h[g]||(h[g]=h[r]**this.blobPower*(Math.random()*.2+.9),h[g]>1&&d.push(g))}this.heights=this.heights.map((r,g)=>V(r+h[g]))},s=J(a);for(let h=0;h{if(!this.heights||!this.grid)return;const h=new Uint8Array(this.heights.length);let u=0,l,c=V(J(n));do{const r=this.getPointInRange(t,graphWidth),g=this.getPointInRange(i,graphHeight);if(r===void 0||g===void 0)return;l=X(r,g,this.grid),u++}while(this.heights[l]<20&&u<50);const d=[l];for(;d.length;){const r=d.shift();if(c=c**this.blobPower*(Math.random()*.2+.9),c<1)return;this.grid.cells.c[r].forEach(g=>{h[g]||this.heights===null||(this.heights[g]=V(this.heights[g]-c*(Math.random()*.2+.9)),h[g]=1,d.push(g))})}},s=J(a);for(let h=0;h{if(!this.heights||!this.grid)return;const l=(f,p)=>{const y=[f],k=this.grid.points;for(c[f]=1;f!==p;){let b=1/0;if(this.grid.cells.c[f].forEach(v=>{if(c[v])return;let w=(k[p][0]-k[v][0])**2+(k[p][1]-k[v][1])**2;Math.random()>.85&&(w=w/2),wgraphWidth/3)&&k<50);o=X(f,p,this.grid),s=X(v,b,this.grid)}const r=l(o,s);let g=r.slice(),m=0;for(;g.length;){const f=g.slice();if(g=[],m++,f.forEach(p=>{this.heights&&(this.heights[p]=V(this.heights[p]+d*(Math.random()*.3+.85)))}),d=d**this.linePower-1,d<2)break;f.forEach(p=>{this.grid.cells.c[p].forEach(y=>{c[y]||(g.push(y),c[y]=1)})})}r.forEach((f,p)=>{if(p%6===0)for(const y of Ra(m)){const k=ln(this.grid.cells.c[f],(v,w)=>this.heights[v]-this.heights[w]);if(k===void 0)continue;const b=this.grid.cells.c[f][k];this.heights[b]=(this.heights[f]*2+this.heights[b])/3,f=b}})},u=J(a);for(let l=0;l{if(!this.heights||!this.grid)return;const l=(f,p)=>{const y=[f],k=this.grid.points;for(c[f]=1;f!==p;){let b=1/0;if(this.grid.cells.c[f].forEach(v=>{if(c[v])return;let w=(k[p][0]-k[v][0])**2+(k[p][1]-k[v][1])**2;Math.random()>.8&&(w=w/2),wgraphWidth/2)&&f<50);s=X(b,v,this.grid)}const r=l(o,s);let g=r.slice(),m=0;for(;g.length;){const f=g.slice();if(g=[],m++,f.forEach(p=>{this.heights[p]=V(this.heights[p]-d*(Math.random()*.3+.85))}),d=d**this.linePower-1,d<2)break;f.forEach(p=>{this.grid.cells.c[p].forEach(y=>{c[y]||(g.push(y),c[y]=1)})})}r.forEach((f,p)=>{if(p%6===0)for(const y of Ra(m)){const k=ln(this.grid.cells.c[f],(v,w)=>this.heights[v]-this.heights[w]);if(k===void 0)continue;const b=this.grid.cells.c[f][k];this.heights[b]=(this.heights[f]*2+this.heights[b])/3,f=b}})},u=J(a);for(let l=0;l{const k=[],b=this.grid.points;for(;p!==y;){let v=1/0;this.grid.cells.c[p].forEach(w=>{let _=(b[y][0]-b[w][0])**2+(b[y][1]-b[w][1])**2;Math.random()>.8&&(_=_/2),_{this.grid.cells.c[k].forEach(b=>{i[b]||(i[b]=1,m.push(b),this.heights[b]**=y,this.heights[b]>100&&(this.heights[b]=5))})}),g=m.slice()}}modify(a,n,t,i){if(!this.heights)return;const o=a==="land"?20:a==="all"?0:+a.split("-")[0],s=a==="land"||a==="all"?100:+a.split("-")[1],h=o===20;this.heights=this.heights.map(u=>us?u:(n&&(u=h?Math.max(u+n,20):u+n),t!==1&&(u=h?(u-20)*t+20:u*t),i&&(u=h?(u-20)**i+20:u**i),V(u)))}smooth(a=2,n=0){!this.heights||!this.grid||(this.heights=this.heights.map((t,i)=>{const o=[t];return this.grid.cells.c[i].forEach(s=>{o.push(this.heights[s])}),a===1?Ha(o)+n:V((t*(a-1)+Ha(o)+n)/a)}))}mask(a=1){if(!this.heights||!this.grid)return;const n=a?Math.abs(a):1;this.heights=this.heights.map((t,i)=>{const[o,s]=this.grid.points[i],h=2*o/graphWidth-1,u=2*s/graphHeight-1;let l=(1-h**2)*(1-u**2);a<0&&(l=1-l);const c=t*l;return V((t*(n-1)+c)/n)})}invert(a,n){if(!B(a)||!this.heights||!this.grid)return;const t=n!=="y",i=n!=="x",{cellsX:o,cellsY:s}=this.grid,h=this.heights.map((u,l)=>{if(!this.heights)return 0;const c=l%o,d=Math.floor(l/o),r=t?o-c-1:c,g=i?s-d-1:d,m=r+g*o;return this.heights[m]});this.heights=h}addStep(a,n,t,i,o){if(a==="Hill"){this.addHill(n,t,i,o);return}if(a==="Pit"){this.addPit(n,t,i,o);return}if(a==="Range"){this.addRange(n,t,i,o);return}if(a==="Trough"){this.addTrough(n,t,i,o);return}if(a==="Strait"){this.addStrait(n,t);return}if(a==="Mask"){this.mask(+n);return}if(a==="Invert"){this.invert(+n,t);return}if(a==="Add"){this.modify(t,+n,1);return}if(a==="Multiply"){this.modify(t,0,+n);return}if(a==="Smooth"){this.smooth(+n);return}}async generate(a){TIME&&console.time("defineHeightmap");const n=j("templateInput").value;Math.random=Te(seed);const i=n in heightmapTemplates?this.fromTemplate(a,n):await this.fromPrecreated(a,n);return TIME&&console.timeEnd("defineHeightmap"),this.clearData(),i}fromTemplate(a,n){const i=(heightmapTemplates[n]?.template||"").split(` +`);if(!i.length)throw new Error(`Heightmap template: no steps. Template: ${n}. Steps: ${i}`);this.setGraph(a);for(const o of i){const s=o.trim().split(" ");if(s.length<2)throw new Error(`Heightmap template: steps < 2. Template: ${n}. Step: ${s}`);this.addStep(...s)}return this.heights}getHeightsFromImageData(a){if(this.heights)for(let n=0;n{const i=document.createElement("canvas"),o=i.getContext("2d"),{cellsX:s,cellsY:h}=a;i.width=s,i.height=h;const u=new Image;u.src=`./heightmaps/${n}.png`,u.onload=()=>{if(!o)throw new Error("Could not get canvas context");this.heights=this.heights||new Uint8Array(s*h),o.drawImage(u,0,0,s,h);const l=o.getImageData(0,0,s,h);this.setGraph(a),this.getHeightsFromImageData(l.data),i.remove(),u.remove(),t(this.heights)}})}getHeights(){return this.heights}}window.HeightmapGenerator=new Lu;class Pu{DEEPER_LAND=3;LANDLOCKED=2;LAND_COAST=1;UNMARKED=0;WATER_COAST=-1;DEEP_WATER=-2;markup({distanceField:a,neighbors:n,start:t,increment:i,limit:o=ea.INT8_MAX}){for(let s=t,h=1/0;h>0&&s!==o;s+=i){h=0;const u=s-i;for(let l=0;l=20;let g=!1;for(;l.length;){const f=l.pop();!g&&t[f]&&(g=!0);for(const p of n[f]){const y=a[p]>=20;r===y&&h[p]===this.UNMARKED?(h[p]=c,l.push(p)):r&&!y&&(s[f]=this.LAND_COAST,s[p]=this.WATER_COAST)}}const m=r?"island":g?"ocean":"lake";u.push({i:c,land:r,border:g,type:m}),l[0]=h.indexOf(this.UNMARKED)}this.markup({distanceField:s,neighbors:n,start:this.DEEP_WATER,increment:-1,limit:-10}),grid.cells.t=s,grid.cells.f=h,grid.features=[0,...u],TIME&&console.timeEnd("markupGrid")}markupPack(){const a=p=>{const y=s[p].filter(v=>Gt(v,pack)),k=y.map(v=>fe(i.p[p],i.p[v])),b=k.indexOf(Math.min.apply(Math,k));r[p]=y[b],g[p]=y.length},n=(p,y)=>{if(p==="ocean")return[y,[]];const k=z=>d[z],b=k(y),v=z=>k(z)===b,w=z=>k(z)!==b,_=T(y),M=S(_);return[_,M];function T(z){const A=C=>h[C]||s[C].some(w);if(A(z))return z;const x=i.i.filter(v).find(A);if(x===void 0)throw new Error(`Markup: firstCell ${z} is not on the feature or map border`);return x}function S(z){const A=i.v[z].find(x=>o.c[x].some(w));if(A===void 0)throw new Error(`Markup: startingVertex for cell ${z} is not found`);return Me({vertices:o,startingVertex:A,ofSameType:v,closeRing:!1})}},t=({firstCell:p,land:y,border:k,featureId:b,totalCells:v})=>{const w=y?"island":k?"ocean":"lake",[_,M]=n(w,p),T=sn(M.map(x=>o.p[x])),S=gl(T),z=Math.abs(N(S)),A={i:b,type:w,land:y,border:k,cells:v,firstCell:_,vertices:M,area:z,shoreline:[],height:0};return w==="lake"&&(S>0&&(A.vertices=A.vertices.reverse()),A.shoreline=jn(A.vertices.flatMap(x=>o.c[x].filter(C=>ae(C,pack)))),A.height=Lakes.getHeight(A)),{...A}};TIME&&console.time("markupPack");const{cells:i,vertices:o}=pack,{c:s,b:h,i:u}=i,l=u.length;if(!l)return;const c=new Int8Array(l),d=new Uint16Array(l),r=pe({maxValue:l,length:l}),g=new Uint8Array(l),m=[],f=[0];for(let p=1;f[0]!==-1;p++){const y=f[0];d[y]=p;const k=ae(y,pack);let b=!!h[y],v=1;for(;f.length;){const w=f.pop();h[w]&&(b=!0);for(const _ of s[w]){const M=ae(_,pack);k&&!M?(c[w]=this.LAND_COAST,c[_]=this.WATER_COAST,r[w]||a(w)):k&&M&&(c[_]===this.UNMARKED&&c[w]===this.LAND_COAST?c[_]=this.LANDLOCKED:c[w]===this.UNMARKED&&c[_]===this.LAND_COAST&&(c[w]=this.LANDLOCKED)),!d[_]&&k===M&&(f.push(_),d[_]=p,v++)}}m.push(t({firstCell:y,land:k,border:b,featureId:p,totalCells:v})),f[0]=d.indexOf(this.UNMARKED)}this.markup({distanceField:c,neighbors:s,start:this.DEEPER_LAND,increment:1}),this.markup({distanceField:c,neighbors:s,start:this.DEEP_WATER,increment:-1,limit:-10}),pack.cells.t=c,pack.cells.f=d,pack.cells.haven=r,pack.cells.harbor=g,pack.features=[0,...m],TIME&&console.timeEnd("markupPack")}defineGroups(){const a=grid.cells.i.length,n=a/25,t=a/1e3,i=a/10,o=a/1e3,s=c=>{const d=pack.features[pack.cells.f[c.firstCell-1]];return d&&d.type==="lake"?"lake_island":c.cells>i?"continent":c.cells>o?"island":"isle"},h=c=>c.cells>n?"ocean":c.cells>t?"sea":"gulf",u=c=>{if(c.temp<-3)return"frozen";if(c.height>60&&c.cells<10&&c.firstCell%10===0)return"lava";if(!c.inlets&&!c.outlet){if(c.evaporation>c.flux*4)return"dry";if(c.cells<3&&c.firstCell%10===0)return"sinkhole"}return!c.outlet&&c.evaporation>c.flux?"salt":"freshwater"},l=c=>{if(c.type==="island")return s(c);if(c.type==="ocean")return h(c);if(c.type==="lake")return u(c);throw new Error(`Markup: unknown feature type ${c.type}`)};for(const c of pack.features)!c||c.type==="ocean"||(c.type==="lake"&&(c.height=Lakes.getHeight(c)),c.group=l(c))}}window.Features=new Pu;class Iu{chains=[];calculateChain(a){const n=[],t=a.split(",");for(const i of t){const o=i.trim().toLowerCase(),s=!/[^\x20-\x7e]/.test(o);for(let h=-1,u="";ht){u.lengthr===m[g+1]&&!i.includes(r)?d:d.length?d.slice(-1)==="-"&&r===" "?d:d.slice(-1)===" "||d.slice(-1)==="-"?d+r.toUpperCase():r==="a"&&m[g+1]==="e"||g+2d.length<2)&&(c=c.split(" ").map((d,r)=>r?d.toLowerCase():d).join("")),c.length<2&&(ERROR&&console.error("Name is too short! Random name will be selected"),c=Ja(nameBases[a].b.split(","))),c}getCulture(a,n,t,i){if(a===void 0)return ERROR&&console.error("Please define a culture"),"ERROR";const o=pack.cultures[a].base;return this.getBase(o,n,t,i)}getCultureShort(a){return a===void 0?(ERROR&&console.error("Please define a culture"),"ERROR"):this.getBaseShort(pack.cultures[a].base)}getBaseShort(a){const n=nameBases[a]?nameBases[a].min-1:void 0,t=n?Math.max(nameBases[a].max-2,n):void 0;return this.getBase(a,n,t,"")}validateSuffix(a,n){if(a.slice(-1*n.length)===n)return a;const t=n.charAt(0);return a.slice(-1)===t&&(a=a.slice(0,-1)),q(t)===q(a.slice(-1))&&q(t)===q(a.slice(-2,-1))&&(a=a.slice(0,-1)),a.slice(-1)===t&&(a=a.slice(0,-1)),a+n}addSuffix(a){const n=B(.8)?"ia":"land";return n==="ia"&&a.length>6?a=a.slice(0,-(a.length-3)):n==="land"&&a.length>6&&(a=a.slice(0,-(a.length-5))),this.validateSuffix(a,n)}getState(a,n,t){if(a===void 0)return ERROR&&console.error("Please define a base name"),"ERROR";if(n===void 0&&t===void 0)return ERROR&&console.error("Please define a culture"),"ERROR";if(t===void 0&&(t=pack.cultures[n].base),a.includes(" ")&&(a=Lt(a.replace(/ /g,"").toLowerCase())),a.length>6&&a.slice(-4)==="berg"&&(a=a.slice(0,-4)),a.length>5&&a.slice(-3)==="ton"&&(a=a.slice(0,-3)),t===5&&["sk","ev","ov"].includes(a.slice(-2)))a=a.slice(0,-2);else{if(t===12)return q(a.slice(-1))?a:`${a}u`;t===18&&B(.4)&&(a=q(a.slice(0,1).toLowerCase())?`Al${a.toLowerCase()}`:`Al ${a}`)}if(t>32&&t<42)return a;if(a.length>3&&q(a.slice(-1)))if(q(a.slice(-2,-1))&&B(.85))a=a.slice(0,-2);else if(B(.7))a=a.slice(0,-1);else return a;else if(B(.4))return a;let i="ia";const o=Math.random(),s=a.length;return t===3&&o<.03&&s<7||t===4&&o<.03&&s<7||t===13&&o<.03&&s<7?i="terra":t===2&&o<.03&&s<7?i="terre":t===0&&o<.5&&s<7||t===1&&o<.4&&s<7||t===6&&o<.3&&s<7||t===32&&o<.1&&s<7?i="land":t===7&&o<.1?i="eia":t===9&&o<.35?i="maa":t===15&&o<.4&&s<6?i="orszag":t===16?i=o<.6?"yurt":"eli":t===10?i="guk":t===11?i=" Guo":t===14?i=o<.5&&s<6?"tlan":"co":(t===17&&o<.8||t===18&&o<.8)&&(i="a"),this.validateSuffix(a,i)}getMapName(a){if(!a&&locked("mapName"))return;a&&locked("mapName")&&unlock("mapName");const n=B(.7)?2:B(.5)?Y(0,6):Y(0,31);if(!nameBases[n])return tip("Namebase is not found",!1,"error"),"";const t=nameBases[n].min-1,i=Math.max(nameBases[n].max-3,t),o=this.getBase(n,t,i,""),s=B(.7)?this.addSuffix(o):o;mapName.value=s}getNameBases(){return[{name:"German",i:0,min:5,max:12,d:"lt",m:0,b:"Achern,Aichhalden,Aitern,Albbruck,Alpirsbach,Altensteig,Althengstett,Appenweier,Auggen,Badenen,Badenweiler,Baiersbronn,Ballrechten,Bellingen,Berghaupten,Bernau,Biberach,Biederbach,Binzen,Birkendorf,Birkenfeld,Bischweier,Blumberg,Bollen,Bollschweil,Bonndorf,Bosingen,Braunlingen,Breisach,Breisgau,Breitnau,Brigachtal,Buchenbach,Buggingen,Buhl,Buhlertal,Calw,Dachsberg,Dobel,Donaueschingen,Dornhan,Dornstetten,Dottingen,Dunningen,Durbach,Durrheim,Ebhausen,Ebringen,Efringen,Egenhausen,Ehrenkirchen,Ehrsberg,Eimeldingen,Eisenbach,Elzach,Elztal,Emmendingen,Endingen,Engelsbrand,Enz,Enzklosterle,Eschbronn,Ettenheim,Ettlingen,Feldberg,Fischerbach,Fischingen,Fluorn,Forbach,Freiamt,Freiburg,Freudenstadt,Friedenweiler,Friesenheim,Frohnd,Furtwangen,Gaggenau,Geisingen,Gengenbach,Gernsbach,Glatt,Glatten,Glottertal,Gorwihl,Gottenheim,Grafenhausen,Grenzach,Griesbach,Gutach,Gutenbach,Hag,Haiterbach,Hardt,Harmersbach,Hasel,Haslach,Hausach,Hausen,Hausern,Heitersheim,Herbolzheim,Herrenalb,Herrischried,Hinterzarten,Hochenschwand,Hofen,Hofstetten,Hohberg,Horb,Horben,Hornberg,Hufingen,Ibach,Ihringen,Inzlingen,Kandern,Kappel,Kappelrodeck,Karlsbad,Karlsruhe,Kehl,Keltern,Kippenheim,Kirchzarten,Konigsfeld,Krozingen,Kuppenheim,Kussaberg,Lahr,Lauchringen,Lauf,Laufenburg,Lautenbach,Lauterbach,Lenzkirch,Liebenzell,Loffenau,Loffingen,Lorrach,Lossburg,Mahlberg,Malsburg,Malsch,March,Marxzell,Marzell,Maulburg,Monchweiler,Muhlenbach,Mullheim,Munstertal,Murg,Nagold,Neubulach,Neuenburg,Neuhausen,Neuried,Neuweiler,Niedereschach,Nordrach,Oberharmersbach,Oberkirch,Oberndorf,Oberbach,Oberried,Oberwolfach,Offenburg,Ohlsbach,Oppenau,Ortenberg,otigheim,Ottenhofen,Ottersweier,Peterstal,Pfaffenweiler,Pfalzgrafenweiler,Pforzheim,Rastatt,Renchen,Rheinau,Rheinfelden,Rheinmunster,Rickenbach,Rippoldsau,Rohrdorf,Rottweil,Rummingen,Rust,Sackingen,Sasbach,Sasbachwalden,Schallbach,Schallstadt,Schapbach,Schenkenzell,Schiltach,Schliengen,Schluchsee,Schomberg,Schonach,Schonau,Schonenberg,Schonwald,Schopfheim,Schopfloch,Schramberg,Schuttertal,Schwenningen,Schworstadt,Seebach,Seelbach,Seewald,Sexau,Simmersfeld,Simonswald,Sinzheim,Solden,Staufen,Stegen,Steinach,Steinen,Steinmauern,Straubenhardt,Stuhlingen,Sulz,Sulzburg,Teinach,Tiefenbronn,Tiengen,Titisee,Todtmoos,Todtnau,Todtnauberg,Triberg,Tunau,Tuningen,uhlingen,Unterkirnach,Reichenbach,Utzenfeld,Villingen,Villingendorf,Vogtsburg,Vohrenbach,Waldachtal,Waldbronn,Waldkirch,Waldshut,Wehr,Weil,Weilheim,Weisenbach,Wembach,Wieden,Wiesental,Wildbad,Wildberg,Winzeln,Wittlingen,Wittnau,Wolfach,Wutach,Wutoschingen,Wyhlen,Zavelstein"},{name:"English",i:1,min:6,max:11,d:"",m:.1,b:"Abingdon,Albrighton,Alcester,Almondbury,Altrincham,Amersham,Andover,Appleby,Ashboume,Atherstone,Aveton,Axbridge,Aylesbury,Baldock,Bamburgh,Barton,Basingstoke,Berden,Bere,Berkeley,Berwick,Betley,Bideford,Bingley,Birmingham,Blandford,Blechingley,Bodmin,Bolton,Bootham,Boroughbridge,Boscastle,Bossinney,Bramber,Brampton,Brasted,Bretford,Bridgetown,Bridlington,Bromyard,Bruton,Buckingham,Bungay,Burton,Calne,Cambridge,Canterbury,Carlisle,Castleton,Caus,Charmouth,Chawleigh,Chichester,Chillington,Chinnor,Chipping,Chisbury,Cleobury,Clifford,Clifton,Clitheroe,Cockermouth,Coleshill,Combe,Congleton,Crafthole,Crediton,Cuddenbeck,Dalton,Darlington,Dodbrooke,Drax,Dudley,Dunstable,Dunster,Dunwich,Durham,Dymock,Exeter,Exning,Faringdon,Felton,Fenny,Finedon,Flookburgh,Fowey,Frampton,Gateshead,Gatton,Godmanchester,Grampound,Grantham,Guildford,Halesowen,Halton,Harbottle,Harlow,Hatfield,Hatherleigh,Haydon,Helston,Henley,Hertford,Heytesbury,Hinckley,Hitchin,Holme,Hornby,Horsham,Kendal,Kenilworth,Kilkhampton,Kineton,Kington,Kinver,Kirby,Knaresborough,Knutsford,Launceston,Leighton,Lewes,Linton,Louth,Luton,Lyme,Lympstone,Macclesfield,Madeley,Malborough,Maldon,Manchester,Manningtree,Marazion,Marlborough,Marshfield,Mere,Merryfield,Middlewich,Midhurst,Milborne,Mitford,Modbury,Montacute,Mousehole,Newbiggin,Newborough,Newbury,Newenden,Newent,Norham,Northleach,Noss,Oakham,Olney,Orford,Ormskirk,Oswestry,Padstow,Paignton,Penkneth,Penrith,Penzance,Pershore,Petersfield,Pevensey,Pickering,Pilton,Pontefract,Portsmouth,Preston,Quatford,Reading,Redcliff,Retford,Rockingham,Romney,Rothbury,Rothwell,Salisbury,Saltash,Seaford,Seasalter,Sherston,Shifnal,Shoreham,Sidmouth,Skipsea,Skipton,Solihull,Somerton,Southam,Southwark,Standon,Stansted,Stapleton,Stottesdon,Sudbury,Swavesey,Tamerton,Tarporley,Tetbury,Thatcham,Thaxted,Thetford,Thornbury,Tintagel,Tiverton,Torksey,Totnes,Towcester,Tregoney,Trematon,Tutbury,Uxbridge,Wallingford,Wareham,Warenmouth,Wargrave,Warton,Watchet,Watford,Wendover,Westbury,Westcheap,Weymouth,Whitford,Wickwar,Wigan,Wigmore,Winchelsea,Winkleigh,Wiscombe,Witham,Witheridge,Wiveliscombe,Woodbury,Yeovil"},{name:"French",i:2,min:5,max:13,d:"nlrs",m:.1,b:"Adon,Aillant,Amilly,Andonville,Ardon,Artenay,Ascheres,Ascoux,Attray,Aubin,Audeville,Aulnay,Autruy,Auvilliers,Auxy,Aveyron,Baccon,Bardon,Barville,Batilly,Baule,Bazoches,Beauchamps,Beaugency,Beaulieu,Beaune,Bellegarde,Boesses,Boigny,Boiscommun,Boismorand,Boisseaux,Bondaroy,Bonnee,Bonny,Bordes,Bou,Bougy,Bouilly,Boulay,Bouzonville,Bouzy,Boynes,Bray,Breteau,Briare,Briarres,Bricy,Bromeilles,Bucy,Cepoy,Cercottes,Cerdon,Cernoy,Cesarville,Chailly,Chaingy,Chalette,Chambon,Champoulet,Chanteau,Chantecoq,Chapell,Charme,Charmont,Charsonville,Chateau,Chateauneuf,Chatel,Chatenoy,Chatillon,Chaussy,Checy,Chevannes,Chevillon,Chevilly,Chevry,Chilleurs,Choux,Chuelles,Clery,Coinces,Coligny,Combleux,Combreux,Conflans,Corbeilles,Corquilleroy,Cortrat,Coudroy,Coullons,Coulmiers,Courcelles,Courcy,Courtemaux,Courtempierre,Courtenay,Cravant,Crottes,Dadonville,Dammarie,Dampierre,Darvoy,Desmonts,Dimancheville,Donnery,Dordives,Dossainville,Douchy,Dry,Echilleuses,Egry,Engenville,Epieds,Erceville,Ervauville,Escrennes,Escrignelles,Estouy,Faverelles,Fay,Feins,Ferolles,Ferrieres,Fleury,Fontenay,Foret,Foucherolles,Freville,Gatinais,Gaubertin,Gemigny,Germigny,Gidy,Gien,Girolles,Givraines,Gondreville,Grangermont,Greneville,Griselles,Guigneville,Guilly,Gyleslonains,Huetre,Huisseau,Ingrannes,Ingre,Intville,Isdes,Ivre,Jargeau,Jouy,Juranville,Bussiere,Laas,Ladon,Lailly,Langesse,Leouville,Ligny,Lombreuil,Lorcy,Lorris,Loury,Louzouer,Malesherbois,Marcilly,Mardie,Mareau,Marigny,Marsainvilliers,Melleroy,Menestreau,Merinville,Messas,Meung,Mezieres,Migneres,Mignerette,Mirabeau,Montargis,Montbarrois,Montbouy,Montcresson,Montereau,Montigny,Montliard,Mormant,Morville,Moulinet,Moulon,Nancray,Nargis,Nesploy,Neuville,Neuvy,Nevoy,Nibelle,Nogent,Noyers,Ocre,Oison,Olivet,Ondreville,Onzerain,Orleans,Ormes,Orville,Oussoy,Outarville,Ouzouer,Pannecieres,Pannes,Patay,Paucourt,Pers,Pierrefitte,Pithiverais,Pithiviers,Poilly,Potier,Prefontaines,Presnoy,Pressigny,Puiseaux,Quiers,Ramoulu,Rebrechien,Rouvray,Rozieres,Rozoy,Ruan,Sandillon,Santeau,Saran,Sceaux,Seichebrieres,Semoy,Sennely,Sermaises,Sigloy,Solterre,Sougy,Sully,Sury,Tavers,Thignonville,Thimory,Thorailles,Thou,Tigy,Tivernon,Tournoisis,Trainou,Treilles,Trigueres,Trinay,Vannes,Varennes,Vennecy,Vieilles,Vienne,Viglain,Vignes,Villamblain,Villemandeur,Villemoutiers,Villemurlin,Villeneuve,Villereau,Villevoques,Villorceau,Vimory,Vitry,Vrigny"},{name:"Italian",i:3,min:5,max:12,d:"cltr",m:.1,b:"Accumoli,Acquafondata,Acquapendente,Acuto,Affile,Agosta,Alatri,Albano,Allumiere,Alvito,Amaseno,Amatrice,Anagni,Anguillara,Anticoli,Antrodoco,Anzio,Aprilia,Aquino,Arcinazzo,Ariccia,Arpino,Arsoli,Ausonia,Bagnoregio,Bassiano,Bellegra,Belmonte,Bolsena,Bomarzo,Borgorose,Boville,Bracciano,Broccostella,Calcata,Camerata,Campagnano,Campoli,Canale,Canino,Cantalice,Cantalupo,Capranica,Caprarola,Carbognano,Casalattico,Casalvieri,Castelforte,Castelnuovo,Castiglione,Castro,Castrocielo,Ceccano,Celleno,Cellere,Cerreto,Cervara,Cerveteri,Ciampino,Ciciliano,Cittaducale,Cittareale,Civita,Civitella,Colfelice,Colleferro,Collepardo,Colonna,Concerviano,Configni,Contigliano,Cori,Cottanello,Esperia,Faleria,Farnese,Ferentino,Fiamignano,Filacciano,Fiuggi,Fiumicino,Fondi,Fontana,Fonte,Fontechiari,Formia,Frascati,Frasso,Frosinone,Fumone,Gaeta,Gallese,Gavignano,Genazzano,Giuliano,Gorga,Gradoli,Grottaferrata,Grotte,Guarcino,Guidonia,Ischia,Isola,Labico,Labro,Ladispoli,Latera,Lenola,Leonessa,Licenza,Longone,Lubriano,Maenza,Magliano,Marano,Marcellina,Marcetelli,Marino,Mazzano,Mentana,Micigliano,Minturno,Montalto,Montasola,Montebuono,Monteflavio,Montelanico,Monteleone,Montenero,Monterosi,Moricone,Morlupo,Nazzano,Nemi,Nerola,Nespolo,Nettuno,Norma,Olevano,Onano,Oriolo,Orte,Orvinio,Paganico,Paliano,Palombara,Patrica,Pescorocchiano,Petrella,Piansano,Picinisco,Pico,Piedimonte,Piglio,Pignataro,Poggio,Poli,Pomezia,Pontecorvo,Pontinia,Ponzano,Posta,Pozzaglia,Priverno,Proceno,Rignano,Riofreddo,Ripi,Rivodutri,Rocca,Roccagorga,Roccantica,Roccasecca,Roiate,Ronciglione,Roviano,Salisano,Sambuci,Santa,Santini,Scandriglia,Segni,Selci,Sermoneta,Serrone,Settefrati,Sezze,Sgurgola,Sonnino,Sora,Soriano,Sperlonga,Spigno,Subiaco,Supino,Sutri,Tarano,Tarquinia,Terelle,Terracina,Tivoli,Toffia,Tolfa,Torrice,Torricella,Trevi,Trevignano,Trivigliano,Turania,Tuscania,Valentano,Vallecorsa,Vallemaio,Vallepietra,Vallerano,Vasanello,Vejano,Velletri,Ventotene,Veroli,Vetralla,Vicalvi,Vico,Vicovaro,Vignanello,Viterbo,Viticuso,Vitorchiano,Vivaro,Zagarolo"},{name:"Castillian",i:4,min:5,max:11,d:"lr",m:0,b:"Ajofrin,Alameda,Alaminos,Albares,Albarreal,Albendiego,Alcanizo,Alcaudete,Alcolea,Aldea,Aldeanueva,Algar,Algora,Alhondiga,Almadrones,Almendral,Alovera,Anguita,Arbancon,Argecilla,Arges,Arroyo,Atanzon,Atienza,Azuqueca,Baides,Banos,Bargas,Barriopedro,Belvis,Berninches,Brihuega,Buenaventura,Burgos,Burguillos,Bustares,Cabanillas,Calzada,Camarena,Campillo,Cantalojas,Cardiel,Carmena,Casas,Castejon,Castellar,Castilforte,Castillo,Castilnuevo,Cazalegas,Centenera,Cervera,Checa,Chozas,Chueca,Cifuentes,Cincovillas,Ciruelas,Cogollor,Cogolludo,Consuegra,Copernal,Corral,Cuerva,Domingo,Dosbarrios,Driebes,Duron,Escalona,Escalonilla,Escamilla,Escopete,Espinosa,Esplegares,Esquivias,Estables,Estriegana,Fontanar,Fuembellida,Fuensalida,Fuentelsaz,Gajanejos,Galvez,Gascuena,Gerindote,Guadamur,Heras,Herreria,Herreruela,Hinojosa,Hita,Hombrados,Hontanar,Hormigos,Huecas,Huerta,Humanes,Illana,Illescas,Iniestola,Irueste,Jadraque,Jirueque,Lagartera,Ledanca,Lillo,Lominchar,Loranca,Lucillos,Luzaga,Luzon,Madrid,Magan,Malaga,Malpica,Manzanar,Maqueda,Masegoso,Matillas,Medranda,Megina,Mejorada,Millana,Milmarcos,Mirabueno,Miralrio,Mocejon,Mochales,Molina,Mondejar,Montarron,Mora,Moratilla,Morenilla,Navas,Negredo,Noblejas,Numancia,Nuno,Ocana,Ocentejo,Olias,Olmeda,Ontigola,Orea,Orgaz,Oropesa,Otero,Palma,Pardos,Paredes,Penalver,Pepino,Peralejos,Pinilla,Pioz,Piqueras,Portillo,Poveda,Pozo,Pradena,Prados,Puebla,Puerto,Quero,Quintanar,Rebollosa,Retamoso,Riba,Riofrio,Robledo,Romanillos,Romanones,Rueda,Salmeron,Santiuste,Santo,Sauca,Segura,Selas,Semillas,Sesena,Setiles,Sevilla,Siguenza,Solanillos,Somolinos,Sonseca,Sotillo,Talavera,Taravilla,Tembleque,Tendilla,Tierzo,Torralba,Torre,Torrejon,Torrijos,Tortola,Tortuera,Totanes,Trillo,Uceda,Ugena,Urda,Utande,Valdesotos,Valhermoso,Valtablado,Valverde,Velada,Viana,Yebra,Yuncos,Yunquera,Zaorejas,Zarzuela,Zorita"},{name:"Ruthenian",i:5,min:5,max:10,d:"",m:0,b:"Belgorod,Beloberezhye,Belyi,Belz,Berestiy,Berezhets,Berezovets,Berezutsk,Bobruisk,Bolonets,Borisov,Borovsk,Bozhesk,Bratslav,Bryansk,Brynsk,Buryn,Byhov,Chechersk,Chemesov,Cheremosh,Cherlen,Chern,Chernigov,Chernitsa,Chernobyl,Chernogorod,Chertoryesk,Chetvertnia,Demyansk,Derevesk,Devyagoresk,Dichin,Dmitrov,Dorogobuch,Dorogobuzh,Drestvin,Drokov,Drutsk,Dubechin,Dubichi,Dubki,Dubkov,Dveren,Galich,Glebovo,Glinsk,Goloty,Gomiy,Gorodets,Gorodische,Gorodno,Gorohovets,Goroshin,Gorval,Goryshon,Holm,Horobor,Hoten,Hotin,Hotmyzhsk,Ilovech,Ivan,Izborsk,Izheslavl,Kamenets,Kanev,Karachev,Karna,Kavarna,Klechesk,Klyapech,Kolomyya,Kolyvan,Kopyl,Korec,Kornik,Korochunov,Korshev,Korsun,Koshkin,Kotelno,Kovyla,Kozelsk,Kozelsk,Kremenets,Krichev,Krylatsk,Ksniatin,Kulatsk,Kursk,Kursk,Lebedev,Lida,Logosko,Lomihvost,Loshesk,Loshichi,Lubech,Lubno,Lubutsk,Lutsk,Luchin,Luki,Lukoml,Luzha,Lvov,Mtsensk,Mdin,Medniki,Melecha,Merech,Meretsk,Mescherskoe,Meshkovsk,Metlitsk,Mezetsk,Mglin,Mihailov,Mikitin,Mikulino,Miloslavichi,Mogilev,Mologa,Moreva,Mosalsk,Moschiny,Mozyr,Mstislav,Mstislavets,Muravin,Nemech,Nemiza,Nerinsk,Nichan,Novgorod,Novogorodok,Obolichi,Obolensk,Obolensk,Oleshsk,Olgov,Omelnik,Opoka,Opoki,Oreshek,Orlets,Osechen,Oster,Ostrog,Ostrov,Perelai,Peremil,Peremyshl,Pererov,Peresechen,Perevitsk,Pereyaslav,Pinsk,Ples,Polotsk,Pronsk,Proposhesk,Punia,Putivl,Rechitsa,Rodno,Rogachev,Romanov,Romny,Roslavl,Rostislavl,Rostovets,Rsha,Ruza,Rybchesk,Rylsk,Rzhavesk,Rzhev,Rzhischev,Sambor,Serensk,Serensk,Serpeysk,Shilov,Shuya,Sinech,Sizhka,Skala,Slovensk,Slutsk,Smedin,Sneporod,Snitin,Snovsk,Sochevo,Sokolec,Starica,Starodub,Stepan,Sterzh,Streshin,Sutesk,Svinetsk,Svisloch,Terebovl,Ternov,Teshilov,Teterin,Tiversk,Torchevsk,Toropets,Torzhok,Tripolye,Trubchevsk,Tur,Turov,Usvyaty,Uteshkov,Vasilkov,Velil,Velye,Venev,Venicha,Verderev,Vereya,Veveresk,Viazma,Vidbesk,Vidychev,Voino,Volodimer,Volok,Volyn,Vorobesk,Voronich,Voronok,Vorotynsk,Vrev,Vruchiy,Vselug,Vyatichsk,Vyatka,Vyshegorod,Vyshgorod,Vysokoe,Yagniatin,Yaropolch,Yasenets,Yuryev,Yuryevets,Zaraysk,Zhitomel,Zholvazh,Zizhech,Zubkov,Zudechev,Zvenigorod"},{name:"Nordic",i:6,min:6,max:10,d:"kln",m:.1,b:"Akureyri,Aldra,Alftanes,Andenes,Austbo,Auvog,Bakkafjordur,Ballangen,Bardal,Beisfjord,Bifrost,Bildudalur,Bjerka,Bjerkvik,Bjorkosen,Bliksvaer,Blokken,Blonduos,Bolga,Bolungarvik,Borg,Borgarnes,Bosmoen,Bostad,Bostrand,Botsvika,Brautarholt,Breiddalsvik,Bringsli,Brunahlid,Budardalur,Byggdakjarni,Dalvik,Djupivogur,Donnes,Drageid,Drangsnes,Egilsstadir,Eiteroga,Elvenes,Engavogen,Ertenvog,Eskifjordur,Evenes,Eyrarbakki,Fagernes,Fallmoen,Fellabaer,Fenes,Finnoya,Fjaer,Fjelldal,Flakstad,Flateyri,Flostrand,Fludir,Gardaber,Gardur,Gimstad,Givaer,Gjeroy,Gladstad,Godoya,Godoynes,Granmoen,Gravdal,Grenivik,Grimsey,Grindavik,Grytting,Hafnir,Halsa,Hauganes,Haugland,Hauknes,Hella,Helland,Hellissandur,Hestad,Higrav,Hnifsdalur,Hofn,Hofsos,Holand,Holar,Holen,Holkestad,Holmavik,Hopen,Hovden,Hrafnagil,Hrisey,Husavik,Husvik,Hvammstangi,Hvanneyri,Hveragerdi,Hvolsvollur,Igeroy,Indre,Inndyr,Innhavet,Innes,Isafjordur,Jarklaustur,Jarnsreykir,Junkerdal,Kaldvog,Kanstad,Karlsoy,Kavosen,Keflavik,Kjelde,Kjerstad,Klakk,Kopasker,Kopavogur,Korgen,Kristnes,Krutoga,Krystad,Kvina,Lande,Laugar,Laugaras,Laugarbakki,Laugarvatn,Laupstad,Leines,Leira,Leiren,Leland,Lenvika,Loding,Lodingen,Lonsbakki,Lopsmarka,Lovund,Luroy,Maela,Melahverfi,Meloy,Mevik,Misvaer,Mornes,Mosfellsber,Moskenes,Myken,Naurstad,Nesberg,Nesjahverfi,Nesset,Nevernes,Obygda,Ofoten,Ogskardet,Okervika,Oknes,Olafsfjordur,Oldervika,Olstad,Onstad,Oppeid,Oresvika,Orsnes,Orsvog,Osmyra,Overdal,Prestoya,Raudalaekur,Raufarhofn,Reipo,Reykholar,Reykholt,Reykjahlid,Rif,Rinoya,Rodoy,Rognan,Rosvika,Rovika,Salhus,Sanden,Sandgerdi,Sandoker,Sandset,Sandvika,Saudarkrokur,Selfoss,Selsoya,Sennesvik,Setso,Siglufjordur,Silvalen,Skagastrond,Skjerstad,Skonland,Skorvogen,Skrova,Sleneset,Snubba,Softing,Solheim,Solheimar,Sorarnoy,Sorfugloy,Sorland,Sormela,Sorvaer,Sovika,Stamsund,Stamsvika,Stave,Stokka,Stokkseyri,Storjord,Storo,Storvika,Strand,Straumen,Strendene,Sudavik,Sudureyri,Sundoya,Sydalen,Thingeyri,Thorlakshofn,Thorshofn,Tjarnabyggd,Tjotta,Tosbotn,Traelnes,Trofors,Trones,Tverro,Ulvsvog,Unnstad,Utskor,Valla,Vandved,Varmahlid,Vassos,Vevelstad,Vidrek,Vik,Vikholmen,Vogar,Vogehamn,Vopnafjordur"},{name:"Greek",i:7,min:5,max:11,d:"s",m:.1,b:"Abdera,Acharnae,Aegae,Aegina,Agrinion,Aigosthena,Akragas,Akroinon,Akrotiri,Alalia,Alexandria,Amarynthos,Amaseia,Amphicaea,Amphigeneia,Amphipolis,Antipatrea,Antiochia,Apamea,Aphidna,Apollonia,Argos,Artemita,Argyropolis,Asklepios,Athenai,Athmonia,Bhrytos,Borysthenes,Brauron,Byblos,Byzantion,Bythinion,Calydon,Chamaizi,Chalcis,Chios,Cleona,Corcyra,Croton,Cyrene,Cythera,Decelea,Delos,Delphi,Dicaearchia,Didyma,Dion,Dioscurias,Dodona,Dorylaion,Elateia,Eleusis,Eleutherna,Emporion,Ephesos,Epidamnos,Epidauros,Epizephyrian,Erythrae,Eubea,Golgi,Gonnos,Gorgippia,Gournia,Gortyn,Gytion,Hagios,Halicarnassos,Heliopolis,Hellespontos,Heloros,Heraclea,Hierapolis,Himera,Histria,Hubla,Hyele,Ialysos,Iasos,Idalion,Imbros,Iolcos,Itanos,Ithaca,Juktas,Kallipolis,Kameiros,Karistos,Kasmenai,Kepoi,Kimmerikon,Knossos,Korinthos,Kos,Kourion,Kydonia,Kyrenia,Lamia,Lampsacos,Laodicea,Lapithos,Larissa,Lebena,Lefkada,Lekhaion,Leibethra,Leontinoi,Lilaea,Lindos,Lissos,Magnesia,Mantineia,Marathon,Marmara,Massalia,Megalopolis,Megara,Metapontion,Methumna,Miletos,Morgantina,Mulai,Mukenai,Myonia,Myra,Myrmekion,Myos,Nauplios,Naucratis,Naupaktos,Naxos,Neapolis,Nemea,Nicaea,Nicopolis,Nymphaion,Nysa,Odessos,Olbia,Olympia,Olynthos,Opos,Orchomenos,Oricos,Orestias,Oreos,Onchesmos,Pagasae,Palaikastro,Pandosia,Panticapaion,Paphos,Pargamon,Paros,Pegai,Pelion,Peiraies,Phaistos,Phaleron,Pharos,Pithekussa,Philippopolis,Phocaea,Pinara,Pisa,Pitane,Plataea,Poseidonia,Potidaea,Pseira,Psychro,Pteleos,Pydna,Pylos,Pyrgos,Rhamnos,Rhithymna,Rhypae,Rizinia,Rodos,Salamis,Samos,Skyllaion,Seleucia,Semasos,Sestos,Scidros,Sicyon,,Sinope,Siris,Smyrna,Sozopolis,Sparta,Stagiros,Stratos,Stymphalos,Sybaris,Surakousai,Taras,Tanagra,Tanais,Tauromenion,Tegea,Temnos,Teos,Thapsos,Thassos,Thebai,Theodosia,Therma,Thespian,Thronion,Thoricos,Thurii,Thyreum,Thyria,Tithoraea,Tomis,Tragurion,Tripolis,Troliton,Troy,Tylissos,Tyros,Vathypetros,Zakynthos,Zakros"},{name:"Roman",i:8,min:6,max:11,d:"ln",m:.1,b:"Abila,Adflexum,Adnicrem,Aelia,Aelius,Aeminium,Aequum,Agrippina,Agrippinae,Ala,Albanianis,Aleria,Ambianum,Andautonia,Apulum,Aquae,Aquaegranni,Aquensis,Aquileia,Aquincum,Arae,Argentoratum,Ariminum,Ascrivium,Asturica,Atrebatum,Atuatuca,Augusta,Aurelia,Aurelianorum,Batavar,Batavorum,Belum,Biriciana,Blestium,Bonames,Bonna,Bononia,Borbetomagus,Bovium,Bracara,Brigantium,Burgodunum,Caesaraugusta,Caesarea,Caesaromagus,Calleva,Camulodunum,Cannstatt,Cantiacorum,Capitolina,Caralis,Castellum,Castra,Castrum,Cibalae,Clausentum,Colonia,Concangis,Condate,Confluentes,Conimbriga,Corduba,Coria,Corieltauvorum,Corinium,Coriovallum,Cornoviorum,Danum,Deva,Dianium,Divodurum,Dobunnorum,Drusi,Dubris,Dumnoniorum,Durnovaria,Durocobrivis,Durocornovium,Duroliponte,Durovernum,Durovigutum,Eboracum,Ebusus,Edetanorum,Emerita,Emona,Emporiae,Euracini,Faventia,Flaviae,Florentia,Forum,Gerulata,Gerunda,Gesoscribate,Glevensium,Hadriani,Herculanea,Isca,Italica,Iulia,Iuliobrigensium,Iuvavum,Lactodurum,Lagentium,Lapurdum,Lauri,Legionis,Lemanis,Lentia,Lepidi,Letocetum,Lindinis,Lindum,Lixus,Londinium,Lopodunum,Lousonna,Lucus,Lugdunum,Luguvalium,Lutetia,Mancunium,Marsonia,Martius,Massa,Massilia,Matilo,Mattiacorum,Mediolanum,Mod,Mogontiacum,Moridunum,Mursa,Naissus,Nervia,Nida,Nigrum,Novaesium,Noviomagus,Olicana,Olisippo,Ovilava,Parisiorum,Partiscum,Paterna,Pistoria,Placentia,Pollentia,Pomaria,Pompeii,Pons,Portus,Praetoria,Praetorium,Pullum,Ragusium,Ratae,Raurica,Ravenna,Regina,Regium,Regulbium,Rigomagus,Roma,Romula,Rutupiae,Salassorum,Salernum,Salona,Scalabis,Segovia,Silurum,Sirmium,Siscia,Sorviodurum,Sumelocenna,Tarraco,Taurinorum,Theranda,Traiectum,Treverorum,Tungrorum,Turicum,Ulpia,Valentia,Venetiae,Venta,Verulamium,Vesontio,Vetera,Victoriae,Victrix,Villa,Viminacium,Vindelicorum,Vindobona,Vinovia,Viroconium"},{name:"Finnic",i:9,min:5,max:11,d:"akiut",m:0,b:"Aanekoski,Ahlainen,Aholanvaara,Ahtari,Aijala,Akaa,Alajarvi,Antsla,Aspo,Bennas,Bjorkoby,Elva,Emasalo,Espoo,Esse,Evitskog,Forssa,Haapamaki,Haapavesi,Haapsalu,Hameenlinna,Hanko,Harjavalta,Hattuvaara,Hautajarvi,Havumaki,Heinola,Hetta,Hinkabole,Hirmula,Hossa,Huittinen,Husula,Hyryla,Hyvinkaa,Ikaalinen,Iskmo,Itakoski,Jamsa,Jarvenpaa,Jeppo,Jioesuu,Jiogeva,Joensuu,Jokikyla,Jungsund,Jyvaskyla,Kaamasmukka,Kajaani,Kalajoki,Kallaste,Kankaanpaa,Karkku,Karpankyla,Kaskinen,Kasnas,Kauhajoki,Kauhava,Kauniainen,Kauvatsa,Kehra,Kellokoski,Kelottijarvi,Kemi,Kemijarvi,Kerava,Keuruu,Kiljava,Kiuruvesi,Kivesjarvi,Kiviioli,Kivisuo,Klaukkala,Klovskog,Kohtlajarve,Kokemaki,Kokkola,Kolho,Koskue,Kotka,Kouva,Kaupunki,Kuhmo,Kunda,Kuopio,Kuressaare,Kurikka,Kuusamo,Kylmalankyla,Lahti,Laitila,Lankipohja,Lansikyla,Lapua,Laurila,Lautiosaari,Lempaala,Lepsama,Liedakkala,Lieksa,Littoinen,Lohja,Loimaa,Loksa,Loviisa,Malmi,Mantta,Matasvaara,Maula,Miiluranta,Mioisakula,Munapirtti,Mustvee,Muurahainen,Naantali,Nappa,Narpio,Niinimaa,Niinisalo,Nikkila,Nilsia,Nivala,Nokia,Nummela,Nuorgam,Nuvvus,Obbnas,Oitti,Ojakkala,Onninen,Orimattila,Orivesi,Otanmaki,Otava,Otepaa,Oulainen,Oulu,Paavola,Paide,Paimio,Pakankyla,Paldiski,Parainen,Parkumaki,Parola,Perttula,Pieksamaki,Pioltsamaa,Piolva,Pohjavaara,Porhola,Porrasa,Porvoo,Pudasjarvi,Purmo,Pyhajarvi,Raahe,Raasepori,Raisio,Rajamaki,Rakvere,Rapina,Rapla,Rauma,Rautio,Reposaari,Riihimaki,Rovaniemi,Roykka,Ruonala,Ruottala,Rutalahti,Saarijarvi,Salo,Sastamala,Saue,Savonlinna,Seinajoki,Sillamae,Siuntio,Sompujarvi,Suonenjoki,Suurejaani,Syrjantaka,Tamsalu,Tapa,Temmes,Tiorva,Tormasenvaara,Tornio,Tottijarvi,Tulppio,Turenki,Turi,Tuukkala,Tuurala,Tuuri,Tuuski,Tuusniemi,Ulvila,Unari,Upinniemi,Utti,Uusikaupunki,Vaaksy,Vaalimaa,Vaarinmaja,Vaasa,Vainikkala,Valga,Valkeakoski,Vantaa,Varkaus,Vehkapera,Vehmasmaki,Vieki,Vierumaki,Viitasaari,Viljandi,Vilppula,Viohma,Vioru,Virrat,Ylike,Ylivieska,Ylojarvi"},{name:"Korean",i:10,min:5,max:11,d:"",m:0,b:"Anjung,Ansan,Anseong,Anyang,Aphae,Apo,Baekseok,Baeksu,Beolgyo,Boeun,Boseong,Busan,Buyeo,Changnyeong,Changwon,Cheonan,Cheongdo,Cheongjin,Cheongsong,Cheongyang,Cheorwon,Chirwon,Chuncheon,Chungju,Daedeok,Daegaya,Daejeon,Damyang,Dangjin,Dasa,Donghae,Dongsong,Doyang,Eonyang,Gaeseong,Ganggyeong,Ganghwa,Gangneung,Ganseong,Gaun,Geochang,Geoje,Geoncheon,Geumho,Geumil,Geumwang,Gijang,Gimcheon,Gimhwa,Gimje,Goa,Gochang,Gohan,Gongdo,Gongju,Goseong,Goyang,Gumi,Gunpo,Gunsan,Guri,Gurye,Gwangju,Gwangyang,Gwansan,Gyeongseong,Hadong,Hamchang,Hampyeong,Hamyeol,Hanam,Hapcheon,Hayang,Heungnam,Hongnong,Hongseong,Hwacheon,Hwando,Hwaseong,Hwasun,Hwawon,Hyangnam,Incheon,Inje,Iri,Janghang,Jangheung,Jangseong,Jangseungpo,Jangsu,Jecheon,Jeju,Jeomchon,Jeongeup,Jeonggwan,Jeongju,Jeongok,Jeongseon,Jeonju,Jido,Jiksan,Jinan,Jincheon,Jindo,Jingeon,Jinjeop,Jinnampo,Jinyeong,Jocheon,Jochiwon,Jori,Maepo,Mangyeong,Mokpo,Muju,Munsan,Naesu,Naju,Namhae,Namwon,Namyang,Namyangju,Nongong,Nonsan,Ocheon,Okcheon,Okgu,Onam,Onsan,Onyang,Opo,Paengseong,Pogok,Poseung,Pungsan,Pyeongchang,Pyeonghae,Pyeongyang,Sabi,Sacheon,Samcheok,Samho,Samrye,Sancheong,Sangdong,Sangju,Sapgyo,Sariwon,Sejong,Seocheon,Seogwipo,Seonghwan,Seongjin,Seongju,Seongnam,Seongsan,Seosan,Seungju,Siheung,Sindong,Sintaein,Soheul,Sokcho,Songak,Songjeong,Songnim,Songtan,Suncheon,Taean,Taebaek,Tongjin,Uijeongbu,Uiryeong,Uiwang,Uljin,Ulleung,Unbong,Ungcheon,Ungjin,Waegwan,Wando,Wayang,Wiryeseong,Wondeok,Yangju,Yangsan,Yangyang,Yecheon,Yeomchi,Yeoncheon,Yeongam,Yeongcheon,Yeongdeok,Yeongdong,Yeonggwang,Yeongju,Yeongwol,Yeongyang,Yeonil,Yongin,Yongjin,Yugu"},{name:"Chinese",i:11,min:5,max:10,d:"",m:0,b:"Anding,Anlu,Anqing,Anshun,Baixing,Banyang,Baoqing,Binzhou,Caozhou,Changbai,Changchun,Changde,Changling,Changsha,Changzhou,Chengdu,Chenzhou,Chizhou,Chongqing,Chuxiong,Chuzhou,Dading,Daming,Datong,Daxing,Dengzhou,Deqing,Dihua,Dingli,Dongan,Dongchang,Dongchuan,Dongping,Duyun,Fengtian,Fengxiang,Fengyang,Fenzhou,Funing,Fuzhou,Ganzhou,Gaoyao,Gaozhou,Gongchang,Guangnan,Guangning,Guangping,Guangxin,Guangzhou,Guiyang,Hailong,Hangzhou,Hanyang,Hanzhong,Heihe,Hejian,Henan,Hengzhou,Hezhong,Huaian,Huaiqing,Huanglong,Huangzhou,Huining,Hulan,Huzhou,Jiading,Jian,Jianchang,Jiangning,Jiankang,Jiaxing,Jiayang,Jilin,Jinan,Jingjiang,Jingzhao,Jinhua,Jinzhou,Jiujiang,Kaifeng,Kaihua,Kangding,Kuizhou,Laizhou,Lianzhou,Liaoyang,Lijiang,Linan,Linhuang,Lintao,Liping,Liuzhou,Longan,Longjiang,Longxing,Luan,Lubin,Luzhou,Mishan,Nanan,Nanchang,Nandian,Nankang,Nanyang,Nenjiang,Ningbo,Ningguo,Ningwu,Ningxia,Ningyuan,Pingjiang,Pingliang,Pingyang,Puer,Puzhou,Qianzhou,Qingyang,Qingyuan,Qingzhou,Qujing,Quzhou,Raozhou,Rende,Ruian,Ruizhou,Shafeng,Shajing,Shaoqing,Shaowu,Shaoxing,Shaozhou,Shinan,Shiqian,Shouchun,Shuangcheng,Shulei,Shunde,Shuntian,Shuoping,Sicheng,Sinan,Sizhou,Songjiang,Suiding,Suihua,Suining,Suzhou,Taian,Taibei,Taiping,Taiwan,Taiyuan,Taizhou,Taonan,Tengchong,Tingzhou,Tongchuan,Tongqing,Tongzhou,Weihui,Wensu,Wenzhou,Wuchang,Wuding,Wuzhou,Xian,Xianchun,Xianping,Xijin,Xiliang,Xincheng,Xingan,Xingde,Xinghua,Xingjing,Xingyi,Xingyuan,Xingzhong,Xining,Xinmen,Xiping,Xuanhua,Xunzhou,Xuzhou,Yanan,Yangzhou,Yanji,Yanping,Yanzhou,Yazhou,Yichang,Yidu,Yilan,Yili,Yingchang,Yingde,Yingtian,Yingzhou,Yongchang,Yongping,Yongshun,Yuanzhou,Yuezhou,Yulin,Yunnan,Yunyang,Zezhou,Zhang,Zhangzhou,Zhaoqing,Zhaotong,Zhenan,Zhending,Zhenhai,Zhenjiang,Zhenxi,Zhenyun,Zhongshan,Zunyi"},{name:"Japanese",i:12,min:4,max:10,d:"",m:0,b:"Abira,Aga,Aikawa,Aizumisato,Ajigasawa,Akkeshi,Amagi,Ami,Ando,Asakawa,Ashikita,Bandai,Biratori,Chonan,Esashi,Fuchu,Fujimi,Funagata,Genkai,Godo,Goka,Gonohe,Gyokuto,Haboro,Hamatonbetsu,Harima,Hashikami,Hayashima,Heguri,Hidaka,Higashiura,Hiranai,Hirogawa,Hiroo,Hodatsushimizu,Hoki,Hokuei,Hokuryu,Horokanai,Ibigawa,Ichikai,Ichikawa,Ichinohe,Iijima,Iizuna,Ikawa,Inagawa,Itakura,Iwaizumi,Iwate,Kaisei,Kamifurano,Kamiita,Kamijima,Kamikawa,Kamishihoro,Kamiyama,Kanda,Kanna,Kasagi,Kasuya,Katsuura,Kawabe,Kawamoto,Kawanehon,Kawanishi,Kawara,Kawasaki,Kawatana,Kawazu,Kihoku,Kikonai,Kin,Kiso,Kitagata,Kitajima,Kiyama,Kiyosato,Kofu,Koge,Kohoku,Kokonoe,Kora,Kosa,Kotohira,Kudoyama,Kumejima,Kumenan,Kumiyama,Kunitomi,Kurate,Kushimoto,Kutchan,Kyonan,Kyotamba,Mashike,Matsumae,Mifune,Mihama,Minabe,Minami,Minamiechizen,Minamitane,Misaki,Misasa,Misato,Miyashiro,Miyoshi,Mori,Moseushi,Mutsuzawa,Nagaizumi,Nagatoro,Nagayo,Nagomi,Nakadomari,Nakanojo,Nakashibetsu,Namegawa,Nanbu,Nanporo,Naoshima,Nasu,Niseko,Nishihara,Nishiizu,Nishikatsura,Nishikawa,Nishinoshima,Nishiwaga,Nogi,Noto,Nyuzen,Oarai,Obuse,Odai,Ogawara,Oharu,Oirase,Oishida,Oiso,Oizumi,Oji,Okagaki,Okutama,Omu,Ono,Osaka,Otobe,Otsuki,Owani,Reihoku,Rifu,Rikubetsu,Rishiri,Rokunohe,Ryuo,Saka,Sakuho,Samani,Satsuma,Sayo,Saza,Setana,Shakotan,Shibayama,Shikama,Shimamoto,Shimizu,Shintomi,Shirakawa,Shisui,Shitara,Sobetsu,Sue,Sumita,Suooshima,Suttsu,Tabuse,Tachiarai,Tadami,Tadaoka,Taiji,Taiki,Takachiho,Takahama,Taketoyo,Taragi,Tateshina,Tatsugo,Tawaramoto,Teshikaga,Tobe,Tokigawa,Toma,Tomioka,Tonosho,Tosa,Toyokoro,Toyotomi,Toyoyama,Tsubata,Tsubetsu,Tsukigata,Tsuno,Tsuwano,Umi,Wakasa,Yamamoto,Yamanobe,Yamatsuri,Yanaizu,Yasuda,Yoichi,Yonaguni,Yoro,Yoshino,Yubetsu,Yugawara,Yuni,Yusuhara,Yuza"},{name:"Portuguese",i:13,min:5,max:11,d:"",m:.1,b:"Abrigada,Afonsoeiro,Agueda,Aguilada,Alagoas,Alagoinhas,Albufeira,Alcanhoes,Alcobaca,Alcoutim,Aldoar,Alenquer,Alfeizerao,Algarve,Almada,Almagreira,Almeirim,Alpalhao,Alpedrinha,Alvorada,Amieira,Anapolis,Apelacao,Aranhas,Arganil,Armacao,Assenceira,Aveiro,Avelar,Balsas,Barcarena,Barreiras,Barretos,Batalha,Beira,Benavente,Betim,Braga,Braganca,Brasilia,Brejo,Cabeceiras,Cabedelo,Cachoeiras,Cadafais,Calhandriz,Calheta,Caminha,Campinas,Canidelo,Canoas,Capinha,Carmoes,Cartaxo,Carvalhal,Carvoeiro,Cascavel,Castanhal,Caxias,Chapadinha,Chaves,Cocais,Coentral,Coimbra,Comporta,Conde,Coqueirinho,Coruche,Damaia,Dourados,Enxames,Ericeira,Ervidel,Escalhao,Esmoriz,Espinhal,Estela,Estoril,Eunapolis,Evora,Famalicao,Fanhoes,Faro,Fatima,Felgueiras,Ferreira,Figueira,Flecheiras,Florianopolis,Fornalhas,Fortaleza,Freiria,Freixeira,Fronteira,Fundao,Gracas,Gradil,Grainho,Gralheira,Guimaraes,Horta,Ilhavo,Ilheus,Lages,Lagos,Laranjeiras,Lavacolhos,Leiria,Limoeiro,Linhares,Lisboa,Lomba,Lorvao,Lourical,Lourinha,Luziania,Macedo,Machava,Malveira,Marinhais,Maxial,Mealhada,Milharado,Mira,Mirandela,Mogadouro,Montalegre,Mourao,Nespereira,Nilopolis,Obidos,Odemira,Odivelas,Oeiras,Oleiros,Olhalvo,Olinda,Olival,Oliveira,Oliveirinha,Palheiros,Palmeira,Palmital,Pampilhosa,Pantanal,Paradinha,Parelheiros,Pedrosinho,Pegoes,Penafiel,Peniche,Pinhao,Pinheiro,Pombal,Pontal,Pontinha,Portel,Portimao,Quarteira,Queluz,Ramalhal,Reboleira,Recife,Redinha,Ribadouro,Ribeira,Ribeirao,Rosais,Sabugal,Sacavem,Sagres,Sandim,Sangalhos,Santarem,Santos,Sarilhos,Seixas,Seixezelo,Seixo,Silvares,Silveira,Sinhaem,Sintra,Sobral,Sobralinho,Tabuaco,Tabuleiro,Taveiro,Teixoso,Telhado,Telheiro,Tomar,Torreira,Trancoso,Troviscal,Vagos,Varzea,Velas,Viamao,Viana,Vidigal,Vidigueira,Vidual,Vilamar,Vimeiro,Vinhais,Vitoria"},{name:"Nahuatl",i:14,min:6,max:13,d:"l",m:0,b:"Acapulco,Acatepec,Acatlan,Acaxochitlan,Acolman,Actopan,Acuamanala,Ahuacatlan,Almoloya,Amacuzac,Amanalco,Amaxac,Apaxco,Apetatitlan,Apizaco,Atenco,Atizapan,Atlacomulco,Atlapexco,Atotonilco,Axapusco,Axochiapan,Axocomanitla,Axutla,Azcapotzalco,Aztahuacan,Calimaya,Calnali,Calpulalpan,Camotlan,Capulhuac,Chalco,Chapulhuacan,Chapultepec,Chiapan,Chiautempan,Chiconautla,Chihuahua,Chilcuautla,Chimalhuacan,Cholollan,Cihuatlan,Coahuila,Coatepec,Coatetelco,Coatlan,Coatlinchan,Coatzacoalcos,Cocotitlan,Cohetzala,Colima,Colotlan,Coyoacan,Coyohuacan,Cuapiaxtla,Cuauhnahuac,Cuauhtemoc,Cuauhtitlan,Cuautepec,Cuautla,Cuaxomulco,Culhuacan,Ecatepec,Eloxochitlan,Epatlan,Epazoyucan,Huamantla,Huascazaloya,Huatlatlauca,Huautla,Huehuetlan,Huehuetoca,Huexotla,Hueyapan,Hueyotlipan,Hueypoxtla,Huichapan,Huimilpan,Huitzilac,Ixtapallocan,Iztacalco,Iztaccihuatl,Iztapalapa,Lolotla,Malinalco,Mapachtlan,Mazatepec,Mazatlan,Metepec,Metztitlan,Mexico,Miacatlan,Michoacan,Minatitlan,Mixcoac,Mixtla,Molcaxac,Nanacamilpa,Naucalpan,Naupan,Nextlalpan,Nezahualcoyotl,Nopalucan,Oaxaca,Ocotepec,Ocotitlan,Ocotlan,Ocoyoacac,Ocuilan,Ocuituco,Omitlan,Otompan,Otzoloapan,Pacula,Pahuatlan,Panotla,Papalotla,Patlachican,Piaztla,Popocatepetl,Sultepec,Tecamac,Tecolotlan,Tecozautla,Temamatla,Temascalapa,Temixco,Temoac,Temoaya,Tenayuca,Tenochtitlan,Teocuitlatlan,Teotihuacan,Teotlalco,Tepeacac,Tepeapulco,Tepehuacan,Tepetitlan,Tepeyanco,Tepotzotlan,Tepoztlan,Tetecala,Tetlatlahuca,Texcalyacac,Texcoco,Tezontepec,Tezoyuca,Timilpan,Tizapan,Tizayuca,Tlacopan,Tlacotenco,Tlahuac,Tlahuelilpan,Tlahuiltepa,Tlalmanalco,Tlalnepantla,Tlalpan,Tlanchinol,Tlatelolco,Tlaxcala,Tlaxcoapan,Tlayacapan,Tocatlan,Tolcayuca,Toluca,Tonanitla,Tonantzintla,Tonatico,Totolac,Totolapan,Tototlan,Tuchtlan,Tulantepec,Tultepec,Tzompantepec,Xalatlaco,Xaloztoc,Xaltocan,Xiloxoxtla,Xochiatipan,Xochicoatlan,Xochimilco,Xochitepec,Xolotlan,Xonacatlan,Yahualica,Yautepec,Yecapixtla,Yehaultepec,Zacatecas,Zacazonapan,Zacoalco,Zacualpan,Zacualtipan,Zapotlan,Zimapan,Zinacantepec,Zoyaltepec,Zumpahuacan"},{name:"Hungarian",i:15,min:6,max:13,d:"",m:.1,b:"Aba,Abadszalok,Adony,Ajak,Albertirsa,Alsozsolca,Aszod,Babolna,Bacsalmas,Baktaloranthaza,Balassagyarmat,Balatonalmadi,Balatonboglar,Balkany,Balmazujvaros,Barcs,Bataszek,Batonyterenye,Battonya,Bekes,Berettyoujfalu,Berhida,Biatorbagy,Bicske,Biharkeresztes,Bodajk,Boly,Bonyhad,Budakalasz,Budakeszi,Celldomolk,Csakvar,Csenger,Csongrad,Csorna,Csorvas,Csurgo,Dabas,Demecser,Derecske,Devavanya,Devecser,Dombovar,Dombrad,Dunafoldvar,Dunaharaszti,Dunavarsany,Dunavecse,Edeleny,Elek,Emod,Encs,Enying,Ercsi,Fegyvernek,Fehergyarmat,Felsozsolca,Fertoszentmiklos,Fonyod,Fot,Fuzesabony,Fuzesgyarmat,Gardony,God,Gyal,Gyomaendrod,Gyomro,Hajdudorog,Hajduhadhaz,Hajdusamson,Hajduszoboszlo,Halasztelek,Harkany,Hatvan,Heves,Heviz,Ibrany,Isaszeg,Izsak,Janoshalma,Janossomorja,Jaszapati,Jaszarokszallas,Jaszfenyszaru,Jaszkiser,Kaba,Kalocsa,Kapuvar,Karcag,Kecel,Kemecse,Kenderes,Kerekegyhaza,Keszthely,Kisber,Kiskunmajsa,Kistarcsa,Kistelek,Kisujszallas,Kisvarda,Komadi,Komarom,Komlo,Kormend,Korosladany,Koszeg,Kozarmisleny,Kunhegyes,Kunszentmarton,Kunszentmiklos,Labatlan,Lajosmizse,Lenti,Letavertes,Letenye,Lorinci,Maglod,Mako,Mandok,Marcali,Martonvasar,Mateszalka,Melykut,Mezobereny,Mezocsat,Mezohegyes,Mezokeresztes,Mezokovesd,Mezotur,Mindszent,Mohacs,Monor,Mor,Morahalom,Nadudvar,Nagyatad,Nagyecsed,Nagyhalasz,Nagykallo,Nagykoros,Nagymaros,Nyekladhaza,Nyergesujfalu,Nyirbator,Nyirmada,Nyirtelek,Ocsa,Orkeny,Oroszlany,Paks,Pannonhalma,Paszto,Pecel,Pecsvarad,Pilisvorosvar,Polgar,Polgardi,Pomaz,Puspokladany,Pusztaszabolcs,Putnok,Racalmas,Rackeve,Rakamaz,Rakoczifalva,Sajoszent,Sandorfalva,Sarbogard,Sarkad,Sarospatak,Sarvar,Satoraljaujhely,Siklos,Simontornya,Soltvadkert,Sumeg,Szabadszallas,Szarvas,Szazhalombatta,Szecseny,Szeghalom,Szentgotthard,Szentlorinc,Szerencs,Szigethalom,Szigetvar,Szikszo,Tab,Tamasi,Tapioszele,Tapolca,Teglas,Tet,Tiszafoldvar,Tiszafured,Tiszakecske,Tiszalok,Tiszaujvaros,Tiszavasvari,Tokaj,Tokol,Tompa,Torokbalint,Torokszentmiklos,Totkomlos,Tura,Turkeve,Ujkigyos,ujszasz,Vamospercs,Varpalota,Vasarosnameny,Vasvar,Vecses,Veresegyhaz,Verpelet,Veszto,Zahony,Zalaszentgrot,Zirc,Zsambek"},{name:"Turkish",i:16,min:4,max:10,d:"",m:0,b:"Yelkaya,Buyrukkaya,Erdemtepe,Alakesen,Baharbeyli,Bozbay,Karaoklu,Altunbey,Yalkale,Yalkut,Akardere,Altayburnu,Esentepe,Okbelen,Derinsu,Alaoba,Yamanbeyli,Aykor,Ekinova,Saztepe,Baharkale,Devrekdibi,Alpseki,Ormanseki,Erkale,Yalbelen,Aytay,Yamanyaka,Altaydelen,Esen,Yedieli,Alpkor,Demirkor,Yediyol,Erdemkaya,Yayburnu,Ganiler,Bayatyurt,Kopuzteke,Aytepe,Deniz,Ayan,Ayazdere,Tepe,Kayra,Ayyaka,Deren,Adatepe,Kalkaneli,Bozkale,Yedidelen,Kocayolu,Sazdere,Bozkesen,Oguzeli,Yayladibi,Uluyol,Altay,Ayvar,Alazyaka,Yaloba,Suyaka,Baltaberi,Poyrazdelen,Eymir,Yediyuva,Kurt,Yeltepe,Oktar,Kara Ok,Ekinberi,Er Yurdu,Eren,Erenler,Ser,Oguz,Asay,Bozokeli,Aykut,Ormanyol,Yazkaya,Kalkanova,Yazbeyli,Dokuz Teke,Bilge,Ertensuyu,Kopuzyuva,Buyrukkut,Akardiken,Aybaray,Aslanbeyli,Altun Kaynak,Atikobasi,Yayla Eli,Kor Tepe,Salureli,Kor Kaya,Aybarberi,Kemerev,Yanaray,Beydileli,Buyrukoba,Yolduman,Tengri Tepe,Dokuzsu,Uzunkor,Erdem Yurdu,Kemer,Korteke,Bozokev,Bozoba,Ormankale,Askale,Oguztoprak,Yolberi,Kumseki,Esenobasi,Turkbelen,Ayazseki,Cereneli,Taykut,Bayramdelen,Beydilyaka,Boztepe,Uluoba,Yelyaka,Ulgardiken,Esensu,Baykale,Cerenkor,Bozyol,Duranoba,Aladuman,Denizli,Bahar,Yarkesen,Dokuzer,Yamankaya,Kocatarla,Alayaka,Toprakeli,Sarptarla,Sarpkoy,Serkaynak,Adayaka,Ayazkaynak,Kopuz,Turk,Kart,Kum,Erten,Buyruk,Yel,Ada,Alazova,Ayvarduman,Buyrukok,Ayvartoprak,Uzuntepe,Binseki,Yedibey,Durankale,Alaztoprak,Sarp Ok,Yaparobasi,Yaytepe,Asberi,Kalkankor,Beydiltepe,Adaberi,Bilgeyolu,Ganiyurt,Alkanteke,Esenerler,Asbey,Erdemkale,Erenkaynak,Oguzkoyu,Ayazoba,Boynuztoprak,Okova,Yaloklu,Sivriberi,Yuladiken,Sazbey,Karakaynak,Kopuzkoyu,Buyrukay,Kocakaya,Tepeduman,Yanarseki,Atikyurt,Esenev,Akarbeyli,Yayteke,Devreksungur,Akseki,Baykut,Kalkandere,Ulgarova,Devrekev,Yulabey,Bayatev,Yazsu,Vuraleli,Sivribeyli,Alaova,Alpobasi,Yalyurt,Elmatoprak,Alazkaynak,Esenay,Ertenev,Salurkor,Ekinok,Yalbey,Yeldere,Ganibay,Altaykut,Baltaboy,Ereli,Ayvarsu,Uzunsaz,Bayeli,Erenyol,Kocabay,Derintay,Ayazyol,Aslanoba,Esenkaynak,Ekinlik,Alpyolu,Alayunt,Bozeski,Erkil,Duransuyu,Yulak,Kut,Dodurga,Kutlubey,Kutluyurt,Boynuz,Alayol,Aybar,Aslaneli,Kemerseki,Baltasuyu,Akarer,Ayvarburnu,Boynuzbeyli,Adasungur,Esenkor,Yamanoba,Toprakkor,Uzunyurt,Sungur,Bozok,Kemerli,Alaz,Demirci,Kartepe"},{name:"Berber",i:17,min:4,max:10,d:"s",m:.2,b:"Abkhouch,Adrar,Aeraysh,Afrag,Agadir,Agelmam,Aghmat,Agrakal,Agulmam,Ahaggar,Ait Baha,Ajdir,Akka,Almou,Amegdul,Amizmiz,Amknas,Amlil,Amurakush,Anfa,Annaba,Aousja,Arbat,Arfud,Argoub,Arif,Asfi,Asfru,Ashawen,Assamer,Assif,Awlluz,Ayt Melel,Azaghar,Azila,Azilal,Azmour,Azro,Azrou,Beccar,Beja,Bennour,Benslimane,Berkane,Berrechid,Bizerte,Bjaed,Bouayach,Boudenib,Boufrah,Bouskoura,Boutferda,Darallouch,Dar Bouazza,Darchaabane,Dcheira,Demnat,Denden,Djebel,Djedeida,Drargua,Elhusima,Essaouira,Ezzahra,Fas,Fnideq,Ghezeze,Goubellat,Grisaffen,Guelmim,Guercif,Hammamet,Harrouda,Hdifa,Hoceima,Houara,Idhan,Idurar,Ifendassen,Ifoghas,Ifrane,Ighoud,Ikbir,Imilchil,Imzuren,Inezgane,Irherm,Izoughar,Jendouba,Kacem,Kelibia,Kenitra,Kerrando,Khalidia,Khemisset,Khenifra,Khouribga,Khourigba,Kidal,Korba,Korbous,Lahraouyine,Larache,Leyun,Lqliaa,Manouba,Martil,Mazagan,Mcherga,Mdiq,Megrine,Mellal,Melloul,Midelt,Misur,Mohammedia,Mornag,Mrirt,Nabeul,Nadhour,Nador,Nawaksut,Nefza,Ouarzazate,Ouazzane,Oued Zem,Oujda,Ouladteima,Qsentina,Rades,Rafraf,Safi,Sefrou,Sejnane,Settat,Sijilmassa,Skhirat,Slimane,Somaa,Sraghna,Susa,Tabarka,Tadrart,Taferka,Tafilalt,Tafrawt,Tafza,Tagbalut,Tagerdayt,Taghzut,Takelsa,Taliouine,Tanja,Tantan,Taourirt,Targuist,Taroudant,Tarudant,Tasfelalayt,Tassort,Tata,Tattiwin,Tawnat,Taza,Tazagurt,Tazerka,Tazizawt,Taznakht,Tebourba,Teboursouk,Temara,Testour,Tetouan,Tibeskert,Tifelt,Tijdit,Tinariwen,Tinduf,Tinja,Tittawan,Tiznit,Toubkal,Trables,Tubqal,Tunes,Ultasila,Urup,Wagguten,Wararni,Warzazat,Watlas,Wehran,Wejda,Xamida,Yedder,Youssoufia,Zaghouan,Zahret,Zemmour,Zriba"},{name:"Arabic",i:18,min:4,max:9,d:"ae",m:.2,b:"Abha,Ajman,Alabar,Alarjam,Alashraf,Alawali,Albawadi,Albirk,Aldhabiyah,Alduwaid,Alfareeq,Algayed,Alhazim,Alhrateem,Alhudaydah,Alhuwaya,Aljahra,Aljubail,Alkhafah,Alkhalas,Alkhawaneej,Alkhen,Alkhobar,Alkhuznah,Allisafah,Almshaykh,Almurjan,Almuwayh,Almuzaylif,Alnaheem,Alnashifah,Alqah,Alqouz,Alqurayyat,Alradha,Alraqmiah,Alsadyah,Alsafa,Alshagab,Alshuqaiq,Alsilaa,Althafeer,Alwasqah,Amaq,Amran,Annaseem,Aqbiyah,Arafat,Arar,Ardah,Asfan,Ashayrah,Askar,Ayaar,Aziziyah,Baesh,Bahrah,Balhaf,Banizayd,Bidiyah,Bisha,Biyatah,Buqhayq,Burayda,Dafiyat,Damad,Dammam,Dariyah,Dhafar,Dhahran,Dhalkut,Dhurma,Dibab,Doha,Dukhan,Duwaibah,Enaker,Fadhla,Fahaheel,Fanateer,Farasan,Fardah,Fujairah,Ghalilah,Ghar,Ghizlan,Ghomgyah,Ghran,Hadiyah,Haffah,Hajanbah,Hajrah,Haqqaq,Haradh,Hasar,Hawiyah,Hebaa,Hefar,Hijal,Husnah,Huwailat,Huwaitah,Irqah,Isharah,Ithrah,Jamalah,Jarab,Jareef,Jazan,Jeddah,Jiblah,Jihanah,Jilah,Jizan,Joraibah,Juban,Jumeirah,Kamaran,Keyad,Khab,Khaiybar,Khasab,Khathirah,Khawarah,Khulais,Kumzar,Limah,Linah,Madrak,Mahab,Mahalah,Makhtar,Mashwar,Masirah,Masliyah,Mastabah,Mazhar,Medina,Meeqat,Mirbah,Mokhtara,Muharraq,Muladdah,Musaykah,Mushayrif,Musrah,Mussafah,Nafhan,Najran,Nakhab,Nizwa,Oman,Qadah,Qalhat,Qamrah,Qasam,Qosmah,Qurain,Quriyat,Qurwa,Radaa,Rafha,Rahlah,Rakamah,Rasheedah,Rasmadrakah,Risabah,Rustaq,Ryadh,Sabtaljarah,Sadah,Safinah,Saham,Saihat,Salalah,Salmiya,Shabwah,Shalim,Shaqra,Sharjah,Sharurah,Shatifiyah,Shidah,Shihar,Shoqra,Shuwaq,Sibah,Sihmah,Sinaw,Sirwah,Sohar,Suhailah,Sulaibiya,Sunbah,Tabuk,Taif,Taqah,Tarif,Tharban,Thuqbah,Thuwal,Tubarjal,Turaif,Turbah,Tuwaiq,Ubar,Umaljerem,Urayarah,Urwah,Wabrah,Warbah,Yabreen,Yadamah,Yafur,Yarim,Yemen,Yiyallah,Zabid,Zahwah,Zallaq,Zinjibar,Zulumah"},{name:"Inuit",i:19,min:5,max:15,d:"alutsn",m:0,b:"Aaluik,Aappilattoq,Aasiaat,Agissat,Agssaussat,Akuliarutsip,Akunnaaq,Alluitsup,Alluttoq,Amitsorsuaq,Ammassalik,Anarusuk,Anguniartarfik,Annertussoq,Annikitsoq,Apparsuit,Apusiaajik,Arsivik,Arsuk,Atammik,Ateqanaq,Atilissuaq,Attu,Augpalugtoq,Aukarnersuaq,Aumat,Auvilkikavsaup,Avadtlek,Avallersuaq,Bjornesk,Blabaerdalen,Blomsterdalen,Brattalhid,Bredebrae,Brededal,Claushavn,Edderfulegoer,Egger,Eqalugalinnguit,Eqalugarssuit,Eqaluit,Eqqua,Etah,Graah,Hakluyt,Haredalen,Hareoen,Hundeo,Igaliku,Igdlorssuit,Igdluluarssuk,Iginniafik,Ikamiut,Ikarissat,Ikateq,Ikermiut,Ikermoissuaq,Ikorfarssuit,Ilimanaq,Illorsuit,Illunnguit,Iluileq,Ilulissat,Imaarsivik,Imartunarssuk,Immikkoortukajik,Innaarsuit,Inneruulalik,Inussullissuaq,Iperaq,Ippik,Iqek,Isortok,Isungartussoq,Itileq,Itissaalik,Itivdleq,Ittit,Ittoqqortoormiit,Ivingmiut,Ivittuut,Kanajoorartuut,Kangaamiut,Kangeq,Kangerluk,Kangerlussuaq,Kanglinnguit,Kapisillit,Kekertamiut,Kiatak,Kiataussaq,Kigatak,Kinaussak,Kingittorsuaq,Kitak,Kitsissuarsuit,Kitsissut,Klenczner,Kook,Kraulshavn,Kujalleq,Kullorsuaq,Kulusuk,Kuurmiit,Kuusuaq,Laksedalen,Maniitsoq,Marrakajik,Mattaangassut,Mernoq,Mittivakkat,Moriusaq,Myggbukta,Naajaat,Nangissat,Nanuuseq,Nappassoq,Narsarmijt,Narsarsuaq,Narssaq,Nasiffik,Natsiarsiorfik,Naujanguit,Niaqornaarsuk,Niaqornat,Nordfjordspasset,Nugatsiaq,Nunarssit,Nunarsuaq,Nunataaq,Nunatakavsaup,Nutaarmiut,Nuugaatsiaq,Nuuk,Nuukullak,Olonkinbyen,Oodaaq,Oqaatsut,Oqaitsunguit,Oqonermiut,Paagussat,Paamiut,Paatuut,Palungataq,Pamialluk,Perserajoq,Pituffik,Puugutaa,Puulkuip,Qaanaq,Qaasuitsup,Qaersut,Qajartalik,Qallunaat,Qaneq,Qaqortok,Qasigiannguit,Qassimiut,Qeertartivaq,Qeqertaq,Qeqertasussuk,Qeqqata,Qernertoq,Qernertunnguit,Qianarreq,Qingagssat,Qoornuup,Qorlortorsuaq,Qullikorsuit,Qunnerit,Qutdleq,Ravnedalen,Ritenbenk,Rypedalen,Saarloq,Saatorsuaq,Saattut,Salliaruseq,Sammeqqat,Sammisoq,Sanningassoq,Saqqaq,Saqqarlersuaq,Saqqarliit,Sarfannguit,Sattiaatteq,Savissivik,Serfanguaq,Sermersooq,Sermiligaaq,Sermilik,Sermitsiaq,Simitakaja,Simiutaq,Singamaq,Siorapaluk,Sisimiut,Sisuarsuit,Sullorsuaq,Suunikajik,Sverdrup,Taartoq,Takiseeq,Tasirliaq,Tasiusak,Tiilerilaaq,Timilersua,Timmiarmiut,Tukingassoq,Tussaaq,Tuttulissuup,Tuujuk,Uiivaq,Uilortussoq,Ujuaakajiip,Ukkusissat,Upernavik,Uttorsiutit,Uumannaq,Uunartoq,Uvkusigssat,Ymer"},{name:"Basque",i:20,min:4,max:11,d:"r",m:.1,b:"Agurain,Aia,Aiara,Albiztur,Alkiza,Altzaga,Amorebieta,Amurrio,Andoain,Anoeta,Antzuola,Arakaldo,Arantzazu,Arbatzegi,Areatza,Arratzua,Arrieta,Artea,Artziniega,Asteasu,Astigarraga,Ataun,Atxondo,Aulesti,Azkoitia,Azpeitia,Bakio,Baliarrain,Barakaldo,Barrika,Barrundia,Basauri,Beasain,Bedia,Beizama,Belauntza,Berastegi,Bergara,Bermeo,Bernedo,Berriatua,Berriz,Bidania,Bilar,Bilbao,Busturia,Deba,Derio,Donostia,Dulantzi,Durango,Ea,Eibar,Elantxobe,Elduain,Elgeta,Elgoibar,Elorrio,Erandio,Ergoitia,Ermua,Errenteria,Errezil,Eskoriatza,Eskuernaga,Etxebarri,Etxebarria,Ezkio,Forua,Gabiria,Gaintza,Galdakao,Gamiz,Garai,Gasteiz,Gatzaga,Gaubea,Gautegiz,Gaztelu,Gernika,Gerrikaitz,Getaria,Getxo,Gizaburuaga,Goiatz,Gorliz,Gorriaga,Harana,Hernani,Hondarribia,Ibarra,Ibarrangelu,Idiazabal,Iekora,Igorre,Ikaztegieta,Irun,Irura,Iruraiz,Itsaso,Itsasondo,Iurreta,Izurtza,Jatabe,Kanpezu,Karrantza,Kortezubi,Kripan,Kuartango,Lanestosa,Lantziego,Larrabetzu,Lasarte,Laukiz,Lazkao,Leaburu,Legazpi,Legorreta,Legutio,Leintz,Leioa,Lekeitio,Lemoa,Lemoiz,Leza,Lezama,Lezo,Lizartza,Maeztu,Mallabia,Manaria,Markina,Maruri,Menaka,Mendaro,Mendata,Mendexa,Morga,Mundaka,Mungia,Munitibar,Murueta,Muskiz,Mutiloa,Mutriku,Nabarniz,Oiartzun,Oion,Okondo,Olaberria,Onati,Ondarroa,Ordizia,Orendain,Orexa,Oria,Orio,Ormaiztegi,Orozko,Ortuella,Otegi,Otxandio,Pasaia,Plentzia,Santurtzi,Sestao,Sondika,Soraluze,Sukarrieta,Tolosa,Trapagaran,Turtzioz,Ubarrundia,Ubide,Ugao,Urdua,Urduliz,Urizaharra,Urkabustaiz,Urnieta,Urretxu,Usurbil,Xemein,Zabaleta,Zaia,Zaldibar,Zambrana,Zamudio,Zaratamo,Zarautz,Zeberio,Zegama,Zerain,Zestoa,Zierbena,Zigoitia,Ziortza,Zuia,Zumaia,Zumarraga"},{name:"Nigerian",i:21,min:4,max:10,d:"",m:.3,b:"Abadogo,Abafon,Adealesu,Adeto,Adyongo,Afaga,Afamju,Agigbigi,Agogoke,Ahute,Aiyelaboro,Ajebe,Ajola,Akarekwu,Akunuba,Alawode,Alkaijji,Amangam,Amgbaye,Amtasa,Amunigun,Animahun,Anyoko,Arapagi,Asande,Awgbagba,Awhum,Awodu,Babateduwa,Bandakwai,Bangdi,Bilikani,Birnindodo,Braidu,Bulakawa,Buriburi,Cainnan,Chakum,Chondugh,Dagwarga,Darpi,Dokatofa,Dozere,Ebelibri,Efem,Ekoku,Ekpe,Ewhoeviri,Galea,Gamen,Ganjin,Gantetudu,Gargar,Garinbode,Gbure,Gerti,Gidan,Gitabaremu,Giyagiri,Giyawa,Gmawa,Golakochi,Golumba,Gunji,Gwambula,Gwodoti,Hayinlere,Hayinmaialewa,Hirishi,Hombo,Ibefum,Iberekodo,Icharge,Idofin,Idofinoka,Igbogo,Ijoko,Ijuwa,Ikawga,Ikhin,Ikpakidout,Ikpeoniong,Imuogo,Ipawo,Ipinlerere,Isicha,Itakpa,Jangi,Jare,Jataudakum,Jaurogomki,Jepel,Kafinmalama,Katab,Katanga,Katinda,Katirije,Kaurakimba,Keffinshanu,Kellumiri,Kiagbodor,Kirbutu,Kita,Kogogo,Kopje,Korokorosei,Kotoku,Kuata,Kujum,Kukau,Kunboon,Kuonubogbene,Kurawe,Kushinahu,Kwaramakeri,Ladimeji,Lafiaro,Lahaga,Laindebajanle,Laindegoro,Lakati,Litenswa,Maba,Madarzai,Maianita,Malikansaa,Mata,Megoyo,Meku,Miama,Modi,Mshi,Msugh,Muduvu,Murnachehu,Namnai,Ndamanma,Ndiwulunbe,Ndonutim,Ngbande,Nguengu,Ntoekpe,Nyajo,Nyior,Odajie,Ogbaga,Ogultu,Ogunbunmi,Ojopode,Okehin,Olugunna,Omotunde,Onipede,Onma,Orhere,Orya,Otukwang,Otunade,Rampa,Rimi,Rugan,Rumbukawa,Sabiu,Sangabama,Sarabe,Seboregetore,Shafar,Shagwa,Shata,Shengu,Sokoron,Sunnayu,Tafoki,Takula,Talontan,Tarhemba,Tayu,Ter,Timtim,Timyam,Tindirke,Tokunbo,Torlwam,Tseakaadza,Tseanongo,Tsebeeve,Tsepaegh,Tuba,Tumbo,Tungalombo,Tunganyakwe,Uhkirhi,Umoru,Umuabai,Umuajuju,Unchida,Ungua,Unguwar,Unongo,Usha,Utongbo,Vembera,Wuro,Yanbashi,Yanmedi,Yoku,Zarunkwari,Zilumo,Zulika"},{name:"Celtic",i:22,min:4,max:12,d:"nld",m:0,b:"Aberaman,Aberangell,Aberarth,Aberavon,Aberbanc,Aberbargoed,Aberbeeg,Abercanaid,Abercarn,Abercastle,Abercegir,Abercraf,Abercregan,Abercych,Abercynon,Aberdare,Aberdaron,Aberdaugleddau,Aberdeen,Aberdulais,Aberdyfi,Aberedw,Abereiddy,Abererch,Abereron,Aberfan,Aberffraw,Aberffrwd,Abergavenny,Abergele,Aberglasslyn,Abergorlech,Abergwaun,Abergwesyn,Abergwili,Abergwynfi,Abergwyngregyn,Abergynolwyn,Aberhafesp,Aberhonddu,Aberkenfig,Aberllefenni,Abermain,Abermaw,Abermorddu,Abermule,Abernant,Aberpennar,Aberporth,Aberriw,Abersoch,Abersychan,Abertawe,Aberteifi,Aberthin,Abertillery,Abertridwr,Aberystwyth,Achininver,Afonhafren,Alisaha,Anfosadh,Antinbhearmor,Ardenna,Attacon,Banwen,Beira,Bhrura,Bleddfa,Boioduro,Bona,Boskyny,Boslowenpolbrogh,Boudobriga,Bravon,Brigant,Briganta,Briva,Brosnach,Caersws,Cambodunum,Cambra,Caracta,Catumagos,Centobriga,Ceredigion,Chalain,Chearbhallain,Chlasaigh,Chormaic,Cuileannach,Dinn,Diwa,Dubingen,Duibhidighe,Duro,Ebora,Ebruac,Eburodunum,Eccles,Egloskuri,Eighe,Eireann,Elerghi,Ferkunos,Fhlaithnin,Gallbhuaile,Genua,Ghrainnse,Gwyles,Heartsease,Hebron,Hordh,Inbhear,Inbhir,Inbhirair,Innerleithen,Innerleven,Innerwick,Inver,Inveraldie,Inverallan,Inveralmond,Inveramsay,Inveran,Inveraray,Inverarnan,Inverbervie,Inverclyde,Inverell,Inveresk,Inverfarigaig,Invergarry,Invergordon,Invergowrie,Inverhaddon,Inverkeilor,Inverkeithing,Inverkeithney,Inverkip,Inverleigh,Inverleith,Inverloch,Inverlochlarig,Inverlochy,Invermay,Invermoriston,Inverness,Inveroran,Invershin,Inversnaid,Invertrossachs,Inverugie,Inveruglas,Inverurie,Iubhrach,Karardhek,Kilninver,Kirkcaldy,Kirkintilloch,Krake,Lanngorrow,Latense,Leming,Lindomagos,Llanaber,Llandidiwg,Llandyrnog,Llanfarthyn,Llangadwaldr,Llansanwyr,Lochinver,Lugduno,Magoduro,Mheara,Monmouthshire,Nanshiryarth,Narann,Novioduno,Nowijonago,Octoduron,Penning,Pheofharain,Ponsmeur,Raithin,Ricomago,Rossinver,Salodurum,Seguia,Sentica,Theorsa,Tobargeal,Trealaw,Trefesgob,Trewedhenek,Trewythelan,Tuaisceart,Uige,Vitodurum,Windobona"},{name:"Mesopotamian",i:23,min:4,max:9,d:"srpl",m:.1,b:"Adab,Adamndun,Adma,Admatum,Agrab,Akkad,Akshak,Amnanum,Andarig,Anshan,Apiru,Apum,Arantu,Arbid,Arpachiyah,Arpad,Arrapha,Ashlakka,Assur,Awan,Babilim,Bad-Tibira,Balawat,Barsip,Birtu,Bit-Bunakki,Borsippa,Chuera,Dashrah,Der,Dilbat,Diniktum,Doura,Dur-Kurigalzu,Dur-Sharrukin,Dur-Untash,Dûr-gurgurri,Ebla,Ekallatum,Ekalte,Emar,Erbil,Eresh,Eridu,Eshnunn,Eshnunna,Gargamish,Gasur,Gawra,Gibil,Girsu,Gizza,Habirun,Habur,Hadatu,Hakkulan,Halab,Halabit,Hamazi,Hamoukar,Haradum,Harbidum,Harran,Harranu,Hassuna,Hatarikka,Hatra,Hissar,Hiyawa,Hormirzad,Ida-Maras,Idamaraz,Idu,Imerishu,Imgur-Enlil,Irisagrig,Irnina,Irridu,Isin,Issinnitum,Iturungal,Izubitum,Jarmo,Jemdet,Kabnak,Kadesh,Kahat,Kalhu,Kar-Shulmanu-Asharedu,Kar-Tukulti-Ninurta,Kar-shulmanu-asharedu,Karana,Karatepe,Kartukulti,Kazallu,Kesh,Kidsha,Kinza,Kish,Kisiga,Kisurra,Kuara,Kurda,Kurruhanni,Kutha,Lagaba,Lagash,Larak,Larsa,Leilan,Malgium,Marad,Mardaman,Mari,Marlik,Mashkan,Mashkan-shapir,Matutem,Me-Turan,Meliddu,Mumbaqat,Nabada,Nagar,Nanagugal,Nerebtum,Nigin,Nimrud,Nina,Nineveh,Ninua,Nippur,Niru,Niya,Nuhashe,Nuhasse,Nuzi,Puzrish-Dagan,Qalatjarmo,Qatara,Qatna,Qattunan,Qidshu,Rapiqum,Rawda,Sagaz,Shaduppum,Shaggaratum,Shalbatu,Shanidar,Sharrukin,Shawwan,Shehna,Shekhna,Shemshara,Shibaniba,Shubat-Enlil,Shurkutir,Shuruppak,Shusharra,Shushin,Sikan,Sippar,Sippar-Amnanum,Sippar-sha-Annunitum,Subatum,Susuka,Tadmor,Tarbisu,Telul,Terqa,Tirazish,Tisbon,Tuba,Tushhan,Tuttul,Tutub,Ubaid,Umma,Ur,Urah,Urbilum,Urkesh,Ursa'um,Uruk,Urum,Uzarlulu,Warka,Washukanni,Zabalam,Zarri-Amnan"},{name:"Iranian",i:24,min:5,max:11,d:"",m:.1,b:"Abali,Abrisham,Absard,Abuzeydabad,Afus,Alavicheh,Alikosh,Amol,Anarak,Anbar,Andisheh,Anshan,Aran,Ardabil,Arderica,Ardestan,Arjomand,Asgaran,Asgharabad,Ashian,Awan,Babajan,Badrud,Bafran,Baghestan,Baghshad,Bahadoran,Baharan Shahr,Baharestan,Bakun,Bam,Baqershahr,Barzok,Bastam,Behistun,Bitistar,Bumahen,Bushehr,Chadegan,Chahardangeh,Chamgardan,Chermahin,Choghabonut,Chugan,Damaneh,Damavand,Darabgard,Daran,Dastgerd,Dehaq,Dehaqan,Dezful,Dizicheh,Dorcheh,Dowlatabad,Duruntash,Ecbatana,Eslamshahr,Estakhr,Ezhiyeh,Falavarjan,Farrokhi,Fasham,Ferdowsieh,Fereydunshahr,Ferunabad,Firuzkuh,Fuladshahr,Ganjdareh,Ganzak,Gaz,Geoy,Godin,Goldasht,Golestan,Golpayegan,Golshahr,Golshan,Gorgab,Guged,Habibabad,Hafshejan,Hajjifiruz,Hana,Harand,Hasanabad,Hasanlu,Hashtgerd,Hecatompylos,Hormirzad,Imanshahr,Isfahan,Jandaq,Javadabad,Jiroft,Jowsheqan ,Jowzdan,Kabnak,Kahrizak,Kahriz Sang,Kangavar,Karaj,Karkevand,Kashan,Kelishad,Kermanshah,Khaledabad,Khansar,Khorramabad,Khur,Khvorzuq,Kilan,Komeh,Komeshcheh,Konar,Kuhpayeh,Kul,Kushk,Lavasan,Laybid,Liyan,Lyan,Mahabad,Mahallat,Majlesi,Malard,Manzariyeh,Marlik,Meshkat,Meymeh,Miandasht,Mish,Mobarakeh,Nahavand,Nain,Najafabad,Naqshe,Narezzash,Nasimshahr,Nasirshahr,Nasrabad,Natanz,Neyasar,Nikabad,Nimvar,Nushabad,Pakdasht,Parand,Pardis,Parsa,Pasargadai,Patigrabana,Pir Bakran,Pishva,Qahderijan,Qahjaverestan,Qamsar,Qarchak,Qods,Rabat,Ray-shahr,Rezvanshahr,Rhages,Robat Karim,Rozveh,Rudehen,Sabashahr,Safadasht,Sagzi,Salehieh,Sandal,Sarvestan,Sedeh,Sefidshahr,Semirom,Semnan,Shadpurabad,Shah,Shahdad,Shahedshahr,Shahin,Shahpour,Shahr,Shahreza,Shahriar,Sharifabad,Shemshak,Shiraz,Shushan,Shushtar,Sialk,Sin,Sukhteh,Tabas,Tabriz,Takhte,Talkhuncheh,Talli,Tarq,Temukan,Tepe,Tiran,Tudeshk,Tureng,Urmia,Vahidieh,Vahrkana,Vanak,Varamin,Varnamkhast,Varzaneh,Vazvan,Yahya,Yarim,Yasuj,Zarrin Shahr,Zavareh,Zayandeh,Zazeran,Ziar,Zibashahr,Zranka"},{name:"Hawaiian",i:25,min:5,max:10,d:"auo",m:1,b:"Aapueo,Ahoa,Ahuakaio,Ahupau,Alaakua,Alae,Alaeloa,Alamihi,Aleamai,Alena,Alio,Aupokopoko,Halakaa,Haleu,Haliimaile,Hamoa,Hanakaoo,Hanaulu,Hanawana,Hanehoi,Haou,Hikiaupea,Hokuula,Honohina,Honokahua,Honokeana,Honokohau,Honolulu,Honomaele,Hononana,Honopou,Hoolawa,Huelo,Kaalaea,Kaapahu,Kaeo,Kahalehili,Kahana,Kahuai,Kailua,Kainehe,Kakalahale,Kakanoni,Kalenanui,Kaleoaihe,Kalialinui,Kalihi,Kalimaohe,Kaloi,Kamani,Kamehame,Kanahena,Kaniaula,Kaonoulu,Kapaloa,Kapohue,Kapuaikini,Kapunakea,Kauau,Kaulalo,Kaulanamoa,Kauluohana,Kaumakani,Kaumanu,Kaunauhane,Kaupakulua,Kawaloa,Keaa,Keaaula,Keahua,Keahuapono,Kealahou,Keanae,Keauhou,Kelawea,Keokea,Keopuka,Kikoo,Kipapa,Koakupuna,Koali,Kolokolo,Kopili,Kou,Kualapa,Kuhiwa,Kuholilea,Kuhua,Kuia,Kuikui,Kukoae,Kukohia,Kukuiaeo,Kukuipuka,Kukuiula,Kulahuhu,Lapakea,Lapueo,Launiupoko,Lole,Maalo,Mahinahina,Mailepai,Makaakini,Makaalae,Makaehu,Makaiwa,Makaliua,Makapipi,Makapuu,Maluaka,Manawainui,Mehamenui,Moalii,Moanui,Mohopili,Mokae,Mokuia,Mokupapa,Mooiki,Mooloa,Moomuku,Muolea,Nakaaha,Nakalepo,Nakaohu,Nakapehu,Nakula,Napili,Niniau,Nuu,Oloewa,Olowalu,Omaopio,Onau,Onouli,Opaeula,Opana,Opikoula,Paakea,Paeahu,Paehala,Paeohi,Pahoa,Paia,Pakakia,Palauea,Palemo,Paniau,Papaaea,Papaanui,Papaauhau,Papaka,Papauluana,Pauku,Paunau,Pauwalu,Pauwela,Pohakanele,Polaiki,Polanui,Polapola,Poopoo,Poponui,Poupouwela,Puahoowali,Puakea,Puako,Pualaea,Puehuehu,Pueokauiki,Pukaauhuhu,Pukuilua,Pulehu,Puolua,Puou,Puuhaehae,Puuiki,Puuki,Puulani,Puunau,Puuomaile,Uaoa,Uhao,Ukumehame,Ulaino,Ulumalu,Wahikuli,Waianae,Waianu,Waiawa,Waiehu,Waieli,Waikapu,Wailamoa,Wailaulau,Wainee,Waiohole,Waiohonu,Waiohuli,Waiokama,Waiokila,Waiopai,Waiopua,Waipao,Waipionui,Waipouli"},{name:"Karnataka",i:26,min:5,max:11,d:"tnl",m:0,b:"Adityapatna,Adyar,Afzalpur,Aland,Alnavar,Alur,Ambikanagara,Anekal,Ankola,Annigeri,Arkalgud,Arsikere,Athni,Aurad,Badami,Bagalkot,Bagepalli,Bail,Bajpe,Bangalore,Bangarapet,Bankapura,Bannur,Bantval,Basavakalyan,Basavana,Belgaum,Beltangadi,Belur,Bhadravati,Bhalki,Bhatkal,Bhimarayanagudi,Bidar,Bijapur,Bilgi,Birur,Bommasandra,Byadgi,Challakere,Chamarajanagar,Channagiri,Channapatna,Channarayapatna,Chik,Chikmagalur,Chiknayakanhalli,Chikodi,Chincholi,Chintamani,Chitapur,Chitgoppa,Chitradurga,Dandeli,Dargajogihalli,Devadurga,Devanahalli,Dod,Donimalai,Gadag,Gajendragarh,Gangawati,Gauribidanur,Gokak,Gonikoppal,Gubbi,Gudibanda,Gulbarga,Guledgudda,Gundlupet,Gurmatkal,Haliyal,Hangal,Harapanahalli,Harihar,Hassan,Hatti,Haveri,Hebbagodi,Heggadadevankote,Hirekerur,Holalkere,Hole,Homnabad,Honavar,Honnali,Hoovina,Hosakote,Hosanagara,Hosdurga,Hospet,Hubli,Hukeri,Hungund,Hunsur,Ilkal,Indi,Jagalur,Jamkhandi,Jevargi,Jog,Kadigenahalli,Kadur,Kalghatgi,Kamalapuram,Kampli,Kanakapura,Karkal,Karwar,Khanapur,Kodiyal,Kolar,Kollegal,Konnur,Koppa,Koppal,Koratagere,Kotturu,Krishnarajanagara,Krishnarajasagara,Krishnarajpet,Kudchi,Kudligi,Kudremukh,Kumta,Kundapura,Kundgol,Kunigal,Kurgunta,Kushalnagar,Kushtagi,Lakshmeshwar,Lingsugur,Londa,Maddur,Madhugiri,Madikeri,Mahalingpur,Malavalli,Mallar,Malur,Mandya,Mangalore,Manvi,Molakalmuru,Mudalgi,Mudbidri,Muddebihal,Mudgal,Mudhol,Mudigere,Mulbagal,Mulgund,Mulki,Mulur,Mundargi,Mundgod,Munirabad,Mysore,Nagamangala,Nanjangud,Narasimharajapura,Naregal,Nargund,Navalgund,Nipani,Pandavapura,Pavagada,Piriyapatna,Pudu,Puttur,Rabkavi,Raichur,Ramanagaram,Ramdurg,Ranibennur,Raybag,Robertson,Ron,Sadalgi,Sagar,Sakleshpur,Saligram,Sandur,Sankeshwar,Saundatti,Savanur,Sedam,Shahabad,Shahpur,Shaktinagar,Shiggaon,Shikarpur,Shirhatti,Shorapur,Shrirangapattana,Siddapur,Sidlaghatta,Sindgi,Sindhnur,Sira,Siralkoppa,Sirsi,Siruguppa,Somvarpet,Sorab,Sringeri,Srinivaspur,Sulya,Talikota,Tarikere,Tekkalakote,Terdal,Thumbe,Tiptur,Tirthahalli,Tirumakudal,Tumkur,Turuvekere,Udupi,Vijayapura,Wadi,Yadgir,Yelandur,Yelbarga,Yellapur,Yenagudde"},{name:"Quechua",i:27,min:6,max:12,d:"l",m:0,b:"Alpahuaycco,Anchihuay,Anqea,Apurimac,Arequipa,Atahuallpa,Atawalpa,Atico,Ayacucho,Ayahuanco,Ayllu,Cajamarca,Canayre,Canchacancha,Carapo,Carhuac,Carhuacatac,Cashan,Caullaraju,Caxamalca,Cayesh,Ccahuasno,Ccarhuacc,Ccopayoc,Chacchapunta,Chacraraju,Challhuamayo,Champara,Chanchan,Chekiacraju,Chillihua,Chinchey,Chontah,Chopicalqui,Chucuito,Chuito,Chullo,Chumpi,Chuncho,Chupahuacho,Chuquiapo,Chuquisaca,Churup,Cocapata,Cochabamba,Cojup,Collota,Conococha,Corihuayrachina,Cuchoquesera,Cusichaca,Haika,Hanpiq,Hatun,Haywarisqa,Huaca,Huachinga,Hualcan,Hualchancca,Huamanga,Huamashraju,Huancarhuas,Huandoy,Huantsan,Huanupampa,Huarmihuanusca,Huascaran,Huaylas,Huayllabamba,Huayrana,Huaytara,Huichajanca,Huinayhuayna,Huinche,Huinioch,Illiasca,Intipunku,Iquicha,Ishinca,Jahuacocha,Jirishanca,Juli,Jurau,Kakananpunta,Kamasqa,Karpay,Kausay,Khuya,Kuelap,Lanccochayocc,Llaca,Llactapata,Llanganuco,Llaqta,Lloqllasca,Llupachayoc,Luricocha,Machu,Mallku,Matarraju,Mechecc,Mikhuy,Milluacocha,Morochuco,Munay,Ocshapalca,Ollantaytambo,Oroccahua,Oronccoy,Oyolo,Pacamayo,Pacaycasa,Paccharaju,Pachacamac,Pachakamaq,Pachakuteq,Pachakuti,Pachamama,Paititi,Pajaten,Palcaraju,Pallccas,Pampa,Panaka,Paqarina,Paqo,Parap,Paria,Patahuasi,Patallacta,Patibamba,Pisac,Pisco,Pongos,Pucacolpa,Pucahirca,Pucaranra,Pumatambo,Puscanturpa,Putaca,Puyupatamarca,Qawaq,Qayqa,Qochamoqo,Qollana,Qorihuayrachina,Qorimoqo,Qotupuquio,Quenuaracra,Queshque,Quillcayhuanca,Quillya,Quitaracsa,Quitaraju,Qusqu,Rajucolta,Rajutakanan,Rajutuna,Ranrahirca,Ranrapalca,Raria,Rasac,Rimarima,Riobamba,Runkuracay,Rurec,Sacsa,Sacsamarca,Saiwa,Sarapo,Sayacmarca,Sayripata,Sinakara,Sonccopa,Taripaypacha,Taulliraju,Tawantinsuyu,Taytanchis,Tiwanaku,Tocllaraju,Tsacra,Tuco,Tucubamba,Tullparaju,Tumbes,Uchuraccay,Uchuraqay,Ulta,Urihuana,Uruashraju,Vallunaraju,Vilcabamba,Wacho,Wankawillka,Wayra,Yachay,Yahuarraju,Yanamarey,Yanaqucha,Yanesha,Yerupaja"},{name:"Swahili",i:28,min:4,max:9,d:"",m:0,b:"Abim,Adjumani,Alebtong,Amolatar,Amuru,Apac,Arua,Arusha,Babati,Baragoi,Bombo,Budaka,Bugembe,Bugiri,Buikwe,Bukedea,Bukoba,Bukomansimbi,Bukungu,Buliisa,Bundibugyo,Bungoma,Busembatya,Bushenyi,Busia,Busolwe,Butaleja,Butambala,Butere,Buwenge,Buyende,Dadaab,Dodoma,Dokolo,Eldoret,Elegu,Emali,Embu,Entebbe,Garissa,Gede,Gulu,Handeni,Hima,Hoima,Hola,Ibanda,Iganga,Iringa,Isingiro,Isiolo,Jinja,Kaabong,Kabuyanda,Kabwohe,Kagadi,Kajiado,Kakinga,Kakiri,Kakuma,Kalangala,Kaliro,Kalongo,Kalungu,Kampala,Kamwenge,Kanungu,Kapchorwa,Kasese,Kasulu,Katakwi,Kayunga,Keroka,Kiambu,Kibaale,Kibaha,Kibingo,Kibwezi,Kigoma,Kihiihi,Kilifi,Kiruhura,Kiryandongo,Kisii,Kisoro,Kisumu,Kitale,Kitgum,Kitui,Koboko,Korogwe,Kotido,Kumi,Kyazanga,Kyegegwa,Kyenjojo,Kyotera,Lamu,Langata,Lindi,Lodwar,Lokichoggio,Londiani,Loyangalani,Lugazi,Lukaya,Luweero,Lwakhakha,Lwengo,Lyantonde,Machakos,Mafinga,Makambako,Makindu,Malaba,Malindi,Manafwa,Mandera,Marsabit,Masaka,Masindi,Masulita,Matugga,Mayuge,Mbale,Mbarara,Mbeya,Meru,Mitooma,Mityana,Mombasa,Morogoro,Moroto,Moyale,Moyo,Mpanda,Mpigi,Mpondwe,Mtwara,Mubende,Mukono,Muranga,Musoma,Mutomo,Mutukula,Mwanza,Nagongera,Nairobi,Naivasha,Nakapiripirit,Nakaseke,Nakasongola,Nakuru,Namanga,Namayingo,Namutumba,Nansana,Nanyuki,Narok,Naromoru,Nebbi,Ngora,Njeru,Njombe,Nkokonjeru,Ntungamo,Nyahururu,Nyeri,Oyam,Pader,Paidha,Pakwach,Pallisa,Rakai,Ruiru,Rukungiri,Rwimi,Sanga,Sembabule,Shimoni,Shinyanga,Singida,Sironko,Songea,Soroti,Ssabagabo,Sumbawanga,Tabora,Takaungu,Tanga,Thika,Tororo,Tunduma,Vihiga,Voi,Wajir,Wakiso,Watamu,Webuye,Wobulenzi,Wote,Wundanyi,Yumbe,Zanzibar"},{name:"Vietnamese",i:29,min:3,max:12,d:"",m:1,b:"An Giang,Anh Son,An Khe,An Nhon,Ayun Pa,Bac Giang,Bac Kan,Bac Lieu,Bac Ninh,Ba Don,Bao Loc,Ba Ria,Ba Ria-Vung Tau,Ba Thuoc,Ben Cat,Ben Tre,Bien Hoa,Bim Son,Binh Dinh,Binh Duong,Binh Long,Binh Minh,Binh Phuoc,Binh Thuan,Buon Ho,Buon Ma Thuot,Cai Lay,Ca Mau,Cam Khe,Cam Pha,Cam Ranh,Cam Thuy,Can Tho,Cao Bang,Cao Lanh,Cao Phong,Chau Doc,Chi Linh,Con Cuong,Cua Lo,Da Bac,Dak Lak,Da Lat,Da Nang,Di An,Dien Ban,Dien Bien,Dien Bien Phu,Dien Chau,Do Luong,Dong Ha,Dong Hoi,Dong Trieu,Duc Pho,Duyen Hai,Duy Tien,Gia Lai,Gia Nghia,Gia Rai,Go Cong,Ha Giang,Ha Hoa,Hai Duong,Hai Phong,Ha Long,Ha Nam,Ha Noi,Ha Tinh,Ha Trung,Hau Giang,Hoa Binh,Hoang Mai,Hoa Thanh,Ho Chi Minh,Hoi An,Hong Linh,Hong Ngu,Hue,Hung Nguyen,Hung Yen,Huong Thuy,Huong Tra,Khanh Hoa,Kien Tuong,Kim Boi,Kinh Mon,Kon Tum,Ky Anh,Ky Son,Lac Son,Lac Thuy,La Gi,Lai Chau,Lam Thao,Lang Chanh,Lang Son,Lao Cai,Long An,Long Khanh,Long My,Long Xuyen,Luong Son,Mai Chau,Mong Cai,Muong Lat,Muong Lay,My Hao,My Tho,Nam Dan,Nam Dinh,Nga Bay,Nga Nam,Nga Son,Nghe An,Nghia Dan,Nghia Lo,Nghi Loc,Nghi Son,Ngoc Lac,Nha Trang,Nhu Thanh,Nhu Xuan,Ninh Binh,Ninh Hoa,Nong Cong,Phan Rang Thap Cham,Phan Thiet,Pho Yen,Phu Ly,Phu My,Phu Ninh,Phuoc Long,Phu Tho,Phu Yen,Pleiku,Quang Binh,Quang Nam,Quang Ngai,Quang Ninh,Quang Tri,Quang Xuong,Quang Yen,Quan Hoa,Quan Son,Que Phong,Quy Chau,Quy Hop,Quynh Luu,Quy Nhon,Rach Gia,Sa Dec,Sai Gon,Sam Son,Sa Pa,Soc Trang,Song Cau,Song Cong,Son La,Son Tay,Tam Diep,Tam Ky,Tan An,Tan Chau,Tan Ky,Tan Lac,Tan Son,Tan Uyen,Tay Ninh,Thach Thanh,Thai Binh,Thai Hoa,Thai Nguyen,Thanh Chuong,Thanh Hoa,Thieu Hoa,Thuan An,Thua Thien-Hue,Thu Dau Mot,Thu Duc,Thuong Xuan,Tien Giang,Trang Bang,Tra Vinh,Trieu Son,Tu Son,Tuyen Quang,Tuy Hoa,Uong Bi,Viet Tri,Vinh,Vinh Chau,Vinh Loc,Vinh Long,Vinh Yen,Vi Thanh,Vung Tau,Yen Bai,Yen Dinh,Yen Thanh,Yen Thuy"},{name:"Cantonese",i:30,min:5,max:11,d:"",m:0,b:"Chaiwan,Chingchung,Chinghoi,Chingsen,Chingshing,Chiunam,Chiuon,Chiuyeung,Chiyuen,Choihung,Chuehoi,Chuiman,Chungfu,Chungsan,Chunguktsuen,Dakhing,Daopo,Daumun,Dingwu,Dinpak,Donggun,Dongyuen,Duenchau,Fachau,Fanling,Fatgong,Fatshan,Fotan,Fuktien,Fumun,Funggong,Funghoi,Fungshun,Fungtei,Gamtin,Gochau,Goming,Gonghoi,Gongshing,Goyiu,Hanghau,Hangmei,Hengon,Heungchau,Heunggong,Heungkiu,Hingning,Hohfuktong,Hoichue,Hoifung,Hoiping,Hokong,Hokshan,Hoyuen,Hunghom,Hungshuikiu,Jiuling,Kamsheung,Kamwan,Kaulongtong,Keilun,Kinon,Kinsang,Kityeung,Kongmun,Kukgong,Kwaifong,Kwaihing,Kwongchau,Kwongling,Kwongming,Kwuntong,Laichikok,Laiking,Laiwan,Lamtei,Lamtin,Leitung,Leungking,Limkong,Linping,Linshan,Loding,Lokcheong,Lokfu,Longchuen,Longgong,Longmun,Longping,Longwa,Longwu,Lowu,Luichau,Lukfung,Lukho,Lungmun,Macheung,Maliushui,Maonshan,Mauming,Maunam,Meifoo,Mingkum,Mogong,Mongkok,Muichau,Muigong,Muiyuen,Naiwai,Namcheong,Namhoi,Namhong,Namsha,Nganwai,Ngautaukok,Ngchuen,Ngwa,Onting,Pakwun,Paotoishan,Pingshan,Pingyuen,Poklo,Pongon,Poning,Potau,Puito,Punyue,Saiwanho,Saiyingpun,Samshing,Samshui,Samtsen,Samyuenlei,Sanfung,Sanhing,Sanhui,Sanwai,Seiwui,Shamshuipo,Shanmei,Shantau,Shauking,Shekmun,Shekpai,Sheungshui,Shingkui,Shiuhing,Shundak,Shunyi,Shupinwai,Simshing,Siuhei,Siuhong,Siukwan,Siulun,Suikai,Taihing,Taikoo,Taipo,Taishuihang,Taiwai,Taiwohau,Tinhau,Tinshuiwai,Tiukengleng,Toishan,Tongfong,Tonglowan,Tsakyoochung,Tsamgong,Tsangshing,Tseungkwano,Tsimshatsui,Tsinggong,Tsingshantsuen,Tsingwun,Tsingyi,Tsingyuen,Tsiuchau,Tsuenshekshan,Tsuenwan,Tuenmun,Tungchung,Waichap,Waichau,Waidong,Wailoi,Waishing,Waiyeung,Wanchai,Wanfau,Wanshing,Wingon,Wongpo,Wongtaisin,Woping,Wukaisha,Yano,Yaumatei,Yautong,Yenfa,Yeungchun,Yeungdong,Yeungsai,Yeungshan,Yimtin,Yingdak,Yiuping,Yongshing,Yongyuen,Yuenlong,Yuenshing,Yuetsau,Yuknam,Yunping"},{name:"Mongolian",i:31,min:5,max:12,d:"aou",m:.3,b:"Adaatsag,Airag,Alag Erdene,Altai,Altanshiree,Altantsogts,Arbulag,Baatsagaan,Batnorov,Batshireet,Battsengel,Bayan Adarga,Bayan Agt,Bayanbulag,Bayandalai,Bayandun,Bayangovi,Bayanjargalan,Bayankhongor,Bayankhutag,Bayanlig,Bayanmonkh,Bayannur,Bayannuur,Bayan Ondor,Bayan Ovoo,Bayantal,Bayantsagaan,Bayantumen,Bayan Uul,Bayanzurkh,Berkh,Biger,Binder,Bogd,Bombogor,Bor Ondor,Bugat,Bugt,Bulgan,Buregkhangai,Burentogtokh,Buutsagaan,Buyant,Chandmani,Chandmani Ondor,Choibalsan,Chuluunkhoroot,Chuluut,Dadal,Dalanjargalan,Dalanzadgad,Darhan Muminggan,Darkhan,Darvi,Dashbalbar,Dashinchilen,Delger,Delgerekh,Delgerkhaan,Delgerkhangai,Delgertsogt,Deluun,Deren,Dorgon,Duut,Erdene,Erdenebulgan,Erdeneburen,Erdenedalai,Erdenemandal,Erdenetsogt,Galshar,Galt,Galuut,Govi Ugtaal,Gurvan,Gurvanbulag,Gurvansaikhan,Gurvanzagal,Hinggan,Hodong,Holingol,Hondlon,Horin Ger,Horqin,Hulunbuir,Hure,Ikhkhet,Ikh Tamir,Ikh Uul,Jargalan,Jargalant,Jargaltkhaan,Jarud,Jinst,Khairkhan,Khalhgol,Khaliun,Khanbogd,Khangai,Khangal,Khankh,Khankhongor,Khashaat,Khatanbulag,Khatgal,Kherlen,Khishig Ondor,Khokh,Kholonbuir,Khongor,Khotont,Khovd,Khovsgol,Khuld,Khureemaral,Khurmen,Khutag Ondor,Luus,Mandakh,Mandal Ovoo,Mankhan,Manlai,Matad,Mogod,Monkhkhairkhan,Moron,Most,Myangad,Nogoonnuur,Nomgon,Norovlin,Noyon,Ogii,Olgii,Olziit,Omnodelger,Ondorkhaan,Ondorshil,Ondor Ulaan,Ongniud,Ordos,Orgon,Orkhon,Rashaant,Renchinlkhumbe,Sagsai,Saikhan,Saikhandulaan,Saikhan Ovoo,Sainshand,Saintsagaan,Selenge,Sergelen,Sevrei,Sharga,Sharyngol,Shine Ider,Shinejinst,Shiveegovi,Sumber,Taishir,Tarialan,Tariat,Teshig,Togrog,Togtoh,Tolbo,Tomorbulag,Tonkhil,Tosontsengel,Tsagaandelger,Tsagaannuur,Tsagaan Ovoo,Tsagaan Uur,Tsakhir,Tseel,Tsengel,Tsenkher,Tsenkhermandal,Tsetseg,Tsetserleg,Tsogt,Tsogt Ovoo,Tsogttsetsii,Tumed,Tunel,Tuvshruulekh,Ulaanbadrakh,Ulaankhus,Ulaan Uul,Ulanhad,Ulanqab,Uyench,Yesonbulag,Zag,Zalainur,Zamyn Uud,Zereg"},{name:"Human Generic",i:32,min:6,max:11,d:"peolst",m:0,b:"Amberglen,Angelhand,Arrowden,Autumnband,Autumnkeep,Basinfrost,Basinmore,Bayfrost,Beargarde,Bearmire,Bellcairn,Bellport,Bellreach,Blackwatch,Bleakward,Bonemouth,Boulder,Bridgefalls,Bridgeforest,Brinepeak,Brittlehelm,Bronzegrasp,Castlecross,Castlefair,Cavemire,Claymond,Claymouth,Clearguard,Cliffgate,Cliffshear,Cliffshield,Cloudbay,Cloudcrest,Cloudwood,Coldholde,Cragbury,Crowgrove,Crowvault,Crystalrock,Crystalspire,Cursefield,Curseguard,Cursespell,Dawnforest,Dawnwater,Deadford,Deadkeep,Deepcairn,Deerchill,Demonfall,Dewglen,Dewmere,Diredale,Direden,Dirtshield,Dogcoast,Dogmeadow,Dragonbreak,Dragonhold,Dragonward,Dryhost,Dustcross,Dustwatch,Eaglevein,Earthfield,Earthgate,Earthpass,Ebonfront,Edgehaven,Eldergate,Eldermere,Embervault,Everchill,Evercoast,Falsevale,Faypond,Fayvale,Fayyard,Fearpeak,Flameguard,Flamewell,Freyshell,Ghostdale,Ghostpeak,Gloomburn,Goldbreach,Goldyard,Grassplains,Graypost,Greeneld,Grimegrove,Grimeshire,Heartfall,Heartford,Heartvault,Highbourne,Hillpass,Hollowstorm,Honeywater,Houndcall,Houndholde,Iceholde,Icelight,Irongrave,Ironhollow,Knightlight,Knighttide,Lagoonpass,Lakecross,Lastmere,Laststar,Lightvale,Limeband,Littlehall,Littlehold,Littlemire,Lostcairn,Lostshield,Loststar,Madfair,Madham,Midholde,Mightglen,Millstrand,Mistvault,Mondpass,Moonacre,Moongulf,Moonwell,Mosshand,Mosstide,Mosswind,Mudford,Mudwich,Mythgulch,Mythshear,Nevercrest,Neverfront,Newfalls,Nighthall,Oakenbell,Oakenrun,Oceanstar,Oldreach,Oldwall,Oldwatch,Oxbrook,Oxlight,Pearlhaven,Pinepond,Pondfalls,Pondtown,Pureshell,Quickbell,Quickpass,Ravenside,Roguehaven,Roseborn,Rosedale,Rosereach,Rustmore,Saltmouth,Sandhill,Scorchpost,Scorchstall,Shadeforest,Shademeadow,Shadeville,Shimmerrun,Shimmerwood,Shroudrock,Silentkeep,Silvercairn,Silvergulch,Smallmire,Smoothcliff,Smoothgrove,Smoothtown,Snakemere,Snowbay,Snowshield,Snowtown,Southbreak,Springmire,Springview,Stagport,Steammouth,Steamwall,Steepmoor,Stillhall,Stoneguard,Stonespell,Stormhand,Stormhorn,Sungulf,Sunhall,Swampmaw,Swangarde,Swanwall,Swiftwell,Thorncairn,Thornhelm,Thornyard,Timberside,Tradewick,Westmeadow,Westpoint,Whiteshore,Whitvalley,Wildeden,Wildwell,Wildyard,Winterhaven,Wolfpass"},{name:"Elven",i:33,min:6,max:12,d:"lenmsrg",m:0,b:"Adrindest,Aethel,Afranthemar,Aiqua,Alari,Allanar,Almalian,Alora,Alyanasari,Alyelona,Alyran,Ammar,Anyndell,Arasari,Aren,Ashmebel,Aymlume,Bel-Didhel,Brinorion,Caelora,Chaulssad,Chaundra,Cyhmel,Cyrang,Dolarith,Dolonde,Draethe,Dranzan,Draugaust,E'ana,Eahil,Edhil,Eebel,Efranluma,Eld-Sinnocrin,Elelthyr,Ellanalin,Ellena,Ellorthond,Eltaesi,Elunore,Emyranserine,Entheas,Eriargond,Esari,Esath,Eserius,Eshsalin,Eshthalas,Evraland,Faellenor,Famelenora,Filranlean,Filsaqua,Gafetheas,Gaf Serine,Geliene,Gondorwin,Guallu,Haeth,Hanluna,Haulssad,Heloriath,Himlarien,Himliene,Hinnead,Hlinas,Hloireenil,Hluihei,Hlurthei,Hlynead,Iaenarion,Iaron,Illanathaes,Illfanora,Imlarlon,Imyse,Imyvelian,Inferius,Inlurth,innsshe,Iralserin,Irethtalos,Irholona,Ishal,Ishlashara,Ithelion,Ithlin,Iulil,Jaal,Jamkadi,Kaalume,Kaansera,Karanthanil,Karnosea,Kasethyr,Keatheas,Kelsya,Keth Aiqua,Kmlon,Kyathlenor,Kyhasera,Lahetheas,Lefdorei,Lelhamelle,Lilean,Lindeenil,Lindoress,Litys,Llaughei,Lya,Lyfa,Lylharion,Lynathalas,Machei,Masenoris,Mathethil,Mathentheas,Meethalas,Menyamar,Mithlonde,Mytha,Mythsemelle,Mythsthas,Naahona,Nalore,Nandeedil,Nasad Ilaurth,Nasin,Nathemar,Neadar,Neilon,Nelalon,Nellean,Nelnetaesi,Nilenathyr,Nionande,Nylm,Nytenanas,Nythanlenor,O'anlenora,Obeth,Ofaenathyr,Ollmnaes,Ollsmel,Olwen,Olyaneas,Omanalon,Onelion,Onelond,Orlormel,Ormrion,Oshana,Oshvamel,Raethei,Rauguall,Reisera,Reslenora,Ryanasera,Rymaserin,Sahnor,Saselune,Sel-Zedraazin,Selananor,Sellerion,Selmaluma,Shaeras,Shemnas,Shemserin,Sheosari,Sileltalos,Siriande,Siriathil,Srannor,Sshanntyr,Sshaulu,Syholume,Sylharius,Sylranbel,Taesi,Thalor,Tharenlon,Thelethlune,Thelhohil,Themar,Thene,Thilfalean,Thilnaenor,Thvethalas,Thylathlond,Tiregul,Tlauven,Tlindhe,Ulal,Ullve,Ulmetheas,Ulssin,Umnalin,Umye,Umyheserine,Unanneas,Unarith,Undraeth,Unysarion,Vel-Shonidor,Venas,Vin Argor,Wasrion,Wlalean,Yaeluma,Yeelume,Yethrion,Ymserine,Yueghed,Yuerran,Yuethin"},{name:"Dark Elven",i:34,min:6,max:14,d:"nrslamg",m:.2,b:"Abaethaggar,Abburth,Afranthemar,Aharasplit,Aidanat,Ald'ruhn,Ashamanu,Ashesari,Ashletheas,Baerario,Baereghel,Baethei,Bahashae,Balmora,Bel-Didhel,Borethanil,Buiyrandyn,Caellagith,Caellathala,Caergroth,Caldras,Chaggar,Chaggaust,Channtar,Charrvhel'raugaust,Chaulssin,Chaundra,ChedNasad,ChetarIthlin,ChethRrhinn,Chymaer,Clarkarond,Cloibbra,Commoragh,Cyrangroth,Cilben,D'eldarc,Daedhrog,Dalkyn,Do'Urden,Doladress,Dolarith,Dolonde,Draethe,Dranzan,Dranzithl,Draugaust,Dreghei,Drelhei,Dryndlu,Dusklyngh,DyonG'ennivalz,Edraithion,Eld-Sinnocrin,Ellorthond,Enhethyr,Entheas,ErrarIthinn,Eryndlyn,Faladhell,Faneadar,Fethalas,Filranlean,Formarion,Ferdor,Gafetheas,Ghrond,Gilranel,Glamordis,Gnaarmok,Gnisis,Golothaer,Gondorwin,Guallidurth,Guallu,Gulshin,Haeth,Haggraef,Harganeth,Harkaldra,Haulssad,Haundrauth,Heloriath,Hlammachar,Hlaughei,Hloireenil,Hluitar,Inferius,Innsshe,Ithilaughym,Iz'aiogith,Jaal,Jhachalkhyn,Kaerabrae,Karanthanil,Karondkar,Karsoluthiyl,Kellyth,Khuul,Lahetheas,Lidurth,Lindeenil,Lirillaquen,LithMy'athar,LlurthDreier,Lolth,Lothuial,Luihaulen'tar,Maeralyn,Maerimydra,Mathathlona,Mathethil,Mellodona,Menagith,Menegwen,Menerrendil,Menzithl,Menzoberranzan,Mila-Nipal,Mithryn,Molagmar,Mundor,Myvanas,Naggarond,Nandeedil,NasadIlaurth,Nauthor,Navethas,Neadar,Nurtaleewe,Nidiel,Noruiben,Olwen,O'lalona,Obeth,Ofaenathyr,Orlormel,Orlytlar,Pelagiad,Raethei,Raugaust,Rauguall,Rilauven,Rrharrvhei,Sadrith,Sel-Zedraazin,Seydaneen,Shaz'rir,Skaal,Sschindylryn,Shamath,Shamenz,Shanntur,Sshanntynlan,Sshanntyr,Shaulssin,SzithMorcane,Szithlin,Szobaeth,Sirdhemben,T'lindhet,Tebh'zhor,Telmere,Telnarquel,Tharlarast,Thylathlond,Tlaughe,Trizex,Tyrybblyn,Ugauth,Ughym,Uhaelben,Ullmatalos,Ulmetheas,Ulrenserine,Uluitur,Undraeth,Undraurth,Undrek'Thoz,Ungethal,UstNatha,Uthaessien,V'elddrinnsshar,Vaajha,Vel-Shonidor,Velddra,Velothi,Venead,Vhalth'vha,Vinargothr,Vojha,Waethe,Waethei,Xaalkis,Yakaridan,Yeelume,Yridhremben,Yuethin,Yuethindrynn,Zirnakaynin"},{name:"Dwarven",i:35,min:4,max:11,d:"dk",m:0,b:"Addundad,Ahagzad,Ahazil,Akil,Akzizad,Anumush,Araddush,Arar,Arbhur,Badushund,Baragzig,Baragzund,Barakinb,Barakzig,Barakzinb,Barakzir,Baramunz,Barazinb,Barazir,Bilgabar,Bilgatharb,Bilgathaz,Bilgila,Bilnaragz,Bilnulbar,Bilnulbun,Bizaddum,Bizaddush,Bizanarg,Bizaram,Bizinbiz,Biziram,Bunaram,Bundinar,Bundushol,Bundushund,Bundushur,Buzaram,Buzundab,Buzundush,Gabaragz,Gabaram,Gabilgab,Gabilgath,Gabizir,Gabunal,Gabunul,Gabuzan,Gatharam,Gatharbhur,Gathizdum,Gathuragz,Gathuraz,Gila,Giledzir,Gilukkhath,Gilukkhel,Gunala,Gunargath,Gunargil,Gundumunz,Gundusharb,Gundushizd,Kharbharbiln,Kharbhatharb,Kharbhela,Kharbilgab,Kharbuzadd,Khatharbar,Khathizdin,Khathundush,Khazanar,Khazinbund,Khaziragz,Khaziraz,Khizdabun,Khizdusharbh,Khizdushath,Khizdushel,Khizdushur,Kholedzar,Khundabiln,Khundabuz,Khundinarg,Khundushel,Khuragzig,Khuramunz,Kibarak,Kibilnal,Kibizar,Kibunarg,Kibundin,Kibuzan,Kinbadab,Kinbaragz,Kinbarakz,Kinbaram,Kinbizah,Kinbuzar,Nala,Naledzar,Naledzig,Naledzinb,Naragzah,Naragzar,Naragzig,Narakzah,Narakzar,Naramunz,Narazar,Nargabad,Nargabar,Nargatharb,Nargila,Nargundum,Nargundush,Nargunul,Narukthar,Narukthel,Nula,Nulbadush,Nulbaram,Nulbilnarg,Nulbunal,Nulbundab,Nulbundin,Nulbundum,Nulbuzah,Nuledzah,Nuledzig,Nulukkhaz,Nulukkhund,Nulukkhur,Sharakinb,Sharakzar,Sharamunz,Sharbarukth,Shatharbhizd,Shatharbiz,Shathazah,Shathizdush,Shathola,Shaziragz,Shizdinar,Shizdushund,Sholukkharb,Shundinulb,Shundushund,Shurakzund,Shuramunz,Tumunzadd,Tumunzan,Tumunzar,Tumunzinb,Tumunzir,Ukthad,Ulbirad,Ulbirar,Ulunzar,Ulur,Umunzad,Undalar,Undukkhil,Undun,Undur,Unduzur,Unzar,Unzathun,Usharar,Zaddinarg,Zaddushur,Zaharbad,Zaharbhizd,Zarakib,Zarakzar,Zaramunz,Zarukthel,Zinbarukth,Zirakinb,Zirakzir,Ziramunz,Ziruktharbh,Zirukthur,Zundumunz"},{name:"Goblin",i:36,min:4,max:9,d:"eag",m:0,b:"Asinx,Bhiagielt,Biokvish,Blix,Blus,Bratliaq,Breshass,Bridvelb,Brybsil,Bugbig,Buyagh,Cel,Chalk,Chiafzia,Chox,Cielb,Cosvil,Crekork,Crild,Croibieq,Diervaq,Dobruing,Driord,Eebligz,Een,Enissee,Esz,Far,Felhob,Froihiofz,Fruict,Fygsee,Gagablin,Gigganqi,Givzieqee,Glamzofs,Glernaahx,Gneabs,Gnoklig,Gobbledak,gobbok,Gobbrin,Heszai,Hiszils,Hobgar,Honk,Iahzaarm,Ialsirt,Ilm,Ish,Jasheafta,Joimtoilm,Kass,Katmelt,Kleabtong,Kleardeek,Klilm,Kluirm,Kuipuinx,Moft,Mogg,Nilbog,Oimzoishai,Onq,Ozbiard,Paas,Phax,Phigheldai,Preang,Prolkeh,Pyreazzi,Qeerags,Qosx,Rekx,Shaxi,Sios,Slehzit,Slofboif,Slukex,Srefs,Srurd,Stiaggaltia,Stiolx,Stioskurt,Stroir,Strytzakt,Stuikvact,Styrzangai,Suirx,Swaxi,Taxai,Thelt,Thresxea,Thult,Traglila,Treaq,Ulb,Ulm,Utha,Utiarm,Veekz,Vohniots,Vreagaald,Watvielx,Wrogdilk,Wruilt,Xurx,Ziggek,Zriokots"},{name:"Orc",i:37,min:4,max:8,d:"gzrcu",m:0,b:"Adgoz,Adgril-Gha,Adog,Adzurd,Agkadh,Agzil-Ghal,Akh,Ariz-Dru,Arkugzo,Arrordri,Ashnedh,Azrurdrekh,Bagzildre,Bashnud,Bedgez-Graz,Bhakh,Bhegh,Bhiccozdur,Bhicrur,Bhirgoshbel,Bhog,Bhurkrukh,Bod-Rugniz,Bogzel,Bozdra,Bozgrun,Bozziz,Bral-Lazogh,Brazadh,Brogved,Brogzozir,Brolzug,Brordegeg,Brorkril-Zrog,Brugroz,Brukh-Zrabrul,Brur-Korre,Bulbredh,Bulgragh,Chaz-Charard,Chegan-Khed,Chugga,Chuzar,Dhalgron-Mog,Dhazon-Ner,Dhezza,Dhoddud,Dhodh-Brerdrodh,Dhodh-Ghigin,Dhoggun-Bhogh,Dhulbazzol,Digzagkigh,Dirdrurd,Dodkakh,Dorgri,Drizdedh,Drobagh,Drodh-Ashnugh,Drogvukh-Drodh,Drukh-Qodgoz,Drurkuz,Dududh,Dur-Khaddol,Egmod,Ekh-Beccon,Ekh-Krerdrugh,Ekh-Mezred,Gagh-Druzred,Gazdrakh-Vrard,Gegnod,Gerkradh,Ghagrocroz,Ghared-Krin,Ghedgrolbrol,Gheggor,Ghizgil,Gho-Ugnud,Gholgard,Gidh-Ucceg,Goccogmurd,Golkon,Graz-Khulgag,Gribrabrokh,Gridkog,Grigh-Kaggaz,Grirkrun-Qur,Grughokh,Grurro,Gugh-Zozgrod,Gur-Ghogkagh,Ibagh-Chol,Ibruzzed,Ibul-Brad,Iggulzaz,Ikh-Ugnan,Irdrelzug,Irmekh-Bhor,Kacruz,Kalbrugh,Karkor-Zrid,Kazzuz-Zrar,Kezul-Bruz,Kharkiz,Khebun,Khorbric,Khuldrerra,Khuzdraz,Kirgol,Koggodh,Korkrir-Grar,Kraghird,Krar-Zurmurd,Krigh-Bhurdin,Kroddadh,Krudh-Khogzokh,Kudgroccukh,Kudrukh,Kudzal,Kuzgrurd-Dedh,Larud,Legvicrodh,Lorgran,Lugekh,Lulkore,Mazgar,Merkraz,Mocculdrer,Modh-Odod,Morbraz,Mubror,Muccug-Ghuz,Mughakh-Chil,Murmad,Nazad-Ludh,Negvidh,Nelzor-Zroz,Nirdrukh,Nogvolkar,Nubud,Nuccag,Nudh-Kuldra,Nuzecro,Oddigh-Krodh,Okh-Uggekh,Ordol,Orkudh-Bhur,Orrad,Qashnagh,Qiccad-Chal,Qiddolzog,Qidzodkakh,Qirzodh,Rarurd,Reradgri,Rezegh,Rezgrugh,Rodrekh,Rogh-Chirzaz,Rordrushnokh,Rozzez,Ruddirgrad,Rurguz-Vig,Ruzgrin,Ugh-Vruron,Ughudadh,Uldrukh-Bhudh,Ulgor,Ulkin,Ummugh-Ekh,Uzaggor,Uzdriboz,Uzdroz,Uzord,Uzron,Vaddog,Vagord-Khod,Velgrudh,Verrugh,Vrazin,Vrobrun,Vrugh-Nardrer,Vrurgu,Vuccidh,Vun-Gaghukh,Zacrad,Zalbrez,Zigmorbredh,Zordrordud,Zorrudh,Zradgukh,Zragmukh,Zragrizgrakh,Zraldrozzuz,Zrard-Krodog,Zrazzuz-Vaz,Zrigud,Zrulbukh-Dekh,Zubod-Ur,Zulbriz,Zun-Bergrord"},{name:"Giant",i:38,min:5,max:10,d:"kdtng",m:0,b:"Addund,Aerora,Agane,Anumush,Arangrim,Bahourg,Baragzund,Barakinb,Barakzig,Barakzinb,Baramunz,Barazinb,Beornelde,Beratira,Borgbert,Botharic,Bremrol,Brerstin,Brildung,Brozu,Bundushund,Burthug,Chazruc,Chergun,Churtec,Dagdhor,Dankuc,Darnaric,Debuch,Dina,Dinez,Diru,Drard,Druguk,Dugfast,Duhal,Dulkun,Eldond,Enuz,Eraddam,Eradhelm,Froththorn,Fynwyn,Gabaragz,Gabaram,Gabizir,Gabuzan,Gagkake,Galfald,Galgrim,Gatal,Gazin,Geru,Gila,Giledzir,Girkun,Glumvat,Gluthmark,Gomruch,Gorkege,Gortho,Gostuz,Grimor,Grimtira,Guddud,Gudgiz,Gulwo,Gunargath,Gundusharb,Guril,Gurkale,Guruge,Guzi,Hargarth,Hartreo,Heimfara,Hildlaug,Idgurth,Inez,Inginy,Iora,Irkin,Jaldhor,Jarwar,Jornangar,Jornmoth,Kakkek,Kaltoch,Kegkez,Kengord,Kharbharbiln,Khatharbar,Khathizdin,Khazanar,Khaziragz,Khizdabun,Khizdushel,Khundinarg,Kibarak,Kibizar,Kigine,Kilfond,Kilkan,Kinbadab,Kinbuzar,Koril,Kostand,Kuzake,Lindira,Lingarth,Maerdis,Magald,Marbold,Marbrand,Memron,Minu,Mistoch,Morluch,Mornkin,Morntaric,Nagu,Naragzah,Naramunz,Narazar,Nargabar,Nargatharb,Nargundush,Nargunul,Natan,Natil,Neliz,Nelkun,Noluch,Norginny,Nulbaram,Nulbilnarg,Nuledzah,Nuledzig,Nulukkhaz,Nulukkhur,Nurkel,Oci,Olane,Oldstin,Orga,Ranava,Ranhera,Rannerg,Rirkan,Rizen,Rurki,Rurkoc,Sadgach,Sgandrol,Sharakzar,Shatharbiz,Shathizdush,Shathola,Shizdinar,Sholukkharb,Shundushund,Shurakzund,Sidga,Sigbeorn,Sigbi,Solfod,Somrud,Srokvan,Stighere,Sulduch,Talkale,Theoddan,Theodgrim,Throtrek,Tigkiz,Tolkeg,Toren,Tozage,Tulkug,Tumunzar,Umunzad,Undukkhil,Usharar,Valdhere,Varkud,Velfirth,Velhera,Vigkan,Vorkige,Vozig,Vylwed,Widhyrde,Wylaeya,Yili,Yotane,Yudgor,Yulkake,Zigez,Zugkan,Zugke"},{name:"Draconic",i:39,min:6,max:14,d:"aliuszrox",m:0,b:"Aaronarra,Adalon,Adamarondor,Aeglyl,Aerosclughpalar,Aghazstamn,Aglaraerose,Agoshyrvor,Alduin,Alhazmabad,Altagos,Ammaratha,Amrennathed,Anaglathos,Andrathanach,Araemra,Araugauthos,Arauthator,Arharzel,Arngalor,Arveiaturace,Athauglas,Augaurath,Auntyrlothtor,Azarvilandral,Azhaq,Balagos,Baratathlaer,Bleucorundum,BrazzPolis,Canthraxis,Capnolithyl,Charvekkanathor,Chellewis,Chelnadatilar,Cirrothamalan,Claugiyliamatar,Cragnortherma,Dargentum,Dendeirmerdammarar,Dheubpurcwenpyl,Domborcojh,Draconobalen,Dragansalor,Dupretiskava,Durnehviir,Eacoathildarandus,Eldrisithain,Enixtryx,Eormennoth,Esmerandanna,Evenaelorathos,Faenphaele,Felgolos,Felrivenser,Firkraag,Fll'Yissetat,Furlinastis,Galadaeros,Galglentor,Garnetallisar,Garthammus,Gaulauntyr,Ghaulantatra,Glouroth,Greshrukk,Guyanothaz,Haerinvureem,Haklashara,Halagaster,Halaglathgar,Havarlan,Heltipyre,Hethcypressarvil,Hoondarrh,Icehauptannarthanyx,Iiurrendeem,Ileuthra,Iltharagh,Ingeloakastimizilian,Irdrithkryn,Ishenalyr,Iymrith,Jaerlethket,Jalanvaloss,Jharakkan,Kasidikal,Kastrandrethilian,Khavalanoth,Khuralosothantar,Kisonraathiisar,Kissethkashaan,Kistarianth,Klauth,Klithalrundrar,Krashos,Kreston,Kriionfanthicus,Krosulhah,Krustalanos,Kruziikrel,Kuldrak,Lareth,Latovenomer,Lhammaruntosz,Llimark,Ma'fel'no'sei'kedeh'naar,MaelestorRex,Magarovallanthanz,Mahatnartorian,Mahrlee,Malaeragoth,Malagarthaul,Malazan,Maldraedior,Maldrithor,MalekSalerno,Maughrysear,Mejas,Meliordianix,Merah,Mikkaalgensis,Mirmulnir,Mistinarperadnacles,Miteach,Mithbarazak,Morueme,Moruharzel,Naaslaarum,Nahagliiv,Nalavarauthatoryl,Naxorlytaalsxar,Nevalarich,Nolalothcaragascint,Nurvureem,Nymmurh,Odahviing,Olothontor,Ormalagos,Otaaryliakkarnos,Paarthurnax,Pelath,Pelendralaar,Praelorisstan,Praxasalandos,Protanther,Qiminstiir,Quelindritar,Ralionate,Rathalylaug,Rathguul,Rauglothgor,Raumorthadar,Relonikiv,Ringreemeralxoth,Roraurim,Rynnarvyx,Sablaxaahl,Sahloknir,Sahrotaar,Samdralyrion,Saryndalaghlothtor,Sawaka,Shalamalauth,Shammagar,Sharndrel,Shianax,Skarlthoon,Skurge,Smergadas,Ssalangan,Sssurist,Sussethilasis,Sylvallitham,Tamarand,Tantlevgithus,Tarlacoal,Tenaarlaktor,Thalagyrt,Tharas'kalagram,Thauglorimorgorus,Thoklastees,Thyka,Tsenshivah,Ueurwen,Uinnessivar,Urnalithorgathla,Velcuthimmorhar,Velora,Vendrathdammarar,Venomindhar,Viinturuth,Voaraghamanthar,Voslaarum,Vr'tark,Vrondahorevos,Vuljotnaak,Vulthuryol,Wastirek,Worlathaugh,Xargithorvar,Xavarathimius,Yemere,Ylithargathril,Ylveraasahlisar,Za-Jikku,Zarlandris,Zellenesterex,Zilanthar,Zormapalearath,Zundaerazylym,Zz'Pzora"},{name:"Arachnid",i:40,min:4,max:10,d:"erlsk",m:0,b:"Aaqok'ser,Aiced,Aizachis,Allinqel,As'taq,Ashrash,Caaqtos,Ceek'sax,Ceezuq,Cek'sier,Cen'qi,Ceqzocer,Cezeed,Chachocaq,Charis,Chashilieth,Checib,Chernul,Chezi,Chiazu,Chishros,Chixhi,Chizhi,Chollash,Choq'sha,Cinchichail,Collul,Ecush'taid,Ekiqe,Eqas,Er'uria,Erikas,Es'tase,Esrub,Exha,Haqsho,Hiavheesh,Hitha,Hok'thi,Hossa,Iacid,Iciever,Illuq,Isnir,Keezut,Kheellavas,Kheizoh,Khiachod,Khika,Khirzur,Khonrud,Khrakku,Khraqshis,Khrethish'ti,Khriashus,Khrika,Khrirni,Klashirel,Kleil'sha,Klishuth,Krarnit,Kras'tex,Krotieqas,Lais'tid,Laizuh,Lasnoth,Len'qeer,Leqanches,Lezad,Lhilir,Lhivhath,Lhok'thu,Lialliesed,Liaraq,Liceva,Lichorro,Lilla,Lokieqib,Nakur,Neerhaca,Neet'er,Neezoh,Nenchiled,Nerhalneth,Nir'ih,Nizus,Noreeqo,On'qix,Qalitho,Qas'tor,Qasol,Qavrud,Qavud,Qazar,Qazru,Qekno,Qeqravee,Qes'tor,Qhaik'sal,Qhak'sish,Qhazsakais,Qheliva,Qhenchaqes,Qherazal,Qhon'qos,Qhosh,Qish'tur,Qisih,Qorhoci,Qranchiq,Racith,Rak'zes,Ranchis,Rarhie,Rarzi,Rarzisiaq,Ras'tih,Ravosho,Recad,Rekid,Rernee,Rertachis,Rezhokketh,Reziel,Rhacish,Rhail'shel,Rhairhizse,Rhakivex,Rhaqeer,Rhartix,Rheciezsei,Rheevid,Rhel'shir,Rhevhie,Rhiavekot,Rhikkos,Rhiqese,Rhiqi,Rhiqracar,Rhisned,Rhousnateb,Riakeesnex,Rintachal,Rir'ul,Rourk'u,Rouzakri,Sailiqei,Sanchiqed,Saqshu,Sat'ier,Sazi,Seiqas,Shieth'i,Shiqsheh,Shizha,Shrachuvo,Shranqo,Shravhos,Shravuth,Shreerhod,Shrethuh,Shriantieth,Shronqash,Shrovarhir,Shrozih,Siacaqoh,Siezosh,Siq'sha,Sirro,Sornosi,Srachussi,Szaca,Szacih,Szaqova,Szasu,Szazhilos,Szeerrud,Szeezsad,Szeknur,Szesir,Szezhirros,Szilshith,Szon'qol,Szornuq,Xeekke,Yeek'su,Yeeq'zox,Yeqil,Yeqroq,Yeveed,Yevied,Yicaveeh,Yirresh,Yisie,Yithik'thaih,Yorhaqshes,Zacheek'sa,Zakkasa,Zelraq,Zeqo,Zharuncho,Zhath'arhish,Zhavirrit,Zhazilraq,Zhazsachiel,Zhek'tha,Zhequ,Zhias'ted,Zhicat,Zhicur,Zhirhacil,Zhizri,Zhochizses,Ziarih,Zirnib"},{name:"Serpents",i:41,min:5,max:11,d:"slrk",m:0,b:"Aj'ha,Aj'i,Aj'tiss,Ajakess,Aksas,Aksiss,Al'en,An'jeshe,Apjige,Arkkess,Athaz,Atus,Azras,Caji,Cakrasar,Cal'arrun,Capji,Cathras,Cej'han,Ces,Cez'jenta,Cij'te,Cinash,Cizran,Coth'jus,Cothrash,Culzanek,Cunaless,Ej'tesh,Elzazash,Ergek,Eshjuk,Ethris,Gan'jas,Gapja,Gar'thituph,Gopjeguss,Gor'thesh,Gragishaph,Grar'theness,Grath'ji,Gressinas,Grolzesh,Grorjar,Grozrash,Guj'ika,Harji,Hej'hez,Herkush,Horgarrez,Illuph,Ipjar,Ithashin,Kaj'ess,Kar'kash,Kepjusha,Ki'kintus,Kissere,Koph,Kopjess,Kra'kasher,Krak,Krapjez,Krashjuless,Kraz'ji,Krirrigis,Krussin,Ma'lush,Mage,Maj'tak,Mal'a,Mapja,Mar'kash,Mar'kis,Marjin,Mas,Mathan,Men'jas,Meth'jaresh,Mij'hegak,Min'jash,Mith'jas,Monassu,Moss,Naj'hass,Najugash,Nak,Napjiph,Nar'ka,Nar'thuss,Narrusha,Nash,Nashjekez,Nataph,Nij'ass,Nij'tessiph,Nishjiss,Norkkuss,Nus,Olluruss,Or'thi,Or'thuss,Paj'a,Parkka,Pas,Pathujen,Paz'jaz,Pepjerras,Pirkkanar,Pituk,Porjunek,Pu'ke,Ragen,Ran'jess,Rargush,Razjuph,Rilzan,Riss,Rithruz,Rorgiss,Rossez,Rraj'asesh,Rraj'tass,Rrar'kess,Rrar'thuph,Rras,Rrazresh,Rrej'hish,Rrigelash,Rris,Rris,Rroksurrush,Rukrussush,Rurri,Russa,Ruth'jes,Sa'kitesh,Sar'thass,Sarjas,Sazjuzush,Ser'thez,Sezrass,Shajas,Shas,Shashja,Shass,Shetesh,Shijek,Shun'jaler,Shurjarri,Skaler,Skalla,Skallentas,Skaph,Skar'kerriz,Skath'jeruk,Sker'kalas,Skor,Skoz'ji,Sku'lu,Skuph,Skur'thur,Slalli,Slalt'har,Slelziress,Slil'ar,Sloz'jisa,Sojesh,Solle,Sorge,Sral'e,Sran'ji,Srapjess,Srar'thazur,Srash,Srath'jess,Srathrarre,Srerkkash,Srus,Sruss'tugeph,Sun,Suss'tir,Uzrash,Vargush,Vek,Vess'tu,Viph,Vult'ha,Vupjer,Vushjesash,Xagez,Xassa,Xulzessu,Zaj'tiss,Zan'jer,Zarriss,Zassegus,Zirres,Zsor,Zurjass"},{name:"Levantine",i:42,min:4,max:12,d:"ankprs",m:0,b:"Adme,Adramet,Agadir,Akko,Akzib,Alimas,Alis-Ubbo,Alqosh,Amid,Ammon,Ampi,Amurru,Andarig,Anpa,Araden,Aram,Arwad,Ashkelon,Athar,Atiq,Aza,Azeka,Baalbek,Babel,Batrun,Beerot,Beersheba,Beit Shemesh,Berytus,Bet Agus,Bet Anya,Beth-Horon,Bethel,Bethlehem,Bethuel,Bet Nahrin,Bet Nohadra,Bet Zalin,Birmula,Biruta,Bit Agushi,Bitan,Bit Zamani,Cerne,Dammeseq,Darmsuq,Dor,Eddial,Eden Ekron,Elah,Emek,Emun,Ephratah,Eyn Ganim,Finike,Gades,Galatia,Gaza,Gebal,Gedera,Gerizzim,Gethsemane,Gibeon,Gilead,Gilgal,Golgotha,Goshen,Gytte,Hagalil,Haifa,Halab,Haqel Dma,Har Habayit,Har Nevo,Har Pisga,Havilah,Hazor,Hebron,Hormah,Iboshim,Iriho,Irinem,Irridu,Israel,Kadesh,Kanaan,Kapara,Karaly,Kart-Hadasht,Keret Chadeshet,Kernah,Kesed,Keysariya,Kfar,Kfar Nahum,Khalibon,Khalpe,Khamat,Kiryat,Kittim,Kurda,Lapethos,Larna,Lepqis,Lepriptza,Liksos,Lod,Luv,Malaka,Malet,Marat,Megido,Melitta,Merdin,Metsada,Mishmarot,Mitzrayim,Moab,Mopsos,Motye,Mukish,Nampigi,Nampigu,Natzrat,Nimrud,Nineveh,Nob,Nuhadra,Oea,Ofir,Oyat,Phineka,Phoenicus,Pleshet,Qart-Tubah Sarepta,Qatna,Rabat Amon,Rakkath,Ramat Aviv,Ramitha,Ramta,Rehovot,Reshef,Rushadir,Rushakad,Samrin,Sefarad,Sehyon,Sepat,Sexi,Sharon,Shechem,Shefelat,Shfanim,Shiloh,Shmaya,Shomron,Sidon,Sinay,Sis,Solki,Sur,Suria,Tabetu,Tadmur,Tarshish,Tartus,Teberya,Tefessedt,Tekoa,Teyman,Tinga,Tipasa,Tsabratan,Tur Abdin,Tzarfat,Tziyon,Tzor,Ugarit,Unubaal,Ureshlem,Urhay,Urushalim,Vaga,Yaffa,Yamhad,Yam hamelach,Yam Kineret,Yamutbal,Yathrib,Yaudi,Yavne,Yehuda,Yerushalayim,Yev,Yevus,Yizreel,Yurdnan,Zarefat,Zeboim,Zeurta,Zeytim,Zikhron,Zmurna"}]}}window.Names=new Iu;class Du{cells;vertices;pointsN;used;lineGen=tn().curve(Tl);oceanLayers;constructor(a){this.oceanLayers=a}randomizeOutline(){const a=[];let n=.2;for(let t=-9;t<0;t++)B(n)?(n=.2,a.push(t)):n*=2;return a}connectVertices(a,n){const t=[];for(let i=0,o=a;i===0||o!==a&&i<1e4;i++){const s=t[t.length-1];t.push(o);const h=this.vertices.c[o];h.filter(r=>this.cells.t[r]===n).forEach(r=>{this.used[r]=1});const u=this.vertices.v[o],l=!this.cells.t[h[0]]||this.cells.t[h[0]]===n-1,c=!this.cells.t[h[1]]||this.cells.t[h[1]]===n-1,d=!this.cells.t[h[2]]||this.cells.t[h[2]]===n-1;if(u[0]!==void 0&&u[0]!==s&&l!==c?o=u[0]:u[1]!==void 0&&u[1]!==s&&c!==d?o=u[1]:u[2]!==void 0&&u[2]!==s&&l!==d&&(o=u[2]),o===t[t.length-1]){ERROR&&console.error("Next vertex is not found");break}}return t.push(t[0]),t}findStart(a,n){return this.cells.b[a]?this.cells.v[a].find(t=>this.vertices.c[t].some(i=>i>=this.pointsN)):this.cells.v[a][this.cells.c[a].findIndex(t=>this.cells.t[t]+o),t=[],i=N(.4/n.length,2);this.used=new Uint8Array(this.pointsN);for(const o of this.cells.i){const s=this.cells.t[o];if(s>0||this.used[o]||!n.includes(s))continue;const h=this.findStart(o,s);if(!h)continue;this.used[o]=1;const u=this.connectVertices(h,s);if(u.length<4)continue;const l=1+s*-2,c=u.filter((r,g)=>!(g%l)||this.vertices.c[r].some(m=>m>=this.pointsN));if(c.length<4)continue;const d=sn(c.map(r=>this.vertices.p[r]),graphWidth,graphHeight,1);t.push([s,d])}for(const o of n){const h=t.filter(u=>u[0]===o).map(u=>ze(this.lineGen(u[1])||"")).join("");h&&this.oceanLayers.append("path").attr("d",h).attr("fill","#ecf2f9").attr("fill-opacity",i)}TIME&&console.timeEnd("drawOceanLayers")}}window.OceanLayers=()=>new Du(oceanLayers).draw();class Gu{LAKE_ELEVATION_DELTA=.1;getHeight(a){const n=pack.cells.h,t=Ba(a.shoreline.map(i=>n[i]))||20;return N(t-this.LAKE_ELEVATION_DELTA,2)}defineNames(){pack.features.forEach(a=>{a.type==="lake"&&(a.name=this.getName(a))})}getName(a){const n=a.shoreline[0],t=pack.cells.culture[n];return Names.getCulture(t)}cleanupLakeData=()=>{for(const a of pack.features){if(a.type!=="lake")continue;delete a.river,delete a.enteringFlux,delete a.outCell,delete a.closed,a.height=N(a.height,3);const n=a.inlets?.filter(i=>pack.rivers.find(o=>o.i===i));!n||!n.length?delete a.inlets:a.inlets=n,a.outlet&&pack.rivers.find(i=>i.i===a.outlet)||delete a.outlet}};defineClimateData(a){const{cells:n,features:t}=pack,i=new Uint16Array(n.i.length),o=l=>l.shoreline.reduce((c,d)=>c+grid.cells.prec[n.g[d]],0),s=l=>l.cells<6?grid.cells.temp[n.g[l.firstCell]]:N(Ha(l.shoreline.map(c=>grid.cells.temp[n.g[c]])),1),h=l=>{const c=(l.height-18)**Number(heightExponentInput.value),d=(700*(l.temp+.006*c)/50+75)/(80-l.temp);return N(d*l.cells)},u=l=>l.shoreline.sort((c,d)=>a[c]-a[d])[0];return t.forEach(l=>{l.type==="lake"&&(l.flux=o(l),l.temp=s(l),l.evaporation=h(l),!l.closed&&(l.outCell=u(l),i[l.outCell]=l.i))}),i}detectCloseLakes(a){const{cells:n}=pack,t=+j("lakeElevationLimitOutput")?.value;pack.features.forEach(i=>{if(i.type!=="lake")return;delete i.closed;const o=i.height+t;if(o>99){i.closed=!1;return}let s=!0;const h=i.shoreline.sort((c,d)=>a[c]-a[d])[0],u=[h],l=[];for(l[h]=!0;u.length&&s;){const c=u.pop();for(const d of n.c[c])if(!l[d]&&!(a[d]>=o)){if(a[d]<20){const r=pack.features[n.f[d]];(r.type==="ocean"||i.height>r.height)&&(s=!1)}l[d]=!0,u.push(d)}}i.closed=s})}}window.Lakes=new Gu;class Ou{FLUX_FACTOR=500;MAX_FLUX_WIDTH=1;LENGTH_FACTOR=200;LENGTH_STEP_WIDTH=1/this.LENGTH_FACTOR;LENGTH_PROGRESSION=[1,1,2,3,5,8,13,21,34].map(a=>a/this.LENGTH_FACTOR);lineGen=tn().curve(zl);riverTypes={main:{big:{River:1},small:{Creek:9,River:3,Brook:3,Stream:1}},fork:{big:{Fork:1},small:{Branch:1}}};smallLength=null;generate(a=!0){TIME&&console.time("generateRivers"),Math.random=Te(seed);const{cells:n,features:t}=pack,i={},o={},s=(m,f)=>{i[f]?i[f].push(m):i[f]=[m]},h=()=>{const f=(pointsInput.dataset.cells/1e4)**.25,p=grid.cells.prec,y=n.i.filter(b=>g[b]>=20).sort((b,v)=>g[v]-g[b]),k=Lakes.defineClimateData(g);for(const b of y){n.fl[b]+=p[n.g[b]]/f;const v=k[b]?t.filter(M=>b===M.outCell&&M.flux>M.evaporation):[];for(const M of v){const T=n.c[b].find(S=>g[S]<20&&n.f[S]===M.i);n.fl[T]+=Math.max(M.flux-M.evaporation,0),n.r[T]!==M.river&&(n.c[T].some(z=>n.r[z]===M.river)?(n.r[T]=M.river,s(T,M.river)):(n.r[T]=r,s(T,r),r++)),M.outlet=n.r[T],u(b,n.fl[T],M.outlet)}const w=v[0]?.outlet;for(const M of v)if(Array.isArray(M.inlets))for(const T of M.inlets)o[T]=w;if(n.b[b]&&n.r[b]){s(-1,n.r[b]);continue}let _=null;if(k[b]?_=n.c[b].filter(T=>!v.map(S=>S.i).includes(n.f[T])).sort((T,S)=>g[T]-g[S])[0]:n.haven[b]?_=n.haven[b]:_=n.c[b].sort((M,T)=>g[M]-g[T])[0],!(g[b]<=g[_])){if(n.fl[b]<30){g[_]>=20&&(n.fl[_]+=n.fl[b]);continue}n.r[b]||(n.r[b]=r,s(b,r),r++),u(_,n.fl[b],n.r[b])}}},u=(m,f,p)=>{const y=n.fl[m]-n.conf[m],k=n.r[m];if(k?f>y?(n.conf[m]+=n.fl[m],g[m]>=20&&(o[k]=p),n.r[m]=p):(n.conf[m]+=f,g[m]>=20&&(o[p]=k)):n.r[m]=p,g[m]<20){const b=t[n.f[m]];b.type==="lake"&&((!b.river||f>b.enteringFlux)&&(b.river=p,b.enteringFlux=f),b.flux=b.flux+f,b.inlets?b.inlets.push(p):b.inlets=[p])}else n.fl[m]+=f;s(m,p)},l=()=>{n.r=new Uint16Array(n.i.length),n.conf=new Uint16Array(n.i.length),pack.rivers=[];const m=N(1/(pointsInput.dataset.cells/1e4)**.25,2),f=m*1.2;for(const p in i){const y=i[p];if(y.length<3)continue;const k=+p;for(const x of y)x<0||n.h[x]<20||(n.r[x]?n.conf[x]=1:n.r[x]=k);const b=y[0],v=y[y.length-2],w=o[p]||0,_=!w||w===k?f:m,M=this.addMeandering(y),T=n.fl[v],S=this.getApproximateLength(M),z=this.getSourceWidth(n.fl[b]),A=this.getWidth(this.getOffset({flux:T,pointIndex:M.length,widthFactor:_,startingWidth:z}));pack.rivers.push({i:k,source:b,mouth:v,discharge:T,length:S,width:A,widthFactor:_,sourceWidth:z,parent:w,cells:y})}},c=()=>{for(const f of pack.cells.i){if(n.h[f]<35||!n.fl[f])continue;const p=n.c[f].filter(b=>n.h[b]>n.h[f]),y=p.reduce((b,v)=>b+n.fl[v],0)/p.length;if(!y)continue;const k=Math.floor(n.fl[f]/y);k&&(n.h[f]-=Math.min(k,5))}},d=()=>{for(const m of n.i){if(!n.conf[m])continue;const f=n.c[m].filter(p=>n.r[p]&&g[p]>g[m]).map(p=>n.fl[p]).sort((p,y)=>y-p);n.conf[m]=f.reduce((p,y,k)=>k?p+y:p,0)}};n.fl=new Uint16Array(n.i.length),n.r=new Uint16Array(n.i.length),n.conf=new Uint8Array(n.i.length);let r=1;const g=this.alterHeights();Lakes.detectCloseLakes(g),this.resolveDepressions(g),h(),l(),d(),Lakes.cleanupLakeData(),a&&(n.h=Uint8Array.from(g),c()),TIME&&console.timeEnd("generateRivers")}alterHeights(){const{h:a,c:n,t}=pack.cells;return Array.from(a).map((i,o)=>i<20||t[o]<1?i:i+t[o]/100+Ha(n[o].map(s=>t[s]))/1e4)}resolveDepressions(a){const{cells:n,features:t}=pack,i=+document.getElementById("resolveDepressionsStepsOutput")?.value,o=i*.85,s=i*.75,h=g=>t[n.f[g]].height||a[g],u=t.filter(g=>g.type==="lake"),l=n.i.filter(g=>a[g]>=20&&!n.b[g]);l.sort((g,m)=>a[g]-a[m]);const c=[];let d=1/0,r=null;for(let g=0;d&&g5&&ai(c)>0){a=this.alterHeights(),d=c[0];break}if(d=0,ga[p]));if(!(f>=100||m.height>f)){if(g>s){m.shoreline.forEach(p=>{a[p]=n.h[p]}),m.height=Ba(m.shoreline.map(p=>a[p]))-1,m.closed=!0;continue}d++,m.height=f+.2}}for(const m of l){const f=Ba(n.c[m].map(p=>h(p)));f>=100||a[m]>f||(d++,a[m]=f+.1)}r!==null&&c.push(d-r),r=d}d&&WARN&&console.warn(`Unresolved depressions: ${d}. Edit heightmap to fix`)}addMeandering(a,n=null,t=.5){const{fl:i,h:o}=pack.cells,s=[],h=a.length-1,u=this.getRiverPoints(a,n);let l=o[a[0]]<20?1:10;for(let c=0;c<=h;c++,l++){const d=a[c],r=c===h,[g,m]=u[c];if(s.push([g,m,i[d]]),r)break;const f=a[c+1],[p,y]=u[c+1];if(f===-1){s.push([p,y,i[d]]);break}const k=(p-g)**2+(y-m)**2;if(k<=25&&a.length>=6)continue;const b=t+1/l+Math.max(t-l/100,0),v=Math.atan2(y-m,p-g),w=Math.sin(v)*b,_=Math.cos(v)*b;if(l<20&&(k>64||k>36&&a.length<5)){const M=(g*2+p)/3+-w,T=(m*2+y)/3+_,S=(g+p*2)/3+w/2,z=(m+y*2)/3-_/2;s.push([M,T,0],[S,z,0])}else if(k>25||a.length<6){const M=(g+p)/2+-w,T=(m+y)/2+_;s.push([M,T,0])}}return s}getRiverPoints(a,n){if(n)return n;const{p:t}=pack.cells;return a.map((i,o)=>i===-1?this.getBorderPoint(a[o-1]):t[i])}getBorderPoint(a){const[n,t]=pack.cells.p[a],i=Math.min(t,graphHeight-t,n,graphWidth-n);return i===t?[n,0]:i===graphHeight-t?[n,graphHeight]:i===n?[0,t]:[graphWidth,t]}getOffset({flux:a,pointIndex:n,widthFactor:t,startingWidth:i}){if(n===0)return i;const o=Math.min(a**.7/this.FLUX_FACTOR,this.MAX_FLUX_WIDTH),s=n*this.LENGTH_STEP_WIDTH+(this.LENGTH_PROGRESSION[n]||this.LENGTH_PROGRESSION.at(-1));return t*(s+o)+i}getSourceWidth(a){return N(Math.min(a**.9/this.FLUX_FACTOR,this.MAX_FLUX_WIDTH),2)}getRiverPath(a,n,t){this.lineGen.curve(Cl.alpha(.1));const i=[],o=[];let s=0;for(let l=0;ls&&(s=m);const y=this.getOffset({flux:s,pointIndex:l,widthFactor:n,startingWidth:t}),k=Math.atan2(d-p,c-f),b=Math.sin(k)*y,v=Math.cos(k)*y;i.push([r-b,g+v]),o.push([r+b,g-v])}const h=this.lineGen(o.reverse());let u=this.lineGen(i)||"";return u=u.substring(u.indexOf("C")),ze(h+u,1)}specify(){const a=pack.rivers;if(a.length)for(const n of a)n.basin=this.getBasin(n.i),n.name=this.getName(n.mouth),n.type=this.getType(n)}getName(a){return Names.getCulture(pack.cells.culture[a])}getType({i:a,length:n,parent:t}){if(this.smallLength===null){const s=Math.ceil(pack.rivers.length*.15);this.smallLength=pack.rivers.map(h=>h.length||0).sort((h,u)=>h-u)[s]}const i=nt+(o?Math.hypot(i[0]-s[o-1][0],i[1]-s[o-1][1]):0),0);return N(n,2)}getWidth(a){return N((a/1.5)**1.8,2)}remove(a){const n=pack.cells,t=pack.rivers.filter(i=>i.i===a||i.parent===a||i.basin===a).map(i=>i.i);t.forEach(i=>{rivers.select(`#river${i}`).remove()}),n.r.forEach((i,o)=>{!i||!t.includes(i)||(n.r[o]=0,n.fl[o]=grid.cells.prec[n.g[o]],n.conf[o]=0)}),pack.rivers=pack.rivers.filter(i=>!t.includes(i.i))}getBasin(a){const n=pack.rivers.find(t=>t.i===a)?.parent;return!n||a===n?a:this.getBasin(n)}getNextId(a){return a.length?Math.max(...a.map(n=>n.i))+1:1}}window.Rivers=new Ou;class qu{shift(){const{cells:a,features:n,burgs:t}=pack,i=grid.cells.temp,o={};for(const h of t){if(!h.i||h.lock)continue;delete h.port;const u=h.cell,l=a.haven[u],c=a.harbor[u],d=a.f[l];if(!d)continue;const r=n[d].cells>1,g=c&&h.capital||c===1,m=i[a.g[u]]<=0;r&&g&&!m&&(o[d]||(o[d]=[]),o[d].push(h))}const s=(h,u)=>{const{cells:l,vertices:c}=pack,[d,r]=l.p[h],g=l.v[h].filter(_=>c.c[_].some(M=>M===u)),[m,f]=c.p[g[0]],[p,y]=c.p[g[1]],k=(m+p)/2,b=(f+y)/2,v=N(d+.95*(k-d),2),w=N(r+.95*(b-r),2);return[v,w]};Object.entries(o).forEach(([h,u])=>{u.length<2||u.forEach(l=>{l.port=h;const c=a.haven[l.cell],[d,r]=s(l.cell,c);l.x=d,l.y=r})});for(const h of t){if(!h.i||h.lock||h.port||!a.r[h.cell])continue;const u=h.cell,l=Math.min(a.fl[u]/150,1);h.x=u%2?N(h.x+l,2):N(h.x-l,2),h.y=a.r[u]%2?N(h.y+l,2):N(h.y-l,2)}}generate(){TIME&&console.time("generateBurgs");const{cells:a}=pack;let n=[0];a.burg=new Uint16Array(a.i.length);const t=a.i.filter(l=>a.s[l]>0&&a.culture[l]);if(!t.length)return ERROR&&console.error("There is no populated cells with culture assigned. Cannot generate states"),n;let i=ue();const o=()=>{const l=m=>m*(.5+Math.random()*.5),c=new Int16Array(a.s.map(l)),d=t.sort((m,f)=>c[f]-c[m]),r=h();let g=(graphWidth+graphHeight)/2/r;for(let m=0;n.length<=r;m++){const f=d[m],[p,y]=a.p[f];i.find(p,y,g)===void 0&&(n.push({cell:f,x:p,y}),i.add([p,y])),m===d.length-1&&(WARN&&console.warn("Cannot place capitals with current spacing. Trying again with reduced spacing"),i=ue(),m=-1,n=[0],g/=1.2)}n.forEach((m,f)=>{f&&(m.i=f,m.state=f,m.culture=a.culture[m.cell],m.name=Names.getCultureShort(m.culture),m.feature=a.f[m.cell],m.capital=1,a.burg[m.cell]=f)})},s=()=>{const l=m=>m*Qa(1,3,0,20,3),c=new Int16Array(a.s.map(l)),d=t.sort((m,f)=>c[f]-c[m]),r=u();let g=(graphWidth+graphHeight)/150/(r**.7/66);for(let m=0;m1;){for(let f=0;m60)return"Highland";if(t.r[a]&&t.fl[a]>=100)return"River";const s=t.biome[a],h=t.pop[a];if(!t.burg[a]||h<=5){if(h<5&&[1,2,3,4].includes(s))return"Nomadic";if(s>4&&s<10)return"Hunting"}return"Generic"}definePopulation(a){const n=a.cell;let t=pack.cells.s[n]/5;a.capital&&(t*=1.5);const i=Routes.getConnectivityRate(n);i&&(t*=i),t*=Qa(1,1,.25,4,5),t+=(a.i%100-n%100)/1e3,a.population=N(Math.max(t,.01),3)}defineEmblem(a){a.type=this.getType(a.cell,a.port);const n=pack.states[a.state],t=n.coa;let i=.25;a.capital?i+=.1:a.port&&(i-=.1),a.culture!==n.culture&&(i-=.25);const o=a.capital&&B(.2)?"Capital":a.type==="Generic"?"City":a.type;a.coa=COA.generate(t,i,null,o),a.coa.shield=COA.getShield(a.culture,a.state)}defineFeatures(a){const n=a.population;a.citadel=Number(a.capital||n>50&&B(.75)||n>15&&B(.5)||B(.1)),a.plaza=Number(Routes.isCrossroad(a.cell)||Routes.hasRoad(a.cell)&&B(.7)||n>20||n>10&&B(.8)),a.walls=Number(a.capital||n>30||n>20&&B(.75)||n>10&&B(.5)||B(.1)),a.shanty=Number(n>60||n>40&&B(.75)||n>20&&a.walls&&B(.4));const t=pack.cells.religion[a.cell],i=pack.states[a.state].form==="Theocracy";a.temple=Number(t&&i&&B(.5)||n>50||n>35&&B(.75)||n>20&&B(.5))}getDefaultGroups(){return[{name:"capital",active:!0,order:9,features:{capital:!0},preview:"watabou-city"},{name:"city",active:!0,order:8,percentile:90,min:5,preview:"watabou-city"},{name:"fort",active:!0,features:{citadel:!0,walls:!1,plaza:!1,port:!1},order:6,max:1},{name:"monastery",active:!0,features:{temple:!0,walls:!1,plaza:!1,port:!1},order:5,max:.8},{name:"caravanserai",active:!0,features:{port:!1,plaza:!0},order:4,max:.8,biomes:[1,2,3]},{name:"trading_post",active:!0,order:3,features:{plaza:!0},max:.8,biomes:[5,6,7,8,9,10,11,12]},{name:"village",active:!0,order:2,min:.1,max:2,preview:"watabou-village"},{name:"hamlet",active:!0,order:1,features:{plaza:!1},max:.1,preview:"watabou-village"},{name:"town",active:!0,order:7,isDefault:!0,preview:"watabou-city"}]}defineGroup(a,n){if(a.lock&&a.group&&options.burgs.groups.find(o=>o.name===a.group))return;const t=options.burgs.groups.find(i=>i.isDefault);if(!t){ERROR&&console.error("No default group defined");return}a.group=t.name;for(const i of options.burgs.groups)if(i.active&&!(i.min&&!(a.population>=i.min))&&!(i.max&&!(a.population<=i.max))&&!(i.features&&!Object.entries(i.features).every(([s,h])=>!!a[s]===h))&&!(i.biomes&&!i.biomes.includes(pack.cells.biome[a.cell]))&&!(i.percentile&&!(n.indexOf(a.population)>=Math.floor(n.length*i.percentile/100)))){a.group=i.name;return}}specify(){TIME&&console.time("specifyBurgs"),pack.burgs.forEach(n=>{!n.i||n.removed||n.lock||(this.definePopulation(n),this.defineEmblem(n),this.defineFeatures(n))});const a=pack.burgs.filter(n=>n.i&&!n.removed).map(n=>n.population).sort((n,t)=>n-t);pack.burgs.forEach(n=>{!n.i||n.removed||this.defineGroup(n,a)}),TIME&&console.timeEnd("specifyBurgs")}createWatabouCityLinks(a){const n=pack.cells,{i:t,name:i,population:o,cell:s}=a,h=a.MFCG||seed+String(a.i).padStart(4,"0"),u=2.13*(o*populationRate/urbanDensity)**.385,l=ma(Math.ceil(u),6,100),c=N(o*populationRate*urbanization),d=n.r[s]?1:0,r=+(parseInt(a.port,10)>0),g=(()=>{if(!r||!n.haven[s])return null;const[z,A]=n.p[s],[x,C]=n.p[n.haven[s]],E=Math.atan2(C-A,x-z)*180/Math.PI;return E<=0?N(ee(Math.abs(E),0,180),2):N(2-ee(E,0,180),2)})(),f=+(d?[1,2,3,4,5,6,7,8]:[5,6,7,8]).includes(n.biome[s]),p=+a.citadel,y=+(p&&ba(2)(t)),k=Routes.isCrossroad(s),b=+a.walls,v=+a.plaza,w=+a.temple,_=+a.shanty,M="natural",T=new URL("https://watabou.github.io/city-generator/");T.search=new URLSearchParams({name:i||"",population:c.toString(),size:l.toString(),seed:h,river:d.toString(),coast:r.toString(),farms:f.toString(),citadel:p.toString(),urban_castle:y.toString(),hub:k.toString(),plaza:v.toString(),temple:w.toString(),walls:b.toString(),shantytown:_.toString(),gates:"-1",style:M}).toString(),g&&T.searchParams.append("sea",g.toString());const S=T.toString();return{link:S,preview:`${S}&preview=1`}}createWatabouVillageLinks(a){const{cells:n,features:t}=pack,{i,population:o,cell:s}=a,h=seed+String(i).padStart(4,"0"),u=N(o*populationRate*urbanization),l=[];n.r[s]&&n.haven[s]?l.push("estuary"):n.haven[s]&&t[n.f[s]].cells===1?l.push("island,district"):a.port?l.push("coast"):n.conf[s]?l.push("confluence"):n.r[s]?l.push("river"):u<200&&ba(4)(s)&&l.push("pond");const c=Routes.getConnectivityRate(s);l.push(c>1?"highway":c===1?"dead end":"isolated");const d=n.biome[s];(n.r[s]?[1,2,3,4,5,6,7,8]:[5,6,7,8]).includes(d)?ba(6)(s)&&l.push("farmland"):l.push("uncultivated");const g=grid.cells.temp[n.g[s]];(g<=0||g>28||g>25&&ba(3)(s))&&l.push("no orchards"),a.plaza||l.push("no square"),a.walls&&l.push("palisade"),u<100?l.push("sparse"):u>300&&l.push("dense");const m=u>1500?1600:u>1e3?1400:u>500?1e3:u>200?800:u>100?600:400,f=N(m/2.05),p=[1,2].includes(d)?"sand":g<=5||[9,10,11].includes(d)?"snow":"default",y=new URL("https://watabou.github.io/village-generator/");y.search=new URLSearchParams({pop:u.toString(),name:a.name||"",seed:h,width:m.toString(),height:f.toString(),style:p,tags:l.join(",")}).toString();const k=y.toString();return{link:k,preview:`${k}&preview=1`}}createWatabouDwellingLinks(a){const n=seed+String(a.i).padStart(4,"0"),t=N(a.population*populationRate*urbanization),i=t>200?["large","tall"]:t>100?["large"]:t>50?["tall"]:t>20?["low"]:["small"],o=new URL("https://watabou.github.io/dwellings/");o.search=new URLSearchParams({pop:t.toString(),name:"",seed:n,tags:i.join(",")}).toString();const s=o.toString();return{link:s,preview:`${s}&preview=1`}}getPreview(a){const n={"watabou-city":i=>this.createWatabouCityLinks(i),"watabou-village":i=>this.createWatabouVillageLinks(i),"watabou-dwelling":i=>this.createWatabouDwellingLinks(i)};if(a.link)return{link:a.link,preview:a.link};const t=options.burgs.groups.find(i=>i.name===a.group);return!t?.preview||!n[t.preview]?{link:null,preview:null}:n[t.preview](a)}add([a,n]){const{cells:t}=pack,i=pack.burgs.length,o=window.findCell(a,n,void 0,pack),s=t.culture[o],h=Names.getCulture(s),u=t.state[o],l=t.f[o],c={cell:o,x:a,y:n,i,state:u,culture:s,name:h,feature:l,capital:0,port:"0"};this.definePopulation(c),this.defineEmblem(c),this.defineFeatures(c);const d=pack.burgs.filter(g=>g.i&&!g.removed).map(g=>g.population).sort((g,m)=>g-m);this.defineGroup(c,d),pack.burgs.push(c),t.burg[o]=i;const r=Routes.connect(o);return r&&layerIsOn("toggleRoutes")&&drawRoute(r),drawBurgIcon(c),drawBurgLabel(c),i}changeGroup(a,n){if(n)a.group=n;else{const i=pack.burgs.filter(o=>o.i&&!o.removed).map(o=>o.population).sort((o,s)=>o-s);this.defineGroup(a,i)}drawBurgIcon(a),drawBurgLabel(a)}remove(a){const n=pack.burgs[a];if(!n)return tip(`Burg ${a} not found`,!1,"error");pack.cells.burg[n.cell]=0,n.removed=!0;const t=notes.findIndex(i=>i.id===`burg${a}`);t!==-1&¬es.splice(t,1),n.coa&&(j(`burgCOA${a}`)?.remove(),emblems.select(`#burgEmblems > use[data-i='${a}']`).remove(),delete n.coa),removeBurgIcon(n.i),removeBurgLabel(n.i)}}window.Burgs=new qu;class ju{MIN_LAND_HEIGHT=20;getDefault(){const a=["Marine","Hot desert","Cold desert","Savanna","Grassland","Tropical seasonal forest","Temperate deciduous forest","Tropical rainforest","Temperate rainforest","Taiga","Tundra","Glacier","Wetland"],n=["#466eab","#fbe79f","#b5b887","#d2d082","#c8d68f","#b6d95d","#29bc56","#7dcb35","#409c43","#4b6b32","#96784b","#d5e7eb","#0b9131"],t=[0,4,10,22,30,50,100,80,90,12,4,0,12],i=[0,3,2,120,120,120,120,150,150,100,5,0,250],o=[{},{dune:3,cactus:6,deadTree:1},{dune:9,deadTree:1},{acacia:1,grass:9},{grass:1},{acacia:8,palm:1},{deciduous:1},{acacia:5,palm:3,deciduous:1,swamp:1},{deciduous:6,swamp:1},{conifer:1},{grass:1},{},{swamp:1}],s=[10,200,150,60,50,70,70,80,90,200,1e3,5e3,150],h=[new Uint8Array([1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,10]),new Uint8Array([3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,9,9,9,9,10,10,10]),new Uint8Array([5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,9,9,9,9,9,10,10,10]),new Uint8Array([5,6,6,6,6,6,6,8,8,8,8,8,8,8,8,8,8,9,9,9,9,9,9,10,10,10]),new Uint8Array([7,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,9,9,9,9,9,9,9,10,10])],u=[];for(let l=0;l{let c=h[o[l]];n[l]&&(c+=Math.max(a[l]/10,2));const d=i[l].filter(r=>t[r]>=this.MIN_LAND_HEIGHT).map(r=>h[o[r]]).concat([c]);return N(4+Ha(d))};for(let l=0;l=25&&!i&&a<8)return 1;if(this.isWetland(a,n,t))return 12;const o=Math.min(a/5|0,4),s=Math.min(Math.max(20-n,0),25);return biomesData.biomesMatrix[o][s]}isWetland(a,n,t){return n<=-2?!1:a>40&&t<25||a>24&&t>24&&t<60}}window.Biomes=new ju;class Uu{cells;getRandomShield(){const a=de(COA.shields.types);return de(COA.shields[a])}getDefault(a=0){const n=pack.cells,t=n.s,i=Vn(t),o=n.t,s=n.h,h=grid.cells.temp,u=r=>Math.ceil(t[r]/i*3),l=(r,g)=>{const m=Math.abs(h[n.g[r]]-g);return m?m+1:1},c=(r,g,m=4)=>g.includes(n.biome[r])?1:m,d=(r,g=4)=>n.haven[r]&&pack.features[n.f[n.haven[r]]].type!=="lake"?1:g;if(culturesSet.value==="european")return[{name:"Shwazen",base:0,odd:1,sort:r=>u(r)/l(r,10)/c(r,[6,8]),shield:"swiss"},{name:"Angshire",base:1,odd:1,sort:r=>u(r)/l(r,10)/d(r),shield:"wedged"},{name:"Luari",base:2,odd:1,sort:r=>u(r)/l(r,12)/c(r,[6,8]),shield:"french"},{name:"Tallian",base:3,odd:1,sort:r=>u(r)/l(r,15),shield:"horsehead"},{name:"Astellian",base:4,odd:1,sort:r=>u(r)/l(r,16),shield:"spanish"},{name:"Slovan",base:5,odd:1,sort:r=>u(r)/l(r,6)*o[r],shield:"polish"},{name:"Norse",base:6,odd:1,sort:r=>u(r)/l(r,5),shield:"heater"},{name:"Elladan",base:7,odd:1,sort:r=>u(r)/l(r,18)*s[r],shield:"boeotian"},{name:"Romian",base:8,odd:.2,sort:r=>u(r)/l(r,15)/o[r],shield:"roman"},{name:"Soumi",base:9,odd:1,sort:r=>u(r)/l(r,5)/c(r,[9])*o[r],shield:"pavise"},{name:"Portuzian",base:13,odd:1,sort:r=>u(r)/l(r,17)/d(r),shield:"renaissance"},{name:"Vengrian",base:15,odd:1,sort:r=>u(r)/l(r,11)/c(r,[4])*o[r],shield:"horsehead2"},{name:"Turchian",base:16,odd:.05,sort:r=>u(r)/l(r,14),shield:"round"},{name:"Euskati",base:20,odd:.05,sort:r=>u(r)/l(r,15)*s[r],shield:"oldFrench"},{name:"Keltan",base:22,odd:.05,sort:r=>u(r)/l(r,11)/c(r,[6,8])*o[r],shield:"oval"}];if(culturesSet.value==="oriental")return[{name:"Koryo",base:10,odd:1,sort:r=>u(r)/l(r,12)/o[r],shield:"round"},{name:"Hantzu",base:11,odd:1,sort:r=>u(r)/l(r,13),shield:"banner"},{name:"Yamoto",base:12,odd:1,sort:r=>u(r)/l(r,15)/o[r],shield:"round"},{name:"Turchian",base:16,odd:1,sort:r=>u(r)/l(r,12),shield:"round"},{name:"Berberan",base:17,odd:.2,sort:r=>u(r)/l(r,19)/c(r,[1,2,3],7)*o[r],shield:"oval"},{name:"Eurabic",base:18,odd:1,sort:r=>u(r)/l(r,26)/c(r,[1,2],7)*o[r],shield:"oval"},{name:"Efratic",base:23,odd:.1,sort:r=>u(r)/l(r,22)*o[r],shield:"round"},{name:"Tehrani",base:24,odd:1,sort:r=>u(r)/l(r,18)*s[r],shield:"round"},{name:"Maui",base:25,odd:.2,sort:r=>u(r)/l(r,24)/d(r)/o[r],shield:"vesicaPiscis"},{name:"Carnatic",base:26,odd:.5,sort:r=>u(r)/l(r,26),shield:"round"},{name:"Vietic",base:29,odd:.8,sort:r=>u(r)/l(r,25)/c(r,[7],7)/o[r],shield:"banner"},{name:"Guantzu",base:30,odd:.5,sort:r=>u(r)/l(r,17),shield:"banner"},{name:"Ulus",base:31,odd:1,sort:r=>u(r)/l(r,5)/c(r,[2,4,10],7)*o[r],shield:"banner"}];if(culturesSet.value==="english"){const r=()=>Names.getBase(1,5,9,"");return[{name:r(),base:1,odd:1,shield:"heater"},{name:r(),base:1,odd:1,shield:"wedged"},{name:r(),base:1,odd:1,shield:"swiss"},{name:r(),base:1,odd:1,shield:"oldFrench"},{name:r(),base:1,odd:1,shield:"swiss"},{name:r(),base:1,odd:1,shield:"spanish"},{name:r(),base:1,odd:1,shield:"hessen"},{name:r(),base:1,odd:1,shield:"fantasy5"},{name:r(),base:1,odd:1,shield:"fantasy4"},{name:r(),base:1,odd:1,shield:"fantasy1"}]}return culturesSet.value==="antique"?[{name:"Roman",base:8,odd:1,sort:r=>u(r)/l(r,14)/o[r],shield:"roman"},{name:"Roman",base:8,odd:1,sort:r=>u(r)/l(r,15)/d(r),shield:"roman"},{name:"Roman",base:8,odd:1,sort:r=>u(r)/l(r,16)/d(r),shield:"roman"},{name:"Roman",base:8,odd:1,sort:r=>u(r)/l(r,17)/o[r],shield:"roman"},{name:"Hellenic",base:7,odd:1,sort:r=>u(r)/l(r,18)/d(r)*s[r],shield:"boeotian"},{name:"Hellenic",base:7,odd:1,sort:r=>u(r)/l(r,19)/d(r)*s[r],shield:"boeotian"},{name:"Macedonian",base:7,odd:.5,sort:r=>u(r)/l(r,12)*s[r],shield:"round"},{name:"Celtic",base:22,odd:1,sort:r=>u(r)/l(r,11)**.5/c(r,[6,8]),shield:"round"},{name:"Germanic",base:0,odd:1,sort:r=>u(r)/l(r,10)**.5/c(r,[6,8]),shield:"round"},{name:"Persian",base:24,odd:.8,sort:r=>u(r)/l(r,18)*s[r],shield:"oval"},{name:"Scythian",base:24,odd:.5,sort:r=>u(r)/l(r,11)**.5/c(r,[4]),shield:"round"},{name:"Cantabrian",base:20,odd:.5,sort:r=>u(r)/l(r,16)*s[r],shield:"oval"},{name:"Estian",base:9,odd:.2,sort:r=>u(r)/l(r,5)*o[r],shield:"pavise"},{name:"Carthaginian",base:42,odd:.3,sort:r=>u(r)/l(r,20)/d(r),shield:"oval"},{name:"Hebrew",base:42,odd:.2,sort:r=>u(r)/l(r,19)*d(r),shield:"oval"},{name:"Mesopotamian",base:23,odd:.2,sort:r=>u(r)/l(r,22)/c(r,[1,2,3]),shield:"oval"}]:culturesSet.value==="highFantasy"?[{name:"Quenian (Elfish)",base:33,odd:1,sort:r=>u(r)/c(r,[6,7,8,9],10)*o[r],shield:"gondor"},{name:"Eldar (Elfish)",base:33,odd:1,sort:r=>u(r)/c(r,[6,7,8,9],10)*o[r],shield:"noldor"},{name:"Trow (Dark Elfish)",base:34,odd:.9,sort:r=>u(r)/c(r,[7,8,9,12],10)*o[r],shield:"hessen"},{name:"Lothian (Dark Elfish)",base:34,odd:.3,sort:r=>u(r)/c(r,[7,8,9,12],10)*o[r],shield:"wedged"},{name:"Dunirr (Dwarven)",base:35,odd:1,sort:r=>u(r)+s[r],shield:"ironHills"},{name:"Khazadur (Dwarven)",base:35,odd:1,sort:r=>u(r)+s[r],shield:"erebor"},{name:"Kobold (Goblin)",base:36,odd:1,sort:r=>o[r]-t[r],shield:"moriaOrc"},{name:"Uruk (Orkish)",base:37,odd:1,sort:r=>s[r]*o[r],shield:"urukHai"},{name:"Ugluk (Orkish)",base:37,odd:.5,sort:r=>s[r]*o[r]/c(r,[1,2,10,11]),shield:"moriaOrc"},{name:"Yotunn (Giants)",base:38,odd:.7,sort:r=>l(r,-10),shield:"pavise"},{name:"Rake (Drakonic)",base:39,odd:.7,sort:r=>-t[r],shield:"fantasy2"},{name:"Arago (Arachnid)",base:40,odd:.7,sort:r=>o[r]-t[r],shield:"horsehead2"},{name:"Aj'Snaga (Serpents)",base:41,odd:.7,sort:r=>u(r)/c(r,[12],10),shield:"fantasy1"},{name:"Anor (Human)",base:32,odd:1,sort:r=>u(r)/l(r,10),shield:"fantasy5"},{name:"Dail (Human)",base:32,odd:1,sort:r=>u(r)/l(r,13),shield:"roman"},{name:"Rohand (Human)",base:16,odd:1,sort:r=>u(r)/l(r,16),shield:"round"},{name:"Dulandir (Human)",base:31,odd:1,sort:r=>u(r)/l(r,5)/c(r,[2,4,10],7)*o[r],shield:"easterling"}]:culturesSet.value==="darkFantasy"?[{name:"Angshire",base:1,odd:1,sort:r=>u(r)/l(r,10)/d(r),shield:"heater"},{name:"Enlandic",base:1,odd:1,sort:r=>u(r)/l(r,12),shield:"heater"},{name:"Westen",base:1,odd:1,sort:r=>u(r)/l(r,10),shield:"heater"},{name:"Nortumbic",base:1,odd:1,sort:r=>u(r)/l(r,7),shield:"heater"},{name:"Mercian",base:1,odd:1,sort:r=>u(r)/l(r,9),shield:"heater"},{name:"Kentian",base:1,odd:1,sort:r=>u(r)/l(r,12),shield:"heater"},{name:"Norse",base:6,odd:.7,sort:r=>u(r)/l(r,5)/d(r),shield:"oldFrench"},{name:"Schwarzen",base:0,odd:.3,sort:r=>u(r)/l(r,10)/c(r,[6,8]),shield:"gonfalon"},{name:"Luarian",base:2,odd:.3,sort:r=>u(r)/l(r,12)/c(r,[6,8]),shield:"oldFrench"},{name:"Hetallian",base:3,odd:.3,sort:r=>u(r)/l(r,15),shield:"oval"},{name:"Astellian",base:4,odd:.3,sort:r=>u(r)/l(r,16),shield:"spanish"},{name:"Kiswaili",base:28,odd:.05,sort:r=>u(r)/l(r,29)/c(r,[1,3,5,7]),shield:"vesicaPiscis"},{name:"Yoruba",base:21,odd:.05,sort:r=>u(r)/l(r,15)/c(r,[5,7]),shield:"vesicaPiscis"},{name:"Koryo",base:10,odd:.05,sort:r=>u(r)/l(r,12)/o[r],shield:"round"},{name:"Hantzu",base:11,odd:.05,sort:r=>u(r)/l(r,13),shield:"banner"},{name:"Yamoto",base:12,odd:.05,sort:r=>u(r)/l(r,15)/o[r],shield:"round"},{name:"Guantzu",base:30,odd:.05,sort:r=>u(r)/l(r,17),shield:"banner"},{name:"Ulus",base:31,odd:.05,sort:r=>u(r)/l(r,5)/c(r,[2,4,10],7)*o[r],shield:"banner"},{name:"Turan",base:16,odd:.05,sort:r=>u(r)/l(r,12),shield:"round"},{name:"Berberan",base:17,odd:.05,sort:r=>u(r)/l(r,19)/c(r,[1,2,3],7)*o[r],shield:"round"},{name:"Eurabic",base:18,odd:.05,sort:r=>u(r)/l(r,26)/c(r,[1,2],7)*o[r],shield:"round"},{name:"Slovan",base:5,odd:.05,sort:r=>u(r)/l(r,6)*o[r],shield:"round"},{name:"Keltan",base:22,odd:.1,sort:r=>u(r)/l(r,11)**.5/c(r,[6,8]),shield:"vesicaPiscis"},{name:"Elladan",base:7,odd:.2,sort:r=>u(r)/l(r,18)/d(r)*s[r],shield:"boeotian"},{name:"Romian",base:8,odd:.2,sort:r=>u(r)/l(r,14)/o[r],shield:"roman"},{name:"Eldar",base:33,odd:.5,sort:r=>u(r)/c(r,[6,7,8,9],10)*o[r],shield:"fantasy5"},{name:"Trow",base:34,odd:.8,sort:r=>u(r)/c(r,[7,8,9,12],10)*o[r],shield:"hessen"},{name:"Durinn",base:35,odd:.8,sort:r=>u(r)+s[r],shield:"erebor"},{name:"Kobblin",base:36,odd:.8,sort:r=>o[r]-t[r],shield:"moriaOrc"},{name:"Uruk",base:37,odd:.8,sort:r=>s[r]*o[r]/c(r,[1,2,10,11]),shield:"urukHai"},{name:"Yotunn",base:38,odd:.8,sort:r=>l(r,-10),shield:"pavise"},{name:"Drake",base:39,odd:.9,sort:r=>-t[r],shield:"fantasy2"},{name:"Rakhnid",base:40,odd:.9,sort:r=>o[r]-t[r],shield:"horsehead2"},{name:"Aj'Snaga",base:41,odd:.9,sort:r=>u(r)/c(r,[12],10),shield:"fantasy1"}]:culturesSet.value==="random"?Ra(a).map(()=>{const r=Y(nameBases.length-1);return{name:Names.getBaseShort(r),base:r,odd:1,shield:this.getRandomShield()}}):[{name:"Shwazen",base:0,odd:.7,sort:r=>u(r)/l(r,10)/c(r,[6,8]),shield:"hessen"},{name:"Angshire",base:1,odd:1,sort:r=>u(r)/l(r,10)/d(r),shield:"heater"},{name:"Luari",base:2,odd:.6,sort:r=>u(r)/l(r,12)/c(r,[6,8]),shield:"oldFrench"},{name:"Tallian",base:3,odd:.6,sort:r=>u(r)/l(r,15),shield:"horsehead2"},{name:"Astellian",base:4,odd:.6,sort:r=>u(r)/l(r,16),shield:"spanish"},{name:"Slovan",base:5,odd:.7,sort:r=>u(r)/l(r,6)*o[r],shield:"round"},{name:"Norse",base:6,odd:.7,sort:r=>u(r)/l(r,5),shield:"heater"},{name:"Elladan",base:7,odd:.7,sort:r=>u(r)/l(r,18)*s[r],shield:"boeotian"},{name:"Romian",base:8,odd:.7,sort:r=>u(r)/l(r,15),shield:"roman"},{name:"Soumi",base:9,odd:.3,sort:r=>u(r)/l(r,5)/c(r,[9])*o[r],shield:"pavise"},{name:"Koryo",base:10,odd:.1,sort:r=>u(r)/l(r,12)/o[r],shield:"round"},{name:"Hantzu",base:11,odd:.1,sort:r=>u(r)/l(r,13),shield:"banner"},{name:"Yamoto",base:12,odd:.1,sort:r=>u(r)/l(r,15)/o[r],shield:"round"},{name:"Portuzian",base:13,odd:.4,sort:r=>u(r)/l(r,17)/d(r),shield:"spanish"},{name:"Nawatli",base:14,odd:.1,sort:r=>s[r]/l(r,18)/c(r,[7]),shield:"square"},{name:"Vengrian",base:15,odd:.2,sort:r=>u(r)/l(r,11)/c(r,[4])*o[r],shield:"wedged"},{name:"Turchian",base:16,odd:.2,sort:r=>u(r)/l(r,13),shield:"round"},{name:"Berberan",base:17,odd:.1,sort:r=>u(r)/l(r,19)/c(r,[1,2,3],7)*o[r],shield:"round"},{name:"Eurabic",base:18,odd:.2,sort:r=>u(r)/l(r,26)/c(r,[1,2],7)*o[r],shield:"round"},{name:"Inuk",base:19,odd:.05,sort:r=>l(r,-1)/c(r,[10,11])/d(r),shield:"square"},{name:"Euskati",base:20,odd:.05,sort:r=>u(r)/l(r,15)*s[r],shield:"spanish"},{name:"Yoruba",base:21,odd:.05,sort:r=>u(r)/l(r,15)/c(r,[5,7]),shield:"vesicaPiscis"},{name:"Keltan",base:22,odd:.05,sort:r=>u(r)/l(r,11)/c(r,[6,8])*o[r],shield:"vesicaPiscis"},{name:"Efratic",base:23,odd:.05,sort:r=>u(r)/l(r,22)*o[r],shield:"diamond"},{name:"Tehrani",base:24,odd:.1,sort:r=>u(r)/l(r,18)*s[r],shield:"round"},{name:"Maui",base:25,odd:.05,sort:r=>u(r)/l(r,24)/d(r)/o[r],shield:"round"},{name:"Carnatic",base:26,odd:.05,sort:r=>u(r)/l(r,26),shield:"round"},{name:"Inqan",base:27,odd:.05,sort:r=>s[r]/l(r,13),shield:"square"},{name:"Kiswaili",base:28,odd:.1,sort:r=>u(r)/l(r,29)/c(r,[1,3,5,7]),shield:"vesicaPiscis"},{name:"Vietic",base:29,odd:.1,sort:r=>u(r)/l(r,25)/c(r,[7],7)/o[r],shield:"banner"},{name:"Guantzu",base:30,odd:.1,sort:r=>u(r)/l(r,17),shield:"banner"},{name:"Ulus",base:31,odd:.1,sort:r=>u(r)/l(r,5)/c(r,[2,4,10],7)*o[r],shield:"banner"},{name:"Hebrew",base:42,odd:.2,sort:r=>u(r)/l(r,18)*d(r),shield:"oval"}]}generate(){TIME&&console.time("generateCultures"),this.cells=pack.cells;const a=new Uint16Array(this.cells.i.length),n=+j("culturesInput").value,t=+(j("culturesSet").selectedOptions[0].dataset.max??"0");let i=Math.min(n,t);const o=this.cells.i.filter(f=>this.cells.s[f]);if(o.length + Only ${i} out of ${culturesInput.value} requested cultures will be generated.
+ Please consider changing climate settings in the World Configurator`,$("#alert").dialog({resizable:!1,title:"Extreme climate warning",buttons:{Ok:function(){$(this).dialog("close")}}});else{WARN&&console.warn("There are no populated cells. Cannot generate cultures"),pack.cultures=[{name:"Wildlands",i:0,base:1,shield:"round"}],this.cells.culture=a,alertMessage.innerHTML=`The climate is harsh and people cannot live in this world.
+ No cultures, states and burgs will be created.
+ Please consider changing climate settings in the World Configurator`,$("#alert").dialog({resizable:!1,title:"Extreme climate warning",buttons:{Ok:function(){$(this).dialog("close")}}});return}const h=(f=>{const p=this.getDefault(f),y=[];if(pack.cultures?.forEach(k=>{k.lock&&!k.removed&&y.push(k)}),!y.length){if(f===p.length)return p;if(p.every(k=>k.odd===1))return p.splice(0,f)}for(let k,b,v=0;y.length0;){do b=Y(p.length-1),k=p[b],v++;while(v<200&&!B(k.odd));y.push(k),p.splice(b,1)}return y})(i);pack.cultures=h;const u=ue(),l=Bt(i),c=j("emblemShape").value,d=[],r=f=>{let p=(graphWidth+graphHeight)/2/i;const y=100,k=[...o].sort((w,_)=>f(_)-f(w)),b=Math.floor(k.length/2);let v=0;for(let w=0;w{if(this.cells.h[f]<70&&[1,2,4].includes(this.cells.biome[f]))return"Nomadic";if(this.cells.h[f]>50)return"Highland";const p=pack.features[this.cells.f[this.cells.haven[f]]];return p.type==="lake"&&p.cells>5?"Lake":this.cells.harbor[f]&&p.type!=="lake"&&B(.1)||this.cells.harbor[f]===1&&B(.6)||pack.features[this.cells.f[f]].group==="isle"&&B(.4)?"Naval":this.cells.r[f]&&this.cells.fl[f]>100?"River":this.cells.t[f]>2&&[3,7,8,9,10,12].includes(this.cells.biome[f])?"Hunting":"Generic"},m=f=>{let p=1;return f==="Lake"?p=.8:f==="Naval"?p=1.5:f==="River"?p=.9:f==="Nomadic"?p=1.5:f==="Hunting"?p=.7:f==="Highland"&&(p=1.2),N((Math.random()*j("sizeVariety").valueAsNumber/2+1)*p,1)};h.forEach((f,p)=>{const y=p+1;if(f.lock){d.push(f.code),u.add(f.center);for(const v of this.cells.i)this.cells.culture[v]===f.i&&(a[v]=y);f.i=y;return}const k=f.sort?f.sort:v=>this.cells.s[v],b=r(k);u.add(this.cells.p[b]),f.center=b,f.i=y,delete f.odd,delete f.sort,f.color=l[p],f.type=g(b),f.expansionism=m(f.type),f.origins=[0],f.code=Ue(f.name,d),d.push(f.code),a[b]=y,c==="random"&&(f.shield=this.getRandomShield())}),this.cells.culture=a,h.unshift({name:"Wildlands",i:0,base:1,origins:[null],shield:"round"}),nameBases.length||(ERROR&&console.error("Name base is empty, default nameBases will be applied"),nameBases=Names.getNameBases()),h.forEach(f=>{f.base=f.base%nameBases.length}),TIME&&console.timeEnd("generateCultures")}add(a){const n=this.getDefault();let t,i,o;pack.cultures.lengthc.code)),h=pack.cultures.length,u=ge(),l=document.getElementById("emblemShape").value;pack.cultures.push({name:o,color:u,base:i,center:a,i:h,expansionism:1,type:"Generic",cells:0,area:0,rural:0,urban:0,origins:[pack.cells.culture[a]],code:s,shield:l==="random"?this.getRandomShield():""})}expand(){TIME&&console.time("expandCultures");const{cells:a,cultures:n}=pack,t=new FlatQueue,i=[],o=j("neutralRate")?.valueAsNumber||1,s=a.i.length*.6*o,h=n.some(r=>!r.removed&&r.lock);if(h)for(const r of a.i)n[a.culture[r]].lock||(a.culture[r]=0);else a.culture=new Uint16Array(a.i.length);for(const r of n)!r.i||r.removed||r.lock||t.push({cellId:r.center,cultureId:r.i,priority:0},0);const u=(r,g,m)=>a.biome[n[r].center]===g?10:m==="Hunting"?biomesData.cost[g]*5:m==="Nomadic"&&g>4&&g<10?biomesData.cost[g]*10:biomesData.cost[g]*2,l=(r,g,m)=>{const f=pack.features[a.f[r]],p=a.area[r];return m==="Lake"&&f.type==="lake"?10:m==="Naval"&&g<20?p*2:m==="Nomadic"&&g<20?p*50:g<20?p*6:m==="Highland"&&g<44?3e3:m==="Highland"&&g<62?200:m==="Highland"?0:g>=67?200:g>=44?30:0},c=(r,g,m)=>m==="River"?r?0:100:r?ma(a.fl[g]/10,20,100):0,d=(r,g)=>r===1?g==="Naval"||g==="Lake"?0:g==="Nomadic"?60:20:r===2?g==="Naval"||g==="Nomadic"?30:0:r!==-1&&(g==="Naval"||g==="Lake")?100:0;for(;t.length;){const{cellId:r,priority:g,cultureId:m}=t.pop(),{type:f,expansionism:p}=n[m];a.c[r].forEach(y=>{if(h){const z=a.culture[y];if(z&&n[z].lock)return}const k=a.biome[y],b=u(m,k,f),v=k===a.biome[y]?0:20,w=l(y,a.h[y],f),_=c(a.r[y],y,f),M=d(a.t[y],f),T=(b+v+w+_+M)/p,S=g+T;S>s||(!i[y]||S0&&(a.culture[y]=m),i[y]=S,t.push({cellId:y,cultureId:m,priority:S},S))})}TIME&&console.timeEnd("expandCultures")}}window.Cultures=new Uu; diff --git a/mobile_app/assets/www/assets/main-6XGJsgx7.js b/mobile_app/assets/www/assets/main-6XGJsgx7.js new file mode 100644 index 00000000..ebcf3d51 --- /dev/null +++ b/mobile_app/assets/www/assets/main-6XGJsgx7.js @@ -0,0 +1,7 @@ +import"./modulepreload-polyfill-B5Qt9EMX.js";String.prototype.replaceAll===void 0&&(String.prototype.replaceAll=function(e,a){return Object.prototype.toString.call(e).toLowerCase()==="[object regexp]"?this.replace(e,a):this.replace(new RegExp(e,"g"),a)});Array.prototype.flat===void 0&&(Array.prototype.flat=function(e){return this.reduce((a,n)=>Array.isArray(n)?a.concat(n.flat(e)):a.concat(n),[])});Array.prototype.at===void 0&&(Array.prototype.at=function(e){if(e<0&&(e+=this.length),!(e<0||e>=this.length))return this[e]});ReadableStream.prototype[Symbol.asyncIterator]===void 0&&(ReadableStream.prototype[Symbol.asyncIterator]=async function*(){const e=this.getReader();try{for(;;){const{done:a,value:n}=await e.read();if(a)return;yield n}}finally{e.releaseLock()}});const N=(e,a=0)=>{const n=10**a;return Math.round(e*n)/n},ma=(e,a,n)=>Math.min(Math.max(e,a),n),V=e=>ma(e,0,100),ee=(e,a,n)=>ma((e-a)/(n-a),0,1),Ut=(e,a,n)=>e+(a-e)*n,Ea=e=>e[e.length-1],jn=e=>[...new Set(e)],Vt=e=>{const a=h=>h,n=h=>h.map(a),t=h=>Object.fromEntries(Object.entries(h).map(([u,l])=>[u,i(l)])),i=h=>h instanceof Object?(s.get(h.constructor)||a)(h):h,o=h=>[...h.entries()].map(([u,l])=>[u,i(l)]),s=new Map([[Int8Array,n],[Uint8Array,n],[Uint8ClampedArray,n],[Int16Array,n],[Uint16Array,n],[Int32Array,n],[Uint32Array,n],[Float32Array,n],[Float64Array,n],[BigInt64Array,n],[BigUint64Array,n],[Map,h=>new Map(o(h))],[WeakMap,h=>new WeakMap(o(h))],[Array,h=>h.map(i)],[Set,h=>[...h.values()].map(i)],[Date,h=>new Date(h.getTime())],[Object,t]]);return i(e)},Un=e=>(console.assert(Number.isInteger(e)&&e>=0&&e<=ea.UINT32_MAX,`Array maxValue must be an integer between 0 and ${ea.UINT32_MAX}, got ${e}`),e<=ea.UINT8_MAX?Uint8Array:e<=ea.UINT16_MAX?Uint16Array:(e<=ea.UINT32_MAX,Uint32Array)),pe=({maxValue:e,length:a,from:n})=>{const t=Un(e);return n?t.from(n):new t(a)},ea={INT8_MAX:127,UINT8_MAX:255,UINT16_MAX:65535,UINT32_MAX:4294967295};function Ft(e,a){return e==null||a==null?NaN:ea?1:e>=a?0:NaN}const Yt=Math.sqrt(50),$t=Math.sqrt(10),Wt=Math.sqrt(2);function ne(e,a,n){const t=(a-e)/Math.max(0,n),i=Math.floor(Math.log10(t)),o=t/Math.pow(10,i),s=o>=Yt?10:o>=$t?5:o>=Wt?2:1;let h,u,l;return i<0?(l=Math.pow(10,-i)/s,h=Math.round(e*l),u=Math.round(a*l),h/la&&--u,l=-l):(l=Math.pow(10,i)*s,h=Math.round(e/l),u=Math.round(a/l),h*la&&--u),u0))return[];if(e===a)return[e];const t=a=i))return[];const h=o-i+1,u=new Array(h);if(t)if(s<0)for(let l=0;l=t)&&(n=t);return n}function Ba(e,a){let n;for(const t of e)t!=null&&(n>t||n===void 0&&t>=t)&&(n=t);return n}function Jt(e,a){let n,t=-1,i=-1;if(a===void 0)for(const o of e)++i,o!=null&&(n>o||n===void 0&&o>=o)&&(n=o,t=i);else for(let o of e)(o=a(o,++i,e))!=null&&(n>o||n===void 0&&o>=o)&&(n=o,t=i);return t}function Ha(e,a){let n=0,t=0;for(let i of e)i!=null&&(i=+i)>=i&&(++n,t+=i);if(n)return t/n}function Ra(e,a,n){e=+e,a=+a,n=(i=arguments.length)<2?(a=e,e=0,1):i<3?1:+n;for(var t=-1,i=Math.max(0,Math.ceil((a-e)/n))|0,o=new Array(i);++t{}};function Fn(){for(var e=0,a=arguments.length,n={},t;e=0&&(t=n.slice(i+1),n=n.slice(0,i)),n&&!a.hasOwnProperty(n))throw new Error("unknown type: "+n);return{type:n,name:t}})}$a.prototype=Fn.prototype={constructor:$a,on:function(e,a){var n=this._,t=ni(e+"",n),i,o=-1,s=t.length;if(arguments.length<2){for(;++o0)for(var n=new Array(i),t=0,i,o;t=0&&(a=e.slice(0,n))!=="xmlns"&&(e=e.slice(n+1)),hn.hasOwnProperty(a)?{space:hn[a],local:e}:e}function ii(e){return function(){var a=this.ownerDocument,n=this.namespaceURI;return n===He&&a.documentElement.namespaceURI===He?a.createElement(e):a.createElementNS(n,e)}}function ri(e){return function(){return this.ownerDocument.createElementNS(e.space,e.local)}}function Yn(e){var a=ye(e);return(a.local?ri:ii)(a)}function oi(){}function Ve(e){return e==null?oi:function(){return this.querySelector(e)}}function si(e){typeof e!="function"&&(e=Ve(e));for(var a=this._groups,n=a.length,t=new Array(n),i=0;i=b&&(b=k+1);!(w=p[b])&&++b=0;)(s=t[i])&&(o&&s.compareDocumentPosition(o)^4&&o.parentNode.insertBefore(s,o),o=s);return this}function Bi(e){e||(e=Ei);function a(d,r){return d&&r?e(d.__data__,r.__data__):!d-!r}for(var n=this._groups,t=n.length,i=new Array(t),o=0;oa?1:e>=a?0:NaN}function Hi(){var e=arguments[0];return arguments[0]=this,e.apply(null,arguments),this}function Ri(){return Array.from(this)}function Li(){for(var e=this._groups,a=0,n=e.length;a1?this.each((a==null?Yi:typeof a=="function"?Wi:$i)(e,a,n??"")):Aa(this.node(),e)}function Aa(e,a){return e.style.getPropertyValue(a)||Jn(e).getComputedStyle(e,null).getPropertyValue(a)}function Qi(e){return function(){delete this[e]}}function Ji(e,a){return function(){this[e]=a}}function Xi(e,a){return function(){var n=a.apply(this,arguments);n==null?delete this[e]:this[e]=n}}function ar(e,a){return arguments.length>1?this.each((a==null?Qi:typeof a=="function"?Xi:Ji)(e,a)):this.node()[e]}function Xn(e){return e.trim().split(/^|\s+/)}function Fe(e){return e.classList||new at(e)}function at(e){this._node=e,this._names=Xn(e.getAttribute("class")||"")}at.prototype={add:function(e){var a=this._names.indexOf(e);a<0&&(this._names.push(e),this._node.setAttribute("class",this._names.join(" ")))},remove:function(e){var a=this._names.indexOf(e);a>=0&&(this._names.splice(a,1),this._node.setAttribute("class",this._names.join(" ")))},contains:function(e){return this._names.indexOf(e)>=0}};function et(e,a){for(var n=Fe(e),t=-1,i=a.length;++t=0&&(n=a.slice(t+1),a=a.slice(0,t)),{type:a,name:n}})}function xr(e){return function(){var a=this.__on;if(a){for(var n=0,t=-1,i=a.length,o;n>8&15|a>>4&240,a>>4&15|a&240,(a&15)<<4|a&15,1):n===8?Oa(a>>24&255,a>>16&255,a>>8&255,(a&255)/255):n===4?Oa(a>>12&15|a>>8&240,a>>8&15|a>>4&240,a>>4&15|a&240,((a&15)<<4|a&15)/255):null):(a=Ir.exec(e))?new P(a[1],a[2],a[3],1):(a=Dr.exec(e))?new P(a[1]*255/100,a[2]*255/100,a[3]*255/100,1):(a=Gr.exec(e))?Oa(a[1],a[2],a[3],a[4]):(a=Or.exec(e))?Oa(a[1]*255/100,a[2]*255/100,a[3]*255/100,a[4]):(a=qr.exec(e))?yn(a[1],a[2]/100,a[3]/100,1):(a=jr.exec(e))?yn(a[1],a[2]/100,a[3]/100,a[4]):cn.hasOwnProperty(e)?fn(cn[e]):e==="transparent"?new P(NaN,NaN,NaN,0):null}function fn(e){return new P(e>>16&255,e>>8&255,e&255,1)}function Oa(e,a,n,t){return t<=0&&(e=a=n=NaN),new P(e,a,n,t)}function it(e){return e instanceof za||(e=Z(e)),e?(e=e.rgb(),new P(e.r,e.g,e.b,e.opacity)):new P}function Re(e,a,n,t){return arguments.length===1?it(e):new P(e,a,n,t??1)}function P(e,a,n,t){this.r=+e,this.g=+a,this.b=+n,this.opacity=+t}ke(P,Re,Ye(za,{brighter(e){return e=e==null?Sa:Math.pow(Sa,e),new P(this.r*e,this.g*e,this.b*e,this.opacity)},darker(e){return e=e==null?ga:Math.pow(ga,e),new P(this.r*e,this.g*e,this.b*e,this.opacity)},rgb(){return this},clamp(){return new P(ca(this.r),ca(this.g),ca(this.b),ie(this.opacity))},displayable(){return-.5<=this.r&&this.r<255.5&&-.5<=this.g&&this.g<255.5&&-.5<=this.b&&this.b<255.5&&0<=this.opacity&&this.opacity<=1},hex:mn,formatHex:mn,formatHex8:Fr,formatRgb:pn,toString:pn}));function mn(){return`#${ha(this.r)}${ha(this.g)}${ha(this.b)}`}function Fr(){return`#${ha(this.r)}${ha(this.g)}${ha(this.b)}${ha((isNaN(this.opacity)?1:this.opacity)*255)}`}function pn(){const e=ie(this.opacity);return`${e===1?"rgb(":"rgba("}${ca(this.r)}, ${ca(this.g)}, ${ca(this.b)}${e===1?")":`, ${e})`}`}function ie(e){return isNaN(e)?1:Math.max(0,Math.min(1,e))}function ca(e){return Math.max(0,Math.min(255,Math.round(e)||0))}function ha(e){return e=ca(e),(e<16?"0":"")+e.toString(16)}function yn(e,a,n,t){return t<=0?e=a=n=NaN:n<=0||n>=1?e=a=NaN:a<=0&&(e=NaN),new F(e,a,n,t)}function rt(e){if(e instanceof F)return new F(e.h,e.s,e.l,e.opacity);if(e instanceof za||(e=Z(e)),!e)return new F;if(e instanceof F)return e;e=e.rgb();var a=e.r/255,n=e.g/255,t=e.b/255,i=Math.min(a,n,t),o=Math.max(a,n,t),s=NaN,h=o-i,u=(o+i)/2;return h?(a===o?s=(n-t)/h+(n0&&u<1?0:s,new F(s,h,u,e.opacity)}function Yr(e,a,n,t){return arguments.length===1?rt(e):new F(e,a,n,t??1)}function F(e,a,n,t){this.h=+e,this.s=+a,this.l=+n,this.opacity=+t}ke(F,Yr,Ye(za,{brighter(e){return e=e==null?Sa:Math.pow(Sa,e),new F(this.h,this.s,this.l*e,this.opacity)},darker(e){return e=e==null?ga:Math.pow(ga,e),new F(this.h,this.s,this.l*e,this.opacity)},rgb(){var e=this.h%360+(this.h<0)*360,a=isNaN(e)||isNaN(this.s)?0:this.s,n=this.l,t=n+(n<.5?n:1-n)*a,i=2*n-t;return new P(Ne(e>=240?e-240:e+120,i,t),Ne(e,i,t),Ne(e<120?e+240:e-120,i,t),this.opacity)},clamp(){return new F(kn(this.h),qa(this.s),qa(this.l),ie(this.opacity))},displayable(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1},formatHsl(){const e=ie(this.opacity);return`${e===1?"hsl(":"hsla("}${kn(this.h)}, ${qa(this.s)*100}%, ${qa(this.l)*100}%${e===1?")":`, ${e})`}`}}));function kn(e){return e=(e||0)%360,e<0?e+360:e}function qa(e){return Math.max(0,Math.min(1,e||0))}function Ne(e,a,n){return(e<60?a+(n-a)*e/60:e<180?n:e<240?a+(n-a)*(240-e)/60:a)*255}const $r=Math.PI/180,Wr=180/Math.PI;var ot=-.14861,$e=1.78277,We=-.29227,be=-.90649,Pa=1.97294,bn=Pa*be,vn=Pa*$e,wn=$e*We-be*ot;function Zr(e){if(e instanceof da)return new da(e.h,e.s,e.l,e.opacity);e instanceof P||(e=it(e));var a=e.r/255,n=e.g/255,t=e.b/255,i=(wn*t+bn*a-vn*n)/(wn+bn-vn),o=t-i,s=(Pa*(n-i)-We*o)/be,h=Math.sqrt(s*s+o*o)/(Pa*i*(1-i)),u=h?Math.atan2(s,o)*Wr-120:NaN;return new da(u<0?u+360:u,h,i,e.opacity)}function sa(e,a,n,t){return arguments.length===1?Zr(e):new da(e,a,n,t??1)}function da(e,a,n,t){this.h=+e,this.s=+a,this.l=+n,this.opacity=+t}ke(da,sa,Ye(za,{brighter(e){return e=e==null?Sa:Math.pow(Sa,e),new da(this.h,this.s,this.l*e,this.opacity)},darker(e){return e=e==null?ga:Math.pow(ga,e),new da(this.h,this.s,this.l*e,this.opacity)},rgb(){var e=isNaN(this.h)?0:(this.h+120)*$r,a=+this.l,n=isNaN(this.s)?0:this.s*a*(1-a),t=Math.cos(e),i=Math.sin(e);return new P(255*(a+n*(ot*t+$e*i)),255*(a+n*(We*t+be*i)),255*(a+n*(Pa*t)),this.opacity)}}));const ve=e=>()=>e;function st(e,a){return function(n){return e+n*a}}function Qr(e,a,n){return e=Math.pow(e,n),a=Math.pow(a,n)-e,n=1/n,function(t){return Math.pow(e+t*a,n)}}function Jr(e,a){var n=a-e;return n?st(e,n>180||n<-180?n-360*Math.round(n/360):n):ve(isNaN(e)?a:e)}function Xr(e){return(e=+e)==1?wa:function(a,n){return n-a?Qr(a,n,e):ve(isNaN(a)?n:a)}}function wa(e,a){var n=a-e;return n?st(e,n):ve(isNaN(e)?a:e)}const re=(function e(a){var n=Xr(a);function t(i,o){var s=n((i=Re(i)).r,(o=Re(o)).r),h=n(i.g,o.g),u=n(i.b,o.b),l=wa(i.opacity,o.opacity);return function(c){return i.r=s(c),i.g=h(c),i.b=u(c),i.opacity=l(c),i+""}}return t.gamma=e,t})(1);function ao(e,a){a||(a=[]);var n=e?Math.min(a.length,e.length):0,t=a.slice(),i;return function(o){for(i=0;in&&(o=a.slice(n,o),h[s]?h[s]+=o:h[++s]=o),(t=t[0])===(i=i[0])?h[s]?h[s]+=i:h[++s]=i:(h[++s]=null,u.push({i:s,x:aa(t,i)})),n=Ce.lastIndex;return n180?c+=360:c-l>180&&(l+=360),r.push({i:d.push(i(d)+"rotate(",null,t)-2,x:aa(l,c)})):c&&d.push(i(d)+"rotate("+c+t)}function h(l,c,d,r){l!==c?r.push({i:d.push(i(d)+"skewX(",null,t)-2,x:aa(l,c)}):c&&d.push(i(d)+"skewX("+c+t)}function u(l,c,d,r,g,m){if(l!==d||c!==r){var f=g.push(i(g)+"scale(",null,",",null,")");m.push({i:f-4,x:aa(l,d)},{i:f-2,x:aa(c,r)})}else(d!==1||r!==1)&&g.push(i(g)+"scale("+d+","+r+")")}return function(l,c){var d=[],r=[];return l=e(l),c=e(c),o(l.translateX,l.translateY,c.translateX,c.translateY,d,r),s(l.rotate,c.rotate,d,r),h(l.skewX,c.skewX,d,r),u(l.scaleX,l.scaleY,c.scaleX,c.scaleY,d,r),l=c=null,function(g){for(var m=-1,f=r.length,p;++m=0&&e._call.call(void 0,a),e=e._next;--_a}function Sn(){fa=(se=Ia.now())+Ae,_a=Na=0;try{fo()}finally{_a=0,po(),fa=0}}function mo(){var e=Ia.now(),a=e-se;a>gt&&(Ae-=a,se=e)}function po(){for(var e,a=oe,n,t=1/0;a;)a._call?(t>a._time&&(t=a._time),e=a,a=a._next):(n=a._next,a._next=null,a=e?e._next=n:oe=n);Ca=e,Ie(t)}function Ie(e){if(!_a){Na&&(Na=clearTimeout(Na));var a=e-fa;a>24?(e<1/0&&(Na=setTimeout(Sn,e-Ia.now()-Ae)),Ta&&(Ta=clearInterval(Ta))):(Ta||(se=Ia.now(),Ta=setInterval(mo,gt)),_a=1,ft(Sn))}}function _n(e,a,n){var t=new le;return a=a==null?0:+a,t.restart(i=>{t.stop(),e(i+a)},a,n),t}var yo=Fn("start","end","cancel","interrupt"),ko=[],pt=0,Mn=1,De=2,Wa=3,zn=4,Ge=5,Za=6;function Se(e,a,n,t,i,o){var s=e.__transition;if(!s)e.__transition={};else if(n in s)return;bo(e,n,{name:a,index:t,group:i,on:yo,tween:ko,time:o.time,delay:o.delay,duration:o.duration,ease:o.ease,timer:null,state:pt})}function Qe(e,a){var n=Q(e,a);if(n.state>pt)throw new Error("too late; already scheduled");return n}function ta(e,a){var n=Q(e,a);if(n.state>Wa)throw new Error("too late; already running");return n}function Q(e,a){var n=e.__transition;if(!n||!(n=n[a]))throw new Error("transition not found");return n}function bo(e,a,n){var t=e.__transition,i;t[a]=n,n.timer=mt(o,0,n.time);function o(l){n.state=Mn,n.timer.restart(s,n.delay,n.time),n.delay<=l&&s(l-n.delay)}function s(l){var c,d,r,g;if(n.state!==Mn)return u();for(c in t)if(g=t[c],g.name===n.name){if(g.state===Wa)return _n(s);g.state===zn?(g.state=Za,g.timer.stop(),g.on.call("interrupt",e,e.__data__,g.index,g.group),delete t[c]):+cDe&&t.state=0&&(a=a.slice(0,n)),!a||a==="start"})}function Zo(e,a,n){var t,i,o=Wo(a)?Qe:ta;return function(){var s=o(this,e),h=s.on;h!==t&&(i=(t=h).copy()).on(a,n),s.on=i}}function Qo(e,a){var n=this._id;return arguments.length<2?Q(this.node(),n).on.on(e):this.each(Zo(n,e,a))}function Jo(e){return function(){var a=this.parentNode;for(var n in this.__transition)if(+n!==e)return;a&&a.removeChild(this)}}function Xo(){return this.on("end.remove",Jo(this._id))}function as(e){var a=this._name,n=this._id;typeof e!="function"&&(e=Ve(e));for(var t=this._groups,i=t.length,o=new Array(i),s=0;s=0))throw new Error(`invalid digits: ${e}`);if(a>15)return vt;const n=10**a;return function(t){this._+=t[0];for(let i=1,o=t.length;ila)if(!(Math.abs(d*u-l*c)>la)||!o)this._append`L${this._x1=a},${this._y1=n}`;else{let g=t-s,m=i-h,f=u*u+l*l,p=g*g+m*m,y=Math.sqrt(f),k=Math.sqrt(r),b=o*Math.tan((Oe-Math.acos((f+r-p)/(2*y*k)))/2),v=b/k,w=b/y;Math.abs(v-1)>la&&this._append`L${a+v*c},${n+v*d}`,this._append`A${o},${o},0,0,${+(d*g>c*m)},${this._x1=a+w*u},${this._y1=n+w*l}`}}arc(a,n,t,i,o,s){if(a=+a,n=+n,t=+t,s=!!s,t<0)throw new Error(`negative radius: ${t}`);let h=t*Math.cos(i),u=t*Math.sin(i),l=a+h,c=n+u,d=1^s,r=s?i-o:o-i;this._x1===null?this._append`M${l},${c}`:(Math.abs(this._x1-l)>la||Math.abs(this._y1-c)>la)&&this._append`L${l},${c}`,t&&(r<0&&(r=r%qe+qe),r>Ms?this._append`A${t},${t},0,1,${d},${a-h},${n-u}A${t},${t},0,1,${d},${this._x1=l},${this._y1=c}`:r>la&&this._append`A${t},${t},0,${+(r>=Oe)},${d},${this._x1=a+t*Math.cos(o)},${this._y1=n+t*Math.sin(o)}`)}rect(a,n,t,i){this._append`M${this._x0=this._x1=+a},${this._y0=this._y1=+n}h${t=+t}v${+i}h${-t}Z`}toString(){return this._}}const ra=11102230246251565e-32,L=134217729,xs=(3+8*ra)*ra;function Ke(e,a,n,t,i){let o,s,h,u,l=a[0],c=t[0],d=0,r=0;c>l==c>-l?(o=l,l=a[++d]):(o=c,c=t[++r]);let g=0;if(dl==c>-l?(s=l+o,h=o-(s-l),l=a[++d]):(s=c+o,h=o-(s-c),c=t[++r]),o=s,h!==0&&(i[g++]=h);dl==c>-l?(s=o+l,u=s-o,h=o-(s-u)+(l-u),l=a[++d]):(s=o+c,u=s-o,h=o-(s-u)+(c-u),c=t[++r]),o=s,h!==0&&(i[g++]=h);for(;d=E||-C>=E||(d=e-S,h=e-(S+d)+(d-i),d=n-z,l=n-(z+d)+(d-i),d=a-A,u=a-(A+d)+(d-o),d=t-x,c=t-(x+d)+(d-o),h===0&&u===0&&l===0&&c===0)||(E=Bs*s+xs*Math.abs(C),C+=S*c+x*h-(A*l+z*u),C>=E||-C>=E))return C;v=h*x,r=L*h,g=r-(r-h),m=h-g,r=L*x,f=r-(r-x),p=x-f,w=m*p-(v-g*f-m*f-g*p),_=u*z,r=L*u,g=r-(r-u),m=u-g,r=L*z,f=r-(r-z),p=z-f,M=m*p-(_-g*f-m*f-g*p),y=w-M,d=w-y,I[0]=w-(y+d)+(d-M),k=v+y,d=k-v,b=v-(k-d)+(y-d),y=b-_,d=b-y,I[1]=b-(y+d)+(d-_),T=k+y,d=T-k,I[2]=k-(T-d)+(y-d),I[3]=T;const O=Ke(4,pa,4,I,Tn);v=S*c,r=L*S,g=r-(r-S),m=S-g,r=L*c,f=r-(r-c),p=c-f,w=m*p-(v-g*f-m*f-g*p),_=A*l,r=L*A,g=r-(r-A),m=A-g,r=L*l,f=r-(r-l),p=l-f,M=m*p-(_-g*f-m*f-g*p),y=w-M,d=w-y,I[0]=w-(y+d)+(d-M),k=v+y,d=k-v,b=v-(k-d)+(y-d),y=b-_,d=b-y,I[1]=b-(y+d)+(d-_),T=k+y,d=T-k,I[2]=k-(T-d)+(y-d),I[3]=T;const K=Ke(O,Tn,4,I,xn);v=h*c,r=L*h,g=r-(r-h),m=h-g,r=L*c,f=r-(r-c),p=c-f,w=m*p-(v-g*f-m*f-g*p),_=u*l,r=L*u,g=r-(r-u),m=u-g,r=L*l,f=r-(r-l),p=l-f,M=m*p-(_-g*f-m*f-g*p),y=w-M,d=w-y,I[0]=w-(y+d)+(d-M),k=v+y,d=k-v,b=v-(k-d)+(y-d),y=b-_,d=b-y,I[1]=b-(y+d)+(d-_),T=k+y,d=T-k,I[2]=k-(T-d)+(y-d),I[3]=T;const H=Ke(K,xn,4,I,Nn);return Nn[H-1]}function Ua(e,a,n,t,i,o){const s=(a-o)*(n-i),h=(e-i)*(t-o),u=s-h,l=Math.abs(s+h);return Math.abs(u)>=Cs*l?u:-Es(e,a,n,t,i,o,l)}const Cn=Math.pow(2,-52),Va=new Uint32Array(512);class Xe{static from(a,n=Is,t=Ds){const i=a.length,o=new Float64Array(i*2);for(let s=0;s>1;if(n>0&&typeof a[0]!="number")throw new Error("Expected coords to contain numbers.");this.coords=a;const t=Math.max(2*n-5,0);this._triangles=new Uint32Array(t*3),this._halfedges=new Int32Array(t*3),this._hashSize=Math.ceil(Math.sqrt(n)),this._hullPrev=new Uint32Array(n),this._hullNext=new Uint32Array(n),this._hullTri=new Uint32Array(n),this._hullHash=new Int32Array(this._hashSize),this._ids=new Uint32Array(n),this._dists=new Float64Array(n),this.update()}update(){const{coords:a,_hullPrev:n,_hullNext:t,_hullTri:i,_hullHash:o}=this,s=a.length>>1;let h=1/0,u=1/0,l=-1/0,c=-1/0;for(let S=0;Sl&&(l=z),A>c&&(c=A),this._ids[S]=S}const d=(h+l)/2,r=(u+c)/2;let g,m,f;for(let S=0,z=1/0;S0&&(m=S,z=A)}let k=a[2*m],b=a[2*m+1],v=1/0;for(let S=0;Sx&&(S[z++]=C,x=E)}this.hull=S.subarray(0,z),this.triangles=new Uint32Array(0),this.halfedges=new Uint32Array(0);return}if(Ua(p,y,k,b,w,_)<0){const S=m,z=k,A=b;m=f,k=w,b=_,f=S,w=z,_=A}const M=Ps(p,y,k,b,w,_);this._cx=M.x,this._cy=M.y;for(let S=0;S0&&Math.abs(C-z)<=Cn&&Math.abs(E-A)<=Cn||(z=C,A=E,x===g||x===m||x===f))continue;let O=0;for(let xe=0,jt=this._hashKey(C,E);xe=0;)if(K=H,K===O){K=-1;break}if(K===-1)continue;let U=this._addTriangle(K,x,t[K],-1,-1,i[K]);i[x]=this._legalize(U+2),i[K]=U,T++;let R=t[K];for(;H=t[R],Ua(C,E,a[2*R],a[2*R+1],a[2*H],a[2*H+1])<0;)U=this._addTriangle(R,x,H,i[x],-1,i[R]),i[x]=this._legalize(U+2),t[R]=R,T--,R=H;if(K===O)for(;H=n[K],Ua(C,E,a[2*H],a[2*H+1],a[2*K],a[2*K+1])<0;)U=this._addTriangle(H,x,K,-1,i[K],i[H]),this._legalize(U+2),i[H]=U,t[K]=K,T--,K=H;this._hullStart=n[x]=K,t[K]=n[R]=x,t[x]=R,o[this._hashKey(C,E)]=x,o[this._hashKey(a[2*K],a[2*K+1])]=K}this.hull=new Uint32Array(T);for(let S=0,z=this._hullStart;S0?3-n:1+n)/4}function Be(e,a,n,t){const i=e-n,o=a-t;return i*i+o*o}function Rs(e,a,n,t,i,o,s,h){const u=e-s,l=a-h,c=n-s,d=t-h,r=i-s,g=o-h,m=u*u+l*l,f=c*c+d*d,p=r*r+g*g;return u*(d*p-f*g)-l*(c*p-f*r)+m*(c*g-d*r)<0}function Ls(e,a,n,t,i,o){const s=n-e,h=t-a,u=i-e,l=o-a,c=s*s+h*h,d=u*u+l*l,r=.5/(s*l-h*u),g=(l*c-h*d)*r,m=(s*d-u*c)*r;return g*g+m*m}function Ps(e,a,n,t,i,o){const s=n-e,h=t-a,u=i-e,l=o-a,c=s*s+h*h,d=u*u+l*l,r=.5/(s*l-h*u),g=e+(l*c-h*d)*r,m=a+(s*d-u*c)*r;return{x:g,y:m}}function ka(e,a,n,t){if(t-n<=20)for(let i=n+1;i<=t;i++){const o=e[i],s=a[o];let h=i-1;for(;h>=n&&a[e[h]]>s;)e[h+1]=e[h--];e[h+1]=o}else{const i=n+t>>1;let o=n+1,s=t;xa(e,i,o),a[e[n]]>a[e[t]]&&xa(e,n,t),a[e[o]]>a[e[t]]&&xa(e,o,t),a[e[n]]>a[e[o]]&&xa(e,n,o);const h=e[o],u=a[h];for(;;){do o++;while(a[e[o]]u);if(s=s-n?(ka(e,a,o,t),ka(e,a,n,s-1)):(ka(e,a,n,s-1),ka(e,a,o,t))}}function xa(e,a,n){const t=e[a];e[a]=e[n],e[n]=t}function Is(e){return e[0]}function Ds(e){return e[1]}function Gs(e){const a=+this._x.call(null,e),n=+this._y.call(null,e);return wt(this.cover(a,n),a,n,e)}function wt(e,a,n,t){if(isNaN(a)||isNaN(n))return e;var i,o=e._root,s={data:t},h=e._x0,u=e._y0,l=e._x1,c=e._y1,d,r,g,m,f,p,y,k;if(!o)return e._root=s,e;for(;o.length;)if((f=a>=(d=(h+l)/2))?h=d:l=d,(p=n>=(r=(u+c)/2))?u=r:c=r,i=o,!(o=o[y=p<<1|f]))return i[y]=s,e;if(g=+e._x.call(null,o.data),m=+e._y.call(null,o.data),a===g&&n===m)return s.next=o,i?i[y]=s:e._root=s,e;do i=i?i[y]=new Array(4):e._root=new Array(4),(f=a>=(d=(h+l)/2))?h=d:l=d,(p=n>=(r=(u+c)/2))?u=r:c=r;while((y=p<<1|f)===(k=(m>=r)<<1|g>=d));return i[k]=o,i[y]=s,e}function Os(e){var a,n,t=e.length,i,o,s=new Array(t),h=new Array(t),u=1/0,l=1/0,c=-1/0,d=-1/0;for(n=0;nc&&(c=i),od&&(d=o));if(u>c||l>d)return this;for(this.cover(u,l).cover(c,d),n=0;ne||e>=i||t>a||a>=o;)switch(l=(ac||(h=m.y0)>d||(u=m.x1)=y)<<1|e>=p)&&(m=r[r.length-1],r[r.length-1]=r[r.length-1-f],r[r.length-1-f]=m)}else{var k=e-+this._x.call(null,g.data),b=a-+this._y.call(null,g.data),v=k*k+b*b;if(v=(r=(s+u)/2))?s=r:u=r,(f=d>=(g=(h+l)/2))?h=g:l=g,a=n,!(n=n[p=f<<1|m]))return this;if(!n.length)break;(a[p+1&3]||a[p+2&3]||a[p+3&3])&&(t=a,y=p)}for(;n.data!==e;)if(i=n,!(n=n.next))return this;return(o=n.next)&&delete n.next,i?(o?i.next=o:delete i.next,this):a?(o?a[p]=o:delete a[p],(n=a[0]||a[1]||a[2]||a[3])&&n===(a[3]||a[2]||a[1]||a[0])&&!n.length&&(t?t[y]=n:this._root=n),this):(this._root=o,this)}function Ys(e){for(var a=0,n=e.length;a=1e21?e.toLocaleString("en").replace(/,/g,""):e.toString(10)}function he(e,a){if((n=(e=a?e.toExponential(a-1):e.toExponential()).indexOf("e"))<0)return null;var n,t=e.slice(0,n);return[t.length>1?t[0]+t.slice(2):t,+e.slice(n+1)]}function Ma(e){return e=he(Math.abs(e)),e?e[1]:NaN}function tl(e,a){return function(n,t){for(var i=n.length,o=[],s=0,h=e[0],u=0;i>0&&h>0&&(u+h+1>t&&(h=Math.max(1,t-u)),o.push(n.substring(i-=h,i+h)),!((u+=h+1)>t));)h=e[s=(s+1)%e.length];return o.reverse().join(a)}}function il(e){return function(a){return a.replace(/[0-9]/g,function(n){return e[+n]})}}var rl=/^(?:(.)?([<>=^]))?([+\-( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?(~)?([a-z%])?$/i;function ce(e){if(!(a=rl.exec(e)))throw new Error("invalid format: "+e);var a;return new en({fill:a[1],align:a[2],sign:a[3],symbol:a[4],zero:a[5],width:a[6],comma:a[7],precision:a[8]&&a[8].slice(1),trim:a[9],type:a[10]})}ce.prototype=en.prototype;function en(e){this.fill=e.fill===void 0?" ":e.fill+"",this.align=e.align===void 0?">":e.align+"",this.sign=e.sign===void 0?"-":e.sign+"",this.symbol=e.symbol===void 0?"":e.symbol+"",this.zero=!!e.zero,this.width=e.width===void 0?void 0:+e.width,this.comma=!!e.comma,this.precision=e.precision===void 0?void 0:+e.precision,this.trim=!!e.trim,this.type=e.type===void 0?"":e.type+""}en.prototype.toString=function(){return this.fill+this.align+this.sign+this.symbol+(this.zero?"0":"")+(this.width===void 0?"":Math.max(1,this.width|0))+(this.comma?",":"")+(this.precision===void 0?"":"."+Math.max(0,this.precision|0))+(this.trim?"~":"")+this.type};function ol(e){a:for(var a=e.length,n=1,t=-1,i;n0&&(t=0);break}return t>0?e.slice(0,t)+e.slice(i+1):e}var At;function sl(e,a){var n=he(e,a);if(!n)return e+"";var t=n[0],i=n[1],o=i-(At=Math.max(-8,Math.min(8,Math.floor(i/3)))*3)+1,s=t.length;return o===s?t:o>s?t+new Array(o-s+1).join("0"):o>0?t.slice(0,o)+"."+t.slice(o):"0."+new Array(1-o).join("0")+he(e,Math.max(0,a+o-1))[0]}function Bn(e,a){var n=he(e,a);if(!n)return e+"";var t=n[0],i=n[1];return i<0?"0."+new Array(-i).join("0")+t:t.length>i+1?t.slice(0,i+1)+"."+t.slice(i+1):t+new Array(i-t.length+2).join("0")}const En={"%":(e,a)=>(e*100).toFixed(a),b:e=>Math.round(e).toString(2),c:e=>e+"",d:nl,e:(e,a)=>e.toExponential(a),f:(e,a)=>e.toFixed(a),g:(e,a)=>e.toPrecision(a),o:e=>Math.round(e).toString(8),p:(e,a)=>Bn(e*100,a),r:Bn,s:sl,X:e=>Math.round(e).toString(16).toUpperCase(),x:e=>Math.round(e).toString(16)};function Hn(e){return e}var Rn=Array.prototype.map,Ln=["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"];function ll(e){var a=e.grouping===void 0||e.thousands===void 0?Hn:tl(Rn.call(e.grouping,Number),e.thousands+""),n=e.currency===void 0?"":e.currency[0]+"",t=e.currency===void 0?"":e.currency[1]+"",i=e.decimal===void 0?".":e.decimal+"",o=e.numerals===void 0?Hn:il(Rn.call(e.numerals,String)),s=e.percent===void 0?"%":e.percent+"",h=e.minus===void 0?"−":e.minus+"",u=e.nan===void 0?"NaN":e.nan+"";function l(d){d=ce(d);var r=d.fill,g=d.align,m=d.sign,f=d.symbol,p=d.zero,y=d.width,k=d.comma,b=d.precision,v=d.trim,w=d.type;w==="n"?(k=!0,w="g"):En[w]||(b===void 0&&(b=12),v=!0,w="g"),(p||r==="0"&&g==="=")&&(p=!0,r="0",g="=");var _=f==="$"?n:f==="#"&&/[boxX]/.test(w)?"0"+w.toLowerCase():"",M=f==="$"?t:/[%p]/.test(w)?s:"",T=En[w],S=/[defgprs%]/.test(w);b=b===void 0?6:/[gprs]/.test(w)?Math.max(1,Math.min(21,b)):Math.max(0,Math.min(20,b));function z(A){var x=_,C=M,E,O,K;if(w==="c")C=T(A)+C,A="";else{A=+A;var H=A<0||1/A<0;if(A=isNaN(A)?u:T(Math.abs(A),b),v&&(A=ol(A)),H&&+A==0&&m!=="+"&&(H=!1),x=(H?m==="("?m:h:m==="-"||m==="("?"":m)+x,C=(w==="s"?Ln[8+At/3]:"")+C+(H&&m==="("?")":""),S){for(E=-1,O=A.length;++EK||K>57){C=(K===46?i+A.slice(E+1):A.slice(E))+C,A=A.slice(0,E);break}}}k&&!p&&(A=a(A,1/0));var U=x.length+A.length+C.length,R=U>1)+x+A+C+R.slice(U);break;default:A=R+x+A+C;break}return o(A)}return z.toString=function(){return d+""},z}function c(d,r){var g=l((d=ce(d),d.type="f",d)),m=Math.max(-8,Math.min(8,Math.floor(Ma(r)/3)))*3,f=Math.pow(10,-m),p=Ln[8+m/3];return function(y){return g(f*y)+p}}return{format:l,formatPrefix:c}}var Fa,St,_t;ul({thousands:",",grouping:[3],currency:["$",""]});function ul(e){return Fa=ll(e),St=Fa.format,_t=Fa.formatPrefix,Fa}function hl(e){return Math.max(0,-Ma(Math.abs(e)))}function cl(e,a){return Math.max(0,Math.max(-8,Math.min(8,Math.floor(Ma(a)/3)))*3-Ma(Math.abs(e)))}function dl(e,a){return e=Math.abs(e),a=Math.abs(a)-e,Math.max(0,Ma(a)-Ma(e))+1}function gl(e){for(var a=-1,n=e.length,t,i=e[n-1],o=0;++a1);return t+i*h*Math.sqrt(-2*Math.log(s)/s)}}return n.source=e,n})(fl);function pl(e,a){switch(arguments.length){case 0:break;case 1:{typeof e=="function"?this.interpolator(e):this.range(e);break}default:{this.domain(e),typeof a=="function"?this.interpolator(a):this.range(a);break}}return this}function Mt(e){return e}function yl(e,a,n,t){var i=Qt(e,a,n),o;switch(t=ce(t??",f"),t.type){case"s":{var s=Math.max(Math.abs(e),Math.abs(a));return t.precision==null&&!isNaN(o=cl(i,s))&&(t.precision=o),_t(t,s)}case"":case"e":case"g":case"p":case"r":{t.precision==null&&!isNaN(o=dl(i,Math.max(Math.abs(e),Math.abs(a))))&&(t.precision=o-(t.type==="e"));break}case"f":case"%":{t.precision==null&&!isNaN(o=hl(i))&&(t.precision=o-(t.type==="%")*2);break}}return St(t)}function kl(e){var a=e.domain;return e.ticks=function(n){var t=a();return Zt(t[0],t[t.length-1],n??10)},e.tickFormat=function(n,t){var i=a();return yl(i[0],i[i.length-1],n??10,t)},e.nice=function(n){n==null&&(n=10);var t=a(),i=0,o=t.length-1,s=t[i],h=t[o],u,l,c=10;for(h0;){if(l=Ee(s,h,n),l===u)return t[i]=s,t[o]=h,a(t);if(l>0)s=Math.floor(s/l)*l,h=Math.ceil(h/l)*l;else if(l<0)s=Math.ceil(s*l)/l,h=Math.floor(h*l)/l;else break;u=l}return e},e}function bl(){var e=0,a=1,n,t,i,o,s=Mt,h=!1,u;function l(d){return d==null||isNaN(d=+d)?u:s(i===0?.5:(d=(o(d)-n)*i,h?Math.max(0,Math.min(1,d)):d))}l.domain=function(d){return arguments.length?([e,a]=d,n=o(e=+e),t=o(a=+a),i=n===t?0:1/(t-n),l):[e,a]},l.clamp=function(d){return arguments.length?(h=!!d,l):h},l.interpolator=function(d){return arguments.length?(s=d,l):s};function c(d){return function(r){var g,m;return arguments.length?([g,m]=r,s=d(g,m),l):[s(0),s(1)]}}return l.range=c(we),l.rangeRound=c(so),l.unknown=function(d){return arguments.length?(u=d,l):u},function(d){return o=d,n=d(e),t=d(a),i=n===t?0:1/(t-n),l}}function vl(e,a){return a.domain(e.domain()).interpolator(e.interpolator()).clamp(e.clamp()).unknown(e.unknown())}function nn(){var e=kl(bl()(Mt));return e.copy=function(){return vl(e,nn())},pl.apply(e,arguments)}dt(sa(-100,.75,.35),sa(80,1.5,.8));dt(sa(260,.75,.35),sa(80,1.5,.8));var Ya=sa();function zt(e){(e<0||e>1)&&(e-=Math.floor(e));var a=Math.abs(e-.5);return Ya.h=360*e-100,Ya.s=1.5-1.5*a,Ya.l=.8-.9*a,Ya+""}function ya(e){return function(){return e}}const Pn=1e-12;function wl(e){let a=3;return e.digits=function(n){if(!arguments.length)return a;if(n==null)a=null;else{const t=Math.floor(n);if(!(t>=0))throw new RangeError(`invalid digits: ${n}`);a=t}return e},()=>new Ts(a)}function Al(e){return typeof e=="object"&&"length"in e?e:Array.from(e)}function Tt(e){this._context=e}Tt.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._point=0},lineEnd:function(){(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line},point:function(e,a){switch(e=+e,a=+a,this._point){case 0:this._point=1,this._line?this._context.lineTo(e,a):this._context.moveTo(e,a);break;case 1:this._point=2;default:this._context.lineTo(e,a);break}}};function Sl(e){return new Tt(e)}function _l(e){return e[0]}function Ml(e){return e[1]}function tn(e,a){var n=ya(!0),t=null,i=Sl,o=null,s=wl(h);e=typeof e=="function"?e:e===void 0?_l:ya(e),a=typeof a=="function"?a:a===void 0?Ml:ya(a);function h(u){var l,c=(u=Al(u)).length,d,r=!1,g;for(t==null&&(o=i(g=s())),l=0;l<=c;++l)!(l0)for(var t=e[0],i=a[0],o=e[n]-t,s=a[n]-i,h=-1,u;++h<=n;)u=h/n,this._basis.point(this._beta*e[h]+(1-this._beta)*(t+u*o),this._beta*a[h]+(1-this._beta)*(i+u*s));this._x=this._y=null,this._basis.lineEnd()},point:function(e,a){this._x.push(+e),this._y.push(+a)}};const xl=(function e(a){function n(t){return a===1?new _e(t):new Nt(t,a)}return n.beta=function(t){return e(+t)},n})(.85);function Dn(e,a,n){e._context.bezierCurveTo(e._x1+e._k*(e._x2-e._x0),e._y1+e._k*(e._y2-e._y0),e._x2+e._k*(e._x1-a),e._y2+e._k*(e._y1-n),e._x2,e._y2)}function rn(e,a){this._context=e,this._k=(1-a)/6}rn.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:Dn(this,this._x1,this._y1);break}(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line},point:function(e,a){switch(e=+e,a=+a,this._point){case 0:this._point=1,this._line?this._context.lineTo(e,a):this._context.moveTo(e,a);break;case 1:this._point=2,this._x1=e,this._y1=a;break;case 2:this._point=3;default:Dn(this,e,a);break}this._x0=this._x1,this._x1=this._x2,this._x2=e,this._y0=this._y1,this._y1=this._y2,this._y2=a}};(function e(a){function n(t){return new rn(t,a)}return n.tension=function(t){return e(+t)},n})(0);function Nl(e,a,n){var t=e._x1,i=e._y1,o=e._x2,s=e._y2;if(e._l01_a>Pn){var h=2*e._l01_2a+3*e._l01_a*e._l12_a+e._l12_2a,u=3*e._l01_a*(e._l01_a+e._l12_a);t=(t*h-e._x0*e._l12_2a+e._x2*e._l01_2a)/u,i=(i*h-e._y0*e._l12_2a+e._y2*e._l01_2a)/u}if(e._l23_a>Pn){var l=2*e._l23_2a+3*e._l23_a*e._l12_a+e._l12_2a,c=3*e._l23_a*(e._l23_a+e._l12_a);o=(o*l+e._x1*e._l23_2a-a*e._l12_2a)/c,s=(s*l+e._y1*e._l23_2a-n*e._l12_2a)/c}e._context.bezierCurveTo(t,i,o,s,e._x2,e._y2)}function Ct(e,a){this._context=e,this._alpha=a}Ct.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:this.point(this._x2,this._y2);break}(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line},point:function(e,a){if(e=+e,a=+a,this._point){var n=this._x2-e,t=this._y2-a;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(n*n+t*t,this._alpha))}switch(this._point){case 0:this._point=1,this._line?this._context.lineTo(e,a):this._context.moveTo(e,a);break;case 1:this._point=2;break;case 2:this._point=3;default:Nl(this,e,a);break}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=e,this._y0=this._y1,this._y1=this._y2,this._y2=a}};const Cl=(function e(a){function n(t){return a?new Ct(t,a):new rn(t,0)}return n.alpha=function(t){return e(+t)},n})(.5);function Ka(e,a,n){this.k=e,this.x=a,this.y=n}Ka.prototype={constructor:Ka,scale:function(e){return e===1?this:new Ka(this.k*e,this.x,this.y)},translate:function(e,a){return e===0&a===0?this:new Ka(this.k,this.x+this.k*e,this.y+this.k*a)},apply:function(e){return[e[0]*this.k+this.x,e[1]*this.k+this.y]},applyX:function(e){return e*this.k+this.x},applyY:function(e){return e*this.k+this.y},invert:function(e){return[(e[0]-this.x)/this.k,(e[1]-this.y)/this.k]},invertX:function(e){return(e-this.x)/this.k},invertY:function(e){return(e-this.y)/this.k},rescaleX:function(e){return e.copy().domain(e.range().map(this.invertX,this).map(e.invert,e))},rescaleY:function(e){return e.copy().domain(e.range().map(this.invertY,this).map(e.invert,e))},toString:function(){return"translate("+this.x+","+this.y+") scale("+this.k+")"}};Ka.prototype;const Y=(e,a)=>e===void 0&&a===void 0?Math.random():(a===void 0&&(a=e,e=0),Math.floor(Math.random()*(a-e+1))+e),B=e=>e>=1?!0:e<=0?!1:Math.random()a=>a%e===0,Qa=(e=100,a=30,n=0,t=300,i=0)=>N(ma(ml.source(()=>Math.random())(e,a)(),n,t),i),Kl=e=>~~e+ +B(e%1),Ja=e=>e[Math.floor(Math.random()*e.length)],de=e=>{const a=[];for(const n in e)for(let t=0;tMath.round(e+(a-e)*Math.random()**n),J=e=>{if(typeof e!="string")return 0;if(!Number.isNaN(+e))return~~e+ +B(+e-~~e);const a=e[0]==="-"?-1:1;Number.isNaN(+e[0])&&(e=e.slice(1));const n=e.includes("-")?e.split("-"):null;if(!n)return 0;const t=Y(parseFloat(n[0])*a,+parseFloat(n[1]));return Number.isNaN(t)||t<0?0:t},Bl=()=>String(Math.floor(Math.random()*1e9)),q=e=>"aeiouyɑ'əøɛœæɶɒɨɪɔɐʊɤɯаоиеёэыуюяàèìòùỳẁȁȅȉȍȕáéíóúýẃőűâêîôûŷŵäëïöüÿẅãẽĩõũỹąęįǫųāēīōūȳăĕĭŏŭǎěǐǒǔȧėȯẏẇạẹịọụỵẉḛḭṵṳ".includes(e),ua=(e,a=3)=>{for(;e.length>a&&q(Ea(Array.from(e)));)e=e.slice(0,-1);return e},El=e=>{const a=[{name:"guo",probability:1,condition:/ Guo$/,action:n=>n.slice(0,-4)},{name:"orszag",probability:1,condition:/orszag$/,action:n=>n.length<9?`${n}ian`:n.slice(0,-6)},{name:"stan",probability:1,condition:/stan$/,action:n=>n.length<9?`${n}i`:ua(n.slice(0,-4))},{name:"land",probability:1,condition:/land$/,action:n=>{if(n.length>9)return n.slice(0,-4);const t=ua(n.slice(0,-4),0);return t.length<3?`${n}ic`:t.length<4?`${t}lish`:`${t}ish`}},{name:"que",probability:1,condition:/que$/,action:n=>n.replace(/que$/,"can")},{name:"a",probability:1,condition:/a$/,action:n=>`${n}n`},{name:"o",probability:1,condition:/o$/,action:n=>n.replace(/o$/,"an")},{name:"u",probability:1,condition:/u$/,action:n=>`${n}an`},{name:"i",probability:1,condition:/i$/,action:n=>`${n}an`},{name:"e",probability:1,condition:/e$/,action:n=>`${n}an`},{name:"ay",probability:1,condition:/ay$/,action:n=>`${n}an`},{name:"os",probability:1,condition:/os$/,action:n=>{const t=ua(n.slice(0,-2),0);return t.length<4?n.slice(0,-1):`${t}ian`}},{name:"es",probability:1,condition:/es$/,action:n=>{const t=ua(n.slice(0,-2),0);return t.length>7?n.slice(0,-1):`${t}ian`}},{name:"l",probability:.8,condition:/l$/,action:n=>`${n}ese`},{name:"n",probability:.8,condition:/n$/,action:n=>`${n}ese`},{name:"ad",probability:.8,condition:/ad$/,action:n=>`${n}ian`},{name:"an",probability:.8,condition:/an$/,action:n=>`${n}ian`},{name:"ish",probability:.25,condition:/^[a-zA-Z]{6}$/,action:n=>`${ua(n.slice(0,-1))}ish`},{name:"an",probability:.5,condition:/^[a-zA-Z]{0,7}$/,action:n=>`${ua(n)}an`}];for(const n of a)if(B(n.probability)&&n.condition.test(e))return n.action(e);return e},Hl=e=>e+(["st","nd","rd"][((e+90)%100-10)%10-1]||"th"),Ue=(e,a=[])=>{const t=e.replace("Old ","O ").replace(/[()]/g,"").split(" "),i=t.join("");let o=t.length===2?t[0][0]+t[1][0]:i.slice(0,2);for(let s=1;sIntl.ListFormat?new Intl.ListFormat(document.documentElement.lang||"en",{style:"long",type:"conjunction"}).format(e):e.join(", "),Ll=(e,a="°C")=>({"°C":t=>`${N(t)}°C`,"°F":t=>`${N(t*9/5+32)}°F`,K:t=>`${N(t+273.15)}K`,"°R":t=>`${N((t+273.15)*9/5)}°R`,"°De":t=>`${N((100-t)*3/2)}°De`,"°N":t=>`${N(t*33/100)}°N`,"°Ré":t=>`${N(t*4/5)}°Ré`,"°Rø":t=>`${N(t*21/40+7.5)}°Rø`})[a](e),Pl=e=>e>=1e9?`${N(e/1e9,1)}B`:e>=1e8?`${N(e/1e6)}M`:e>=1e6?`${N(e/1e6,1)}M`:e>=1e4?`${N(e/1e3)}K`:e>=1e3?`${N(e/1e3,1)}K`:N(e).toString(),Il=e=>{const a=e.slice(-1);return a==="K"?parseInt(e.slice(0,-1),10)*1e3:a==="M"?parseInt(e.slice(0,-1),10)*1e6:a==="B"?parseInt(e.slice(0,-1),10)*1e9:parseInt(e,10)},Dl=e=>{if(e.charAt(0)==="#")return e;const a=e.match(/^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?/i);return a&&a.length===4?"#"+`0${parseInt(a[1],10).toString(16)}`.slice(-2)+`0${parseInt(a[2],10).toString(16)}`.slice(-2)+`0${parseInt(a[3],10).toString(16)}`.slice(-2):""},on=["#dababf","#fb8072","#80b1d3","#fdb462","#b3de69","#fccde5","#c6b9c1","#bc80bd","#ccebc5","#ffed6f","#8dd3c7","#eb8de7"],Bt=e=>{const a=nn(zt);return Xt(()=>Math.random())(Ra(e).map(i=>i<12?on[i]:Z(a((i-12)/(e-12)))?.formatHex())).filter(i=>typeof i=="string")},ge=()=>Z(nn(zt)(Math.random())).formatHex(),Gl=(e,a=.2,n=.3)=>{const t=e&&e[0]==="#"?e:ge();return Z(we(t,ge())(a)).brighter(n).formatHex()},Et=e=>{let a;return e.parentNode?a=e.parentNode:e.host?a=e.host:e.defaultView&&(a=e.defaultView),a!==void 0?[e].concat(Et(a)):[e]},Ol=(e,a=1)=>{for(;document.getElementById(e+a);)a++;return e+a},ql=(e,a,...n)=>jl(e,Array.from,a,n),jl=(e,a,n,t)=>(function i(o,s){if(s>=t.length)return n(o);const h=new Map,u=t[s++];let l=-1;for(const c of o){const d=u(c,++l,o),r=h.get(d);r?r.push(c):h.set(d,[c])}for(const[c,d]of h)h.set(c,i(d,s));return a(h)})(e,0),fe=([e,a],[n,t])=>(e-n)**2+(a-t)**2;class Ul{constructor(a=[],n=(t,i)=>ti?1:0){if(this.data=a,this.length=this.data.length,this.compare=n,this.length>0)for(let t=(this.length>>1)-1;t>=0;t--)this._down(t)}push(a){this.data.push(a),this._up(this.length++)}pop(){if(this.length===0)return;const a=this.data[0],n=this.data.pop();return--this.length>0&&(this.data[0]=n,this._down(0)),a}peek(){return this.data[0]}_up(a){const{data:n,compare:t}=this,i=n[a];for(;a>0;){const o=a-1>>1,s=n[o];if(t(i,s)>=0)break;n[a]=s,a=o}n[a]=i}_down(a){const{data:n,compare:t}=this,i=this.length>>1,o=n[a];for(;a=0)break;n[a]=n[s],a=s}n[a]=o}}function Vl(e,a=1,n=!1){let t=1/0,i=1/0,o=-1/0,s=-1/0;for(const[y,k]of e[0])yo&&(o=y),k>s&&(s=k);const h=o-t,u=s-i,l=Math.max(a,Math.min(h,u));if(l===a){const y=[t,i];return y.distance=0,y}const c=new Ul([],(y,k)=>k.max-y.max);let d=Yl(e);const r=new me(t+h/2,i+u/2,0,e);r.d>d.d&&(d=r);let g=2;function m(y,k,b){const v=new me(y,k,b,e);g++,v.max>d.d+a&&c.push(v),v.d>d.d&&(d=v,n&&console.log(`found best ${Math.round(1e4*v.d)/1e4} after ${g} probes`))}let f=l/2;for(let y=t;ya!=c[1]>a&&e<(c[0]-l[0])*(a-l[1])/(c[1]-l[1])+l[0]&&(t=!t),i=Math.min(i,$l(e,a,l,c))}return i===0?0:(t?1:-1)*Math.sqrt(i)}function Yl(e){let a=0,n=0,t=0;const i=e[0];for(let s=0,h=i.length,u=h-1;s1?(i=t[0],o=t[1]):u>0&&(i+=s*u,o+=h*u)}return s=e-i,h=a-o,s*s+h*h}const Ht=(e,a)=>{const n=a.map(i=>e.p[i]);return`M${n.shift()} L${n.join(" ")} Z`},Gn=(e,a,n)=>{let t=!0,i="";return a.map(s=>{if(n(s))return t=!0,"";const h=t?"M":"L";return t=!1,i=h,` ${h==="L"&&h===i?"":h}${e.p[s]}`}).join("").trim()},Wl=(e,a,n)=>{const t=[];let i=e,o=e;for(;i!==a;)t.push(i),o=n[i],i=o;return t.push(i),t.reverse()},Rt=(e,a,n={polygons:!1,fill:!1,halo:!1,waterGap:!1})=>{const{cells:t,vertices:i}=e,o={},s=new Uint8Array(t.i.length),h=c=>{s[c]=1},u=c=>s[c]===1;for(const c of t.i){if(u(c)||!a(c))continue;h(c);const d=a(c),r=k=>a(k)===d,g=k=>a(k)!==d,m=t.c[c].find(g);if(m===void 0)continue;const f=e.features[t.f[m]];if(f.type==="lake"&&f.shoreline?.every(r))continue;const p=t.v[c].find(k=>i.c[k].some(g));if(p===void 0)throw new Error(`Starting vertex for cell ${c} is not found`);const y=Me({vertices:i,startingVertex:p,ofSameType:r,addToChecked:h,closeRing:!0});y.length<3||l(d,i,y,o,n)}return o;function l(c,d,r,g,m){if(g[c]||(g[c]={}),m.polygons&&(g[c].polygons||(g[c].polygons=[]),g[c].polygons.push(r.map(f=>d.p[f]))),m.fill&&(g[c].fill||(g[c].fill=""),g[c].fill+=Ht(d,r)),m.waterGap){g[c].waterGap||(g[c].waterGap="");const f=p=>d.c[p].every(y=>t.h[y]>=20);g[c].waterGap+=Gn(d,r,f)}if(m.halo){g[c].halo||(g[c].halo="");const f=p=>d.c[p].some(y=>t.b[y]);g[c].halo+=Gn(d,r,f)}}},Zl=(e,a={})=>{const{cells:n,vertices:t}=a,i=Object.fromEntries(e.map(d=>[d,!0])),o=d=>i[d],s=d=>!i[d],h=new Uint8Array(n.c.length),u=d=>{h[d]=1},l=d=>h[d]===1;let c="";for(const d of e){if(l(d))continue;const r=n.c[d].find(s);if(r===void 0)continue;const g=a.features[n.f[r]];if(g.type==="lake"&&g.shoreline&&g.shoreline.every(o))continue;const m=n.v[d].find(p=>t.c[p].some(s));if(m===void 0)throw new Error(`Starting vertex for cell ${d} is not found`);const f=Me({vertices:t,startingVertex:m,ofSameType:o,addToChecked:u,closeRing:!0});f.length<3||(c+=Ht(t,f))}return c},Ql=(e,a)=>{const n=Rt(e,a,{polygons:!0}),t=Object.entries(n).map(([i,o])=>{const s=o.polygons.sort((l,c)=>c.length-l.length),[h,u]=Vl(s,20);return[i,[N(h),N(u)]]});return Object.fromEntries(t)},Me=({vertices:e,startingVertex:a,ofSameType:n,addToChecked:t,closeRing:i})=>{const o=e.c.length,s=[];let h=a;for(let u=0;u===0||h!==a;u++){const l=s.at(-1),c=h;s.push(c);const d=e.c[c];t&&d.filter(n).forEach(t);const[r,g,m]=d.map(n),[f,p,y]=e.v[c];if(f!==l&&r!==g?h=f:p!==l&&g!==m?h=p:y!==l&&r!==m&&(h=y),h>=e.c.length){window.ERROR&&console.error("ConnectVertices: next vertex is out of bounds");break}if(h===c){window.ERROR&&console.error("ConnectVertices: next vertex is not found");break}if(u===o){window.ERROR&&console.error("ConnectVertices: max iterations reached",o);break}}return i&&s.push(a),s},Jl=(e,a,n,t={})=>{if(a(e))return null;const i=[],o=[],s=new window.FlatQueue;for(s.push(e,0);s.length;){const h=s.peekValue(),u=s.pop();for(const l of t.cells.c[u]){if(a(l))return i[l]=u,Wl(l,e,i);const c=n(u,l);if(c===1/0)continue;const d=h+c;d>=o[l]||(i[l]=u,o[l]=d,s.push(l,d))}}return null},ze=(e="",a=1)=>e.replace(/[\d.-][\d.e-]*/g,n=>N(parseFloat(n),a).toString()),Lt=e=>e.charAt(0).toUpperCase()+e.slice(1),Xl=e=>{const a=e.length/2,n=e.split(" ");if(n.length<2)return n;let t="",i="",o="",s="";return n.forEach((h,u)=>{u+1!==n.length&&(h+=" "),s+=h,!t||s.length{if(!e)return[0,0,0,0,0,1];const a=e.replace(/[a-z()]/g,"").replace(/[ ]/g,",").split(",");return[a[0]||0,a[1]||0,a[2]||0,a[3]||0,a[4]||0,a[5]||1]},eu=e=>{try{return JSON.parse(e),!0}catch{return!1}},nu=e=>{try{return JSON.parse(e)}catch{return null}},tu=e=>{if(!e)throw new Error("No string provided");let a=e.toLowerCase().trim().replace(/[^a-z0-9-_]/g,"").replace(/\s+/g,"-");return a.match(/^\d/)&&(a=`_${a}`),a},j=document.getElementById.bind(document);function iu(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var Xa={exports:{}},ru=Xa.exports,On;function ou(){return On||(On=1,(function(e,a){(function(n,t){e.exports=t()})(ru,function(){return n.importState=function(i){var o=new n;return o.importState(i),o},n;function n(){return(function(i){var o=0,s=0,h=0,u=1;i.length==0&&(i=[+new Date]);var l=t();o=l(" "),s=l(" "),h=l(" ");for(var c=0;c>>0,u-=i,u*=i,i=u>>>0,u-=i,i+=u*4294967296}return(i>>>0)*23283064365386963e-26};return o.version="Mash 0.9",o}})})(Xa)),Xa.exports}var su=ou();const Te=iu(su);class lu{delaunay;points;pointsN;cells={v:[],c:[],b:[],i:new Uint32Array};vertices={p:[],v:[],c:[]};constructor(a,n,t){this.delaunay=a,this.points=n,this.pointsN=t,this.vertices;for(let i=0;ithis.triangleOfEdge(u)),this.cells.c[o]=h.map(u=>this.delaunay.triangles[u]).filter(u=>uthis.cells.c[o].length?1:0}const s=this.triangleOfEdge(i);this.vertices.p[s]||(this.vertices.p[s]=this.triangleCenter(s),this.vertices.v[s]=this.trianglesAdjacentToTriangle(s),this.vertices.c[s]=this.pointsOfTriangle(s))}}pointsOfTriangle(a){return this.edgesOfTriangle(a).map(n=>this.delaunay.triangles[n])}trianglesAdjacentToTriangle(a){const n=[];for(const t of this.edgesOfTriangle(a)){const i=this.delaunay.halfedges[t];n.push(this.triangleOfEdge(i))}return n}edgesAroundPoint(a){const n=[];let t=a;do{n.push(t);const i=this.nextHalfedge(t);t=this.delaunay.halfedges[i]}while(t!==-1&&t!==a&&n.length<20);return n}triangleCenter(a){const n=this.pointsOfTriangle(a).map(t=>this.points[t]);return this.circumcenter(n[0],n[1],n[2])}edgesOfTriangle(a){return[3*a,3*a+1,3*a+2]}triangleOfEdge(a){return Math.floor(a/3)}nextHalfedge(a){return a%3===2?a-2:a+1}circumcenter(a,n,t){const[i,o]=a,[s,h]=n,[u,l]=t,c=i*i+o*o,d=s*s+h*h,r=u*u+l*l,g=2*(i*(h-l)+s*(l-o)+u*(o-h));return[Math.floor(1/g*(c*(h-l)+d*(l-o)+r*(o-h))),Math.floor(1/g*(c*(u-s)+d*(i-u)+r*(s-i)))]}}const uu=(e,a,n)=>{const t=N(-1*n),i=n*2,o=e-t*2,s=a-t*2,h=Math.ceil(o/i)-1,u=Math.ceil(s/i)-1,l=[];for(let c=.5;c{const t=n/2,i=t*.9,o=i*2,s=()=>Math.random()*o-i,h=[];for(let u=t;u{TIME&&console.time("placePoints");const n=+(j("pointsInput")?.dataset.cells||0),t=N(Math.sqrt(e*a/n),2),i=uu(e,a,t),o=hu(e,a,t),s=Math.floor((e+.5*t-1e-10)/t),h=Math.floor((a+.5*t-1e-10)/t);return TIME&&console.timeEnd("placePoints"),{spacing:t,cellsDesired:n,boundary:i,points:o,cellsX:s,cellsY:h}},du=(e,a,n,t)=>{if(a&&a!==e.seed)return!0;const i=+(j("pointsInput")?.dataset?.cells||0);if(i!==e.cellsDesired)return!0;const o=N(Math.sqrt(n*t/i),2),s=Math.floor((n+.5*o-1e-10)/o),h=Math.floor((t+.5*o-1e-10)/o);return e.spacing!==o||e.cellsX!==s||e.cellsY!==h},gu=(e,a,n)=>{Math.random=Te(e);const{spacing:t,cellsDesired:i,boundary:o,points:s,cellsX:h,cellsY:u}=cu(a,n),{cells:l,vertices:c}=Pt(s,o);return{spacing:t,cellsDesired:i,boundary:o,points:s,cellsX:h,cellsY:u,cells:l,vertices:c,seed:e}},Pt=(e,a)=>{TIME&&console.time("calculateDelaunay");const n=e.concat(a),t=Xe.from(n);TIME&&console.timeEnd("calculateDelaunay"),TIME&&console.time("calculateVoronoi");const i=new lu(t,n,e.length),o=i.cells;o.i=pe({maxValue:e.length,length:e.length}).map((h,u)=>u);const s=i.vertices;return TIME&&console.timeEnd("calculateVoronoi"),{cells:o,vertices:s}},X=(e,a,n)=>Math.floor(Math.min(a/n.spacing,n.cellsY-1))*n.cellsX+Math.floor(Math.min(e/n.spacing,n.cellsX-1)),fu=(e,a,n,t)=>{const i=t.cells.c;let o=Math.floor(n/t.spacing),s=[X(e,a,t)];if(!o||n===1)return s;if(o>0&&(s=s.concat(i[s[0]])),o>1){let h=i[s[0]];for(;o>1;){const u=h.slice();h=[],u.forEach(l=>{i[l].forEach(c=>{s.indexOf(c)===-1&&(s.push(c),h.push(c))})}),o--}}return s},mu=(e,a,n=1/0,t)=>{if(!t.cells?.q)return;const i=t.cells.q.find(e,a,n);return i?i[2]:void 0},It=(e,a,n,t)=>{let i,o,s;const h=(d,r)=>{d.result=[],d.x0=d.x-r,d.y0=d.y-r,d.x3=d.x+r,d.y3=d.y+r,d.radius=r*r},u=(d,r)=>{if(d.node.data.scanned=!0,rc.x3||c.y1>c.y3||c.x2=r)<<1|+(e>=d),c.i&&(c.q=c.quads[c.quads.length-1],c.quads[c.quads.length-1]=c.quads[c.quads.length-1-c.i],c.quads[c.quads.length-1-c.i]=c.q)}else i=e-+t._x.call(null,c.node.data),o=a-+t._y.call(null,c.node.data),s=i*i+o*o,u(c,s);c.q=c.quads.pop()}return c.result},pu=(e,a,n,t)=>It(e,a,n,t.cells.q).map(o=>o[2]),yu=(e,a)=>a.cells.v[e].map(n=>a.vertices.p[n]),Dt=(e,a)=>a.cells.v[e].map(n=>a.vertices.p[n]);function*ku(e,a,n,t,i,o=3){if(!(n>=e)||!(t>=a)||!(i>0))throw new Error;const s=n-e,h=t-a,u=i*i,l=3*u,c=i*Math.SQRT1_2,d=Math.ceil(s/c),r=Math.ceil(h/c),g=new Array(d*r),m=[];function f(y,k){const b=y/c|0,v=k/c|0,w=Math.max(b-2,0),_=Math.max(v-2,0),M=Math.min(b+3,d),T=Math.min(v+3,r);for(let S=_;Sa.cells.h[e]>=20,Gt=(e,a)=>a.cells.h[e]<20,bu=({heights:e,width:a,height:n,scheme:t,renderOcean:i})=>{const o=document.createElement("canvas");o.width=a,o.height=n;const s=o.getContext("2d"),h=s.createImageData(a,n),u=l=>l<20?i?l:0:l;for(let l=0;le.length<2?e:e.some(i=>i===void 0)?(window.ERROR&&console.error("Undefined point in clipPoly",e),e):window.polygonclip(e,[0,0,a,n],t),vu=(e,a,n=10)=>{if(e.length===2)return 1;let t=1,i=1/0;for(let o=0;o=i||(i=f,t=o+1)}}return t},wu=(e,a)=>{let n=!1;return function(...t){n||(e.apply(this,t),n=!0,setTimeout(()=>{n=!1},a))}},Au=(e,a)=>{let n=!1,t=null,i=null;function o(...s){if(n){t=s,i=this;return}e.apply(this,s),n=!0,setTimeout(()=>{n=!1,t&&(o.apply(i,t),t=i=null)},a)}return o},Su=e=>{const n=navigator.userAgent.toLowerCase().indexOf("firefox")>-1?`${e.toString()} ${e.stack}`:e.stack||"",t=/(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#/%?=~_|!:,.;]*[-A-Z0-9+&@#/%=~_|])/gi;return n.replace(t,s=>`${Ea(s.split("/"))}`).replace(/at /gi,"
  at ")},_u=(e,a)=>{const n=new XMLHttpRequest;n.onload=()=>{const t=new FileReader;t.onloadend=()=>{a(t.result)},t.readAsDataURL(n.response)},n.open("GET",e),n.responseType="blob",n.send()},Mu=e=>{window.open(e,"_blank")},zu=e=>{window.open(`https://github.com/Azgaar/Fantasy-Map-Generator/wiki/${e}`,"_blank")},Tu=(e,a)=>`${a}`,xu=e=>e.ctrlKey||e.metaKey,Nu=(e=100,a=1e3)=>new Date(Y(e,a),Y(12),Y(31)).toLocaleDateString("en",{year:"numeric",month:"long",day:"numeric"}),Ot=(e,a,n,t=2)=>N(a.lonW+e/n*a.lonT,t),qt=(e,a,n,t=2)=>N(a.latN-e/n*a.latT,t),Cu=(e,a,n,t,i,o=2)=>[Ot(e,n,t,o),qt(a,n,i,o)],qn=()=>{const e=document.getElementById("prompt");if(!e)return;const a=e.querySelector("#promptForm");if(!a)return;const n="Please provide an input",t={default:1,step:.01,min:0,max:100,required:!0};window.prompt=(o=n,s=t,h)=>{if(s.default===void 0)return window.ERROR&&console.error("Prompt: options object does not have default value defined");const u=e.querySelector("#promptInput"),l=e.querySelector("#promptText");if(!u||!l)return;l.innerHTML=o;const c=typeof s.default=="number"?"number":"text";u.type=c,s.step!==void 0&&(u.step=s.step.toString()),s.min!==void 0&&(u.min=s.min.toString()),s.max!==void 0&&(u.max=s.max.toString()),u.required=s.required!==!1,u.placeholder=`type a ${c}`,u.value=s.default.toString(),u.style.width=o.length>10?"100%":"auto",e.style.display="block",a.addEventListener("submit",d=>{d.preventDefault(),e.style.display="none";const r=c==="number"?+u.value:u.value;h&&h(r)},{once:!0})};const i=e.querySelector("#promptCancel");i&&i.addEventListener("click",()=>{e.style.display="none"})},Ku=(e,a)=>{window.debug.selectAll("text").remove(),window.debug.selectAll("text").data(e).enter().append("text").attr("x",(n,t)=>a.cells.p[t][0]).attr("y",(n,t)=>a.cells.p[t][1]).text(n=>n)},Bu=(e,a,n)=>{const t=Vn(e),i=Ba(e),o=window.getColorScheme(a.select("#landHeights").attr("scheme"));e=e.map(s=>1-ee(s,i,t)),window.debug.selectAll("polygon").remove(),window.debug.selectAll("polygon").data(e).enter().append("polygon").attr("points",(s,h)=>Dt(h,n)).attr("fill",s=>o(s)).attr("stroke",s=>o(s))},Eu=e=>{window.debug.select("#connections").remove();const a=window.debug.append("g").attr("id","connections").attr("stroke-width",.8),n=e.cells.p,t=e.cells.routes;for(const i in t)for(const o in t[i]){const[s,h]=n[i],[u,l]=n[o],[c,d]=[(s+u)/2,(h+l)/2],r=t[i][o];a.append("line").attr("x1",s).attr("y1",h).attr("x2",c).attr("y2",d).attr("data-id",r).attr("stroke",on[r%12])}},Hu=([e,a],{color:n="red",radius:t=.5})=>{window.debug.append("circle").attr("cx",e).attr("cy",a).attr("r",t).attr("fill",n)},Ru=(e,{color:a="red",width:n=.5})=>{const t=tn().curve(xl);window.debug.append("path").attr("d",ze(t(e))).attr("stroke",a).attr("stroke-width",n).attr("fill","none")};window.rn=N;window.lim=V;window.minmax=ma;window.normalize=ee;window.lerp=Ut;window.vowel=q;window.trimVowels=ua;window.getAdjective=El;window.nth=Hl;window.abbreviate=Ue;window.list=Rl;window.last=Ea;window.unique=jn;window.deepCopy=Vt;window.getTypedArray=Un;window.createTypedArray=pe;window.INT8_MAX=ea.INT8_MAX;window.UINT8_MAX=ea.UINT8_MAX;window.UINT16_MAX=ea.UINT16_MAX;window.UINT32_MAX=ea.UINT32_MAX;window.rand=Y;window.P=B;window.each=ba;window.gauss=Qa;window.Pint=Kl;window.ra=Ja;window.rw=de;window.biased=Kt;window.getNumberInRange=J;window.generateSeed=Bl;window.convertTemperature=(e,a=window.temperatureScale.value||"°C")=>Ll(e,a);window.si=Pl;window.getInteger=Il;window.toHEX=Dl;window.getColors=Bt;window.getRandomColor=ge;window.getMixedColor=Gl;window.C_12=on;window.getComposedPath=Et;window.getNextId=Ol;window.rollups=ql;window.dist2=fe;window.getIsolines=Rt;window.getPolesOfInaccessibility=Ql;window.connectVertices=Me;window.findPath=(e,a,n)=>Jl(e,a,n,window.pack);window.getVertexPath=e=>Zl(e,window.pack);window.round=ze;window.capitalize=Lt;window.splitInTwo=Xl;window.parseTransform=au;window.sanitizeId=tu;JSON.isValid=eu;JSON.safeParse=nu;window.byId=j;Node.prototype.on=function(e,a,n){return this.addEventListener(e,a,n),this};Node.prototype.off=function(e,a){return this.removeEventListener(e,a),this};window.shouldRegenerateGrid=(e,a)=>du(e,a,window.graphWidth,window.graphHeight);window.generateGrid=()=>gu(window.seed,window.graphWidth,window.graphHeight);window.findGridAll=(e,a,n)=>fu(e,a,n,window.grid);window.findGridCell=(e,a)=>X(e,a,window.grid);window.findCell=(e,a,n)=>mu(e,a,n,window.pack);window.findAll=(e,a,n)=>pu(e,a,n,window.pack);window.getPackPolygon=e=>yu(e,window.pack);window.getGridPolygon=e=>Dt(e,window.grid);window.calculateVoronoi=Pt;window.poissonDiscSampler=ku;window.findAllInQuadtree=It;window.drawHeights=bu;window.isLand=e=>ae(e,window.pack);window.isWater=e=>Gt(e,window.pack);window.clipPoly=(e,a)=>sn(e,graphWidth,graphHeight,a);window.getSegmentId=vu;window.debounce=wu;window.throttle=Au;window.parseError=Su;window.getBase64=_u;window.openURL=Mu;window.wiki=zu;window.link=Tu;window.isCtrlClick=xu;window.generateDate=Nu;window.getLongitude=(e,a)=>Ot(e,mapCoordinates,graphWidth,a);window.getLatitude=(e,a)=>qt(e,mapCoordinates,graphHeight,a);window.getCoordinates=(e,a,n)=>Cu(e,a,mapCoordinates,graphWidth,graphHeight,n);document.readyState==="loading"?document.addEventListener("DOMContentLoaded",qn):qn();window.drawCellsValue=e=>Ku(e,window.pack);window.drawPolygons=e=>Bu(e,window.terrs,window.grid);window.drawRouteConnections=()=>Eu(window.packedGraph);window.drawPoint=Hu;window.drawPath=Ru;class Lu{grid=null;heights=null;blobPower=0;linePower=0;clearData(){this.heights=null,this.grid=null}getBlobPower(a){return{1e3:.93,2e3:.95,5e3:.97,1e4:.98,2e4:.99,3e4:.991,4e4:.993,5e4:.994,6e4:.995,7e4:.9955,8e4:.996,9e4:.9964,1e5:.9973}[a]||.98}getLinePower(a){return{1e3:.75,2e3:.77,5e3:.79,1e4:.81,2e4:.82,3e4:.83,4e4:.84,5e4:.86,6e4:.87,7e4:.88,8e4:.91,9e4:.92,1e5:.93}[a]||.81}getPointInRange(a,n){if(typeof a!="string"){window.ERROR&&console.error("Range should be a string");return}const t=parseInt(a.split("-")[0],10)/100||0,i=parseInt(a.split("-")[1],10)/100||t;return Y(t*n,i*n)}setGraph(a){const{cellsDesired:n,cells:t,points:i}=a;this.heights=t.h?Uint8Array.from(t.h):pe({maxValue:100,length:i.length}),this.blobPower=this.getBlobPower(n),this.linePower=this.getLinePower(n),this.grid=a}addHill(a,n,t,i){const o=()=>{if(!this.heights||!this.grid)return;const h=new Uint8Array(this.heights.length);let u=0,l;const c=V(J(n));do{const r=this.getPointInRange(t,graphWidth),g=this.getPointInRange(i,graphHeight);if(r===void 0||g===void 0)return;l=X(r,g,this.grid),u++}while(this.heights[l]+c>90&&u<50);h[l]=c;const d=[l];for(;d.length;){const r=d.shift();for(const g of this.grid.cells.c[r])h[g]||(h[g]=h[r]**this.blobPower*(Math.random()*.2+.9),h[g]>1&&d.push(g))}this.heights=this.heights.map((r,g)=>V(r+h[g]))},s=J(a);for(let h=0;h{if(!this.heights||!this.grid)return;const h=new Uint8Array(this.heights.length);let u=0,l,c=V(J(n));do{const r=this.getPointInRange(t,graphWidth),g=this.getPointInRange(i,graphHeight);if(r===void 0||g===void 0)return;l=X(r,g,this.grid),u++}while(this.heights[l]<20&&u<50);const d=[l];for(;d.length;){const r=d.shift();if(c=c**this.blobPower*(Math.random()*.2+.9),c<1)return;this.grid.cells.c[r].forEach(g=>{h[g]||this.heights===null||(this.heights[g]=V(this.heights[g]-c*(Math.random()*.2+.9)),h[g]=1,d.push(g))})}},s=J(a);for(let h=0;h{if(!this.heights||!this.grid)return;const l=(f,p)=>{const y=[f],k=this.grid.points;for(c[f]=1;f!==p;){let b=1/0;if(this.grid.cells.c[f].forEach(v=>{if(c[v])return;let w=(k[p][0]-k[v][0])**2+(k[p][1]-k[v][1])**2;Math.random()>.85&&(w=w/2),wgraphWidth/3)&&k<50);o=X(f,p,this.grid),s=X(v,b,this.grid)}const r=l(o,s);let g=r.slice(),m=0;for(;g.length;){const f=g.slice();if(g=[],m++,f.forEach(p=>{this.heights&&(this.heights[p]=V(this.heights[p]+d*(Math.random()*.3+.85)))}),d=d**this.linePower-1,d<2)break;f.forEach(p=>{this.grid.cells.c[p].forEach(y=>{c[y]||(g.push(y),c[y]=1)})})}r.forEach((f,p)=>{if(p%6===0)for(const y of Ra(m)){const k=ln(this.grid.cells.c[f],(v,w)=>this.heights[v]-this.heights[w]);if(k===void 0)continue;const b=this.grid.cells.c[f][k];this.heights[b]=(this.heights[f]*2+this.heights[b])/3,f=b}})},u=J(a);for(let l=0;l{if(!this.heights||!this.grid)return;const l=(f,p)=>{const y=[f],k=this.grid.points;for(c[f]=1;f!==p;){let b=1/0;if(this.grid.cells.c[f].forEach(v=>{if(c[v])return;let w=(k[p][0]-k[v][0])**2+(k[p][1]-k[v][1])**2;Math.random()>.8&&(w=w/2),wgraphWidth/2)&&f<50);s=X(b,v,this.grid)}const r=l(o,s);let g=r.slice(),m=0;for(;g.length;){const f=g.slice();if(g=[],m++,f.forEach(p=>{this.heights[p]=V(this.heights[p]-d*(Math.random()*.3+.85))}),d=d**this.linePower-1,d<2)break;f.forEach(p=>{this.grid.cells.c[p].forEach(y=>{c[y]||(g.push(y),c[y]=1)})})}r.forEach((f,p)=>{if(p%6===0)for(const y of Ra(m)){const k=ln(this.grid.cells.c[f],(v,w)=>this.heights[v]-this.heights[w]);if(k===void 0)continue;const b=this.grid.cells.c[f][k];this.heights[b]=(this.heights[f]*2+this.heights[b])/3,f=b}})},u=J(a);for(let l=0;l{const k=[],b=this.grid.points;for(;p!==y;){let v=1/0;this.grid.cells.c[p].forEach(w=>{let _=(b[y][0]-b[w][0])**2+(b[y][1]-b[w][1])**2;Math.random()>.8&&(_=_/2),_{this.grid.cells.c[k].forEach(b=>{i[b]||(i[b]=1,m.push(b),this.heights[b]**=y,this.heights[b]>100&&(this.heights[b]=5))})}),g=m.slice()}}modify(a,n,t,i){if(!this.heights)return;const o=a==="land"?20:a==="all"?0:+a.split("-")[0],s=a==="land"||a==="all"?100:+a.split("-")[1],h=o===20;this.heights=this.heights.map(u=>us?u:(n&&(u=h?Math.max(u+n,20):u+n),t!==1&&(u=h?(u-20)*t+20:u*t),i&&(u=h?(u-20)**i+20:u**i),V(u)))}smooth(a=2,n=0){!this.heights||!this.grid||(this.heights=this.heights.map((t,i)=>{const o=[t];return this.grid.cells.c[i].forEach(s=>{o.push(this.heights[s])}),a===1?Ha(o)+n:V((t*(a-1)+Ha(o)+n)/a)}))}mask(a=1){if(!this.heights||!this.grid)return;const n=a?Math.abs(a):1;this.heights=this.heights.map((t,i)=>{const[o,s]=this.grid.points[i],h=2*o/graphWidth-1,u=2*s/graphHeight-1;let l=(1-h**2)*(1-u**2);a<0&&(l=1-l);const c=t*l;return V((t*(n-1)+c)/n)})}invert(a,n){if(!B(a)||!this.heights||!this.grid)return;const t=n!=="y",i=n!=="x",{cellsX:o,cellsY:s}=this.grid,h=this.heights.map((u,l)=>{if(!this.heights)return 0;const c=l%o,d=Math.floor(l/o),r=t?o-c-1:c,g=i?s-d-1:d,m=r+g*o;return this.heights[m]});this.heights=h}addStep(a,n,t,i,o){if(a==="Hill"){this.addHill(n,t,i,o);return}if(a==="Pit"){this.addPit(n,t,i,o);return}if(a==="Range"){this.addRange(n,t,i,o);return}if(a==="Trough"){this.addTrough(n,t,i,o);return}if(a==="Strait"){this.addStrait(n,t);return}if(a==="Mask"){this.mask(+n);return}if(a==="Invert"){this.invert(+n,t);return}if(a==="Add"){this.modify(t,+n,1);return}if(a==="Multiply"){this.modify(t,0,+n);return}if(a==="Smooth"){this.smooth(+n);return}}async generate(a){TIME&&console.time("defineHeightmap");const n=j("templateInput").value;Math.random=Te(seed);const i=n in heightmapTemplates?this.fromTemplate(a,n):await this.fromPrecreated(a,n);return TIME&&console.timeEnd("defineHeightmap"),this.clearData(),i}fromTemplate(a,n){const i=(heightmapTemplates[n]?.template||"").split(` +`);if(!i.length)throw new Error(`Heightmap template: no steps. Template: ${n}. Steps: ${i}`);this.setGraph(a);for(const o of i){const s=o.trim().split(" ");if(s.length<2)throw new Error(`Heightmap template: steps < 2. Template: ${n}. Step: ${s}`);this.addStep(...s)}return this.heights}getHeightsFromImageData(a){if(this.heights)for(let n=0;n{const i=document.createElement("canvas"),o=i.getContext("2d"),{cellsX:s,cellsY:h}=a;i.width=s,i.height=h;const u=new Image;u.src=`./heightmaps/${n}.png`,u.onload=()=>{if(!o)throw new Error("Could not get canvas context");this.heights=this.heights||new Uint8Array(s*h),o.drawImage(u,0,0,s,h);const l=o.getImageData(0,0,s,h);this.setGraph(a),this.getHeightsFromImageData(l.data),i.remove(),u.remove(),t(this.heights)}})}getHeights(){return this.heights}}window.HeightmapGenerator=new Lu;class Pu{DEEPER_LAND=3;LANDLOCKED=2;LAND_COAST=1;UNMARKED=0;WATER_COAST=-1;DEEP_WATER=-2;markup({distanceField:a,neighbors:n,start:t,increment:i,limit:o=ea.INT8_MAX}){for(let s=t,h=1/0;h>0&&s!==o;s+=i){h=0;const u=s-i;for(let l=0;l=20;let g=!1;for(;l.length;){const f=l.pop();!g&&t[f]&&(g=!0);for(const p of n[f]){const y=a[p]>=20;r===y&&h[p]===this.UNMARKED?(h[p]=c,l.push(p)):r&&!y&&(s[f]=this.LAND_COAST,s[p]=this.WATER_COAST)}}const m=r?"island":g?"ocean":"lake";u.push({i:c,land:r,border:g,type:m}),l[0]=h.indexOf(this.UNMARKED)}this.markup({distanceField:s,neighbors:n,start:this.DEEP_WATER,increment:-1,limit:-10}),grid.cells.t=s,grid.cells.f=h,grid.features=[0,...u],TIME&&console.timeEnd("markupGrid")}markupPack(){const a=p=>{const y=s[p].filter(v=>Gt(v,pack)),k=y.map(v=>fe(i.p[p],i.p[v])),b=k.indexOf(Math.min.apply(Math,k));r[p]=y[b],g[p]=y.length},n=(p,y)=>{if(p==="ocean")return[y,[]];const k=z=>d[z],b=k(y),v=z=>k(z)===b,w=z=>k(z)!==b,_=T(y),M=S(_);return[_,M];function T(z){const A=C=>h[C]||s[C].some(w);if(A(z))return z;const x=i.i.filter(v).find(A);if(x===void 0)throw new Error(`Markup: firstCell ${z} is not on the feature or map border`);return x}function S(z){const A=i.v[z].find(x=>o.c[x].some(w));if(A===void 0)throw new Error(`Markup: startingVertex for cell ${z} is not found`);return Me({vertices:o,startingVertex:A,ofSameType:v,closeRing:!1})}},t=({firstCell:p,land:y,border:k,featureId:b,totalCells:v})=>{const w=y?"island":k?"ocean":"lake",[_,M]=n(w,p),T=sn(M.map(x=>o.p[x])),S=gl(T),z=Math.abs(N(S)),A={i:b,type:w,land:y,border:k,cells:v,firstCell:_,vertices:M,area:z,shoreline:[],height:0};return w==="lake"&&(S>0&&(A.vertices=A.vertices.reverse()),A.shoreline=jn(A.vertices.flatMap(x=>o.c[x].filter(C=>ae(C,pack)))),A.height=Lakes.getHeight(A)),{...A}};TIME&&console.time("markupPack");const{cells:i,vertices:o}=pack,{c:s,b:h,i:u}=i,l=u.length;if(!l)return;const c=new Int8Array(l),d=new Uint16Array(l),r=pe({maxValue:l,length:l}),g=new Uint8Array(l),m=[],f=[0];for(let p=1;f[0]!==-1;p++){const y=f[0];d[y]=p;const k=ae(y,pack);let b=!!h[y],v=1;for(;f.length;){const w=f.pop();h[w]&&(b=!0);for(const _ of s[w]){const M=ae(_,pack);k&&!M?(c[w]=this.LAND_COAST,c[_]=this.WATER_COAST,r[w]||a(w)):k&&M&&(c[_]===this.UNMARKED&&c[w]===this.LAND_COAST?c[_]=this.LANDLOCKED:c[w]===this.UNMARKED&&c[_]===this.LAND_COAST&&(c[w]=this.LANDLOCKED)),!d[_]&&k===M&&(f.push(_),d[_]=p,v++)}}m.push(t({firstCell:y,land:k,border:b,featureId:p,totalCells:v})),f[0]=d.indexOf(this.UNMARKED)}this.markup({distanceField:c,neighbors:s,start:this.DEEPER_LAND,increment:1}),this.markup({distanceField:c,neighbors:s,start:this.DEEP_WATER,increment:-1,limit:-10}),pack.cells.t=c,pack.cells.f=d,pack.cells.haven=r,pack.cells.harbor=g,pack.features=[0,...m],TIME&&console.timeEnd("markupPack")}defineGroups(){const a=grid.cells.i.length,n=a/25,t=a/1e3,i=a/10,o=a/1e3,s=c=>{const d=pack.features[pack.cells.f[c.firstCell-1]];return d&&d.type==="lake"?"lake_island":c.cells>i?"continent":c.cells>o?"island":"isle"},h=c=>c.cells>n?"ocean":c.cells>t?"sea":"gulf",u=c=>{if(c.temp<-3)return"frozen";if(c.height>60&&c.cells<10&&c.firstCell%10===0)return"lava";if(!c.inlets&&!c.outlet){if(c.evaporation>c.flux*4)return"dry";if(c.cells<3&&c.firstCell%10===0)return"sinkhole"}return!c.outlet&&c.evaporation>c.flux?"salt":"freshwater"},l=c=>{if(c.type==="island")return s(c);if(c.type==="ocean")return h(c);if(c.type==="lake")return u(c);throw new Error(`Markup: unknown feature type ${c.type}`)};for(const c of pack.features)!c||c.type==="ocean"||(c.type==="lake"&&(c.height=Lakes.getHeight(c)),c.group=l(c))}}window.Features=new Pu;class Iu{chains=[];calculateChain(a){const n=[],t=a.split(",");for(const i of t){const o=i.trim().toLowerCase(),s=!/[^\x20-\x7e]/.test(o);for(let h=-1,u="";ht){u.lengthr===m[g+1]&&!i.includes(r)?d:d.length?d.slice(-1)==="-"&&r===" "?d:d.slice(-1)===" "||d.slice(-1)==="-"?d+r.toUpperCase():r==="a"&&m[g+1]==="e"||g+2d.length<2)&&(c=c.split(" ").map((d,r)=>r?d.toLowerCase():d).join("")),c.length<2&&(ERROR&&console.error("Name is too short! Random name will be selected"),c=Ja(nameBases[a].b.split(","))),c}getCulture(a,n,t,i){if(a===void 0)return ERROR&&console.error("Please define a culture"),"ERROR";const o=pack.cultures[a].base;return this.getBase(o,n,t,i)}getCultureShort(a){return a===void 0?(ERROR&&console.error("Please define a culture"),"ERROR"):this.getBaseShort(pack.cultures[a].base)}getBaseShort(a){const n=nameBases[a]?nameBases[a].min-1:void 0,t=n?Math.max(nameBases[a].max-2,n):void 0;return this.getBase(a,n,t,"")}validateSuffix(a,n){if(a.slice(-1*n.length)===n)return a;const t=n.charAt(0);return a.slice(-1)===t&&(a=a.slice(0,-1)),q(t)===q(a.slice(-1))&&q(t)===q(a.slice(-2,-1))&&(a=a.slice(0,-1)),a.slice(-1)===t&&(a=a.slice(0,-1)),a+n}addSuffix(a){const n=B(.8)?"ia":"land";return n==="ia"&&a.length>6?a=a.slice(0,-(a.length-3)):n==="land"&&a.length>6&&(a=a.slice(0,-(a.length-5))),this.validateSuffix(a,n)}getState(a,n,t){if(a===void 0)return ERROR&&console.error("Please define a base name"),"ERROR";if(n===void 0&&t===void 0)return ERROR&&console.error("Please define a culture"),"ERROR";if(t===void 0&&(t=pack.cultures[n].base),a.includes(" ")&&(a=Lt(a.replace(/ /g,"").toLowerCase())),a.length>6&&a.slice(-4)==="berg"&&(a=a.slice(0,-4)),a.length>5&&a.slice(-3)==="ton"&&(a=a.slice(0,-3)),t===5&&["sk","ev","ov"].includes(a.slice(-2)))a=a.slice(0,-2);else{if(t===12)return q(a.slice(-1))?a:`${a}u`;t===18&&B(.4)&&(a=q(a.slice(0,1).toLowerCase())?`Al${a.toLowerCase()}`:`Al ${a}`)}if(t>32&&t<42)return a;if(a.length>3&&q(a.slice(-1)))if(q(a.slice(-2,-1))&&B(.85))a=a.slice(0,-2);else if(B(.7))a=a.slice(0,-1);else return a;else if(B(.4))return a;let i="ia";const o=Math.random(),s=a.length;return t===3&&o<.03&&s<7||t===4&&o<.03&&s<7||t===13&&o<.03&&s<7?i="terra":t===2&&o<.03&&s<7?i="terre":t===0&&o<.5&&s<7||t===1&&o<.4&&s<7||t===6&&o<.3&&s<7||t===32&&o<.1&&s<7?i="land":t===7&&o<.1?i="eia":t===9&&o<.35?i="maa":t===15&&o<.4&&s<6?i="orszag":t===16?i=o<.6?"yurt":"eli":t===10?i="guk":t===11?i=" Guo":t===14?i=o<.5&&s<6?"tlan":"co":(t===17&&o<.8||t===18&&o<.8)&&(i="a"),this.validateSuffix(a,i)}getMapName(a){if(!a&&locked("mapName"))return;a&&locked("mapName")&&unlock("mapName");const n=B(.7)?2:B(.5)?Y(0,6):Y(0,31);if(!nameBases[n])return tip("Namebase is not found",!1,"error"),"";const t=nameBases[n].min-1,i=Math.max(nameBases[n].max-3,t),o=this.getBase(n,t,i,""),s=B(.7)?this.addSuffix(o):o;mapName.value=s}getNameBases(){return[{name:"German",i:0,min:5,max:12,d:"lt",m:0,b:"Achern,Aichhalden,Aitern,Albbruck,Alpirsbach,Altensteig,Althengstett,Appenweier,Auggen,Badenen,Badenweiler,Baiersbronn,Ballrechten,Bellingen,Berghaupten,Bernau,Biberach,Biederbach,Binzen,Birkendorf,Birkenfeld,Bischweier,Blumberg,Bollen,Bollschweil,Bonndorf,Bosingen,Braunlingen,Breisach,Breisgau,Breitnau,Brigachtal,Buchenbach,Buggingen,Buhl,Buhlertal,Calw,Dachsberg,Dobel,Donaueschingen,Dornhan,Dornstetten,Dottingen,Dunningen,Durbach,Durrheim,Ebhausen,Ebringen,Efringen,Egenhausen,Ehrenkirchen,Ehrsberg,Eimeldingen,Eisenbach,Elzach,Elztal,Emmendingen,Endingen,Engelsbrand,Enz,Enzklosterle,Eschbronn,Ettenheim,Ettlingen,Feldberg,Fischerbach,Fischingen,Fluorn,Forbach,Freiamt,Freiburg,Freudenstadt,Friedenweiler,Friesenheim,Frohnd,Furtwangen,Gaggenau,Geisingen,Gengenbach,Gernsbach,Glatt,Glatten,Glottertal,Gorwihl,Gottenheim,Grafenhausen,Grenzach,Griesbach,Gutach,Gutenbach,Hag,Haiterbach,Hardt,Harmersbach,Hasel,Haslach,Hausach,Hausen,Hausern,Heitersheim,Herbolzheim,Herrenalb,Herrischried,Hinterzarten,Hochenschwand,Hofen,Hofstetten,Hohberg,Horb,Horben,Hornberg,Hufingen,Ibach,Ihringen,Inzlingen,Kandern,Kappel,Kappelrodeck,Karlsbad,Karlsruhe,Kehl,Keltern,Kippenheim,Kirchzarten,Konigsfeld,Krozingen,Kuppenheim,Kussaberg,Lahr,Lauchringen,Lauf,Laufenburg,Lautenbach,Lauterbach,Lenzkirch,Liebenzell,Loffenau,Loffingen,Lorrach,Lossburg,Mahlberg,Malsburg,Malsch,March,Marxzell,Marzell,Maulburg,Monchweiler,Muhlenbach,Mullheim,Munstertal,Murg,Nagold,Neubulach,Neuenburg,Neuhausen,Neuried,Neuweiler,Niedereschach,Nordrach,Oberharmersbach,Oberkirch,Oberndorf,Oberbach,Oberried,Oberwolfach,Offenburg,Ohlsbach,Oppenau,Ortenberg,otigheim,Ottenhofen,Ottersweier,Peterstal,Pfaffenweiler,Pfalzgrafenweiler,Pforzheim,Rastatt,Renchen,Rheinau,Rheinfelden,Rheinmunster,Rickenbach,Rippoldsau,Rohrdorf,Rottweil,Rummingen,Rust,Sackingen,Sasbach,Sasbachwalden,Schallbach,Schallstadt,Schapbach,Schenkenzell,Schiltach,Schliengen,Schluchsee,Schomberg,Schonach,Schonau,Schonenberg,Schonwald,Schopfheim,Schopfloch,Schramberg,Schuttertal,Schwenningen,Schworstadt,Seebach,Seelbach,Seewald,Sexau,Simmersfeld,Simonswald,Sinzheim,Solden,Staufen,Stegen,Steinach,Steinen,Steinmauern,Straubenhardt,Stuhlingen,Sulz,Sulzburg,Teinach,Tiefenbronn,Tiengen,Titisee,Todtmoos,Todtnau,Todtnauberg,Triberg,Tunau,Tuningen,uhlingen,Unterkirnach,Reichenbach,Utzenfeld,Villingen,Villingendorf,Vogtsburg,Vohrenbach,Waldachtal,Waldbronn,Waldkirch,Waldshut,Wehr,Weil,Weilheim,Weisenbach,Wembach,Wieden,Wiesental,Wildbad,Wildberg,Winzeln,Wittlingen,Wittnau,Wolfach,Wutach,Wutoschingen,Wyhlen,Zavelstein"},{name:"English",i:1,min:6,max:11,d:"",m:.1,b:"Abingdon,Albrighton,Alcester,Almondbury,Altrincham,Amersham,Andover,Appleby,Ashboume,Atherstone,Aveton,Axbridge,Aylesbury,Baldock,Bamburgh,Barton,Basingstoke,Berden,Bere,Berkeley,Berwick,Betley,Bideford,Bingley,Birmingham,Blandford,Blechingley,Bodmin,Bolton,Bootham,Boroughbridge,Boscastle,Bossinney,Bramber,Brampton,Brasted,Bretford,Bridgetown,Bridlington,Bromyard,Bruton,Buckingham,Bungay,Burton,Calne,Cambridge,Canterbury,Carlisle,Castleton,Caus,Charmouth,Chawleigh,Chichester,Chillington,Chinnor,Chipping,Chisbury,Cleobury,Clifford,Clifton,Clitheroe,Cockermouth,Coleshill,Combe,Congleton,Crafthole,Crediton,Cuddenbeck,Dalton,Darlington,Dodbrooke,Drax,Dudley,Dunstable,Dunster,Dunwich,Durham,Dymock,Exeter,Exning,Faringdon,Felton,Fenny,Finedon,Flookburgh,Fowey,Frampton,Gateshead,Gatton,Godmanchester,Grampound,Grantham,Guildford,Halesowen,Halton,Harbottle,Harlow,Hatfield,Hatherleigh,Haydon,Helston,Henley,Hertford,Heytesbury,Hinckley,Hitchin,Holme,Hornby,Horsham,Kendal,Kenilworth,Kilkhampton,Kineton,Kington,Kinver,Kirby,Knaresborough,Knutsford,Launceston,Leighton,Lewes,Linton,Louth,Luton,Lyme,Lympstone,Macclesfield,Madeley,Malborough,Maldon,Manchester,Manningtree,Marazion,Marlborough,Marshfield,Mere,Merryfield,Middlewich,Midhurst,Milborne,Mitford,Modbury,Montacute,Mousehole,Newbiggin,Newborough,Newbury,Newenden,Newent,Norham,Northleach,Noss,Oakham,Olney,Orford,Ormskirk,Oswestry,Padstow,Paignton,Penkneth,Penrith,Penzance,Pershore,Petersfield,Pevensey,Pickering,Pilton,Pontefract,Portsmouth,Preston,Quatford,Reading,Redcliff,Retford,Rockingham,Romney,Rothbury,Rothwell,Salisbury,Saltash,Seaford,Seasalter,Sherston,Shifnal,Shoreham,Sidmouth,Skipsea,Skipton,Solihull,Somerton,Southam,Southwark,Standon,Stansted,Stapleton,Stottesdon,Sudbury,Swavesey,Tamerton,Tarporley,Tetbury,Thatcham,Thaxted,Thetford,Thornbury,Tintagel,Tiverton,Torksey,Totnes,Towcester,Tregoney,Trematon,Tutbury,Uxbridge,Wallingford,Wareham,Warenmouth,Wargrave,Warton,Watchet,Watford,Wendover,Westbury,Westcheap,Weymouth,Whitford,Wickwar,Wigan,Wigmore,Winchelsea,Winkleigh,Wiscombe,Witham,Witheridge,Wiveliscombe,Woodbury,Yeovil"},{name:"French",i:2,min:5,max:13,d:"nlrs",m:.1,b:"Adon,Aillant,Amilly,Andonville,Ardon,Artenay,Ascheres,Ascoux,Attray,Aubin,Audeville,Aulnay,Autruy,Auvilliers,Auxy,Aveyron,Baccon,Bardon,Barville,Batilly,Baule,Bazoches,Beauchamps,Beaugency,Beaulieu,Beaune,Bellegarde,Boesses,Boigny,Boiscommun,Boismorand,Boisseaux,Bondaroy,Bonnee,Bonny,Bordes,Bou,Bougy,Bouilly,Boulay,Bouzonville,Bouzy,Boynes,Bray,Breteau,Briare,Briarres,Bricy,Bromeilles,Bucy,Cepoy,Cercottes,Cerdon,Cernoy,Cesarville,Chailly,Chaingy,Chalette,Chambon,Champoulet,Chanteau,Chantecoq,Chapell,Charme,Charmont,Charsonville,Chateau,Chateauneuf,Chatel,Chatenoy,Chatillon,Chaussy,Checy,Chevannes,Chevillon,Chevilly,Chevry,Chilleurs,Choux,Chuelles,Clery,Coinces,Coligny,Combleux,Combreux,Conflans,Corbeilles,Corquilleroy,Cortrat,Coudroy,Coullons,Coulmiers,Courcelles,Courcy,Courtemaux,Courtempierre,Courtenay,Cravant,Crottes,Dadonville,Dammarie,Dampierre,Darvoy,Desmonts,Dimancheville,Donnery,Dordives,Dossainville,Douchy,Dry,Echilleuses,Egry,Engenville,Epieds,Erceville,Ervauville,Escrennes,Escrignelles,Estouy,Faverelles,Fay,Feins,Ferolles,Ferrieres,Fleury,Fontenay,Foret,Foucherolles,Freville,Gatinais,Gaubertin,Gemigny,Germigny,Gidy,Gien,Girolles,Givraines,Gondreville,Grangermont,Greneville,Griselles,Guigneville,Guilly,Gyleslonains,Huetre,Huisseau,Ingrannes,Ingre,Intville,Isdes,Ivre,Jargeau,Jouy,Juranville,Bussiere,Laas,Ladon,Lailly,Langesse,Leouville,Ligny,Lombreuil,Lorcy,Lorris,Loury,Louzouer,Malesherbois,Marcilly,Mardie,Mareau,Marigny,Marsainvilliers,Melleroy,Menestreau,Merinville,Messas,Meung,Mezieres,Migneres,Mignerette,Mirabeau,Montargis,Montbarrois,Montbouy,Montcresson,Montereau,Montigny,Montliard,Mormant,Morville,Moulinet,Moulon,Nancray,Nargis,Nesploy,Neuville,Neuvy,Nevoy,Nibelle,Nogent,Noyers,Ocre,Oison,Olivet,Ondreville,Onzerain,Orleans,Ormes,Orville,Oussoy,Outarville,Ouzouer,Pannecieres,Pannes,Patay,Paucourt,Pers,Pierrefitte,Pithiverais,Pithiviers,Poilly,Potier,Prefontaines,Presnoy,Pressigny,Puiseaux,Quiers,Ramoulu,Rebrechien,Rouvray,Rozieres,Rozoy,Ruan,Sandillon,Santeau,Saran,Sceaux,Seichebrieres,Semoy,Sennely,Sermaises,Sigloy,Solterre,Sougy,Sully,Sury,Tavers,Thignonville,Thimory,Thorailles,Thou,Tigy,Tivernon,Tournoisis,Trainou,Treilles,Trigueres,Trinay,Vannes,Varennes,Vennecy,Vieilles,Vienne,Viglain,Vignes,Villamblain,Villemandeur,Villemoutiers,Villemurlin,Villeneuve,Villereau,Villevoques,Villorceau,Vimory,Vitry,Vrigny"},{name:"Italian",i:3,min:5,max:12,d:"cltr",m:.1,b:"Accumoli,Acquafondata,Acquapendente,Acuto,Affile,Agosta,Alatri,Albano,Allumiere,Alvito,Amaseno,Amatrice,Anagni,Anguillara,Anticoli,Antrodoco,Anzio,Aprilia,Aquino,Arcinazzo,Ariccia,Arpino,Arsoli,Ausonia,Bagnoregio,Bassiano,Bellegra,Belmonte,Bolsena,Bomarzo,Borgorose,Boville,Bracciano,Broccostella,Calcata,Camerata,Campagnano,Campoli,Canale,Canino,Cantalice,Cantalupo,Capranica,Caprarola,Carbognano,Casalattico,Casalvieri,Castelforte,Castelnuovo,Castiglione,Castro,Castrocielo,Ceccano,Celleno,Cellere,Cerreto,Cervara,Cerveteri,Ciampino,Ciciliano,Cittaducale,Cittareale,Civita,Civitella,Colfelice,Colleferro,Collepardo,Colonna,Concerviano,Configni,Contigliano,Cori,Cottanello,Esperia,Faleria,Farnese,Ferentino,Fiamignano,Filacciano,Fiuggi,Fiumicino,Fondi,Fontana,Fonte,Fontechiari,Formia,Frascati,Frasso,Frosinone,Fumone,Gaeta,Gallese,Gavignano,Genazzano,Giuliano,Gorga,Gradoli,Grottaferrata,Grotte,Guarcino,Guidonia,Ischia,Isola,Labico,Labro,Ladispoli,Latera,Lenola,Leonessa,Licenza,Longone,Lubriano,Maenza,Magliano,Marano,Marcellina,Marcetelli,Marino,Mazzano,Mentana,Micigliano,Minturno,Montalto,Montasola,Montebuono,Monteflavio,Montelanico,Monteleone,Montenero,Monterosi,Moricone,Morlupo,Nazzano,Nemi,Nerola,Nespolo,Nettuno,Norma,Olevano,Onano,Oriolo,Orte,Orvinio,Paganico,Paliano,Palombara,Patrica,Pescorocchiano,Petrella,Piansano,Picinisco,Pico,Piedimonte,Piglio,Pignataro,Poggio,Poli,Pomezia,Pontecorvo,Pontinia,Ponzano,Posta,Pozzaglia,Priverno,Proceno,Rignano,Riofreddo,Ripi,Rivodutri,Rocca,Roccagorga,Roccantica,Roccasecca,Roiate,Ronciglione,Roviano,Salisano,Sambuci,Santa,Santini,Scandriglia,Segni,Selci,Sermoneta,Serrone,Settefrati,Sezze,Sgurgola,Sonnino,Sora,Soriano,Sperlonga,Spigno,Subiaco,Supino,Sutri,Tarano,Tarquinia,Terelle,Terracina,Tivoli,Toffia,Tolfa,Torrice,Torricella,Trevi,Trevignano,Trivigliano,Turania,Tuscania,Valentano,Vallecorsa,Vallemaio,Vallepietra,Vallerano,Vasanello,Vejano,Velletri,Ventotene,Veroli,Vetralla,Vicalvi,Vico,Vicovaro,Vignanello,Viterbo,Viticuso,Vitorchiano,Vivaro,Zagarolo"},{name:"Castillian",i:4,min:5,max:11,d:"lr",m:0,b:"Ajofrin,Alameda,Alaminos,Albares,Albarreal,Albendiego,Alcanizo,Alcaudete,Alcolea,Aldea,Aldeanueva,Algar,Algora,Alhondiga,Almadrones,Almendral,Alovera,Anguita,Arbancon,Argecilla,Arges,Arroyo,Atanzon,Atienza,Azuqueca,Baides,Banos,Bargas,Barriopedro,Belvis,Berninches,Brihuega,Buenaventura,Burgos,Burguillos,Bustares,Cabanillas,Calzada,Camarena,Campillo,Cantalojas,Cardiel,Carmena,Casas,Castejon,Castellar,Castilforte,Castillo,Castilnuevo,Cazalegas,Centenera,Cervera,Checa,Chozas,Chueca,Cifuentes,Cincovillas,Ciruelas,Cogollor,Cogolludo,Consuegra,Copernal,Corral,Cuerva,Domingo,Dosbarrios,Driebes,Duron,Escalona,Escalonilla,Escamilla,Escopete,Espinosa,Esplegares,Esquivias,Estables,Estriegana,Fontanar,Fuembellida,Fuensalida,Fuentelsaz,Gajanejos,Galvez,Gascuena,Gerindote,Guadamur,Heras,Herreria,Herreruela,Hinojosa,Hita,Hombrados,Hontanar,Hormigos,Huecas,Huerta,Humanes,Illana,Illescas,Iniestola,Irueste,Jadraque,Jirueque,Lagartera,Ledanca,Lillo,Lominchar,Loranca,Lucillos,Luzaga,Luzon,Madrid,Magan,Malaga,Malpica,Manzanar,Maqueda,Masegoso,Matillas,Medranda,Megina,Mejorada,Millana,Milmarcos,Mirabueno,Miralrio,Mocejon,Mochales,Molina,Mondejar,Montarron,Mora,Moratilla,Morenilla,Navas,Negredo,Noblejas,Numancia,Nuno,Ocana,Ocentejo,Olias,Olmeda,Ontigola,Orea,Orgaz,Oropesa,Otero,Palma,Pardos,Paredes,Penalver,Pepino,Peralejos,Pinilla,Pioz,Piqueras,Portillo,Poveda,Pozo,Pradena,Prados,Puebla,Puerto,Quero,Quintanar,Rebollosa,Retamoso,Riba,Riofrio,Robledo,Romanillos,Romanones,Rueda,Salmeron,Santiuste,Santo,Sauca,Segura,Selas,Semillas,Sesena,Setiles,Sevilla,Siguenza,Solanillos,Somolinos,Sonseca,Sotillo,Talavera,Taravilla,Tembleque,Tendilla,Tierzo,Torralba,Torre,Torrejon,Torrijos,Tortola,Tortuera,Totanes,Trillo,Uceda,Ugena,Urda,Utande,Valdesotos,Valhermoso,Valtablado,Valverde,Velada,Viana,Yebra,Yuncos,Yunquera,Zaorejas,Zarzuela,Zorita"},{name:"Ruthenian",i:5,min:5,max:10,d:"",m:0,b:"Belgorod,Beloberezhye,Belyi,Belz,Berestiy,Berezhets,Berezovets,Berezutsk,Bobruisk,Bolonets,Borisov,Borovsk,Bozhesk,Bratslav,Bryansk,Brynsk,Buryn,Byhov,Chechersk,Chemesov,Cheremosh,Cherlen,Chern,Chernigov,Chernitsa,Chernobyl,Chernogorod,Chertoryesk,Chetvertnia,Demyansk,Derevesk,Devyagoresk,Dichin,Dmitrov,Dorogobuch,Dorogobuzh,Drestvin,Drokov,Drutsk,Dubechin,Dubichi,Dubki,Dubkov,Dveren,Galich,Glebovo,Glinsk,Goloty,Gomiy,Gorodets,Gorodische,Gorodno,Gorohovets,Goroshin,Gorval,Goryshon,Holm,Horobor,Hoten,Hotin,Hotmyzhsk,Ilovech,Ivan,Izborsk,Izheslavl,Kamenets,Kanev,Karachev,Karna,Kavarna,Klechesk,Klyapech,Kolomyya,Kolyvan,Kopyl,Korec,Kornik,Korochunov,Korshev,Korsun,Koshkin,Kotelno,Kovyla,Kozelsk,Kozelsk,Kremenets,Krichev,Krylatsk,Ksniatin,Kulatsk,Kursk,Kursk,Lebedev,Lida,Logosko,Lomihvost,Loshesk,Loshichi,Lubech,Lubno,Lubutsk,Lutsk,Luchin,Luki,Lukoml,Luzha,Lvov,Mtsensk,Mdin,Medniki,Melecha,Merech,Meretsk,Mescherskoe,Meshkovsk,Metlitsk,Mezetsk,Mglin,Mihailov,Mikitin,Mikulino,Miloslavichi,Mogilev,Mologa,Moreva,Mosalsk,Moschiny,Mozyr,Mstislav,Mstislavets,Muravin,Nemech,Nemiza,Nerinsk,Nichan,Novgorod,Novogorodok,Obolichi,Obolensk,Obolensk,Oleshsk,Olgov,Omelnik,Opoka,Opoki,Oreshek,Orlets,Osechen,Oster,Ostrog,Ostrov,Perelai,Peremil,Peremyshl,Pererov,Peresechen,Perevitsk,Pereyaslav,Pinsk,Ples,Polotsk,Pronsk,Proposhesk,Punia,Putivl,Rechitsa,Rodno,Rogachev,Romanov,Romny,Roslavl,Rostislavl,Rostovets,Rsha,Ruza,Rybchesk,Rylsk,Rzhavesk,Rzhev,Rzhischev,Sambor,Serensk,Serensk,Serpeysk,Shilov,Shuya,Sinech,Sizhka,Skala,Slovensk,Slutsk,Smedin,Sneporod,Snitin,Snovsk,Sochevo,Sokolec,Starica,Starodub,Stepan,Sterzh,Streshin,Sutesk,Svinetsk,Svisloch,Terebovl,Ternov,Teshilov,Teterin,Tiversk,Torchevsk,Toropets,Torzhok,Tripolye,Trubchevsk,Tur,Turov,Usvyaty,Uteshkov,Vasilkov,Velil,Velye,Venev,Venicha,Verderev,Vereya,Veveresk,Viazma,Vidbesk,Vidychev,Voino,Volodimer,Volok,Volyn,Vorobesk,Voronich,Voronok,Vorotynsk,Vrev,Vruchiy,Vselug,Vyatichsk,Vyatka,Vyshegorod,Vyshgorod,Vysokoe,Yagniatin,Yaropolch,Yasenets,Yuryev,Yuryevets,Zaraysk,Zhitomel,Zholvazh,Zizhech,Zubkov,Zudechev,Zvenigorod"},{name:"Nordic",i:6,min:6,max:10,d:"kln",m:.1,b:"Akureyri,Aldra,Alftanes,Andenes,Austbo,Auvog,Bakkafjordur,Ballangen,Bardal,Beisfjord,Bifrost,Bildudalur,Bjerka,Bjerkvik,Bjorkosen,Bliksvaer,Blokken,Blonduos,Bolga,Bolungarvik,Borg,Borgarnes,Bosmoen,Bostad,Bostrand,Botsvika,Brautarholt,Breiddalsvik,Bringsli,Brunahlid,Budardalur,Byggdakjarni,Dalvik,Djupivogur,Donnes,Drageid,Drangsnes,Egilsstadir,Eiteroga,Elvenes,Engavogen,Ertenvog,Eskifjordur,Evenes,Eyrarbakki,Fagernes,Fallmoen,Fellabaer,Fenes,Finnoya,Fjaer,Fjelldal,Flakstad,Flateyri,Flostrand,Fludir,Gardaber,Gardur,Gimstad,Givaer,Gjeroy,Gladstad,Godoya,Godoynes,Granmoen,Gravdal,Grenivik,Grimsey,Grindavik,Grytting,Hafnir,Halsa,Hauganes,Haugland,Hauknes,Hella,Helland,Hellissandur,Hestad,Higrav,Hnifsdalur,Hofn,Hofsos,Holand,Holar,Holen,Holkestad,Holmavik,Hopen,Hovden,Hrafnagil,Hrisey,Husavik,Husvik,Hvammstangi,Hvanneyri,Hveragerdi,Hvolsvollur,Igeroy,Indre,Inndyr,Innhavet,Innes,Isafjordur,Jarklaustur,Jarnsreykir,Junkerdal,Kaldvog,Kanstad,Karlsoy,Kavosen,Keflavik,Kjelde,Kjerstad,Klakk,Kopasker,Kopavogur,Korgen,Kristnes,Krutoga,Krystad,Kvina,Lande,Laugar,Laugaras,Laugarbakki,Laugarvatn,Laupstad,Leines,Leira,Leiren,Leland,Lenvika,Loding,Lodingen,Lonsbakki,Lopsmarka,Lovund,Luroy,Maela,Melahverfi,Meloy,Mevik,Misvaer,Mornes,Mosfellsber,Moskenes,Myken,Naurstad,Nesberg,Nesjahverfi,Nesset,Nevernes,Obygda,Ofoten,Ogskardet,Okervika,Oknes,Olafsfjordur,Oldervika,Olstad,Onstad,Oppeid,Oresvika,Orsnes,Orsvog,Osmyra,Overdal,Prestoya,Raudalaekur,Raufarhofn,Reipo,Reykholar,Reykholt,Reykjahlid,Rif,Rinoya,Rodoy,Rognan,Rosvika,Rovika,Salhus,Sanden,Sandgerdi,Sandoker,Sandset,Sandvika,Saudarkrokur,Selfoss,Selsoya,Sennesvik,Setso,Siglufjordur,Silvalen,Skagastrond,Skjerstad,Skonland,Skorvogen,Skrova,Sleneset,Snubba,Softing,Solheim,Solheimar,Sorarnoy,Sorfugloy,Sorland,Sormela,Sorvaer,Sovika,Stamsund,Stamsvika,Stave,Stokka,Stokkseyri,Storjord,Storo,Storvika,Strand,Straumen,Strendene,Sudavik,Sudureyri,Sundoya,Sydalen,Thingeyri,Thorlakshofn,Thorshofn,Tjarnabyggd,Tjotta,Tosbotn,Traelnes,Trofors,Trones,Tverro,Ulvsvog,Unnstad,Utskor,Valla,Vandved,Varmahlid,Vassos,Vevelstad,Vidrek,Vik,Vikholmen,Vogar,Vogehamn,Vopnafjordur"},{name:"Greek",i:7,min:5,max:11,d:"s",m:.1,b:"Abdera,Acharnae,Aegae,Aegina,Agrinion,Aigosthena,Akragas,Akroinon,Akrotiri,Alalia,Alexandria,Amarynthos,Amaseia,Amphicaea,Amphigeneia,Amphipolis,Antipatrea,Antiochia,Apamea,Aphidna,Apollonia,Argos,Artemita,Argyropolis,Asklepios,Athenai,Athmonia,Bhrytos,Borysthenes,Brauron,Byblos,Byzantion,Bythinion,Calydon,Chamaizi,Chalcis,Chios,Cleona,Corcyra,Croton,Cyrene,Cythera,Decelea,Delos,Delphi,Dicaearchia,Didyma,Dion,Dioscurias,Dodona,Dorylaion,Elateia,Eleusis,Eleutherna,Emporion,Ephesos,Epidamnos,Epidauros,Epizephyrian,Erythrae,Eubea,Golgi,Gonnos,Gorgippia,Gournia,Gortyn,Gytion,Hagios,Halicarnassos,Heliopolis,Hellespontos,Heloros,Heraclea,Hierapolis,Himera,Histria,Hubla,Hyele,Ialysos,Iasos,Idalion,Imbros,Iolcos,Itanos,Ithaca,Juktas,Kallipolis,Kameiros,Karistos,Kasmenai,Kepoi,Kimmerikon,Knossos,Korinthos,Kos,Kourion,Kydonia,Kyrenia,Lamia,Lampsacos,Laodicea,Lapithos,Larissa,Lebena,Lefkada,Lekhaion,Leibethra,Leontinoi,Lilaea,Lindos,Lissos,Magnesia,Mantineia,Marathon,Marmara,Massalia,Megalopolis,Megara,Metapontion,Methumna,Miletos,Morgantina,Mulai,Mukenai,Myonia,Myra,Myrmekion,Myos,Nauplios,Naucratis,Naupaktos,Naxos,Neapolis,Nemea,Nicaea,Nicopolis,Nymphaion,Nysa,Odessos,Olbia,Olympia,Olynthos,Opos,Orchomenos,Oricos,Orestias,Oreos,Onchesmos,Pagasae,Palaikastro,Pandosia,Panticapaion,Paphos,Pargamon,Paros,Pegai,Pelion,Peiraies,Phaistos,Phaleron,Pharos,Pithekussa,Philippopolis,Phocaea,Pinara,Pisa,Pitane,Plataea,Poseidonia,Potidaea,Pseira,Psychro,Pteleos,Pydna,Pylos,Pyrgos,Rhamnos,Rhithymna,Rhypae,Rizinia,Rodos,Salamis,Samos,Skyllaion,Seleucia,Semasos,Sestos,Scidros,Sicyon,,Sinope,Siris,Smyrna,Sozopolis,Sparta,Stagiros,Stratos,Stymphalos,Sybaris,Surakousai,Taras,Tanagra,Tanais,Tauromenion,Tegea,Temnos,Teos,Thapsos,Thassos,Thebai,Theodosia,Therma,Thespian,Thronion,Thoricos,Thurii,Thyreum,Thyria,Tithoraea,Tomis,Tragurion,Tripolis,Troliton,Troy,Tylissos,Tyros,Vathypetros,Zakynthos,Zakros"},{name:"Roman",i:8,min:6,max:11,d:"ln",m:.1,b:"Abila,Adflexum,Adnicrem,Aelia,Aelius,Aeminium,Aequum,Agrippina,Agrippinae,Ala,Albanianis,Aleria,Ambianum,Andautonia,Apulum,Aquae,Aquaegranni,Aquensis,Aquileia,Aquincum,Arae,Argentoratum,Ariminum,Ascrivium,Asturica,Atrebatum,Atuatuca,Augusta,Aurelia,Aurelianorum,Batavar,Batavorum,Belum,Biriciana,Blestium,Bonames,Bonna,Bononia,Borbetomagus,Bovium,Bracara,Brigantium,Burgodunum,Caesaraugusta,Caesarea,Caesaromagus,Calleva,Camulodunum,Cannstatt,Cantiacorum,Capitolina,Caralis,Castellum,Castra,Castrum,Cibalae,Clausentum,Colonia,Concangis,Condate,Confluentes,Conimbriga,Corduba,Coria,Corieltauvorum,Corinium,Coriovallum,Cornoviorum,Danum,Deva,Dianium,Divodurum,Dobunnorum,Drusi,Dubris,Dumnoniorum,Durnovaria,Durocobrivis,Durocornovium,Duroliponte,Durovernum,Durovigutum,Eboracum,Ebusus,Edetanorum,Emerita,Emona,Emporiae,Euracini,Faventia,Flaviae,Florentia,Forum,Gerulata,Gerunda,Gesoscribate,Glevensium,Hadriani,Herculanea,Isca,Italica,Iulia,Iuliobrigensium,Iuvavum,Lactodurum,Lagentium,Lapurdum,Lauri,Legionis,Lemanis,Lentia,Lepidi,Letocetum,Lindinis,Lindum,Lixus,Londinium,Lopodunum,Lousonna,Lucus,Lugdunum,Luguvalium,Lutetia,Mancunium,Marsonia,Martius,Massa,Massilia,Matilo,Mattiacorum,Mediolanum,Mod,Mogontiacum,Moridunum,Mursa,Naissus,Nervia,Nida,Nigrum,Novaesium,Noviomagus,Olicana,Olisippo,Ovilava,Parisiorum,Partiscum,Paterna,Pistoria,Placentia,Pollentia,Pomaria,Pompeii,Pons,Portus,Praetoria,Praetorium,Pullum,Ragusium,Ratae,Raurica,Ravenna,Regina,Regium,Regulbium,Rigomagus,Roma,Romula,Rutupiae,Salassorum,Salernum,Salona,Scalabis,Segovia,Silurum,Sirmium,Siscia,Sorviodurum,Sumelocenna,Tarraco,Taurinorum,Theranda,Traiectum,Treverorum,Tungrorum,Turicum,Ulpia,Valentia,Venetiae,Venta,Verulamium,Vesontio,Vetera,Victoriae,Victrix,Villa,Viminacium,Vindelicorum,Vindobona,Vinovia,Viroconium"},{name:"Finnic",i:9,min:5,max:11,d:"akiut",m:0,b:"Aanekoski,Ahlainen,Aholanvaara,Ahtari,Aijala,Akaa,Alajarvi,Antsla,Aspo,Bennas,Bjorkoby,Elva,Emasalo,Espoo,Esse,Evitskog,Forssa,Haapamaki,Haapavesi,Haapsalu,Hameenlinna,Hanko,Harjavalta,Hattuvaara,Hautajarvi,Havumaki,Heinola,Hetta,Hinkabole,Hirmula,Hossa,Huittinen,Husula,Hyryla,Hyvinkaa,Ikaalinen,Iskmo,Itakoski,Jamsa,Jarvenpaa,Jeppo,Jioesuu,Jiogeva,Joensuu,Jokikyla,Jungsund,Jyvaskyla,Kaamasmukka,Kajaani,Kalajoki,Kallaste,Kankaanpaa,Karkku,Karpankyla,Kaskinen,Kasnas,Kauhajoki,Kauhava,Kauniainen,Kauvatsa,Kehra,Kellokoski,Kelottijarvi,Kemi,Kemijarvi,Kerava,Keuruu,Kiljava,Kiuruvesi,Kivesjarvi,Kiviioli,Kivisuo,Klaukkala,Klovskog,Kohtlajarve,Kokemaki,Kokkola,Kolho,Koskue,Kotka,Kouva,Kaupunki,Kuhmo,Kunda,Kuopio,Kuressaare,Kurikka,Kuusamo,Kylmalankyla,Lahti,Laitila,Lankipohja,Lansikyla,Lapua,Laurila,Lautiosaari,Lempaala,Lepsama,Liedakkala,Lieksa,Littoinen,Lohja,Loimaa,Loksa,Loviisa,Malmi,Mantta,Matasvaara,Maula,Miiluranta,Mioisakula,Munapirtti,Mustvee,Muurahainen,Naantali,Nappa,Narpio,Niinimaa,Niinisalo,Nikkila,Nilsia,Nivala,Nokia,Nummela,Nuorgam,Nuvvus,Obbnas,Oitti,Ojakkala,Onninen,Orimattila,Orivesi,Otanmaki,Otava,Otepaa,Oulainen,Oulu,Paavola,Paide,Paimio,Pakankyla,Paldiski,Parainen,Parkumaki,Parola,Perttula,Pieksamaki,Pioltsamaa,Piolva,Pohjavaara,Porhola,Porrasa,Porvoo,Pudasjarvi,Purmo,Pyhajarvi,Raahe,Raasepori,Raisio,Rajamaki,Rakvere,Rapina,Rapla,Rauma,Rautio,Reposaari,Riihimaki,Rovaniemi,Roykka,Ruonala,Ruottala,Rutalahti,Saarijarvi,Salo,Sastamala,Saue,Savonlinna,Seinajoki,Sillamae,Siuntio,Sompujarvi,Suonenjoki,Suurejaani,Syrjantaka,Tamsalu,Tapa,Temmes,Tiorva,Tormasenvaara,Tornio,Tottijarvi,Tulppio,Turenki,Turi,Tuukkala,Tuurala,Tuuri,Tuuski,Tuusniemi,Ulvila,Unari,Upinniemi,Utti,Uusikaupunki,Vaaksy,Vaalimaa,Vaarinmaja,Vaasa,Vainikkala,Valga,Valkeakoski,Vantaa,Varkaus,Vehkapera,Vehmasmaki,Vieki,Vierumaki,Viitasaari,Viljandi,Vilppula,Viohma,Vioru,Virrat,Ylike,Ylivieska,Ylojarvi"},{name:"Korean",i:10,min:5,max:11,d:"",m:0,b:"Anjung,Ansan,Anseong,Anyang,Aphae,Apo,Baekseok,Baeksu,Beolgyo,Boeun,Boseong,Busan,Buyeo,Changnyeong,Changwon,Cheonan,Cheongdo,Cheongjin,Cheongsong,Cheongyang,Cheorwon,Chirwon,Chuncheon,Chungju,Daedeok,Daegaya,Daejeon,Damyang,Dangjin,Dasa,Donghae,Dongsong,Doyang,Eonyang,Gaeseong,Ganggyeong,Ganghwa,Gangneung,Ganseong,Gaun,Geochang,Geoje,Geoncheon,Geumho,Geumil,Geumwang,Gijang,Gimcheon,Gimhwa,Gimje,Goa,Gochang,Gohan,Gongdo,Gongju,Goseong,Goyang,Gumi,Gunpo,Gunsan,Guri,Gurye,Gwangju,Gwangyang,Gwansan,Gyeongseong,Hadong,Hamchang,Hampyeong,Hamyeol,Hanam,Hapcheon,Hayang,Heungnam,Hongnong,Hongseong,Hwacheon,Hwando,Hwaseong,Hwasun,Hwawon,Hyangnam,Incheon,Inje,Iri,Janghang,Jangheung,Jangseong,Jangseungpo,Jangsu,Jecheon,Jeju,Jeomchon,Jeongeup,Jeonggwan,Jeongju,Jeongok,Jeongseon,Jeonju,Jido,Jiksan,Jinan,Jincheon,Jindo,Jingeon,Jinjeop,Jinnampo,Jinyeong,Jocheon,Jochiwon,Jori,Maepo,Mangyeong,Mokpo,Muju,Munsan,Naesu,Naju,Namhae,Namwon,Namyang,Namyangju,Nongong,Nonsan,Ocheon,Okcheon,Okgu,Onam,Onsan,Onyang,Opo,Paengseong,Pogok,Poseung,Pungsan,Pyeongchang,Pyeonghae,Pyeongyang,Sabi,Sacheon,Samcheok,Samho,Samrye,Sancheong,Sangdong,Sangju,Sapgyo,Sariwon,Sejong,Seocheon,Seogwipo,Seonghwan,Seongjin,Seongju,Seongnam,Seongsan,Seosan,Seungju,Siheung,Sindong,Sintaein,Soheul,Sokcho,Songak,Songjeong,Songnim,Songtan,Suncheon,Taean,Taebaek,Tongjin,Uijeongbu,Uiryeong,Uiwang,Uljin,Ulleung,Unbong,Ungcheon,Ungjin,Waegwan,Wando,Wayang,Wiryeseong,Wondeok,Yangju,Yangsan,Yangyang,Yecheon,Yeomchi,Yeoncheon,Yeongam,Yeongcheon,Yeongdeok,Yeongdong,Yeonggwang,Yeongju,Yeongwol,Yeongyang,Yeonil,Yongin,Yongjin,Yugu"},{name:"Chinese",i:11,min:5,max:10,d:"",m:0,b:"Anding,Anlu,Anqing,Anshun,Baixing,Banyang,Baoqing,Binzhou,Caozhou,Changbai,Changchun,Changde,Changling,Changsha,Changzhou,Chengdu,Chenzhou,Chizhou,Chongqing,Chuxiong,Chuzhou,Dading,Daming,Datong,Daxing,Dengzhou,Deqing,Dihua,Dingli,Dongan,Dongchang,Dongchuan,Dongping,Duyun,Fengtian,Fengxiang,Fengyang,Fenzhou,Funing,Fuzhou,Ganzhou,Gaoyao,Gaozhou,Gongchang,Guangnan,Guangning,Guangping,Guangxin,Guangzhou,Guiyang,Hailong,Hangzhou,Hanyang,Hanzhong,Heihe,Hejian,Henan,Hengzhou,Hezhong,Huaian,Huaiqing,Huanglong,Huangzhou,Huining,Hulan,Huzhou,Jiading,Jian,Jianchang,Jiangning,Jiankang,Jiaxing,Jiayang,Jilin,Jinan,Jingjiang,Jingzhao,Jinhua,Jinzhou,Jiujiang,Kaifeng,Kaihua,Kangding,Kuizhou,Laizhou,Lianzhou,Liaoyang,Lijiang,Linan,Linhuang,Lintao,Liping,Liuzhou,Longan,Longjiang,Longxing,Luan,Lubin,Luzhou,Mishan,Nanan,Nanchang,Nandian,Nankang,Nanyang,Nenjiang,Ningbo,Ningguo,Ningwu,Ningxia,Ningyuan,Pingjiang,Pingliang,Pingyang,Puer,Puzhou,Qianzhou,Qingyang,Qingyuan,Qingzhou,Qujing,Quzhou,Raozhou,Rende,Ruian,Ruizhou,Shafeng,Shajing,Shaoqing,Shaowu,Shaoxing,Shaozhou,Shinan,Shiqian,Shouchun,Shuangcheng,Shulei,Shunde,Shuntian,Shuoping,Sicheng,Sinan,Sizhou,Songjiang,Suiding,Suihua,Suining,Suzhou,Taian,Taibei,Taiping,Taiwan,Taiyuan,Taizhou,Taonan,Tengchong,Tingzhou,Tongchuan,Tongqing,Tongzhou,Weihui,Wensu,Wenzhou,Wuchang,Wuding,Wuzhou,Xian,Xianchun,Xianping,Xijin,Xiliang,Xincheng,Xingan,Xingde,Xinghua,Xingjing,Xingyi,Xingyuan,Xingzhong,Xining,Xinmen,Xiping,Xuanhua,Xunzhou,Xuzhou,Yanan,Yangzhou,Yanji,Yanping,Yanzhou,Yazhou,Yichang,Yidu,Yilan,Yili,Yingchang,Yingde,Yingtian,Yingzhou,Yongchang,Yongping,Yongshun,Yuanzhou,Yuezhou,Yulin,Yunnan,Yunyang,Zezhou,Zhang,Zhangzhou,Zhaoqing,Zhaotong,Zhenan,Zhending,Zhenhai,Zhenjiang,Zhenxi,Zhenyun,Zhongshan,Zunyi"},{name:"Japanese",i:12,min:4,max:10,d:"",m:0,b:"Abira,Aga,Aikawa,Aizumisato,Ajigasawa,Akkeshi,Amagi,Ami,Ando,Asakawa,Ashikita,Bandai,Biratori,Chonan,Esashi,Fuchu,Fujimi,Funagata,Genkai,Godo,Goka,Gonohe,Gyokuto,Haboro,Hamatonbetsu,Harima,Hashikami,Hayashima,Heguri,Hidaka,Higashiura,Hiranai,Hirogawa,Hiroo,Hodatsushimizu,Hoki,Hokuei,Hokuryu,Horokanai,Ibigawa,Ichikai,Ichikawa,Ichinohe,Iijima,Iizuna,Ikawa,Inagawa,Itakura,Iwaizumi,Iwate,Kaisei,Kamifurano,Kamiita,Kamijima,Kamikawa,Kamishihoro,Kamiyama,Kanda,Kanna,Kasagi,Kasuya,Katsuura,Kawabe,Kawamoto,Kawanehon,Kawanishi,Kawara,Kawasaki,Kawatana,Kawazu,Kihoku,Kikonai,Kin,Kiso,Kitagata,Kitajima,Kiyama,Kiyosato,Kofu,Koge,Kohoku,Kokonoe,Kora,Kosa,Kotohira,Kudoyama,Kumejima,Kumenan,Kumiyama,Kunitomi,Kurate,Kushimoto,Kutchan,Kyonan,Kyotamba,Mashike,Matsumae,Mifune,Mihama,Minabe,Minami,Minamiechizen,Minamitane,Misaki,Misasa,Misato,Miyashiro,Miyoshi,Mori,Moseushi,Mutsuzawa,Nagaizumi,Nagatoro,Nagayo,Nagomi,Nakadomari,Nakanojo,Nakashibetsu,Namegawa,Nanbu,Nanporo,Naoshima,Nasu,Niseko,Nishihara,Nishiizu,Nishikatsura,Nishikawa,Nishinoshima,Nishiwaga,Nogi,Noto,Nyuzen,Oarai,Obuse,Odai,Ogawara,Oharu,Oirase,Oishida,Oiso,Oizumi,Oji,Okagaki,Okutama,Omu,Ono,Osaka,Otobe,Otsuki,Owani,Reihoku,Rifu,Rikubetsu,Rishiri,Rokunohe,Ryuo,Saka,Sakuho,Samani,Satsuma,Sayo,Saza,Setana,Shakotan,Shibayama,Shikama,Shimamoto,Shimizu,Shintomi,Shirakawa,Shisui,Shitara,Sobetsu,Sue,Sumita,Suooshima,Suttsu,Tabuse,Tachiarai,Tadami,Tadaoka,Taiji,Taiki,Takachiho,Takahama,Taketoyo,Taragi,Tateshina,Tatsugo,Tawaramoto,Teshikaga,Tobe,Tokigawa,Toma,Tomioka,Tonosho,Tosa,Toyokoro,Toyotomi,Toyoyama,Tsubata,Tsubetsu,Tsukigata,Tsuno,Tsuwano,Umi,Wakasa,Yamamoto,Yamanobe,Yamatsuri,Yanaizu,Yasuda,Yoichi,Yonaguni,Yoro,Yoshino,Yubetsu,Yugawara,Yuni,Yusuhara,Yuza"},{name:"Portuguese",i:13,min:5,max:11,d:"",m:.1,b:"Abrigada,Afonsoeiro,Agueda,Aguilada,Alagoas,Alagoinhas,Albufeira,Alcanhoes,Alcobaca,Alcoutim,Aldoar,Alenquer,Alfeizerao,Algarve,Almada,Almagreira,Almeirim,Alpalhao,Alpedrinha,Alvorada,Amieira,Anapolis,Apelacao,Aranhas,Arganil,Armacao,Assenceira,Aveiro,Avelar,Balsas,Barcarena,Barreiras,Barretos,Batalha,Beira,Benavente,Betim,Braga,Braganca,Brasilia,Brejo,Cabeceiras,Cabedelo,Cachoeiras,Cadafais,Calhandriz,Calheta,Caminha,Campinas,Canidelo,Canoas,Capinha,Carmoes,Cartaxo,Carvalhal,Carvoeiro,Cascavel,Castanhal,Caxias,Chapadinha,Chaves,Cocais,Coentral,Coimbra,Comporta,Conde,Coqueirinho,Coruche,Damaia,Dourados,Enxames,Ericeira,Ervidel,Escalhao,Esmoriz,Espinhal,Estela,Estoril,Eunapolis,Evora,Famalicao,Fanhoes,Faro,Fatima,Felgueiras,Ferreira,Figueira,Flecheiras,Florianopolis,Fornalhas,Fortaleza,Freiria,Freixeira,Fronteira,Fundao,Gracas,Gradil,Grainho,Gralheira,Guimaraes,Horta,Ilhavo,Ilheus,Lages,Lagos,Laranjeiras,Lavacolhos,Leiria,Limoeiro,Linhares,Lisboa,Lomba,Lorvao,Lourical,Lourinha,Luziania,Macedo,Machava,Malveira,Marinhais,Maxial,Mealhada,Milharado,Mira,Mirandela,Mogadouro,Montalegre,Mourao,Nespereira,Nilopolis,Obidos,Odemira,Odivelas,Oeiras,Oleiros,Olhalvo,Olinda,Olival,Oliveira,Oliveirinha,Palheiros,Palmeira,Palmital,Pampilhosa,Pantanal,Paradinha,Parelheiros,Pedrosinho,Pegoes,Penafiel,Peniche,Pinhao,Pinheiro,Pombal,Pontal,Pontinha,Portel,Portimao,Quarteira,Queluz,Ramalhal,Reboleira,Recife,Redinha,Ribadouro,Ribeira,Ribeirao,Rosais,Sabugal,Sacavem,Sagres,Sandim,Sangalhos,Santarem,Santos,Sarilhos,Seixas,Seixezelo,Seixo,Silvares,Silveira,Sinhaem,Sintra,Sobral,Sobralinho,Tabuaco,Tabuleiro,Taveiro,Teixoso,Telhado,Telheiro,Tomar,Torreira,Trancoso,Troviscal,Vagos,Varzea,Velas,Viamao,Viana,Vidigal,Vidigueira,Vidual,Vilamar,Vimeiro,Vinhais,Vitoria"},{name:"Nahuatl",i:14,min:6,max:13,d:"l",m:0,b:"Acapulco,Acatepec,Acatlan,Acaxochitlan,Acolman,Actopan,Acuamanala,Ahuacatlan,Almoloya,Amacuzac,Amanalco,Amaxac,Apaxco,Apetatitlan,Apizaco,Atenco,Atizapan,Atlacomulco,Atlapexco,Atotonilco,Axapusco,Axochiapan,Axocomanitla,Axutla,Azcapotzalco,Aztahuacan,Calimaya,Calnali,Calpulalpan,Camotlan,Capulhuac,Chalco,Chapulhuacan,Chapultepec,Chiapan,Chiautempan,Chiconautla,Chihuahua,Chilcuautla,Chimalhuacan,Cholollan,Cihuatlan,Coahuila,Coatepec,Coatetelco,Coatlan,Coatlinchan,Coatzacoalcos,Cocotitlan,Cohetzala,Colima,Colotlan,Coyoacan,Coyohuacan,Cuapiaxtla,Cuauhnahuac,Cuauhtemoc,Cuauhtitlan,Cuautepec,Cuautla,Cuaxomulco,Culhuacan,Ecatepec,Eloxochitlan,Epatlan,Epazoyucan,Huamantla,Huascazaloya,Huatlatlauca,Huautla,Huehuetlan,Huehuetoca,Huexotla,Hueyapan,Hueyotlipan,Hueypoxtla,Huichapan,Huimilpan,Huitzilac,Ixtapallocan,Iztacalco,Iztaccihuatl,Iztapalapa,Lolotla,Malinalco,Mapachtlan,Mazatepec,Mazatlan,Metepec,Metztitlan,Mexico,Miacatlan,Michoacan,Minatitlan,Mixcoac,Mixtla,Molcaxac,Nanacamilpa,Naucalpan,Naupan,Nextlalpan,Nezahualcoyotl,Nopalucan,Oaxaca,Ocotepec,Ocotitlan,Ocotlan,Ocoyoacac,Ocuilan,Ocuituco,Omitlan,Otompan,Otzoloapan,Pacula,Pahuatlan,Panotla,Papalotla,Patlachican,Piaztla,Popocatepetl,Sultepec,Tecamac,Tecolotlan,Tecozautla,Temamatla,Temascalapa,Temixco,Temoac,Temoaya,Tenayuca,Tenochtitlan,Teocuitlatlan,Teotihuacan,Teotlalco,Tepeacac,Tepeapulco,Tepehuacan,Tepetitlan,Tepeyanco,Tepotzotlan,Tepoztlan,Tetecala,Tetlatlahuca,Texcalyacac,Texcoco,Tezontepec,Tezoyuca,Timilpan,Tizapan,Tizayuca,Tlacopan,Tlacotenco,Tlahuac,Tlahuelilpan,Tlahuiltepa,Tlalmanalco,Tlalnepantla,Tlalpan,Tlanchinol,Tlatelolco,Tlaxcala,Tlaxcoapan,Tlayacapan,Tocatlan,Tolcayuca,Toluca,Tonanitla,Tonantzintla,Tonatico,Totolac,Totolapan,Tototlan,Tuchtlan,Tulantepec,Tultepec,Tzompantepec,Xalatlaco,Xaloztoc,Xaltocan,Xiloxoxtla,Xochiatipan,Xochicoatlan,Xochimilco,Xochitepec,Xolotlan,Xonacatlan,Yahualica,Yautepec,Yecapixtla,Yehaultepec,Zacatecas,Zacazonapan,Zacoalco,Zacualpan,Zacualtipan,Zapotlan,Zimapan,Zinacantepec,Zoyaltepec,Zumpahuacan"},{name:"Hungarian",i:15,min:6,max:13,d:"",m:.1,b:"Aba,Abadszalok,Adony,Ajak,Albertirsa,Alsozsolca,Aszod,Babolna,Bacsalmas,Baktaloranthaza,Balassagyarmat,Balatonalmadi,Balatonboglar,Balkany,Balmazujvaros,Barcs,Bataszek,Batonyterenye,Battonya,Bekes,Berettyoujfalu,Berhida,Biatorbagy,Bicske,Biharkeresztes,Bodajk,Boly,Bonyhad,Budakalasz,Budakeszi,Celldomolk,Csakvar,Csenger,Csongrad,Csorna,Csorvas,Csurgo,Dabas,Demecser,Derecske,Devavanya,Devecser,Dombovar,Dombrad,Dunafoldvar,Dunaharaszti,Dunavarsany,Dunavecse,Edeleny,Elek,Emod,Encs,Enying,Ercsi,Fegyvernek,Fehergyarmat,Felsozsolca,Fertoszentmiklos,Fonyod,Fot,Fuzesabony,Fuzesgyarmat,Gardony,God,Gyal,Gyomaendrod,Gyomro,Hajdudorog,Hajduhadhaz,Hajdusamson,Hajduszoboszlo,Halasztelek,Harkany,Hatvan,Heves,Heviz,Ibrany,Isaszeg,Izsak,Janoshalma,Janossomorja,Jaszapati,Jaszarokszallas,Jaszfenyszaru,Jaszkiser,Kaba,Kalocsa,Kapuvar,Karcag,Kecel,Kemecse,Kenderes,Kerekegyhaza,Keszthely,Kisber,Kiskunmajsa,Kistarcsa,Kistelek,Kisujszallas,Kisvarda,Komadi,Komarom,Komlo,Kormend,Korosladany,Koszeg,Kozarmisleny,Kunhegyes,Kunszentmarton,Kunszentmiklos,Labatlan,Lajosmizse,Lenti,Letavertes,Letenye,Lorinci,Maglod,Mako,Mandok,Marcali,Martonvasar,Mateszalka,Melykut,Mezobereny,Mezocsat,Mezohegyes,Mezokeresztes,Mezokovesd,Mezotur,Mindszent,Mohacs,Monor,Mor,Morahalom,Nadudvar,Nagyatad,Nagyecsed,Nagyhalasz,Nagykallo,Nagykoros,Nagymaros,Nyekladhaza,Nyergesujfalu,Nyirbator,Nyirmada,Nyirtelek,Ocsa,Orkeny,Oroszlany,Paks,Pannonhalma,Paszto,Pecel,Pecsvarad,Pilisvorosvar,Polgar,Polgardi,Pomaz,Puspokladany,Pusztaszabolcs,Putnok,Racalmas,Rackeve,Rakamaz,Rakoczifalva,Sajoszent,Sandorfalva,Sarbogard,Sarkad,Sarospatak,Sarvar,Satoraljaujhely,Siklos,Simontornya,Soltvadkert,Sumeg,Szabadszallas,Szarvas,Szazhalombatta,Szecseny,Szeghalom,Szentgotthard,Szentlorinc,Szerencs,Szigethalom,Szigetvar,Szikszo,Tab,Tamasi,Tapioszele,Tapolca,Teglas,Tet,Tiszafoldvar,Tiszafured,Tiszakecske,Tiszalok,Tiszaujvaros,Tiszavasvari,Tokaj,Tokol,Tompa,Torokbalint,Torokszentmiklos,Totkomlos,Tura,Turkeve,Ujkigyos,ujszasz,Vamospercs,Varpalota,Vasarosnameny,Vasvar,Vecses,Veresegyhaz,Verpelet,Veszto,Zahony,Zalaszentgrot,Zirc,Zsambek"},{name:"Turkish",i:16,min:4,max:10,d:"",m:0,b:"Yelkaya,Buyrukkaya,Erdemtepe,Alakesen,Baharbeyli,Bozbay,Karaoklu,Altunbey,Yalkale,Yalkut,Akardere,Altayburnu,Esentepe,Okbelen,Derinsu,Alaoba,Yamanbeyli,Aykor,Ekinova,Saztepe,Baharkale,Devrekdibi,Alpseki,Ormanseki,Erkale,Yalbelen,Aytay,Yamanyaka,Altaydelen,Esen,Yedieli,Alpkor,Demirkor,Yediyol,Erdemkaya,Yayburnu,Ganiler,Bayatyurt,Kopuzteke,Aytepe,Deniz,Ayan,Ayazdere,Tepe,Kayra,Ayyaka,Deren,Adatepe,Kalkaneli,Bozkale,Yedidelen,Kocayolu,Sazdere,Bozkesen,Oguzeli,Yayladibi,Uluyol,Altay,Ayvar,Alazyaka,Yaloba,Suyaka,Baltaberi,Poyrazdelen,Eymir,Yediyuva,Kurt,Yeltepe,Oktar,Kara Ok,Ekinberi,Er Yurdu,Eren,Erenler,Ser,Oguz,Asay,Bozokeli,Aykut,Ormanyol,Yazkaya,Kalkanova,Yazbeyli,Dokuz Teke,Bilge,Ertensuyu,Kopuzyuva,Buyrukkut,Akardiken,Aybaray,Aslanbeyli,Altun Kaynak,Atikobasi,Yayla Eli,Kor Tepe,Salureli,Kor Kaya,Aybarberi,Kemerev,Yanaray,Beydileli,Buyrukoba,Yolduman,Tengri Tepe,Dokuzsu,Uzunkor,Erdem Yurdu,Kemer,Korteke,Bozokev,Bozoba,Ormankale,Askale,Oguztoprak,Yolberi,Kumseki,Esenobasi,Turkbelen,Ayazseki,Cereneli,Taykut,Bayramdelen,Beydilyaka,Boztepe,Uluoba,Yelyaka,Ulgardiken,Esensu,Baykale,Cerenkor,Bozyol,Duranoba,Aladuman,Denizli,Bahar,Yarkesen,Dokuzer,Yamankaya,Kocatarla,Alayaka,Toprakeli,Sarptarla,Sarpkoy,Serkaynak,Adayaka,Ayazkaynak,Kopuz,Turk,Kart,Kum,Erten,Buyruk,Yel,Ada,Alazova,Ayvarduman,Buyrukok,Ayvartoprak,Uzuntepe,Binseki,Yedibey,Durankale,Alaztoprak,Sarp Ok,Yaparobasi,Yaytepe,Asberi,Kalkankor,Beydiltepe,Adaberi,Bilgeyolu,Ganiyurt,Alkanteke,Esenerler,Asbey,Erdemkale,Erenkaynak,Oguzkoyu,Ayazoba,Boynuztoprak,Okova,Yaloklu,Sivriberi,Yuladiken,Sazbey,Karakaynak,Kopuzkoyu,Buyrukay,Kocakaya,Tepeduman,Yanarseki,Atikyurt,Esenev,Akarbeyli,Yayteke,Devreksungur,Akseki,Baykut,Kalkandere,Ulgarova,Devrekev,Yulabey,Bayatev,Yazsu,Vuraleli,Sivribeyli,Alaova,Alpobasi,Yalyurt,Elmatoprak,Alazkaynak,Esenay,Ertenev,Salurkor,Ekinok,Yalbey,Yeldere,Ganibay,Altaykut,Baltaboy,Ereli,Ayvarsu,Uzunsaz,Bayeli,Erenyol,Kocabay,Derintay,Ayazyol,Aslanoba,Esenkaynak,Ekinlik,Alpyolu,Alayunt,Bozeski,Erkil,Duransuyu,Yulak,Kut,Dodurga,Kutlubey,Kutluyurt,Boynuz,Alayol,Aybar,Aslaneli,Kemerseki,Baltasuyu,Akarer,Ayvarburnu,Boynuzbeyli,Adasungur,Esenkor,Yamanoba,Toprakkor,Uzunyurt,Sungur,Bozok,Kemerli,Alaz,Demirci,Kartepe"},{name:"Berber",i:17,min:4,max:10,d:"s",m:.2,b:"Abkhouch,Adrar,Aeraysh,Afrag,Agadir,Agelmam,Aghmat,Agrakal,Agulmam,Ahaggar,Ait Baha,Ajdir,Akka,Almou,Amegdul,Amizmiz,Amknas,Amlil,Amurakush,Anfa,Annaba,Aousja,Arbat,Arfud,Argoub,Arif,Asfi,Asfru,Ashawen,Assamer,Assif,Awlluz,Ayt Melel,Azaghar,Azila,Azilal,Azmour,Azro,Azrou,Beccar,Beja,Bennour,Benslimane,Berkane,Berrechid,Bizerte,Bjaed,Bouayach,Boudenib,Boufrah,Bouskoura,Boutferda,Darallouch,Dar Bouazza,Darchaabane,Dcheira,Demnat,Denden,Djebel,Djedeida,Drargua,Elhusima,Essaouira,Ezzahra,Fas,Fnideq,Ghezeze,Goubellat,Grisaffen,Guelmim,Guercif,Hammamet,Harrouda,Hdifa,Hoceima,Houara,Idhan,Idurar,Ifendassen,Ifoghas,Ifrane,Ighoud,Ikbir,Imilchil,Imzuren,Inezgane,Irherm,Izoughar,Jendouba,Kacem,Kelibia,Kenitra,Kerrando,Khalidia,Khemisset,Khenifra,Khouribga,Khourigba,Kidal,Korba,Korbous,Lahraouyine,Larache,Leyun,Lqliaa,Manouba,Martil,Mazagan,Mcherga,Mdiq,Megrine,Mellal,Melloul,Midelt,Misur,Mohammedia,Mornag,Mrirt,Nabeul,Nadhour,Nador,Nawaksut,Nefza,Ouarzazate,Ouazzane,Oued Zem,Oujda,Ouladteima,Qsentina,Rades,Rafraf,Safi,Sefrou,Sejnane,Settat,Sijilmassa,Skhirat,Slimane,Somaa,Sraghna,Susa,Tabarka,Tadrart,Taferka,Tafilalt,Tafrawt,Tafza,Tagbalut,Tagerdayt,Taghzut,Takelsa,Taliouine,Tanja,Tantan,Taourirt,Targuist,Taroudant,Tarudant,Tasfelalayt,Tassort,Tata,Tattiwin,Tawnat,Taza,Tazagurt,Tazerka,Tazizawt,Taznakht,Tebourba,Teboursouk,Temara,Testour,Tetouan,Tibeskert,Tifelt,Tijdit,Tinariwen,Tinduf,Tinja,Tittawan,Tiznit,Toubkal,Trables,Tubqal,Tunes,Ultasila,Urup,Wagguten,Wararni,Warzazat,Watlas,Wehran,Wejda,Xamida,Yedder,Youssoufia,Zaghouan,Zahret,Zemmour,Zriba"},{name:"Arabic",i:18,min:4,max:9,d:"ae",m:.2,b:"Abha,Ajman,Alabar,Alarjam,Alashraf,Alawali,Albawadi,Albirk,Aldhabiyah,Alduwaid,Alfareeq,Algayed,Alhazim,Alhrateem,Alhudaydah,Alhuwaya,Aljahra,Aljubail,Alkhafah,Alkhalas,Alkhawaneej,Alkhen,Alkhobar,Alkhuznah,Allisafah,Almshaykh,Almurjan,Almuwayh,Almuzaylif,Alnaheem,Alnashifah,Alqah,Alqouz,Alqurayyat,Alradha,Alraqmiah,Alsadyah,Alsafa,Alshagab,Alshuqaiq,Alsilaa,Althafeer,Alwasqah,Amaq,Amran,Annaseem,Aqbiyah,Arafat,Arar,Ardah,Asfan,Ashayrah,Askar,Ayaar,Aziziyah,Baesh,Bahrah,Balhaf,Banizayd,Bidiyah,Bisha,Biyatah,Buqhayq,Burayda,Dafiyat,Damad,Dammam,Dariyah,Dhafar,Dhahran,Dhalkut,Dhurma,Dibab,Doha,Dukhan,Duwaibah,Enaker,Fadhla,Fahaheel,Fanateer,Farasan,Fardah,Fujairah,Ghalilah,Ghar,Ghizlan,Ghomgyah,Ghran,Hadiyah,Haffah,Hajanbah,Hajrah,Haqqaq,Haradh,Hasar,Hawiyah,Hebaa,Hefar,Hijal,Husnah,Huwailat,Huwaitah,Irqah,Isharah,Ithrah,Jamalah,Jarab,Jareef,Jazan,Jeddah,Jiblah,Jihanah,Jilah,Jizan,Joraibah,Juban,Jumeirah,Kamaran,Keyad,Khab,Khaiybar,Khasab,Khathirah,Khawarah,Khulais,Kumzar,Limah,Linah,Madrak,Mahab,Mahalah,Makhtar,Mashwar,Masirah,Masliyah,Mastabah,Mazhar,Medina,Meeqat,Mirbah,Mokhtara,Muharraq,Muladdah,Musaykah,Mushayrif,Musrah,Mussafah,Nafhan,Najran,Nakhab,Nizwa,Oman,Qadah,Qalhat,Qamrah,Qasam,Qosmah,Qurain,Quriyat,Qurwa,Radaa,Rafha,Rahlah,Rakamah,Rasheedah,Rasmadrakah,Risabah,Rustaq,Ryadh,Sabtaljarah,Sadah,Safinah,Saham,Saihat,Salalah,Salmiya,Shabwah,Shalim,Shaqra,Sharjah,Sharurah,Shatifiyah,Shidah,Shihar,Shoqra,Shuwaq,Sibah,Sihmah,Sinaw,Sirwah,Sohar,Suhailah,Sulaibiya,Sunbah,Tabuk,Taif,Taqah,Tarif,Tharban,Thuqbah,Thuwal,Tubarjal,Turaif,Turbah,Tuwaiq,Ubar,Umaljerem,Urayarah,Urwah,Wabrah,Warbah,Yabreen,Yadamah,Yafur,Yarim,Yemen,Yiyallah,Zabid,Zahwah,Zallaq,Zinjibar,Zulumah"},{name:"Inuit",i:19,min:5,max:15,d:"alutsn",m:0,b:"Aaluik,Aappilattoq,Aasiaat,Agissat,Agssaussat,Akuliarutsip,Akunnaaq,Alluitsup,Alluttoq,Amitsorsuaq,Ammassalik,Anarusuk,Anguniartarfik,Annertussoq,Annikitsoq,Apparsuit,Apusiaajik,Arsivik,Arsuk,Atammik,Ateqanaq,Atilissuaq,Attu,Augpalugtoq,Aukarnersuaq,Aumat,Auvilkikavsaup,Avadtlek,Avallersuaq,Bjornesk,Blabaerdalen,Blomsterdalen,Brattalhid,Bredebrae,Brededal,Claushavn,Edderfulegoer,Egger,Eqalugalinnguit,Eqalugarssuit,Eqaluit,Eqqua,Etah,Graah,Hakluyt,Haredalen,Hareoen,Hundeo,Igaliku,Igdlorssuit,Igdluluarssuk,Iginniafik,Ikamiut,Ikarissat,Ikateq,Ikermiut,Ikermoissuaq,Ikorfarssuit,Ilimanaq,Illorsuit,Illunnguit,Iluileq,Ilulissat,Imaarsivik,Imartunarssuk,Immikkoortukajik,Innaarsuit,Inneruulalik,Inussullissuaq,Iperaq,Ippik,Iqek,Isortok,Isungartussoq,Itileq,Itissaalik,Itivdleq,Ittit,Ittoqqortoormiit,Ivingmiut,Ivittuut,Kanajoorartuut,Kangaamiut,Kangeq,Kangerluk,Kangerlussuaq,Kanglinnguit,Kapisillit,Kekertamiut,Kiatak,Kiataussaq,Kigatak,Kinaussak,Kingittorsuaq,Kitak,Kitsissuarsuit,Kitsissut,Klenczner,Kook,Kraulshavn,Kujalleq,Kullorsuaq,Kulusuk,Kuurmiit,Kuusuaq,Laksedalen,Maniitsoq,Marrakajik,Mattaangassut,Mernoq,Mittivakkat,Moriusaq,Myggbukta,Naajaat,Nangissat,Nanuuseq,Nappassoq,Narsarmijt,Narsarsuaq,Narssaq,Nasiffik,Natsiarsiorfik,Naujanguit,Niaqornaarsuk,Niaqornat,Nordfjordspasset,Nugatsiaq,Nunarssit,Nunarsuaq,Nunataaq,Nunatakavsaup,Nutaarmiut,Nuugaatsiaq,Nuuk,Nuukullak,Olonkinbyen,Oodaaq,Oqaatsut,Oqaitsunguit,Oqonermiut,Paagussat,Paamiut,Paatuut,Palungataq,Pamialluk,Perserajoq,Pituffik,Puugutaa,Puulkuip,Qaanaq,Qaasuitsup,Qaersut,Qajartalik,Qallunaat,Qaneq,Qaqortok,Qasigiannguit,Qassimiut,Qeertartivaq,Qeqertaq,Qeqertasussuk,Qeqqata,Qernertoq,Qernertunnguit,Qianarreq,Qingagssat,Qoornuup,Qorlortorsuaq,Qullikorsuit,Qunnerit,Qutdleq,Ravnedalen,Ritenbenk,Rypedalen,Saarloq,Saatorsuaq,Saattut,Salliaruseq,Sammeqqat,Sammisoq,Sanningassoq,Saqqaq,Saqqarlersuaq,Saqqarliit,Sarfannguit,Sattiaatteq,Savissivik,Serfanguaq,Sermersooq,Sermiligaaq,Sermilik,Sermitsiaq,Simitakaja,Simiutaq,Singamaq,Siorapaluk,Sisimiut,Sisuarsuit,Sullorsuaq,Suunikajik,Sverdrup,Taartoq,Takiseeq,Tasirliaq,Tasiusak,Tiilerilaaq,Timilersua,Timmiarmiut,Tukingassoq,Tussaaq,Tuttulissuup,Tuujuk,Uiivaq,Uilortussoq,Ujuaakajiip,Ukkusissat,Upernavik,Uttorsiutit,Uumannaq,Uunartoq,Uvkusigssat,Ymer"},{name:"Basque",i:20,min:4,max:11,d:"r",m:.1,b:"Agurain,Aia,Aiara,Albiztur,Alkiza,Altzaga,Amorebieta,Amurrio,Andoain,Anoeta,Antzuola,Arakaldo,Arantzazu,Arbatzegi,Areatza,Arratzua,Arrieta,Artea,Artziniega,Asteasu,Astigarraga,Ataun,Atxondo,Aulesti,Azkoitia,Azpeitia,Bakio,Baliarrain,Barakaldo,Barrika,Barrundia,Basauri,Beasain,Bedia,Beizama,Belauntza,Berastegi,Bergara,Bermeo,Bernedo,Berriatua,Berriz,Bidania,Bilar,Bilbao,Busturia,Deba,Derio,Donostia,Dulantzi,Durango,Ea,Eibar,Elantxobe,Elduain,Elgeta,Elgoibar,Elorrio,Erandio,Ergoitia,Ermua,Errenteria,Errezil,Eskoriatza,Eskuernaga,Etxebarri,Etxebarria,Ezkio,Forua,Gabiria,Gaintza,Galdakao,Gamiz,Garai,Gasteiz,Gatzaga,Gaubea,Gautegiz,Gaztelu,Gernika,Gerrikaitz,Getaria,Getxo,Gizaburuaga,Goiatz,Gorliz,Gorriaga,Harana,Hernani,Hondarribia,Ibarra,Ibarrangelu,Idiazabal,Iekora,Igorre,Ikaztegieta,Irun,Irura,Iruraiz,Itsaso,Itsasondo,Iurreta,Izurtza,Jatabe,Kanpezu,Karrantza,Kortezubi,Kripan,Kuartango,Lanestosa,Lantziego,Larrabetzu,Lasarte,Laukiz,Lazkao,Leaburu,Legazpi,Legorreta,Legutio,Leintz,Leioa,Lekeitio,Lemoa,Lemoiz,Leza,Lezama,Lezo,Lizartza,Maeztu,Mallabia,Manaria,Markina,Maruri,Menaka,Mendaro,Mendata,Mendexa,Morga,Mundaka,Mungia,Munitibar,Murueta,Muskiz,Mutiloa,Mutriku,Nabarniz,Oiartzun,Oion,Okondo,Olaberria,Onati,Ondarroa,Ordizia,Orendain,Orexa,Oria,Orio,Ormaiztegi,Orozko,Ortuella,Otegi,Otxandio,Pasaia,Plentzia,Santurtzi,Sestao,Sondika,Soraluze,Sukarrieta,Tolosa,Trapagaran,Turtzioz,Ubarrundia,Ubide,Ugao,Urdua,Urduliz,Urizaharra,Urkabustaiz,Urnieta,Urretxu,Usurbil,Xemein,Zabaleta,Zaia,Zaldibar,Zambrana,Zamudio,Zaratamo,Zarautz,Zeberio,Zegama,Zerain,Zestoa,Zierbena,Zigoitia,Ziortza,Zuia,Zumaia,Zumarraga"},{name:"Nigerian",i:21,min:4,max:10,d:"",m:.3,b:"Abadogo,Abafon,Adealesu,Adeto,Adyongo,Afaga,Afamju,Agigbigi,Agogoke,Ahute,Aiyelaboro,Ajebe,Ajola,Akarekwu,Akunuba,Alawode,Alkaijji,Amangam,Amgbaye,Amtasa,Amunigun,Animahun,Anyoko,Arapagi,Asande,Awgbagba,Awhum,Awodu,Babateduwa,Bandakwai,Bangdi,Bilikani,Birnindodo,Braidu,Bulakawa,Buriburi,Cainnan,Chakum,Chondugh,Dagwarga,Darpi,Dokatofa,Dozere,Ebelibri,Efem,Ekoku,Ekpe,Ewhoeviri,Galea,Gamen,Ganjin,Gantetudu,Gargar,Garinbode,Gbure,Gerti,Gidan,Gitabaremu,Giyagiri,Giyawa,Gmawa,Golakochi,Golumba,Gunji,Gwambula,Gwodoti,Hayinlere,Hayinmaialewa,Hirishi,Hombo,Ibefum,Iberekodo,Icharge,Idofin,Idofinoka,Igbogo,Ijoko,Ijuwa,Ikawga,Ikhin,Ikpakidout,Ikpeoniong,Imuogo,Ipawo,Ipinlerere,Isicha,Itakpa,Jangi,Jare,Jataudakum,Jaurogomki,Jepel,Kafinmalama,Katab,Katanga,Katinda,Katirije,Kaurakimba,Keffinshanu,Kellumiri,Kiagbodor,Kirbutu,Kita,Kogogo,Kopje,Korokorosei,Kotoku,Kuata,Kujum,Kukau,Kunboon,Kuonubogbene,Kurawe,Kushinahu,Kwaramakeri,Ladimeji,Lafiaro,Lahaga,Laindebajanle,Laindegoro,Lakati,Litenswa,Maba,Madarzai,Maianita,Malikansaa,Mata,Megoyo,Meku,Miama,Modi,Mshi,Msugh,Muduvu,Murnachehu,Namnai,Ndamanma,Ndiwulunbe,Ndonutim,Ngbande,Nguengu,Ntoekpe,Nyajo,Nyior,Odajie,Ogbaga,Ogultu,Ogunbunmi,Ojopode,Okehin,Olugunna,Omotunde,Onipede,Onma,Orhere,Orya,Otukwang,Otunade,Rampa,Rimi,Rugan,Rumbukawa,Sabiu,Sangabama,Sarabe,Seboregetore,Shafar,Shagwa,Shata,Shengu,Sokoron,Sunnayu,Tafoki,Takula,Talontan,Tarhemba,Tayu,Ter,Timtim,Timyam,Tindirke,Tokunbo,Torlwam,Tseakaadza,Tseanongo,Tsebeeve,Tsepaegh,Tuba,Tumbo,Tungalombo,Tunganyakwe,Uhkirhi,Umoru,Umuabai,Umuajuju,Unchida,Ungua,Unguwar,Unongo,Usha,Utongbo,Vembera,Wuro,Yanbashi,Yanmedi,Yoku,Zarunkwari,Zilumo,Zulika"},{name:"Celtic",i:22,min:4,max:12,d:"nld",m:0,b:"Aberaman,Aberangell,Aberarth,Aberavon,Aberbanc,Aberbargoed,Aberbeeg,Abercanaid,Abercarn,Abercastle,Abercegir,Abercraf,Abercregan,Abercych,Abercynon,Aberdare,Aberdaron,Aberdaugleddau,Aberdeen,Aberdulais,Aberdyfi,Aberedw,Abereiddy,Abererch,Abereron,Aberfan,Aberffraw,Aberffrwd,Abergavenny,Abergele,Aberglasslyn,Abergorlech,Abergwaun,Abergwesyn,Abergwili,Abergwynfi,Abergwyngregyn,Abergynolwyn,Aberhafesp,Aberhonddu,Aberkenfig,Aberllefenni,Abermain,Abermaw,Abermorddu,Abermule,Abernant,Aberpennar,Aberporth,Aberriw,Abersoch,Abersychan,Abertawe,Aberteifi,Aberthin,Abertillery,Abertridwr,Aberystwyth,Achininver,Afonhafren,Alisaha,Anfosadh,Antinbhearmor,Ardenna,Attacon,Banwen,Beira,Bhrura,Bleddfa,Boioduro,Bona,Boskyny,Boslowenpolbrogh,Boudobriga,Bravon,Brigant,Briganta,Briva,Brosnach,Caersws,Cambodunum,Cambra,Caracta,Catumagos,Centobriga,Ceredigion,Chalain,Chearbhallain,Chlasaigh,Chormaic,Cuileannach,Dinn,Diwa,Dubingen,Duibhidighe,Duro,Ebora,Ebruac,Eburodunum,Eccles,Egloskuri,Eighe,Eireann,Elerghi,Ferkunos,Fhlaithnin,Gallbhuaile,Genua,Ghrainnse,Gwyles,Heartsease,Hebron,Hordh,Inbhear,Inbhir,Inbhirair,Innerleithen,Innerleven,Innerwick,Inver,Inveraldie,Inverallan,Inveralmond,Inveramsay,Inveran,Inveraray,Inverarnan,Inverbervie,Inverclyde,Inverell,Inveresk,Inverfarigaig,Invergarry,Invergordon,Invergowrie,Inverhaddon,Inverkeilor,Inverkeithing,Inverkeithney,Inverkip,Inverleigh,Inverleith,Inverloch,Inverlochlarig,Inverlochy,Invermay,Invermoriston,Inverness,Inveroran,Invershin,Inversnaid,Invertrossachs,Inverugie,Inveruglas,Inverurie,Iubhrach,Karardhek,Kilninver,Kirkcaldy,Kirkintilloch,Krake,Lanngorrow,Latense,Leming,Lindomagos,Llanaber,Llandidiwg,Llandyrnog,Llanfarthyn,Llangadwaldr,Llansanwyr,Lochinver,Lugduno,Magoduro,Mheara,Monmouthshire,Nanshiryarth,Narann,Novioduno,Nowijonago,Octoduron,Penning,Pheofharain,Ponsmeur,Raithin,Ricomago,Rossinver,Salodurum,Seguia,Sentica,Theorsa,Tobargeal,Trealaw,Trefesgob,Trewedhenek,Trewythelan,Tuaisceart,Uige,Vitodurum,Windobona"},{name:"Mesopotamian",i:23,min:4,max:9,d:"srpl",m:.1,b:"Adab,Adamndun,Adma,Admatum,Agrab,Akkad,Akshak,Amnanum,Andarig,Anshan,Apiru,Apum,Arantu,Arbid,Arpachiyah,Arpad,Arrapha,Ashlakka,Assur,Awan,Babilim,Bad-Tibira,Balawat,Barsip,Birtu,Bit-Bunakki,Borsippa,Chuera,Dashrah,Der,Dilbat,Diniktum,Doura,Dur-Kurigalzu,Dur-Sharrukin,Dur-Untash,Dûr-gurgurri,Ebla,Ekallatum,Ekalte,Emar,Erbil,Eresh,Eridu,Eshnunn,Eshnunna,Gargamish,Gasur,Gawra,Gibil,Girsu,Gizza,Habirun,Habur,Hadatu,Hakkulan,Halab,Halabit,Hamazi,Hamoukar,Haradum,Harbidum,Harran,Harranu,Hassuna,Hatarikka,Hatra,Hissar,Hiyawa,Hormirzad,Ida-Maras,Idamaraz,Idu,Imerishu,Imgur-Enlil,Irisagrig,Irnina,Irridu,Isin,Issinnitum,Iturungal,Izubitum,Jarmo,Jemdet,Kabnak,Kadesh,Kahat,Kalhu,Kar-Shulmanu-Asharedu,Kar-Tukulti-Ninurta,Kar-shulmanu-asharedu,Karana,Karatepe,Kartukulti,Kazallu,Kesh,Kidsha,Kinza,Kish,Kisiga,Kisurra,Kuara,Kurda,Kurruhanni,Kutha,Lagaba,Lagash,Larak,Larsa,Leilan,Malgium,Marad,Mardaman,Mari,Marlik,Mashkan,Mashkan-shapir,Matutem,Me-Turan,Meliddu,Mumbaqat,Nabada,Nagar,Nanagugal,Nerebtum,Nigin,Nimrud,Nina,Nineveh,Ninua,Nippur,Niru,Niya,Nuhashe,Nuhasse,Nuzi,Puzrish-Dagan,Qalatjarmo,Qatara,Qatna,Qattunan,Qidshu,Rapiqum,Rawda,Sagaz,Shaduppum,Shaggaratum,Shalbatu,Shanidar,Sharrukin,Shawwan,Shehna,Shekhna,Shemshara,Shibaniba,Shubat-Enlil,Shurkutir,Shuruppak,Shusharra,Shushin,Sikan,Sippar,Sippar-Amnanum,Sippar-sha-Annunitum,Subatum,Susuka,Tadmor,Tarbisu,Telul,Terqa,Tirazish,Tisbon,Tuba,Tushhan,Tuttul,Tutub,Ubaid,Umma,Ur,Urah,Urbilum,Urkesh,Ursa'um,Uruk,Urum,Uzarlulu,Warka,Washukanni,Zabalam,Zarri-Amnan"},{name:"Iranian",i:24,min:5,max:11,d:"",m:.1,b:"Abali,Abrisham,Absard,Abuzeydabad,Afus,Alavicheh,Alikosh,Amol,Anarak,Anbar,Andisheh,Anshan,Aran,Ardabil,Arderica,Ardestan,Arjomand,Asgaran,Asgharabad,Ashian,Awan,Babajan,Badrud,Bafran,Baghestan,Baghshad,Bahadoran,Baharan Shahr,Baharestan,Bakun,Bam,Baqershahr,Barzok,Bastam,Behistun,Bitistar,Bumahen,Bushehr,Chadegan,Chahardangeh,Chamgardan,Chermahin,Choghabonut,Chugan,Damaneh,Damavand,Darabgard,Daran,Dastgerd,Dehaq,Dehaqan,Dezful,Dizicheh,Dorcheh,Dowlatabad,Duruntash,Ecbatana,Eslamshahr,Estakhr,Ezhiyeh,Falavarjan,Farrokhi,Fasham,Ferdowsieh,Fereydunshahr,Ferunabad,Firuzkuh,Fuladshahr,Ganjdareh,Ganzak,Gaz,Geoy,Godin,Goldasht,Golestan,Golpayegan,Golshahr,Golshan,Gorgab,Guged,Habibabad,Hafshejan,Hajjifiruz,Hana,Harand,Hasanabad,Hasanlu,Hashtgerd,Hecatompylos,Hormirzad,Imanshahr,Isfahan,Jandaq,Javadabad,Jiroft,Jowsheqan ,Jowzdan,Kabnak,Kahrizak,Kahriz Sang,Kangavar,Karaj,Karkevand,Kashan,Kelishad,Kermanshah,Khaledabad,Khansar,Khorramabad,Khur,Khvorzuq,Kilan,Komeh,Komeshcheh,Konar,Kuhpayeh,Kul,Kushk,Lavasan,Laybid,Liyan,Lyan,Mahabad,Mahallat,Majlesi,Malard,Manzariyeh,Marlik,Meshkat,Meymeh,Miandasht,Mish,Mobarakeh,Nahavand,Nain,Najafabad,Naqshe,Narezzash,Nasimshahr,Nasirshahr,Nasrabad,Natanz,Neyasar,Nikabad,Nimvar,Nushabad,Pakdasht,Parand,Pardis,Parsa,Pasargadai,Patigrabana,Pir Bakran,Pishva,Qahderijan,Qahjaverestan,Qamsar,Qarchak,Qods,Rabat,Ray-shahr,Rezvanshahr,Rhages,Robat Karim,Rozveh,Rudehen,Sabashahr,Safadasht,Sagzi,Salehieh,Sandal,Sarvestan,Sedeh,Sefidshahr,Semirom,Semnan,Shadpurabad,Shah,Shahdad,Shahedshahr,Shahin,Shahpour,Shahr,Shahreza,Shahriar,Sharifabad,Shemshak,Shiraz,Shushan,Shushtar,Sialk,Sin,Sukhteh,Tabas,Tabriz,Takhte,Talkhuncheh,Talli,Tarq,Temukan,Tepe,Tiran,Tudeshk,Tureng,Urmia,Vahidieh,Vahrkana,Vanak,Varamin,Varnamkhast,Varzaneh,Vazvan,Yahya,Yarim,Yasuj,Zarrin Shahr,Zavareh,Zayandeh,Zazeran,Ziar,Zibashahr,Zranka"},{name:"Hawaiian",i:25,min:5,max:10,d:"auo",m:1,b:"Aapueo,Ahoa,Ahuakaio,Ahupau,Alaakua,Alae,Alaeloa,Alamihi,Aleamai,Alena,Alio,Aupokopoko,Halakaa,Haleu,Haliimaile,Hamoa,Hanakaoo,Hanaulu,Hanawana,Hanehoi,Haou,Hikiaupea,Hokuula,Honohina,Honokahua,Honokeana,Honokohau,Honolulu,Honomaele,Hononana,Honopou,Hoolawa,Huelo,Kaalaea,Kaapahu,Kaeo,Kahalehili,Kahana,Kahuai,Kailua,Kainehe,Kakalahale,Kakanoni,Kalenanui,Kaleoaihe,Kalialinui,Kalihi,Kalimaohe,Kaloi,Kamani,Kamehame,Kanahena,Kaniaula,Kaonoulu,Kapaloa,Kapohue,Kapuaikini,Kapunakea,Kauau,Kaulalo,Kaulanamoa,Kauluohana,Kaumakani,Kaumanu,Kaunauhane,Kaupakulua,Kawaloa,Keaa,Keaaula,Keahua,Keahuapono,Kealahou,Keanae,Keauhou,Kelawea,Keokea,Keopuka,Kikoo,Kipapa,Koakupuna,Koali,Kolokolo,Kopili,Kou,Kualapa,Kuhiwa,Kuholilea,Kuhua,Kuia,Kuikui,Kukoae,Kukohia,Kukuiaeo,Kukuipuka,Kukuiula,Kulahuhu,Lapakea,Lapueo,Launiupoko,Lole,Maalo,Mahinahina,Mailepai,Makaakini,Makaalae,Makaehu,Makaiwa,Makaliua,Makapipi,Makapuu,Maluaka,Manawainui,Mehamenui,Moalii,Moanui,Mohopili,Mokae,Mokuia,Mokupapa,Mooiki,Mooloa,Moomuku,Muolea,Nakaaha,Nakalepo,Nakaohu,Nakapehu,Nakula,Napili,Niniau,Nuu,Oloewa,Olowalu,Omaopio,Onau,Onouli,Opaeula,Opana,Opikoula,Paakea,Paeahu,Paehala,Paeohi,Pahoa,Paia,Pakakia,Palauea,Palemo,Paniau,Papaaea,Papaanui,Papaauhau,Papaka,Papauluana,Pauku,Paunau,Pauwalu,Pauwela,Pohakanele,Polaiki,Polanui,Polapola,Poopoo,Poponui,Poupouwela,Puahoowali,Puakea,Puako,Pualaea,Puehuehu,Pueokauiki,Pukaauhuhu,Pukuilua,Pulehu,Puolua,Puou,Puuhaehae,Puuiki,Puuki,Puulani,Puunau,Puuomaile,Uaoa,Uhao,Ukumehame,Ulaino,Ulumalu,Wahikuli,Waianae,Waianu,Waiawa,Waiehu,Waieli,Waikapu,Wailamoa,Wailaulau,Wainee,Waiohole,Waiohonu,Waiohuli,Waiokama,Waiokila,Waiopai,Waiopua,Waipao,Waipionui,Waipouli"},{name:"Karnataka",i:26,min:5,max:11,d:"tnl",m:0,b:"Adityapatna,Adyar,Afzalpur,Aland,Alnavar,Alur,Ambikanagara,Anekal,Ankola,Annigeri,Arkalgud,Arsikere,Athni,Aurad,Badami,Bagalkot,Bagepalli,Bail,Bajpe,Bangalore,Bangarapet,Bankapura,Bannur,Bantval,Basavakalyan,Basavana,Belgaum,Beltangadi,Belur,Bhadravati,Bhalki,Bhatkal,Bhimarayanagudi,Bidar,Bijapur,Bilgi,Birur,Bommasandra,Byadgi,Challakere,Chamarajanagar,Channagiri,Channapatna,Channarayapatna,Chik,Chikmagalur,Chiknayakanhalli,Chikodi,Chincholi,Chintamani,Chitapur,Chitgoppa,Chitradurga,Dandeli,Dargajogihalli,Devadurga,Devanahalli,Dod,Donimalai,Gadag,Gajendragarh,Gangawati,Gauribidanur,Gokak,Gonikoppal,Gubbi,Gudibanda,Gulbarga,Guledgudda,Gundlupet,Gurmatkal,Haliyal,Hangal,Harapanahalli,Harihar,Hassan,Hatti,Haveri,Hebbagodi,Heggadadevankote,Hirekerur,Holalkere,Hole,Homnabad,Honavar,Honnali,Hoovina,Hosakote,Hosanagara,Hosdurga,Hospet,Hubli,Hukeri,Hungund,Hunsur,Ilkal,Indi,Jagalur,Jamkhandi,Jevargi,Jog,Kadigenahalli,Kadur,Kalghatgi,Kamalapuram,Kampli,Kanakapura,Karkal,Karwar,Khanapur,Kodiyal,Kolar,Kollegal,Konnur,Koppa,Koppal,Koratagere,Kotturu,Krishnarajanagara,Krishnarajasagara,Krishnarajpet,Kudchi,Kudligi,Kudremukh,Kumta,Kundapura,Kundgol,Kunigal,Kurgunta,Kushalnagar,Kushtagi,Lakshmeshwar,Lingsugur,Londa,Maddur,Madhugiri,Madikeri,Mahalingpur,Malavalli,Mallar,Malur,Mandya,Mangalore,Manvi,Molakalmuru,Mudalgi,Mudbidri,Muddebihal,Mudgal,Mudhol,Mudigere,Mulbagal,Mulgund,Mulki,Mulur,Mundargi,Mundgod,Munirabad,Mysore,Nagamangala,Nanjangud,Narasimharajapura,Naregal,Nargund,Navalgund,Nipani,Pandavapura,Pavagada,Piriyapatna,Pudu,Puttur,Rabkavi,Raichur,Ramanagaram,Ramdurg,Ranibennur,Raybag,Robertson,Ron,Sadalgi,Sagar,Sakleshpur,Saligram,Sandur,Sankeshwar,Saundatti,Savanur,Sedam,Shahabad,Shahpur,Shaktinagar,Shiggaon,Shikarpur,Shirhatti,Shorapur,Shrirangapattana,Siddapur,Sidlaghatta,Sindgi,Sindhnur,Sira,Siralkoppa,Sirsi,Siruguppa,Somvarpet,Sorab,Sringeri,Srinivaspur,Sulya,Talikota,Tarikere,Tekkalakote,Terdal,Thumbe,Tiptur,Tirthahalli,Tirumakudal,Tumkur,Turuvekere,Udupi,Vijayapura,Wadi,Yadgir,Yelandur,Yelbarga,Yellapur,Yenagudde"},{name:"Quechua",i:27,min:6,max:12,d:"l",m:0,b:"Alpahuaycco,Anchihuay,Anqea,Apurimac,Arequipa,Atahuallpa,Atawalpa,Atico,Ayacucho,Ayahuanco,Ayllu,Cajamarca,Canayre,Canchacancha,Carapo,Carhuac,Carhuacatac,Cashan,Caullaraju,Caxamalca,Cayesh,Ccahuasno,Ccarhuacc,Ccopayoc,Chacchapunta,Chacraraju,Challhuamayo,Champara,Chanchan,Chekiacraju,Chillihua,Chinchey,Chontah,Chopicalqui,Chucuito,Chuito,Chullo,Chumpi,Chuncho,Chupahuacho,Chuquiapo,Chuquisaca,Churup,Cocapata,Cochabamba,Cojup,Collota,Conococha,Corihuayrachina,Cuchoquesera,Cusichaca,Haika,Hanpiq,Hatun,Haywarisqa,Huaca,Huachinga,Hualcan,Hualchancca,Huamanga,Huamashraju,Huancarhuas,Huandoy,Huantsan,Huanupampa,Huarmihuanusca,Huascaran,Huaylas,Huayllabamba,Huayrana,Huaytara,Huichajanca,Huinayhuayna,Huinche,Huinioch,Illiasca,Intipunku,Iquicha,Ishinca,Jahuacocha,Jirishanca,Juli,Jurau,Kakananpunta,Kamasqa,Karpay,Kausay,Khuya,Kuelap,Lanccochayocc,Llaca,Llactapata,Llanganuco,Llaqta,Lloqllasca,Llupachayoc,Luricocha,Machu,Mallku,Matarraju,Mechecc,Mikhuy,Milluacocha,Morochuco,Munay,Ocshapalca,Ollantaytambo,Oroccahua,Oronccoy,Oyolo,Pacamayo,Pacaycasa,Paccharaju,Pachacamac,Pachakamaq,Pachakuteq,Pachakuti,Pachamama,Paititi,Pajaten,Palcaraju,Pallccas,Pampa,Panaka,Paqarina,Paqo,Parap,Paria,Patahuasi,Patallacta,Patibamba,Pisac,Pisco,Pongos,Pucacolpa,Pucahirca,Pucaranra,Pumatambo,Puscanturpa,Putaca,Puyupatamarca,Qawaq,Qayqa,Qochamoqo,Qollana,Qorihuayrachina,Qorimoqo,Qotupuquio,Quenuaracra,Queshque,Quillcayhuanca,Quillya,Quitaracsa,Quitaraju,Qusqu,Rajucolta,Rajutakanan,Rajutuna,Ranrahirca,Ranrapalca,Raria,Rasac,Rimarima,Riobamba,Runkuracay,Rurec,Sacsa,Sacsamarca,Saiwa,Sarapo,Sayacmarca,Sayripata,Sinakara,Sonccopa,Taripaypacha,Taulliraju,Tawantinsuyu,Taytanchis,Tiwanaku,Tocllaraju,Tsacra,Tuco,Tucubamba,Tullparaju,Tumbes,Uchuraccay,Uchuraqay,Ulta,Urihuana,Uruashraju,Vallunaraju,Vilcabamba,Wacho,Wankawillka,Wayra,Yachay,Yahuarraju,Yanamarey,Yanaqucha,Yanesha,Yerupaja"},{name:"Swahili",i:28,min:4,max:9,d:"",m:0,b:"Abim,Adjumani,Alebtong,Amolatar,Amuru,Apac,Arua,Arusha,Babati,Baragoi,Bombo,Budaka,Bugembe,Bugiri,Buikwe,Bukedea,Bukoba,Bukomansimbi,Bukungu,Buliisa,Bundibugyo,Bungoma,Busembatya,Bushenyi,Busia,Busolwe,Butaleja,Butambala,Butere,Buwenge,Buyende,Dadaab,Dodoma,Dokolo,Eldoret,Elegu,Emali,Embu,Entebbe,Garissa,Gede,Gulu,Handeni,Hima,Hoima,Hola,Ibanda,Iganga,Iringa,Isingiro,Isiolo,Jinja,Kaabong,Kabuyanda,Kabwohe,Kagadi,Kajiado,Kakinga,Kakiri,Kakuma,Kalangala,Kaliro,Kalongo,Kalungu,Kampala,Kamwenge,Kanungu,Kapchorwa,Kasese,Kasulu,Katakwi,Kayunga,Keroka,Kiambu,Kibaale,Kibaha,Kibingo,Kibwezi,Kigoma,Kihiihi,Kilifi,Kiruhura,Kiryandongo,Kisii,Kisoro,Kisumu,Kitale,Kitgum,Kitui,Koboko,Korogwe,Kotido,Kumi,Kyazanga,Kyegegwa,Kyenjojo,Kyotera,Lamu,Langata,Lindi,Lodwar,Lokichoggio,Londiani,Loyangalani,Lugazi,Lukaya,Luweero,Lwakhakha,Lwengo,Lyantonde,Machakos,Mafinga,Makambako,Makindu,Malaba,Malindi,Manafwa,Mandera,Marsabit,Masaka,Masindi,Masulita,Matugga,Mayuge,Mbale,Mbarara,Mbeya,Meru,Mitooma,Mityana,Mombasa,Morogoro,Moroto,Moyale,Moyo,Mpanda,Mpigi,Mpondwe,Mtwara,Mubende,Mukono,Muranga,Musoma,Mutomo,Mutukula,Mwanza,Nagongera,Nairobi,Naivasha,Nakapiripirit,Nakaseke,Nakasongola,Nakuru,Namanga,Namayingo,Namutumba,Nansana,Nanyuki,Narok,Naromoru,Nebbi,Ngora,Njeru,Njombe,Nkokonjeru,Ntungamo,Nyahururu,Nyeri,Oyam,Pader,Paidha,Pakwach,Pallisa,Rakai,Ruiru,Rukungiri,Rwimi,Sanga,Sembabule,Shimoni,Shinyanga,Singida,Sironko,Songea,Soroti,Ssabagabo,Sumbawanga,Tabora,Takaungu,Tanga,Thika,Tororo,Tunduma,Vihiga,Voi,Wajir,Wakiso,Watamu,Webuye,Wobulenzi,Wote,Wundanyi,Yumbe,Zanzibar"},{name:"Vietnamese",i:29,min:3,max:12,d:"",m:1,b:"An Giang,Anh Son,An Khe,An Nhon,Ayun Pa,Bac Giang,Bac Kan,Bac Lieu,Bac Ninh,Ba Don,Bao Loc,Ba Ria,Ba Ria-Vung Tau,Ba Thuoc,Ben Cat,Ben Tre,Bien Hoa,Bim Son,Binh Dinh,Binh Duong,Binh Long,Binh Minh,Binh Phuoc,Binh Thuan,Buon Ho,Buon Ma Thuot,Cai Lay,Ca Mau,Cam Khe,Cam Pha,Cam Ranh,Cam Thuy,Can Tho,Cao Bang,Cao Lanh,Cao Phong,Chau Doc,Chi Linh,Con Cuong,Cua Lo,Da Bac,Dak Lak,Da Lat,Da Nang,Di An,Dien Ban,Dien Bien,Dien Bien Phu,Dien Chau,Do Luong,Dong Ha,Dong Hoi,Dong Trieu,Duc Pho,Duyen Hai,Duy Tien,Gia Lai,Gia Nghia,Gia Rai,Go Cong,Ha Giang,Ha Hoa,Hai Duong,Hai Phong,Ha Long,Ha Nam,Ha Noi,Ha Tinh,Ha Trung,Hau Giang,Hoa Binh,Hoang Mai,Hoa Thanh,Ho Chi Minh,Hoi An,Hong Linh,Hong Ngu,Hue,Hung Nguyen,Hung Yen,Huong Thuy,Huong Tra,Khanh Hoa,Kien Tuong,Kim Boi,Kinh Mon,Kon Tum,Ky Anh,Ky Son,Lac Son,Lac Thuy,La Gi,Lai Chau,Lam Thao,Lang Chanh,Lang Son,Lao Cai,Long An,Long Khanh,Long My,Long Xuyen,Luong Son,Mai Chau,Mong Cai,Muong Lat,Muong Lay,My Hao,My Tho,Nam Dan,Nam Dinh,Nga Bay,Nga Nam,Nga Son,Nghe An,Nghia Dan,Nghia Lo,Nghi Loc,Nghi Son,Ngoc Lac,Nha Trang,Nhu Thanh,Nhu Xuan,Ninh Binh,Ninh Hoa,Nong Cong,Phan Rang Thap Cham,Phan Thiet,Pho Yen,Phu Ly,Phu My,Phu Ninh,Phuoc Long,Phu Tho,Phu Yen,Pleiku,Quang Binh,Quang Nam,Quang Ngai,Quang Ninh,Quang Tri,Quang Xuong,Quang Yen,Quan Hoa,Quan Son,Que Phong,Quy Chau,Quy Hop,Quynh Luu,Quy Nhon,Rach Gia,Sa Dec,Sai Gon,Sam Son,Sa Pa,Soc Trang,Song Cau,Song Cong,Son La,Son Tay,Tam Diep,Tam Ky,Tan An,Tan Chau,Tan Ky,Tan Lac,Tan Son,Tan Uyen,Tay Ninh,Thach Thanh,Thai Binh,Thai Hoa,Thai Nguyen,Thanh Chuong,Thanh Hoa,Thieu Hoa,Thuan An,Thua Thien-Hue,Thu Dau Mot,Thu Duc,Thuong Xuan,Tien Giang,Trang Bang,Tra Vinh,Trieu Son,Tu Son,Tuyen Quang,Tuy Hoa,Uong Bi,Viet Tri,Vinh,Vinh Chau,Vinh Loc,Vinh Long,Vinh Yen,Vi Thanh,Vung Tau,Yen Bai,Yen Dinh,Yen Thanh,Yen Thuy"},{name:"Cantonese",i:30,min:5,max:11,d:"",m:0,b:"Chaiwan,Chingchung,Chinghoi,Chingsen,Chingshing,Chiunam,Chiuon,Chiuyeung,Chiyuen,Choihung,Chuehoi,Chuiman,Chungfu,Chungsan,Chunguktsuen,Dakhing,Daopo,Daumun,Dingwu,Dinpak,Donggun,Dongyuen,Duenchau,Fachau,Fanling,Fatgong,Fatshan,Fotan,Fuktien,Fumun,Funggong,Funghoi,Fungshun,Fungtei,Gamtin,Gochau,Goming,Gonghoi,Gongshing,Goyiu,Hanghau,Hangmei,Hengon,Heungchau,Heunggong,Heungkiu,Hingning,Hohfuktong,Hoichue,Hoifung,Hoiping,Hokong,Hokshan,Hoyuen,Hunghom,Hungshuikiu,Jiuling,Kamsheung,Kamwan,Kaulongtong,Keilun,Kinon,Kinsang,Kityeung,Kongmun,Kukgong,Kwaifong,Kwaihing,Kwongchau,Kwongling,Kwongming,Kwuntong,Laichikok,Laiking,Laiwan,Lamtei,Lamtin,Leitung,Leungking,Limkong,Linping,Linshan,Loding,Lokcheong,Lokfu,Longchuen,Longgong,Longmun,Longping,Longwa,Longwu,Lowu,Luichau,Lukfung,Lukho,Lungmun,Macheung,Maliushui,Maonshan,Mauming,Maunam,Meifoo,Mingkum,Mogong,Mongkok,Muichau,Muigong,Muiyuen,Naiwai,Namcheong,Namhoi,Namhong,Namsha,Nganwai,Ngautaukok,Ngchuen,Ngwa,Onting,Pakwun,Paotoishan,Pingshan,Pingyuen,Poklo,Pongon,Poning,Potau,Puito,Punyue,Saiwanho,Saiyingpun,Samshing,Samshui,Samtsen,Samyuenlei,Sanfung,Sanhing,Sanhui,Sanwai,Seiwui,Shamshuipo,Shanmei,Shantau,Shauking,Shekmun,Shekpai,Sheungshui,Shingkui,Shiuhing,Shundak,Shunyi,Shupinwai,Simshing,Siuhei,Siuhong,Siukwan,Siulun,Suikai,Taihing,Taikoo,Taipo,Taishuihang,Taiwai,Taiwohau,Tinhau,Tinshuiwai,Tiukengleng,Toishan,Tongfong,Tonglowan,Tsakyoochung,Tsamgong,Tsangshing,Tseungkwano,Tsimshatsui,Tsinggong,Tsingshantsuen,Tsingwun,Tsingyi,Tsingyuen,Tsiuchau,Tsuenshekshan,Tsuenwan,Tuenmun,Tungchung,Waichap,Waichau,Waidong,Wailoi,Waishing,Waiyeung,Wanchai,Wanfau,Wanshing,Wingon,Wongpo,Wongtaisin,Woping,Wukaisha,Yano,Yaumatei,Yautong,Yenfa,Yeungchun,Yeungdong,Yeungsai,Yeungshan,Yimtin,Yingdak,Yiuping,Yongshing,Yongyuen,Yuenlong,Yuenshing,Yuetsau,Yuknam,Yunping"},{name:"Mongolian",i:31,min:5,max:12,d:"aou",m:.3,b:"Adaatsag,Airag,Alag Erdene,Altai,Altanshiree,Altantsogts,Arbulag,Baatsagaan,Batnorov,Batshireet,Battsengel,Bayan Adarga,Bayan Agt,Bayanbulag,Bayandalai,Bayandun,Bayangovi,Bayanjargalan,Bayankhongor,Bayankhutag,Bayanlig,Bayanmonkh,Bayannur,Bayannuur,Bayan Ondor,Bayan Ovoo,Bayantal,Bayantsagaan,Bayantumen,Bayan Uul,Bayanzurkh,Berkh,Biger,Binder,Bogd,Bombogor,Bor Ondor,Bugat,Bugt,Bulgan,Buregkhangai,Burentogtokh,Buutsagaan,Buyant,Chandmani,Chandmani Ondor,Choibalsan,Chuluunkhoroot,Chuluut,Dadal,Dalanjargalan,Dalanzadgad,Darhan Muminggan,Darkhan,Darvi,Dashbalbar,Dashinchilen,Delger,Delgerekh,Delgerkhaan,Delgerkhangai,Delgertsogt,Deluun,Deren,Dorgon,Duut,Erdene,Erdenebulgan,Erdeneburen,Erdenedalai,Erdenemandal,Erdenetsogt,Galshar,Galt,Galuut,Govi Ugtaal,Gurvan,Gurvanbulag,Gurvansaikhan,Gurvanzagal,Hinggan,Hodong,Holingol,Hondlon,Horin Ger,Horqin,Hulunbuir,Hure,Ikhkhet,Ikh Tamir,Ikh Uul,Jargalan,Jargalant,Jargaltkhaan,Jarud,Jinst,Khairkhan,Khalhgol,Khaliun,Khanbogd,Khangai,Khangal,Khankh,Khankhongor,Khashaat,Khatanbulag,Khatgal,Kherlen,Khishig Ondor,Khokh,Kholonbuir,Khongor,Khotont,Khovd,Khovsgol,Khuld,Khureemaral,Khurmen,Khutag Ondor,Luus,Mandakh,Mandal Ovoo,Mankhan,Manlai,Matad,Mogod,Monkhkhairkhan,Moron,Most,Myangad,Nogoonnuur,Nomgon,Norovlin,Noyon,Ogii,Olgii,Olziit,Omnodelger,Ondorkhaan,Ondorshil,Ondor Ulaan,Ongniud,Ordos,Orgon,Orkhon,Rashaant,Renchinlkhumbe,Sagsai,Saikhan,Saikhandulaan,Saikhan Ovoo,Sainshand,Saintsagaan,Selenge,Sergelen,Sevrei,Sharga,Sharyngol,Shine Ider,Shinejinst,Shiveegovi,Sumber,Taishir,Tarialan,Tariat,Teshig,Togrog,Togtoh,Tolbo,Tomorbulag,Tonkhil,Tosontsengel,Tsagaandelger,Tsagaannuur,Tsagaan Ovoo,Tsagaan Uur,Tsakhir,Tseel,Tsengel,Tsenkher,Tsenkhermandal,Tsetseg,Tsetserleg,Tsogt,Tsogt Ovoo,Tsogttsetsii,Tumed,Tunel,Tuvshruulekh,Ulaanbadrakh,Ulaankhus,Ulaan Uul,Ulanhad,Ulanqab,Uyench,Yesonbulag,Zag,Zalainur,Zamyn Uud,Zereg"},{name:"Human Generic",i:32,min:6,max:11,d:"peolst",m:0,b:"Amberglen,Angelhand,Arrowden,Autumnband,Autumnkeep,Basinfrost,Basinmore,Bayfrost,Beargarde,Bearmire,Bellcairn,Bellport,Bellreach,Blackwatch,Bleakward,Bonemouth,Boulder,Bridgefalls,Bridgeforest,Brinepeak,Brittlehelm,Bronzegrasp,Castlecross,Castlefair,Cavemire,Claymond,Claymouth,Clearguard,Cliffgate,Cliffshear,Cliffshield,Cloudbay,Cloudcrest,Cloudwood,Coldholde,Cragbury,Crowgrove,Crowvault,Crystalrock,Crystalspire,Cursefield,Curseguard,Cursespell,Dawnforest,Dawnwater,Deadford,Deadkeep,Deepcairn,Deerchill,Demonfall,Dewglen,Dewmere,Diredale,Direden,Dirtshield,Dogcoast,Dogmeadow,Dragonbreak,Dragonhold,Dragonward,Dryhost,Dustcross,Dustwatch,Eaglevein,Earthfield,Earthgate,Earthpass,Ebonfront,Edgehaven,Eldergate,Eldermere,Embervault,Everchill,Evercoast,Falsevale,Faypond,Fayvale,Fayyard,Fearpeak,Flameguard,Flamewell,Freyshell,Ghostdale,Ghostpeak,Gloomburn,Goldbreach,Goldyard,Grassplains,Graypost,Greeneld,Grimegrove,Grimeshire,Heartfall,Heartford,Heartvault,Highbourne,Hillpass,Hollowstorm,Honeywater,Houndcall,Houndholde,Iceholde,Icelight,Irongrave,Ironhollow,Knightlight,Knighttide,Lagoonpass,Lakecross,Lastmere,Laststar,Lightvale,Limeband,Littlehall,Littlehold,Littlemire,Lostcairn,Lostshield,Loststar,Madfair,Madham,Midholde,Mightglen,Millstrand,Mistvault,Mondpass,Moonacre,Moongulf,Moonwell,Mosshand,Mosstide,Mosswind,Mudford,Mudwich,Mythgulch,Mythshear,Nevercrest,Neverfront,Newfalls,Nighthall,Oakenbell,Oakenrun,Oceanstar,Oldreach,Oldwall,Oldwatch,Oxbrook,Oxlight,Pearlhaven,Pinepond,Pondfalls,Pondtown,Pureshell,Quickbell,Quickpass,Ravenside,Roguehaven,Roseborn,Rosedale,Rosereach,Rustmore,Saltmouth,Sandhill,Scorchpost,Scorchstall,Shadeforest,Shademeadow,Shadeville,Shimmerrun,Shimmerwood,Shroudrock,Silentkeep,Silvercairn,Silvergulch,Smallmire,Smoothcliff,Smoothgrove,Smoothtown,Snakemere,Snowbay,Snowshield,Snowtown,Southbreak,Springmire,Springview,Stagport,Steammouth,Steamwall,Steepmoor,Stillhall,Stoneguard,Stonespell,Stormhand,Stormhorn,Sungulf,Sunhall,Swampmaw,Swangarde,Swanwall,Swiftwell,Thorncairn,Thornhelm,Thornyard,Timberside,Tradewick,Westmeadow,Westpoint,Whiteshore,Whitvalley,Wildeden,Wildwell,Wildyard,Winterhaven,Wolfpass"},{name:"Elven",i:33,min:6,max:12,d:"lenmsrg",m:0,b:"Adrindest,Aethel,Afranthemar,Aiqua,Alari,Allanar,Almalian,Alora,Alyanasari,Alyelona,Alyran,Ammar,Anyndell,Arasari,Aren,Ashmebel,Aymlume,Bel-Didhel,Brinorion,Caelora,Chaulssad,Chaundra,Cyhmel,Cyrang,Dolarith,Dolonde,Draethe,Dranzan,Draugaust,E'ana,Eahil,Edhil,Eebel,Efranluma,Eld-Sinnocrin,Elelthyr,Ellanalin,Ellena,Ellorthond,Eltaesi,Elunore,Emyranserine,Entheas,Eriargond,Esari,Esath,Eserius,Eshsalin,Eshthalas,Evraland,Faellenor,Famelenora,Filranlean,Filsaqua,Gafetheas,Gaf Serine,Geliene,Gondorwin,Guallu,Haeth,Hanluna,Haulssad,Heloriath,Himlarien,Himliene,Hinnead,Hlinas,Hloireenil,Hluihei,Hlurthei,Hlynead,Iaenarion,Iaron,Illanathaes,Illfanora,Imlarlon,Imyse,Imyvelian,Inferius,Inlurth,innsshe,Iralserin,Irethtalos,Irholona,Ishal,Ishlashara,Ithelion,Ithlin,Iulil,Jaal,Jamkadi,Kaalume,Kaansera,Karanthanil,Karnosea,Kasethyr,Keatheas,Kelsya,Keth Aiqua,Kmlon,Kyathlenor,Kyhasera,Lahetheas,Lefdorei,Lelhamelle,Lilean,Lindeenil,Lindoress,Litys,Llaughei,Lya,Lyfa,Lylharion,Lynathalas,Machei,Masenoris,Mathethil,Mathentheas,Meethalas,Menyamar,Mithlonde,Mytha,Mythsemelle,Mythsthas,Naahona,Nalore,Nandeedil,Nasad Ilaurth,Nasin,Nathemar,Neadar,Neilon,Nelalon,Nellean,Nelnetaesi,Nilenathyr,Nionande,Nylm,Nytenanas,Nythanlenor,O'anlenora,Obeth,Ofaenathyr,Ollmnaes,Ollsmel,Olwen,Olyaneas,Omanalon,Onelion,Onelond,Orlormel,Ormrion,Oshana,Oshvamel,Raethei,Rauguall,Reisera,Reslenora,Ryanasera,Rymaserin,Sahnor,Saselune,Sel-Zedraazin,Selananor,Sellerion,Selmaluma,Shaeras,Shemnas,Shemserin,Sheosari,Sileltalos,Siriande,Siriathil,Srannor,Sshanntyr,Sshaulu,Syholume,Sylharius,Sylranbel,Taesi,Thalor,Tharenlon,Thelethlune,Thelhohil,Themar,Thene,Thilfalean,Thilnaenor,Thvethalas,Thylathlond,Tiregul,Tlauven,Tlindhe,Ulal,Ullve,Ulmetheas,Ulssin,Umnalin,Umye,Umyheserine,Unanneas,Unarith,Undraeth,Unysarion,Vel-Shonidor,Venas,Vin Argor,Wasrion,Wlalean,Yaeluma,Yeelume,Yethrion,Ymserine,Yueghed,Yuerran,Yuethin"},{name:"Dark Elven",i:34,min:6,max:14,d:"nrslamg",m:.2,b:"Abaethaggar,Abburth,Afranthemar,Aharasplit,Aidanat,Ald'ruhn,Ashamanu,Ashesari,Ashletheas,Baerario,Baereghel,Baethei,Bahashae,Balmora,Bel-Didhel,Borethanil,Buiyrandyn,Caellagith,Caellathala,Caergroth,Caldras,Chaggar,Chaggaust,Channtar,Charrvhel'raugaust,Chaulssin,Chaundra,ChedNasad,ChetarIthlin,ChethRrhinn,Chymaer,Clarkarond,Cloibbra,Commoragh,Cyrangroth,Cilben,D'eldarc,Daedhrog,Dalkyn,Do'Urden,Doladress,Dolarith,Dolonde,Draethe,Dranzan,Dranzithl,Draugaust,Dreghei,Drelhei,Dryndlu,Dusklyngh,DyonG'ennivalz,Edraithion,Eld-Sinnocrin,Ellorthond,Enhethyr,Entheas,ErrarIthinn,Eryndlyn,Faladhell,Faneadar,Fethalas,Filranlean,Formarion,Ferdor,Gafetheas,Ghrond,Gilranel,Glamordis,Gnaarmok,Gnisis,Golothaer,Gondorwin,Guallidurth,Guallu,Gulshin,Haeth,Haggraef,Harganeth,Harkaldra,Haulssad,Haundrauth,Heloriath,Hlammachar,Hlaughei,Hloireenil,Hluitar,Inferius,Innsshe,Ithilaughym,Iz'aiogith,Jaal,Jhachalkhyn,Kaerabrae,Karanthanil,Karondkar,Karsoluthiyl,Kellyth,Khuul,Lahetheas,Lidurth,Lindeenil,Lirillaquen,LithMy'athar,LlurthDreier,Lolth,Lothuial,Luihaulen'tar,Maeralyn,Maerimydra,Mathathlona,Mathethil,Mellodona,Menagith,Menegwen,Menerrendil,Menzithl,Menzoberranzan,Mila-Nipal,Mithryn,Molagmar,Mundor,Myvanas,Naggarond,Nandeedil,NasadIlaurth,Nauthor,Navethas,Neadar,Nurtaleewe,Nidiel,Noruiben,Olwen,O'lalona,Obeth,Ofaenathyr,Orlormel,Orlytlar,Pelagiad,Raethei,Raugaust,Rauguall,Rilauven,Rrharrvhei,Sadrith,Sel-Zedraazin,Seydaneen,Shaz'rir,Skaal,Sschindylryn,Shamath,Shamenz,Shanntur,Sshanntynlan,Sshanntyr,Shaulssin,SzithMorcane,Szithlin,Szobaeth,Sirdhemben,T'lindhet,Tebh'zhor,Telmere,Telnarquel,Tharlarast,Thylathlond,Tlaughe,Trizex,Tyrybblyn,Ugauth,Ughym,Uhaelben,Ullmatalos,Ulmetheas,Ulrenserine,Uluitur,Undraeth,Undraurth,Undrek'Thoz,Ungethal,UstNatha,Uthaessien,V'elddrinnsshar,Vaajha,Vel-Shonidor,Velddra,Velothi,Venead,Vhalth'vha,Vinargothr,Vojha,Waethe,Waethei,Xaalkis,Yakaridan,Yeelume,Yridhremben,Yuethin,Yuethindrynn,Zirnakaynin"},{name:"Dwarven",i:35,min:4,max:11,d:"dk",m:0,b:"Addundad,Ahagzad,Ahazil,Akil,Akzizad,Anumush,Araddush,Arar,Arbhur,Badushund,Baragzig,Baragzund,Barakinb,Barakzig,Barakzinb,Barakzir,Baramunz,Barazinb,Barazir,Bilgabar,Bilgatharb,Bilgathaz,Bilgila,Bilnaragz,Bilnulbar,Bilnulbun,Bizaddum,Bizaddush,Bizanarg,Bizaram,Bizinbiz,Biziram,Bunaram,Bundinar,Bundushol,Bundushund,Bundushur,Buzaram,Buzundab,Buzundush,Gabaragz,Gabaram,Gabilgab,Gabilgath,Gabizir,Gabunal,Gabunul,Gabuzan,Gatharam,Gatharbhur,Gathizdum,Gathuragz,Gathuraz,Gila,Giledzir,Gilukkhath,Gilukkhel,Gunala,Gunargath,Gunargil,Gundumunz,Gundusharb,Gundushizd,Kharbharbiln,Kharbhatharb,Kharbhela,Kharbilgab,Kharbuzadd,Khatharbar,Khathizdin,Khathundush,Khazanar,Khazinbund,Khaziragz,Khaziraz,Khizdabun,Khizdusharbh,Khizdushath,Khizdushel,Khizdushur,Kholedzar,Khundabiln,Khundabuz,Khundinarg,Khundushel,Khuragzig,Khuramunz,Kibarak,Kibilnal,Kibizar,Kibunarg,Kibundin,Kibuzan,Kinbadab,Kinbaragz,Kinbarakz,Kinbaram,Kinbizah,Kinbuzar,Nala,Naledzar,Naledzig,Naledzinb,Naragzah,Naragzar,Naragzig,Narakzah,Narakzar,Naramunz,Narazar,Nargabad,Nargabar,Nargatharb,Nargila,Nargundum,Nargundush,Nargunul,Narukthar,Narukthel,Nula,Nulbadush,Nulbaram,Nulbilnarg,Nulbunal,Nulbundab,Nulbundin,Nulbundum,Nulbuzah,Nuledzah,Nuledzig,Nulukkhaz,Nulukkhund,Nulukkhur,Sharakinb,Sharakzar,Sharamunz,Sharbarukth,Shatharbhizd,Shatharbiz,Shathazah,Shathizdush,Shathola,Shaziragz,Shizdinar,Shizdushund,Sholukkharb,Shundinulb,Shundushund,Shurakzund,Shuramunz,Tumunzadd,Tumunzan,Tumunzar,Tumunzinb,Tumunzir,Ukthad,Ulbirad,Ulbirar,Ulunzar,Ulur,Umunzad,Undalar,Undukkhil,Undun,Undur,Unduzur,Unzar,Unzathun,Usharar,Zaddinarg,Zaddushur,Zaharbad,Zaharbhizd,Zarakib,Zarakzar,Zaramunz,Zarukthel,Zinbarukth,Zirakinb,Zirakzir,Ziramunz,Ziruktharbh,Zirukthur,Zundumunz"},{name:"Goblin",i:36,min:4,max:9,d:"eag",m:0,b:"Asinx,Bhiagielt,Biokvish,Blix,Blus,Bratliaq,Breshass,Bridvelb,Brybsil,Bugbig,Buyagh,Cel,Chalk,Chiafzia,Chox,Cielb,Cosvil,Crekork,Crild,Croibieq,Diervaq,Dobruing,Driord,Eebligz,Een,Enissee,Esz,Far,Felhob,Froihiofz,Fruict,Fygsee,Gagablin,Gigganqi,Givzieqee,Glamzofs,Glernaahx,Gneabs,Gnoklig,Gobbledak,gobbok,Gobbrin,Heszai,Hiszils,Hobgar,Honk,Iahzaarm,Ialsirt,Ilm,Ish,Jasheafta,Joimtoilm,Kass,Katmelt,Kleabtong,Kleardeek,Klilm,Kluirm,Kuipuinx,Moft,Mogg,Nilbog,Oimzoishai,Onq,Ozbiard,Paas,Phax,Phigheldai,Preang,Prolkeh,Pyreazzi,Qeerags,Qosx,Rekx,Shaxi,Sios,Slehzit,Slofboif,Slukex,Srefs,Srurd,Stiaggaltia,Stiolx,Stioskurt,Stroir,Strytzakt,Stuikvact,Styrzangai,Suirx,Swaxi,Taxai,Thelt,Thresxea,Thult,Traglila,Treaq,Ulb,Ulm,Utha,Utiarm,Veekz,Vohniots,Vreagaald,Watvielx,Wrogdilk,Wruilt,Xurx,Ziggek,Zriokots"},{name:"Orc",i:37,min:4,max:8,d:"gzrcu",m:0,b:"Adgoz,Adgril-Gha,Adog,Adzurd,Agkadh,Agzil-Ghal,Akh,Ariz-Dru,Arkugzo,Arrordri,Ashnedh,Azrurdrekh,Bagzildre,Bashnud,Bedgez-Graz,Bhakh,Bhegh,Bhiccozdur,Bhicrur,Bhirgoshbel,Bhog,Bhurkrukh,Bod-Rugniz,Bogzel,Bozdra,Bozgrun,Bozziz,Bral-Lazogh,Brazadh,Brogved,Brogzozir,Brolzug,Brordegeg,Brorkril-Zrog,Brugroz,Brukh-Zrabrul,Brur-Korre,Bulbredh,Bulgragh,Chaz-Charard,Chegan-Khed,Chugga,Chuzar,Dhalgron-Mog,Dhazon-Ner,Dhezza,Dhoddud,Dhodh-Brerdrodh,Dhodh-Ghigin,Dhoggun-Bhogh,Dhulbazzol,Digzagkigh,Dirdrurd,Dodkakh,Dorgri,Drizdedh,Drobagh,Drodh-Ashnugh,Drogvukh-Drodh,Drukh-Qodgoz,Drurkuz,Dududh,Dur-Khaddol,Egmod,Ekh-Beccon,Ekh-Krerdrugh,Ekh-Mezred,Gagh-Druzred,Gazdrakh-Vrard,Gegnod,Gerkradh,Ghagrocroz,Ghared-Krin,Ghedgrolbrol,Gheggor,Ghizgil,Gho-Ugnud,Gholgard,Gidh-Ucceg,Goccogmurd,Golkon,Graz-Khulgag,Gribrabrokh,Gridkog,Grigh-Kaggaz,Grirkrun-Qur,Grughokh,Grurro,Gugh-Zozgrod,Gur-Ghogkagh,Ibagh-Chol,Ibruzzed,Ibul-Brad,Iggulzaz,Ikh-Ugnan,Irdrelzug,Irmekh-Bhor,Kacruz,Kalbrugh,Karkor-Zrid,Kazzuz-Zrar,Kezul-Bruz,Kharkiz,Khebun,Khorbric,Khuldrerra,Khuzdraz,Kirgol,Koggodh,Korkrir-Grar,Kraghird,Krar-Zurmurd,Krigh-Bhurdin,Kroddadh,Krudh-Khogzokh,Kudgroccukh,Kudrukh,Kudzal,Kuzgrurd-Dedh,Larud,Legvicrodh,Lorgran,Lugekh,Lulkore,Mazgar,Merkraz,Mocculdrer,Modh-Odod,Morbraz,Mubror,Muccug-Ghuz,Mughakh-Chil,Murmad,Nazad-Ludh,Negvidh,Nelzor-Zroz,Nirdrukh,Nogvolkar,Nubud,Nuccag,Nudh-Kuldra,Nuzecro,Oddigh-Krodh,Okh-Uggekh,Ordol,Orkudh-Bhur,Orrad,Qashnagh,Qiccad-Chal,Qiddolzog,Qidzodkakh,Qirzodh,Rarurd,Reradgri,Rezegh,Rezgrugh,Rodrekh,Rogh-Chirzaz,Rordrushnokh,Rozzez,Ruddirgrad,Rurguz-Vig,Ruzgrin,Ugh-Vruron,Ughudadh,Uldrukh-Bhudh,Ulgor,Ulkin,Ummugh-Ekh,Uzaggor,Uzdriboz,Uzdroz,Uzord,Uzron,Vaddog,Vagord-Khod,Velgrudh,Verrugh,Vrazin,Vrobrun,Vrugh-Nardrer,Vrurgu,Vuccidh,Vun-Gaghukh,Zacrad,Zalbrez,Zigmorbredh,Zordrordud,Zorrudh,Zradgukh,Zragmukh,Zragrizgrakh,Zraldrozzuz,Zrard-Krodog,Zrazzuz-Vaz,Zrigud,Zrulbukh-Dekh,Zubod-Ur,Zulbriz,Zun-Bergrord"},{name:"Giant",i:38,min:5,max:10,d:"kdtng",m:0,b:"Addund,Aerora,Agane,Anumush,Arangrim,Bahourg,Baragzund,Barakinb,Barakzig,Barakzinb,Baramunz,Barazinb,Beornelde,Beratira,Borgbert,Botharic,Bremrol,Brerstin,Brildung,Brozu,Bundushund,Burthug,Chazruc,Chergun,Churtec,Dagdhor,Dankuc,Darnaric,Debuch,Dina,Dinez,Diru,Drard,Druguk,Dugfast,Duhal,Dulkun,Eldond,Enuz,Eraddam,Eradhelm,Froththorn,Fynwyn,Gabaragz,Gabaram,Gabizir,Gabuzan,Gagkake,Galfald,Galgrim,Gatal,Gazin,Geru,Gila,Giledzir,Girkun,Glumvat,Gluthmark,Gomruch,Gorkege,Gortho,Gostuz,Grimor,Grimtira,Guddud,Gudgiz,Gulwo,Gunargath,Gundusharb,Guril,Gurkale,Guruge,Guzi,Hargarth,Hartreo,Heimfara,Hildlaug,Idgurth,Inez,Inginy,Iora,Irkin,Jaldhor,Jarwar,Jornangar,Jornmoth,Kakkek,Kaltoch,Kegkez,Kengord,Kharbharbiln,Khatharbar,Khathizdin,Khazanar,Khaziragz,Khizdabun,Khizdushel,Khundinarg,Kibarak,Kibizar,Kigine,Kilfond,Kilkan,Kinbadab,Kinbuzar,Koril,Kostand,Kuzake,Lindira,Lingarth,Maerdis,Magald,Marbold,Marbrand,Memron,Minu,Mistoch,Morluch,Mornkin,Morntaric,Nagu,Naragzah,Naramunz,Narazar,Nargabar,Nargatharb,Nargundush,Nargunul,Natan,Natil,Neliz,Nelkun,Noluch,Norginny,Nulbaram,Nulbilnarg,Nuledzah,Nuledzig,Nulukkhaz,Nulukkhur,Nurkel,Oci,Olane,Oldstin,Orga,Ranava,Ranhera,Rannerg,Rirkan,Rizen,Rurki,Rurkoc,Sadgach,Sgandrol,Sharakzar,Shatharbiz,Shathizdush,Shathola,Shizdinar,Sholukkharb,Shundushund,Shurakzund,Sidga,Sigbeorn,Sigbi,Solfod,Somrud,Srokvan,Stighere,Sulduch,Talkale,Theoddan,Theodgrim,Throtrek,Tigkiz,Tolkeg,Toren,Tozage,Tulkug,Tumunzar,Umunzad,Undukkhil,Usharar,Valdhere,Varkud,Velfirth,Velhera,Vigkan,Vorkige,Vozig,Vylwed,Widhyrde,Wylaeya,Yili,Yotane,Yudgor,Yulkake,Zigez,Zugkan,Zugke"},{name:"Draconic",i:39,min:6,max:14,d:"aliuszrox",m:0,b:"Aaronarra,Adalon,Adamarondor,Aeglyl,Aerosclughpalar,Aghazstamn,Aglaraerose,Agoshyrvor,Alduin,Alhazmabad,Altagos,Ammaratha,Amrennathed,Anaglathos,Andrathanach,Araemra,Araugauthos,Arauthator,Arharzel,Arngalor,Arveiaturace,Athauglas,Augaurath,Auntyrlothtor,Azarvilandral,Azhaq,Balagos,Baratathlaer,Bleucorundum,BrazzPolis,Canthraxis,Capnolithyl,Charvekkanathor,Chellewis,Chelnadatilar,Cirrothamalan,Claugiyliamatar,Cragnortherma,Dargentum,Dendeirmerdammarar,Dheubpurcwenpyl,Domborcojh,Draconobalen,Dragansalor,Dupretiskava,Durnehviir,Eacoathildarandus,Eldrisithain,Enixtryx,Eormennoth,Esmerandanna,Evenaelorathos,Faenphaele,Felgolos,Felrivenser,Firkraag,Fll'Yissetat,Furlinastis,Galadaeros,Galglentor,Garnetallisar,Garthammus,Gaulauntyr,Ghaulantatra,Glouroth,Greshrukk,Guyanothaz,Haerinvureem,Haklashara,Halagaster,Halaglathgar,Havarlan,Heltipyre,Hethcypressarvil,Hoondarrh,Icehauptannarthanyx,Iiurrendeem,Ileuthra,Iltharagh,Ingeloakastimizilian,Irdrithkryn,Ishenalyr,Iymrith,Jaerlethket,Jalanvaloss,Jharakkan,Kasidikal,Kastrandrethilian,Khavalanoth,Khuralosothantar,Kisonraathiisar,Kissethkashaan,Kistarianth,Klauth,Klithalrundrar,Krashos,Kreston,Kriionfanthicus,Krosulhah,Krustalanos,Kruziikrel,Kuldrak,Lareth,Latovenomer,Lhammaruntosz,Llimark,Ma'fel'no'sei'kedeh'naar,MaelestorRex,Magarovallanthanz,Mahatnartorian,Mahrlee,Malaeragoth,Malagarthaul,Malazan,Maldraedior,Maldrithor,MalekSalerno,Maughrysear,Mejas,Meliordianix,Merah,Mikkaalgensis,Mirmulnir,Mistinarperadnacles,Miteach,Mithbarazak,Morueme,Moruharzel,Naaslaarum,Nahagliiv,Nalavarauthatoryl,Naxorlytaalsxar,Nevalarich,Nolalothcaragascint,Nurvureem,Nymmurh,Odahviing,Olothontor,Ormalagos,Otaaryliakkarnos,Paarthurnax,Pelath,Pelendralaar,Praelorisstan,Praxasalandos,Protanther,Qiminstiir,Quelindritar,Ralionate,Rathalylaug,Rathguul,Rauglothgor,Raumorthadar,Relonikiv,Ringreemeralxoth,Roraurim,Rynnarvyx,Sablaxaahl,Sahloknir,Sahrotaar,Samdralyrion,Saryndalaghlothtor,Sawaka,Shalamalauth,Shammagar,Sharndrel,Shianax,Skarlthoon,Skurge,Smergadas,Ssalangan,Sssurist,Sussethilasis,Sylvallitham,Tamarand,Tantlevgithus,Tarlacoal,Tenaarlaktor,Thalagyrt,Tharas'kalagram,Thauglorimorgorus,Thoklastees,Thyka,Tsenshivah,Ueurwen,Uinnessivar,Urnalithorgathla,Velcuthimmorhar,Velora,Vendrathdammarar,Venomindhar,Viinturuth,Voaraghamanthar,Voslaarum,Vr'tark,Vrondahorevos,Vuljotnaak,Vulthuryol,Wastirek,Worlathaugh,Xargithorvar,Xavarathimius,Yemere,Ylithargathril,Ylveraasahlisar,Za-Jikku,Zarlandris,Zellenesterex,Zilanthar,Zormapalearath,Zundaerazylym,Zz'Pzora"},{name:"Arachnid",i:40,min:4,max:10,d:"erlsk",m:0,b:"Aaqok'ser,Aiced,Aizachis,Allinqel,As'taq,Ashrash,Caaqtos,Ceek'sax,Ceezuq,Cek'sier,Cen'qi,Ceqzocer,Cezeed,Chachocaq,Charis,Chashilieth,Checib,Chernul,Chezi,Chiazu,Chishros,Chixhi,Chizhi,Chollash,Choq'sha,Cinchichail,Collul,Ecush'taid,Ekiqe,Eqas,Er'uria,Erikas,Es'tase,Esrub,Exha,Haqsho,Hiavheesh,Hitha,Hok'thi,Hossa,Iacid,Iciever,Illuq,Isnir,Keezut,Kheellavas,Kheizoh,Khiachod,Khika,Khirzur,Khonrud,Khrakku,Khraqshis,Khrethish'ti,Khriashus,Khrika,Khrirni,Klashirel,Kleil'sha,Klishuth,Krarnit,Kras'tex,Krotieqas,Lais'tid,Laizuh,Lasnoth,Len'qeer,Leqanches,Lezad,Lhilir,Lhivhath,Lhok'thu,Lialliesed,Liaraq,Liceva,Lichorro,Lilla,Lokieqib,Nakur,Neerhaca,Neet'er,Neezoh,Nenchiled,Nerhalneth,Nir'ih,Nizus,Noreeqo,On'qix,Qalitho,Qas'tor,Qasol,Qavrud,Qavud,Qazar,Qazru,Qekno,Qeqravee,Qes'tor,Qhaik'sal,Qhak'sish,Qhazsakais,Qheliva,Qhenchaqes,Qherazal,Qhon'qos,Qhosh,Qish'tur,Qisih,Qorhoci,Qranchiq,Racith,Rak'zes,Ranchis,Rarhie,Rarzi,Rarzisiaq,Ras'tih,Ravosho,Recad,Rekid,Rernee,Rertachis,Rezhokketh,Reziel,Rhacish,Rhail'shel,Rhairhizse,Rhakivex,Rhaqeer,Rhartix,Rheciezsei,Rheevid,Rhel'shir,Rhevhie,Rhiavekot,Rhikkos,Rhiqese,Rhiqi,Rhiqracar,Rhisned,Rhousnateb,Riakeesnex,Rintachal,Rir'ul,Rourk'u,Rouzakri,Sailiqei,Sanchiqed,Saqshu,Sat'ier,Sazi,Seiqas,Shieth'i,Shiqsheh,Shizha,Shrachuvo,Shranqo,Shravhos,Shravuth,Shreerhod,Shrethuh,Shriantieth,Shronqash,Shrovarhir,Shrozih,Siacaqoh,Siezosh,Siq'sha,Sirro,Sornosi,Srachussi,Szaca,Szacih,Szaqova,Szasu,Szazhilos,Szeerrud,Szeezsad,Szeknur,Szesir,Szezhirros,Szilshith,Szon'qol,Szornuq,Xeekke,Yeek'su,Yeeq'zox,Yeqil,Yeqroq,Yeveed,Yevied,Yicaveeh,Yirresh,Yisie,Yithik'thaih,Yorhaqshes,Zacheek'sa,Zakkasa,Zelraq,Zeqo,Zharuncho,Zhath'arhish,Zhavirrit,Zhazilraq,Zhazsachiel,Zhek'tha,Zhequ,Zhias'ted,Zhicat,Zhicur,Zhirhacil,Zhizri,Zhochizses,Ziarih,Zirnib"},{name:"Serpents",i:41,min:5,max:11,d:"slrk",m:0,b:"Aj'ha,Aj'i,Aj'tiss,Ajakess,Aksas,Aksiss,Al'en,An'jeshe,Apjige,Arkkess,Athaz,Atus,Azras,Caji,Cakrasar,Cal'arrun,Capji,Cathras,Cej'han,Ces,Cez'jenta,Cij'te,Cinash,Cizran,Coth'jus,Cothrash,Culzanek,Cunaless,Ej'tesh,Elzazash,Ergek,Eshjuk,Ethris,Gan'jas,Gapja,Gar'thituph,Gopjeguss,Gor'thesh,Gragishaph,Grar'theness,Grath'ji,Gressinas,Grolzesh,Grorjar,Grozrash,Guj'ika,Harji,Hej'hez,Herkush,Horgarrez,Illuph,Ipjar,Ithashin,Kaj'ess,Kar'kash,Kepjusha,Ki'kintus,Kissere,Koph,Kopjess,Kra'kasher,Krak,Krapjez,Krashjuless,Kraz'ji,Krirrigis,Krussin,Ma'lush,Mage,Maj'tak,Mal'a,Mapja,Mar'kash,Mar'kis,Marjin,Mas,Mathan,Men'jas,Meth'jaresh,Mij'hegak,Min'jash,Mith'jas,Monassu,Moss,Naj'hass,Najugash,Nak,Napjiph,Nar'ka,Nar'thuss,Narrusha,Nash,Nashjekez,Nataph,Nij'ass,Nij'tessiph,Nishjiss,Norkkuss,Nus,Olluruss,Or'thi,Or'thuss,Paj'a,Parkka,Pas,Pathujen,Paz'jaz,Pepjerras,Pirkkanar,Pituk,Porjunek,Pu'ke,Ragen,Ran'jess,Rargush,Razjuph,Rilzan,Riss,Rithruz,Rorgiss,Rossez,Rraj'asesh,Rraj'tass,Rrar'kess,Rrar'thuph,Rras,Rrazresh,Rrej'hish,Rrigelash,Rris,Rris,Rroksurrush,Rukrussush,Rurri,Russa,Ruth'jes,Sa'kitesh,Sar'thass,Sarjas,Sazjuzush,Ser'thez,Sezrass,Shajas,Shas,Shashja,Shass,Shetesh,Shijek,Shun'jaler,Shurjarri,Skaler,Skalla,Skallentas,Skaph,Skar'kerriz,Skath'jeruk,Sker'kalas,Skor,Skoz'ji,Sku'lu,Skuph,Skur'thur,Slalli,Slalt'har,Slelziress,Slil'ar,Sloz'jisa,Sojesh,Solle,Sorge,Sral'e,Sran'ji,Srapjess,Srar'thazur,Srash,Srath'jess,Srathrarre,Srerkkash,Srus,Sruss'tugeph,Sun,Suss'tir,Uzrash,Vargush,Vek,Vess'tu,Viph,Vult'ha,Vupjer,Vushjesash,Xagez,Xassa,Xulzessu,Zaj'tiss,Zan'jer,Zarriss,Zassegus,Zirres,Zsor,Zurjass"},{name:"Levantine",i:42,min:4,max:12,d:"ankprs",m:0,b:"Adme,Adramet,Agadir,Akko,Akzib,Alimas,Alis-Ubbo,Alqosh,Amid,Ammon,Ampi,Amurru,Andarig,Anpa,Araden,Aram,Arwad,Ashkelon,Athar,Atiq,Aza,Azeka,Baalbek,Babel,Batrun,Beerot,Beersheba,Beit Shemesh,Berytus,Bet Agus,Bet Anya,Beth-Horon,Bethel,Bethlehem,Bethuel,Bet Nahrin,Bet Nohadra,Bet Zalin,Birmula,Biruta,Bit Agushi,Bitan,Bit Zamani,Cerne,Dammeseq,Darmsuq,Dor,Eddial,Eden Ekron,Elah,Emek,Emun,Ephratah,Eyn Ganim,Finike,Gades,Galatia,Gaza,Gebal,Gedera,Gerizzim,Gethsemane,Gibeon,Gilead,Gilgal,Golgotha,Goshen,Gytte,Hagalil,Haifa,Halab,Haqel Dma,Har Habayit,Har Nevo,Har Pisga,Havilah,Hazor,Hebron,Hormah,Iboshim,Iriho,Irinem,Irridu,Israel,Kadesh,Kanaan,Kapara,Karaly,Kart-Hadasht,Keret Chadeshet,Kernah,Kesed,Keysariya,Kfar,Kfar Nahum,Khalibon,Khalpe,Khamat,Kiryat,Kittim,Kurda,Lapethos,Larna,Lepqis,Lepriptza,Liksos,Lod,Luv,Malaka,Malet,Marat,Megido,Melitta,Merdin,Metsada,Mishmarot,Mitzrayim,Moab,Mopsos,Motye,Mukish,Nampigi,Nampigu,Natzrat,Nimrud,Nineveh,Nob,Nuhadra,Oea,Ofir,Oyat,Phineka,Phoenicus,Pleshet,Qart-Tubah Sarepta,Qatna,Rabat Amon,Rakkath,Ramat Aviv,Ramitha,Ramta,Rehovot,Reshef,Rushadir,Rushakad,Samrin,Sefarad,Sehyon,Sepat,Sexi,Sharon,Shechem,Shefelat,Shfanim,Shiloh,Shmaya,Shomron,Sidon,Sinay,Sis,Solki,Sur,Suria,Tabetu,Tadmur,Tarshish,Tartus,Teberya,Tefessedt,Tekoa,Teyman,Tinga,Tipasa,Tsabratan,Tur Abdin,Tzarfat,Tziyon,Tzor,Ugarit,Unubaal,Ureshlem,Urhay,Urushalim,Vaga,Yaffa,Yamhad,Yam hamelach,Yam Kineret,Yamutbal,Yathrib,Yaudi,Yavne,Yehuda,Yerushalayim,Yev,Yevus,Yizreel,Yurdnan,Zarefat,Zeboim,Zeurta,Zeytim,Zikhron,Zmurna"}]}}window.Names=new Iu;class Du{cells;vertices;pointsN;used;lineGen=tn().curve(Tl);oceanLayers;constructor(a){this.oceanLayers=a}randomizeOutline(){const a=[];let n=.2;for(let t=-9;t<0;t++)B(n)?(n=.2,a.push(t)):n*=2;return a}connectVertices(a,n){const t=[];for(let i=0,o=a;i===0||o!==a&&i<1e4;i++){const s=t[t.length-1];t.push(o);const h=this.vertices.c[o];h.filter(r=>this.cells.t[r]===n).forEach(r=>{this.used[r]=1});const u=this.vertices.v[o],l=!this.cells.t[h[0]]||this.cells.t[h[0]]===n-1,c=!this.cells.t[h[1]]||this.cells.t[h[1]]===n-1,d=!this.cells.t[h[2]]||this.cells.t[h[2]]===n-1;if(u[0]!==void 0&&u[0]!==s&&l!==c?o=u[0]:u[1]!==void 0&&u[1]!==s&&c!==d?o=u[1]:u[2]!==void 0&&u[2]!==s&&l!==d&&(o=u[2]),o===t[t.length-1]){ERROR&&console.error("Next vertex is not found");break}}return t.push(t[0]),t}findStart(a,n){return this.cells.b[a]?this.cells.v[a].find(t=>this.vertices.c[t].some(i=>i>=this.pointsN)):this.cells.v[a][this.cells.c[a].findIndex(t=>this.cells.t[t]+o),t=[],i=N(.4/n.length,2);this.used=new Uint8Array(this.pointsN);for(const o of this.cells.i){const s=this.cells.t[o];if(s>0||this.used[o]||!n.includes(s))continue;const h=this.findStart(o,s);if(!h)continue;this.used[o]=1;const u=this.connectVertices(h,s);if(u.length<4)continue;const l=1+s*-2,c=u.filter((r,g)=>!(g%l)||this.vertices.c[r].some(m=>m>=this.pointsN));if(c.length<4)continue;const d=sn(c.map(r=>this.vertices.p[r]),graphWidth,graphHeight,1);t.push([s,d])}for(const o of n){const h=t.filter(u=>u[0]===o).map(u=>ze(this.lineGen(u[1])||"")).join("");h&&this.oceanLayers.append("path").attr("d",h).attr("fill","#ecf2f9").attr("fill-opacity",i)}TIME&&console.timeEnd("drawOceanLayers")}}window.OceanLayers=()=>new Du(oceanLayers).draw();class Gu{LAKE_ELEVATION_DELTA=.1;getHeight(a){const n=pack.cells.h,t=Ba(a.shoreline.map(i=>n[i]))||20;return N(t-this.LAKE_ELEVATION_DELTA,2)}defineNames(){pack.features.forEach(a=>{a.type==="lake"&&(a.name=this.getName(a))})}getName(a){const n=a.shoreline[0],t=pack.cells.culture[n];return Names.getCulture(t)}cleanupLakeData=()=>{for(const a of pack.features){if(a.type!=="lake")continue;delete a.river,delete a.enteringFlux,delete a.outCell,delete a.closed,a.height=N(a.height,3);const n=a.inlets?.filter(i=>pack.rivers.find(o=>o.i===i));!n||!n.length?delete a.inlets:a.inlets=n,a.outlet&&pack.rivers.find(i=>i.i===a.outlet)||delete a.outlet}};defineClimateData(a){const{cells:n,features:t}=pack,i=new Uint16Array(n.i.length),o=l=>l.shoreline.reduce((c,d)=>c+grid.cells.prec[n.g[d]],0),s=l=>l.cells<6?grid.cells.temp[n.g[l.firstCell]]:N(Ha(l.shoreline.map(c=>grid.cells.temp[n.g[c]])),1),h=l=>{const c=(l.height-18)**Number(heightExponentInput.value),d=(700*(l.temp+.006*c)/50+75)/(80-l.temp);return N(d*l.cells)},u=l=>l.shoreline.sort((c,d)=>a[c]-a[d])[0];return t.forEach(l=>{l.type==="lake"&&(l.flux=o(l),l.temp=s(l),l.evaporation=h(l),!l.closed&&(l.outCell=u(l),i[l.outCell]=l.i))}),i}detectCloseLakes(a){const{cells:n}=pack,t=+j("lakeElevationLimitOutput")?.value;pack.features.forEach(i=>{if(i.type!=="lake")return;delete i.closed;const o=i.height+t;if(o>99){i.closed=!1;return}let s=!0;const h=i.shoreline.sort((c,d)=>a[c]-a[d])[0],u=[h],l=[];for(l[h]=!0;u.length&&s;){const c=u.pop();for(const d of n.c[c])if(!l[d]&&!(a[d]>=o)){if(a[d]<20){const r=pack.features[n.f[d]];(r.type==="ocean"||i.height>r.height)&&(s=!1)}l[d]=!0,u.push(d)}}i.closed=s})}}window.Lakes=new Gu;class Ou{FLUX_FACTOR=500;MAX_FLUX_WIDTH=1;LENGTH_FACTOR=200;LENGTH_STEP_WIDTH=1/this.LENGTH_FACTOR;LENGTH_PROGRESSION=[1,1,2,3,5,8,13,21,34].map(a=>a/this.LENGTH_FACTOR);lineGen=tn().curve(zl);riverTypes={main:{big:{River:1},small:{Creek:9,River:3,Brook:3,Stream:1}},fork:{big:{Fork:1},small:{Branch:1}}};smallLength=null;generate(a=!0){TIME&&console.time("generateRivers"),Math.random=Te(seed);const{cells:n,features:t}=pack,i={},o={},s=(m,f)=>{i[f]?i[f].push(m):i[f]=[m]},h=()=>{const f=(pointsInput.dataset.cells/1e4)**.25,p=grid.cells.prec,y=n.i.filter(b=>g[b]>=20).sort((b,v)=>g[v]-g[b]),k=Lakes.defineClimateData(g);for(const b of y){n.fl[b]+=p[n.g[b]]/f;const v=k[b]?t.filter(M=>b===M.outCell&&M.flux>M.evaporation):[];for(const M of v){const T=n.c[b].find(S=>g[S]<20&&n.f[S]===M.i);n.fl[T]+=Math.max(M.flux-M.evaporation,0),n.r[T]!==M.river&&(n.c[T].some(z=>n.r[z]===M.river)?(n.r[T]=M.river,s(T,M.river)):(n.r[T]=r,s(T,r),r++)),M.outlet=n.r[T],u(b,n.fl[T],M.outlet)}const w=v[0]?.outlet;for(const M of v)if(Array.isArray(M.inlets))for(const T of M.inlets)o[T]=w;if(n.b[b]&&n.r[b]){s(-1,n.r[b]);continue}let _=null;if(k[b]?_=n.c[b].filter(T=>!v.map(S=>S.i).includes(n.f[T])).sort((T,S)=>g[T]-g[S])[0]:n.haven[b]?_=n.haven[b]:_=n.c[b].sort((M,T)=>g[M]-g[T])[0],!(g[b]<=g[_])){if(n.fl[b]<30){g[_]>=20&&(n.fl[_]+=n.fl[b]);continue}n.r[b]||(n.r[b]=r,s(b,r),r++),u(_,n.fl[b],n.r[b])}}},u=(m,f,p)=>{const y=n.fl[m]-n.conf[m],k=n.r[m];if(k?f>y?(n.conf[m]+=n.fl[m],g[m]>=20&&(o[k]=p),n.r[m]=p):(n.conf[m]+=f,g[m]>=20&&(o[p]=k)):n.r[m]=p,g[m]<20){const b=t[n.f[m]];b.type==="lake"&&((!b.river||f>b.enteringFlux)&&(b.river=p,b.enteringFlux=f),b.flux=b.flux+f,b.inlets?b.inlets.push(p):b.inlets=[p])}else n.fl[m]+=f;s(m,p)},l=()=>{n.r=new Uint16Array(n.i.length),n.conf=new Uint16Array(n.i.length),pack.rivers=[];const m=N(1/(pointsInput.dataset.cells/1e4)**.25,2),f=m*1.2;for(const p in i){const y=i[p];if(y.length<3)continue;const k=+p;for(const x of y)x<0||n.h[x]<20||(n.r[x]?n.conf[x]=1:n.r[x]=k);const b=y[0],v=y[y.length-2],w=o[p]||0,_=!w||w===k?f:m,M=this.addMeandering(y),T=n.fl[v],S=this.getApproximateLength(M),z=this.getSourceWidth(n.fl[b]),A=this.getWidth(this.getOffset({flux:T,pointIndex:M.length,widthFactor:_,startingWidth:z}));pack.rivers.push({i:k,source:b,mouth:v,discharge:T,length:S,width:A,widthFactor:_,sourceWidth:z,parent:w,cells:y})}},c=()=>{for(const f of pack.cells.i){if(n.h[f]<35||!n.fl[f])continue;const p=n.c[f].filter(b=>n.h[b]>n.h[f]),y=p.reduce((b,v)=>b+n.fl[v],0)/p.length;if(!y)continue;const k=Math.floor(n.fl[f]/y);k&&(n.h[f]-=Math.min(k,5))}},d=()=>{for(const m of n.i){if(!n.conf[m])continue;const f=n.c[m].filter(p=>n.r[p]&&g[p]>g[m]).map(p=>n.fl[p]).sort((p,y)=>y-p);n.conf[m]=f.reduce((p,y,k)=>k?p+y:p,0)}};n.fl=new Uint16Array(n.i.length),n.r=new Uint16Array(n.i.length),n.conf=new Uint8Array(n.i.length);let r=1;const g=this.alterHeights();Lakes.detectCloseLakes(g),this.resolveDepressions(g),h(),l(),d(),Lakes.cleanupLakeData(),a&&(n.h=Uint8Array.from(g),c()),TIME&&console.timeEnd("generateRivers")}alterHeights(){const{h:a,c:n,t}=pack.cells;return Array.from(a).map((i,o)=>i<20||t[o]<1?i:i+t[o]/100+Ha(n[o].map(s=>t[s]))/1e4)}resolveDepressions(a){const{cells:n,features:t}=pack,i=+document.getElementById("resolveDepressionsStepsOutput")?.value,o=i*.85,s=i*.75,h=g=>t[n.f[g]].height||a[g],u=t.filter(g=>g.type==="lake"),l=n.i.filter(g=>a[g]>=20&&!n.b[g]);l.sort((g,m)=>a[g]-a[m]);const c=[];let d=1/0,r=null;for(let g=0;d&&g5&&ai(c)>0){a=this.alterHeights(),d=c[0];break}if(d=0,ga[p]));if(!(f>=100||m.height>f)){if(g>s){m.shoreline.forEach(p=>{a[p]=n.h[p]}),m.height=Ba(m.shoreline.map(p=>a[p]))-1,m.closed=!0;continue}d++,m.height=f+.2}}for(const m of l){const f=Ba(n.c[m].map(p=>h(p)));f>=100||a[m]>f||(d++,a[m]=f+.1)}r!==null&&c.push(d-r),r=d}d&&WARN&&console.warn(`Unresolved depressions: ${d}. Edit heightmap to fix`)}addMeandering(a,n=null,t=.5){const{fl:i,h:o}=pack.cells,s=[],h=a.length-1,u=this.getRiverPoints(a,n);let l=o[a[0]]<20?1:10;for(let c=0;c<=h;c++,l++){const d=a[c],r=c===h,[g,m]=u[c];if(s.push([g,m,i[d]]),r)break;const f=a[c+1],[p,y]=u[c+1];if(f===-1){s.push([p,y,i[d]]);break}const k=(p-g)**2+(y-m)**2;if(k<=25&&a.length>=6)continue;const b=t+1/l+Math.max(t-l/100,0),v=Math.atan2(y-m,p-g),w=Math.sin(v)*b,_=Math.cos(v)*b;if(l<20&&(k>64||k>36&&a.length<5)){const M=(g*2+p)/3+-w,T=(m*2+y)/3+_,S=(g+p*2)/3+w/2,z=(m+y*2)/3-_/2;s.push([M,T,0],[S,z,0])}else if(k>25||a.length<6){const M=(g+p)/2+-w,T=(m+y)/2+_;s.push([M,T,0])}}return s}getRiverPoints(a,n){if(n)return n;const{p:t}=pack.cells;return a.map((i,o)=>i===-1?this.getBorderPoint(a[o-1]):t[i])}getBorderPoint(a){const[n,t]=pack.cells.p[a],i=Math.min(t,graphHeight-t,n,graphWidth-n);return i===t?[n,0]:i===graphHeight-t?[n,graphHeight]:i===n?[0,t]:[graphWidth,t]}getOffset({flux:a,pointIndex:n,widthFactor:t,startingWidth:i}){if(n===0)return i;const o=Math.min(a**.7/this.FLUX_FACTOR,this.MAX_FLUX_WIDTH),s=n*this.LENGTH_STEP_WIDTH+(this.LENGTH_PROGRESSION[n]||this.LENGTH_PROGRESSION.at(-1));return t*(s+o)+i}getSourceWidth(a){return N(Math.min(a**.9/this.FLUX_FACTOR,this.MAX_FLUX_WIDTH),2)}getRiverPath(a,n,t){this.lineGen.curve(Cl.alpha(.1));const i=[],o=[];let s=0;for(let l=0;ls&&(s=m);const y=this.getOffset({flux:s,pointIndex:l,widthFactor:n,startingWidth:t}),k=Math.atan2(d-p,c-f),b=Math.sin(k)*y,v=Math.cos(k)*y;i.push([r-b,g+v]),o.push([r+b,g-v])}const h=this.lineGen(o.reverse());let u=this.lineGen(i)||"";return u=u.substring(u.indexOf("C")),ze(h+u,1)}specify(){const a=pack.rivers;if(a.length)for(const n of a)n.basin=this.getBasin(n.i),n.name=this.getName(n.mouth),n.type=this.getType(n)}getName(a){return Names.getCulture(pack.cells.culture[a])}getType({i:a,length:n,parent:t}){if(this.smallLength===null){const s=Math.ceil(pack.rivers.length*.15);this.smallLength=pack.rivers.map(h=>h.length||0).sort((h,u)=>h-u)[s]}const i=nt+(o?Math.hypot(i[0]-s[o-1][0],i[1]-s[o-1][1]):0),0);return N(n,2)}getWidth(a){return N((a/1.5)**1.8,2)}remove(a){const n=pack.cells,t=pack.rivers.filter(i=>i.i===a||i.parent===a||i.basin===a).map(i=>i.i);t.forEach(i=>{rivers.select(`#river${i}`).remove()}),n.r.forEach((i,o)=>{!i||!t.includes(i)||(n.r[o]=0,n.fl[o]=grid.cells.prec[n.g[o]],n.conf[o]=0)}),pack.rivers=pack.rivers.filter(i=>!t.includes(i.i))}getBasin(a){const n=pack.rivers.find(t=>t.i===a)?.parent;return!n||a===n?a:this.getBasin(n)}getNextId(a){return a.length?Math.max(...a.map(n=>n.i))+1:1}}window.Rivers=new Ou;class qu{shift(){const{cells:a,features:n,burgs:t}=pack,i=grid.cells.temp,o={};for(const h of t){if(!h.i||h.lock)continue;delete h.port;const u=h.cell,l=a.haven[u],c=a.harbor[u],d=a.f[l];if(!d)continue;const r=n[d].cells>1,g=c&&h.capital||c===1,m=i[a.g[u]]<=0;r&&g&&!m&&(o[d]||(o[d]=[]),o[d].push(h))}const s=(h,u)=>{const{cells:l,vertices:c}=pack,[d,r]=l.p[h],g=l.v[h].filter(_=>c.c[_].some(M=>M===u)),[m,f]=c.p[g[0]],[p,y]=c.p[g[1]],k=(m+p)/2,b=(f+y)/2,v=N(d+.95*(k-d),2),w=N(r+.95*(b-r),2);return[v,w]};Object.entries(o).forEach(([h,u])=>{u.length<2||u.forEach(l=>{l.port=h;const c=a.haven[l.cell],[d,r]=s(l.cell,c);l.x=d,l.y=r})});for(const h of t){if(!h.i||h.lock||h.port||!a.r[h.cell])continue;const u=h.cell,l=Math.min(a.fl[u]/150,1);h.x=u%2?N(h.x+l,2):N(h.x-l,2),h.y=a.r[u]%2?N(h.y+l,2):N(h.y-l,2)}}generate(){TIME&&console.time("generateBurgs");const{cells:a}=pack;let n=[0];a.burg=new Uint16Array(a.i.length);const t=a.i.filter(l=>a.s[l]>0&&a.culture[l]);if(!t.length)return ERROR&&console.error("There is no populated cells with culture assigned. Cannot generate states"),n;let i=ue();const o=()=>{const l=m=>m*(.5+Math.random()*.5),c=new Int16Array(a.s.map(l)),d=t.sort((m,f)=>c[f]-c[m]),r=h();let g=(graphWidth+graphHeight)/2/r;for(let m=0;n.length<=r;m++){const f=d[m],[p,y]=a.p[f];i.find(p,y,g)===void 0&&(n.push({cell:f,x:p,y}),i.add([p,y])),m===d.length-1&&(WARN&&console.warn("Cannot place capitals with current spacing. Trying again with reduced spacing"),i=ue(),m=-1,n=[0],g/=1.2)}n.forEach((m,f)=>{f&&(m.i=f,m.state=f,m.culture=a.culture[m.cell],m.name=Names.getCultureShort(m.culture),m.feature=a.f[m.cell],m.capital=1,a.burg[m.cell]=f)})},s=()=>{const l=m=>m*Qa(1,3,0,20,3),c=new Int16Array(a.s.map(l)),d=t.sort((m,f)=>c[f]-c[m]),r=u();let g=(graphWidth+graphHeight)/150/(r**.7/66);for(let m=0;m1;){for(let f=0;m60)return"Highland";if(t.r[a]&&t.fl[a]>=100)return"River";const s=t.biome[a],h=t.pop[a];if(!t.burg[a]||h<=5){if(h<5&&[1,2,3,4].includes(s))return"Nomadic";if(s>4&&s<10)return"Hunting"}return"Generic"}definePopulation(a){const n=a.cell;let t=pack.cells.s[n]/5;a.capital&&(t*=1.5);const i=Routes.getConnectivityRate(n);i&&(t*=i),t*=Qa(1,1,.25,4,5),t+=(a.i%100-n%100)/1e3,a.population=N(Math.max(t,.01),3)}defineEmblem(a){a.type=this.getType(a.cell,a.port);const n=pack.states[a.state],t=n.coa;let i=.25;a.capital?i+=.1:a.port&&(i-=.1),a.culture!==n.culture&&(i-=.25);const o=a.capital&&B(.2)?"Capital":a.type==="Generic"?"City":a.type;a.coa=COA.generate(t,i,null,o),a.coa.shield=COA.getShield(a.culture,a.state)}defineFeatures(a){const n=a.population;a.citadel=Number(a.capital||n>50&&B(.75)||n>15&&B(.5)||B(.1)),a.plaza=Number(Routes.isCrossroad(a.cell)||Routes.hasRoad(a.cell)&&B(.7)||n>20||n>10&&B(.8)),a.walls=Number(a.capital||n>30||n>20&&B(.75)||n>10&&B(.5)||B(.1)),a.shanty=Number(n>60||n>40&&B(.75)||n>20&&a.walls&&B(.4));const t=pack.cells.religion[a.cell],i=pack.states[a.state].form==="Theocracy";a.temple=Number(t&&i&&B(.5)||n>50||n>35&&B(.75)||n>20&&B(.5))}getDefaultGroups(){return[{name:"capital",active:!0,order:9,features:{capital:!0},preview:"watabou-city"},{name:"city",active:!0,order:8,percentile:90,min:5,preview:"watabou-city"},{name:"fort",active:!0,features:{citadel:!0,walls:!1,plaza:!1,port:!1},order:6,max:1},{name:"monastery",active:!0,features:{temple:!0,walls:!1,plaza:!1,port:!1},order:5,max:.8},{name:"caravanserai",active:!0,features:{port:!1,plaza:!0},order:4,max:.8,biomes:[1,2,3]},{name:"trading_post",active:!0,order:3,features:{plaza:!0},max:.8,biomes:[5,6,7,8,9,10,11,12]},{name:"village",active:!0,order:2,min:.1,max:2,preview:"watabou-village"},{name:"hamlet",active:!0,order:1,features:{plaza:!1},max:.1,preview:"watabou-village"},{name:"town",active:!0,order:7,isDefault:!0,preview:"watabou-city"}]}defineGroup(a,n){if(a.lock&&a.group&&options.burgs.groups.find(o=>o.name===a.group))return;const t=options.burgs.groups.find(i=>i.isDefault);if(!t){ERROR&&console.error("No default group defined");return}a.group=t.name;for(const i of options.burgs.groups)if(i.active&&!(i.min&&!(a.population>=i.min))&&!(i.max&&!(a.population<=i.max))&&!(i.features&&!Object.entries(i.features).every(([s,h])=>!!a[s]===h))&&!(i.biomes&&!i.biomes.includes(pack.cells.biome[a.cell]))&&!(i.percentile&&!(n.indexOf(a.population)>=Math.floor(n.length*i.percentile/100)))){a.group=i.name;return}}specify(){TIME&&console.time("specifyBurgs"),pack.burgs.forEach(n=>{!n.i||n.removed||n.lock||(this.definePopulation(n),this.defineEmblem(n),this.defineFeatures(n))});const a=pack.burgs.filter(n=>n.i&&!n.removed).map(n=>n.population).sort((n,t)=>n-t);pack.burgs.forEach(n=>{!n.i||n.removed||this.defineGroup(n,a)}),TIME&&console.timeEnd("specifyBurgs")}createWatabouCityLinks(a){const n=pack.cells,{i:t,name:i,population:o,cell:s}=a,h=a.MFCG||seed+String(a.i).padStart(4,"0"),u=2.13*(o*populationRate/urbanDensity)**.385,l=ma(Math.ceil(u),6,100),c=N(o*populationRate*urbanization),d=n.r[s]?1:0,r=+(parseInt(a.port,10)>0),g=(()=>{if(!r||!n.haven[s])return null;const[z,A]=n.p[s],[x,C]=n.p[n.haven[s]],E=Math.atan2(C-A,x-z)*180/Math.PI;return E<=0?N(ee(Math.abs(E),0,180),2):N(2-ee(E,0,180),2)})(),f=+(d?[1,2,3,4,5,6,7,8]:[5,6,7,8]).includes(n.biome[s]),p=+a.citadel,y=+(p&&ba(2)(t)),k=Routes.isCrossroad(s),b=+a.walls,v=+a.plaza,w=+a.temple,_=+a.shanty,M="natural",T=new URL("https://watabou.github.io/city-generator/");T.search=new URLSearchParams({name:i||"",population:c.toString(),size:l.toString(),seed:h,river:d.toString(),coast:r.toString(),farms:f.toString(),citadel:p.toString(),urban_castle:y.toString(),hub:k.toString(),plaza:v.toString(),temple:w.toString(),walls:b.toString(),shantytown:_.toString(),gates:"-1",style:M}).toString(),g&&T.searchParams.append("sea",g.toString());const S=T.toString();return{link:S,preview:`${S}&preview=1`}}createWatabouVillageLinks(a){const{cells:n,features:t}=pack,{i,population:o,cell:s}=a,h=seed+String(i).padStart(4,"0"),u=N(o*populationRate*urbanization),l=[];n.r[s]&&n.haven[s]?l.push("estuary"):n.haven[s]&&t[n.f[s]].cells===1?l.push("island,district"):a.port?l.push("coast"):n.conf[s]?l.push("confluence"):n.r[s]?l.push("river"):u<200&&ba(4)(s)&&l.push("pond");const c=Routes.getConnectivityRate(s);l.push(c>1?"highway":c===1?"dead end":"isolated");const d=n.biome[s];(n.r[s]?[1,2,3,4,5,6,7,8]:[5,6,7,8]).includes(d)?ba(6)(s)&&l.push("farmland"):l.push("uncultivated");const g=grid.cells.temp[n.g[s]];(g<=0||g>28||g>25&&ba(3)(s))&&l.push("no orchards"),a.plaza||l.push("no square"),a.walls&&l.push("palisade"),u<100?l.push("sparse"):u>300&&l.push("dense");const m=u>1500?1600:u>1e3?1400:u>500?1e3:u>200?800:u>100?600:400,f=N(m/2.05),p=[1,2].includes(d)?"sand":g<=5||[9,10,11].includes(d)?"snow":"default",y=new URL("https://watabou.github.io/village-generator/");y.search=new URLSearchParams({pop:u.toString(),name:a.name||"",seed:h,width:m.toString(),height:f.toString(),style:p,tags:l.join(",")}).toString();const k=y.toString();return{link:k,preview:`${k}&preview=1`}}createWatabouDwellingLinks(a){const n=seed+String(a.i).padStart(4,"0"),t=N(a.population*populationRate*urbanization),i=t>200?["large","tall"]:t>100?["large"]:t>50?["tall"]:t>20?["low"]:["small"],o=new URL("https://watabou.github.io/dwellings/");o.search=new URLSearchParams({pop:t.toString(),name:"",seed:n,tags:i.join(",")}).toString();const s=o.toString();return{link:s,preview:`${s}&preview=1`}}getPreview(a){const n={"watabou-city":i=>this.createWatabouCityLinks(i),"watabou-village":i=>this.createWatabouVillageLinks(i),"watabou-dwelling":i=>this.createWatabouDwellingLinks(i)};if(a.link)return{link:a.link,preview:a.link};const t=options.burgs.groups.find(i=>i.name===a.group);return!t?.preview||!n[t.preview]?{link:null,preview:null}:n[t.preview](a)}add([a,n]){const{cells:t}=pack,i=pack.burgs.length,o=window.findCell(a,n,void 0,pack),s=t.culture[o],h=Names.getCulture(s),u=t.state[o],l=t.f[o],c={cell:o,x:a,y:n,i,state:u,culture:s,name:h,feature:l,capital:0,port:"0"};this.definePopulation(c),this.defineEmblem(c),this.defineFeatures(c);const d=pack.burgs.filter(g=>g.i&&!g.removed).map(g=>g.population).sort((g,m)=>g-m);this.defineGroup(c,d),pack.burgs.push(c),t.burg[o]=i;const r=Routes.connect(o);return r&&layerIsOn("toggleRoutes")&&drawRoute(r),drawBurgIcon(c),drawBurgLabel(c),i}changeGroup(a,n){if(n)a.group=n;else{const i=pack.burgs.filter(o=>o.i&&!o.removed).map(o=>o.population).sort((o,s)=>o-s);this.defineGroup(a,i)}drawBurgIcon(a),drawBurgLabel(a)}remove(a){const n=pack.burgs[a];if(!n)return tip(`Burg ${a} not found`,!1,"error");pack.cells.burg[n.cell]=0,n.removed=!0;const t=notes.findIndex(i=>i.id===`burg${a}`);t!==-1&¬es.splice(t,1),n.coa&&(j(`burgCOA${a}`)?.remove(),emblems.select(`#burgEmblems > use[data-i='${a}']`).remove(),delete n.coa),removeBurgIcon(n.i),removeBurgLabel(n.i)}}window.Burgs=new qu;class ju{MIN_LAND_HEIGHT=20;getDefault(){const a=["Marine","Hot desert","Cold desert","Savanna","Grassland","Tropical seasonal forest","Temperate deciduous forest","Tropical rainforest","Temperate rainforest","Taiga","Tundra","Glacier","Wetland"],n=["#466eab","#fbe79f","#b5b887","#d2d082","#c8d68f","#b6d95d","#29bc56","#7dcb35","#409c43","#4b6b32","#96784b","#d5e7eb","#0b9131"],t=[0,4,10,22,30,50,100,80,90,12,4,0,12],i=[0,3,2,120,120,120,120,150,150,100,5,0,250],o=[{},{dune:3,cactus:6,deadTree:1},{dune:9,deadTree:1},{acacia:1,grass:9},{grass:1},{acacia:8,palm:1},{deciduous:1},{acacia:5,palm:3,deciduous:1,swamp:1},{deciduous:6,swamp:1},{conifer:1},{grass:1},{},{swamp:1}],s=[10,200,150,60,50,70,70,80,90,200,1e3,5e3,150],h=[new Uint8Array([1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,10]),new Uint8Array([3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,9,9,9,9,10,10,10]),new Uint8Array([5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,9,9,9,9,9,10,10,10]),new Uint8Array([5,6,6,6,6,6,6,8,8,8,8,8,8,8,8,8,8,9,9,9,9,9,9,10,10,10]),new Uint8Array([7,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,9,9,9,9,9,9,9,10,10])],u=[];for(let l=0;l{let c=h[o[l]];n[l]&&(c+=Math.max(a[l]/10,2));const d=i[l].filter(r=>t[r]>=this.MIN_LAND_HEIGHT).map(r=>h[o[r]]).concat([c]);return N(4+Ha(d))};for(let l=0;l=25&&!i&&a<8)return 1;if(this.isWetland(a,n,t))return 12;const o=Math.min(a/5|0,4),s=Math.min(Math.max(20-n,0),25);return biomesData.biomesMatrix[o][s]}isWetland(a,n,t){return n<=-2?!1:a>40&&t<25||a>24&&t>24&&t<60}}window.Biomes=new ju;class Uu{cells;getRandomShield(){const a=de(COA.shields.types);return de(COA.shields[a])}getDefault(a=0){const n=pack.cells,t=n.s,i=Vn(t),o=n.t,s=n.h,h=grid.cells.temp,u=r=>Math.ceil(t[r]/i*3),l=(r,g)=>{const m=Math.abs(h[n.g[r]]-g);return m?m+1:1},c=(r,g,m=4)=>g.includes(n.biome[r])?1:m,d=(r,g=4)=>n.haven[r]&&pack.features[n.f[n.haven[r]]].type!=="lake"?1:g;if(culturesSet.value==="european")return[{name:"Shwazen",base:0,odd:1,sort:r=>u(r)/l(r,10)/c(r,[6,8]),shield:"swiss"},{name:"Angshire",base:1,odd:1,sort:r=>u(r)/l(r,10)/d(r),shield:"wedged"},{name:"Luari",base:2,odd:1,sort:r=>u(r)/l(r,12)/c(r,[6,8]),shield:"french"},{name:"Tallian",base:3,odd:1,sort:r=>u(r)/l(r,15),shield:"horsehead"},{name:"Astellian",base:4,odd:1,sort:r=>u(r)/l(r,16),shield:"spanish"},{name:"Slovan",base:5,odd:1,sort:r=>u(r)/l(r,6)*o[r],shield:"polish"},{name:"Norse",base:6,odd:1,sort:r=>u(r)/l(r,5),shield:"heater"},{name:"Elladan",base:7,odd:1,sort:r=>u(r)/l(r,18)*s[r],shield:"boeotian"},{name:"Romian",base:8,odd:.2,sort:r=>u(r)/l(r,15)/o[r],shield:"roman"},{name:"Soumi",base:9,odd:1,sort:r=>u(r)/l(r,5)/c(r,[9])*o[r],shield:"pavise"},{name:"Portuzian",base:13,odd:1,sort:r=>u(r)/l(r,17)/d(r),shield:"renaissance"},{name:"Vengrian",base:15,odd:1,sort:r=>u(r)/l(r,11)/c(r,[4])*o[r],shield:"horsehead2"},{name:"Turchian",base:16,odd:.05,sort:r=>u(r)/l(r,14),shield:"round"},{name:"Euskati",base:20,odd:.05,sort:r=>u(r)/l(r,15)*s[r],shield:"oldFrench"},{name:"Keltan",base:22,odd:.05,sort:r=>u(r)/l(r,11)/c(r,[6,8])*o[r],shield:"oval"}];if(culturesSet.value==="oriental")return[{name:"Koryo",base:10,odd:1,sort:r=>u(r)/l(r,12)/o[r],shield:"round"},{name:"Hantzu",base:11,odd:1,sort:r=>u(r)/l(r,13),shield:"banner"},{name:"Yamoto",base:12,odd:1,sort:r=>u(r)/l(r,15)/o[r],shield:"round"},{name:"Turchian",base:16,odd:1,sort:r=>u(r)/l(r,12),shield:"round"},{name:"Berberan",base:17,odd:.2,sort:r=>u(r)/l(r,19)/c(r,[1,2,3],7)*o[r],shield:"oval"},{name:"Eurabic",base:18,odd:1,sort:r=>u(r)/l(r,26)/c(r,[1,2],7)*o[r],shield:"oval"},{name:"Efratic",base:23,odd:.1,sort:r=>u(r)/l(r,22)*o[r],shield:"round"},{name:"Tehrani",base:24,odd:1,sort:r=>u(r)/l(r,18)*s[r],shield:"round"},{name:"Maui",base:25,odd:.2,sort:r=>u(r)/l(r,24)/d(r)/o[r],shield:"vesicaPiscis"},{name:"Carnatic",base:26,odd:.5,sort:r=>u(r)/l(r,26),shield:"round"},{name:"Vietic",base:29,odd:.8,sort:r=>u(r)/l(r,25)/c(r,[7],7)/o[r],shield:"banner"},{name:"Guantzu",base:30,odd:.5,sort:r=>u(r)/l(r,17),shield:"banner"},{name:"Ulus",base:31,odd:1,sort:r=>u(r)/l(r,5)/c(r,[2,4,10],7)*o[r],shield:"banner"}];if(culturesSet.value==="english"){const r=()=>Names.getBase(1,5,9,"");return[{name:r(),base:1,odd:1,shield:"heater"},{name:r(),base:1,odd:1,shield:"wedged"},{name:r(),base:1,odd:1,shield:"swiss"},{name:r(),base:1,odd:1,shield:"oldFrench"},{name:r(),base:1,odd:1,shield:"swiss"},{name:r(),base:1,odd:1,shield:"spanish"},{name:r(),base:1,odd:1,shield:"hessen"},{name:r(),base:1,odd:1,shield:"fantasy5"},{name:r(),base:1,odd:1,shield:"fantasy4"},{name:r(),base:1,odd:1,shield:"fantasy1"}]}return culturesSet.value==="antique"?[{name:"Roman",base:8,odd:1,sort:r=>u(r)/l(r,14)/o[r],shield:"roman"},{name:"Roman",base:8,odd:1,sort:r=>u(r)/l(r,15)/d(r),shield:"roman"},{name:"Roman",base:8,odd:1,sort:r=>u(r)/l(r,16)/d(r),shield:"roman"},{name:"Roman",base:8,odd:1,sort:r=>u(r)/l(r,17)/o[r],shield:"roman"},{name:"Hellenic",base:7,odd:1,sort:r=>u(r)/l(r,18)/d(r)*s[r],shield:"boeotian"},{name:"Hellenic",base:7,odd:1,sort:r=>u(r)/l(r,19)/d(r)*s[r],shield:"boeotian"},{name:"Macedonian",base:7,odd:.5,sort:r=>u(r)/l(r,12)*s[r],shield:"round"},{name:"Celtic",base:22,odd:1,sort:r=>u(r)/l(r,11)**.5/c(r,[6,8]),shield:"round"},{name:"Germanic",base:0,odd:1,sort:r=>u(r)/l(r,10)**.5/c(r,[6,8]),shield:"round"},{name:"Persian",base:24,odd:.8,sort:r=>u(r)/l(r,18)*s[r],shield:"oval"},{name:"Scythian",base:24,odd:.5,sort:r=>u(r)/l(r,11)**.5/c(r,[4]),shield:"round"},{name:"Cantabrian",base:20,odd:.5,sort:r=>u(r)/l(r,16)*s[r],shield:"oval"},{name:"Estian",base:9,odd:.2,sort:r=>u(r)/l(r,5)*o[r],shield:"pavise"},{name:"Carthaginian",base:42,odd:.3,sort:r=>u(r)/l(r,20)/d(r),shield:"oval"},{name:"Hebrew",base:42,odd:.2,sort:r=>u(r)/l(r,19)*d(r),shield:"oval"},{name:"Mesopotamian",base:23,odd:.2,sort:r=>u(r)/l(r,22)/c(r,[1,2,3]),shield:"oval"}]:culturesSet.value==="highFantasy"?[{name:"Quenian (Elfish)",base:33,odd:1,sort:r=>u(r)/c(r,[6,7,8,9],10)*o[r],shield:"gondor"},{name:"Eldar (Elfish)",base:33,odd:1,sort:r=>u(r)/c(r,[6,7,8,9],10)*o[r],shield:"noldor"},{name:"Trow (Dark Elfish)",base:34,odd:.9,sort:r=>u(r)/c(r,[7,8,9,12],10)*o[r],shield:"hessen"},{name:"Lothian (Dark Elfish)",base:34,odd:.3,sort:r=>u(r)/c(r,[7,8,9,12],10)*o[r],shield:"wedged"},{name:"Dunirr (Dwarven)",base:35,odd:1,sort:r=>u(r)+s[r],shield:"ironHills"},{name:"Khazadur (Dwarven)",base:35,odd:1,sort:r=>u(r)+s[r],shield:"erebor"},{name:"Kobold (Goblin)",base:36,odd:1,sort:r=>o[r]-t[r],shield:"moriaOrc"},{name:"Uruk (Orkish)",base:37,odd:1,sort:r=>s[r]*o[r],shield:"urukHai"},{name:"Ugluk (Orkish)",base:37,odd:.5,sort:r=>s[r]*o[r]/c(r,[1,2,10,11]),shield:"moriaOrc"},{name:"Yotunn (Giants)",base:38,odd:.7,sort:r=>l(r,-10),shield:"pavise"},{name:"Rake (Drakonic)",base:39,odd:.7,sort:r=>-t[r],shield:"fantasy2"},{name:"Arago (Arachnid)",base:40,odd:.7,sort:r=>o[r]-t[r],shield:"horsehead2"},{name:"Aj'Snaga (Serpents)",base:41,odd:.7,sort:r=>u(r)/c(r,[12],10),shield:"fantasy1"},{name:"Anor (Human)",base:32,odd:1,sort:r=>u(r)/l(r,10),shield:"fantasy5"},{name:"Dail (Human)",base:32,odd:1,sort:r=>u(r)/l(r,13),shield:"roman"},{name:"Rohand (Human)",base:16,odd:1,sort:r=>u(r)/l(r,16),shield:"round"},{name:"Dulandir (Human)",base:31,odd:1,sort:r=>u(r)/l(r,5)/c(r,[2,4,10],7)*o[r],shield:"easterling"}]:culturesSet.value==="darkFantasy"?[{name:"Angshire",base:1,odd:1,sort:r=>u(r)/l(r,10)/d(r),shield:"heater"},{name:"Enlandic",base:1,odd:1,sort:r=>u(r)/l(r,12),shield:"heater"},{name:"Westen",base:1,odd:1,sort:r=>u(r)/l(r,10),shield:"heater"},{name:"Nortumbic",base:1,odd:1,sort:r=>u(r)/l(r,7),shield:"heater"},{name:"Mercian",base:1,odd:1,sort:r=>u(r)/l(r,9),shield:"heater"},{name:"Kentian",base:1,odd:1,sort:r=>u(r)/l(r,12),shield:"heater"},{name:"Norse",base:6,odd:.7,sort:r=>u(r)/l(r,5)/d(r),shield:"oldFrench"},{name:"Schwarzen",base:0,odd:.3,sort:r=>u(r)/l(r,10)/c(r,[6,8]),shield:"gonfalon"},{name:"Luarian",base:2,odd:.3,sort:r=>u(r)/l(r,12)/c(r,[6,8]),shield:"oldFrench"},{name:"Hetallian",base:3,odd:.3,sort:r=>u(r)/l(r,15),shield:"oval"},{name:"Astellian",base:4,odd:.3,sort:r=>u(r)/l(r,16),shield:"spanish"},{name:"Kiswaili",base:28,odd:.05,sort:r=>u(r)/l(r,29)/c(r,[1,3,5,7]),shield:"vesicaPiscis"},{name:"Yoruba",base:21,odd:.05,sort:r=>u(r)/l(r,15)/c(r,[5,7]),shield:"vesicaPiscis"},{name:"Koryo",base:10,odd:.05,sort:r=>u(r)/l(r,12)/o[r],shield:"round"},{name:"Hantzu",base:11,odd:.05,sort:r=>u(r)/l(r,13),shield:"banner"},{name:"Yamoto",base:12,odd:.05,sort:r=>u(r)/l(r,15)/o[r],shield:"round"},{name:"Guantzu",base:30,odd:.05,sort:r=>u(r)/l(r,17),shield:"banner"},{name:"Ulus",base:31,odd:.05,sort:r=>u(r)/l(r,5)/c(r,[2,4,10],7)*o[r],shield:"banner"},{name:"Turan",base:16,odd:.05,sort:r=>u(r)/l(r,12),shield:"round"},{name:"Berberan",base:17,odd:.05,sort:r=>u(r)/l(r,19)/c(r,[1,2,3],7)*o[r],shield:"round"},{name:"Eurabic",base:18,odd:.05,sort:r=>u(r)/l(r,26)/c(r,[1,2],7)*o[r],shield:"round"},{name:"Slovan",base:5,odd:.05,sort:r=>u(r)/l(r,6)*o[r],shield:"round"},{name:"Keltan",base:22,odd:.1,sort:r=>u(r)/l(r,11)**.5/c(r,[6,8]),shield:"vesicaPiscis"},{name:"Elladan",base:7,odd:.2,sort:r=>u(r)/l(r,18)/d(r)*s[r],shield:"boeotian"},{name:"Romian",base:8,odd:.2,sort:r=>u(r)/l(r,14)/o[r],shield:"roman"},{name:"Eldar",base:33,odd:.5,sort:r=>u(r)/c(r,[6,7,8,9],10)*o[r],shield:"fantasy5"},{name:"Trow",base:34,odd:.8,sort:r=>u(r)/c(r,[7,8,9,12],10)*o[r],shield:"hessen"},{name:"Durinn",base:35,odd:.8,sort:r=>u(r)+s[r],shield:"erebor"},{name:"Kobblin",base:36,odd:.8,sort:r=>o[r]-t[r],shield:"moriaOrc"},{name:"Uruk",base:37,odd:.8,sort:r=>s[r]*o[r]/c(r,[1,2,10,11]),shield:"urukHai"},{name:"Yotunn",base:38,odd:.8,sort:r=>l(r,-10),shield:"pavise"},{name:"Drake",base:39,odd:.9,sort:r=>-t[r],shield:"fantasy2"},{name:"Rakhnid",base:40,odd:.9,sort:r=>o[r]-t[r],shield:"horsehead2"},{name:"Aj'Snaga",base:41,odd:.9,sort:r=>u(r)/c(r,[12],10),shield:"fantasy1"}]:culturesSet.value==="random"?Ra(a).map(()=>{const r=Y(nameBases.length-1);return{name:Names.getBaseShort(r),base:r,odd:1,shield:this.getRandomShield()}}):[{name:"Shwazen",base:0,odd:.7,sort:r=>u(r)/l(r,10)/c(r,[6,8]),shield:"hessen"},{name:"Angshire",base:1,odd:1,sort:r=>u(r)/l(r,10)/d(r),shield:"heater"},{name:"Luari",base:2,odd:.6,sort:r=>u(r)/l(r,12)/c(r,[6,8]),shield:"oldFrench"},{name:"Tallian",base:3,odd:.6,sort:r=>u(r)/l(r,15),shield:"horsehead2"},{name:"Astellian",base:4,odd:.6,sort:r=>u(r)/l(r,16),shield:"spanish"},{name:"Slovan",base:5,odd:.7,sort:r=>u(r)/l(r,6)*o[r],shield:"round"},{name:"Norse",base:6,odd:.7,sort:r=>u(r)/l(r,5),shield:"heater"},{name:"Elladan",base:7,odd:.7,sort:r=>u(r)/l(r,18)*s[r],shield:"boeotian"},{name:"Romian",base:8,odd:.7,sort:r=>u(r)/l(r,15),shield:"roman"},{name:"Soumi",base:9,odd:.3,sort:r=>u(r)/l(r,5)/c(r,[9])*o[r],shield:"pavise"},{name:"Koryo",base:10,odd:.1,sort:r=>u(r)/l(r,12)/o[r],shield:"round"},{name:"Hantzu",base:11,odd:.1,sort:r=>u(r)/l(r,13),shield:"banner"},{name:"Yamoto",base:12,odd:.1,sort:r=>u(r)/l(r,15)/o[r],shield:"round"},{name:"Portuzian",base:13,odd:.4,sort:r=>u(r)/l(r,17)/d(r),shield:"spanish"},{name:"Nawatli",base:14,odd:.1,sort:r=>s[r]/l(r,18)/c(r,[7]),shield:"square"},{name:"Vengrian",base:15,odd:.2,sort:r=>u(r)/l(r,11)/c(r,[4])*o[r],shield:"wedged"},{name:"Turchian",base:16,odd:.2,sort:r=>u(r)/l(r,13),shield:"round"},{name:"Berberan",base:17,odd:.1,sort:r=>u(r)/l(r,19)/c(r,[1,2,3],7)*o[r],shield:"round"},{name:"Eurabic",base:18,odd:.2,sort:r=>u(r)/l(r,26)/c(r,[1,2],7)*o[r],shield:"round"},{name:"Inuk",base:19,odd:.05,sort:r=>l(r,-1)/c(r,[10,11])/d(r),shield:"square"},{name:"Euskati",base:20,odd:.05,sort:r=>u(r)/l(r,15)*s[r],shield:"spanish"},{name:"Yoruba",base:21,odd:.05,sort:r=>u(r)/l(r,15)/c(r,[5,7]),shield:"vesicaPiscis"},{name:"Keltan",base:22,odd:.05,sort:r=>u(r)/l(r,11)/c(r,[6,8])*o[r],shield:"vesicaPiscis"},{name:"Efratic",base:23,odd:.05,sort:r=>u(r)/l(r,22)*o[r],shield:"diamond"},{name:"Tehrani",base:24,odd:.1,sort:r=>u(r)/l(r,18)*s[r],shield:"round"},{name:"Maui",base:25,odd:.05,sort:r=>u(r)/l(r,24)/d(r)/o[r],shield:"round"},{name:"Carnatic",base:26,odd:.05,sort:r=>u(r)/l(r,26),shield:"round"},{name:"Inqan",base:27,odd:.05,sort:r=>s[r]/l(r,13),shield:"square"},{name:"Kiswaili",base:28,odd:.1,sort:r=>u(r)/l(r,29)/c(r,[1,3,5,7]),shield:"vesicaPiscis"},{name:"Vietic",base:29,odd:.1,sort:r=>u(r)/l(r,25)/c(r,[7],7)/o[r],shield:"banner"},{name:"Guantzu",base:30,odd:.1,sort:r=>u(r)/l(r,17),shield:"banner"},{name:"Ulus",base:31,odd:.1,sort:r=>u(r)/l(r,5)/c(r,[2,4,10],7)*o[r],shield:"banner"},{name:"Hebrew",base:42,odd:.2,sort:r=>u(r)/l(r,18)*d(r),shield:"oval"}]}generate(){TIME&&console.time("generateCultures"),this.cells=pack.cells;const a=new Uint16Array(this.cells.i.length),n=+j("culturesInput").value,t=+(j("culturesSet").selectedOptions[0].dataset.max??"0");let i=Math.min(n,t);const o=this.cells.i.filter(f=>this.cells.s[f]);if(o.length + Only ${i} out of ${culturesInput.value} requested cultures will be generated.
+ Please consider changing climate settings in the World Configurator`,$("#alert").dialog({resizable:!1,title:"Extreme climate warning",buttons:{Ok:function(){$(this).dialog("close")}}});else{WARN&&console.warn("There are no populated cells. Cannot generate cultures"),pack.cultures=[{name:"Wildlands",i:0,base:1,shield:"round"}],this.cells.culture=a,alertMessage.innerHTML=`The climate is harsh and people cannot live in this world.
+ No cultures, states and burgs will be created.
+ Please consider changing climate settings in the World Configurator`,$("#alert").dialog({resizable:!1,title:"Extreme climate warning",buttons:{Ok:function(){$(this).dialog("close")}}});return}const h=(f=>{const p=this.getDefault(f),y=[];if(pack.cultures?.forEach(k=>{k.lock&&!k.removed&&y.push(k)}),!y.length){if(f===p.length)return p;if(p.every(k=>k.odd===1))return p.splice(0,f)}for(let k,b,v=0;y.length0;){do b=Y(p.length-1),k=p[b],v++;while(v<200&&!B(k.odd));y.push(k),p.splice(b,1)}return y})(i);pack.cultures=h;const u=ue(),l=Bt(i),c=j("emblemShape").value,d=[],r=f=>{let p=(graphWidth+graphHeight)/2/i;const y=100,k=[...o].sort((w,_)=>f(_)-f(w)),b=Math.floor(k.length/2);let v=0;for(let w=0;w{if(this.cells.h[f]<70&&[1,2,4].includes(this.cells.biome[f]))return"Nomadic";if(this.cells.h[f]>50)return"Highland";const p=pack.features[this.cells.f[this.cells.haven[f]]];return p.type==="lake"&&p.cells>5?"Lake":this.cells.harbor[f]&&p.type!=="lake"&&B(.1)||this.cells.harbor[f]===1&&B(.6)||pack.features[this.cells.f[f]].group==="isle"&&B(.4)?"Naval":this.cells.r[f]&&this.cells.fl[f]>100?"River":this.cells.t[f]>2&&[3,7,8,9,10,12].includes(this.cells.biome[f])?"Hunting":"Generic"},m=f=>{let p=1;return f==="Lake"?p=.8:f==="Naval"?p=1.5:f==="River"?p=.9:f==="Nomadic"?p=1.5:f==="Hunting"?p=.7:f==="Highland"&&(p=1.2),N((Math.random()*j("sizeVariety").valueAsNumber/2+1)*p,1)};h.forEach((f,p)=>{const y=p+1;if(f.lock){d.push(f.code),u.add(f.center);for(const v of this.cells.i)this.cells.culture[v]===f.i&&(a[v]=y);f.i=y;return}const k=f.sort?f.sort:v=>this.cells.s[v],b=r(k);u.add(this.cells.p[b]),f.center=b,f.i=y,delete f.odd,delete f.sort,f.color=l[p],f.type=g(b),f.expansionism=m(f.type),f.origins=[0],f.code=Ue(f.name,d),d.push(f.code),a[b]=y,c==="random"&&(f.shield=this.getRandomShield())}),this.cells.culture=a,h.unshift({name:"Wildlands",i:0,base:1,origins:[null],shield:"round"}),nameBases.length||(ERROR&&console.error("Name base is empty, default nameBases will be applied"),nameBases=Names.getNameBases()),h.forEach(f=>{f.base=f.base%nameBases.length}),TIME&&console.timeEnd("generateCultures")}add(a){const n=this.getDefault();let t,i,o;pack.cultures.lengthc.code)),h=pack.cultures.length,u=ge(),l=document.getElementById("emblemShape").value;pack.cultures.push({name:o,color:u,base:i,center:a,i:h,expansionism:1,type:"Generic",cells:0,area:0,rural:0,urban:0,origins:[pack.cells.culture[a]],code:s,shield:l==="random"?this.getRandomShield():""})}expand(){TIME&&console.time("expandCultures");const{cells:a,cultures:n}=pack,t=new FlatQueue,i=[],o=j("neutralRate")?.valueAsNumber||1,s=a.i.length*.6*o,h=n.some(r=>!r.removed&&r.lock);if(h)for(const r of a.i)n[a.culture[r]].lock||(a.culture[r]=0);else a.culture=new Uint16Array(a.i.length);for(const r of n)!r.i||r.removed||r.lock||t.push({cellId:r.center,cultureId:r.i,priority:0},0);const u=(r,g,m)=>a.biome[n[r].center]===g?10:m==="Hunting"?biomesData.cost[g]*5:m==="Nomadic"&&g>4&&g<10?biomesData.cost[g]*10:biomesData.cost[g]*2,l=(r,g,m)=>{const f=pack.features[a.f[r]],p=a.area[r];return m==="Lake"&&f.type==="lake"?10:m==="Naval"&&g<20?p*2:m==="Nomadic"&&g<20?p*50:g<20?p*6:m==="Highland"&&g<44?3e3:m==="Highland"&&g<62?200:m==="Highland"?0:g>=67?200:g>=44?30:0},c=(r,g,m)=>m==="River"?r?0:100:r?ma(a.fl[g]/10,20,100):0,d=(r,g)=>r===1?g==="Naval"||g==="Lake"?0:g==="Nomadic"?60:20:r===2?g==="Naval"||g==="Nomadic"?30:0:r!==-1&&(g==="Naval"||g==="Lake")?100:0;for(;t.length;){const{cellId:r,priority:g,cultureId:m}=t.pop(),{type:f,expansionism:p}=n[m];a.c[r].forEach(y=>{if(h){const z=a.culture[y];if(z&&n[z].lock)return}const k=a.biome[y],b=u(m,k,f),v=k===a.biome[y]?0:20,w=l(y,a.h[y],f),_=c(a.r[y],y,f),M=d(a.t[y],f),T=(b+v+w+_+M)/p,S=g+T;S>s||(!i[y]||S0&&(a.culture[y]=m),i[y]=S,t.push({cellId:y,cultureId:m,priority:S},S))})}TIME&&console.timeEnd("expandCultures")}}window.Cultures=new Uu; diff --git a/mobile_app/assets/www/assets/modulepreload-polyfill-B5Qt9EMX.js b/mobile_app/assets/www/assets/modulepreload-polyfill-B5Qt9EMX.js new file mode 100644 index 00000000..3e0a78a5 --- /dev/null +++ b/mobile_app/assets/www/assets/modulepreload-polyfill-B5Qt9EMX.js @@ -0,0 +1 @@ +(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const e of document.querySelectorAll('link[rel="modulepreload"]'))i(e);new MutationObserver(e=>{for(const r of e)if(r.type==="childList")for(const o of r.addedNodes)o.tagName==="LINK"&&o.rel==="modulepreload"&&i(o)}).observe(document,{childList:!0,subtree:!0});function s(e){const r={};return e.integrity&&(r.integrity=e.integrity),e.referrerPolicy&&(r.referrerPolicy=e.referrerPolicy),e.crossOrigin==="use-credentials"?r.credentials="include":e.crossOrigin==="anonymous"?r.credentials="omit":r.credentials="same-origin",r}function i(e){if(e.ep)return;e.ep=!0;const r=s(e);fetch(e.href,r)}})(); diff --git a/mobile_app/assets/www/charges/agnusDei.svg b/mobile_app/assets/www/charges/agnusDei.svg new file mode 100644 index 00000000..60ea9d87 --- /dev/null +++ b/mobile_app/assets/www/charges/agnusDei.svg @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/anchor.svg b/mobile_app/assets/www/charges/anchor.svg new file mode 100644 index 00000000..59678314 --- /dev/null +++ b/mobile_app/assets/www/charges/anchor.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/mobile_app/assets/www/charges/angel.svg b/mobile_app/assets/www/charges/angel.svg new file mode 100644 index 00000000..e6f3ba3e --- /dev/null +++ b/mobile_app/assets/www/charges/angel.svg @@ -0,0 +1,227 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/annulet.svg b/mobile_app/assets/www/charges/annulet.svg new file mode 100644 index 00000000..b3dad13d --- /dev/null +++ b/mobile_app/assets/www/charges/annulet.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/mobile_app/assets/www/charges/anvil.svg b/mobile_app/assets/www/charges/anvil.svg new file mode 100644 index 00000000..2b6b0868 --- /dev/null +++ b/mobile_app/assets/www/charges/anvil.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/mobile_app/assets/www/charges/apple.svg b/mobile_app/assets/www/charges/apple.svg new file mode 100644 index 00000000..6679428d --- /dev/null +++ b/mobile_app/assets/www/charges/apple.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/mobile_app/assets/www/charges/arbalest.svg b/mobile_app/assets/www/charges/arbalest.svg new file mode 100644 index 00000000..38adac50 --- /dev/null +++ b/mobile_app/assets/www/charges/arbalest.svg @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/arbalest2.svg b/mobile_app/assets/www/charges/arbalest2.svg new file mode 100644 index 00000000..be9b1a6a --- /dev/null +++ b/mobile_app/assets/www/charges/arbalest2.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/archer.svg b/mobile_app/assets/www/charges/archer.svg new file mode 100644 index 00000000..00891c1b --- /dev/null +++ b/mobile_app/assets/www/charges/archer.svg @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/armEmbowedHoldingSabre.svg b/mobile_app/assets/www/charges/armEmbowedHoldingSabre.svg new file mode 100644 index 00000000..2fbae9f6 --- /dev/null +++ b/mobile_app/assets/www/charges/armEmbowedHoldingSabre.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/armEmbowedVambraced.svg b/mobile_app/assets/www/charges/armEmbowedVambraced.svg new file mode 100644 index 00000000..ac1422b5 --- /dev/null +++ b/mobile_app/assets/www/charges/armEmbowedVambraced.svg @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/armEmbowedVambracedHoldingSword.svg b/mobile_app/assets/www/charges/armEmbowedVambracedHoldingSword.svg new file mode 100644 index 00000000..d00d8bab --- /dev/null +++ b/mobile_app/assets/www/charges/armEmbowedVambracedHoldingSword.svg @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/armillarySphere.svg b/mobile_app/assets/www/charges/armillarySphere.svg new file mode 100644 index 00000000..45d09b8d --- /dev/null +++ b/mobile_app/assets/www/charges/armillarySphere.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/mobile_app/assets/www/charges/arrow.svg b/mobile_app/assets/www/charges/arrow.svg new file mode 100644 index 00000000..2135169f --- /dev/null +++ b/mobile_app/assets/www/charges/arrow.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/arrowsSheaf.svg b/mobile_app/assets/www/charges/arrowsSheaf.svg new file mode 100644 index 00000000..4b879e10 --- /dev/null +++ b/mobile_app/assets/www/charges/arrowsSheaf.svg @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/attire.svg b/mobile_app/assets/www/charges/attire.svg new file mode 100644 index 00000000..99427a60 --- /dev/null +++ b/mobile_app/assets/www/charges/attire.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/axe.svg b/mobile_app/assets/www/charges/axe.svg new file mode 100644 index 00000000..e1608145 --- /dev/null +++ b/mobile_app/assets/www/charges/axe.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/badgerStatant.svg b/mobile_app/assets/www/charges/badgerStatant.svg new file mode 100644 index 00000000..29cd5f39 --- /dev/null +++ b/mobile_app/assets/www/charges/badgerStatant.svg @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/banner.svg b/mobile_app/assets/www/charges/banner.svg new file mode 100644 index 00000000..8ca47b97 --- /dev/null +++ b/mobile_app/assets/www/charges/banner.svg @@ -0,0 +1,35 @@ + + + + diff --git a/mobile_app/assets/www/charges/basilisk.svg b/mobile_app/assets/www/charges/basilisk.svg new file mode 100644 index 00000000..b2755dff --- /dev/null +++ b/mobile_app/assets/www/charges/basilisk.svg @@ -0,0 +1,220 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/bearPassant.svg b/mobile_app/assets/www/charges/bearPassant.svg new file mode 100644 index 00000000..847ea7bd --- /dev/null +++ b/mobile_app/assets/www/charges/bearPassant.svg @@ -0,0 +1,142 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/bearRampant.svg b/mobile_app/assets/www/charges/bearRampant.svg new file mode 100644 index 00000000..418d6fb3 --- /dev/null +++ b/mobile_app/assets/www/charges/bearRampant.svg @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/bee.svg b/mobile_app/assets/www/charges/bee.svg new file mode 100644 index 00000000..7f3a0069 --- /dev/null +++ b/mobile_app/assets/www/charges/bee.svg @@ -0,0 +1,116 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/bell.svg b/mobile_app/assets/www/charges/bell.svg new file mode 100644 index 00000000..307b6493 --- /dev/null +++ b/mobile_app/assets/www/charges/bell.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/billet.svg b/mobile_app/assets/www/charges/billet.svg new file mode 100644 index 00000000..9482f5a7 --- /dev/null +++ b/mobile_app/assets/www/charges/billet.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/mobile_app/assets/www/charges/boarHeadErased.svg b/mobile_app/assets/www/charges/boarHeadErased.svg new file mode 100644 index 00000000..08348586 --- /dev/null +++ b/mobile_app/assets/www/charges/boarHeadErased.svg @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/boarRampant.svg b/mobile_app/assets/www/charges/boarRampant.svg new file mode 100644 index 00000000..436fb439 --- /dev/null +++ b/mobile_app/assets/www/charges/boarRampant.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/boat.svg b/mobile_app/assets/www/charges/boat.svg new file mode 100644 index 00000000..b50f6194 --- /dev/null +++ b/mobile_app/assets/www/charges/boat.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/boat2.svg b/mobile_app/assets/www/charges/boat2.svg new file mode 100644 index 00000000..f3e37a5b --- /dev/null +++ b/mobile_app/assets/www/charges/boat2.svg @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/bone.svg b/mobile_app/assets/www/charges/bone.svg new file mode 100644 index 00000000..27a9e410 --- /dev/null +++ b/mobile_app/assets/www/charges/bone.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/mobile_app/assets/www/charges/bookClosed.svg b/mobile_app/assets/www/charges/bookClosed.svg new file mode 100644 index 00000000..0cd74341 --- /dev/null +++ b/mobile_app/assets/www/charges/bookClosed.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/bookClosed2.svg b/mobile_app/assets/www/charges/bookClosed2.svg new file mode 100644 index 00000000..bf8d2519 --- /dev/null +++ b/mobile_app/assets/www/charges/bookClosed2.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/bookOpen.svg b/mobile_app/assets/www/charges/bookOpen.svg new file mode 100644 index 00000000..62f1c6fc --- /dev/null +++ b/mobile_app/assets/www/charges/bookOpen.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/bow.svg b/mobile_app/assets/www/charges/bow.svg new file mode 100644 index 00000000..b1f2c8ec --- /dev/null +++ b/mobile_app/assets/www/charges/bow.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/mobile_app/assets/www/charges/bowWithArrow.svg b/mobile_app/assets/www/charges/bowWithArrow.svg new file mode 100644 index 00000000..12d7f9ff --- /dev/null +++ b/mobile_app/assets/www/charges/bowWithArrow.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/bowWithThreeArrows.svg b/mobile_app/assets/www/charges/bowWithThreeArrows.svg new file mode 100644 index 00000000..0efc30f2 --- /dev/null +++ b/mobile_app/assets/www/charges/bowWithThreeArrows.svg @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/bridge.svg b/mobile_app/assets/www/charges/bridge.svg new file mode 100644 index 00000000..f5ce588e --- /dev/null +++ b/mobile_app/assets/www/charges/bridge.svg @@ -0,0 +1,92 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/bridge2.svg b/mobile_app/assets/www/charges/bridge2.svg new file mode 100644 index 00000000..6d3dfab5 --- /dev/null +++ b/mobile_app/assets/www/charges/bridge2.svg @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/bucket.svg b/mobile_app/assets/www/charges/bucket.svg new file mode 100644 index 00000000..56c7e83c --- /dev/null +++ b/mobile_app/assets/www/charges/bucket.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/mobile_app/assets/www/charges/buckle.svg b/mobile_app/assets/www/charges/buckle.svg new file mode 100644 index 00000000..b83ba97d --- /dev/null +++ b/mobile_app/assets/www/charges/buckle.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/mobile_app/assets/www/charges/bugleHorn.svg b/mobile_app/assets/www/charges/bugleHorn.svg new file mode 100644 index 00000000..a7985ca6 --- /dev/null +++ b/mobile_app/assets/www/charges/bugleHorn.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/bugleHorn2.svg b/mobile_app/assets/www/charges/bugleHorn2.svg new file mode 100644 index 00000000..cf5bcaa7 --- /dev/null +++ b/mobile_app/assets/www/charges/bugleHorn2.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/bullHeadCaboshed.svg b/mobile_app/assets/www/charges/bullHeadCaboshed.svg new file mode 100644 index 00000000..d3ddeccc --- /dev/null +++ b/mobile_app/assets/www/charges/bullHeadCaboshed.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/bullPassant.svg b/mobile_app/assets/www/charges/bullPassant.svg new file mode 100644 index 00000000..0314b64e --- /dev/null +++ b/mobile_app/assets/www/charges/bullPassant.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/butterfly.svg b/mobile_app/assets/www/charges/butterfly.svg new file mode 100644 index 00000000..2c301fcf --- /dev/null +++ b/mobile_app/assets/www/charges/butterfly.svg @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/camel.svg b/mobile_app/assets/www/charges/camel.svg new file mode 100644 index 00000000..e2dd8bb9 --- /dev/null +++ b/mobile_app/assets/www/charges/camel.svg @@ -0,0 +1,125 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/cancer.svg b/mobile_app/assets/www/charges/cancer.svg new file mode 100644 index 00000000..a8bf102c --- /dev/null +++ b/mobile_app/assets/www/charges/cancer.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/cannon.svg b/mobile_app/assets/www/charges/cannon.svg new file mode 100644 index 00000000..05e88b25 --- /dev/null +++ b/mobile_app/assets/www/charges/cannon.svg @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/caravel.svg b/mobile_app/assets/www/charges/caravel.svg new file mode 100644 index 00000000..9eb57671 --- /dev/null +++ b/mobile_app/assets/www/charges/caravel.svg @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/carreau.svg b/mobile_app/assets/www/charges/carreau.svg new file mode 100644 index 00000000..bfeeb049 --- /dev/null +++ b/mobile_app/assets/www/charges/carreau.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/mobile_app/assets/www/charges/castle.svg b/mobile_app/assets/www/charges/castle.svg new file mode 100644 index 00000000..43a2fa38 --- /dev/null +++ b/mobile_app/assets/www/charges/castle.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/castle2.svg b/mobile_app/assets/www/charges/castle2.svg new file mode 100644 index 00000000..5f12a8aa --- /dev/null +++ b/mobile_app/assets/www/charges/castle2.svg @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/catPassantGuardant.svg b/mobile_app/assets/www/charges/catPassantGuardant.svg new file mode 100644 index 00000000..b49dc820 --- /dev/null +++ b/mobile_app/assets/www/charges/catPassantGuardant.svg @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/cavalier.svg b/mobile_app/assets/www/charges/cavalier.svg new file mode 100644 index 00000000..7bfad7ac --- /dev/null +++ b/mobile_app/assets/www/charges/cavalier.svg @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/centaur.svg b/mobile_app/assets/www/charges/centaur.svg new file mode 100644 index 00000000..f4ddeb22 --- /dev/null +++ b/mobile_app/assets/www/charges/centaur.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/chain.svg b/mobile_app/assets/www/charges/chain.svg new file mode 100644 index 00000000..cfe4a3bb --- /dev/null +++ b/mobile_app/assets/www/charges/chain.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/chalice.svg b/mobile_app/assets/www/charges/chalice.svg new file mode 100644 index 00000000..0f4f95f6 --- /dev/null +++ b/mobile_app/assets/www/charges/chalice.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/cinquefoil.svg b/mobile_app/assets/www/charges/cinquefoil.svg new file mode 100644 index 00000000..49db293e --- /dev/null +++ b/mobile_app/assets/www/charges/cinquefoil.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/cock.svg b/mobile_app/assets/www/charges/cock.svg new file mode 100644 index 00000000..4b100034 --- /dev/null +++ b/mobile_app/assets/www/charges/cock.svg @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/column.svg b/mobile_app/assets/www/charges/column.svg new file mode 100644 index 00000000..38d8b2a0 --- /dev/null +++ b/mobile_app/assets/www/charges/column.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/comet.svg b/mobile_app/assets/www/charges/comet.svg new file mode 100644 index 00000000..096ddb67 --- /dev/null +++ b/mobile_app/assets/www/charges/comet.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/mobile_app/assets/www/charges/compassRose.svg b/mobile_app/assets/www/charges/compassRose.svg new file mode 100644 index 00000000..dec495cc --- /dev/null +++ b/mobile_app/assets/www/charges/compassRose.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/mobile_app/assets/www/charges/cossack.svg b/mobile_app/assets/www/charges/cossack.svg new file mode 100644 index 00000000..f5cf75ed --- /dev/null +++ b/mobile_app/assets/www/charges/cossack.svg @@ -0,0 +1,201 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/cowHorns.svg b/mobile_app/assets/www/charges/cowHorns.svg new file mode 100644 index 00000000..74378210 --- /dev/null +++ b/mobile_app/assets/www/charges/cowHorns.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/cowStatant.svg b/mobile_app/assets/www/charges/cowStatant.svg new file mode 100644 index 00000000..66b46823 --- /dev/null +++ b/mobile_app/assets/www/charges/cowStatant.svg @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/crescent.svg b/mobile_app/assets/www/charges/crescent.svg new file mode 100644 index 00000000..9181995b --- /dev/null +++ b/mobile_app/assets/www/charges/crescent.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/mobile_app/assets/www/charges/crocodile.svg b/mobile_app/assets/www/charges/crocodile.svg new file mode 100644 index 00000000..442e456d --- /dev/null +++ b/mobile_app/assets/www/charges/crocodile.svg @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/crosier.svg b/mobile_app/assets/www/charges/crosier.svg new file mode 100644 index 00000000..631ef998 --- /dev/null +++ b/mobile_app/assets/www/charges/crosier.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/mobile_app/assets/www/charges/crossAnkh.svg b/mobile_app/assets/www/charges/crossAnkh.svg new file mode 100644 index 00000000..6bbac70e --- /dev/null +++ b/mobile_app/assets/www/charges/crossAnkh.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/mobile_app/assets/www/charges/crossArrowed.svg b/mobile_app/assets/www/charges/crossArrowed.svg new file mode 100644 index 00000000..ff4b6c02 --- /dev/null +++ b/mobile_app/assets/www/charges/crossArrowed.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/mobile_app/assets/www/charges/crossAvellane.svg b/mobile_app/assets/www/charges/crossAvellane.svg new file mode 100644 index 00000000..303e7f72 --- /dev/null +++ b/mobile_app/assets/www/charges/crossAvellane.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/mobile_app/assets/www/charges/crossBiparted.svg b/mobile_app/assets/www/charges/crossBiparted.svg new file mode 100644 index 00000000..0e6ac5f8 --- /dev/null +++ b/mobile_app/assets/www/charges/crossBiparted.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/mobile_app/assets/www/charges/crossBottony.svg b/mobile_app/assets/www/charges/crossBottony.svg new file mode 100644 index 00000000..2d246b29 --- /dev/null +++ b/mobile_app/assets/www/charges/crossBottony.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/mobile_app/assets/www/charges/crossBurgundy.svg b/mobile_app/assets/www/charges/crossBurgundy.svg new file mode 100644 index 00000000..cb681714 --- /dev/null +++ b/mobile_app/assets/www/charges/crossBurgundy.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/mobile_app/assets/www/charges/crossCalvary.svg b/mobile_app/assets/www/charges/crossCalvary.svg new file mode 100644 index 00000000..dd0447b5 --- /dev/null +++ b/mobile_app/assets/www/charges/crossCalvary.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/mobile_app/assets/www/charges/crossCarolingian.svg b/mobile_app/assets/www/charges/crossCarolingian.svg new file mode 100644 index 00000000..761464a7 --- /dev/null +++ b/mobile_app/assets/www/charges/crossCarolingian.svg @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/crossCeltic.svg b/mobile_app/assets/www/charges/crossCeltic.svg new file mode 100644 index 00000000..6abe10fe --- /dev/null +++ b/mobile_app/assets/www/charges/crossCeltic.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/mobile_app/assets/www/charges/crossCeltic2.svg b/mobile_app/assets/www/charges/crossCeltic2.svg new file mode 100644 index 00000000..84628911 --- /dev/null +++ b/mobile_app/assets/www/charges/crossCeltic2.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/mobile_app/assets/www/charges/crossCercelee.svg b/mobile_app/assets/www/charges/crossCercelee.svg new file mode 100644 index 00000000..2b8bff16 --- /dev/null +++ b/mobile_app/assets/www/charges/crossCercelee.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/mobile_app/assets/www/charges/crossClechy.svg b/mobile_app/assets/www/charges/crossClechy.svg new file mode 100644 index 00000000..c246534e --- /dev/null +++ b/mobile_app/assets/www/charges/crossClechy.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/mobile_app/assets/www/charges/crossDouble.svg b/mobile_app/assets/www/charges/crossDouble.svg new file mode 100644 index 00000000..1a0e4bc8 --- /dev/null +++ b/mobile_app/assets/www/charges/crossDouble.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/mobile_app/assets/www/charges/crossErminee.svg b/mobile_app/assets/www/charges/crossErminee.svg new file mode 100644 index 00000000..1def3830 --- /dev/null +++ b/mobile_app/assets/www/charges/crossErminee.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/mobile_app/assets/www/charges/crossFitchy.svg b/mobile_app/assets/www/charges/crossFitchy.svg new file mode 100644 index 00000000..954b8e70 --- /dev/null +++ b/mobile_app/assets/www/charges/crossFitchy.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/mobile_app/assets/www/charges/crossFleury.svg b/mobile_app/assets/www/charges/crossFleury.svg new file mode 100644 index 00000000..d617a15d --- /dev/null +++ b/mobile_app/assets/www/charges/crossFleury.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/mobile_app/assets/www/charges/crossFormee.svg b/mobile_app/assets/www/charges/crossFormee.svg new file mode 100644 index 00000000..efef99d4 --- /dev/null +++ b/mobile_app/assets/www/charges/crossFormee.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/mobile_app/assets/www/charges/crossFormee2.svg b/mobile_app/assets/www/charges/crossFormee2.svg new file mode 100644 index 00000000..2309e494 --- /dev/null +++ b/mobile_app/assets/www/charges/crossFormee2.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/mobile_app/assets/www/charges/crossFourchy.svg b/mobile_app/assets/www/charges/crossFourchy.svg new file mode 100644 index 00000000..9308a143 --- /dev/null +++ b/mobile_app/assets/www/charges/crossFourchy.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/mobile_app/assets/www/charges/crossGamma.svg b/mobile_app/assets/www/charges/crossGamma.svg new file mode 100644 index 00000000..d2da6490 --- /dev/null +++ b/mobile_app/assets/www/charges/crossGamma.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/mobile_app/assets/www/charges/crossHummetty.svg b/mobile_app/assets/www/charges/crossHummetty.svg new file mode 100644 index 00000000..e2676ab2 --- /dev/null +++ b/mobile_app/assets/www/charges/crossHummetty.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/mobile_app/assets/www/charges/crossJerusalem.svg b/mobile_app/assets/www/charges/crossJerusalem.svg new file mode 100644 index 00000000..54ba95dc --- /dev/null +++ b/mobile_app/assets/www/charges/crossJerusalem.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/mobile_app/assets/www/charges/crossLatin.svg b/mobile_app/assets/www/charges/crossLatin.svg new file mode 100644 index 00000000..16f60138 --- /dev/null +++ b/mobile_app/assets/www/charges/crossLatin.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/mobile_app/assets/www/charges/crossMaltese.svg b/mobile_app/assets/www/charges/crossMaltese.svg new file mode 100644 index 00000000..5718dacf --- /dev/null +++ b/mobile_app/assets/www/charges/crossMaltese.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/mobile_app/assets/www/charges/crossMoline.svg b/mobile_app/assets/www/charges/crossMoline.svg new file mode 100644 index 00000000..97f3b918 --- /dev/null +++ b/mobile_app/assets/www/charges/crossMoline.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/mobile_app/assets/www/charges/crossOccitan.svg b/mobile_app/assets/www/charges/crossOccitan.svg new file mode 100644 index 00000000..15fe7587 --- /dev/null +++ b/mobile_app/assets/www/charges/crossOccitan.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/mobile_app/assets/www/charges/crossOrthodox.svg b/mobile_app/assets/www/charges/crossOrthodox.svg new file mode 100644 index 00000000..9519f84d --- /dev/null +++ b/mobile_app/assets/www/charges/crossOrthodox.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/mobile_app/assets/www/charges/crossPatonce.svg b/mobile_app/assets/www/charges/crossPatonce.svg new file mode 100644 index 00000000..aaaec339 --- /dev/null +++ b/mobile_app/assets/www/charges/crossPatonce.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/mobile_app/assets/www/charges/crossPatriarchal.svg b/mobile_app/assets/www/charges/crossPatriarchal.svg new file mode 100644 index 00000000..12338bc2 --- /dev/null +++ b/mobile_app/assets/www/charges/crossPatriarchal.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/mobile_app/assets/www/charges/crossPattee.svg b/mobile_app/assets/www/charges/crossPattee.svg new file mode 100644 index 00000000..1c3bf761 --- /dev/null +++ b/mobile_app/assets/www/charges/crossPattee.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/mobile_app/assets/www/charges/crossPatteeAlisee.svg b/mobile_app/assets/www/charges/crossPatteeAlisee.svg new file mode 100644 index 00000000..801e7113 --- /dev/null +++ b/mobile_app/assets/www/charges/crossPatteeAlisee.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/mobile_app/assets/www/charges/crossPommy.svg b/mobile_app/assets/www/charges/crossPommy.svg new file mode 100644 index 00000000..da002347 --- /dev/null +++ b/mobile_app/assets/www/charges/crossPommy.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/mobile_app/assets/www/charges/crossPotent.svg b/mobile_app/assets/www/charges/crossPotent.svg new file mode 100644 index 00000000..cc3bb92f --- /dev/null +++ b/mobile_app/assets/www/charges/crossPotent.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/mobile_app/assets/www/charges/crossSaltire.svg b/mobile_app/assets/www/charges/crossSaltire.svg new file mode 100644 index 00000000..8798ba45 --- /dev/null +++ b/mobile_app/assets/www/charges/crossSaltire.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/mobile_app/assets/www/charges/crossSantiago.svg b/mobile_app/assets/www/charges/crossSantiago.svg new file mode 100644 index 00000000..7e510a90 --- /dev/null +++ b/mobile_app/assets/www/charges/crossSantiago.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/mobile_app/assets/www/charges/crossTau.svg b/mobile_app/assets/www/charges/crossTau.svg new file mode 100644 index 00000000..0789faf5 --- /dev/null +++ b/mobile_app/assets/www/charges/crossTau.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/mobile_app/assets/www/charges/crossTemplar.svg b/mobile_app/assets/www/charges/crossTemplar.svg new file mode 100644 index 00000000..9c33613c --- /dev/null +++ b/mobile_app/assets/www/charges/crossTemplar.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/mobile_app/assets/www/charges/crossTriquetra.svg b/mobile_app/assets/www/charges/crossTriquetra.svg new file mode 100644 index 00000000..024225c1 --- /dev/null +++ b/mobile_app/assets/www/charges/crossTriquetra.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/mobile_app/assets/www/charges/crossVoided.svg b/mobile_app/assets/www/charges/crossVoided.svg new file mode 100644 index 00000000..0fa95bd7 --- /dev/null +++ b/mobile_app/assets/www/charges/crossVoided.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/mobile_app/assets/www/charges/crossedBones.svg b/mobile_app/assets/www/charges/crossedBones.svg new file mode 100644 index 00000000..3b06442f --- /dev/null +++ b/mobile_app/assets/www/charges/crossedBones.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/mobile_app/assets/www/charges/crosslet.svg b/mobile_app/assets/www/charges/crosslet.svg new file mode 100644 index 00000000..645b68a3 --- /dev/null +++ b/mobile_app/assets/www/charges/crosslet.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/mobile_app/assets/www/charges/crown.svg b/mobile_app/assets/www/charges/crown.svg new file mode 100644 index 00000000..00dbbacf --- /dev/null +++ b/mobile_app/assets/www/charges/crown.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/crown2.svg b/mobile_app/assets/www/charges/crown2.svg new file mode 100644 index 00000000..f06a106e --- /dev/null +++ b/mobile_app/assets/www/charges/crown2.svg @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/deerHeadCaboshed.svg b/mobile_app/assets/www/charges/deerHeadCaboshed.svg new file mode 100644 index 00000000..aca87f99 --- /dev/null +++ b/mobile_app/assets/www/charges/deerHeadCaboshed.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/delf.svg b/mobile_app/assets/www/charges/delf.svg new file mode 100644 index 00000000..227bd04f --- /dev/null +++ b/mobile_app/assets/www/charges/delf.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/mobile_app/assets/www/charges/dolphin.svg b/mobile_app/assets/www/charges/dolphin.svg new file mode 100644 index 00000000..be5b00bd --- /dev/null +++ b/mobile_app/assets/www/charges/dolphin.svg @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/donkeyHeadCaboshed.svg b/mobile_app/assets/www/charges/donkeyHeadCaboshed.svg new file mode 100644 index 00000000..da5aee0a --- /dev/null +++ b/mobile_app/assets/www/charges/donkeyHeadCaboshed.svg @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/dove.svg b/mobile_app/assets/www/charges/dove.svg new file mode 100644 index 00000000..7406a6ec --- /dev/null +++ b/mobile_app/assets/www/charges/dove.svg @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/doveDisplayed.svg b/mobile_app/assets/www/charges/doveDisplayed.svg new file mode 100644 index 00000000..35bd14d6 --- /dev/null +++ b/mobile_app/assets/www/charges/doveDisplayed.svg @@ -0,0 +1,112 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/dragonPassant.svg b/mobile_app/assets/www/charges/dragonPassant.svg new file mode 100644 index 00000000..b8fbc58e --- /dev/null +++ b/mobile_app/assets/www/charges/dragonPassant.svg @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/dragonRampant.svg b/mobile_app/assets/www/charges/dragonRampant.svg new file mode 100644 index 00000000..6ff64c2a --- /dev/null +++ b/mobile_app/assets/www/charges/dragonRampant.svg @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/dragonfly.svg b/mobile_app/assets/www/charges/dragonfly.svg new file mode 100644 index 00000000..c8b501ca --- /dev/null +++ b/mobile_app/assets/www/charges/dragonfly.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/drakkar.svg b/mobile_app/assets/www/charges/drakkar.svg new file mode 100644 index 00000000..f36c3c4d --- /dev/null +++ b/mobile_app/assets/www/charges/drakkar.svg @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/drawingCompass.svg b/mobile_app/assets/www/charges/drawingCompass.svg new file mode 100644 index 00000000..65a252d3 --- /dev/null +++ b/mobile_app/assets/www/charges/drawingCompass.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/drum.svg b/mobile_app/assets/www/charges/drum.svg new file mode 100644 index 00000000..bd8fd638 --- /dev/null +++ b/mobile_app/assets/www/charges/drum.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/duck.svg b/mobile_app/assets/www/charges/duck.svg new file mode 100644 index 00000000..940c3e4d --- /dev/null +++ b/mobile_app/assets/www/charges/duck.svg @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/eagle.svg b/mobile_app/assets/www/charges/eagle.svg new file mode 100644 index 00000000..c52fd495 --- /dev/null +++ b/mobile_app/assets/www/charges/eagle.svg @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/eagleTwoHeads.svg b/mobile_app/assets/www/charges/eagleTwoHeads.svg new file mode 100644 index 00000000..cc8ac124 --- /dev/null +++ b/mobile_app/assets/www/charges/eagleTwoHeads.svg @@ -0,0 +1,103 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/earOfWheat.svg b/mobile_app/assets/www/charges/earOfWheat.svg new file mode 100644 index 00000000..a1b3072c --- /dev/null +++ b/mobile_app/assets/www/charges/earOfWheat.svg @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/elephant.svg b/mobile_app/assets/www/charges/elephant.svg new file mode 100644 index 00000000..fed4c13f --- /dev/null +++ b/mobile_app/assets/www/charges/elephant.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/elephantHeadErased.svg b/mobile_app/assets/www/charges/elephantHeadErased.svg new file mode 100644 index 00000000..f521413b --- /dev/null +++ b/mobile_app/assets/www/charges/elephantHeadErased.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/escallop.svg b/mobile_app/assets/www/charges/escallop.svg new file mode 100644 index 00000000..4fda9dda --- /dev/null +++ b/mobile_app/assets/www/charges/escallop.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/estoile.svg b/mobile_app/assets/www/charges/estoile.svg new file mode 100644 index 00000000..6966ccbc --- /dev/null +++ b/mobile_app/assets/www/charges/estoile.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/falchion.svg b/mobile_app/assets/www/charges/falchion.svg new file mode 100644 index 00000000..ccb71d3d --- /dev/null +++ b/mobile_app/assets/www/charges/falchion.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/falcon.svg b/mobile_app/assets/www/charges/falcon.svg new file mode 100644 index 00000000..5e4cebd5 --- /dev/null +++ b/mobile_app/assets/www/charges/falcon.svg @@ -0,0 +1,223 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/fan.svg b/mobile_app/assets/www/charges/fan.svg new file mode 100644 index 00000000..d7504ac6 --- /dev/null +++ b/mobile_app/assets/www/charges/fan.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/fasces.svg b/mobile_app/assets/www/charges/fasces.svg new file mode 100644 index 00000000..71e27285 --- /dev/null +++ b/mobile_app/assets/www/charges/fasces.svg @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/feather.svg b/mobile_app/assets/www/charges/feather.svg new file mode 100644 index 00000000..0be55bf5 --- /dev/null +++ b/mobile_app/assets/www/charges/feather.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/mobile_app/assets/www/charges/flamberge.svg b/mobile_app/assets/www/charges/flamberge.svg new file mode 100644 index 00000000..ab9d2277 --- /dev/null +++ b/mobile_app/assets/www/charges/flamberge.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/flangedMace.svg b/mobile_app/assets/www/charges/flangedMace.svg new file mode 100644 index 00000000..901d942f --- /dev/null +++ b/mobile_app/assets/www/charges/flangedMace.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/fleurDeLis.svg b/mobile_app/assets/www/charges/fleurDeLis.svg new file mode 100644 index 00000000..2583e48f --- /dev/null +++ b/mobile_app/assets/www/charges/fleurDeLis.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/fly.svg b/mobile_app/assets/www/charges/fly.svg new file mode 100644 index 00000000..9c880f72 --- /dev/null +++ b/mobile_app/assets/www/charges/fly.svg @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/foot.svg b/mobile_app/assets/www/charges/foot.svg new file mode 100644 index 00000000..22963e5b --- /dev/null +++ b/mobile_app/assets/www/charges/foot.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/fountain.svg b/mobile_app/assets/www/charges/fountain.svg new file mode 100644 index 00000000..1ed8ac67 --- /dev/null +++ b/mobile_app/assets/www/charges/fountain.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/frog.svg b/mobile_app/assets/www/charges/frog.svg new file mode 100644 index 00000000..392d3d05 --- /dev/null +++ b/mobile_app/assets/www/charges/frog.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/fusil.svg b/mobile_app/assets/www/charges/fusil.svg new file mode 100644 index 00000000..eac10ed4 --- /dev/null +++ b/mobile_app/assets/www/charges/fusil.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/mobile_app/assets/www/charges/garb.svg b/mobile_app/assets/www/charges/garb.svg new file mode 100644 index 00000000..fbefacd8 --- /dev/null +++ b/mobile_app/assets/www/charges/garb.svg @@ -0,0 +1,150 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/gauntlet.svg b/mobile_app/assets/www/charges/gauntlet.svg new file mode 100644 index 00000000..f00a03eb --- /dev/null +++ b/mobile_app/assets/www/charges/gauntlet.svg @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/gear.svg b/mobile_app/assets/www/charges/gear.svg new file mode 100644 index 00000000..2d128dfb --- /dev/null +++ b/mobile_app/assets/www/charges/gear.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/mobile_app/assets/www/charges/goat.svg b/mobile_app/assets/www/charges/goat.svg new file mode 100644 index 00000000..721c3f15 --- /dev/null +++ b/mobile_app/assets/www/charges/goat.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/goutte.svg b/mobile_app/assets/www/charges/goutte.svg new file mode 100644 index 00000000..40f23183 --- /dev/null +++ b/mobile_app/assets/www/charges/goutte.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/mobile_app/assets/www/charges/grapeBunch.svg b/mobile_app/assets/www/charges/grapeBunch.svg new file mode 100644 index 00000000..38d4693f --- /dev/null +++ b/mobile_app/assets/www/charges/grapeBunch.svg @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/grapeBunch2.svg b/mobile_app/assets/www/charges/grapeBunch2.svg new file mode 100644 index 00000000..0af7b6a6 --- /dev/null +++ b/mobile_app/assets/www/charges/grapeBunch2.svg @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/grenade.svg b/mobile_app/assets/www/charges/grenade.svg new file mode 100644 index 00000000..07436784 --- /dev/null +++ b/mobile_app/assets/www/charges/grenade.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/greyhoundCourant.svg b/mobile_app/assets/www/charges/greyhoundCourant.svg new file mode 100644 index 00000000..916d70cf --- /dev/null +++ b/mobile_app/assets/www/charges/greyhoundCourant.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/mobile_app/assets/www/charges/greyhoundRampant.svg b/mobile_app/assets/www/charges/greyhoundRampant.svg new file mode 100644 index 00000000..cf607df5 --- /dev/null +++ b/mobile_app/assets/www/charges/greyhoundRampant.svg @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/greyhoundSejant.svg b/mobile_app/assets/www/charges/greyhoundSejant.svg new file mode 100644 index 00000000..09efa81c --- /dev/null +++ b/mobile_app/assets/www/charges/greyhoundSejant.svg @@ -0,0 +1,108 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/griffinPassant.svg b/mobile_app/assets/www/charges/griffinPassant.svg new file mode 100644 index 00000000..871b3591 --- /dev/null +++ b/mobile_app/assets/www/charges/griffinPassant.svg @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/griffinRampant.svg b/mobile_app/assets/www/charges/griffinRampant.svg new file mode 100644 index 00000000..da2cfebe --- /dev/null +++ b/mobile_app/assets/www/charges/griffinRampant.svg @@ -0,0 +1,115 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/hand.svg b/mobile_app/assets/www/charges/hand.svg new file mode 100644 index 00000000..91c279ae --- /dev/null +++ b/mobile_app/assets/www/charges/hand.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/harp.svg b/mobile_app/assets/www/charges/harp.svg new file mode 100644 index 00000000..91e5ee08 --- /dev/null +++ b/mobile_app/assets/www/charges/harp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/mobile_app/assets/www/charges/hatchet.svg b/mobile_app/assets/www/charges/hatchet.svg new file mode 100644 index 00000000..37052556 --- /dev/null +++ b/mobile_app/assets/www/charges/hatchet.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/mobile_app/assets/www/charges/head.svg b/mobile_app/assets/www/charges/head.svg new file mode 100644 index 00000000..08e36060 --- /dev/null +++ b/mobile_app/assets/www/charges/head.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/mobile_app/assets/www/charges/headWreathed.svg b/mobile_app/assets/www/charges/headWreathed.svg new file mode 100644 index 00000000..b6dafc64 --- /dev/null +++ b/mobile_app/assets/www/charges/headWreathed.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/heart.svg b/mobile_app/assets/www/charges/heart.svg new file mode 100644 index 00000000..56d0940c --- /dev/null +++ b/mobile_app/assets/www/charges/heart.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/mobile_app/assets/www/charges/hedgehog.svg b/mobile_app/assets/www/charges/hedgehog.svg new file mode 100644 index 00000000..c7a84caa --- /dev/null +++ b/mobile_app/assets/www/charges/hedgehog.svg @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/helmet.svg b/mobile_app/assets/www/charges/helmet.svg new file mode 100644 index 00000000..9099c7c3 --- /dev/null +++ b/mobile_app/assets/www/charges/helmet.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/helmetCorinthian.svg b/mobile_app/assets/www/charges/helmetCorinthian.svg new file mode 100644 index 00000000..3ccd9cdd --- /dev/null +++ b/mobile_app/assets/www/charges/helmetCorinthian.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/helmetGreat.svg b/mobile_app/assets/www/charges/helmetGreat.svg new file mode 100644 index 00000000..b7a7bf49 --- /dev/null +++ b/mobile_app/assets/www/charges/helmetGreat.svg @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/helmetZischagge.svg b/mobile_app/assets/www/charges/helmetZischagge.svg new file mode 100644 index 00000000..8985d197 --- /dev/null +++ b/mobile_app/assets/www/charges/helmetZischagge.svg @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/heron.svg b/mobile_app/assets/www/charges/heron.svg new file mode 100644 index 00000000..4893b082 --- /dev/null +++ b/mobile_app/assets/www/charges/heron.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/hindStatant.svg b/mobile_app/assets/www/charges/hindStatant.svg new file mode 100644 index 00000000..3f9cc429 --- /dev/null +++ b/mobile_app/assets/www/charges/hindStatant.svg @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/hook.svg b/mobile_app/assets/www/charges/hook.svg new file mode 100644 index 00000000..d5679f64 --- /dev/null +++ b/mobile_app/assets/www/charges/hook.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/mobile_app/assets/www/charges/horseHeadCouped.svg b/mobile_app/assets/www/charges/horseHeadCouped.svg new file mode 100644 index 00000000..8c455c23 --- /dev/null +++ b/mobile_app/assets/www/charges/horseHeadCouped.svg @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/horsePassant.svg b/mobile_app/assets/www/charges/horsePassant.svg new file mode 100644 index 00000000..b2361b84 --- /dev/null +++ b/mobile_app/assets/www/charges/horsePassant.svg @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/horseRampant.svg b/mobile_app/assets/www/charges/horseRampant.svg new file mode 100644 index 00000000..be7fee6c --- /dev/null +++ b/mobile_app/assets/www/charges/horseRampant.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/horseSalient.svg b/mobile_app/assets/www/charges/horseSalient.svg new file mode 100644 index 00000000..21b5db48 --- /dev/null +++ b/mobile_app/assets/www/charges/horseSalient.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/mobile_app/assets/www/charges/horseshoe.svg b/mobile_app/assets/www/charges/horseshoe.svg new file mode 100644 index 00000000..3bd51f7a --- /dev/null +++ b/mobile_app/assets/www/charges/horseshoe.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/mobile_app/assets/www/charges/hourglass.svg b/mobile_app/assets/www/charges/hourglass.svg new file mode 100644 index 00000000..87e7930b --- /dev/null +++ b/mobile_app/assets/www/charges/hourglass.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/key.svg b/mobile_app/assets/www/charges/key.svg new file mode 100644 index 00000000..6fb883ea --- /dev/null +++ b/mobile_app/assets/www/charges/key.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/ladder.svg b/mobile_app/assets/www/charges/ladder.svg new file mode 100644 index 00000000..fc72f130 --- /dev/null +++ b/mobile_app/assets/www/charges/ladder.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/ladder2.svg b/mobile_app/assets/www/charges/ladder2.svg new file mode 100644 index 00000000..5596e045 --- /dev/null +++ b/mobile_app/assets/www/charges/ladder2.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/ladybird.svg b/mobile_app/assets/www/charges/ladybird.svg new file mode 100644 index 00000000..3cc1587e --- /dev/null +++ b/mobile_app/assets/www/charges/ladybird.svg @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/lamb.svg b/mobile_app/assets/www/charges/lamb.svg new file mode 100644 index 00000000..1d574b53 --- /dev/null +++ b/mobile_app/assets/www/charges/lamb.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/lambPassantReguardant.svg b/mobile_app/assets/www/charges/lambPassantReguardant.svg new file mode 100644 index 00000000..90884eb7 --- /dev/null +++ b/mobile_app/assets/www/charges/lambPassantReguardant.svg @@ -0,0 +1,118 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/lanceHead.svg b/mobile_app/assets/www/charges/lanceHead.svg new file mode 100644 index 00000000..255492db --- /dev/null +++ b/mobile_app/assets/www/charges/lanceHead.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/mobile_app/assets/www/charges/lanceWithBanner.svg b/mobile_app/assets/www/charges/lanceWithBanner.svg new file mode 100644 index 00000000..556e5ade --- /dev/null +++ b/mobile_app/assets/www/charges/lanceWithBanner.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/mobile_app/assets/www/charges/laurelWreath.svg b/mobile_app/assets/www/charges/laurelWreath.svg new file mode 100644 index 00000000..989e00c4 --- /dev/null +++ b/mobile_app/assets/www/charges/laurelWreath.svg @@ -0,0 +1,263 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/laurelWreath2.svg b/mobile_app/assets/www/charges/laurelWreath2.svg new file mode 100644 index 00000000..6dfb373e --- /dev/null +++ b/mobile_app/assets/www/charges/laurelWreath2.svg @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/lighthouse.svg b/mobile_app/assets/www/charges/lighthouse.svg new file mode 100644 index 00000000..b66938f5 --- /dev/null +++ b/mobile_app/assets/www/charges/lighthouse.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/lionHeadCaboshed.svg b/mobile_app/assets/www/charges/lionHeadCaboshed.svg new file mode 100644 index 00000000..63022fc0 --- /dev/null +++ b/mobile_app/assets/www/charges/lionHeadCaboshed.svg @@ -0,0 +1,107 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/lionHeadErased.svg b/mobile_app/assets/www/charges/lionHeadErased.svg new file mode 100644 index 00000000..7ed39c67 --- /dev/null +++ b/mobile_app/assets/www/charges/lionHeadErased.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/lionPassant.svg b/mobile_app/assets/www/charges/lionPassant.svg new file mode 100644 index 00000000..7dd6b396 --- /dev/null +++ b/mobile_app/assets/www/charges/lionPassant.svg @@ -0,0 +1,185 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/lionPassantGuardant.svg b/mobile_app/assets/www/charges/lionPassantGuardant.svg new file mode 100644 index 00000000..584e8835 --- /dev/null +++ b/mobile_app/assets/www/charges/lionPassantGuardant.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/mobile_app/assets/www/charges/lionRampant.svg b/mobile_app/assets/www/charges/lionRampant.svg new file mode 100644 index 00000000..8aab2b09 --- /dev/null +++ b/mobile_app/assets/www/charges/lionRampant.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/mobile_app/assets/www/charges/lionSejant.svg b/mobile_app/assets/www/charges/lionSejant.svg new file mode 100644 index 00000000..23ca98db --- /dev/null +++ b/mobile_app/assets/www/charges/lionSejant.svg @@ -0,0 +1,125 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/lizard.svg b/mobile_app/assets/www/charges/lizard.svg new file mode 100644 index 00000000..dc8dbf9d --- /dev/null +++ b/mobile_app/assets/www/charges/lizard.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/lochaberAxe.svg b/mobile_app/assets/www/charges/lochaberAxe.svg new file mode 100644 index 00000000..cf09c61e --- /dev/null +++ b/mobile_app/assets/www/charges/lochaberAxe.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/mobile_app/assets/www/charges/log.svg b/mobile_app/assets/www/charges/log.svg new file mode 100644 index 00000000..387fad44 --- /dev/null +++ b/mobile_app/assets/www/charges/log.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/mobile_app/assets/www/charges/lozenge.svg b/mobile_app/assets/www/charges/lozenge.svg new file mode 100644 index 00000000..4cfb22c9 --- /dev/null +++ b/mobile_app/assets/www/charges/lozenge.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/mobile_app/assets/www/charges/lozengeFaceted.svg b/mobile_app/assets/www/charges/lozengeFaceted.svg new file mode 100644 index 00000000..63a575e3 --- /dev/null +++ b/mobile_app/assets/www/charges/lozengeFaceted.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/lozengePloye.svg b/mobile_app/assets/www/charges/lozengePloye.svg new file mode 100644 index 00000000..0187c681 --- /dev/null +++ b/mobile_app/assets/www/charges/lozengePloye.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/mobile_app/assets/www/charges/lute.svg b/mobile_app/assets/www/charges/lute.svg new file mode 100644 index 00000000..c88cc397 --- /dev/null +++ b/mobile_app/assets/www/charges/lute.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/mobile_app/assets/www/charges/lymphad.svg b/mobile_app/assets/www/charges/lymphad.svg new file mode 100644 index 00000000..457f10d7 --- /dev/null +++ b/mobile_app/assets/www/charges/lymphad.svg @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/lyre.svg b/mobile_app/assets/www/charges/lyre.svg new file mode 100644 index 00000000..d89b8550 --- /dev/null +++ b/mobile_app/assets/www/charges/lyre.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/mace.svg b/mobile_app/assets/www/charges/mace.svg new file mode 100644 index 00000000..a3f0e074 --- /dev/null +++ b/mobile_app/assets/www/charges/mace.svg @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/maces.svg b/mobile_app/assets/www/charges/maces.svg new file mode 100644 index 00000000..93988b80 --- /dev/null +++ b/mobile_app/assets/www/charges/maces.svg @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/mallet.svg b/mobile_app/assets/www/charges/mallet.svg new file mode 100644 index 00000000..ecb418f9 --- /dev/null +++ b/mobile_app/assets/www/charges/mallet.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/mantle.svg b/mobile_app/assets/www/charges/mantle.svg new file mode 100644 index 00000000..5493c30b --- /dev/null +++ b/mobile_app/assets/www/charges/mantle.svg @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/mapleLeaf.svg b/mobile_app/assets/www/charges/mapleLeaf.svg new file mode 100644 index 00000000..93e63767 --- /dev/null +++ b/mobile_app/assets/www/charges/mapleLeaf.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/martenCourant.svg b/mobile_app/assets/www/charges/martenCourant.svg new file mode 100644 index 00000000..1760d038 --- /dev/null +++ b/mobile_app/assets/www/charges/martenCourant.svg @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/mascle.svg b/mobile_app/assets/www/charges/mascle.svg new file mode 100644 index 00000000..b867e47a --- /dev/null +++ b/mobile_app/assets/www/charges/mascle.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/mobile_app/assets/www/charges/mastiffStatant.svg b/mobile_app/assets/www/charges/mastiffStatant.svg new file mode 100644 index 00000000..14feb266 --- /dev/null +++ b/mobile_app/assets/www/charges/mastiffStatant.svg @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/millstone.svg b/mobile_app/assets/www/charges/millstone.svg new file mode 100644 index 00000000..f8d523ca --- /dev/null +++ b/mobile_app/assets/www/charges/millstone.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/mitre.svg b/mobile_app/assets/www/charges/mitre.svg new file mode 100644 index 00000000..1a20e002 --- /dev/null +++ b/mobile_app/assets/www/charges/mitre.svg @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/monk.svg b/mobile_app/assets/www/charges/monk.svg new file mode 100644 index 00000000..8ede0359 --- /dev/null +++ b/mobile_app/assets/www/charges/monk.svg @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/moonInCrescent.svg b/mobile_app/assets/www/charges/moonInCrescent.svg new file mode 100644 index 00000000..27fdb512 --- /dev/null +++ b/mobile_app/assets/www/charges/moonInCrescent.svg @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/mullet.svg b/mobile_app/assets/www/charges/mullet.svg new file mode 100644 index 00000000..2658e971 --- /dev/null +++ b/mobile_app/assets/www/charges/mullet.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/mobile_app/assets/www/charges/mullet10.svg b/mobile_app/assets/www/charges/mullet10.svg new file mode 100644 index 00000000..60ed608a --- /dev/null +++ b/mobile_app/assets/www/charges/mullet10.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/mobile_app/assets/www/charges/mullet4.svg b/mobile_app/assets/www/charges/mullet4.svg new file mode 100644 index 00000000..37242f99 --- /dev/null +++ b/mobile_app/assets/www/charges/mullet4.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/mobile_app/assets/www/charges/mullet6.svg b/mobile_app/assets/www/charges/mullet6.svg new file mode 100644 index 00000000..1a1972aa --- /dev/null +++ b/mobile_app/assets/www/charges/mullet6.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/mobile_app/assets/www/charges/mullet6Faceted.svg b/mobile_app/assets/www/charges/mullet6Faceted.svg new file mode 100644 index 00000000..1ca0c335 --- /dev/null +++ b/mobile_app/assets/www/charges/mullet6Faceted.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/mobile_app/assets/www/charges/mullet6Pierced.svg b/mobile_app/assets/www/charges/mullet6Pierced.svg new file mode 100644 index 00000000..96d6f279 --- /dev/null +++ b/mobile_app/assets/www/charges/mullet6Pierced.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/mobile_app/assets/www/charges/mullet7.svg b/mobile_app/assets/www/charges/mullet7.svg new file mode 100644 index 00000000..53321978 --- /dev/null +++ b/mobile_app/assets/www/charges/mullet7.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/mobile_app/assets/www/charges/mullet8.svg b/mobile_app/assets/www/charges/mullet8.svg new file mode 100644 index 00000000..0239a883 --- /dev/null +++ b/mobile_app/assets/www/charges/mullet8.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/mobile_app/assets/www/charges/mulletFaceted.svg b/mobile_app/assets/www/charges/mulletFaceted.svg new file mode 100644 index 00000000..a43fe26e --- /dev/null +++ b/mobile_app/assets/www/charges/mulletFaceted.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/mobile_app/assets/www/charges/mulletPierced.svg b/mobile_app/assets/www/charges/mulletPierced.svg new file mode 100644 index 00000000..b469bf0c --- /dev/null +++ b/mobile_app/assets/www/charges/mulletPierced.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/mobile_app/assets/www/charges/oak.svg b/mobile_app/assets/www/charges/oak.svg new file mode 100644 index 00000000..b01da9b4 --- /dev/null +++ b/mobile_app/assets/www/charges/oak.svg @@ -0,0 +1,347 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/orb.svg b/mobile_app/assets/www/charges/orb.svg new file mode 100644 index 00000000..2d7354f5 --- /dev/null +++ b/mobile_app/assets/www/charges/orb.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/ouroboros.svg b/mobile_app/assets/www/charges/ouroboros.svg new file mode 100644 index 00000000..f0f39146 --- /dev/null +++ b/mobile_app/assets/www/charges/ouroboros.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/mobile_app/assets/www/charges/owl.svg b/mobile_app/assets/www/charges/owl.svg new file mode 100644 index 00000000..015a7f81 --- /dev/null +++ b/mobile_app/assets/www/charges/owl.svg @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/owlDisplayed.svg b/mobile_app/assets/www/charges/owlDisplayed.svg new file mode 100644 index 00000000..353fe5e7 --- /dev/null +++ b/mobile_app/assets/www/charges/owlDisplayed.svg @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/palace.svg b/mobile_app/assets/www/charges/palace.svg new file mode 100644 index 00000000..9e03dd4b --- /dev/null +++ b/mobile_app/assets/www/charges/palace.svg @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/palmTree.svg b/mobile_app/assets/www/charges/palmTree.svg new file mode 100644 index 00000000..590d14a3 --- /dev/null +++ b/mobile_app/assets/www/charges/palmTree.svg @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/parrot.svg b/mobile_app/assets/www/charges/parrot.svg new file mode 100644 index 00000000..92d7dd10 --- /dev/null +++ b/mobile_app/assets/www/charges/parrot.svg @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/peacock.svg b/mobile_app/assets/www/charges/peacock.svg new file mode 100644 index 00000000..064831f4 --- /dev/null +++ b/mobile_app/assets/www/charges/peacock.svg @@ -0,0 +1,167 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/peacockInPride.svg b/mobile_app/assets/www/charges/peacockInPride.svg new file mode 100644 index 00000000..b8b4f8c7 --- /dev/null +++ b/mobile_app/assets/www/charges/peacockInPride.svg @@ -0,0 +1,216 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/pear.svg b/mobile_app/assets/www/charges/pear.svg new file mode 100644 index 00000000..d421e208 --- /dev/null +++ b/mobile_app/assets/www/charges/pear.svg @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/pegasus.svg b/mobile_app/assets/www/charges/pegasus.svg new file mode 100644 index 00000000..5335022d --- /dev/null +++ b/mobile_app/assets/www/charges/pegasus.svg @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/pike.svg b/mobile_app/assets/www/charges/pike.svg new file mode 100644 index 00000000..812002b7 --- /dev/null +++ b/mobile_app/assets/www/charges/pike.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/pillar.svg b/mobile_app/assets/www/charges/pillar.svg new file mode 100644 index 00000000..d9aa943f --- /dev/null +++ b/mobile_app/assets/www/charges/pillar.svg @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/pincers.svg b/mobile_app/assets/www/charges/pincers.svg new file mode 100644 index 00000000..2e91f728 --- /dev/null +++ b/mobile_app/assets/www/charges/pincers.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/mobile_app/assets/www/charges/pineCone.svg b/mobile_app/assets/www/charges/pineCone.svg new file mode 100644 index 00000000..c326f2a2 --- /dev/null +++ b/mobile_app/assets/www/charges/pineCone.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/pineTree.svg b/mobile_app/assets/www/charges/pineTree.svg new file mode 100644 index 00000000..2abebe11 --- /dev/null +++ b/mobile_app/assets/www/charges/pineTree.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/pique.svg b/mobile_app/assets/www/charges/pique.svg new file mode 100644 index 00000000..06c5836e --- /dev/null +++ b/mobile_app/assets/www/charges/pique.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/mobile_app/assets/www/charges/plaice.svg b/mobile_app/assets/www/charges/plaice.svg new file mode 100644 index 00000000..8325d1ca --- /dev/null +++ b/mobile_app/assets/www/charges/plaice.svg @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/plough.svg b/mobile_app/assets/www/charges/plough.svg new file mode 100644 index 00000000..7c1f42fc --- /dev/null +++ b/mobile_app/assets/www/charges/plough.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/ploughshare.svg b/mobile_app/assets/www/charges/ploughshare.svg new file mode 100644 index 00000000..45928f03 --- /dev/null +++ b/mobile_app/assets/www/charges/ploughshare.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/mobile_app/assets/www/charges/porcupine.svg b/mobile_app/assets/www/charges/porcupine.svg new file mode 100644 index 00000000..bdc53081 --- /dev/null +++ b/mobile_app/assets/www/charges/porcupine.svg @@ -0,0 +1,137 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/portcullis.svg b/mobile_app/assets/www/charges/portcullis.svg new file mode 100644 index 00000000..de154326 --- /dev/null +++ b/mobile_app/assets/www/charges/portcullis.svg @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/pot.svg b/mobile_app/assets/www/charges/pot.svg new file mode 100644 index 00000000..64cc0ff6 --- /dev/null +++ b/mobile_app/assets/www/charges/pot.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/quatrefoil.svg b/mobile_app/assets/www/charges/quatrefoil.svg new file mode 100644 index 00000000..ff33f762 --- /dev/null +++ b/mobile_app/assets/www/charges/quatrefoil.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/rabbitSejant.svg b/mobile_app/assets/www/charges/rabbitSejant.svg new file mode 100644 index 00000000..c61e0a9b --- /dev/null +++ b/mobile_app/assets/www/charges/rabbitSejant.svg @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/raft.svg b/mobile_app/assets/www/charges/raft.svg new file mode 100644 index 00000000..d5b728b4 --- /dev/null +++ b/mobile_app/assets/www/charges/raft.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/rake.svg b/mobile_app/assets/www/charges/rake.svg new file mode 100644 index 00000000..6feed725 --- /dev/null +++ b/mobile_app/assets/www/charges/rake.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/ramHeadErased.svg b/mobile_app/assets/www/charges/ramHeadErased.svg new file mode 100644 index 00000000..c971f7b4 --- /dev/null +++ b/mobile_app/assets/www/charges/ramHeadErased.svg @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/ramPassant.svg b/mobile_app/assets/www/charges/ramPassant.svg new file mode 100644 index 00000000..421e416c --- /dev/null +++ b/mobile_app/assets/www/charges/ramPassant.svg @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/ramsHorn.svg b/mobile_app/assets/www/charges/ramsHorn.svg new file mode 100644 index 00000000..26585cc9 --- /dev/null +++ b/mobile_app/assets/www/charges/ramsHorn.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/rapier.svg b/mobile_app/assets/www/charges/rapier.svg new file mode 100644 index 00000000..fed83920 --- /dev/null +++ b/mobile_app/assets/www/charges/rapier.svg @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/ratRampant.svg b/mobile_app/assets/www/charges/ratRampant.svg new file mode 100644 index 00000000..13c6746a --- /dev/null +++ b/mobile_app/assets/www/charges/ratRampant.svg @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/raven.svg b/mobile_app/assets/www/charges/raven.svg new file mode 100644 index 00000000..6e3c4eca --- /dev/null +++ b/mobile_app/assets/www/charges/raven.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/rhinoceros.svg b/mobile_app/assets/www/charges/rhinoceros.svg new file mode 100644 index 00000000..1d43c4f4 --- /dev/null +++ b/mobile_app/assets/www/charges/rhinoceros.svg @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/ribbon1.svg b/mobile_app/assets/www/charges/ribbon1.svg new file mode 100644 index 00000000..03bf3515 --- /dev/null +++ b/mobile_app/assets/www/charges/ribbon1.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/ribbon2.svg b/mobile_app/assets/www/charges/ribbon2.svg new file mode 100644 index 00000000..0f15bb04 --- /dev/null +++ b/mobile_app/assets/www/charges/ribbon2.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/mobile_app/assets/www/charges/ribbon3.svg b/mobile_app/assets/www/charges/ribbon3.svg new file mode 100644 index 00000000..dd168991 --- /dev/null +++ b/mobile_app/assets/www/charges/ribbon3.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/ribbon4.svg b/mobile_app/assets/www/charges/ribbon4.svg new file mode 100644 index 00000000..bab35959 --- /dev/null +++ b/mobile_app/assets/www/charges/ribbon4.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/ribbon5.svg b/mobile_app/assets/www/charges/ribbon5.svg new file mode 100644 index 00000000..3c718bce --- /dev/null +++ b/mobile_app/assets/www/charges/ribbon5.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/ribbon6.svg b/mobile_app/assets/www/charges/ribbon6.svg new file mode 100644 index 00000000..a32eede7 --- /dev/null +++ b/mobile_app/assets/www/charges/ribbon6.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/mobile_app/assets/www/charges/ribbon7.svg b/mobile_app/assets/www/charges/ribbon7.svg new file mode 100644 index 00000000..2d9a1e21 --- /dev/null +++ b/mobile_app/assets/www/charges/ribbon7.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/ribbon8.svg b/mobile_app/assets/www/charges/ribbon8.svg new file mode 100644 index 00000000..f7c672a7 --- /dev/null +++ b/mobile_app/assets/www/charges/ribbon8.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/mobile_app/assets/www/charges/rose.svg b/mobile_app/assets/www/charges/rose.svg new file mode 100644 index 00000000..7ce11665 --- /dev/null +++ b/mobile_app/assets/www/charges/rose.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/roundel.svg b/mobile_app/assets/www/charges/roundel.svg new file mode 100644 index 00000000..344991ed --- /dev/null +++ b/mobile_app/assets/www/charges/roundel.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/mobile_app/assets/www/charges/roundel2.svg b/mobile_app/assets/www/charges/roundel2.svg new file mode 100644 index 00000000..fffa7ad4 --- /dev/null +++ b/mobile_app/assets/www/charges/roundel2.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/mobile_app/assets/www/charges/rustre.svg b/mobile_app/assets/www/charges/rustre.svg new file mode 100644 index 00000000..60c253a1 --- /dev/null +++ b/mobile_app/assets/www/charges/rustre.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/mobile_app/assets/www/charges/sabre.svg b/mobile_app/assets/www/charges/sabre.svg new file mode 100644 index 00000000..0f1f002d --- /dev/null +++ b/mobile_app/assets/www/charges/sabre.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/sabre2.svg b/mobile_app/assets/www/charges/sabre2.svg new file mode 100644 index 00000000..2466a761 --- /dev/null +++ b/mobile_app/assets/www/charges/sabre2.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/sabresCrossed.svg b/mobile_app/assets/www/charges/sabresCrossed.svg new file mode 100644 index 00000000..e9cec5f4 --- /dev/null +++ b/mobile_app/assets/www/charges/sabresCrossed.svg @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/sagittarius.svg b/mobile_app/assets/www/charges/sagittarius.svg new file mode 100644 index 00000000..ac5eaeeb --- /dev/null +++ b/mobile_app/assets/www/charges/sagittarius.svg @@ -0,0 +1,136 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/salmon.svg b/mobile_app/assets/www/charges/salmon.svg new file mode 100644 index 00000000..bda9bf49 --- /dev/null +++ b/mobile_app/assets/www/charges/salmon.svg @@ -0,0 +1,127 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/saw.svg b/mobile_app/assets/www/charges/saw.svg new file mode 100644 index 00000000..c356263f --- /dev/null +++ b/mobile_app/assets/www/charges/saw.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/scale.svg b/mobile_app/assets/www/charges/scale.svg new file mode 100644 index 00000000..b2da96ea --- /dev/null +++ b/mobile_app/assets/www/charges/scale.svg @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/scaleImbalanced.svg b/mobile_app/assets/www/charges/scaleImbalanced.svg new file mode 100644 index 00000000..ea151649 --- /dev/null +++ b/mobile_app/assets/www/charges/scaleImbalanced.svg @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/scalesHanging.svg b/mobile_app/assets/www/charges/scalesHanging.svg new file mode 100644 index 00000000..1065211b --- /dev/null +++ b/mobile_app/assets/www/charges/scalesHanging.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/sceptre.svg b/mobile_app/assets/www/charges/sceptre.svg new file mode 100644 index 00000000..57869cbf --- /dev/null +++ b/mobile_app/assets/www/charges/sceptre.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/scissors.svg b/mobile_app/assets/www/charges/scissors.svg new file mode 100644 index 00000000..a7437f1e --- /dev/null +++ b/mobile_app/assets/www/charges/scissors.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/mobile_app/assets/www/charges/scissors2.svg b/mobile_app/assets/www/charges/scissors2.svg new file mode 100644 index 00000000..109d8238 --- /dev/null +++ b/mobile_app/assets/www/charges/scissors2.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/scorpion.svg b/mobile_app/assets/www/charges/scorpion.svg new file mode 100644 index 00000000..c132511d --- /dev/null +++ b/mobile_app/assets/www/charges/scorpion.svg @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/scrollClosed.svg b/mobile_app/assets/www/charges/scrollClosed.svg new file mode 100644 index 00000000..1f7d8034 --- /dev/null +++ b/mobile_app/assets/www/charges/scrollClosed.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/scythe.svg b/mobile_app/assets/www/charges/scythe.svg new file mode 100644 index 00000000..b8d0a04d --- /dev/null +++ b/mobile_app/assets/www/charges/scythe.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/scythe2.svg b/mobile_app/assets/www/charges/scythe2.svg new file mode 100644 index 00000000..7fa9de5d --- /dev/null +++ b/mobile_app/assets/www/charges/scythe2.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/mobile_app/assets/www/charges/serpent.svg b/mobile_app/assets/www/charges/serpent.svg new file mode 100644 index 00000000..e12c9570 --- /dev/null +++ b/mobile_app/assets/www/charges/serpent.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/sextifoil.svg b/mobile_app/assets/www/charges/sextifoil.svg new file mode 100644 index 00000000..ad6e3303 --- /dev/null +++ b/mobile_app/assets/www/charges/sextifoil.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/shears.svg b/mobile_app/assets/www/charges/shears.svg new file mode 100644 index 00000000..3b3daeb4 --- /dev/null +++ b/mobile_app/assets/www/charges/shears.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/mobile_app/assets/www/charges/shield.svg b/mobile_app/assets/www/charges/shield.svg new file mode 100644 index 00000000..89ad41de --- /dev/null +++ b/mobile_app/assets/www/charges/shield.svg @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/shipWheel.svg b/mobile_app/assets/www/charges/shipWheel.svg new file mode 100644 index 00000000..fa23136c --- /dev/null +++ b/mobile_app/assets/www/charges/shipWheel.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/sickle.svg b/mobile_app/assets/www/charges/sickle.svg new file mode 100644 index 00000000..753eeeaa --- /dev/null +++ b/mobile_app/assets/www/charges/sickle.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/skeleton.svg b/mobile_app/assets/www/charges/skeleton.svg new file mode 100644 index 00000000..cde28dae --- /dev/null +++ b/mobile_app/assets/www/charges/skeleton.svg @@ -0,0 +1,105 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/skull.svg b/mobile_app/assets/www/charges/skull.svg new file mode 100644 index 00000000..c7dc7044 --- /dev/null +++ b/mobile_app/assets/www/charges/skull.svg @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/skull2.svg b/mobile_app/assets/www/charges/skull2.svg new file mode 100644 index 00000000..a580afd7 --- /dev/null +++ b/mobile_app/assets/www/charges/skull2.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/snail.svg b/mobile_app/assets/www/charges/snail.svg new file mode 100644 index 00000000..387dc48a --- /dev/null +++ b/mobile_app/assets/www/charges/snail.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/snake.svg b/mobile_app/assets/www/charges/snake.svg new file mode 100644 index 00000000..532f2c0c --- /dev/null +++ b/mobile_app/assets/www/charges/snake.svg @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/snowflake.svg b/mobile_app/assets/www/charges/snowflake.svg new file mode 100644 index 00000000..d85d067b --- /dev/null +++ b/mobile_app/assets/www/charges/snowflake.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/mobile_app/assets/www/charges/spear.svg b/mobile_app/assets/www/charges/spear.svg new file mode 100644 index 00000000..9944f9d5 --- /dev/null +++ b/mobile_app/assets/www/charges/spear.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/spiral.svg b/mobile_app/assets/www/charges/spiral.svg new file mode 100644 index 00000000..05736127 --- /dev/null +++ b/mobile_app/assets/www/charges/spiral.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/mobile_app/assets/www/charges/squirrel.svg b/mobile_app/assets/www/charges/squirrel.svg new file mode 100644 index 00000000..bf2cc68b --- /dev/null +++ b/mobile_app/assets/www/charges/squirrel.svg @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/stagLodgedRegardant.svg b/mobile_app/assets/www/charges/stagLodgedRegardant.svg new file mode 100644 index 00000000..024f648c --- /dev/null +++ b/mobile_app/assets/www/charges/stagLodgedRegardant.svg @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/stagPassant.svg b/mobile_app/assets/www/charges/stagPassant.svg new file mode 100644 index 00000000..745ed25e --- /dev/null +++ b/mobile_app/assets/www/charges/stagPassant.svg @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/stagsAttires.svg b/mobile_app/assets/www/charges/stagsAttires.svg new file mode 100644 index 00000000..c8b3692b --- /dev/null +++ b/mobile_app/assets/www/charges/stagsAttires.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/stirrup.svg b/mobile_app/assets/www/charges/stirrup.svg new file mode 100644 index 00000000..4350ad26 --- /dev/null +++ b/mobile_app/assets/www/charges/stirrup.svg @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/sun.svg b/mobile_app/assets/www/charges/sun.svg new file mode 100644 index 00000000..6d58a55c --- /dev/null +++ b/mobile_app/assets/www/charges/sun.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/mobile_app/assets/www/charges/sunInSplendour.svg b/mobile_app/assets/www/charges/sunInSplendour.svg new file mode 100644 index 00000000..4de9c571 --- /dev/null +++ b/mobile_app/assets/www/charges/sunInSplendour.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/sunInSplendour2.svg b/mobile_app/assets/www/charges/sunInSplendour2.svg new file mode 100644 index 00000000..d56c221d --- /dev/null +++ b/mobile_app/assets/www/charges/sunInSplendour2.svg @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/swallow.svg b/mobile_app/assets/www/charges/swallow.svg new file mode 100644 index 00000000..bf363a15 --- /dev/null +++ b/mobile_app/assets/www/charges/swallow.svg @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/swan.svg b/mobile_app/assets/www/charges/swan.svg new file mode 100644 index 00000000..26a345f7 --- /dev/null +++ b/mobile_app/assets/www/charges/swan.svg @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/swanErased.svg b/mobile_app/assets/www/charges/swanErased.svg new file mode 100644 index 00000000..510c380a --- /dev/null +++ b/mobile_app/assets/www/charges/swanErased.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/sword.svg b/mobile_app/assets/www/charges/sword.svg new file mode 100644 index 00000000..cdf8853b --- /dev/null +++ b/mobile_app/assets/www/charges/sword.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/talbotPassant.svg b/mobile_app/assets/www/charges/talbotPassant.svg new file mode 100644 index 00000000..121e6ba4 --- /dev/null +++ b/mobile_app/assets/www/charges/talbotPassant.svg @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/talbotSejant.svg b/mobile_app/assets/www/charges/talbotSejant.svg new file mode 100644 index 00000000..e89d4b90 --- /dev/null +++ b/mobile_app/assets/www/charges/talbotSejant.svg @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/template.svg b/mobile_app/assets/www/charges/template.svg new file mode 100644 index 00000000..cad51295 --- /dev/null +++ b/mobile_app/assets/www/charges/template.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/thistle.svg b/mobile_app/assets/www/charges/thistle.svg new file mode 100644 index 00000000..09cff52a --- /dev/null +++ b/mobile_app/assets/www/charges/thistle.svg @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/tower.svg b/mobile_app/assets/www/charges/tower.svg new file mode 100644 index 00000000..9754803a --- /dev/null +++ b/mobile_app/assets/www/charges/tower.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/tree.svg b/mobile_app/assets/www/charges/tree.svg new file mode 100644 index 00000000..0e2854fc --- /dev/null +++ b/mobile_app/assets/www/charges/tree.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/mobile_app/assets/www/charges/trefle.svg b/mobile_app/assets/www/charges/trefle.svg new file mode 100644 index 00000000..8180526b --- /dev/null +++ b/mobile_app/assets/www/charges/trefle.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/mobile_app/assets/www/charges/trefoil.svg b/mobile_app/assets/www/charges/trefoil.svg new file mode 100644 index 00000000..438c993e --- /dev/null +++ b/mobile_app/assets/www/charges/trefoil.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/triangle.svg b/mobile_app/assets/www/charges/triangle.svg new file mode 100644 index 00000000..0a06d67c --- /dev/null +++ b/mobile_app/assets/www/charges/triangle.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/mobile_app/assets/www/charges/trianglePierced.svg b/mobile_app/assets/www/charges/trianglePierced.svg new file mode 100644 index 00000000..6bbe2fc2 --- /dev/null +++ b/mobile_app/assets/www/charges/trianglePierced.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/mobile_app/assets/www/charges/trowel.svg b/mobile_app/assets/www/charges/trowel.svg new file mode 100644 index 00000000..b9533474 --- /dev/null +++ b/mobile_app/assets/www/charges/trowel.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/unicornRampant.svg b/mobile_app/assets/www/charges/unicornRampant.svg new file mode 100644 index 00000000..a3102dbc --- /dev/null +++ b/mobile_app/assets/www/charges/unicornRampant.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/wasp.svg b/mobile_app/assets/www/charges/wasp.svg new file mode 100644 index 00000000..9d54306c --- /dev/null +++ b/mobile_app/assets/www/charges/wasp.svg @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/wheatStalk.svg b/mobile_app/assets/www/charges/wheatStalk.svg new file mode 100644 index 00000000..c6113ccd --- /dev/null +++ b/mobile_app/assets/www/charges/wheatStalk.svg @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/wheel.svg b/mobile_app/assets/www/charges/wheel.svg new file mode 100644 index 00000000..6133eee9 --- /dev/null +++ b/mobile_app/assets/www/charges/wheel.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/windmill.svg b/mobile_app/assets/www/charges/windmill.svg new file mode 100644 index 00000000..b814ef1e --- /dev/null +++ b/mobile_app/assets/www/charges/windmill.svg @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/wing.svg b/mobile_app/assets/www/charges/wing.svg new file mode 100644 index 00000000..d38622f2 --- /dev/null +++ b/mobile_app/assets/www/charges/wing.svg @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/wingSword.svg b/mobile_app/assets/www/charges/wingSword.svg new file mode 100644 index 00000000..75c2f80e --- /dev/null +++ b/mobile_app/assets/www/charges/wingSword.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/wolfHeadErased.svg b/mobile_app/assets/www/charges/wolfHeadErased.svg new file mode 100644 index 00000000..518ea83f --- /dev/null +++ b/mobile_app/assets/www/charges/wolfHeadErased.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/wolfPassant.svg b/mobile_app/assets/www/charges/wolfPassant.svg new file mode 100644 index 00000000..06f8761a --- /dev/null +++ b/mobile_app/assets/www/charges/wolfPassant.svg @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/wolfRampant.svg b/mobile_app/assets/www/charges/wolfRampant.svg new file mode 100644 index 00000000..f5c7f57c --- /dev/null +++ b/mobile_app/assets/www/charges/wolfRampant.svg @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/wolfStatant.svg b/mobile_app/assets/www/charges/wolfStatant.svg new file mode 100644 index 00000000..d592b9ef --- /dev/null +++ b/mobile_app/assets/www/charges/wolfStatant.svg @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/wyvern.svg b/mobile_app/assets/www/charges/wyvern.svg new file mode 100644 index 00000000..f09b821e --- /dev/null +++ b/mobile_app/assets/www/charges/wyvern.svg @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/charges/wyvernWithWingsDisplayed.svg b/mobile_app/assets/www/charges/wyvernWithWingsDisplayed.svg new file mode 100644 index 00000000..d3aef9b4 --- /dev/null +++ b/mobile_app/assets/www/charges/wyvernWithWingsDisplayed.svg @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/components/fill-box.js b/mobile_app/assets/www/components/fill-box.js new file mode 100644 index 00000000..b4d075c3 --- /dev/null +++ b/mobile_app/assets/www/components/fill-box.js @@ -0,0 +1,74 @@ +{ + const style = /* css */ ` + fill-box:not([disabled]) { + cursor: pointer; + } + + fill-box > svg { + vertical-align: middle; + pointer-events: none; + } + + fill-box > svg > rect { + stroke: #666666; + stroke-width: 2; + } + `; + + const styleElement = document.createElement("style"); + styleElement.setAttribute("type", "text/css"); + styleElement.innerHTML = style; + document.head.appendChild(styleElement); +} + +{ + const template = document.createElement("template"); + template.innerHTML = /* html */ ` + + + + `; + + class FillBox extends HTMLElement { + constructor() { + super(); + + this.appendChild(template.content.cloneNode(true)); + this.querySelector("rect")?.setAttribute("fill", this.fill); + this.querySelector("svg")?.setAttribute("width", this.size); + this.querySelector("svg")?.setAttribute("height", this.size); + } + + static showTip() { + tip(this.tip); + } + + connectedCallback() { + this.addEventListener("mousemove", this.constructor.showTip); + } + + disconnectedCallback() { + this.removeEventListener("mousemove", this.constructor.showTip); + } + + get fill() { + return this.getAttribute("fill") || "#333"; + } + + set fill(newFill) { + this.setAttribute("fill", newFill); + this.querySelector("rect")?.setAttribute("fill", newFill); + } + + get size() { + return this.getAttribute("size") || "1em"; + } + + get tip() { + return this.dataset.tip || "Fill style. Click to change"; + } + } + + // cannot use Shadow DOM here as need an access to svg hatches + customElements.define("fill-box", FillBox); +} diff --git a/mobile_app/assets/www/components/slider-input.js b/mobile_app/assets/www/components/slider-input.js new file mode 100644 index 00000000..f1732027 --- /dev/null +++ b/mobile_app/assets/www/components/slider-input.js @@ -0,0 +1,78 @@ +{ + const style = /* css */ ` + slider-input { + display: flex; + align-items: center; + gap: .4em; + } + `; + + const styleElement = document.createElement("style"); + styleElement.setAttribute("type", "text/css"); + styleElement.innerHTML = style; + document.head.appendChild(styleElement); +} + +{ + const template = document.createElement("template"); + template.innerHTML = /* html */ ` + + + `; + + class SliderInput extends HTMLElement { + constructor() { + super(); + this.appendChild(template.content.cloneNode(true)); + + const range = this.querySelector("input[type=range]"); + const number = this.querySelector("input[type=number]"); + + range.value = number.value = this.value || this.getAttribute("value") || 50; + range.min = number.min = this.getAttribute("min") || 0; + range.max = number.max = this.getAttribute("max") || 100; + range.step = number.step = this.getAttribute("step") || 1; + + range.addEventListener("input", this.handleEvent.bind(this)); + number.addEventListener("input", this.handleEvent.bind(this)); + range.addEventListener("change", this.handleEvent.bind(this)); + number.addEventListener("change", this.handleEvent.bind(this)); + } + + handleEvent(e) { + const value = e.target.value; + const isNaN = Number.isNaN(Number(value)); + if (isNaN || value === "") return e.stopPropagation(); + + const range = this.querySelector("input[type=range]"); + const number = this.querySelector("input[type=number]"); + this.value = range.value = number.value = value; + + this.dispatchEvent( + new CustomEvent(e.type, { + detail: {value}, + bubbles: true, + composed: true + }) + ); + } + + set value(value) { + const range = this.querySelector("input[type=range]"); + const number = this.querySelector("input[type=number]"); + range.value = number.value = value; + } + + get value() { + const number = this.querySelector("input[type=number]"); + return number.value; + } + + get valueAsNumber() { + const number = this.querySelector("input[type=number]"); + return number.valueAsNumber; + } + } + + customElements.define("slider-input", SliderInput); +} diff --git a/mobile_app/assets/www/config/heightmap-templates.js b/mobile_app/assets/www/config/heightmap-templates.js new file mode 100644 index 00000000..29738609 --- /dev/null +++ b/mobile_app/assets/www/config/heightmap-templates.js @@ -0,0 +1,166 @@ +"use strict"; + +const heightmapTemplates = (function () { + const volcano = `Hill 1 90-100 44-56 40-60 + Multiply 0.8 50-100 0 0 + Range 1.5 30-55 45-55 40-60 + Smooth 3 0 0 0 + Hill 1.5 35-45 25-30 20-75 + Hill 1 35-55 75-80 25-75 + Hill 0.5 20-25 10-15 20-25 + Mask 3 0 0 0`; + + const highIsland = `Hill 1 90-100 65-75 47-53 + Add 7 all 0 0 + Hill 5-6 20-30 25-55 45-55 + Range 1 40-50 45-55 45-55 + Multiply 0.8 land 0 0 + Mask 3 0 0 0 + Smooth 2 0 0 0 + Trough 2-3 20-30 20-30 20-30 + Trough 2-3 20-30 60-80 70-80 + Hill 1 10-15 60-60 50-50 + Hill 1.5 13-16 15-20 20-75 + Range 1.5 30-40 15-85 30-40 + Range 1.5 30-40 15-85 60-70 + Pit 3-5 10-30 15-85 20-80`; + + const lowIsland = `Hill 1 90-99 60-80 45-55 + Hill 1-2 20-30 10-30 10-90 + Smooth 2 0 0 0 + Hill 6-7 25-35 20-70 30-70 + Range 1 40-50 45-55 45-55 + Trough 2-3 20-30 15-85 20-30 + Trough 2-3 20-30 15-85 70-80 + Hill 1.5 10-15 5-15 20-80 + Hill 1 10-15 85-95 70-80 + Pit 5-7 15-25 15-85 20-80 + Multiply 0.4 20-100 0 0 + Mask 4 0 0 0`; + + const continents = `Hill 1 80-85 60-80 40-60 + Hill 1 80-85 20-30 40-60 + Hill 6-7 15-30 25-75 15-85 + Multiply 0.6 land 0 0 + Hill 8-10 5-10 15-85 20-80 + Range 1-2 30-60 5-15 25-75 + Range 1-2 30-60 80-95 25-75 + Range 0-3 30-60 80-90 20-80 + Strait 2 vertical 0 0 + Strait 1 vertical 0 0 + Smooth 3 0 0 0 + Trough 3-4 15-20 15-85 20-80 + Trough 3-4 5-10 45-55 45-55 + Pit 3-4 10-20 15-85 20-80 + Mask 4 0 0 0`; + + const archipelago = `Add 11 all 0 0 + Range 2-3 40-60 20-80 20-80 + Hill 5 15-20 10-90 30-70 + Hill 2 10-15 10-30 20-80 + Hill 2 10-15 60-90 20-80 + Smooth 3 0 0 0 + Trough 10 20-30 5-95 5-95 + Strait 2 vertical 0 0 + Strait 2 horizontal 0 0`; + + const atoll = `Hill 1 75-80 50-60 45-55 + Hill 1.5 30-50 25-75 30-70 + Hill .5 30-50 25-35 30-70 + Smooth 1 0 0 0 + Multiply 0.2 25-100 0 0 + Hill 0.5 10-20 50-55 48-52`; + + const mediterranean = `Range 4-6 30-80 0-100 0-10 + Range 4-6 30-80 0-100 90-100 + Hill 6-8 30-50 10-90 0-5 + Hill 6-8 30-50 10-90 95-100 + Multiply 0.9 land 0 0 + Mask -2 0 0 0 + Smooth 1 0 0 0 + Hill 2-3 30-70 0-5 20-80 + Hill 2-3 30-70 95-100 20-80 + Trough 3-6 40-50 0-100 0-10 + Trough 3-6 40-50 0-100 90-100`; + + const peninsula = `Range 2-3 20-35 40-50 0-15 + Add 5 all 0 0 + Hill 1 90-100 10-90 0-5 + Add 13 all 0 0 + Hill 3-4 3-5 5-95 80-100 + Hill 1-2 3-5 5-95 40-60 + Trough 5-6 10-25 5-95 5-95 + Smooth 3 0 0 0 + Invert 0.4 both 0 0`; + + const pangea = `Hill 1-2 25-40 15-50 0-10 + Hill 1-2 5-40 50-85 0-10 + Hill 1-2 25-40 50-85 90-100 + Hill 1-2 5-40 15-50 90-100 + Hill 8-12 20-40 20-80 48-52 + Smooth 2 0 0 0 + Multiply 0.7 land 0 0 + Trough 3-4 25-35 5-95 10-20 + Trough 3-4 25-35 5-95 80-90 + Range 5-6 30-40 10-90 35-65`; + + const isthmus = `Hill 5-10 15-30 0-30 0-20 + Hill 5-10 15-30 10-50 20-40 + Hill 5-10 15-30 30-70 40-60 + Hill 5-10 15-30 50-90 60-80 + Hill 5-10 15-30 70-100 80-100 + Smooth 2 0 0 0 + Trough 4-8 15-30 0-30 0-20 + Trough 4-8 15-30 10-50 20-40 + Trough 4-8 15-30 30-70 40-60 + Trough 4-8 15-30 50-90 60-80 + Trough 4-8 15-30 70-100 80-100 + Invert 0.25 x 0 0`; + + const shattered = `Hill 8 35-40 15-85 30-70 + Trough 10-20 40-50 5-95 5-95 + Range 5-7 30-40 10-90 20-80 + Pit 12-20 30-40 15-85 20-80`; + + const taklamakan = `Hill 1-3 20-30 30-70 30-70 + Hill 2-4 60-85 0-5 0-100 + Hill 2-4 60-85 95-100 0-100 + Hill 3-4 60-85 20-80 0-5 + Hill 3-4 60-85 20-80 95-100 + Smooth 3 0 0 0`; + + const oldWorld = `Range 3 70 15-85 20-80 + Hill 2-3 50-70 15-45 20-80 + Hill 2-3 50-70 65-85 20-80 + Hill 4-6 20-25 15-85 20-80 + Multiply 0.5 land 0 0 + Smooth 2 0 0 0 + Range 3-4 20-50 15-35 20-45 + Range 2-4 20-50 65-85 45-80 + Strait 3-7 vertical 0 0 + Trough 6-8 20-50 15-85 45-65 + Pit 5-6 20-30 10-90 10-90`; + + const fractious = `Hill 12-15 50-80 5-95 5-95 + Mask -1.5 0 0 0 + Mask 3 0 0 0 + Add -20 30-100 0 0 + Range 6-8 40-50 5-95 10-90`; + + return { + volcano: {id: 0, name: "Volcano", template: volcano, probability: 3}, + highIsland: {id: 1, name: "High Island", template: highIsland, probability: 19}, + lowIsland: {id: 2, name: "Low Island", template: lowIsland, probability: 9}, + continents: {id: 3, name: "Continents", template: continents, probability: 16}, + archipelago: {id: 4, name: "Archipelago", template: archipelago, probability: 18}, + atoll: {id: 5, name: "Atoll", template: atoll, probability: 1}, + mediterranean: {id: 6, name: "Mediterranean", template: mediterranean, probability: 5}, + peninsula: {id: 7, name: "Peninsula", template: peninsula, probability: 3}, + pangea: {id: 8, name: "Pangea", template: pangea, probability: 5}, + isthmus: {id: 9, name: "Isthmus", template: isthmus, probability: 2}, + shattered: {id: 10, name: "Shattered", template: shattered, probability: 7}, + taklamakan: {id: 11, name: "Taklamakan", template: taklamakan, probability: 1}, + oldWorld: {id: 12, name: "Old World", template: oldWorld, probability: 8}, + fractious: {id: 13, name: "Fractious", template: fractious, probability: 3} + }; +})(); diff --git a/mobile_app/assets/www/config/precreated-heightmaps.js b/mobile_app/assets/www/config/precreated-heightmaps.js new file mode 100644 index 00000000..22f45abd --- /dev/null +++ b/mobile_app/assets/www/config/precreated-heightmaps.js @@ -0,0 +1,27 @@ +"use strict"; + +const precreatedHeightmaps = { + "africa-centric": {id: 0, name: "Africa Centric"}, + arabia: {id: 1, name: "Arabia"}, + atlantics: {id: 2, name: "Atlantics"}, + britain: {id: 3, name: "Britain"}, + caribbean: {id: 4, name: "Caribbean"}, + "east-asia": {id: 5, name: "East Asia"}, + eurasia: {id: 6, name: "Eurasia"}, + europe: {id: 7, name: "Europe"}, + "europe-accented": {id: 8, name: "Europe Accented"}, + "europe-and-central-asia": {id: 9, name: "Europe and Central Asia"}, + "europe-central": {id: 10, name: "Europe Central"}, + "europe-north": {id: 11, name: "Europe North"}, + greenland: {id: 12, name: "Greenland"}, + hellenica: {id: 13, name: "Hellenica"}, + iceland: {id: 14, name: "Iceland"}, + "indian-ocean": {id: 15, name: "Indian Ocean"}, + "mediterranean-sea": {id: 16, name: "Mediterranean Sea"}, + "middle-east": {id: 17, name: "Middle East"}, + "north-america": {id: 18, name: "North America"}, + "us-centric": {id: 19, name: "US-centric"}, + "us-mainland": {id: 20, name: "US Mainland"}, + world: {id: 21, name: "World"}, + "world-from-pacific": {id: 22, name: "World from Pacific"} +}; diff --git a/mobile_app/assets/www/dropbox.html b/mobile_app/assets/www/dropbox.html new file mode 100644 index 00000000..cd1921da --- /dev/null +++ b/mobile_app/assets/www/dropbox.html @@ -0,0 +1,48 @@ + + + + + + FMG Dropbox Auth + + + + + diff --git a/mobile_app/assets/www/engine/engine.html b/mobile_app/assets/www/engine/engine.html new file mode 100644 index 00000000..75db1b3b --- /dev/null +++ b/mobile_app/assets/www/engine/engine.html @@ -0,0 +1,17 @@ + + + + + + Fantasy Map Engine (WebGL) + + + + + + + + diff --git a/mobile_app/assets/www/heightmaps/africa-centric.png b/mobile_app/assets/www/heightmaps/africa-centric.png new file mode 100644 index 00000000..02e4a311 Binary files /dev/null and b/mobile_app/assets/www/heightmaps/africa-centric.png differ diff --git a/mobile_app/assets/www/heightmaps/arabia.png b/mobile_app/assets/www/heightmaps/arabia.png new file mode 100644 index 00000000..27946711 Binary files /dev/null and b/mobile_app/assets/www/heightmaps/arabia.png differ diff --git a/mobile_app/assets/www/heightmaps/atlantics.png b/mobile_app/assets/www/heightmaps/atlantics.png new file mode 100644 index 00000000..be123705 Binary files /dev/null and b/mobile_app/assets/www/heightmaps/atlantics.png differ diff --git a/mobile_app/assets/www/heightmaps/britain.png b/mobile_app/assets/www/heightmaps/britain.png new file mode 100644 index 00000000..60e08da4 Binary files /dev/null and b/mobile_app/assets/www/heightmaps/britain.png differ diff --git a/mobile_app/assets/www/heightmaps/caribbean.png b/mobile_app/assets/www/heightmaps/caribbean.png new file mode 100644 index 00000000..e4a8ed05 Binary files /dev/null and b/mobile_app/assets/www/heightmaps/caribbean.png differ diff --git a/mobile_app/assets/www/heightmaps/east-asia.png b/mobile_app/assets/www/heightmaps/east-asia.png new file mode 100644 index 00000000..41144db5 Binary files /dev/null and b/mobile_app/assets/www/heightmaps/east-asia.png differ diff --git a/mobile_app/assets/www/heightmaps/eurasia.png b/mobile_app/assets/www/heightmaps/eurasia.png new file mode 100644 index 00000000..bdbdb4d7 Binary files /dev/null and b/mobile_app/assets/www/heightmaps/eurasia.png differ diff --git a/mobile_app/assets/www/heightmaps/europe-accented.png b/mobile_app/assets/www/heightmaps/europe-accented.png new file mode 100644 index 00000000..9be9480e Binary files /dev/null and b/mobile_app/assets/www/heightmaps/europe-accented.png differ diff --git a/mobile_app/assets/www/heightmaps/europe-and-central-asia.png b/mobile_app/assets/www/heightmaps/europe-and-central-asia.png new file mode 100644 index 00000000..c23e97ed Binary files /dev/null and b/mobile_app/assets/www/heightmaps/europe-and-central-asia.png differ diff --git a/mobile_app/assets/www/heightmaps/europe-central.png b/mobile_app/assets/www/heightmaps/europe-central.png new file mode 100644 index 00000000..b220f546 Binary files /dev/null and b/mobile_app/assets/www/heightmaps/europe-central.png differ diff --git a/mobile_app/assets/www/heightmaps/europe-north.png b/mobile_app/assets/www/heightmaps/europe-north.png new file mode 100644 index 00000000..1bb49184 Binary files /dev/null and b/mobile_app/assets/www/heightmaps/europe-north.png differ diff --git a/mobile_app/assets/www/heightmaps/europe.png b/mobile_app/assets/www/heightmaps/europe.png new file mode 100644 index 00000000..59dfdfea Binary files /dev/null and b/mobile_app/assets/www/heightmaps/europe.png differ diff --git a/mobile_app/assets/www/heightmaps/greenland.png b/mobile_app/assets/www/heightmaps/greenland.png new file mode 100644 index 00000000..3136c539 Binary files /dev/null and b/mobile_app/assets/www/heightmaps/greenland.png differ diff --git a/mobile_app/assets/www/heightmaps/hellenica.png b/mobile_app/assets/www/heightmaps/hellenica.png new file mode 100644 index 00000000..2681d6ec Binary files /dev/null and b/mobile_app/assets/www/heightmaps/hellenica.png differ diff --git a/mobile_app/assets/www/heightmaps/iceland.png b/mobile_app/assets/www/heightmaps/iceland.png new file mode 100644 index 00000000..88463158 Binary files /dev/null and b/mobile_app/assets/www/heightmaps/iceland.png differ diff --git a/mobile_app/assets/www/heightmaps/import-rules.txt b/mobile_app/assets/www/heightmaps/import-rules.txt new file mode 100644 index 00000000..69499114 --- /dev/null +++ b/mobile_app/assets/www/heightmaps/import-rules.txt @@ -0,0 +1,8 @@ +To get heightmap with correct height scale: +1. Open https://tangrams.github.io/heightmapper +2. Toggle off auto-exposure +3. Set max elevation to 2000 +4. Set min elevation to -500 +5. Find region you like +6. Render image +7. Optionally rescale image to a smaller size (e.g. 500x300px) as high resolution is not used diff --git a/mobile_app/assets/www/heightmaps/indian-ocean.png b/mobile_app/assets/www/heightmaps/indian-ocean.png new file mode 100644 index 00000000..860ca952 Binary files /dev/null and b/mobile_app/assets/www/heightmaps/indian-ocean.png differ diff --git a/mobile_app/assets/www/heightmaps/mediterranean-sea.png b/mobile_app/assets/www/heightmaps/mediterranean-sea.png new file mode 100644 index 00000000..6a7c8bb3 Binary files /dev/null and b/mobile_app/assets/www/heightmaps/mediterranean-sea.png differ diff --git a/mobile_app/assets/www/heightmaps/middle-east.png b/mobile_app/assets/www/heightmaps/middle-east.png new file mode 100644 index 00000000..bfcc55bb Binary files /dev/null and b/mobile_app/assets/www/heightmaps/middle-east.png differ diff --git a/mobile_app/assets/www/heightmaps/north-america.png b/mobile_app/assets/www/heightmaps/north-america.png new file mode 100644 index 00000000..1c1f1ad5 Binary files /dev/null and b/mobile_app/assets/www/heightmaps/north-america.png differ diff --git a/mobile_app/assets/www/heightmaps/us-centric.png b/mobile_app/assets/www/heightmaps/us-centric.png new file mode 100644 index 00000000..7094df6a Binary files /dev/null and b/mobile_app/assets/www/heightmaps/us-centric.png differ diff --git a/mobile_app/assets/www/heightmaps/us-mainland.png b/mobile_app/assets/www/heightmaps/us-mainland.png new file mode 100644 index 00000000..3b1984e7 Binary files /dev/null and b/mobile_app/assets/www/heightmaps/us-mainland.png differ diff --git a/mobile_app/assets/www/heightmaps/world-from-pacific.png b/mobile_app/assets/www/heightmaps/world-from-pacific.png new file mode 100644 index 00000000..02043165 Binary files /dev/null and b/mobile_app/assets/www/heightmaps/world-from-pacific.png differ diff --git a/mobile_app/assets/www/heightmaps/world.png b/mobile_app/assets/www/heightmaps/world.png new file mode 100644 index 00000000..22a79298 Binary files /dev/null and b/mobile_app/assets/www/heightmaps/world.png differ diff --git a/mobile_app/assets/www/icons.css b/mobile_app/assets/www/icons.css new file mode 100644 index 00000000..4740f091 --- /dev/null +++ b/mobile_app/assets/www/icons.css @@ -0,0 +1,290 @@ +/* FontAwesome icons, see license https://github.com/FortAwesome/Font-Awesome/blob/master/LICENSE.txt */ +@font-face { + font-family: 'icons'; + src: url('data:application/font-woff2;base64,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 ') format('woff2'); + font-weight: normal; + font-style: normal; +} + + [class^="icon-"]:before, [class*=" icon-"]:before, [class^="icon-"]:after, [class*=" icon-"]:after { + font-family: "icons"; + font-style: normal; + font-weight: normal; + display: inline-block; + text-decoration: inherit; + width: 1em; + text-align: center; + font-size: 1em; + margin: -1px; + padding: 0; + + /* For safety - reset parent styles, that can break glyph codes*/ + font-variant: normal; + text-transform: none; + line-height: 1em; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +/* Font Awesome icons */ +.icon-pencil:before {content:'\e800';} /* '' */ +.icon-font:before {content:'\e801';} /* '' */ +.icon-arrows-cw:before {content:'\e802';} /* '' */ +.icon-doc:before {content:'\e803';} /* '' */ +.icon-trash-empty:before {content:'\e804';} /* '' */ +.icon-ok:before {content:'\e805';} /* '' */ +.icon-ok-circled:before {content:'\e806';} /* '' */ +.icon-ok-circled2:before {content:'\e807';} /* '' */ +.icon-link:before {content:'\e808';} /* '' */ +.icon-globe:before {content:'\e809';} /* '' */ +.icon-plus:before {content:'\e80a';} /* '' */ +.icon-plus-circled:before {content:'\e80b';} /* '' */ +.icon-minus-circled:before {content:'\e80c';} /* '' */ +.icon-minus:before {content:'\e80d';} /* '' */ +.icon-text-height:before {content:'\e80e';} /* '' */ +.icon-adjust:before {content:'\e80f';} /* '' */ +.icon-tag:before {content:'\e810';} /* '' */ +.icon-tags:before {content:'\e811';} /* '' */ +.icon-logout:before {content:'\e812';} /* '' */ +.icon-download:before {content:'\e813';} /* '' */ +.icon-down-circled2:before {content:'\e814';} /* '' */ +.icon-upload:before {content:'\e815';} /* '' */ +.icon-up-circled2:before {content:'\e816';} /* '' */ +.icon-cancel-circled2:before {content:'\e817';} /* '' */ +.icon-cancel-circled:before {content:'\e818';} /* '' */ +.icon-cancel:before {content:'\e819';} /* '' */ +.icon-check:before {content:'\e81a';} /* '' */ +.icon-align-left:before {content:'\e81b';} /* '' */ +.icon-align-center:before {content:'\e81c';} /* '' */ +.icon-align-right:before {content:'\e81d';} /* '' */ +.icon-align-justify:before {content:'\e81e';} /* '' */ +.icon-star:before {content:'\e81f';} /* '' */ +.icon-star-empty:before {content:'\e820';} /* '' */ +.icon-search:before {content:'\e821';} /* '' */ +.icon-mail:before {content:'\e822';} /* '' */ +.icon-eye:before {content:'\e823';} /* '' */ +.icon-eye-off:before {content:'\e824';} /* '' */ +.icon-pin:before {content:'\e825';} /* '' */ +.icon-lock-open:before {content:'\e826';} /* '' */ +.icon-lock:before {content:'\e827';} /* '' */ +.icon-attach:before {content:'\e828';} /* '' */ +.icon-home:before {content:'\e829';} /* '' */ +.icon-info-circled:before {content:'\e82a';} /* '' */ +.icon-help-circled:before {content:'\e82b';} /* '' */ +.icon-shuffle:before {content:'\e82c';} /* '' */ +.icon-ccw:before {content:'\e82d';} /* '' */ +.icon-cw:before {content:'\e82e';} /* '' */ +.icon-play:before {content:'\e82f';} /* '' */ +.icon-play-circled2:before {content:'\e830';} /* '' */ +.icon-down-big:before {content:'\e831';} /* '' */ +.icon-left-big:before {content:'\e832';} /* '' */ +.icon-right-big:before {content:'\e833';} /* '' */ +.icon-up-big:before {content:'\e834';} /* '' */ +.icon-up-open:before {content:'\e835';} /* '' */ +.icon-right-open:before {content:'\e836';} /* '' */ +.icon-left-open:before {content:'\e837';} /* '' */ +.icon-down-open:before {content:'\e838';} /* '' */ +.icon-cloud:before {content:'\e839';} /* '' */ +.icon-text-width:before {content:'\e83a';} /* '' */ +.icon-italic:before {content:'\e83b';} /* '' */ +.icon-bold:before {content:'\e83c';} /* '' */ +.icon-retweet:before {content:'\e83d';} /* '' */ +.icon-user:before {content:'\e83e';} /* '' */ +.icon-users:before {content:'\e83f';} /* '' */ +.icon-flag:before {content:'\e840';} /* '' */ +.icon-heart:before {content:'\e841';} /* '' */ +.icon-heart-empty:before {content:'\e842';} /* '' */ +.icon-edit:before {content:'\e843';} /* '' */ +.icon-export:before {content:'\e844';} /* '' */ +.icon-cog:before {content:'\e845';} /* '' */ +.icon-cog-alt:before {content:'\e846';} /* '' */ +.icon-wrench:before {content:'\e847';} /* '' */ +.icon-resize-vertical:before {content:'\e848';} /* '' */ +.icon-resize-small:before {content:'\e849';} /* '' */ +.icon-resize-full:before {content:'\e84a';} /* '' */ +.icon-resize-horizontal:before {content:'\e84b';} /* '' */ +.icon-target:before {content:'\e84c';} /* '' */ +.icon-signal:before {content:'\e84d';} /* '' */ +.icon-umbrella:before {content:'\e84e';} /* '' */ +.icon-leaf:before {content:'\e84f';} /* '' */ +.icon-book:before {content:'\e850';} /* '' */ +.icon-asterisk:before {content:'\e851';} /* '' */ +.icon-chart-bar:before {content:'\e852';} /* '' */ +.icon-key:before {content:'\e853';} /* '' */ +.icon-hammer:before {content:'\e854';} /* '' */ +.icon-star-half:before {content:'\e855';} /* '' */ +.icon-move:before {content:'\f047';} /* '' */ +.icon-expand-1:before {content:'\f065';} /* '' */ +.icon-link-ext:before {content:'\f08e';} /* '' */ +.icon-check-empty:before {content:'\f096';} /* '' */ +.icon-resize-full-alt:before {content:'\f0b2';} /* '' */ +.icon-flask:before {content:'\f0c3';} /* '' */ +.icon-docs:before {content:'\f0c5';} /* '' */ +.icon-list-bullet:before {content:'\f0ca';} /* '' */ +.icon-mail-alt:before {content:'\f0e0';} /* '' */ +.icon-sitemap:before {content:'\f0e8';} /* '' */ +.icon-exchange:before {content:'\f0ec';} /* '' */ +.icon-download-cloud:before {content:'\f0ed';} /* '' */ +.icon-upload-cloud:before {content:'\f0ee';} /* '' */ +.icon-plus-squared:before {content:'\f0fe';} /* '' */ +.icon-circle-empty:before {content:'\f10c';} /* '' */ +.icon-folder-empty:before {content:'\f114';} /* '' */ +.icon-folder-open-empty:before {content:'\f115';} /* '' */ +.icon-flag-empty:before {content:'\f11d';} /* '' */ +.icon-star-half-alt:before {content:'\f123';} /* '' */ +.icon-fork:before {content:'\f126';} /* '' */ +.icon-unlink:before {content:'\f127';} /* '' */ +.icon-help:before {content:'\f128';} /* '' */ +.icon-info:before {content:'\f129';} /* '' */ +.icon-eraser:before {content:'\f12d';} /* '' */ +.icon-rocket:before {content:'\f135';} /* '' */ +.icon-anchor:before {content:'\f13d';} /* '' */ +.icon-lock-open-alt:before {content:'\f13e';} /* '' */ +.icon-play-circled:before {content:'\f144';} /* '' */ +.icon-minus-squared:before {content:'\f146';} /* '' */ +.icon-minus-squared-alt:before {content:'\f147';} /* '' */ +.icon-level-up:before {content:'\f148';} /* '' */ +.icon-level-down:before {content:'\f149';} /* '' */ +.icon-ok-squared:before {content:'\f14a';} /* '' */ +.icon-pencil-squared:before {content:'\f14b';} /* '' */ +.icon-compass:before {content:'\f14e';} /* '' */ +.icon-expand:before {content:'\f150';} /* '' */ +.icon-collapse:before {content:'\f151';} /* '' */ +.icon-expand-right:before {content:'\f152';} /* '' */ +.icon-sort-alt-up:before {content:'\f160';} /* '' */ +.icon-sort-alt-down:before {content:'\f161';} /* '' */ +.icon-female:before {content:'\f182';} /* '' */ +.icon-male:before {content:'\f183';} /* '' */ +.icon-sun:before {content:'\f185';} /* '' */ +.icon-box:before {content:'\f187';} /* '' */ +.icon-bug:before {content:'\f188';} /* '' */ +.icon-right-circled2:before {content:'\f18e';} /* '' */ +.icon-left-circled2:before {content:'\f190';} /* '' */ +.icon-collapse-left:before {content:'\f191';} /* '' */ +.icon-dot-circled:before {content:'\f192';} /* '' */ +.icon-plus-squared-alt:before {content:'\f196';} /* '' */ +.icon-bank:before {content:'\f19c';} /* '' */ +.icon-child:before {content:'\f1ae';} /* '' */ +.icon-paw:before {content:'\f1b0';} /* '' */ +.icon-tree:before {content:'\f1bb';} /* '' */ +.icon-history:before {content:'\f1da';} /* '' */ +.icon-header:before {content:'\f1dc';} /* '' */ +.icon-sliders:before {content:'\f1de';} /* '' */ +.icon-trash:before {content:'\f1f8';} /* '' */ +.icon-brush:before {content:'\f1fc';} /* '' */ +.icon-chart-area:before {content:'\f1fe';} /* '' */ +.icon-chart-pie:before {content:'\f200';} /* '' */ +.icon-chart-line:before {content:'\f201';} /* '' */ +.icon-ship:before {content:'\f21a';} /* '' */ +.icon-user-secret:before {content:'\f21b';} /* '' */ +.icon-venus:before {content:'\f221';} /* '' */ +.icon-mars:before {content:'\f222';} /* '' */ +.icon-venus-mars:before {content:'\f228';} /* '' */ +.icon-neuter:before {content:'\f22c';} /* '' */ +.icon-user-plus:before {content:'\f234';} /* '' */ +.icon-user-times:before {content:'\f235';} /* '' */ +.icon-object-ungroup:before {content:'\f248';} /* '' */ +.icon-clone:before {content:'\f24d';} /* '' */ +.icon-balance-scale:before {content:'\f24e';} /* '' */ +.icon-hourglass-1:before {content:'\f251';} /* '' */ +.icon-hand-grab-o:before {content:'\f255';} /* '' */ +.icon-hand-paper-o:before {content:'\f256';} /* '' */ +.icon-wikipedia-w:before {content:'\f266';} /* '' */ +.icon-calendar-check-o:before {content:'\f274';} /* '' */ +.icon-map-pin:before {content:'\f276';} /* '' */ +.icon-map-signs:before {content:'\f277';} /* '' */ +.icon-map-o:before {content:'\f278';} /* '' */ +.icon-map:before {content:'\f279';} /* '' */ +.icon-fort-awesome:before {content:'\f286';} /* '' */ +.icon-percent:before {content:'\f295';} /* '' */ +.icon-shield-alt:before {content:'\f3ed';} /* '' */ +.icon-chess-bishop:before {content:'\f43a';} /* '' */ +.icon-chess-king:before {content:'\f43f';} /* '' */ +.icon-chess-knight:before {content:'\f441';} /* '' */ +.icon-chess-pawn:before {content:'\f443';} /* '' */ +.icon-chess-queen:before {content:'\f445';} /* '' */ +.icon-chess-rook:before {content:'\f447';} /* '' */ +.icon-sign:before {content:'\f4d9';} /* '' */ +.icon-user-friends:before {content:'\f500';} /* '' */ +.icon-user-shield:before {content:'\f505';} /* '' */ +.icon-crow:before {content:'\f520';} /* '' */ +.icon-crown:before {content:'\f521';} /* '' */ +.icon-ruler:before {content:'\f545';} /* '' */ +.icon-store:before {content:'\f54e';} /* '' */ +.icon-bezier-curve:before {content:'\f55b';} /* '' */ +.icon-drafting-compass:before {content:'\f568';} /* '' */ +.icon-globe-africa:before {content:'\f57c';} /* '' */ +.icon-monument:before {content:'\f5a6';} /* '' */ +.icon-mortar-pestle:before {content:'\f5a7';} /* '' */ +.icon-paint-roller:before {content:'\f5aa';} /* '' */ +.icon-pen-fancy:before {content:'\f5ac';} /* '' */ +.icon-pen-nib:before {content:'\f5ad';} /* '' */ +.icon-pencil-ruler:before {content:'\f5ae';} /* '' */ +.icon-draw-polygon:before {content:'\f5ee';} /* '' */ +.icon-layer-group:before {content:'\f5fd';} /* '' */ +.icon-menorah:before {content:'\f676';} /* '' */ +.icon-mosque:before {content:'\f678';} /* '' */ +.icon-place-of-worship:before {content:'\f67f';} /* '' */ +.icon-synagogue:before {content:'\f69b';} /* '' */ +.icon-book-dead:before {content:'\f6b7';} /* '' */ +.icon-campground:before {content:'\f6bb';} /* '' */ +.icon-mountain:before {content:'\f6fc';} /* '' */ +.icon-network-wired:before {content:'\f6ff';} /* '' */ +.icon-temperature-high:before {content:'\f769';} /* '' */ +.icon-temperature-low:before {content:'\f76b';} /* '' */ + +/* Amended FA icons */ +.icon-sort-name-up:after {font-size:.9em;content:'\f15d';} +.icon-sort-name-down:after {font-size:.9em;content:'\f15e';} +.icon-sort-number-up:after {font-size:.9em;content:'\f162';} +.icon-sort-number-down:after {font-size:.9em;content:'\f163';} + +/* Custom icons */ +.icon-w:before {font-style:italic;content:'w:';} +.icon-f:before {font-style:italic;content:'f:';} +.icon-n:before {font-style:italic;content:'n:';} +.icon-i:before {font-style:italic;content:'i:';} +.icon-s:before {font-style:italic;content:'s:';} +.icon-r:before {font-style:italic;content:'r:';} +.icon-a:before {font-style:italic;content:'a:';} +.icon-smooth:before {font-weight: bold;content:'∼';} +.icon-disrupt:before {font-weight: bold;content:'⥄';} +.icon-if:before {font-style: italic; font-weight: bold;content:'if';} +.icon-coa:before {content:'\f3ed'; font-size: .9em; color: #999;} /* '' */ +.icon-half:before {font-weight: bold;content:'½';} +.icon-voice:before {content:'🔊';} +.icon-robot:before {content:'🤖';} +.icon-die:before {content:'🎲';} +.icon-button-die:before {content:'🎲'; padding-right: .4em;} +.icon-button-power:before {content:'💪'; padding-right: .6em;} + +.icon-button-melee:before {content:'⚔️'; padding-right: .4em;} +.icon-button-skirmish:before {content:'🎯'; padding-right: .4em;} +.icon-button-pursue:before {content:'🐎'; padding-right: .4em;} +.icon-button-retreat:before {content:'🏳️'; padding-right: .4em;} +.icon-button-shelling:before {content:'💣'; padding-right: .4em;} +.icon-button-boarding:before {content:'⚔️'; padding-right: .4em;} +.icon-button-chase:before {content:'⛵'; padding-right: .4em;} +.icon-button-withdrawal:before {content:'🏳️'; padding-right: .4em;} +.icon-button-bombardment:before {content:'💣'; padding-right: .4em;} +.icon-button-blockade:before {content:'⏳'; padding-right: .4em;} +.icon-button-sheltering:before {content:'🔒'; padding-right: .4em;} +.icon-button-sortie:before {content:'🚪'; padding-right: .4em;} +.icon-button-defense:before {content:'🛡️'; padding-right: .4em;} +.icon-button-storming:before {content:'⚔️'; padding-right: .4em;} +.icon-button-looting:before {content:'☠️'; padding-right: .4em;} +.icon-button-surrendering:before {content:'🏳️'; padding-right: .4em;} +.icon-button-surprise:before {content:'⚡'; padding-right: .4em;} +.icon-button-shock:before {content:'💫'; padding-right: .4em;} +.icon-button-flee:before {content:'⛵'; padding-right: .4em;} +.icon-button-waiting:before {content:'⌛'; padding-right: .4em;} +.icon-button-maneuvering:before {content:'💢'; padding-right: .4em;} +.icon-button-dogfight:before {content:'🐕'; padding-right: .4em;} + +.icon-button-field:before {content:'🗡️'; padding-right: .4em;} +.icon-button-naval:before {content:'🌊'; padding-right: .4em;} +.icon-button-siege:before {content:'🏰'; padding-right: .4em;} +.icon-button-ambush:before {content:'🌳'; padding-right: .4em;} +.icon-button-landing:before {content:'⚓'; padding-right: .4em;} +.icon-button-air:before {content:'💨'; padding-right: .4em;} +.icon-button-screenshot:before {content:'🖥️'; padding-right: .4em;} diff --git a/mobile_app/assets/www/images/Discord.png b/mobile_app/assets/www/images/Discord.png new file mode 100644 index 00000000..78dab317 Binary files /dev/null and b/mobile_app/assets/www/images/Discord.png differ diff --git a/mobile_app/assets/www/images/Facebook.png b/mobile_app/assets/www/images/Facebook.png new file mode 100644 index 00000000..3d249fd9 Binary files /dev/null and b/mobile_app/assets/www/images/Facebook.png differ diff --git a/mobile_app/assets/www/images/Pinterest.png b/mobile_app/assets/www/images/Pinterest.png new file mode 100644 index 00000000..fcc85914 Binary files /dev/null and b/mobile_app/assets/www/images/Pinterest.png differ diff --git a/mobile_app/assets/www/images/Reddit.png b/mobile_app/assets/www/images/Reddit.png new file mode 100644 index 00000000..4637f3a4 Binary files /dev/null and b/mobile_app/assets/www/images/Reddit.png differ diff --git a/mobile_app/assets/www/images/Twitter.png b/mobile_app/assets/www/images/Twitter.png new file mode 100644 index 00000000..05e0c2c2 Binary files /dev/null and b/mobile_app/assets/www/images/Twitter.png differ diff --git a/mobile_app/assets/www/images/icons/favicon-16x16.png b/mobile_app/assets/www/images/icons/favicon-16x16.png new file mode 100644 index 00000000..ddd75b4a Binary files /dev/null and b/mobile_app/assets/www/images/icons/favicon-16x16.png differ diff --git a/mobile_app/assets/www/images/icons/favicon-32x32.png b/mobile_app/assets/www/images/icons/favicon-32x32.png new file mode 100644 index 00000000..13e5179d Binary files /dev/null and b/mobile_app/assets/www/images/icons/favicon-32x32.png differ diff --git a/mobile_app/assets/www/images/icons/icon_x512.png b/mobile_app/assets/www/images/icons/icon_x512.png new file mode 100644 index 00000000..f1f8c9aa Binary files /dev/null and b/mobile_app/assets/www/images/icons/icon_x512.png differ diff --git a/mobile_app/assets/www/images/icons/maskable_icon_x128.png b/mobile_app/assets/www/images/icons/maskable_icon_x128.png new file mode 100644 index 00000000..fa877d1b Binary files /dev/null and b/mobile_app/assets/www/images/icons/maskable_icon_x128.png differ diff --git a/mobile_app/assets/www/images/icons/maskable_icon_x192.png b/mobile_app/assets/www/images/icons/maskable_icon_x192.png new file mode 100644 index 00000000..3322eab3 Binary files /dev/null and b/mobile_app/assets/www/images/icons/maskable_icon_x192.png differ diff --git a/mobile_app/assets/www/images/icons/maskable_icon_x384.png b/mobile_app/assets/www/images/icons/maskable_icon_x384.png new file mode 100644 index 00000000..c7e7e705 Binary files /dev/null and b/mobile_app/assets/www/images/icons/maskable_icon_x384.png differ diff --git a/mobile_app/assets/www/images/icons/maskable_icon_x512.png b/mobile_app/assets/www/images/icons/maskable_icon_x512.png new file mode 100644 index 00000000..5b2361fd Binary files /dev/null and b/mobile_app/assets/www/images/icons/maskable_icon_x512.png differ diff --git a/mobile_app/assets/www/images/kiwiroo.png b/mobile_app/assets/www/images/kiwiroo.png new file mode 100644 index 00000000..4f34ae7e Binary files /dev/null and b/mobile_app/assets/www/images/kiwiroo.png differ diff --git a/mobile_app/assets/www/images/pattern1.png b/mobile_app/assets/www/images/pattern1.png new file mode 100644 index 00000000..59375796 Binary files /dev/null and b/mobile_app/assets/www/images/pattern1.png differ diff --git a/mobile_app/assets/www/images/pattern2.png b/mobile_app/assets/www/images/pattern2.png new file mode 100644 index 00000000..e96f68fa Binary files /dev/null and b/mobile_app/assets/www/images/pattern2.png differ diff --git a/mobile_app/assets/www/images/pattern3.png b/mobile_app/assets/www/images/pattern3.png new file mode 100644 index 00000000..636fde6f Binary files /dev/null and b/mobile_app/assets/www/images/pattern3.png differ diff --git a/mobile_app/assets/www/images/pattern4.png b/mobile_app/assets/www/images/pattern4.png new file mode 100644 index 00000000..d96aa18a Binary files /dev/null and b/mobile_app/assets/www/images/pattern4.png differ diff --git a/mobile_app/assets/www/images/pattern5.png b/mobile_app/assets/www/images/pattern5.png new file mode 100644 index 00000000..82a2af7c Binary files /dev/null and b/mobile_app/assets/www/images/pattern5.png differ diff --git a/mobile_app/assets/www/images/pattern6.png b/mobile_app/assets/www/images/pattern6.png new file mode 100644 index 00000000..dc9271ef Binary files /dev/null and b/mobile_app/assets/www/images/pattern6.png differ diff --git a/mobile_app/assets/www/images/preview.png b/mobile_app/assets/www/images/preview.png new file mode 100644 index 00000000..2b150732 Binary files /dev/null and b/mobile_app/assets/www/images/preview.png differ diff --git a/mobile_app/assets/www/images/textures/antique-big.jpg b/mobile_app/assets/www/images/textures/antique-big.jpg new file mode 100644 index 00000000..711b1681 Binary files /dev/null and b/mobile_app/assets/www/images/textures/antique-big.jpg differ diff --git a/mobile_app/assets/www/images/textures/antique-small.jpg b/mobile_app/assets/www/images/textures/antique-small.jpg new file mode 100644 index 00000000..851b5d07 Binary files /dev/null and b/mobile_app/assets/www/images/textures/antique-small.jpg differ diff --git a/mobile_app/assets/www/images/textures/folded-paper-big.jpg b/mobile_app/assets/www/images/textures/folded-paper-big.jpg new file mode 100644 index 00000000..c2c4d761 Binary files /dev/null and b/mobile_app/assets/www/images/textures/folded-paper-big.jpg differ diff --git a/mobile_app/assets/www/images/textures/folded-paper-small.jpg b/mobile_app/assets/www/images/textures/folded-paper-small.jpg new file mode 100644 index 00000000..88418a13 Binary files /dev/null and b/mobile_app/assets/www/images/textures/folded-paper-small.jpg differ diff --git a/mobile_app/assets/www/images/textures/gray-paper.jpg b/mobile_app/assets/www/images/textures/gray-paper.jpg new file mode 100644 index 00000000..238d6e4c Binary files /dev/null and b/mobile_app/assets/www/images/textures/gray-paper.jpg differ diff --git a/mobile_app/assets/www/images/textures/iran-small.jpg b/mobile_app/assets/www/images/textures/iran-small.jpg new file mode 100644 index 00000000..39f34512 Binary files /dev/null and b/mobile_app/assets/www/images/textures/iran-small.jpg differ diff --git a/mobile_app/assets/www/images/textures/marble-big.jpg b/mobile_app/assets/www/images/textures/marble-big.jpg new file mode 100644 index 00000000..c1d2a6d4 Binary files /dev/null and b/mobile_app/assets/www/images/textures/marble-big.jpg differ diff --git a/mobile_app/assets/www/images/textures/marble-blue-big.jpg b/mobile_app/assets/www/images/textures/marble-blue-big.jpg new file mode 100644 index 00000000..dbfc0975 Binary files /dev/null and b/mobile_app/assets/www/images/textures/marble-blue-big.jpg differ diff --git a/mobile_app/assets/www/images/textures/marble-blue-small.jpg b/mobile_app/assets/www/images/textures/marble-blue-small.jpg new file mode 100644 index 00000000..2e95fdcb Binary files /dev/null and b/mobile_app/assets/www/images/textures/marble-blue-small.jpg differ diff --git a/mobile_app/assets/www/images/textures/marble-small.jpg b/mobile_app/assets/www/images/textures/marble-small.jpg new file mode 100644 index 00000000..10d1a9ab Binary files /dev/null and b/mobile_app/assets/www/images/textures/marble-small.jpg differ diff --git a/mobile_app/assets/www/images/textures/mars-big.jpg b/mobile_app/assets/www/images/textures/mars-big.jpg new file mode 100644 index 00000000..3fd39dae Binary files /dev/null and b/mobile_app/assets/www/images/textures/mars-big.jpg differ diff --git a/mobile_app/assets/www/images/textures/mars-small.jpg b/mobile_app/assets/www/images/textures/mars-small.jpg new file mode 100644 index 00000000..75de8dd3 Binary files /dev/null and b/mobile_app/assets/www/images/textures/mars-small.jpg differ diff --git a/mobile_app/assets/www/images/textures/mauritania-small.jpg b/mobile_app/assets/www/images/textures/mauritania-small.jpg new file mode 100644 index 00000000..22d9cecf Binary files /dev/null and b/mobile_app/assets/www/images/textures/mauritania-small.jpg differ diff --git a/mobile_app/assets/www/images/textures/mercury-big.jpg b/mobile_app/assets/www/images/textures/mercury-big.jpg new file mode 100644 index 00000000..7e06f0ee Binary files /dev/null and b/mobile_app/assets/www/images/textures/mercury-big.jpg differ diff --git a/mobile_app/assets/www/images/textures/mercury-small.jpg b/mobile_app/assets/www/images/textures/mercury-small.jpg new file mode 100644 index 00000000..53f31ee3 Binary files /dev/null and b/mobile_app/assets/www/images/textures/mercury-small.jpg differ diff --git a/mobile_app/assets/www/images/textures/ocean.jpg b/mobile_app/assets/www/images/textures/ocean.jpg new file mode 100644 index 00000000..981366ca Binary files /dev/null and b/mobile_app/assets/www/images/textures/ocean.jpg differ diff --git a/mobile_app/assets/www/images/textures/pergamena-small.jpg b/mobile_app/assets/www/images/textures/pergamena-small.jpg new file mode 100644 index 00000000..951f9eda Binary files /dev/null and b/mobile_app/assets/www/images/textures/pergamena-small.jpg differ diff --git a/mobile_app/assets/www/images/textures/plaster.jpg b/mobile_app/assets/www/images/textures/plaster.jpg new file mode 100644 index 00000000..8ec85c81 Binary files /dev/null and b/mobile_app/assets/www/images/textures/plaster.jpg differ diff --git a/mobile_app/assets/www/images/textures/soiled-paper-vertical.png b/mobile_app/assets/www/images/textures/soiled-paper-vertical.png new file mode 100644 index 00000000..f8bb720e Binary files /dev/null and b/mobile_app/assets/www/images/textures/soiled-paper-vertical.png differ diff --git a/mobile_app/assets/www/images/textures/soiled-paper.jpg b/mobile_app/assets/www/images/textures/soiled-paper.jpg new file mode 100644 index 00000000..00333992 Binary files /dev/null and b/mobile_app/assets/www/images/textures/soiled-paper.jpg differ diff --git a/mobile_app/assets/www/images/textures/spain-small.jpg b/mobile_app/assets/www/images/textures/spain-small.jpg new file mode 100644 index 00000000..a413f508 Binary files /dev/null and b/mobile_app/assets/www/images/textures/spain-small.jpg differ diff --git a/mobile_app/assets/www/images/textures/timbercut-big.jpg b/mobile_app/assets/www/images/textures/timbercut-big.jpg new file mode 100644 index 00000000..7dc9b656 Binary files /dev/null and b/mobile_app/assets/www/images/textures/timbercut-big.jpg differ diff --git a/mobile_app/assets/www/images/textures/timbercut-small.jpg b/mobile_app/assets/www/images/textures/timbercut-small.jpg new file mode 100644 index 00000000..a73e47be Binary files /dev/null and b/mobile_app/assets/www/images/textures/timbercut-small.jpg differ diff --git a/mobile_app/assets/www/index.css b/mobile_app/assets/www/index.css new file mode 100644 index 00000000..83733477 --- /dev/null +++ b/mobile_app/assets/www/index.css @@ -0,0 +1,2429 @@ +:root { + --monospace: Consolas, monospace; + --serif: Georgia, serif; + --sans-serif: Helvetica, Arial, sans-serif; +} + +/* hide Google translate header */ +body > .skiptranslate { + display: none; +} + +/* hide Google translate in-progress widget */ +body > .skiptranslate + div { + display: none; +} + +/* make translated text wrapper non-blocking */ +font { + pointer-events: none; +} + +form input:invalid { + outline: 1px solid #ed4337; + outline-offset: 1px; +} + +input, +select, +button { + font-size: 1em; +} + +input, +select, +textarea { + border: 0.5px solid #dbdfe6; + border-radius: 0.5px; + box-sizing: border-box; +} + +select { + height: 1.6em; + border-top-color: #abadb3; + padding: 0; + text-indent: 0px; +} + +input { + border-top-color: #abadb3; + padding: 2px; + text-indent: 1px; +} + +input:read-only { + cursor: default; +} + +input[type="radio"] { + vertical-align: bottom; + cursor: pointer; + accent-color: var(--header); +} + +textarea { + padding: 3px; + box-sizing: border-box; + width: 100%; +} + +iframe { + border: 0; + width: 100%; +} + +#map { + background-color: #000000; + mask-mode: alpha; + mask-clip: no-clip; + fill-rule: evenodd; + user-select: none; +} + +#canvas { + position: absolute; + pointer-events: none; +} + +#preview { + position: absolute; + bottom: 1em; + left: 1em; + cursor: pointer; +} + +#pickerContainer { + position: absolute; + z-index: 100; +} + +input, +button, +select, +a, +textarea { + outline: none; +} + +button, +select, +a { + cursor: pointer; +} + +.pointer { + cursor: pointer !important; +} + +#prec text { + font-size: 32px; + stroke: none; + text-shadow: 1px 1px 1px #9daac9; + user-select: none; +} + +#population, +#cells, +#compass { + fill: none; +} + +#landmass { + mask: url(#land); + fill-rule: evenodd; +} + +#lakes, +#coastline, +#armies, +#ice, +#emblems { + cursor: pointer; +} + +#temperature { + font-family: var(--sans-serif); + font-weight: 700; + text-anchor: middle; + dominant-baseline: central; + text-shadow: 0px 0px 10px white; + fill-rule: evenodd; +} + +#oceanLayers, +#terrs { + fill-rule: evenodd; +} + +#coastline { + fill: none; + stroke-linejoin: round; +} + +t, +#regions, +#cults, +#relig, +#biomes, +#provincesBody, +#terrs, +#tooltip, +#temperature, +#texture, +#landmass, +#vignette, +#gridOverlay, +#fogging { + pointer-events: none; +} + +#armies text { + pointer-events: none; + user-select: none; + stroke: none; + fill: #fff; + text-shadow: 0 0 4px #000; + dominant-baseline: central; + text-anchor: middle; + font-family: var(--sans-serif); + fill-opacity: 1; +} + +#armies text.regimentIcon { + font-size: 0.8em; +} + +#statesHalo { + fill: none; + stroke-linecap: round; + stroke-linejoin: round; +} + +#statesBody, +#provincesBody, +#relig, +#biomes, +#cults { + stroke-linejoin: round; + fill-rule: evenodd; +} + +#statesBody, +#provincesBody, +#relig, +#cults { + mask: url(#land); +} + +#borders { + stroke-linejoin: round; + fill: none; +} + +#rivers { + stroke: none; + mask: url(#land); + cursor: pointer; + fill-rule: nonzero; +} + +#anchors { + pointer-events: none; +} + +#terrain, +#burgIcons { + cursor: pointer; +} + +.strokes { + stroke-width: 0.08px; + width: 2px; + stroke: #5c5c70; + stroke-dasharray: 0.5, 0.7; + stroke-linecap: round; +} + +#routes { + fill: none; + cursor: pointer; +} + +i.icon-lock { + cursor: pointer; +} + +#labelEditor div { + display: inline-block; +} + +#labels { + text-anchor: middle; + dominant-baseline: central; + cursor: pointer; +} + +.chartInfo { + text-align: center; + font-family: var(--sans-serif); + font-style: italic; + font-size: 12px; +} + +#statesTree text, +#provincesTree text { + pointer-events: none; + user-select: none; + stroke: none; + font-size: 11px; +} + +#statesTree circle { + filter: url(#dropShadow05); + stroke: #666666; + stroke-width: 1; +} + +#statesTree circle.selected, +#provincesTree .selected { + stroke: #c13119; + stroke-width: 2; +} + +.regimentDragLine { + marker-end: url(#end-arrow); + stroke: #333333; + stroke-dasharray: 5; + stroke-dashoffset: 1000; + animation: dash 80s linear backwards; +} + +.arrow { + marker-end: url(#end-arrow-small); + stroke: #555; + stroke-width: 0.5; +} + +@keyframes dash { + to { + stroke-dashoffset: 0; + } +} + +#provinceLabels, +#burgLabels { + dominant-baseline: alphabetic; + text-anchor: middle; +} + +#routeLength, +#coastlineArea { + background-color: #eeeeee; + border: 1px solid #a5a5a5; + line-height: 1.3em; + cursor: default; +} + +#brushCircle { + stroke: #373737; + stroke-width: 1.5px; + stroke-dasharray: 7; + stroke-linecap: butt; + fill: none; +} + +text.drag { + text-shadow: 0 0 1px red; +} + +#dialogs { + background-color: var(--bg-dialogs); +} + +.draggable { + cursor: move; +} + +.ui-widget-header { + border-bottom: 1px solid var(--dark-solid); + background: var(--header); + color: #ffffff; + font-weight: bold; +} + +button.ui-button:disabled { + filter: brightness(0.95); +} + +button.ui-button:disabled:hover { + cursor: default; +} + +.ui-dialog, +#optionsContainer { + user-select: none; +} + +#optionsTrigger { + padding: 0.6em 0.45em; +} + +@media (max-width: 600px) { + #optionsTrigger { + font-size: 2em; + padding: 0; + width: 1.3em; + height: 1.6em; + border: solid 1px #5e4fa2; + } +} + +#options { + position: absolute; + font-family: var(--monospace); + border: solid 1px #5e4fa2; + margin: 10px; + padding-bottom: 0.3em; + background: var(--bg-light); +} + +#options input, +#options select, +#options button { + font-family: var(--monospace); +} + +#collapsible { + margin: 11px; + border: 0; + position: absolute; + z-index: 2; + display: grid; + grid-template-columns: 2fr 7fr; +} + +.tab { + border-bottom: 1px solid var(--dark-solid); + height: 2.2em; + display: flex; + justify-content: space-between; +} + +div.tab > button#optionsHide { + width: auto; + font-family: var(--sans-serif); + padding: 0.6em 0.45em; +} + +button.options { + width: 100%; + background-color: var(--bg-main); + font-weight: bold; + border: none; + transition: 0.2s; +} + +button.active { + background-color: var(--header); + color: white; +} + +button.options:hover { + background-color: var(--header-active); + color: white; +} + +#options p { + font-style: italic; + font-weight: bold; + margin: 0.8em 0 0 0; +} + +#options .tip { + color: #444; + font-size: 0.9em; + font-family: sans-serif; + font-style: italic; + margin-left: 0.5em; +} + +#aboutContent { + text-align: justify; +} + +#aboutContent p { + font-weight: normal; + font-style: normal; +} + +#aboutContent a { + color: #1d1b1c; + font-weight: bold; + text-decoration: underline; +} + +#optionsContent span { + font-size: 0.9em; +} + +#options i { + color: #31272c; + font-size: 0.85em; + cursor: pointer; +} + +#options button i.icon-cog { + position: absolute; + padding: 0.1em 0.3em; + background-color: var(--bg-lighter); + border-radius: 50%; + visibility: hidden; + opacity: 0; + transition: 0.4s ease-in-out; +} + +#options button i.icon-cog:hover { + color: #111; + background-color: var(--bg-light); + transform: rotateZ(180deg); +} + +#options button i.icon-cog:active { + transform: translateY(1px); +} + +#options button:hover i.icon-cog { + visibility: visible; + opacity: 1; +} + +input[type="color"] { + -webkit-appearance: none; + cursor: pointer; + border: 1px solid #a9a9a9; +} + +input[type="color"]::-webkit-color-swatch-wrapper { + padding: 0; +} + +#options input[type="color"] { + width: 4.5em; + height: 1em; + border: 0; +} + +#convertImageDialog input[type="color"] { + width: 38px; + padding: 0; + border: 0; + background: none; + cursor: pointer; +} + +#options select { + height: 1.5em; + border: 0; + cursor: pointer; + font-size: smaller; +} + +#options input[type="text"] { + border: 0px; + width: 62%; + font-size: smaller; +} + +#options output { + text-align: right; + font-size: smaller; +} + +#options input[type="number"] { + font-size: 0.8em; + border: 0; + text-align: right; + background-color: transparent; + width: 3.3em; +} + +#options input[type="number"]::-webkit-inner-spin-button, +#options input[type="number"]::-webkit-outer-spin-button { + -webkit-appearance: none; + margin: 0; +} + +#options input[type="number"] { + appearance: textfield; + -moz-appearance: textfield; +} + +#options input[type="number"]:hover { + outline: 1px solid var(--dark-solid); +} + +#options input.paired { + text-align: center; + background-color: white; +} + +#options input.long { + width: 100%; + background-color: white; + text-align: left; +} + +#options input[type="range"] { + width: 100%; + height: 8px; + background: 0; + appearance: none; + margin-left: 0; + border: 0; + padding: 0; +} + +#options input[type="range"]::-webkit-slider-thumb { + -webkit-appearance: none; + border-radius: 15%; + width: 0.91em; + height: 0.91em; + background: var(--light-solid); + border: 1px solid var(--dark-solid); + cursor: pointer; + margin-top: -0.4em; + box-shadow: 0.5px 0.5px 0px var(--dark-solid); +} + +#options input[type="range"]::-moz-range-thumb { + -moz-appearance: none; + border-radius: 15%; + width: 0.73em; + height: 0.73em; + background: var(--light-solid); + border: 1px solid var(--dark-solid); + cursor: pointer; + box-shadow: 0.5px 0.5px 0px var(--dark-solid); +} + +#options input[type="range"]::-webkit-slider-runnable-track { + height: 2px; + background: #ffffff; +} + +#options input[type="range"]::-moz-range-track { + -moz-appearance: none; + background-color: #ffffff; + height: 2px; +} + +#options select { + width: 100%; +} + +#loadGoogleTranslateButton { + font-size: smaller; + padding: 0.4em 0.5em; +} + +#options input[type="color"] { + width: 2em; + padding: 1px; +} + +.tabcontent button.sideButton { + border-radius: 15%; + font-size: 0.8em; + margin-block: -1em; +} + +#layersContent button.active, +#styleContent button:active { + transform: translate(0px, 1px); +} + +#styleSelectFont > option { + font-size: 2em; +} + +#sticked { + display: flex; + justify-content: space-evenly; + width: 100%; +} + +#sticked button { + background-color: transparent; + font-weight: bold; + border: 0; +} + +#sticked button:hover { + color: white; +} + +#exitCustomization { + right: 10px; + bottom: 10px; + position: absolute; + display: none; +} + +#exitCustomization > div { + width: 12em; + background: var(--dark-solid); + cursor: move; +} + +#finalizeHeightmap { + width: 100%; + border: none; + padding: 0.45em 0.75em; + margin: 0.4em 0; + white-space: nowrap; + font-family: var(--monospace); + animation: glowing 2s infinite; +} + +.glow { + animation: glowing 3s infinite ease-in-out; +} + +@keyframes glowing { + 0% { + box-shadow: 0 0 1px #f44336; + } + 50% { + box-shadow: 0 0 10px #f44336; + } + 100% { + box-shadow: 0 0 1px #f44336; + } +} + +.tabcontent { + display: none; + padding: 0 12px 2px 12px; + opacity: 0.9; +} + +.tabcontent button { + background-color: var(--bg-lighter); + border: none; + padding: 0.45em 0.75em; + margin: 0.35em 0; + transition: 0.1s; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; +} + +.tabcontent button.pressed { + background-color: var(--header); + font-style: italic; +} + +.tabcontent button:hover { + background-color: var(--header-active); +} + +#toolsContent > .grid { + display: grid; + grid-template-columns: repeat(3, 1fr); + margin: 0.2em 0; +} + +#toolsContent button { + padding: 0.35em 0; + margin: 0.16em 0.12em; +} + +#mapLayers { + display: inline-block; + padding: 0; + margin: 0; +} + +#mapFilters > button { + width: 23%; + padding: 4px 0; +} + +#viewMode > button { + padding: 0.35em; + margin: 0.3em 0.3em 0.6em 0.3em; + float: left; + width: 30.7%; +} + +fieldset { + border: 1px solid var(--dark-solid); +} + +.tabcontent li { + list-style-type: none; + background-color: var(--bg-main); + cursor: pointer; + padding: 0.35em; + margin: 0.2em 0.3em; + float: left; + width: 28%; + text-align: center; + text-transform: capitalize; + + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; +} + +.tabcontent li.buttonoff { + background-color: var(--bg-disabled); + color: #444444aa; +} + +.tabcontent li:hover { + box-shadow: 0 0 2px 2px var(--dark-solid) 17; +} + +.tabcontent button:hover { + background-color: var(--header); +} + +#optionsContainer span { + cursor: default; +} + +#cellInfo { + user-select: text; +} + +#tooltip { + position: fixed; + text-align: center; + bottom: 0.5vw; + width: 70%; + left: 15%; + cursor: default; + text-shadow: 1px 1px 2px #1d0e0f; + color: #ffffff; + font-size: calc(12px + 0.5vw); + white-space: pre-line; + z-index: 99999; + background: linear-gradient(0.1turn, #ffffff00, #c71d1d66, #ffffff00); +} + +#optionsContent table { + border-spacing: 0; + line-height: 1.2em; +} + +#optionsContent table td:nth-of-type(1) { + width: 3%; +} + +#optionsContent table td:nth-of-type(2) { + width: 40%; +} + +#optionsContent table td:nth-of-type(4) { + text-align: right; + width: 6%; +} + +.emblemShapePreview { + width: 1.5em; + height: 1.5em; + margin: -0.4em 0.1em; + fill: #fff; + stroke: #000; + stroke-width: 5px; +} + +#styleContent table { + border-spacing: 0; + margin-left: 0.2em; + width: 100%; +} + +#styleContent table tr { + width: 100%; + display: table; +} + +#styleContent table td:nth-of-type(1) { + width: 34.2%; +} + +#styleElements tbody, +#styleElements caption { + display: none; +} + +#styleIsOff { + color: darkred; + font-weight: 700; + text-align: left; +} + +#styleElements .whiteButton { + padding: 0 0.8em; + border: 0; + background-color: #ffffff !important; +} + +.overflow-table { + width: 100%; + text-align: center; +} + +.matrix-table { + max-height: 80vh; + max-width: 85vw; + scrollbar-width: thin; + overflow: auto; +} + +.matrix-table > table { + text-align: center; + border-collapse: collapse; + font-size: smaller; +} + +.matrix-table > table th, +.matrix-table > table td { + border: 1px solid var(--dark-solid); + height: 2em; + padding: 0.2em; + position: relative; +} + +.matrix-table > table th { + background-color: #302a2a; + color: #ffffff; +} + +.matrix-table > table td:hover { + outline: 2px solid var(--dark-solid); + outline-offset: -1px; + z-index: 1; + cursor: pointer; +} + +.matrix-table > table td.Ally { + background-color: #73ec73; + color: #000000; +} + +.matrix-table > table td.Friendly { + background-color: #d4f8aa; +} + +.matrix-table > table td.Neutral { + background-color: #d8d9d3; +} + +.matrix-table > table td.Suspicion { + background-color: #eeafaa; +} + +.matrix-table > table td.Enemy { + background-color: #ffa39c; + color: #af0d23; +} + +.matrix-table > table td.Unknown { + background-color: #c1bfbf; +} + +.matrix-table > table td.Rival { + background-color: #bd845c; +} + +.matrix-table > table td.Vassal { + background-color: #87cefa; +} + +.matrix-table > table td.Suzerain { + background-color: #8f8fe1; +} + +.matrix-table > table td.x { + background-color: #d4ca94; + cursor: initial; +} + +#sizeOutput { + color: green; +} + +.setColors { + display: inline-block; +} + +#templateTools > button { + width: 1.8em; + height: 1.6em; + margin: 1px; + padding: 0.1em 0.5em; + float: left; + font-size: 1.2em; + font-family: var(--monospace); +} + +#brushesButtons > button { + padding: 0.3em; +} + +#brushesButtons svg { + pointer-events: none; +} + +#brushesPanel > div { + margin: 2px 0; +} + +#templateEditor > div { + margin: 1px 0; +} + +#templateEditor #templateTools { + display: inline-block; + margin-bottom: -0.3em; +} + +#templateBody > div { + border: 1px solid #a3a3a3; + border-radius: 1px; + background-image: linear-gradient(to right, #ffffff 0%, #fafafa 51%, #ebebeb 100%); + margin: 1px 1px; + padding: 0.1em 0.2em; + height: 1.2em; +} + +#templateBody > div:hover { + border-color: #808080; + background-image: linear-gradient(to right, #fcfcfc 0%, #ededed 51%, #dedede 100%); +} + +#templateBody > div > div { + display: inline-block; +} + +#templateBody > div > span { + float: right; + margin-inline: 1px; +} + +#templateBody > div > i { + float: right; +} + +#templateBody input, +#templateBody select { + width: 4.5em; + height: 1em; + border: 0; + background-color: #ffffff95; + color: #05044d; + font-style: italic; + font-family: var(--monospace); +} + +#templateBody select { + width: 8em; + height: 1.4em; + cursor: pointer; + font-size: 0.9em; +} + +#templateBody .icon-resize-vertical { + cursor: row-resize; + font-size: 0.9em; + color: #555555; + margin: 1px 1px; +} + +#templateBody .icon-check-empty, +#templateBody .icon-check { + width: 1.1em; + cursor: pointer; + color: #575957; + font-size: 0.9em; +} + +#controlPoints { + fill: #ff0000; + stroke: #841f1f; + stroke-width: 0.25; + cursor: move; + opacity: 0.8; +} + +#controlPoints > path { + fill: none; + stroke: #0a0909; + stroke-width: 2; + opacity: 0.4; + cursor: pointer; +} + +#controlCells { + pointer-events: none; + fill: #82c8ff80; + stroke: none; +} + +#vertices > circle { + fill: #ff0000; + stroke: #841f1f; + stroke-width: 0.1; + cursor: move; + opacity: 0.8; +} + +#vertices > polygon { + fill: none; + stroke: #808080; + stroke-width: 0.1; +} + +#controlPoints > circle:hover, +#vertices > circle:hover { + stroke: #2c0808; +} + +#battleBody > table { + padding: 0.2em 0.6em 0.2em 0.6em; + border: 1px solid #ccc; + margin: 0.2em 0 0.4em 0; + display: block; + overflow: auto; + max-height: 34vh; + width: 100%; +} + +#battleBody > table .regiment { + width: 13em; + font-weight: bold; +} + +tr.battleCasualties, +tr.battleSurvivors { + font-style: italic; + font-size: 0.9em; +} + +#battleBottom div.battleTypes { + position: fixed; + background-color: #ffffff30; +} + +#battleBody div.battlePhases { + position: absolute; + background-color: #ffffff30; +} + +#battleBody div.battlePhases > button, +#battleBottom div.battleTypes > button { + width: 3.2em; + display: block; + margin: 0.2em 0; +} + +div#regimentSelectorBody { + max-height: 50vh; + font-size: 0.9em; +} + +div#regimentSelectorBody > div { + padding: 0.1em; + border: 1px solid #fff; +} + +div#regimentSelectorBody > div:hover { + border: 1px solid #ccc; +} + +div#regimentSelectorBody > div.selected { + border: 1px solid #b28585; +} + +div#regimentSelectorBody > div.inactive { + background-color: #eee; + color: #aaa; +} + +div#regimentSelectorBody > div > div { + display: inline-block; + pointer-events: none; +} + +.drag-trigger { + border-left: 1em solid transparent; + border-right: 1em solid #000; + border-top: 1em solid transparent; + position: absolute; + right: -1px; + bottom: -1px; + opacity: 0.3; +} + +.drag-trigger:hover { + cursor: move; + opacity: 0.6; +} + +.tint { + filter: sepia(1) hue-rotate(200deg); +} + +.colorsContainer { + display: grid; + grid-template-columns: repeat(5, 1fr); + grid-column-gap: 0.3em; + grid-row-gap: 0.2em; +} + +.color-div { + width: 3em; + height: 1.5em; + border: 1px #999 solid; + cursor: pointer; +} + +#colorsSelect div { + height: 1.7em; + display: inline-block; + cursor: pointer; +} + +.color-div:hover { + border-color: red; +} + +.hoveredColor { + box-shadow: 0 0 1px 1px #717171; +} + +.selectedColor { + outline: 2px solid #f87b66; +} + +#colorScheme { + margin: 6px 1px 4px 1px; +} + +#debug path.selected { + stroke-width: 0.8; + stroke: #da3126; + fill: none; +} + +#debug > text { + font-size: 2px; + text-anchor: middle; + dominant-baseline: central; +} + +.selectedCell { + stroke-width: 1; + stroke: #da3126; +} + +i.resetButton { + float: left; + padding-right: 0.4em; + font-size: 0.8em; + margin-top: 0.25em; + color: #ffffff; + cursor: pointer; +} + +i.resetButton:active { + color: var(--dark-solid); +} + +.ui-dialog button.pressed { + box-shadow: inset 1px 1px 0 0 #ccc; + border-color: #a6a6da; + background-color: #ecd8d8; + border-radius: 10%; +} + +.ui-dialog input[type="range"] { + padding: 0; + height: 2px; + background: #d4d4d4; + position: relative; + appearance: none; + -webkit-appearance: none; +} + +.ui-dialog input[type="range"]::-webkit-slider-thumb { + -webkit-appearance: none; + border-radius: 15%; + width: 1em; + height: 1em; + background: #e9e9e9; + border: 1px solid #9b9b9b; + cursor: pointer; +} + +.ui-dialog input[type="range"]::-moz-range-thumb { + appearance: none; + border-radius: 15%; + width: 1em; + height: 1em; + background: #e9e9e9; + border: 1px solid #9b9b9b; + cursor: pointer; +} + +.ui-dialog input[type="number"] { + width: 4.5em; +} + +.ui-dialog .disabled { + opacity: 0.2; +} + +.ui-dialog:disabled { + cursor: default; +} + +div.slider { + width: 40em; + margin-top: 0.2em; +} + +div.slider .ui-slider-handle { + width: 3em; + height: 1.6em; + top: 50%; + margin-top: -0.8em; + text-align: center; + line-height: 1.6em; +} + +#saveDropdown { + display: none; + position: absolute; + left: 29%; + top: 100%; + border: 1px solid #5e4fa2; + background-color: #a4879b; + width: 5em; +} + +#loadDropdown { + display: none; + position: absolute; + left: 53%; + top: 100%; + border: 1px solid #5e4fa2; + background-color: #a4879b; + width: 9em; +} + +#loadDropdown > div, +#saveDropdown > div { + padding: 2px 4px; + cursor: pointer; +} + +#loadDropdown > div:hover, +#saveDropdown > div:hover { + color: white; +} + +#rescaleHigher, +#rescaleLower, +#rescaleModifier { + width: 3.7em; +} + +.italic { + font-style: italic; +} + +.hidden { + display: none !important; +} + +.table { + max-height: 75vh; + max-width: 75vw; + overflow-x: hidden; + overflow-y: auto; + scrollbar-width: thin; +} + +@media screen and (max-width: 600px) { + .table { + max-width: unset; + } +} + +.dialog::-webkit-scrollbar, +#alertMessage::-webkit-scrollbar, +.table::-webkit-scrollbar, +.matrix-table::-webkit-scrollbar { + width: 6px; + height: 6px; + background-color: transparent; +} + +.dialog::-webkit-scrollbar-thumb, +#alertMessage::-webkit-scrollbar-thumb, +.table::-webkit-scrollbar-thumb, +.matrix-table::-webkit-scrollbar-thumb { + background-color: #aaa; + border-radius: 6px; +} + +.dialog::-webkit-scrollbar-thumb:hover, +#alertMessage::-webkit-scrollbar-thumb:hover, +.table::-webkit-scrollbar-thumb:hover, +.matrix-table::-webkit-scrollbar-thumb:hover { + background: #666; +} + +.dialog { + max-width: 93vw; +} + +.dialog > div { + width: max-content; +} + +div.header { + display: grid; + width: 0; + font-weight: bold; + font-size: 0.9em; +} + +div.header > div:first-child { + margin-left: 1.8em; +} + +.sortable { + cursor: pointer; +} + +.totalLine { + color: #666666; + font-style: italic; + font-size: 0.9em; + margin-bottom: 3px; +} + +.totalLine > div { + display: inline-block; +} + +div.states { + border: 1px solid #d4d4d4; + background-image: linear-gradient(to right, #fafafa80 0%, #f0f0f080 50%, #c8c8c880 100%); + margin: 0.1em 0; + padding: 0 0.2em; + font-size: 0.9em; + line-height: 1.5em; +} + +div.states:hover, +div.states.hovered { + border: 1px solid #c4c4c4; + background-image: linear-gradient(to right, #dedede 100%, #f2f2f2 50%, #fcfcfc 0%); +} + +div.states > *, +div.states sup, +div.totalLine > div { + display: inline-block; +} + +div.states > input { + width: 7em; + background: none; + border: 0; +} + +div.states div { + width: 3.2em; +} + +div.states .biomeHabitability { + width: 4em; + -moz-appearance: textfield; +} + +div.states > .statePopulation { + width: 3em; +} + +div.states:hover > .hiddenIcon { + visibility: visible !important; +} + +div.states .icon-pencil, +div.states .icon-trash-empty, +div.states .icon-eye, +div.states .icon-pin, +div.states .icon-flag-empty, +div.states .icon-cw, +div.states .icon-lock, +div.states .icon-lock-open { + cursor: pointer; +} + +div.states .icon-resize-vertical { + cursor: row-resize; + font-size: 0.9em; +} + +div.states > [class^="icon-"] { + color: #6e5e66; + padding: 0; +} + +div.states > .icon-arrows-cw { + color: #67575c; + font-size: 0.9em; + cursor: pointer; +} + +div.states > .before { + color: #6e5e66; + padding: 0 1px 0 0; +} + +div.states > .small { + font-size: 0.9em; +} + +div.states > select { + width: 7em; + cursor: pointer; + border: 0; + background-color: transparent; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; +} + +div.states span.inactive { + color: #c6c2c2; +} + +div.states span.inactive:hover { + color: #abaaaa; +} + +div.states > .riverName { + width: 7em; +} + +div.states > .riverType { + width: 5em; +} + +.coaIcon { + stroke-width: 3; + width: 1.4em; + height: 1.4em; + margin: -0.3em 0; +} + +.coaIcon > use { + pointer-events: none; +} + +#diplomacyBodySection > div { + cursor: pointer; +} + +.changeRelations > * { + pointer-events: none; + cursor: pointer; +} + +#diplomacySelect { + width: 5em; + margin: 0.1em 0 0 -0.3em; + position: fixed; + background-color: #ffffff; + border: 1px solid #1891ff; +} + +#diplomacySelect > div { + width: 100%; + padding-left: 0.3em; +} + +#diplomacySelect > div:hover { + background-color: #1891ff; + color: #ffffff; + width: calc(100% - 0.3em); +} + +#burgsFooterPopulation { + border: 0; + width: 50px; + color: #666666; + font-style: italic; + line-height: 1.4em; +} + +#burgBody div.label { + display: inline-block; + width: 6em; +} + +#burgBody > div > div, +#riverBody > div, +#routeBody > div, +#lakeBody > div { + padding: 0.1em; +} + +#riverBody div.label, +#riverBody input, +#riverBody select, +#routeBody div.label, +#lakeBody div.label, +#lakeBody input, +#lakeBody select { + display: inline-block; + width: 7em; +} + +#routeBody input, +#routeBody select { + display: inline-block; + width: 10em; +} + +#stateNameEditor div.label, +#provinceNameEditor div.label, +#regimentBody div.label, +#markerEditor div.label { + display: inline-block; + width: 5.5em; + padding: 0.3em 0; +} + +#exportToPngTilesScreen div.label { + display: inline-block; + width: 5em; +} + +#regimentBody input[type="number"] { + width: 5em; +} + +.burgFeature { + padding: 1px; + cursor: pointer; +} + +.burgFeature.inactive { + color: #ddd; +} + +.burgFeature.inactive:hover { + color: #abaaaa; +} + +.placeholder { + opacity: 0; + cursor: default; + pointer-events: none; +} + +div.states.selected { + border-color: #b28585; + background-image: linear-gradient(to right, #f2f2f2 0%, #ebe7e7 50%, #e5dadb 100%); +} + +div.states.active { + border: 1px solid #c4c4c4; + background-image: linear-gradient(to right, #dedede 100%, #f2f2f2 50%, #fcfcfc 0%); +} + +div.states.Self { + margin-bottom: 0.2em; + cursor: default !important; + padding: 0.2em 0 0 0.5em; + font-weight: bold; +} + +div.states button.selectCapital { + margin: -1px 21px 0 7px; + padding: 0px 3px; +} + +div.states > input.biomeName { + width: 12em; +} + +div.states > div.biomeArea { + width: 5em; +} + +#militaryBody div.states > input { + -moz-appearance: textfield; +} + +#militaryBody div.states > input, +#militaryBody div.states > div, +#regimentsBody div.states > div { + width: 5em; +} + +#emblemBody > div { + padding: 1px 3px; + transition: all 0.3s ease-out; +} + +#emblemBody > div.active { + background-color: #54ca7728; +} + +#emblemArmiger { + text-align: center; + display: block; +} + +#emblemBody .label { + width: 6em; + display: inline-block; +} + +#emblemBody select { + width: 9em; +} + +#emblemsBottom { + margin-top: 4px; + text-align: center; +} + +#emblemUploadControl, +#emblemDownloadControl { + margin-top: 0.3em; + width: 100%; +} + +div.editorLine { + margin: 0.2em 0; + padding: 0 0.2em; + font-size: 0.9em; +} + +#emblemDownloadControl > input { + width: 4.1em; +} + +#picker text { + cursor: default; +} + +#pickerHeader { + fill: var(--header); + stroke: var(--dark-solid); + cursor: move; +} + +#pickerLabel { + fill: #f8ffff; + font-size: 12px; + font-weight: bold; + font-family: var(--sans-serif); + cursor: move !important; +} + +#pickerCloseRect { + cursor: pointer; + fill: var(--header); + stroke: #f8ffff; +} + +#pickerCloseText { + fill: #f8ffff; + font-size: 10px; + font-family: var(--sans-serif); + pointer-events: none; +} + +#pickerControls line { + stroke: #999999; + stroke-width: 2; +} + +#pickerControls circle { + fill: #ffeb3b; + stroke: #666666; + cursor: ew-resize; +} + +#pickerControls circle:hover { + fill: #eca116; + stroke: #000000; +} + +#pickerControls, +#pickerSpaces { + font-size: 11px; +} + +#pickerSpaces input { + width: 22px; + font-size: 9px; + -moz-appearance: textfield; +} + +#pickerSpaces input::-webkit-inner-spin-button, +#pickerSpaces input::-webkit-outer-spin-button { + -webkit-appearance: none; + margin: 0; +} + +#pickerColors rect, +#pickerHatches rect { + cursor: pointer; +} + +#picker rect.selected { + outline: 2px dashed #b90c0c; + stroke-width: 0; +} + +.hoverButton { + position: sticky; + margin-left: -1.8em; + margin-top: 1px; + background-color: #dedede; + font-size: 8px; + cursor: pointer; + padding: 0px 3px !important; +} + +.unitsHeader { + margin: 0.8em 0 0 -1.1em; + font-weight: bold; + font-style: italic; +} + +#unitsBottom, +#reliefBottom { + margin: 6px 0 0 6px; +} + +#unitsBody label { + display: inline-block; + width: 9em; +} + +#unitsBody > div > select, +#unitsBody > div > input[type="text"] { + width: 14.4em; + border: 1px solid #e9e9e9; +} + +#unitsBody input[type="range"] { + width: 9em; +} + +#unitsEditor i.icon-lock-open, +#unitsEditor i.icon-lock { + color: #626573; + font-size: 0.8em; + cursor: pointer; + position: fixed; + margin: 0.4em 0 0 -0.9em; +} + +#ruler { + cursor: move; + fill: none; +} + +#ruler .rulerPoints { + stroke: #4e5a69; + fill: yellow; + cursor: grab; +} + +#ruler .rulerPoints .control { + fill: #999999; +} + +#ruler .white { + stroke: white; +} + +#ruler .gray { + stroke: #3d3d3d; + pointer-events: none; +} + +#ruler text { + font-family: var(--serif); + fill: #3d3d3d; + text-anchor: middle; + text-shadow: 0 0 4px white; + cursor: pointer; +} + +#ruler path.planimeter { + fill: lightblue; + fill-rule: evenodd; + fill-opacity: 0.5; + stroke: #737373; +} + +#militaryOptionsTable select { + border: 1px solid #d4d4d4; +} + +#militaryOptionsTable input { + width: 9em; + border: 1px solid #d4d4d4; +} + +#militaryOptionsTable input[type="number"] { + width: 5em; +} + +#militaryOptionsTable button, +#burgGroupsBody button { + width: 100%; +} + +#gridOverlay { + fill: none; +} + +#coordinateLabels { + fill: #333333; + font-family: var(--monospace); + text-shadow: 0 0 4px white; + stroke-width: 0; + dominant-baseline: central; + text-anchor: middle; +} + +ul.share-buttons { + margin: 4px 0 0 0; + padding-left: 8%; +} + +ul.share-buttons li { + padding: 0; + background: none !important; + width: 16%; + margin: 0; +} + +ul.share-buttons img { + width: 2em; +} + +input[type="checkbox"].native { + accent-color: var(--header); + cursor: pointer; +} + +input[type="checkbox"]:not(.native) { + display: none; +} + +.checkbox, +.checkbox-label { + cursor: pointer; +} + +.checkbox + .checkbox-label:before { + content: ""; + display: inline-block; + vertical-align: bottom; + width: 0.6em; + height: 0.6em; + padding: 0.2em; + margin-right: 0.2em; + border: 1px solid darkgrey; + border-radius: 15%; + background: white; + font-family: var(--monospace); +} + +.checkbox:checked + .checkbox-label:before { + line-height: 0.8em; + font-weight: bold; + content: "✓"; + color: #333333; +} + +div.textual select, +div.textual textarea, +div.textual input { + font-family: var(--monospace); +} + +div.textual fieldset { + margin: 3px 3px 5px 0; + border-style: dashed; +} + +div.textual span, +.textual legend { + font-size: 0.9em; + font-weight: bold; +} + +#namesbaseExamples { + font-family: var(--monospace); + cursor: pointer; +} + +#markers { + cursor: pointer; + font-family: var(--monospace); + user-select: none; + text-anchor: middle; + dominant-baseline: central; +} + +.highlighted { + outline-width: 2px; + outline-style: dashed; + outline-color: #0da6ff; + outline-offset: 100px; + fill: none; +} + +#notes { + display: none; + position: fixed; + width: 28vw; + right: 1vw; + top: 1vw; + font-size: 1.2em; + border: 1px solid #5e4fa2; + background: rgba(255, 250, 228, 0.7); + box-shadow: 2px 2px 5px -3px #3a2804; +} + +@media screen and (max-width: 600px) { + #notes { + width: 50vw; + } +} + +#notesHeader { + font-weight: bold; + font-size: 1.3em; + padding: 16px 0 4px 12px; + border-bottom: 1px solid #5e4fa2; +} + +#notesBody { + padding: 14px 12px; + max-height: 80vh; + overflow: auto; +} + +#notesBody > iframe { + user-select: none; +} + +#notesBody p { + margin: 4px; +} + +#notesLegend { + width: auto; + height: 87%; + outline: 0; + overflow-y: auto; + padding: 0.6em; + font-family: var(--monospace); + background-color: #fff; + border: 1px solid #dedede; + color: #000; +} + +svg.button { + position: relative; + background-color: transparent; + margin: -5px; + padding: 0; +} + +#reliefEditor > div > div { + font-style: italic; + display: inline-block; +} + +#reliefEditor div.reliefEditorLabel { + width: 4em; +} + +#reliefEditor input[type="range"] { + width: 16em; +} + +#reliefIconsDiv { + margin-top: 2px; + padding: 2px; + width: 100%; +} + +#reliefIconsDiv svg { + width: 40px; + height: 40px; + background-color: #e7e6e4; + border: 1px solid #a9a9a9; + cursor: pointer; +} + +#reliefIconsDiv svg:hover { + border-color: #5c5c5c; + background-color: #eef6fb; + transition: all 0.3s ease-out 3s; + transform: scale(2); +} + +#reliefIconsDiv svg.pressed { + border: 1px solid #b3352c; + background-color: #f2f2f2; +} + +#reliefIconsSeletionAny { + display: none; + text-anchor: middle; + dominant-baseline: central; +} + +#alertMessage { + user-select: text; + max-height: 70vh; + max-width: 75vw; + overflow: auto; +} + +#alertMessage ul { + padding-left: 1.2em; + margin: 1em 0; +} + +.pseudoLink { + cursor: pointer; + text-decoration: underline; +} + +.info-line { + font-size: 0.9em; + font-style: italic; + color: gray; + user-select: none; +} + +.optionsSeedRestore { + font-size: 12px; + cursor: pointer; + margin-right: 2px; +} + +.optionsSeedRestore:hover { + color: blue; +} + +#worldControls { + width: 16em; + display: inline-block; + vertical-align: top; +} + +#worldControls > div { + display: block; + margin: 1px 0; + padding: 2px 0; +} + +#worldControls input[type="number"] { + border: 1px solid #e5e5e5; + padding: 0px; + width: 4em; +} + +#worldControls i.icon-lock-open, +#worldControls i.icon-lock { + color: #626573; + font-size: 0.8em; + cursor: pointer; +} + +#globe { + stroke: black; + stroke-width: 1; +} + +#globeNoteLines { + stroke-dasharray: 5; + stroke: #bbb; +} + +#globaAxisLabels { + font-style: italic; + font-size: 9px; + font-family: var(--monospace); + stroke: none; + fill: #001754; +} + +#globeLatLabels { + font-size: 12px; + font-family: var(--monospace); + stroke: none; + fill: #001754; +} + +#globeWindArrows { + fill: none; + stroke: #6072a3; + cursor: pointer; +} + +#globeWindArrows path { + stroke-width: 1.7px; + fill: none; + stroke: #6072a3; + pointer-events: none; +} + +#globeWindArrows circle { + fill: #fff; + fill-opacity: 0; + stroke-opacity: 0.05; +} + +#globaAxisLabels #restoreWind:hover { + cursor: pointer; + fill: blue; +} + +#globeArea { + fill: white; + fill-opacity: 0.3; +} + +#globeGraticule { + fill: none; + stroke-width: 0.2; +} + +#globePrimeMeridian { + stroke: blue; + stroke-width: 1.4; +} + +#globeEquator { + stroke: red; + stroke-width: 1.4; +} + +#legend { + cursor: move; + user-select: none; +} + +.dontAsk { + margin: 0.9em 0 0 0.6em; + display: inline-flex; + align-items: center; +} + +#errorBox { + font-size: 0.9em; + font-family: var(--monospace); + color: #920303; + background-color: #dabdbd91; + padding: 2px; + border: 1px solid var(--header); +} + +.announcement { + background-color: #a18888; + color: white; + padding: 0.4em 0.5em; + border: dashed 1px var(--dark-solid); +} + +.speaker { + font-size: 0.9em; + cursor: pointer; +} + +#prompt { + position: absolute; + left: 50%; + top: 50%; + transform: translate(-50%, -50%); + max-width: 23em; + padding: 1.2em; + background-color: var(--bg-dialogs); + border: solid 1px var(--dark-solid); + font-size: 1.2em; + z-index: 1000; +} + +#promptText { + padding: 0 0 0.6em 0; + font-weight: bold; + font-family: var(--sans-serif); +} + +#mapOverlay { + position: absolute; + inset: 0; + display: flex; + align-items: center; + justify-content: center; + z-index: 10; + pointer-events: none; + text-align: center; + background: rgba(0, 0, 0, 0.5); + font-size: 2.4em; + color: #fff5da; + text-shadow: 0px 1px 4px #4c3a35; +} + +.epgrid line { + stroke: lightgrey; + stroke-opacity: 0.5; + shape-rendering: crispEdges; +} + +.epgrid path { + stroke-width: 0; +} + +#debug { + font-size: 1px; + opacity: 0.8; +} + +#markerTypeSelector { + font-size: 0.85em; +} + +#markerTypeSelectorWrapper { + position: relative; +} + +#markerTypeSelectMenu { + display: none; +} + +#markerTypeSelectMenu.visible { + display: block; + position: absolute; + height: 250px; + width: 170px; + overflow-y: scroll; + background: inherit; + bottom: 100%; + left: 0; + background: white; +} + +#markerTypeSelectMenu > button { + display: block; + width: 100%; + border: 1px solid #ddd; + margin-bottom: 1px; +} + +#markerTypeSelectMenu > button:hover { + background: #ccc; +} + +.separator { + display: flex; + align-items: center; + text-align: center; + + font-style: italic; + font-weight: bold; + color: #222; + margin: 0.8em 0 0 0; +} +.separator::before, +.separator::after { + content: ""; + flex: 1; + border-bottom: 1px solid #333; +} +.separator:not(:empty)::before { + margin-right: 0.25em; +} +.separator:not(:empty)::after { + margin-left: 0.25em; +} + +@keyframes clockwiseBorderPulse { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } +} + +#chat-widget-container { + user-select: none; +} + +#chat-widget-minimized { + animation: fadeIn 1s ease-in; + transform: scale(0.65); + opacity: var(--bg-opacity); +} + +@keyframes fadeIn { + from { + opacity: 0; + } + to { + opacity: var(--bg-opacity); + } +} + +@media print { + div, + canvas { + display: none; + } +} + +@media only screen and (max-width: 420px) { + table { + width: 100%; + } + + .tabcontent { + max-width: 100%; + } + + .drag-trigger { + display: none; + } +} + +@media (prefers-color-scheme: dark) { + body { + background: #25252a; + } +} diff --git a/mobile_app/assets/www/index.html b/mobile_app/assets/www/index.html new file mode 100644 index 00000000..4d5c13b6 --- /dev/null +++ b/mobile_app/assets/www/index.html @@ -0,0 +1,8581 @@ + + + + + + + Azgaar's Fantasy Map Generator + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+
Azgaar's
+
Fantasy Map Generator
+
‎ ‎
+

LOADING...

+
+
+ +
+
+ + +
+ + +
+ +
+
+ +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mobile_app/assets/www/libs/alea.min.js b/mobile_app/assets/www/libs/alea.min.js new file mode 100644 index 00000000..f4ecef67 --- /dev/null +++ b/mobile_app/assets/www/libs/alea.min.js @@ -0,0 +1,3 @@ +/*https://github.com/macmcmeans/aleaPRNG/blob/master/aleaPRNG-1.1.js +©2010 Johannes Baagøe, MIT license; Derivative ©2017-2020 W. Mac" McMeans, BSD license.*/ +const aleaPRNG=function(){return function(n){"use strict";var r,t,e,o,a,u=new Uint32Array(3),i="";function c(n){var a=function(){var n=4022871197,r=function(r){r=r.toString();for(var t=0,e=r.length;t>>0,n=(o*=n)>>>0,n+=4294967296*(o-=n)}return 2.3283064365386963e-10*(n>>>0)};return r.version="Mash 0.9",r}();r=a(" "),t=a(" "),e=a(" "),o=1;for(var u=0;uarguments[1]&&(n=arguments[1],r=arguments[0]),f(n)&&f(r)?Math.floor(l()*(r-n+1))+n:l()*(r-n)+n},l.restart=function(){c(a)},l.seed=function(){c(Array.prototype.slice.call(arguments))},l.version=function(){return"aleaPRNG 1.1.0"},l.versions=function(){return"aleaPRNG 1.1.0, "+i},0===n.length&&(window.crypto.getRandomValues(u),n=[u[0],u[1],u[2]]),a=n,c(n),l}(Array.prototype.slice.call(arguments))}; \ No newline at end of file diff --git a/mobile_app/assets/www/libs/d3.min.js b/mobile_app/assets/www/libs/d3.min.js new file mode 100644 index 00000000..8ed42731 --- /dev/null +++ b/mobile_app/assets/www/libs/d3.min.js @@ -0,0 +1,2 @@ +// https://d3js.org v5.8.0 Copyright 2019 Mike Bostock +!function(t,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n(t.d3=t.d3||{})}(this,function(t){"use strict";function n(t,n){return tn?1:t>=n?0:NaN}function e(t){var e;return 1===t.length&&(e=t,t=function(t,r){return n(e(t),r)}),{left:function(n,e,r,i){for(null==r&&(r=0),null==i&&(i=n.length);r>>1;t(n[o],e)<0?r=o+1:i=o}return r},right:function(n,e,r,i){for(null==r&&(r=0),null==i&&(i=n.length);r>>1;t(n[o],e)>0?i=o:r=o+1}return r}}}var r=e(n),i=r.right,o=r.left;function a(t,n){return[t,n]}function u(t){return null===t?NaN:+t}function c(t,n){var e,r,i=t.length,o=0,a=-1,c=0,f=0;if(null==n)for(;++a1)return f/(o-1)}function f(t,n){var e=c(t,n);return e?Math.sqrt(e):e}function s(t,n){var e,r,i,o=t.length,a=-1;if(null==n){for(;++a=e)for(r=i=e;++ae&&(r=e),i=e)for(r=i=e;++ae&&(r=e),i0)return[t];if((r=n0)for(t=Math.ceil(t/a),n=Math.floor(n/a),o=new Array(i=Math.ceil(n-t+1));++u=0?(o>=y?10:o>=_?5:o>=b?2:1)*Math.pow(10,i):-Math.pow(10,-i)/(o>=y?10:o>=_?5:o>=b?2:1)}function w(t,n,e){var r=Math.abs(n-t)/Math.max(0,e),i=Math.pow(10,Math.floor(Math.log(r)/Math.LN10)),o=r/i;return o>=y?i*=10:o>=_?i*=5:o>=b&&(i*=2),n=1)return+e(t[r-1],r-1,t);var r,i=(r-1)*n,o=Math.floor(i),a=+e(t[o],o,t);return a+(+e(t[o+1],o+1,t)-a)*(i-o)}}function A(t,n){var e,r,i=t.length,o=-1;if(null==n){for(;++o=e)for(r=e;++or&&(r=e)}else for(;++o=e)for(r=e;++or&&(r=e);return r}function k(t){for(var n,e,r,i=t.length,o=-1,a=0;++o=0;)for(n=(r=t[i]).length;--n>=0;)e[--a]=r[n];return e}function S(t,n){var e,r,i=t.length,o=-1;if(null==n){for(;++o=e)for(r=e;++oe&&(r=e)}else for(;++o=e)for(r=e;++oe&&(r=e);return r}function T(t){if(!(i=t.length))return[];for(var n=-1,e=S(t,E),r=new Array(e);++n=0&&(n=t.slice(e+1),t=t.slice(0,e)),t&&!r.hasOwnProperty(t))throw new Error("unknown type: "+t);return{type:t,name:n}})),a=-1,u=o.length;if(!(arguments.length<2)){if(null!=n&&"function"!=typeof n)throw new Error("invalid callback: "+n);for(;++a0)for(var e,r,i=new Array(e),o=0;o=0&&"xmlns"!==(n=t.slice(0,e))&&(t=t.slice(e+1)),V.hasOwnProperty(n)?{space:V[n],local:t}:t}function W(t){var n=$(t);return(n.local?function(t){return function(){return this.ownerDocument.createElementNS(t.space,t.local)}}:function(t){return function(){var n=this.ownerDocument,e=this.namespaceURI;return e===G&&n.documentElement.namespaceURI===G?n.createElement(t):n.createElementNS(e,t)}})(n)}function Z(){}function Q(t){return null==t?Z:function(){return this.querySelector(t)}}function J(){return[]}function K(t){return null==t?J:function(){return this.querySelectorAll(t)}}function tt(t){return function(){return this.matches(t)}}function nt(t){return new Array(t.length)}function et(t,n){this.ownerDocument=t.ownerDocument,this.namespaceURI=t.namespaceURI,this._next=null,this._parent=t,this.__data__=n}et.prototype={constructor:et,appendChild:function(t){return this._parent.insertBefore(t,this._next)},insertBefore:function(t,n){return this._parent.insertBefore(t,n)},querySelector:function(t){return this._parent.querySelector(t)},querySelectorAll:function(t){return this._parent.querySelectorAll(t)}};var rt="$";function it(t,n,e,r,i,o){for(var a,u=0,c=n.length,f=o.length;un?1:t>=n?0:NaN}function ut(t){return t.ownerDocument&&t.ownerDocument.defaultView||t.document&&t||t.defaultView}function ct(t,n){return t.style.getPropertyValue(n)||ut(t).getComputedStyle(t,null).getPropertyValue(n)}function ft(t){return t.trim().split(/^|\s+/)}function st(t){return t.classList||new lt(t)}function lt(t){this._node=t,this._names=ft(t.getAttribute("class")||"")}function ht(t,n){for(var e=st(t),r=-1,i=n.length;++r=0&&(this._names.splice(n,1),this._node.setAttribute("class",this._names.join(" ")))},contains:function(t){return this._names.indexOf(t)>=0}};var wt={};(t.event=null,"undefined"!=typeof document)&&("onmouseenter"in document.documentElement||(wt={mouseenter:"mouseover",mouseleave:"mouseout"}));function Mt(t,n,e){return t=Nt(t,n,e),function(n){var e=n.relatedTarget;e&&(e===this||8&e.compareDocumentPosition(this))||t.call(this,n)}}function Nt(n,e,r){return function(i){var o=t.event;t.event=i;try{n.call(this,this.__data__,e,r)}finally{t.event=o}}}function At(t){return function(){var n=this.__on;if(n){for(var e,r=0,i=-1,o=n.length;r=x&&(x=m+1);!(b=y[x])&&++x=0;)(r=i[o])&&(a&&4^r.compareDocumentPosition(a)&&a.parentNode.insertBefore(r,a),a=r);return this},sort:function(t){function n(n,e){return n&&e?t(n.__data__,e.__data__):!n-!e}t||(t=at);for(var e=this._groups,r=e.length,i=new Array(r),o=0;o1?this.each((null==n?function(t){return function(){this.style.removeProperty(t)}}:"function"==typeof n?function(t,n,e){return function(){var r=n.apply(this,arguments);null==r?this.style.removeProperty(t):this.style.setProperty(t,r,e)}}:function(t,n,e){return function(){this.style.setProperty(t,n,e)}})(t,n,null==e?"":e)):ct(this.node(),t)},property:function(t,n){return arguments.length>1?this.each((null==n?function(t){return function(){delete this[t]}}:"function"==typeof n?function(t,n){return function(){var e=n.apply(this,arguments);null==e?delete this[t]:this[t]=e}}:function(t,n){return function(){this[t]=n}})(t,n)):this.node()[t]},classed:function(t,n){var e=ft(t+"");if(arguments.length<2){for(var r=st(this.node()),i=-1,o=e.length;++i=0&&(n=t.slice(e+1),t=t.slice(0,e)),{type:t,name:n}})}(t+""),a=o.length;if(!(arguments.length<2)){for(u=n?kt:At,null==e&&(e=!1),r=0;r>8&15|n>>4&240,n>>4&15|240&n,(15&n)<<4|15&n,1):(n=rn.exec(t))?dn(parseInt(n[1],16)):(n=on.exec(t))?new yn(n[1],n[2],n[3],1):(n=an.exec(t))?new yn(255*n[1]/100,255*n[2]/100,255*n[3]/100,1):(n=un.exec(t))?pn(n[1],n[2],n[3],n[4]):(n=cn.exec(t))?pn(255*n[1]/100,255*n[2]/100,255*n[3]/100,n[4]):(n=fn.exec(t))?bn(n[1],n[2]/100,n[3]/100,1):(n=sn.exec(t))?bn(n[1],n[2]/100,n[3]/100,n[4]):ln.hasOwnProperty(t)?dn(ln[t]):"transparent"===t?new yn(NaN,NaN,NaN,0):null}function dn(t){return new yn(t>>16&255,t>>8&255,255&t,1)}function pn(t,n,e,r){return r<=0&&(t=n=e=NaN),new yn(t,n,e,r)}function vn(t){return t instanceof Jt||(t=hn(t)),t?new yn((t=t.rgb()).r,t.g,t.b,t.opacity):new yn}function gn(t,n,e,r){return 1===arguments.length?vn(t):new yn(t,n,e,null==r?1:r)}function yn(t,n,e,r){this.r=+t,this.g=+n,this.b=+e,this.opacity=+r}function _n(t){return((t=Math.max(0,Math.min(255,Math.round(t)||0)))<16?"0":"")+t.toString(16)}function bn(t,n,e,r){return r<=0?t=n=e=NaN:e<=0||e>=1?t=n=NaN:n<=0&&(t=NaN),new xn(t,n,e,r)}function mn(t,n,e,r){return 1===arguments.length?function(t){if(t instanceof xn)return new xn(t.h,t.s,t.l,t.opacity);if(t instanceof Jt||(t=hn(t)),!t)return new xn;if(t instanceof xn)return t;var n=(t=t.rgb()).r/255,e=t.g/255,r=t.b/255,i=Math.min(n,e,r),o=Math.max(n,e,r),a=NaN,u=o-i,c=(o+i)/2;return u?(a=n===o?(e-r)/u+6*(e0&&c<1?0:a,new xn(a,u,c,t.opacity)}(t):new xn(t,n,e,null==r?1:r)}function xn(t,n,e,r){this.h=+t,this.s=+n,this.l=+e,this.opacity=+r}function wn(t,n,e){return 255*(t<60?n+(e-n)*t/60:t<180?e:t<240?n+(e-n)*(240-t)/60:n)}Zt(Jt,hn,{displayable:function(){return this.rgb().displayable()},hex:function(){return this.rgb().hex()},toString:function(){return this.rgb()+""}}),Zt(yn,gn,Qt(Jt,{brighter:function(t){return t=null==t?1/.7:Math.pow(1/.7,t),new yn(this.r*t,this.g*t,this.b*t,this.opacity)},darker:function(t){return t=null==t?.7:Math.pow(.7,t),new yn(this.r*t,this.g*t,this.b*t,this.opacity)},rgb:function(){return this},displayable:function(){return 0<=this.r&&this.r<=255&&0<=this.g&&this.g<=255&&0<=this.b&&this.b<=255&&0<=this.opacity&&this.opacity<=1},hex:function(){return"#"+_n(this.r)+_n(this.g)+_n(this.b)},toString:function(){var t=this.opacity;return(1===(t=isNaN(t)?1:Math.max(0,Math.min(1,t)))?"rgb(":"rgba(")+Math.max(0,Math.min(255,Math.round(this.r)||0))+", "+Math.max(0,Math.min(255,Math.round(this.g)||0))+", "+Math.max(0,Math.min(255,Math.round(this.b)||0))+(1===t?")":", "+t+")")}})),Zt(xn,mn,Qt(Jt,{brighter:function(t){return t=null==t?1/.7:Math.pow(1/.7,t),new xn(this.h,this.s,this.l*t,this.opacity)},darker:function(t){return t=null==t?.7:Math.pow(.7,t),new xn(this.h,this.s,this.l*t,this.opacity)},rgb:function(){var t=this.h%360+360*(this.h<0),n=isNaN(t)||isNaN(this.s)?0:this.s,e=this.l,r=e+(e<.5?e:1-e)*n,i=2*e-r;return new yn(wn(t>=240?t-240:t+120,i,r),wn(t,i,r),wn(t<120?t+240:t-120,i,r),this.opacity)},displayable:function(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1}}));var Mn=Math.PI/180,Nn=180/Math.PI,An=.96422,kn=1,Sn=.82521,Tn=4/29,En=6/29,Cn=3*En*En,Pn=En*En*En;function zn(t){if(t instanceof qn)return new qn(t.l,t.a,t.b,t.opacity);if(t instanceof Fn){if(isNaN(t.h))return new qn(t.l,0,0,t.opacity);var n=t.h*Mn;return new qn(t.l,Math.cos(n)*t.c,Math.sin(n)*t.c,t.opacity)}t instanceof yn||(t=vn(t));var e,r,i=On(t.r),o=On(t.g),a=On(t.b),u=Dn((.2225045*i+.7168786*o+.0606169*a)/kn);return i===o&&o===a?e=r=u:(e=Dn((.4360747*i+.3850649*o+.1430804*a)/An),r=Dn((.0139322*i+.0971045*o+.7141733*a)/Sn)),new qn(116*u-16,500*(e-u),200*(u-r),t.opacity)}function Rn(t,n,e,r){return 1===arguments.length?zn(t):new qn(t,n,e,null==r?1:r)}function qn(t,n,e,r){this.l=+t,this.a=+n,this.b=+e,this.opacity=+r}function Dn(t){return t>Pn?Math.pow(t,1/3):t/Cn+Tn}function Ln(t){return t>En?t*t*t:Cn*(t-Tn)}function Un(t){return 255*(t<=.0031308?12.92*t:1.055*Math.pow(t,1/2.4)-.055)}function On(t){return(t/=255)<=.04045?t/12.92:Math.pow((t+.055)/1.055,2.4)}function Yn(t){if(t instanceof Fn)return new Fn(t.h,t.c,t.l,t.opacity);if(t instanceof qn||(t=zn(t)),0===t.a&&0===t.b)return new Fn(NaN,0,t.l,t.opacity);var n=Math.atan2(t.b,t.a)*Nn;return new Fn(n<0?n+360:n,Math.sqrt(t.a*t.a+t.b*t.b),t.l,t.opacity)}function Bn(t,n,e,r){return 1===arguments.length?Yn(t):new Fn(t,n,e,null==r?1:r)}function Fn(t,n,e,r){this.h=+t,this.c=+n,this.l=+e,this.opacity=+r}Zt(qn,Rn,Qt(Jt,{brighter:function(t){return new qn(this.l+18*(null==t?1:t),this.a,this.b,this.opacity)},darker:function(t){return new qn(this.l-18*(null==t?1:t),this.a,this.b,this.opacity)},rgb:function(){var t=(this.l+16)/116,n=isNaN(this.a)?t:t+this.a/500,e=isNaN(this.b)?t:t-this.b/200;return new yn(Un(3.1338561*(n=An*Ln(n))-1.6168667*(t=kn*Ln(t))-.4906146*(e=Sn*Ln(e))),Un(-.9787684*n+1.9161415*t+.033454*e),Un(.0719453*n-.2289914*t+1.4052427*e),this.opacity)}})),Zt(Fn,Bn,Qt(Jt,{brighter:function(t){return new Fn(this.h,this.c,this.l+18*(null==t?1:t),this.opacity)},darker:function(t){return new Fn(this.h,this.c,this.l-18*(null==t?1:t),this.opacity)},rgb:function(){return zn(this).rgb()}}));var In=-.14861,Hn=1.78277,jn=-.29227,Xn=-.90649,Gn=1.97294,Vn=Gn*Xn,$n=Gn*Hn,Wn=Hn*jn-Xn*In;function Zn(t,n,e,r){return 1===arguments.length?function(t){if(t instanceof Qn)return new Qn(t.h,t.s,t.l,t.opacity);t instanceof yn||(t=vn(t));var n=t.r/255,e=t.g/255,r=t.b/255,i=(Wn*r+Vn*n-$n*e)/(Wn+Vn-$n),o=r-i,a=(Gn*(e-i)-jn*o)/Xn,u=Math.sqrt(a*a+o*o)/(Gn*i*(1-i)),c=u?Math.atan2(a,o)*Nn-120:NaN;return new Qn(c<0?c+360:c,u,i,t.opacity)}(t):new Qn(t,n,e,null==r?1:r)}function Qn(t,n,e,r){this.h=+t,this.s=+n,this.l=+e,this.opacity=+r}function Jn(t,n,e,r,i){var o=t*t,a=o*t;return((1-3*t+3*o-a)*n+(4-6*o+3*a)*e+(1+3*t+3*o-3*a)*r+a*i)/6}function Kn(t){var n=t.length-1;return function(e){var r=e<=0?e=0:e>=1?(e=1,n-1):Math.floor(e*n),i=t[r],o=t[r+1],a=r>0?t[r-1]:2*i-o,u=r180||e<-180?e-360*Math.round(e/360):e):ne(isNaN(t)?n:t)}function ie(t){return 1==(t=+t)?oe:function(n,e){return e-n?function(t,n,e){return t=Math.pow(t,e),n=Math.pow(n,e)-t,e=1/e,function(r){return Math.pow(t+r*n,e)}}(n,e,t):ne(isNaN(n)?e:n)}}function oe(t,n){var e=n-t;return e?ee(t,e):ne(isNaN(t)?n:t)}Zt(Qn,Zn,Qt(Jt,{brighter:function(t){return t=null==t?1/.7:Math.pow(1/.7,t),new Qn(this.h,this.s,this.l*t,this.opacity)},darker:function(t){return t=null==t?.7:Math.pow(.7,t),new Qn(this.h,this.s,this.l*t,this.opacity)},rgb:function(){var t=isNaN(this.h)?0:(this.h+120)*Mn,n=+this.l,e=isNaN(this.s)?0:this.s*n*(1-n),r=Math.cos(t),i=Math.sin(t);return new yn(255*(n+e*(In*r+Hn*i)),255*(n+e*(jn*r+Xn*i)),255*(n+e*(Gn*r)),this.opacity)}}));var ae=function t(n){var e=ie(n);function r(t,n){var r=e((t=gn(t)).r,(n=gn(n)).r),i=e(t.g,n.g),o=e(t.b,n.b),a=oe(t.opacity,n.opacity);return function(n){return t.r=r(n),t.g=i(n),t.b=o(n),t.opacity=a(n),t+""}}return r.gamma=t,r}(1);function ue(t){return function(n){var e,r,i=n.length,o=new Array(i),a=new Array(i),u=new Array(i);for(e=0;eo&&(i=n.slice(o,i),u[a]?u[a]+=i:u[++a]=i),(e=e[0])===(r=r[0])?u[a]?u[a]+=r:u[++a]=r:(u[++a]=null,c.push({i:a,x:he(e,r)})),o=ve.lastIndex;return o180?n+=360:n-t>180&&(t+=360),o.push({i:e.push(i(e)+"rotate(",null,r)-2,x:he(t,n)})):n&&e.push(i(e)+"rotate("+n+r)}(o.rotate,a.rotate,u,c),function(t,n,e,o){t!==n?o.push({i:e.push(i(e)+"skewX(",null,r)-2,x:he(t,n)}):n&&e.push(i(e)+"skewX("+n+r)}(o.skewX,a.skewX,u,c),function(t,n,e,r,o,a){if(t!==e||n!==r){var u=o.push(i(o)+"scale(",null,",",null,")");a.push({i:u-4,x:he(t,e)},{i:u-2,x:he(n,r)})}else 1===e&&1===r||o.push(i(o)+"scale("+e+","+r+")")}(o.scaleX,o.scaleY,a.scaleX,a.scaleY,u,c),o=a=null,function(t){for(var n,e=-1,r=c.length;++e=0&&n._call.call(null,t),n=n._next;--Ge}function ar(){Qe=(Ze=Ke.now())+Je,Ge=Ve=0;try{or()}finally{Ge=0,function(){var t,n,e=je,r=1/0;for(;e;)e._call?(r>e._time&&(r=e._time),t=e,e=e._next):(n=e._next,e._next=null,e=t?t._next=n:je=n);Xe=t,cr(r)}(),Qe=0}}function ur(){var t=Ke.now(),n=t-Ze;n>We&&(Je-=n,Ze=t)}function cr(t){Ge||(Ve&&(Ve=clearTimeout(Ve)),t-Qe>24?(t<1/0&&(Ve=setTimeout(ar,t-Ke.now()-Je)),$e&&($e=clearInterval($e))):($e||(Ze=Ke.now(),$e=setInterval(ur,We)),Ge=1,tr(ar)))}function fr(t,n,e){var r=new rr;return n=null==n?0:+n,r.restart(function(e){r.stop(),t(e+n)},n,e),r}rr.prototype=ir.prototype={constructor:rr,restart:function(t,n,e){if("function"!=typeof t)throw new TypeError("callback is not a function");e=(null==e?nr():+e)+(null==n?0:+n),this._next||Xe===this||(Xe?Xe._next=this:je=this,Xe=this),this._call=t,this._time=e,cr()},stop:function(){this._call&&(this._call=null,this._time=1/0,cr())}};var sr=I("start","end","cancel","interrupt"),lr=[],hr=0,dr=1,pr=2,vr=3,gr=4,yr=5,_r=6;function br(t,n,e,r,i,o){var a=t.__transition;if(a){if(e in a)return}else t.__transition={};!function(t,n,e){var r,i=t.__transition;function o(c){var f,s,l,h;if(e.state!==dr)return u();for(f in i)if((h=i[f]).name===e.name){if(h.state===vr)return fr(o);h.state===gr?(h.state=_r,h.timer.stop(),h.on.call("interrupt",t,t.__data__,h.index,h.group),delete i[f]):+fhr)throw new Error("too late; already scheduled");return e}function xr(t,n){var e=wr(t,n);if(e.state>vr)throw new Error("too late; already running");return e}function wr(t,n){var e=t.__transition;if(!e||!(e=e[n]))throw new Error("transition not found");return e}function Mr(t,n){var e,r,i,o=t.__transition,a=!0;if(o){for(i in n=null==n?null:n+"",o)(e=o[i]).name===n?(r=e.state>pr&&e.state=0&&(t=t.slice(0,n)),!t||"start"===t})}(n)?mr:xr;return function(){var a=o(this,t),u=a.on;u!==r&&(i=(r=u).copy()).on(n,e),a.on=i}}(e,t,n))},attr:function(t,n){var e=$(t),r="transform"===e?Te:Ar;return this.attrTween(t,"function"==typeof n?(e.local?function(t,n,e){var r,i,o;return function(){var a,u,c=e(this);if(null!=c)return(a=this.getAttributeNS(t.space,t.local))===(u=c+"")?null:a===r&&u===i?o:(i=u,o=n(r=a,c));this.removeAttributeNS(t.space,t.local)}}:function(t,n,e){var r,i,o;return function(){var a,u,c=e(this);if(null!=c)return(a=this.getAttribute(t))===(u=c+"")?null:a===r&&u===i?o:(i=u,o=n(r=a,c));this.removeAttribute(t)}})(e,r,Nr(this,"attr."+t,n)):null==n?(e.local?function(t){return function(){this.removeAttributeNS(t.space,t.local)}}:function(t){return function(){this.removeAttribute(t)}})(e):(e.local?function(t,n,e){var r,i,o=e+"";return function(){var a=this.getAttributeNS(t.space,t.local);return a===o?null:a===r?i:i=n(r=a,e)}}:function(t,n,e){var r,i,o=e+"";return function(){var a=this.getAttribute(t);return a===o?null:a===r?i:i=n(r=a,e)}})(e,r,n))},attrTween:function(t,n){var e="attr."+t;if(arguments.length<2)return(e=this.tween(e))&&e._value;if(null==n)return this.tween(e,null);if("function"!=typeof n)throw new Error;var r=$(t);return this.tween(e,(r.local?function(t,n){var e,r;function i(){var i=n.apply(this,arguments);return i!==r&&(e=(r=i)&&function(t,n){return function(e){this.setAttributeNS(t.space,t.local,n(e))}}(t,i)),e}return i._value=n,i}:function(t,n){var e,r;function i(){var i=n.apply(this,arguments);return i!==r&&(e=(r=i)&&function(t,n){return function(e){this.setAttribute(t,n(e))}}(t,i)),e}return i._value=n,i})(r,n))},style:function(t,n,e){var r="transform"==(t+="")?Se:Ar;return null==n?this.styleTween(t,function(t,n){var e,r,i;return function(){var o=ct(this,t),a=(this.style.removeProperty(t),ct(this,t));return o===a?null:o===e&&a===r?i:i=n(e=o,r=a)}}(t,r)).on("end.style."+t,Sr(t)):"function"==typeof n?this.styleTween(t,function(t,n,e){var r,i,o;return function(){var a=ct(this,t),u=e(this),c=u+"";return null==u&&(this.style.removeProperty(t),c=u=ct(this,t)),a===c?null:a===r&&c===i?o:(i=c,o=n(r=a,u))}}(t,r,Nr(this,"style."+t,n))).each(function(t,n){var e,r,i,o,a="style."+n,u="end."+a;return function(){var c=xr(this,t),f=c.on,s=null==c.value[a]?o||(o=Sr(n)):void 0;f===e&&i===s||(r=(e=f).copy()).on(u,i=s),c.on=r}}(this._id,t)):this.styleTween(t,function(t,n,e){var r,i,o=e+"";return function(){var a=ct(this,t);return a===o?null:a===r?i:i=n(r=a,e)}}(t,r,n),e).on("end.style."+t,null)},styleTween:function(t,n,e){var r="style."+(t+="");if(arguments.length<2)return(r=this.tween(r))&&r._value;if(null==n)return this.tween(r,null);if("function"!=typeof n)throw new Error;return this.tween(r,function(t,n,e){var r,i;function o(){var o=n.apply(this,arguments);return o!==i&&(r=(i=o)&&function(t,n,e){return function(r){this.style.setProperty(t,n(r),e)}}(t,o,e)),r}return o._value=n,o}(t,n,null==e?"":e))},text:function(t){return this.tween("text","function"==typeof t?function(t){return function(){var n=t(this);this.textContent=null==n?"":n}}(Nr(this,"text",t)):function(t){return function(){this.textContent=t}}(null==t?"":t+""))},remove:function(){return this.on("end.remove",(t=this._id,function(){var n=this.parentNode;for(var e in this.__transition)if(+e!==t)return;n&&n.removeChild(this)}));var t},tween:function(t,n){var e=this._id;if(t+="",arguments.length<2){for(var r,i=wr(this.node(),e).tween,o=0,a=i.length;o0&&(r=o-p),M<0?h=d-v:M>0&&(a=u-v),x=vi,L.attr("cursor",xi.selection),Y());break;default:return}di()},!0).on("keyup.brush",function(){switch(t.event.keyCode){case 16:P&&(y=_=P=!1,Y());break;case 18:x===yi&&(w<0?s=l:w>0&&(r=o),M<0?h=d:M>0&&(a=u),x=gi,Y());break;case 32:x===vi&&(t.event.altKey?(w&&(s=l-p*w,r=o+p*w),M&&(h=d-v*M,a=u+v*M),x=yi):(w<0?s=l:w>0&&(r=o),M<0?h=d:M>0&&(a=u),x=gi),L.attr("cursor",xi[m]),Y());break;default:return}di()},!0).on("mousemove.brush",O,!0).on("mouseup.brush",B,!0);It(t.event.view)}hi(),Mr(b),c.call(b),q.start()}function O(){var t=Ot(b);!P||y||_||(Math.abs(t[0]-R[0])>Math.abs(t[1]-R[1])?_=!0:y=!0),R=t,g=!0,di(),Y()}function Y(){var t;switch(p=R[0]-z[0],v=R[1]-z[1],x){case vi:case pi:w&&(p=Math.max(S-r,Math.min(E-s,p)),o=r+p,l=s+p),M&&(v=Math.max(T-a,Math.min(C-h,v)),u=a+v,d=h+v);break;case gi:w<0?(p=Math.max(S-r,Math.min(E-r,p)),o=r+p,l=s):w>0&&(p=Math.max(S-s,Math.min(E-s,p)),o=r,l=s+p),M<0?(v=Math.max(T-a,Math.min(C-a,v)),u=a+v,d=h):M>0&&(v=Math.max(T-h,Math.min(C-h,v)),u=a,d=h+v);break;case yi:w&&(o=Math.max(S,Math.min(E,r-p*w)),l=Math.max(S,Math.min(E,s+p*w))),M&&(u=Math.max(T,Math.min(C,a-v*M)),d=Math.max(T,Math.min(C,h+v*M)))}l1e-6)if(Math.abs(s*u-c*f)>1e-6&&i){var h=e-o,d=r-a,p=u*u+c*c,v=h*h+d*d,g=Math.sqrt(p),y=Math.sqrt(l),_=i*Math.tan((Bi-Math.acos((p+l-v)/(2*g*y)))/2),b=_/y,m=_/g;Math.abs(b-1)>1e-6&&(this._+="L"+(t+b*f)+","+(n+b*s)),this._+="A"+i+","+i+",0,0,"+ +(s*h>f*d)+","+(this._x1=t+m*u)+","+(this._y1=n+m*c)}else this._+="L"+(this._x1=t)+","+(this._y1=n);else;},arc:function(t,n,e,r,i,o){t=+t,n=+n;var a=(e=+e)*Math.cos(r),u=e*Math.sin(r),c=t+a,f=n+u,s=1^o,l=o?r-i:i-r;if(e<0)throw new Error("negative radius: "+e);null===this._x1?this._+="M"+c+","+f:(Math.abs(this._x1-c)>1e-6||Math.abs(this._y1-f)>1e-6)&&(this._+="L"+c+","+f),e&&(l<0&&(l=l%Fi+Fi),l>Ii?this._+="A"+e+","+e+",0,1,"+s+","+(t-a)+","+(n-u)+"A"+e+","+e+",0,1,"+s+","+(this._x1=c)+","+(this._y1=f):l>1e-6&&(this._+="A"+e+","+e+",0,"+ +(l>=Bi)+","+s+","+(this._x1=t+e*Math.cos(i))+","+(this._y1=n+e*Math.sin(i))))},rect:function(t,n,e,r){this._+="M"+(this._x0=this._x1=+t)+","+(this._y0=this._y1=+n)+"h"+ +e+"v"+ +r+"h"+-e+"Z"},toString:function(){return this._}};function Zi(){}function Qi(t,n){var e=new Zi;if(t instanceof Zi)t.each(function(t,n){e.set(n,t)});else if(Array.isArray(t)){var r,i=-1,o=t.length;if(null==n)for(;++ir!=d>r&&e<(h-f)*(r-s)/(d-s)+f&&(i=-i)}return i}function so(t,n,e){var r,i,o,a;return function(t,n,e){return(n[0]-t[0])*(e[1]-t[1])==(e[0]-t[0])*(n[1]-t[1])}(t,n,e)&&(i=t[r=+(t[0]===n[0])],o=e[r],a=n[r],i<=o&&o<=a||a<=o&&o<=i)}function lo(){}var ho=[[],[[[1,1.5],[.5,1]]],[[[1.5,1],[1,1.5]]],[[[1.5,1],[.5,1]]],[[[1,.5],[1.5,1]]],[[[1,1.5],[.5,1]],[[1,.5],[1.5,1]]],[[[1,.5],[1,1.5]]],[[[1,.5],[.5,1]]],[[[.5,1],[1,.5]]],[[[1,1.5],[1,.5]]],[[[.5,1],[1,.5]],[[1.5,1],[1,1.5]]],[[[1.5,1],[1,.5]]],[[[.5,1],[1.5,1]]],[[[1,1.5],[1.5,1]]],[[[.5,1],[1,1.5]]],[]];function po(){var t=1,n=1,e=M,r=u;function i(t){var n=e(t);if(Array.isArray(n))n=n.slice().sort(ao);else{var r=s(t),i=r[0],a=r[1];n=w(i,a,n),n=g(Math.floor(i/n)*n,Math.floor(a/n)*n,n)}return n.map(function(n){return o(t,n)})}function o(e,i){var o=[],u=[];return function(e,r,i){var o,u,c,f,s,l,h=new Array,d=new Array;o=u=-1,f=e[0]>=r,ho[f<<1].forEach(p);for(;++o=r,ho[c|f<<1].forEach(p);ho[f<<0].forEach(p);for(;++u=r,s=e[u*t]>=r,ho[f<<1|s<<2].forEach(p);++o=r,l=s,s=e[u*t+o+1]>=r,ho[c|f<<1|s<<2|l<<3].forEach(p);ho[f|s<<3].forEach(p)}o=-1,s=e[u*t]>=r,ho[s<<2].forEach(p);for(;++o=r,ho[s<<2|l<<3].forEach(p);function p(t){var n,e,r=[t[0][0]+o,t[0][1]+u],c=[t[1][0]+o,t[1][1]+u],f=a(r),s=a(c);(n=d[f])?(e=h[s])?(delete d[n.end],delete h[e.start],n===e?(n.ring.push(c),i(n.ring)):h[n.start]=d[e.end]={start:n.start,end:e.end,ring:n.ring.concat(e.ring)}):(delete d[n.end],n.ring.push(c),d[n.end=s]=n):(n=h[s])?(e=d[f])?(delete h[n.start],delete d[e.end],n===e?(n.ring.push(c),i(n.ring)):h[e.start]=d[n.end]={start:e.start,end:n.end,ring:e.ring.concat(n.ring)}):(delete h[n.start],n.ring.unshift(r),h[n.start=f]=n):h[f]=d[s]={start:f,end:s,ring:[r,c]}}ho[s<<3].forEach(p)}(e,i,function(t){r(t,e,i),function(t){for(var n=0,e=t.length,r=t[e-1][1]*t[0][0]-t[e-1][0]*t[0][1];++n0?o.push([t]):u.push(t)}),u.forEach(function(t){for(var n,e=0,r=o.length;e0&&a0&&u0&&o>0))throw new Error("invalid size");return t=r,n=o,i},i.thresholds=function(t){return arguments.length?(e="function"==typeof t?t:Array.isArray(t)?uo(oo.call(t)):uo(t),i):e},i.smooth=function(t){return arguments.length?(r=t?u:lo,i):r===u},i}function vo(t,n,e){for(var r=t.width,i=t.height,o=1+(e<<1),a=0;a=e&&(u>=o&&(c-=t.data[u-o+a*r]),n.data[u-e+a*r]=c/Math.min(u+1,r-1+o-u,o))}function go(t,n,e){for(var r=t.width,i=t.height,o=1+(e<<1),a=0;a=e&&(u>=o&&(c-=t.data[a+(u-o)*r]),n.data[a+(u-e)*r]=c/Math.min(u+1,i-1+o-u,o))}function yo(t){return t[0]}function _o(t){return t[1]}function bo(){return 1}var mo={},xo={},wo=34,Mo=10,No=13;function Ao(t){return new Function("d","return {"+t.map(function(t,n){return JSON.stringify(t)+": d["+n+"]"}).join(",")+"}")}function ko(t){var n=new RegExp('["'+t+"\n\r]"),e=t.charCodeAt(0);function r(t,n){var r,i=[],o=t.length,a=0,u=0,c=o<=0,f=!1;function s(){if(c)return xo;if(f)return f=!1,mo;var n,r,i=a;if(t.charCodeAt(i)===wo){for(;a++=o?c=!0:(r=t.charCodeAt(a++))===Mo?f=!0:r===No&&(f=!0,t.charCodeAt(a)===Mo&&++a),t.slice(i+1,n-1).replace(/""/g,'"')}for(;a=(o=(v+y)/2))?v=o:y=o,(s=e>=(a=(g+_)/2))?g=a:_=a,i=d,!(d=d[l=s<<1|f]))return i[l]=p,t;if(u=+t._x.call(null,d.data),c=+t._y.call(null,d.data),n===u&&e===c)return p.next=d,i?i[l]=p:t._root=p,t;do{i=i?i[l]=new Array(4):t._root=new Array(4),(f=n>=(o=(v+y)/2))?v=o:y=o,(s=e>=(a=(g+_)/2))?g=a:_=a}while((l=s<<1|f)==(h=(c>=a)<<1|u>=o));return i[h]=d,i[l]=p,t}function Jo(t,n,e,r,i){this.node=t,this.x0=n,this.y0=e,this.x1=r,this.y1=i}function Ko(t){return t[0]}function ta(t){return t[1]}function na(t,n,e){var r=new ea(null==n?Ko:n,null==e?ta:e,NaN,NaN,NaN,NaN);return null==t?r:r.addAll(t)}function ea(t,n,e,r,i,o){this._x=t,this._y=n,this._x0=e,this._y0=r,this._x1=i,this._y1=o,this._root=void 0}function ra(t){for(var n={data:t.data},e=n;t=t.next;)e=e.next={data:t.data};return n}var ia=na.prototype=ea.prototype;function oa(t){return t.x+t.vx}function aa(t){return t.y+t.vy}function ua(t){return t.index}function ca(t,n){var e=t.get(n);if(!e)throw new Error("missing: "+n);return e}function fa(t){return t.x}function sa(t){return t.y}ia.copy=function(){var t,n,e=new ea(this._x,this._y,this._x0,this._y0,this._x1,this._y1),r=this._root;if(!r)return e;if(!r.length)return e._root=ra(r),e;for(t=[{source:r,target:e._root=new Array(4)}];r=t.pop();)for(var i=0;i<4;++i)(n=r.source[i])&&(n.length?t.push({source:n,target:r.target[i]=new Array(4)}):r.target[i]=ra(n));return e},ia.add=function(t){var n=+this._x.call(null,t),e=+this._y.call(null,t);return Qo(this.cover(n,e),n,e,t)},ia.addAll=function(t){var n,e,r,i,o=t.length,a=new Array(o),u=new Array(o),c=1/0,f=1/0,s=-1/0,l=-1/0;for(e=0;es&&(s=r),il&&(l=i));for(st||t>i||r>n||n>o))return this;var a,u,c=i-e,f=this._root;switch(u=(n<(r+o)/2)<<1|t<(e+i)/2){case 0:do{(a=new Array(4))[u]=f,f=a}while(o=r+(c*=2),t>(i=e+c)||n>o);break;case 1:do{(a=new Array(4))[u]=f,f=a}while(o=r+(c*=2),(e=i-c)>t||n>o);break;case 2:do{(a=new Array(4))[u]=f,f=a}while(r=o-(c*=2),t>(i=e+c)||r>n);break;case 3:do{(a=new Array(4))[u]=f,f=a}while(r=o-(c*=2),(e=i-c)>t||r>n)}this._root&&this._root.length&&(this._root=f)}return this._x0=e,this._y0=r,this._x1=i,this._y1=o,this},ia.data=function(){var t=[];return this.visit(function(n){if(!n.length)do{t.push(n.data)}while(n=n.next)}),t},ia.extent=function(t){return arguments.length?this.cover(+t[0][0],+t[0][1]).cover(+t[1][0],+t[1][1]):isNaN(this._x0)?void 0:[[this._x0,this._y0],[this._x1,this._y1]]},ia.find=function(t,n,e){var r,i,o,a,u,c,f,s=this._x0,l=this._y0,h=this._x1,d=this._y1,p=[],v=this._root;for(v&&p.push(new Jo(v,s,l,h,d)),null==e?e=1/0:(s=t-e,l=n-e,h=t+e,d=n+e,e*=e);c=p.pop();)if(!(!(v=c.node)||(i=c.x0)>h||(o=c.y0)>d||(a=c.x1)=y)<<1|t>=g)&&(c=p[p.length-1],p[p.length-1]=p[p.length-1-f],p[p.length-1-f]=c)}else{var _=t-+this._x.call(null,v.data),b=n-+this._y.call(null,v.data),m=_*_+b*b;if(m=(u=(p+g)/2))?p=u:g=u,(s=a>=(c=(v+y)/2))?v=c:y=c,n=d,!(d=d[l=s<<1|f]))return this;if(!d.length)break;(n[l+1&3]||n[l+2&3]||n[l+3&3])&&(e=n,h=l)}for(;d.data!==t;)if(r=d,!(d=d.next))return this;return(i=d.next)&&delete d.next,r?(i?r.next=i:delete r.next,this):n?(i?n[l]=i:delete n[l],(d=n[0]||n[1]||n[2]||n[3])&&d===(n[3]||n[2]||n[1]||n[0])&&!d.length&&(e?e[h]=d:this._root=d),this):(this._root=i,this)},ia.removeAll=function(t){for(var n=0,e=t.length;n1?r[0]+r.slice(2):r,+t.slice(e+1)]}function pa(t){return(t=da(Math.abs(t)))?t[1]:NaN}var va,ga=/^(?:(.)?([<>=^]))?([+\-( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?(~)?([a-z%])?$/i;function ya(t){return new _a(t)}function _a(t){if(!(n=ga.exec(t)))throw new Error("invalid format: "+t);var n;this.fill=n[1]||" ",this.align=n[2]||">",this.sign=n[3]||"-",this.symbol=n[4]||"",this.zero=!!n[5],this.width=n[6]&&+n[6],this.comma=!!n[7],this.precision=n[8]&&+n[8].slice(1),this.trim=!!n[9],this.type=n[10]||""}function ba(t,n){var e=da(t,n);if(!e)return t+"";var r=e[0],i=e[1];return i<0?"0."+new Array(-i).join("0")+r:r.length>i+1?r.slice(0,i+1)+"."+r.slice(i+1):r+new Array(i-r.length+2).join("0")}ya.prototype=_a.prototype,_a.prototype.toString=function(){return this.fill+this.align+this.sign+this.symbol+(this.zero?"0":"")+(null==this.width?"":Math.max(1,0|this.width))+(this.comma?",":"")+(null==this.precision?"":"."+Math.max(0,0|this.precision))+(this.trim?"~":"")+this.type};var ma={"%":function(t,n){return(100*t).toFixed(n)},b:function(t){return Math.round(t).toString(2)},c:function(t){return t+""},d:function(t){return Math.round(t).toString(10)},e:function(t,n){return t.toExponential(n)},f:function(t,n){return t.toFixed(n)},g:function(t,n){return t.toPrecision(n)},o:function(t){return Math.round(t).toString(8)},p:function(t,n){return ba(100*t,n)},r:ba,s:function(t,n){var e=da(t,n);if(!e)return t+"";var r=e[0],i=e[1],o=i-(va=3*Math.max(-8,Math.min(8,Math.floor(i/3))))+1,a=r.length;return o===a?r:o>a?r+new Array(o-a+1).join("0"):o>0?r.slice(0,o)+"."+r.slice(o):"0."+new Array(1-o).join("0")+da(t,Math.max(0,n+o-1))[0]},X:function(t){return Math.round(t).toString(16).toUpperCase()},x:function(t){return Math.round(t).toString(16)}};function xa(t){return t}var wa,Ma=["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"];function Na(t){var n,e,r=t.grouping&&t.thousands?(n=t.grouping,e=t.thousands,function(t,r){for(var i=t.length,o=[],a=0,u=n[0],c=0;i>0&&u>0&&(c+u+1>r&&(u=Math.max(1,r-c)),o.push(t.substring(i-=u,i+u)),!((c+=u+1)>r));)u=n[a=(a+1)%n.length];return o.reverse().join(e)}):xa,i=t.currency,o=t.decimal,a=t.numerals?function(t){return function(n){return n.replace(/[0-9]/g,function(n){return t[+n]})}}(t.numerals):xa,u=t.percent||"%";function c(t){var n=(t=ya(t)).fill,e=t.align,c=t.sign,f=t.symbol,s=t.zero,l=t.width,h=t.comma,d=t.precision,p=t.trim,v=t.type;"n"===v?(h=!0,v="g"):ma[v]||(null==d&&(d=12),p=!0,v="g"),(s||"0"===n&&"="===e)&&(s=!0,n="0",e="=");var g="$"===f?i[0]:"#"===f&&/[boxX]/.test(v)?"0"+v.toLowerCase():"",y="$"===f?i[1]:/[%p]/.test(v)?u:"",_=ma[v],b=/[defgprs%]/.test(v);function m(t){var i,u,f,m=g,x=y;if("c"===v)x=_(t)+x,t="";else{var w=(t=+t)<0;if(t=_(Math.abs(t),d),p&&(t=function(t){t:for(var n,e=t.length,r=1,i=-1;r0){if(!+t[r])break t;i=0}}return i>0?t.slice(0,i)+t.slice(n+1):t}(t)),w&&0==+t&&(w=!1),m=(w?"("===c?c:"-":"-"===c||"("===c?"":c)+m,x=("s"===v?Ma[8+va/3]:"")+x+(w&&"("===c?")":""),b)for(i=-1,u=t.length;++i(f=t.charCodeAt(i))||f>57){x=(46===f?o+t.slice(i+1):t.slice(i))+x,t=t.slice(0,i);break}}h&&!s&&(t=r(t,1/0));var M=m.length+t.length+x.length,N=M>1)+m+t+x+N.slice(M);break;default:t=N+m+t+x}return a(t)}return d=null==d?6:/[gprs]/.test(v)?Math.max(1,Math.min(21,d)):Math.max(0,Math.min(20,d)),m.toString=function(){return t+""},m}return{format:c,formatPrefix:function(t,n){var e=c(((t=ya(t)).type="f",t)),r=3*Math.max(-8,Math.min(8,Math.floor(pa(n)/3))),i=Math.pow(10,-r),o=Ma[8+r/3];return function(t){return e(i*t)+o}}}}function Aa(n){return wa=Na(n),t.format=wa.format,t.formatPrefix=wa.formatPrefix,wa}function ka(t){return Math.max(0,-pa(Math.abs(t)))}function Sa(t,n){return Math.max(0,3*Math.max(-8,Math.min(8,Math.floor(pa(n)/3)))-pa(Math.abs(t)))}function Ta(t,n){return t=Math.abs(t),n=Math.abs(n)-t,Math.max(0,pa(n)-pa(t))+1}function Ea(){return new Ca}function Ca(){this.reset()}Aa({decimal:".",thousands:",",grouping:[3],currency:["$",""]}),Ca.prototype={constructor:Ca,reset:function(){this.s=this.t=0},add:function(t){za(Pa,t,this.t),za(this,Pa.s,this.s),this.s?this.t+=Pa.t:this.s=Pa.t},valueOf:function(){return this.s}};var Pa=new Ca;function za(t,n,e){var r=t.s=n+e,i=r-n,o=r-i;t.t=n-o+(e-i)}var Ra=1e-6,qa=1e-12,Da=Math.PI,La=Da/2,Ua=Da/4,Oa=2*Da,Ya=180/Da,Ba=Da/180,Fa=Math.abs,Ia=Math.atan,Ha=Math.atan2,ja=Math.cos,Xa=Math.ceil,Ga=Math.exp,Va=Math.log,$a=Math.pow,Wa=Math.sin,Za=Math.sign||function(t){return t>0?1:t<0?-1:0},Qa=Math.sqrt,Ja=Math.tan;function Ka(t){return t>1?0:t<-1?Da:Math.acos(t)}function tu(t){return t>1?La:t<-1?-La:Math.asin(t)}function nu(t){return(t=Wa(t/2))*t}function eu(){}function ru(t,n){t&&ou.hasOwnProperty(t.type)&&ou[t.type](t,n)}var iu={Feature:function(t,n){ru(t.geometry,n)},FeatureCollection:function(t,n){for(var e=t.features,r=-1,i=e.length;++r=0?1:-1,i=r*e,o=ja(n=(n*=Ba)/2+Ua),a=Wa(n),u=du*a,c=hu*o+u*ja(i),f=u*r*Wa(i);pu.add(Ha(f,c)),lu=t,hu=o,du=a}function xu(t){return[Ha(t[1],t[0]),tu(t[2])]}function wu(t){var n=t[0],e=t[1],r=ja(e);return[r*ja(n),r*Wa(n),Wa(e)]}function Mu(t,n){return t[0]*n[0]+t[1]*n[1]+t[2]*n[2]}function Nu(t,n){return[t[1]*n[2]-t[2]*n[1],t[2]*n[0]-t[0]*n[2],t[0]*n[1]-t[1]*n[0]]}function Au(t,n){t[0]+=n[0],t[1]+=n[1],t[2]+=n[2]}function ku(t,n){return[t[0]*n,t[1]*n,t[2]*n]}function Su(t){var n=Qa(t[0]*t[0]+t[1]*t[1]+t[2]*t[2]);t[0]/=n,t[1]/=n,t[2]/=n}var Tu,Eu,Cu,Pu,zu,Ru,qu,Du,Lu,Uu,Ou,Yu,Bu,Fu,Iu,Hu,ju,Xu,Gu,Vu,$u,Wu,Zu,Qu,Ju,Ku,tc=Ea(),nc={point:ec,lineStart:ic,lineEnd:oc,polygonStart:function(){nc.point=ac,nc.lineStart=uc,nc.lineEnd=cc,tc.reset(),gu.polygonStart()},polygonEnd:function(){gu.polygonEnd(),nc.point=ec,nc.lineStart=ic,nc.lineEnd=oc,pu<0?(Tu=-(Cu=180),Eu=-(Pu=90)):tc>Ra?Pu=90:tc<-Ra&&(Eu=-90),Uu[0]=Tu,Uu[1]=Cu}};function ec(t,n){Lu.push(Uu=[Tu=t,Cu=t]),nPu&&(Pu=n)}function rc(t,n){var e=wu([t*Ba,n*Ba]);if(Du){var r=Nu(Du,e),i=Nu([r[1],-r[0],0],r);Su(i),i=xu(i);var o,a=t-zu,u=a>0?1:-1,c=i[0]*Ya*u,f=Fa(a)>180;f^(u*zuPu&&(Pu=o):f^(u*zu<(c=(c+360)%360-180)&&cPu&&(Pu=n)),f?tfc(Tu,Cu)&&(Cu=t):fc(t,Cu)>fc(Tu,Cu)&&(Tu=t):Cu>=Tu?(tCu&&(Cu=t)):t>zu?fc(Tu,t)>fc(Tu,Cu)&&(Cu=t):fc(t,Cu)>fc(Tu,Cu)&&(Tu=t)}else Lu.push(Uu=[Tu=t,Cu=t]);nPu&&(Pu=n),Du=e,zu=t}function ic(){nc.point=rc}function oc(){Uu[0]=Tu,Uu[1]=Cu,nc.point=ec,Du=null}function ac(t,n){if(Du){var e=t-zu;tc.add(Fa(e)>180?e+(e>0?360:-360):e)}else Ru=t,qu=n;gu.point(t,n),rc(t,n)}function uc(){gu.lineStart()}function cc(){ac(Ru,qu),gu.lineEnd(),Fa(tc)>Ra&&(Tu=-(Cu=180)),Uu[0]=Tu,Uu[1]=Cu,Du=null}function fc(t,n){return(n-=t)<0?n+360:n}function sc(t,n){return t[0]-n[0]}function lc(t,n){return t[0]<=t[1]?t[0]<=n&&n<=t[1]:nDa?t+Math.round(-t/Oa)*Oa:t,n]}function kc(t,n,e){return(t%=Oa)?n||e?Nc(Tc(t),Ec(n,e)):Tc(t):n||e?Ec(n,e):Ac}function Sc(t){return function(n,e){return[(n+=t)>Da?n-Oa:n<-Da?n+Oa:n,e]}}function Tc(t){var n=Sc(t);return n.invert=Sc(-t),n}function Ec(t,n){var e=ja(t),r=Wa(t),i=ja(n),o=Wa(n);function a(t,n){var a=ja(n),u=ja(t)*a,c=Wa(t)*a,f=Wa(n),s=f*e+u*r;return[Ha(c*i-s*o,u*e-f*r),tu(s*i+c*o)]}return a.invert=function(t,n){var a=ja(n),u=ja(t)*a,c=Wa(t)*a,f=Wa(n),s=f*i-c*o;return[Ha(c*i+f*o,u*e+s*r),tu(s*e-u*r)]},a}function Cc(t){function n(n){return(n=t(n[0]*Ba,n[1]*Ba))[0]*=Ya,n[1]*=Ya,n}return t=kc(t[0]*Ba,t[1]*Ba,t.length>2?t[2]*Ba:0),n.invert=function(n){return(n=t.invert(n[0]*Ba,n[1]*Ba))[0]*=Ya,n[1]*=Ya,n},n}function Pc(t,n,e,r,i,o){if(e){var a=ja(n),u=Wa(n),c=r*e;null==i?(i=n+r*Oa,o=n-c/2):(i=zc(a,i),o=zc(a,o),(r>0?io)&&(i+=r*Oa));for(var f,s=i;r>0?s>o:s1&&n.push(n.pop().concat(n.shift()))},result:function(){var e=n;return n=[],t=null,e}}}function qc(t,n){return Fa(t[0]-n[0])=0;--o)i.point((s=f[o])[0],s[1]);else r(h.x,h.p.x,-1,i);h=h.p}f=(h=h.o).z,d=!d}while(!h.v);i.lineEnd()}}}function Uc(t){if(n=t.length){for(var n,e,r=0,i=t[0];++r=0?1:-1,A=N*M,k=A>Da,S=v*x;if(Oc.add(Ha(S*N*Wa(A),g*w+S*ja(A))),a+=k?M+N*Oa:M,k^d>=e^b>=e){var T=Nu(wu(h),wu(_));Su(T);var E=Nu(o,T);Su(E);var C=(k^M>=0?-1:1)*tu(E[2]);(r>C||r===C&&(T[0]||T[1]))&&(u+=k^M>=0?1:-1)}}return(a<-Ra||a0){for(l||(i.polygonStart(),l=!0),i.lineStart(),t=0;t1&&2&c&&h.push(h.pop().concat(h.shift())),a.push(h.filter(Fc))}return h}}function Fc(t){return t.length>1}function Ic(t,n){return((t=t.x)[0]<0?t[1]-La-Ra:La-t[1])-((n=n.x)[0]<0?n[1]-La-Ra:La-n[1])}var Hc=Bc(function(){return!0},function(t){var n,e=NaN,r=NaN,i=NaN;return{lineStart:function(){t.lineStart(),n=1},point:function(o,a){var u=o>0?Da:-Da,c=Fa(o-e);Fa(c-Da)0?La:-La),t.point(i,r),t.lineEnd(),t.lineStart(),t.point(u,r),t.point(o,r),n=0):i!==u&&c>=Da&&(Fa(e-i)Ra?Ia((Wa(n)*(o=ja(r))*Wa(e)-Wa(r)*(i=ja(n))*Wa(t))/(i*o*a)):(n+r)/2}(e,r,o,a),t.point(i,r),t.lineEnd(),t.lineStart(),t.point(u,r),n=0),t.point(e=o,r=a),i=u},lineEnd:function(){t.lineEnd(),e=r=NaN},clean:function(){return 2-n}}},function(t,n,e,r){var i;if(null==t)i=e*La,r.point(-Da,i),r.point(0,i),r.point(Da,i),r.point(Da,0),r.point(Da,-i),r.point(0,-i),r.point(-Da,-i),r.point(-Da,0),r.point(-Da,i);else if(Fa(t[0]-n[0])>Ra){var o=t[0]0,i=Fa(n)>Ra;function o(t,e){return ja(t)*ja(e)>n}function a(t,e,r){var i=[1,0,0],o=Nu(wu(t),wu(e)),a=Mu(o,o),u=o[0],c=a-u*u;if(!c)return!r&&t;var f=n*a/c,s=-n*u/c,l=Nu(i,o),h=ku(i,f);Au(h,ku(o,s));var d=l,p=Mu(h,d),v=Mu(d,d),g=p*p-v*(Mu(h,h)-1);if(!(g<0)){var y=Qa(g),_=ku(d,(-p-y)/v);if(Au(_,h),_=xu(_),!r)return _;var b,m=t[0],x=e[0],w=t[1],M=e[1];x0^_[1]<(Fa(_[0]-m)Da^(m<=_[0]&&_[0]<=x)){var k=ku(d,(-p+y)/v);return Au(k,h),[_,xu(k)]}}}function u(n,e){var i=r?t:Da-t,o=0;return n<-i?o|=1:n>i&&(o|=2),e<-i?o|=4:e>i&&(o|=8),o}return Bc(o,function(t){var n,e,c,f,s;return{lineStart:function(){f=c=!1,s=1},point:function(l,h){var d,p=[l,h],v=o(l,h),g=r?v?0:u(l,h):v?u(l+(l<0?Da:-Da),h):0;if(!n&&(f=c=v)&&t.lineStart(),v!==c&&(!(d=a(n,p))||qc(n,d)||qc(p,d))&&(p[0]+=Ra,p[1]+=Ra,v=o(p[0],p[1])),v!==c)s=0,v?(t.lineStart(),d=a(p,n),t.point(d[0],d[1])):(d=a(n,p),t.point(d[0],d[1]),t.lineEnd()),n=d;else if(i&&n&&r^v){var y;g&e||!(y=a(p,n,!0))||(s=0,r?(t.lineStart(),t.point(y[0][0],y[0][1]),t.point(y[1][0],y[1][1]),t.lineEnd()):(t.point(y[1][0],y[1][1]),t.lineEnd(),t.lineStart(),t.point(y[0][0],y[0][1])))}!v||n&&qc(n,p)||t.point(p[0],p[1]),n=p,c=v,e=g},lineEnd:function(){c&&t.lineEnd(),n=null},clean:function(){return s|(f&&c)<<1}}},function(n,r,i,o){Pc(o,t,e,i,n,r)},r?[0,-t]:[-Da,t-Da])}var Xc=1e9,Gc=-Xc;function Vc(t,n,e,r){function i(i,o){return t<=i&&i<=e&&n<=o&&o<=r}function o(i,o,u,f){var s=0,l=0;if(null==i||(s=a(i,u))!==(l=a(o,u))||c(i,o)<0^u>0)do{f.point(0===s||3===s?t:e,s>1?r:n)}while((s=(s+u+4)%4)!==l);else f.point(o[0],o[1])}function a(r,i){return Fa(r[0]-t)0?0:3:Fa(r[0]-e)0?2:1:Fa(r[1]-n)0?1:0:i>0?3:2}function u(t,n){return c(t.x,n.x)}function c(t,n){var e=a(t,1),r=a(n,1);return e!==r?e-r:0===e?n[1]-t[1]:1===e?t[0]-n[0]:2===e?t[1]-n[1]:n[0]-t[0]}return function(a){var c,f,s,l,h,d,p,v,g,y,_,b=a,m=Rc(),x={point:w,lineStart:function(){x.point=M,f&&f.push(s=[]);y=!0,g=!1,p=v=NaN},lineEnd:function(){c&&(M(l,h),d&&g&&m.rejoin(),c.push(m.result()));x.point=w,g&&b.lineEnd()},polygonStart:function(){b=m,c=[],f=[],_=!0},polygonEnd:function(){var n=function(){for(var n=0,e=0,i=f.length;er&&(h-o)*(r-a)>(d-a)*(t-o)&&++n:d<=r&&(h-o)*(r-a)<(d-a)*(t-o)&&--n;return n}(),e=_&&n,i=(c=k(c)).length;(e||i)&&(a.polygonStart(),e&&(a.lineStart(),o(null,null,1,a),a.lineEnd()),i&&Lc(c,u,n,o,a),a.polygonEnd());b=a,c=f=s=null}};function w(t,n){i(t,n)&&b.point(t,n)}function M(o,a){var u=i(o,a);if(f&&s.push([o,a]),y)l=o,h=a,d=u,y=!1,u&&(b.lineStart(),b.point(o,a));else if(u&&g)b.point(o,a);else{var c=[p=Math.max(Gc,Math.min(Xc,p)),v=Math.max(Gc,Math.min(Xc,v))],m=[o=Math.max(Gc,Math.min(Xc,o)),a=Math.max(Gc,Math.min(Xc,a))];!function(t,n,e,r,i,o){var a,u=t[0],c=t[1],f=0,s=1,l=n[0]-u,h=n[1]-c;if(a=e-u,l||!(a>0)){if(a/=l,l<0){if(a0){if(a>s)return;a>f&&(f=a)}if(a=i-u,l||!(a<0)){if(a/=l,l<0){if(a>s)return;a>f&&(f=a)}else if(l>0){if(a0)){if(a/=h,h<0){if(a0){if(a>s)return;a>f&&(f=a)}if(a=o-c,h||!(a<0)){if(a/=h,h<0){if(a>s)return;a>f&&(f=a)}else if(h>0){if(a0&&(t[0]=u+f*l,t[1]=c+f*h),s<1&&(n[0]=u+s*l,n[1]=c+s*h),!0}}}}}(c,m,t,n,e,r)?u&&(b.lineStart(),b.point(o,a),_=!1):(g||(b.lineStart(),b.point(c[0],c[1])),b.point(m[0],m[1]),u||b.lineEnd(),_=!1)}p=o,v=a,g=u}return x}}var $c,Wc,Zc,Qc=Ea(),Jc={sphere:eu,point:eu,lineStart:function(){Jc.point=tf,Jc.lineEnd=Kc},lineEnd:eu,polygonStart:eu,polygonEnd:eu};function Kc(){Jc.point=Jc.lineEnd=eu}function tf(t,n){$c=t*=Ba,Wc=Wa(n*=Ba),Zc=ja(n),Jc.point=nf}function nf(t,n){t*=Ba;var e=Wa(n*=Ba),r=ja(n),i=Fa(t-$c),o=ja(i),a=r*Wa(i),u=Zc*e-Wc*r*o,c=Wc*e+Zc*r*o;Qc.add(Ha(Qa(a*a+u*u),c)),$c=t,Wc=e,Zc=r}function ef(t){return Qc.reset(),cu(t,Jc),+Qc}var rf=[null,null],of={type:"LineString",coordinates:rf};function af(t,n){return rf[0]=t,rf[1]=n,ef(of)}var uf={Feature:function(t,n){return ff(t.geometry,n)},FeatureCollection:function(t,n){for(var e=t.features,r=-1,i=e.length;++rRa}).map(c)).concat(g(Xa(o/d)*d,i,d).filter(function(t){return Fa(t%v)>Ra}).map(f))}return _.lines=function(){return b().map(function(t){return{type:"LineString",coordinates:t}})},_.outline=function(){return{type:"Polygon",coordinates:[s(r).concat(l(a).slice(1),s(e).reverse().slice(1),l(u).reverse().slice(1))]}},_.extent=function(t){return arguments.length?_.extentMajor(t).extentMinor(t):_.extentMinor()},_.extentMajor=function(t){return arguments.length?(r=+t[0][0],e=+t[1][0],u=+t[0][1],a=+t[1][1],r>e&&(t=r,r=e,e=t),u>a&&(t=u,u=a,a=t),_.precision(y)):[[r,u],[e,a]]},_.extentMinor=function(e){return arguments.length?(n=+e[0][0],t=+e[1][0],o=+e[0][1],i=+e[1][1],n>t&&(e=n,n=t,t=e),o>i&&(e=o,o=i,i=e),_.precision(y)):[[n,o],[t,i]]},_.step=function(t){return arguments.length?_.stepMajor(t).stepMinor(t):_.stepMinor()},_.stepMajor=function(t){return arguments.length?(p=+t[0],v=+t[1],_):[p,v]},_.stepMinor=function(t){return arguments.length?(h=+t[0],d=+t[1],_):[h,d]},_.precision=function(h){return arguments.length?(y=+h,c=vf(o,i,90),f=gf(n,t,y),s=vf(u,a,90),l=gf(r,e,y),_):y},_.extentMajor([[-180,-90+Ra],[180,90-Ra]]).extentMinor([[-180,-80-Ra],[180,80+Ra]])}function _f(t){return t}var bf,mf,xf,wf,Mf=Ea(),Nf=Ea(),Af={point:eu,lineStart:eu,lineEnd:eu,polygonStart:function(){Af.lineStart=kf,Af.lineEnd=Ef},polygonEnd:function(){Af.lineStart=Af.lineEnd=Af.point=eu,Mf.add(Fa(Nf)),Nf.reset()},result:function(){var t=Mf/2;return Mf.reset(),t}};function kf(){Af.point=Sf}function Sf(t,n){Af.point=Tf,bf=xf=t,mf=wf=n}function Tf(t,n){Nf.add(wf*t-xf*n),xf=t,wf=n}function Ef(){Tf(bf,mf)}var Cf=1/0,Pf=Cf,zf=-Cf,Rf=zf,qf={point:function(t,n){tzf&&(zf=t);nRf&&(Rf=n)},lineStart:eu,lineEnd:eu,polygonStart:eu,polygonEnd:eu,result:function(){var t=[[Cf,Pf],[zf,Rf]];return zf=Rf=-(Pf=Cf=1/0),t}};var Df,Lf,Uf,Of,Yf=0,Bf=0,Ff=0,If=0,Hf=0,jf=0,Xf=0,Gf=0,Vf=0,$f={point:Wf,lineStart:Zf,lineEnd:Kf,polygonStart:function(){$f.lineStart=ts,$f.lineEnd=ns},polygonEnd:function(){$f.point=Wf,$f.lineStart=Zf,$f.lineEnd=Kf},result:function(){var t=Vf?[Xf/Vf,Gf/Vf]:jf?[If/jf,Hf/jf]:Ff?[Yf/Ff,Bf/Ff]:[NaN,NaN];return Yf=Bf=Ff=If=Hf=jf=Xf=Gf=Vf=0,t}};function Wf(t,n){Yf+=t,Bf+=n,++Ff}function Zf(){$f.point=Qf}function Qf(t,n){$f.point=Jf,Wf(Uf=t,Of=n)}function Jf(t,n){var e=t-Uf,r=n-Of,i=Qa(e*e+r*r);If+=i*(Uf+t)/2,Hf+=i*(Of+n)/2,jf+=i,Wf(Uf=t,Of=n)}function Kf(){$f.point=Wf}function ts(){$f.point=es}function ns(){rs(Df,Lf)}function es(t,n){$f.point=rs,Wf(Df=Uf=t,Lf=Of=n)}function rs(t,n){var e=t-Uf,r=n-Of,i=Qa(e*e+r*r);If+=i*(Uf+t)/2,Hf+=i*(Of+n)/2,jf+=i,Xf+=(i=Of*t-Uf*n)*(Uf+t),Gf+=i*(Of+n),Vf+=3*i,Wf(Uf=t,Of=n)}function is(t){this._context=t}is.prototype={_radius:4.5,pointRadius:function(t){return this._radius=t,this},polygonStart:function(){this._line=0},polygonEnd:function(){this._line=NaN},lineStart:function(){this._point=0},lineEnd:function(){0===this._line&&this._context.closePath(),this._point=NaN},point:function(t,n){switch(this._point){case 0:this._context.moveTo(t,n),this._point=1;break;case 1:this._context.lineTo(t,n);break;default:this._context.moveTo(t+this._radius,n),this._context.arc(t,n,this._radius,0,Oa)}},result:eu};var os,as,us,cs,fs,ss=Ea(),ls={point:eu,lineStart:function(){ls.point=hs},lineEnd:function(){os&&ds(as,us),ls.point=eu},polygonStart:function(){os=!0},polygonEnd:function(){os=null},result:function(){var t=+ss;return ss.reset(),t}};function hs(t,n){ls.point=ds,as=cs=t,us=fs=n}function ds(t,n){cs-=t,fs-=n,ss.add(Qa(cs*cs+fs*fs)),cs=t,fs=n}function ps(){this._string=[]}function vs(t){return"m0,"+t+"a"+t+","+t+" 0 1,1 0,"+-2*t+"a"+t+","+t+" 0 1,1 0,"+2*t+"z"}function gs(t){return function(n){var e=new ys;for(var r in t)e[r]=t[r];return e.stream=n,e}}function ys(){}function _s(t,n,e){var r=t.clipExtent&&t.clipExtent();return t.scale(150).translate([0,0]),null!=r&&t.clipExtent(null),cu(e,t.stream(qf)),n(qf.result()),null!=r&&t.clipExtent(r),t}function bs(t,n,e){return _s(t,function(e){var r=n[1][0]-n[0][0],i=n[1][1]-n[0][1],o=Math.min(r/(e[1][0]-e[0][0]),i/(e[1][1]-e[0][1])),a=+n[0][0]+(r-o*(e[1][0]+e[0][0]))/2,u=+n[0][1]+(i-o*(e[1][1]+e[0][1]))/2;t.scale(150*o).translate([a,u])},e)}function ms(t,n,e){return bs(t,[[0,0],n],e)}function xs(t,n,e){return _s(t,function(e){var r=+n,i=r/(e[1][0]-e[0][0]),o=(r-i*(e[1][0]+e[0][0]))/2,a=-i*e[0][1];t.scale(150*i).translate([o,a])},e)}function ws(t,n,e){return _s(t,function(e){var r=+n,i=r/(e[1][1]-e[0][1]),o=-i*e[0][0],a=(r-i*(e[1][1]+e[0][1]))/2;t.scale(150*i).translate([o,a])},e)}ps.prototype={_radius:4.5,_circle:vs(4.5),pointRadius:function(t){return(t=+t)!==this._radius&&(this._radius=t,this._circle=null),this},polygonStart:function(){this._line=0},polygonEnd:function(){this._line=NaN},lineStart:function(){this._point=0},lineEnd:function(){0===this._line&&this._string.push("Z"),this._point=NaN},point:function(t,n){switch(this._point){case 0:this._string.push("M",t,",",n),this._point=1;break;case 1:this._string.push("L",t,",",n);break;default:null==this._circle&&(this._circle=vs(this._radius)),this._string.push("M",t,",",n,this._circle)}},result:function(){if(this._string.length){var t=this._string.join("");return this._string=[],t}return null}},ys.prototype={constructor:ys,point:function(t,n){this.stream.point(t,n)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}};var Ms=16,Ns=ja(30*Ba);function As(t,n){return+n?function(t,n){function e(r,i,o,a,u,c,f,s,l,h,d,p,v,g){var y=f-r,_=s-i,b=y*y+_*_;if(b>4*n&&v--){var m=a+h,x=u+d,w=c+p,M=Qa(m*m+x*x+w*w),N=tu(w/=M),A=Fa(Fa(w)-1)n||Fa((y*E+_*C)/b-.5)>.3||a*h+u*d+c*p2?t[2]%360*Ba:0,S()):[g*Ya,y*Ya,_*Ya]},A.angle=function(t){return arguments.length?(b=t%360*Ba,S()):b*Ya},A.precision=function(t){return arguments.length?(a=As(u,N=t*t),T()):Qa(N)},A.fitExtent=function(t,n){return bs(A,t,n)},A.fitSize=function(t,n){return ms(A,t,n)},A.fitWidth=function(t,n){return xs(A,t,n)},A.fitHeight=function(t,n){return ws(A,t,n)},function(){return n=t.apply(this,arguments),A.invert=n.invert&&k,S()}}function Cs(t){var n=0,e=Da/3,r=Es(t),i=r(n,e);return i.parallels=function(t){return arguments.length?r(n=t[0]*Ba,e=t[1]*Ba):[n*Ya,e*Ya]},i}function Ps(t,n){var e=Wa(t),r=(e+Wa(n))/2;if(Fa(r)0?n<-La+Ra&&(n=-La+Ra):n>La-Ra&&(n=La-Ra);var e=i/$a(Bs(n),r);return[e*Wa(r*t),i-e*ja(r*t)]}return o.invert=function(t,n){var e=i-n,o=Za(r)*Qa(t*t+e*e);return[Ha(t,Fa(e))/r*Za(e),2*Ia($a(i/o,1/r))-La]},o}function Is(t,n){return[t,n]}function Hs(t,n){var e=ja(t),r=t===n?Wa(t):(e-ja(n))/(n-t),i=e/r+t;if(Fa(r)=0;)n+=e[r].value;else n=1;t.value=n}function al(t,n){var e,r,i,o,a,u=new sl(t),c=+t.value&&(u.value=t.value),f=[u];for(null==n&&(n=ul);e=f.pop();)if(c&&(e.value=+e.data.value),(i=n(e.data))&&(a=i.length))for(e.children=new Array(a),o=a-1;o>=0;--o)f.push(r=e.children[o]=new sl(i[o])),r.parent=e,r.depth=e.depth+1;return u.eachBefore(fl)}function ul(t){return t.children}function cl(t){t.data=t.data.data}function fl(t){var n=0;do{t.height=n}while((t=t.parent)&&t.height<++n)}function sl(t){this.data=t,this.depth=this.height=0,this.parent=null}Ws.invert=function(t,n){for(var e,r=n,i=r*r,o=i*i*i,a=0;a<12&&(o=(i=(r-=e=(r*(js+Xs*i+o*(Gs+Vs*i))-n)/(js+3*Xs*i+o*(7*Gs+9*Vs*i)))*r)*i*i,!(Fa(e)Ra&&--i>0);return[t/(.8707+(o=r*r)*(o*(o*o*o*(.003971-.001529*o)-.013791)-.131979)),r]},Ks.invert=Ds(tu),tl.invert=Ds(function(t){return 2*Ia(t)}),nl.invert=function(t,n){return[-n,2*Ia(Ga(t))-La]},sl.prototype=al.prototype={constructor:sl,count:function(){return this.eachAfter(ol)},each:function(t){var n,e,r,i,o=this,a=[o];do{for(n=a.reverse(),a=[];o=n.pop();)if(t(o),e=o.children)for(r=0,i=e.length;r=0;--e)i.push(n[e]);return this},sum:function(t){return this.eachAfter(function(n){for(var e=+t(n.data)||0,r=n.children,i=r&&r.length;--i>=0;)e+=r[i].value;n.value=e})},sort:function(t){return this.eachBefore(function(n){n.children&&n.children.sort(t)})},path:function(t){for(var n=this,e=function(t,n){if(t===n)return t;var e=t.ancestors(),r=n.ancestors(),i=null;for(t=e.pop(),n=r.pop();t===n;)i=t,t=e.pop(),n=r.pop();return i}(n,t),r=[n];n!==e;)n=n.parent,r.push(n);for(var i=r.length;t!==e;)r.splice(i,0,t),t=t.parent;return r},ancestors:function(){for(var t=this,n=[t];t=t.parent;)n.push(t);return n},descendants:function(){var t=[];return this.each(function(n){t.push(n)}),t},leaves:function(){var t=[];return this.eachBefore(function(n){n.children||t.push(n)}),t},links:function(){var t=this,n=[];return t.each(function(e){e!==t&&n.push({source:e.parent,target:e})}),n},copy:function(){return al(this).eachBefore(cl)}};var ll=Array.prototype.slice;function hl(t){for(var n,e,r=0,i=(t=function(t){for(var n,e,r=t.length;r;)e=Math.random()*r--|0,n=t[r],t[r]=t[e],t[e]=n;return t}(ll.call(t))).length,o=[];r0&&e*e>r*r+i*i}function gl(t,n){for(var e=0;e(a*=a)?(r=(f+a-i)/(2*f),o=Math.sqrt(Math.max(0,a/f-r*r)),e.x=t.x-r*u-o*c,e.y=t.y-r*c+o*u):(r=(f+i-a)/(2*f),o=Math.sqrt(Math.max(0,i/f-r*r)),e.x=n.x+r*u-o*c,e.y=n.y+r*c+o*u)):(e.x=n.x+e.r,e.y=n.y)}function xl(t,n){var e=t.r+n.r-1e-6,r=n.x-t.x,i=n.y-t.y;return e>0&&e*e>r*r+i*i}function wl(t){var n=t._,e=t.next._,r=n.r+e.r,i=(n.x*e.r+e.x*n.r)/r,o=(n.y*e.r+e.y*n.r)/r;return i*i+o*o}function Ml(t){this._=t,this.next=null,this.previous=null}function Nl(t){if(!(i=t.length))return 0;var n,e,r,i,o,a,u,c,f,s,l;if((n=t[0]).x=0,n.y=0,!(i>1))return n.r;if(e=t[1],n.x=-e.r,e.x=n.r,e.y=0,!(i>2))return n.r+e.r;ml(e,n,r=t[2]),n=new Ml(n),e=new Ml(e),r=new Ml(r),n.next=r.previous=e,e.next=n.previous=r,r.next=e.previous=n;t:for(u=3;uh&&(h=u),g=s*s*v,(d=Math.max(h/g,g/l))>p){s-=u;break}p=d}y.push(a={value:s,dice:c1?n:1)},e}(Gl);var Wl=function t(n){function e(t,e,r,i,o){if((a=t._squarify)&&a.ratio===n)for(var a,u,c,f,s,l=-1,h=a.length,d=t.value;++l1?n:1)},e}(Gl);function Zl(t,n){return t[0]-n[0]||t[1]-n[1]}function Ql(t){for(var n,e,r,i=t.length,o=[0,1],a=2,u=2;u1&&(n=t[o[a-2]],e=t[o[a-1]],r=t[u],(e[0]-n[0])*(r[1]-n[1])-(e[1]-n[1])*(r[0]-n[0])<=0);)--a;o[a++]=u}return o.slice(0,a)}function Jl(){return Math.random()}var Kl=function t(n){function e(t,e){return t=null==t?0:+t,e=null==e?1:+e,1===arguments.length?(e=t,t=0):e-=t,function(){return n()*e+t}}return e.source=t,e}(Jl),th=function t(n){function e(t,e){var r,i;return t=null==t?0:+t,e=null==e?1:+e,function(){var o;if(null!=r)o=r,r=null;else do{r=2*n()-1,o=2*n()-1,i=r*r+o*o}while(!i||i>1);return t+e*o*Math.sqrt(-2*Math.log(i)/i)}}return e.source=t,e}(Jl),nh=function t(n){function e(){var t=th.source(n).apply(this,arguments);return function(){return Math.exp(t())}}return e.source=t,e}(Jl),eh=function t(n){function e(t){return function(){for(var e=0,r=0;rr&&(n=e,e=r,r=n),function(t){return Math.max(e,Math.min(r,t))}}function _h(t,n,e){var r=t[0],i=t[1],o=n[0],a=n[1];return i2?bh:_h,i=o=null,l}function l(n){return isNaN(n=+n)?e:(i||(i=r(a.map(t),u,c)))(t(f(n)))}return l.invert=function(e){return f(n((o||(o=r(u,a.map(t),he)))(e)))},l.domain=function(t){return arguments.length?(a=ch.call(t,dh),f===vh||(f=yh(a)),s()):a.slice()},l.range=function(t){return arguments.length?(u=fh.call(t),s()):u.slice()},l.rangeRound=function(t){return u=fh.call(t),c=_e,s()},l.clamp=function(t){return arguments.length?(f=t?yh(a):vh,l):f!==vh},l.interpolate=function(t){return arguments.length?(c=t,s()):c},l.unknown=function(t){return arguments.length?(e=t,l):e},function(e,r){return t=e,n=r,s()}}function wh(t,n){return xh()(t,n)}function Mh(n,e,r,i){var o,a=w(n,e,r);switch((i=ya(null==i?",f":i)).type){case"s":var u=Math.max(Math.abs(n),Math.abs(e));return null!=i.precision||isNaN(o=Sa(a,u))||(i.precision=o),t.formatPrefix(i,u);case"":case"e":case"g":case"p":case"r":null!=i.precision||isNaN(o=Ta(a,Math.max(Math.abs(n),Math.abs(e))))||(i.precision=o-("e"===i.type));break;case"f":case"%":null!=i.precision||isNaN(o=ka(a))||(i.precision=o-2*("%"===i.type))}return t.format(i)}function Nh(t){var n=t.domain;return t.ticks=function(t){var e=n();return m(e[0],e[e.length-1],null==t?10:t)},t.tickFormat=function(t,e){var r=n();return Mh(r[0],r[r.length-1],null==t?10:t,e)},t.nice=function(e){null==e&&(e=10);var r,i=n(),o=0,a=i.length-1,u=i[o],c=i[a];return c0?r=x(u=Math.floor(u/r)*r,c=Math.ceil(c/r)*r,e):r<0&&(r=x(u=Math.ceil(u*r)/r,c=Math.floor(c*r)/r,e)),r>0?(i[o]=Math.floor(u/r)*r,i[a]=Math.ceil(c/r)*r,n(i)):r<0&&(i[o]=Math.ceil(u*r)/r,i[a]=Math.floor(c*r)/r,n(i)),t},t}function Ah(t,n){var e,r=0,i=(t=t.slice()).length-1,o=t[r],a=t[i];return a0){for(;hc)break;v.push(l)}}else for(;h=1;--s)if(!((l=f*s)c)break;v.push(l)}}else v=m(h,d,Math.min(d-h,p)).map(r);return n?v.reverse():v},i.tickFormat=function(n,o){if(null==o&&(o=10===a?".0e":","),"function"!=typeof o&&(o=t.format(o)),n===1/0)return o;null==n&&(n=10);var u=Math.max(1,a*n/i.ticks().length);return function(t){var n=t/r(Math.round(e(t)));return n*a0))return u;do{u.push(a=new Date(+e)),n(e,o),t(e)}while(a=n)for(;t(n),!e(n);)n.setTime(n-1)},function(t,r){if(t>=t)if(r<0)for(;++r<=0;)for(;n(t,-1),!e(t););else for(;--r>=0;)for(;n(t,1),!e(t););})},e&&(i.count=function(n,r){return Fh.setTime(+n),Ih.setTime(+r),t(Fh),t(Ih),Math.floor(e(Fh,Ih))},i.every=function(t){return t=Math.floor(t),isFinite(t)&&t>0?t>1?i.filter(r?function(n){return r(n)%t==0}:function(n){return i.count(0,n)%t==0}):i:null}),i}var jh=Hh(function(){},function(t,n){t.setTime(+t+n)},function(t,n){return n-t});jh.every=function(t){return t=Math.floor(t),isFinite(t)&&t>0?t>1?Hh(function(n){n.setTime(Math.floor(n/t)*t)},function(n,e){n.setTime(+n+e*t)},function(n,e){return(e-n)/t}):jh:null};var Xh=jh.range,Gh=6e4,Vh=6048e5,$h=Hh(function(t){t.setTime(1e3*Math.floor(t/1e3))},function(t,n){t.setTime(+t+1e3*n)},function(t,n){return(n-t)/1e3},function(t){return t.getUTCSeconds()}),Wh=$h.range,Zh=Hh(function(t){t.setTime(Math.floor(t/Gh)*Gh)},function(t,n){t.setTime(+t+n*Gh)},function(t,n){return(n-t)/Gh},function(t){return t.getMinutes()}),Qh=Zh.range,Jh=Hh(function(t){var n=t.getTimezoneOffset()*Gh%36e5;n<0&&(n+=36e5),t.setTime(36e5*Math.floor((+t-n)/36e5)+n)},function(t,n){t.setTime(+t+36e5*n)},function(t,n){return(n-t)/36e5},function(t){return t.getHours()}),Kh=Jh.range,td=Hh(function(t){t.setHours(0,0,0,0)},function(t,n){t.setDate(t.getDate()+n)},function(t,n){return(n-t-(n.getTimezoneOffset()-t.getTimezoneOffset())*Gh)/864e5},function(t){return t.getDate()-1}),nd=td.range;function ed(t){return Hh(function(n){n.setDate(n.getDate()-(n.getDay()+7-t)%7),n.setHours(0,0,0,0)},function(t,n){t.setDate(t.getDate()+7*n)},function(t,n){return(n-t-(n.getTimezoneOffset()-t.getTimezoneOffset())*Gh)/Vh})}var rd=ed(0),id=ed(1),od=ed(2),ad=ed(3),ud=ed(4),cd=ed(5),fd=ed(6),sd=rd.range,ld=id.range,hd=od.range,dd=ad.range,pd=ud.range,vd=cd.range,gd=fd.range,yd=Hh(function(t){t.setDate(1),t.setHours(0,0,0,0)},function(t,n){t.setMonth(t.getMonth()+n)},function(t,n){return n.getMonth()-t.getMonth()+12*(n.getFullYear()-t.getFullYear())},function(t){return t.getMonth()}),_d=yd.range,bd=Hh(function(t){t.setMonth(0,1),t.setHours(0,0,0,0)},function(t,n){t.setFullYear(t.getFullYear()+n)},function(t,n){return n.getFullYear()-t.getFullYear()},function(t){return t.getFullYear()});bd.every=function(t){return isFinite(t=Math.floor(t))&&t>0?Hh(function(n){n.setFullYear(Math.floor(n.getFullYear()/t)*t),n.setMonth(0,1),n.setHours(0,0,0,0)},function(n,e){n.setFullYear(n.getFullYear()+e*t)}):null};var md=bd.range,xd=Hh(function(t){t.setUTCSeconds(0,0)},function(t,n){t.setTime(+t+n*Gh)},function(t,n){return(n-t)/Gh},function(t){return t.getUTCMinutes()}),wd=xd.range,Md=Hh(function(t){t.setUTCMinutes(0,0,0)},function(t,n){t.setTime(+t+36e5*n)},function(t,n){return(n-t)/36e5},function(t){return t.getUTCHours()}),Nd=Md.range,Ad=Hh(function(t){t.setUTCHours(0,0,0,0)},function(t,n){t.setUTCDate(t.getUTCDate()+n)},function(t,n){return(n-t)/864e5},function(t){return t.getUTCDate()-1}),kd=Ad.range;function Sd(t){return Hh(function(n){n.setUTCDate(n.getUTCDate()-(n.getUTCDay()+7-t)%7),n.setUTCHours(0,0,0,0)},function(t,n){t.setUTCDate(t.getUTCDate()+7*n)},function(t,n){return(n-t)/Vh})}var Td=Sd(0),Ed=Sd(1),Cd=Sd(2),Pd=Sd(3),zd=Sd(4),Rd=Sd(5),qd=Sd(6),Dd=Td.range,Ld=Ed.range,Ud=Cd.range,Od=Pd.range,Yd=zd.range,Bd=Rd.range,Fd=qd.range,Id=Hh(function(t){t.setUTCDate(1),t.setUTCHours(0,0,0,0)},function(t,n){t.setUTCMonth(t.getUTCMonth()+n)},function(t,n){return n.getUTCMonth()-t.getUTCMonth()+12*(n.getUTCFullYear()-t.getUTCFullYear())},function(t){return t.getUTCMonth()}),Hd=Id.range,jd=Hh(function(t){t.setUTCMonth(0,1),t.setUTCHours(0,0,0,0)},function(t,n){t.setUTCFullYear(t.getUTCFullYear()+n)},function(t,n){return n.getUTCFullYear()-t.getUTCFullYear()},function(t){return t.getUTCFullYear()});jd.every=function(t){return isFinite(t=Math.floor(t))&&t>0?Hh(function(n){n.setUTCFullYear(Math.floor(n.getUTCFullYear()/t)*t),n.setUTCMonth(0,1),n.setUTCHours(0,0,0,0)},function(n,e){n.setUTCFullYear(n.getUTCFullYear()+e*t)}):null};var Xd=jd.range;function Gd(t){if(0<=t.y&&t.y<100){var n=new Date(-1,t.m,t.d,t.H,t.M,t.S,t.L);return n.setFullYear(t.y),n}return new Date(t.y,t.m,t.d,t.H,t.M,t.S,t.L)}function Vd(t){if(0<=t.y&&t.y<100){var n=new Date(Date.UTC(-1,t.m,t.d,t.H,t.M,t.S,t.L));return n.setUTCFullYear(t.y),n}return new Date(Date.UTC(t.y,t.m,t.d,t.H,t.M,t.S,t.L))}function $d(t){return{y:t,m:0,d:1,H:0,M:0,S:0,L:0}}function Wd(t){var n=t.dateTime,e=t.date,r=t.time,i=t.periods,o=t.days,a=t.shortDays,u=t.months,c=t.shortMonths,f=rp(i),s=ip(i),l=rp(o),h=ip(o),d=rp(a),p=ip(a),v=rp(u),g=ip(u),y=rp(c),_=ip(c),b={a:function(t){return a[t.getDay()]},A:function(t){return o[t.getDay()]},b:function(t){return c[t.getMonth()]},B:function(t){return u[t.getMonth()]},c:null,d:Np,e:Np,f:Ep,H:Ap,I:kp,j:Sp,L:Tp,m:Cp,M:Pp,p:function(t){return i[+(t.getHours()>=12)]},Q:ov,s:av,S:zp,u:Rp,U:qp,V:Dp,w:Lp,W:Up,x:null,X:null,y:Op,Y:Yp,Z:Bp,"%":iv},m={a:function(t){return a[t.getUTCDay()]},A:function(t){return o[t.getUTCDay()]},b:function(t){return c[t.getUTCMonth()]},B:function(t){return u[t.getUTCMonth()]},c:null,d:Fp,e:Fp,f:Gp,H:Ip,I:Hp,j:jp,L:Xp,m:Vp,M:$p,p:function(t){return i[+(t.getUTCHours()>=12)]},Q:ov,s:av,S:Wp,u:Zp,U:Qp,V:Jp,w:Kp,W:tv,x:null,X:null,y:nv,Y:ev,Z:rv,"%":iv},x={a:function(t,n,e){var r=d.exec(n.slice(e));return r?(t.w=p[r[0].toLowerCase()],e+r[0].length):-1},A:function(t,n,e){var r=l.exec(n.slice(e));return r?(t.w=h[r[0].toLowerCase()],e+r[0].length):-1},b:function(t,n,e){var r=y.exec(n.slice(e));return r?(t.m=_[r[0].toLowerCase()],e+r[0].length):-1},B:function(t,n,e){var r=v.exec(n.slice(e));return r?(t.m=g[r[0].toLowerCase()],e+r[0].length):-1},c:function(t,e,r){return N(t,n,e,r)},d:pp,e:pp,f:mp,H:gp,I:gp,j:vp,L:bp,m:dp,M:yp,p:function(t,n,e){var r=f.exec(n.slice(e));return r?(t.p=s[r[0].toLowerCase()],e+r[0].length):-1},Q:wp,s:Mp,S:_p,u:ap,U:up,V:cp,w:op,W:fp,x:function(t,n,r){return N(t,e,n,r)},X:function(t,n,e){return N(t,r,n,e)},y:lp,Y:sp,Z:hp,"%":xp};function w(t,n){return function(e){var r,i,o,a=[],u=-1,c=0,f=t.length;for(e instanceof Date||(e=new Date(+e));++u53)return null;"w"in o||(o.w=1),"Z"in o?(i=(r=Vd($d(o.y))).getUTCDay(),r=i>4||0===i?Ed.ceil(r):Ed(r),r=Ad.offset(r,7*(o.V-1)),o.y=r.getUTCFullYear(),o.m=r.getUTCMonth(),o.d=r.getUTCDate()+(o.w+6)%7):(i=(r=n($d(o.y))).getDay(),r=i>4||0===i?id.ceil(r):id(r),r=td.offset(r,7*(o.V-1)),o.y=r.getFullYear(),o.m=r.getMonth(),o.d=r.getDate()+(o.w+6)%7)}else("W"in o||"U"in o)&&("w"in o||(o.w="u"in o?o.u%7:"W"in o?1:0),i="Z"in o?Vd($d(o.y)).getUTCDay():n($d(o.y)).getDay(),o.m=0,o.d="W"in o?(o.w+6)%7+7*o.W-(i+5)%7:o.w+7*o.U-(i+6)%7);return"Z"in o?(o.H+=o.Z/100|0,o.M+=o.Z%100,Vd(o)):n(o)}}function N(t,n,e,r){for(var i,o,a=0,u=n.length,c=e.length;a=c)return-1;if(37===(i=n.charCodeAt(a++))){if(i=n.charAt(a++),!(o=x[i in Qd?n.charAt(a++):i])||(r=o(t,e,r))<0)return-1}else if(i!=e.charCodeAt(r++))return-1}return r}return b.x=w(e,b),b.X=w(r,b),b.c=w(n,b),m.x=w(e,m),m.X=w(r,m),m.c=w(n,m),{format:function(t){var n=w(t+="",b);return n.toString=function(){return t},n},parse:function(t){var n=M(t+="",Gd);return n.toString=function(){return t},n},utcFormat:function(t){var n=w(t+="",m);return n.toString=function(){return t},n},utcParse:function(t){var n=M(t,Vd);return n.toString=function(){return t},n}}}var Zd,Qd={"-":"",_:" ",0:"0"},Jd=/^\s*\d+/,Kd=/^%/,tp=/[\\^$*+?|[\]().{}]/g;function np(t,n,e){var r=t<0?"-":"",i=(r?-t:t)+"",o=i.length;return r+(o68?1900:2e3),e+r[0].length):-1}function hp(t,n,e){var r=/^(Z)|([+-]\d\d)(?::?(\d\d))?/.exec(n.slice(e,e+6));return r?(t.Z=r[1]?0:-(r[2]+(r[3]||"00")),e+r[0].length):-1}function dp(t,n,e){var r=Jd.exec(n.slice(e,e+2));return r?(t.m=r[0]-1,e+r[0].length):-1}function pp(t,n,e){var r=Jd.exec(n.slice(e,e+2));return r?(t.d=+r[0],e+r[0].length):-1}function vp(t,n,e){var r=Jd.exec(n.slice(e,e+3));return r?(t.m=0,t.d=+r[0],e+r[0].length):-1}function gp(t,n,e){var r=Jd.exec(n.slice(e,e+2));return r?(t.H=+r[0],e+r[0].length):-1}function yp(t,n,e){var r=Jd.exec(n.slice(e,e+2));return r?(t.M=+r[0],e+r[0].length):-1}function _p(t,n,e){var r=Jd.exec(n.slice(e,e+2));return r?(t.S=+r[0],e+r[0].length):-1}function bp(t,n,e){var r=Jd.exec(n.slice(e,e+3));return r?(t.L=+r[0],e+r[0].length):-1}function mp(t,n,e){var r=Jd.exec(n.slice(e,e+6));return r?(t.L=Math.floor(r[0]/1e3),e+r[0].length):-1}function xp(t,n,e){var r=Kd.exec(n.slice(e,e+1));return r?e+r[0].length:-1}function wp(t,n,e){var r=Jd.exec(n.slice(e));return r?(t.Q=+r[0],e+r[0].length):-1}function Mp(t,n,e){var r=Jd.exec(n.slice(e));return r?(t.Q=1e3*+r[0],e+r[0].length):-1}function Np(t,n){return np(t.getDate(),n,2)}function Ap(t,n){return np(t.getHours(),n,2)}function kp(t,n){return np(t.getHours()%12||12,n,2)}function Sp(t,n){return np(1+td.count(bd(t),t),n,3)}function Tp(t,n){return np(t.getMilliseconds(),n,3)}function Ep(t,n){return Tp(t,n)+"000"}function Cp(t,n){return np(t.getMonth()+1,n,2)}function Pp(t,n){return np(t.getMinutes(),n,2)}function zp(t,n){return np(t.getSeconds(),n,2)}function Rp(t){var n=t.getDay();return 0===n?7:n}function qp(t,n){return np(rd.count(bd(t),t),n,2)}function Dp(t,n){var e=t.getDay();return t=e>=4||0===e?ud(t):ud.ceil(t),np(ud.count(bd(t),t)+(4===bd(t).getDay()),n,2)}function Lp(t){return t.getDay()}function Up(t,n){return np(id.count(bd(t),t),n,2)}function Op(t,n){return np(t.getFullYear()%100,n,2)}function Yp(t,n){return np(t.getFullYear()%1e4,n,4)}function Bp(t){var n=t.getTimezoneOffset();return(n>0?"-":(n*=-1,"+"))+np(n/60|0,"0",2)+np(n%60,"0",2)}function Fp(t,n){return np(t.getUTCDate(),n,2)}function Ip(t,n){return np(t.getUTCHours(),n,2)}function Hp(t,n){return np(t.getUTCHours()%12||12,n,2)}function jp(t,n){return np(1+Ad.count(jd(t),t),n,3)}function Xp(t,n){return np(t.getUTCMilliseconds(),n,3)}function Gp(t,n){return Xp(t,n)+"000"}function Vp(t,n){return np(t.getUTCMonth()+1,n,2)}function $p(t,n){return np(t.getUTCMinutes(),n,2)}function Wp(t,n){return np(t.getUTCSeconds(),n,2)}function Zp(t){var n=t.getUTCDay();return 0===n?7:n}function Qp(t,n){return np(Td.count(jd(t),t),n,2)}function Jp(t,n){var e=t.getUTCDay();return t=e>=4||0===e?zd(t):zd.ceil(t),np(zd.count(jd(t),t)+(4===jd(t).getUTCDay()),n,2)}function Kp(t){return t.getUTCDay()}function tv(t,n){return np(Ed.count(jd(t),t),n,2)}function nv(t,n){return np(t.getUTCFullYear()%100,n,2)}function ev(t,n){return np(t.getUTCFullYear()%1e4,n,4)}function rv(){return"+0000"}function iv(){return"%"}function ov(t){return+t}function av(t){return Math.floor(+t/1e3)}function uv(n){return Zd=Wd(n),t.timeFormat=Zd.format,t.timeParse=Zd.parse,t.utcFormat=Zd.utcFormat,t.utcParse=Zd.utcParse,Zd}uv({dateTime:"%x, %X",date:"%-m/%-d/%Y",time:"%-I:%M:%S %p",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});var cv=Date.prototype.toISOString?function(t){return t.toISOString()}:t.utcFormat("%Y-%m-%dT%H:%M:%S.%LZ");var fv=+new Date("2000-01-01T00:00:00.000Z")?function(t){var n=new Date(t);return isNaN(n)?null:n}:t.utcParse("%Y-%m-%dT%H:%M:%S.%LZ"),sv=1e3,lv=60*sv,hv=60*lv,dv=24*hv,pv=7*dv,vv=30*dv,gv=365*dv;function yv(t){return new Date(t)}function _v(t){return t instanceof Date?+t:+new Date(+t)}function bv(t,n,r,i,o,a,u,c,f){var s=wh(vh,vh),l=s.invert,h=s.domain,d=f(".%L"),p=f(":%S"),v=f("%I:%M"),g=f("%I %p"),y=f("%a %d"),_=f("%b %d"),b=f("%B"),m=f("%Y"),x=[[u,1,sv],[u,5,5*sv],[u,15,15*sv],[u,30,30*sv],[a,1,lv],[a,5,5*lv],[a,15,15*lv],[a,30,30*lv],[o,1,hv],[o,3,3*hv],[o,6,6*hv],[o,12,12*hv],[i,1,dv],[i,2,2*dv],[r,1,pv],[n,1,vv],[n,3,3*vv],[t,1,gv]];function M(e){return(u(e)=1?iy:t<=-1?-iy:Math.asin(t)}function uy(t){return t.innerRadius}function cy(t){return t.outerRadius}function fy(t){return t.startAngle}function sy(t){return t.endAngle}function ly(t){return t&&t.padAngle}function hy(t,n,e,r,i,o,a){var u=t-e,c=n-r,f=(a?o:-o)/ny(u*u+c*c),s=f*c,l=-f*u,h=t+s,d=n+l,p=e+s,v=r+l,g=(h+p)/2,y=(d+v)/2,_=p-h,b=v-d,m=_*_+b*b,x=i-o,w=h*v-p*d,M=(b<0?-1:1)*ny(Jg(0,x*x*m-w*w)),N=(w*b-_*M)/m,A=(-w*_-b*M)/m,k=(w*b+_*M)/m,S=(-w*_+b*M)/m,T=N-g,E=A-y,C=k-g,P=S-y;return T*T+E*E>C*C+P*P&&(N=k,A=S),{cx:N,cy:A,x01:-s,y01:-l,x11:N*(i/x-1),y11:A*(i/x-1)}}function dy(t){this._context=t}function py(t){return new dy(t)}function vy(t){return t[0]}function gy(t){return t[1]}function yy(){var t=vy,n=gy,e=$g(!0),r=null,i=py,o=null;function a(a){var u,c,f,s=a.length,l=!1;for(null==r&&(o=i(f=ji())),u=0;u<=s;++u)!(u=s;--l)u.point(g[l],y[l]);u.lineEnd(),u.areaEnd()}v&&(g[f]=+t(h,f,c),y[f]=+e(h,f,c),u.point(n?+n(h,f,c):g[f],r?+r(h,f,c):y[f]))}if(d)return u=null,d+""||null}function f(){return yy().defined(i).curve(a).context(o)}return c.x=function(e){return arguments.length?(t="function"==typeof e?e:$g(+e),n=null,c):t},c.x0=function(n){return arguments.length?(t="function"==typeof n?n:$g(+n),c):t},c.x1=function(t){return arguments.length?(n=null==t?null:"function"==typeof t?t:$g(+t),c):n},c.y=function(t){return arguments.length?(e="function"==typeof t?t:$g(+t),r=null,c):e},c.y0=function(t){return arguments.length?(e="function"==typeof t?t:$g(+t),c):e},c.y1=function(t){return arguments.length?(r=null==t?null:"function"==typeof t?t:$g(+t),c):r},c.lineX0=c.lineY0=function(){return f().x(t).y(e)},c.lineY1=function(){return f().x(t).y(r)},c.lineX1=function(){return f().x(n).y(e)},c.defined=function(t){return arguments.length?(i="function"==typeof t?t:$g(!!t),c):i},c.curve=function(t){return arguments.length?(a=t,null!=o&&(u=a(o)),c):a},c.context=function(t){return arguments.length?(null==t?o=u=null:u=a(o=t),c):o},c}function by(t,n){return nt?1:n>=t?0:NaN}function my(t){return t}dy.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._point=0},lineEnd:function(){(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,n){switch(t=+t,n=+n,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,n):this._context.moveTo(t,n);break;case 1:this._point=2;default:this._context.lineTo(t,n)}}};var xy=My(py);function wy(t){this._curve=t}function My(t){function n(n){return new wy(t(n))}return n._curve=t,n}function Ny(t){var n=t.curve;return t.angle=t.x,delete t.x,t.radius=t.y,delete t.y,t.curve=function(t){return arguments.length?n(My(t)):n()._curve},t}function Ay(){return Ny(yy().curve(xy))}function ky(){var t=_y().curve(xy),n=t.curve,e=t.lineX0,r=t.lineX1,i=t.lineY0,o=t.lineY1;return t.angle=t.x,delete t.x,t.startAngle=t.x0,delete t.x0,t.endAngle=t.x1,delete t.x1,t.radius=t.y,delete t.y,t.innerRadius=t.y0,delete t.y0,t.outerRadius=t.y1,delete t.y1,t.lineStartAngle=function(){return Ny(e())},delete t.lineX0,t.lineEndAngle=function(){return Ny(r())},delete t.lineX1,t.lineInnerRadius=function(){return Ny(i())},delete t.lineY0,t.lineOuterRadius=function(){return Ny(o())},delete t.lineY1,t.curve=function(t){return arguments.length?n(My(t)):n()._curve},t}function Sy(t,n){return[(n=+n)*Math.cos(t-=Math.PI/2),n*Math.sin(t)]}wy.prototype={areaStart:function(){this._curve.areaStart()},areaEnd:function(){this._curve.areaEnd()},lineStart:function(){this._curve.lineStart()},lineEnd:function(){this._curve.lineEnd()},point:function(t,n){this._curve.point(n*Math.sin(t),n*-Math.cos(t))}};var Ty=Array.prototype.slice;function Ey(t){return t.source}function Cy(t){return t.target}function Py(t){var n=Ey,e=Cy,r=vy,i=gy,o=null;function a(){var a,u=Ty.call(arguments),c=n.apply(this,u),f=e.apply(this,u);if(o||(o=a=ji()),t(o,+r.apply(this,(u[0]=c,u)),+i.apply(this,u),+r.apply(this,(u[0]=f,u)),+i.apply(this,u)),a)return o=null,a+""||null}return a.source=function(t){return arguments.length?(n=t,a):n},a.target=function(t){return arguments.length?(e=t,a):e},a.x=function(t){return arguments.length?(r="function"==typeof t?t:$g(+t),a):r},a.y=function(t){return arguments.length?(i="function"==typeof t?t:$g(+t),a):i},a.context=function(t){return arguments.length?(o=null==t?null:t,a):o},a}function zy(t,n,e,r,i){t.moveTo(n,e),t.bezierCurveTo(n=(n+r)/2,e,n,i,r,i)}function Ry(t,n,e,r,i){t.moveTo(n,e),t.bezierCurveTo(n,e=(e+i)/2,r,e,r,i)}function qy(t,n,e,r,i){var o=Sy(n,e),a=Sy(n,e=(e+i)/2),u=Sy(r,e),c=Sy(r,i);t.moveTo(o[0],o[1]),t.bezierCurveTo(a[0],a[1],u[0],u[1],c[0],c[1])}var Dy={draw:function(t,n){var e=Math.sqrt(n/ry);t.moveTo(e,0),t.arc(0,0,e,0,oy)}},Ly={draw:function(t,n){var e=Math.sqrt(n/5)/2;t.moveTo(-3*e,-e),t.lineTo(-e,-e),t.lineTo(-e,-3*e),t.lineTo(e,-3*e),t.lineTo(e,-e),t.lineTo(3*e,-e),t.lineTo(3*e,e),t.lineTo(e,e),t.lineTo(e,3*e),t.lineTo(-e,3*e),t.lineTo(-e,e),t.lineTo(-3*e,e),t.closePath()}},Uy=Math.sqrt(1/3),Oy=2*Uy,Yy={draw:function(t,n){var e=Math.sqrt(n/Oy),r=e*Uy;t.moveTo(0,-e),t.lineTo(r,0),t.lineTo(0,e),t.lineTo(-r,0),t.closePath()}},By=Math.sin(ry/10)/Math.sin(7*ry/10),Fy=Math.sin(oy/10)*By,Iy=-Math.cos(oy/10)*By,Hy={draw:function(t,n){var e=Math.sqrt(.8908130915292852*n),r=Fy*e,i=Iy*e;t.moveTo(0,-e),t.lineTo(r,i);for(var o=1;o<5;++o){var a=oy*o/5,u=Math.cos(a),c=Math.sin(a);t.lineTo(c*e,-u*e),t.lineTo(u*r-c*i,c*r+u*i)}t.closePath()}},jy={draw:function(t,n){var e=Math.sqrt(n),r=-e/2;t.rect(r,r,e,e)}},Xy=Math.sqrt(3),Gy={draw:function(t,n){var e=-Math.sqrt(n/(3*Xy));t.moveTo(0,2*e),t.lineTo(-Xy*e,-e),t.lineTo(Xy*e,-e),t.closePath()}},Vy=Math.sqrt(3)/2,$y=1/Math.sqrt(12),Wy=3*($y/2+1),Zy={draw:function(t,n){var e=Math.sqrt(n/Wy),r=e/2,i=e*$y,o=r,a=e*$y+e,u=-o,c=a;t.moveTo(r,i),t.lineTo(o,a),t.lineTo(u,c),t.lineTo(-.5*r-Vy*i,Vy*r+-.5*i),t.lineTo(-.5*o-Vy*a,Vy*o+-.5*a),t.lineTo(-.5*u-Vy*c,Vy*u+-.5*c),t.lineTo(-.5*r+Vy*i,-.5*i-Vy*r),t.lineTo(-.5*o+Vy*a,-.5*a-Vy*o),t.lineTo(-.5*u+Vy*c,-.5*c-Vy*u),t.closePath()}},Qy=[Dy,Ly,Yy,jy,Hy,Gy,Zy];function Jy(){}function Ky(t,n,e){t._context.bezierCurveTo((2*t._x0+t._x1)/3,(2*t._y0+t._y1)/3,(t._x0+2*t._x1)/3,(t._y0+2*t._y1)/3,(t._x0+4*t._x1+n)/6,(t._y0+4*t._y1+e)/6)}function t_(t){this._context=t}function n_(t){this._context=t}function e_(t){this._context=t}function r_(t,n){this._basis=new t_(t),this._beta=n}t_.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},lineEnd:function(){switch(this._point){case 3:Ky(this,this._x1,this._y1);case 2:this._context.lineTo(this._x1,this._y1)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,n){switch(t=+t,n=+n,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,n):this._context.moveTo(t,n);break;case 1:this._point=2;break;case 2:this._point=3,this._context.lineTo((5*this._x0+this._x1)/6,(5*this._y0+this._y1)/6);default:Ky(this,t,n)}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=n}},n_.prototype={areaStart:Jy,areaEnd:Jy,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._y0=this._y1=this._y2=this._y3=this._y4=NaN,this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x2,this._y2),this._context.closePath();break;case 2:this._context.moveTo((this._x2+2*this._x3)/3,(this._y2+2*this._y3)/3),this._context.lineTo((this._x3+2*this._x2)/3,(this._y3+2*this._y2)/3),this._context.closePath();break;case 3:this.point(this._x2,this._y2),this.point(this._x3,this._y3),this.point(this._x4,this._y4)}},point:function(t,n){switch(t=+t,n=+n,this._point){case 0:this._point=1,this._x2=t,this._y2=n;break;case 1:this._point=2,this._x3=t,this._y3=n;break;case 2:this._point=3,this._x4=t,this._y4=n,this._context.moveTo((this._x0+4*this._x1+t)/6,(this._y0+4*this._y1+n)/6);break;default:Ky(this,t,n)}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=n}},e_.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,n){switch(t=+t,n=+n,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3;var e=(this._x0+4*this._x1+t)/6,r=(this._y0+4*this._y1+n)/6;this._line?this._context.lineTo(e,r):this._context.moveTo(e,r);break;case 3:this._point=4;default:Ky(this,t,n)}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=n}},r_.prototype={lineStart:function(){this._x=[],this._y=[],this._basis.lineStart()},lineEnd:function(){var t=this._x,n=this._y,e=t.length-1;if(e>0)for(var r,i=t[0],o=n[0],a=t[e]-i,u=n[e]-o,c=-1;++c<=e;)r=c/e,this._basis.point(this._beta*t[c]+(1-this._beta)*(i+r*a),this._beta*n[c]+(1-this._beta)*(o+r*u));this._x=this._y=null,this._basis.lineEnd()},point:function(t,n){this._x.push(+t),this._y.push(+n)}};var i_=function t(n){function e(t){return 1===n?new t_(t):new r_(t,n)}return e.beta=function(n){return t(+n)},e}(.85);function o_(t,n,e){t._context.bezierCurveTo(t._x1+t._k*(t._x2-t._x0),t._y1+t._k*(t._y2-t._y0),t._x2+t._k*(t._x1-n),t._y2+t._k*(t._y1-e),t._x2,t._y2)}function a_(t,n){this._context=t,this._k=(1-n)/6}a_.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:o_(this,this._x1,this._y1)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,n){switch(t=+t,n=+n,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,n):this._context.moveTo(t,n);break;case 1:this._point=2,this._x1=t,this._y1=n;break;case 2:this._point=3;default:o_(this,t,n)}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=n}};var u_=function t(n){function e(t){return new a_(t,n)}return e.tension=function(n){return t(+n)},e}(0);function c_(t,n){this._context=t,this._k=(1-n)/6}c_.prototype={areaStart:Jy,areaEnd:Jy,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x3,this._y3),this._context.closePath();break;case 2:this._context.lineTo(this._x3,this._y3),this._context.closePath();break;case 3:this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5)}},point:function(t,n){switch(t=+t,n=+n,this._point){case 0:this._point=1,this._x3=t,this._y3=n;break;case 1:this._point=2,this._context.moveTo(this._x4=t,this._y4=n);break;case 2:this._point=3,this._x5=t,this._y5=n;break;default:o_(this,t,n)}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=n}};var f_=function t(n){function e(t){return new c_(t,n)}return e.tension=function(n){return t(+n)},e}(0);function s_(t,n){this._context=t,this._k=(1-n)/6}s_.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,n){switch(t=+t,n=+n,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3,this._line?this._context.lineTo(this._x2,this._y2):this._context.moveTo(this._x2,this._y2);break;case 3:this._point=4;default:o_(this,t,n)}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=n}};var l_=function t(n){function e(t){return new s_(t,n)}return e.tension=function(n){return t(+n)},e}(0);function h_(t,n,e){var r=t._x1,i=t._y1,o=t._x2,a=t._y2;if(t._l01_a>ey){var u=2*t._l01_2a+3*t._l01_a*t._l12_a+t._l12_2a,c=3*t._l01_a*(t._l01_a+t._l12_a);r=(r*u-t._x0*t._l12_2a+t._x2*t._l01_2a)/c,i=(i*u-t._y0*t._l12_2a+t._y2*t._l01_2a)/c}if(t._l23_a>ey){var f=2*t._l23_2a+3*t._l23_a*t._l12_a+t._l12_2a,s=3*t._l23_a*(t._l23_a+t._l12_a);o=(o*f+t._x1*t._l23_2a-n*t._l12_2a)/s,a=(a*f+t._y1*t._l23_2a-e*t._l12_2a)/s}t._context.bezierCurveTo(r,i,o,a,t._x2,t._y2)}function d_(t,n){this._context=t,this._alpha=n}d_.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:this.point(this._x2,this._y2)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,n){if(t=+t,n=+n,this._point){var e=this._x2-t,r=this._y2-n;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(e*e+r*r,this._alpha))}switch(this._point){case 0:this._point=1,this._line?this._context.lineTo(t,n):this._context.moveTo(t,n);break;case 1:this._point=2;break;case 2:this._point=3;default:h_(this,t,n)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=n}};var p_=function t(n){function e(t){return n?new d_(t,n):new a_(t,0)}return e.alpha=function(n){return t(+n)},e}(.5);function v_(t,n){this._context=t,this._alpha=n}v_.prototype={areaStart:Jy,areaEnd:Jy,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x3,this._y3),this._context.closePath();break;case 2:this._context.lineTo(this._x3,this._y3),this._context.closePath();break;case 3:this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5)}},point:function(t,n){if(t=+t,n=+n,this._point){var e=this._x2-t,r=this._y2-n;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(e*e+r*r,this._alpha))}switch(this._point){case 0:this._point=1,this._x3=t,this._y3=n;break;case 1:this._point=2,this._context.moveTo(this._x4=t,this._y4=n);break;case 2:this._point=3,this._x5=t,this._y5=n;break;default:h_(this,t,n)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=n}};var g_=function t(n){function e(t){return n?new v_(t,n):new c_(t,0)}return e.alpha=function(n){return t(+n)},e}(.5);function y_(t,n){this._context=t,this._alpha=n}y_.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,n){if(t=+t,n=+n,this._point){var e=this._x2-t,r=this._y2-n;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(e*e+r*r,this._alpha))}switch(this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3,this._line?this._context.lineTo(this._x2,this._y2):this._context.moveTo(this._x2,this._y2);break;case 3:this._point=4;default:h_(this,t,n)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=n}};var __=function t(n){function e(t){return n?new y_(t,n):new s_(t,0)}return e.alpha=function(n){return t(+n)},e}(.5);function b_(t){this._context=t}function m_(t){return t<0?-1:1}function x_(t,n,e){var r=t._x1-t._x0,i=n-t._x1,o=(t._y1-t._y0)/(r||i<0&&-0),a=(e-t._y1)/(i||r<0&&-0),u=(o*i+a*r)/(r+i);return(m_(o)+m_(a))*Math.min(Math.abs(o),Math.abs(a),.5*Math.abs(u))||0}function w_(t,n){var e=t._x1-t._x0;return e?(3*(t._y1-t._y0)/e-n)/2:n}function M_(t,n,e){var r=t._x0,i=t._y0,o=t._x1,a=t._y1,u=(o-r)/3;t._context.bezierCurveTo(r+u,i+u*n,o-u,a-u*e,o,a)}function N_(t){this._context=t}function A_(t){this._context=new k_(t)}function k_(t){this._context=t}function S_(t){this._context=t}function T_(t){var n,e,r=t.length-1,i=new Array(r),o=new Array(r),a=new Array(r);for(i[0]=0,o[0]=2,a[0]=t[0]+2*t[1],n=1;n=0;--n)i[n]=(a[n]-i[n+1])/o[n];for(o[r-1]=(t[r]+i[r-1])/2,n=0;n1)for(var e,r,i,o=1,a=t[n[0]],u=a.length;o=0;)e[n]=n;return e}function z_(t,n){return t[n]}function R_(t){var n=t.map(q_);return P_(t).sort(function(t,e){return n[t]-n[e]})}function q_(t){for(var n,e=-1,r=0,i=t.length,o=-1/0;++eo&&(o=n,r=e);return r}function D_(t){var n=t.map(L_);return P_(t).sort(function(t,e){return n[t]-n[e]})}function L_(t){for(var n,e=0,r=-1,i=t.length;++r0)){if(o/=h,h<0){if(o0){if(o>l)return;o>s&&(s=o)}if(o=r-c,h||!(o<0)){if(o/=h,h<0){if(o>l)return;o>s&&(s=o)}else if(h>0){if(o0)){if(o/=d,d<0){if(o0){if(o>l)return;o>s&&(s=o)}if(o=i-f,d||!(o<0)){if(o/=d,d<0){if(o>l)return;o>s&&(s=o)}else if(d>0){if(o0||l<1)||(s>0&&(t[0]=[c+s*h,f+s*d]),l<1&&(t[1]=[c+l*h,f+l*d]),!0)}}}}}function W_(t,n,e,r,i){var o=t[1];if(o)return!0;var a,u,c=t[0],f=t.left,s=t.right,l=f[0],h=f[1],d=s[0],p=s[1],v=(l+d)/2,g=(h+p)/2;if(p===h){if(v=r)return;if(l>d){if(c){if(c[1]>=i)return}else c=[v,e];o=[v,i]}else{if(c){if(c[1]1)if(l>d){if(c){if(c[1]>=i)return}else c=[(e-u)/a,e];o=[(i-u)/a,i]}else{if(c){if(c[1]=r)return}else c=[n,a*n+u];o=[r,a*r+u]}else{if(c){if(c[0]=0&&(this._t=1-this._t,this._line=1-this._line)},point:function(t,n){switch(t=+t,n=+n,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,n):this._context.moveTo(t,n);break;case 1:this._point=2;default:if(this._t<=0)this._context.lineTo(this._x,n),this._context.lineTo(t,n);else{var e=this._x*(1-this._t)+t*this._t;this._context.lineTo(e,this._y),this._context.lineTo(e,n)}}this._x=t,this._y=n}},B_.prototype={constructor:B_,insert:function(t,n){var e,r,i;if(t){if(n.P=t,n.N=t.N,t.N&&(t.N.P=n),t.N=n,t.R){for(t=t.R;t.L;)t=t.L;t.L=n}else t.R=n;e=t}else this._?(t=j_(this._),n.P=null,n.N=t,t.P=t.L=n,e=t):(n.P=n.N=null,this._=n,e=null);for(n.L=n.R=null,n.U=e,n.C=!0,t=n;e&&e.C;)e===(r=e.U).L?(i=r.R)&&i.C?(e.C=i.C=!1,r.C=!0,t=r):(t===e.R&&(I_(this,e),e=(t=e).U),e.C=!1,r.C=!0,H_(this,r)):(i=r.L)&&i.C?(e.C=i.C=!1,r.C=!0,t=r):(t===e.L&&(H_(this,e),e=(t=e).U),e.C=!1,r.C=!0,I_(this,r)),e=t.U;this._.C=!1},remove:function(t){t.N&&(t.N.P=t.P),t.P&&(t.P.N=t.N),t.N=t.P=null;var n,e,r,i=t.U,o=t.L,a=t.R;if(e=o?a?j_(a):o:a,i?i.L===t?i.L=e:i.R=e:this._=e,o&&a?(r=e.C,e.C=t.C,e.L=o,o.U=e,e!==a?(i=e.U,e.U=t.U,t=e.R,i.L=t,e.R=a,a.U=e):(e.U=i,i=e,t=e.R)):(r=t.C,t=e),t&&(t.U=i),!r)if(t&&t.C)t.C=!1;else{do{if(t===this._)break;if(t===i.L){if((n=i.R).C&&(n.C=!1,i.C=!0,I_(this,i),n=i.R),n.L&&n.L.C||n.R&&n.R.C){n.R&&n.R.C||(n.L.C=!1,n.C=!0,H_(this,n),n=i.R),n.C=i.C,i.C=n.R.C=!1,I_(this,i),t=this._;break}}else if((n=i.L).C&&(n.C=!1,i.C=!0,H_(this,i),n=i.L),n.L&&n.L.C||n.R&&n.R.C){n.L&&n.L.C||(n.R.C=!1,n.C=!0,I_(this,n),n=i.L),n.C=i.C,i.C=n.L.C=!1,H_(this,i),t=this._;break}n.C=!0,t=i,i=i.U}while(!t.C);t&&(t.C=!1)}}};var K_,tb=[];function nb(){F_(this),this.x=this.y=this.arc=this.site=this.cy=null}function eb(t){var n=t.P,e=t.N;if(n&&e){var r=n.site,i=t.site,o=e.site;if(r!==o){var a=i[0],u=i[1],c=r[0]-a,f=r[1]-u,s=o[0]-a,l=o[1]-u,h=2*(c*l-f*s);if(!(h>=-yb)){var d=c*c+f*f,p=s*s+l*l,v=(l*d-f*p)/h,g=(c*p-s*d)/h,y=tb.pop()||new nb;y.arc=t,y.site=i,y.x=v+a,y.y=(y.cy=g+u)+Math.sqrt(v*v+g*g),t.circle=y;for(var _=null,b=pb._;b;)if(y.ygb)u=u.L;else{if(!((i=o-lb(u,a))>gb)){r>-gb?(n=u.P,e=u):i>-gb?(n=u,e=u.N):n=e=u;break}if(!u.R){n=u;break}u=u.R}!function(t){db[t.index]={site:t,halfedges:[]}}(t);var c=ab(t);if(hb.insert(n,c),n||e){if(n===e)return rb(n),e=ab(n.site),hb.insert(c,e),c.edge=e.edge=X_(n.site,c.site),eb(n),void eb(e);if(e){rb(n),rb(e);var f=n.site,s=f[0],l=f[1],h=t[0]-s,d=t[1]-l,p=e.site,v=p[0]-s,g=p[1]-l,y=2*(h*g-d*v),_=h*h+d*d,b=v*v+g*g,m=[(g*_-d*b)/y+s,(h*b-v*_)/y+l];V_(e.edge,f,p,m),c.edge=X_(f,t,null,m),e.edge=X_(t,p,null,m),eb(n),eb(e)}else c.edge=X_(n.site,c.site)}}function sb(t,n){var e=t.site,r=e[0],i=e[1],o=i-n;if(!o)return r;var a=t.P;if(!a)return-1/0;var u=(e=a.site)[0],c=e[1],f=c-n;if(!f)return u;var s=u-r,l=1/o-1/f,h=s/f;return l?(-h+Math.sqrt(h*h-2*l*(s*s/(-2*f)-c+f/2+i-o/2)))/l+r:(r+u)/2}function lb(t,n){var e=t.N;if(e)return sb(e,n);var r=t.site;return r[1]===n?r[0]:1/0}var hb,db,pb,vb,gb=1e-6,yb=1e-12;function _b(t,n){return n[1]-t[1]||n[0]-t[0]}function bb(t,n){var e,r,i,o=t.sort(_b).pop();for(vb=[],db=new Array(t.length),hb=new B_,pb=new B_;;)if(i=K_,o&&(!i||o[1]gb||Math.abs(i[0][1]-i[1][1])>gb)||delete vb[o]}(a,u,c,f),function(t,n,e,r){var i,o,a,u,c,f,s,l,h,d,p,v,g=db.length,y=!0;for(i=0;igb||Math.abs(v-h)>gb)&&(c.splice(u,0,vb.push(G_(a,d,Math.abs(p-t)gb?[t,Math.abs(l-t)gb?[Math.abs(h-r)gb?[e,Math.abs(l-e)gb?[Math.abs(h-n)=u)return null;var c=t-i.site[0],f=n-i.site[1],s=c*c+f*f;do{i=o.cells[r=a],a=null,i.halfedges.forEach(function(e){var r=o.edges[e],u=r.left;if(u!==i.site&&u||(u=r.right)){var c=t-u[0],f=n-u[1],l=c*c+f*f;lr?(r+i)/2:Math.min(0,r)||Math.max(0,i),a>o?(o+a)/2:Math.min(0,o)||Math.max(0,a))}Nb.prototype=wb.prototype,t.version="5.8.0",t.bisect=i,t.bisectRight=i,t.bisectLeft=o,t.ascending=n,t.bisector=e,t.cross=function(t,n,e){var r,i,o,u,c=t.length,f=n.length,s=new Array(c*f);for(null==e&&(e=a),r=o=0;rt?1:n>=t?0:NaN},t.deviation=f,t.extent=s,t.histogram=function(){var t=v,n=s,e=M;function r(r){var o,a,u=r.length,c=new Array(u);for(o=0;ol;)h.pop(),--d;var p,v=new Array(d+1);for(o=0;o<=d;++o)(p=v[o]=[]).x0=o>0?h[o-1]:s,p.x1=o=r.length)return null!=t&&e.sort(t),null!=n?n(e):e;for(var c,f,s,l=-1,h=e.length,d=r[i++],p=Qi(),v=a();++lr.length)return e;var a,u=i[o-1];return null!=n&&o>=r.length?a=e.entries():(a=[],e.each(function(n,e){a.push({key:e,values:t(n,o)})})),null!=u?a.sort(function(t,n){return u(t.key,n.key)}):a}(o(t,0,to,no),0)},key:function(t){return r.push(t),e},sortKeys:function(t){return i[r.length-1]=t,e},sortValues:function(n){return t=n,e},rollup:function(t){return n=t,e}}},t.set=io,t.map=Qi,t.keys=function(t){var n=[];for(var e in t)n.push(e);return n},t.values=function(t){var n=[];for(var e in t)n.push(t[e]);return n},t.entries=function(t){var n=[];for(var e in t)n.push({key:e,value:t[e]});return n},t.color=hn,t.rgb=gn,t.hsl=mn,t.lab=Rn,t.hcl=Bn,t.lch=function(t,n,e,r){return 1===arguments.length?Yn(t):new Fn(e,n,t,null==r?1:r)},t.gray=function(t,n){return new qn(t,0,0,null==n?1:n)},t.cubehelix=Zn,t.contours=po,t.contourDensity=function(){var t=yo,n=_o,e=bo,r=960,i=500,o=20,a=2,u=3*o,c=r+2*u>>a,f=i+2*u>>a,s=uo(20);function l(r){var i=new Float32Array(c*f),l=new Float32Array(c*f);r.forEach(function(r,o,s){var l=+t(r,o,s)+u>>a,h=+n(r,o,s)+u>>a,d=+e(r,o,s);l>=0&&l=0&&h>a),go({width:c,height:f,data:l},{width:c,height:f,data:i},o>>a),vo({width:c,height:f,data:i},{width:c,height:f,data:l},o>>a),go({width:c,height:f,data:l},{width:c,height:f,data:i},o>>a),vo({width:c,height:f,data:i},{width:c,height:f,data:l},o>>a),go({width:c,height:f,data:l},{width:c,height:f,data:i},o>>a);var d=s(i);if(!Array.isArray(d)){var p=A(i);d=w(0,p,d),(d=g(0,Math.floor(p/d)*d,d)).shift()}return po().thresholds(d).size([c,f])(i).map(h)}function h(t){return t.value*=Math.pow(2,-2*a),t.coordinates.forEach(d),t}function d(t){t.forEach(p)}function p(t){t.forEach(v)}function v(t){t[0]=t[0]*Math.pow(2,a)-u,t[1]=t[1]*Math.pow(2,a)-u}function y(){return c=r+2*(u=3*o)>>a,f=i+2*u>>a,l}return l.x=function(n){return arguments.length?(t="function"==typeof n?n:uo(+n),l):t},l.y=function(t){return arguments.length?(n="function"==typeof t?t:uo(+t),l):n},l.weight=function(t){return arguments.length?(e="function"==typeof t?t:uo(+t),l):e},l.size=function(t){if(!arguments.length)return[r,i];var n=Math.ceil(t[0]),e=Math.ceil(t[1]);if(!(n>=0||n>=0))throw new Error("invalid size");return r=n,i=e,y()},l.cellSize=function(t){if(!arguments.length)return 1<=1))throw new Error("invalid cell size");return a=Math.floor(Math.log(t)/Math.LN2),y()},l.thresholds=function(t){return arguments.length?(s="function"==typeof t?t:Array.isArray(t)?uo(oo.call(t)):uo(t),l):s},l.bandwidth=function(t){if(!arguments.length)return Math.sqrt(o*(o+1));if(!((t=+t)>=0))throw new Error("invalid bandwidth");return o=Math.round((Math.sqrt(4*t*t+1)-1)/2),y()},l},t.dispatch=I,t.drag=function(){var n,e,r,i,o=Gt,a=Vt,u=$t,c=Wt,f={},s=I("start","drag","end"),l=0,h=0;function d(t){t.on("mousedown.drag",p).filter(c).on("touchstart.drag",y).on("touchmove.drag",_).on("touchend.drag touchcancel.drag",b).style("touch-action","none").style("-webkit-tap-highlight-color","rgba(0,0,0,0)")}function p(){if(!i&&o.apply(this,arguments)){var u=m("mouse",a.apply(this,arguments),Ot,this,arguments);u&&(zt(t.event.view).on("mousemove.drag",v,!0).on("mouseup.drag",g,!0),It(t.event.view),Bt(),r=!1,n=t.event.clientX,e=t.event.clientY,u("start"))}}function v(){if(Ft(),!r){var i=t.event.clientX-n,o=t.event.clientY-e;r=i*i+o*o>h}f.mouse("drag")}function g(){zt(t.event.view).on("mousemove.drag mouseup.drag",null),Ht(t.event.view,r),Ft(),f.mouse("end")}function y(){if(o.apply(this,arguments)){var n,e,r=t.event.changedTouches,i=a.apply(this,arguments),u=r.length;for(n=0;nc+d||if+d||ou.index){var p=c-a.x-a.vx,v=f-a.y-a.vy,g=p*p+v*v;gt.r&&(t.r=t[n].r)}function u(){if(n){var r,i,o=n.length;for(e=new Array(o),r=0;r=a)){(t.data!==n||t.next)&&(0===s&&(d+=(s=Zo())*s),0===l&&(d+=(l=Zo())*l),d1?(null==e?u.remove(t):u.set(t,d(e)),n):u.get(t)},find:function(n,e,r){var i,o,a,u,c,f=0,s=t.length;for(null==r?r=1/0:r*=r,f=0;f1?(f.on(t,e),n):f.on(t)}}},t.forceX=function(t){var n,e,r,i=Wo(.1);function o(t){for(var i,o=0,a=n.length;ofc(r[0],r[1])&&(r[1]=i[1]),fc(i[0],r[1])>fc(r[0],r[1])&&(r[0]=i[0])):o.push(r=i);for(a=-1/0,n=0,r=o[e=o.length-1];n<=e;r=i,++n)i=o[n],(u=fc(r[1],i[0]))>a&&(a=u,Tu=i[0],Cu=r[1])}return Lu=Uu=null,Tu===1/0||Eu===1/0?[[NaN,NaN],[NaN,NaN]]:[[Tu,Eu],[Cu,Pu]]},t.geoCentroid=function(t){Ou=Yu=Bu=Fu=Iu=Hu=ju=Xu=Gu=Vu=$u=0,cu(t,hc);var n=Gu,e=Vu,r=$u,i=n*n+e*e+r*r;return i=.12&&i<.234&&r>=-.425&&r<-.214?u:i>=.166&&i<.234&&r>=-.214&&r<-.115?c:a).invert(t)},s.stream=function(e){return t&&n===e?t:(r=[a.stream(n=e),u.stream(e),c.stream(e)],i=r.length,t={point:function(t,n){for(var e=-1;++e2?t[2]+90:90]):[(t=e())[0],t[1],t[2]-90]},e([0,0,90]).scale(159.155)},t.geoTransverseMercatorRaw=nl,t.geoRotation=Cc,t.geoStream=cu,t.geoTransform=function(t){return{stream:gs(t)}},t.cluster=function(){var t=el,n=1,e=1,r=!1;function i(i){var o,a=0;i.eachAfter(function(n){var e=n.children;e?(n.x=function(t){return t.reduce(rl,0)/t.length}(e),n.y=function(t){return 1+t.reduce(il,0)}(e)):(n.x=o?a+=t(n,o):0,n.y=0,o=n)});var u=function(t){for(var n;n=t.children;)t=n[0];return t}(i),c=function(t){for(var n;n=t.children;)t=n[n.length-1];return t}(i),f=u.x-t(u,c)/2,s=c.x+t(c,u)/2;return i.eachAfter(r?function(t){t.x=(t.x-i.x)*n,t.y=(i.y-t.y)*e}:function(t){t.x=(t.x-f)/(s-f)*n,t.y=(1-(i.y?t.y/i.y:1))*e})}return i.separation=function(n){return arguments.length?(t=n,i):t},i.size=function(t){return arguments.length?(r=!1,n=+t[0],e=+t[1],i):r?null:[n,e]},i.nodeSize=function(t){return arguments.length?(r=!0,n=+t[0],e=+t[1],i):r?[n,e]:null},i},t.hierarchy=al,t.pack=function(){var t=null,n=1,e=1,r=kl;function i(i){return i.x=n/2,i.y=e/2,t?i.eachBefore(El(t)).eachAfter(Cl(r,.5)).eachBefore(Pl(1)):i.eachBefore(El(Tl)).eachAfter(Cl(kl,1)).eachAfter(Cl(r,i.r/Math.min(n,e))).eachBefore(Pl(Math.min(n,e)/(2*i.r))),i}return i.radius=function(n){return arguments.length?(t=null==(e=n)?null:Al(e),i):t;var e},i.size=function(t){return arguments.length?(n=+t[0],e=+t[1],i):[n,e]},i.padding=function(t){return arguments.length?(r="function"==typeof t?t:Sl(+t),i):r},i},t.packSiblings=function(t){return Nl(t),t},t.packEnclose=hl,t.partition=function(){var t=1,n=1,e=0,r=!1;function i(i){var o=i.height+1;return i.x0=i.y0=e,i.x1=t,i.y1=n/o,i.eachBefore(function(t,n){return function(r){r.children&&Rl(r,r.x0,t*(r.depth+1)/n,r.x1,t*(r.depth+2)/n);var i=r.x0,o=r.y0,a=r.x1-e,u=r.y1-e;a0)throw new Error("cycle");return o}return e.id=function(n){return arguments.length?(t=Al(n),e):t},e.parentId=function(t){return arguments.length?(n=Al(t),e):n},e},t.tree=function(){var t=Yl,n=1,e=1,r=null;function i(i){var c=function(t){for(var n,e,r,i,o,a=new jl(t,0),u=[a];n=u.pop();)if(r=n._.children)for(n.children=new Array(o=r.length),i=o-1;i>=0;--i)u.push(e=n.children[i]=new jl(r[i],i)),e.parent=n;return(a.parent=new jl(null,0)).children=[a],a}(i);if(c.eachAfter(o),c.parent.m=-c.z,c.eachBefore(a),r)i.eachBefore(u);else{var f=i,s=i,l=i;i.eachBefore(function(t){t.xs.x&&(s=t),t.depth>l.depth&&(l=t)});var h=f===s?1:t(f,s)/2,d=h-f.x,p=n/(s.x+h+d),v=e/(l.depth||1);i.eachBefore(function(t){t.x=(t.x+d)*p,t.y=t.depth*v})}return i}function o(n){var e=n.children,r=n.parent.children,i=n.i?r[n.i-1]:null;if(e){!function(t){for(var n,e=0,r=0,i=t.children,o=i.length;--o>=0;)(n=i[o]).z+=e,n.m+=e,e+=n.s+(r+=n.c)}(n);var o=(e[0].z+e[e.length-1].z)/2;i?(n.z=i.z+t(n._,i._),n.m=n.z-o):n.z=o}else i&&(n.z=i.z+t(n._,i._));n.parent.A=function(n,e,r){if(e){for(var i,o=n,a=n,u=e,c=o.parent.children[0],f=o.m,s=a.m,l=u.m,h=c.m;u=Fl(u),o=Bl(o),u&&o;)c=Bl(c),(a=Fl(a)).a=n,(i=u.z+l-o.z-f+t(u._,o._))>0&&(Il(Hl(u,n,r),n,i),f+=i,s+=i),l+=u.m,f+=o.m,h+=c.m,s+=a.m;u&&!Fl(a)&&(a.t=u,a.m+=l-s),o&&!Bl(c)&&(c.t=o,c.m+=f-h,r=n)}return r}(n,i,n.parent.A||r[0])}function a(t){t._.x=t.z+t.parent.m,t.m+=t.parent.m}function u(t){t.x*=n,t.y=t.depth*e}return i.separation=function(n){return arguments.length?(t=n,i):t},i.size=function(t){return arguments.length?(r=!1,n=+t[0],e=+t[1],i):r?null:[n,e]},i.nodeSize=function(t){return arguments.length?(r=!0,n=+t[0],e=+t[1],i):r?[n,e]:null},i},t.treemap=function(){var t=$l,n=!1,e=1,r=1,i=[0],o=kl,a=kl,u=kl,c=kl,f=kl;function s(t){return t.x0=t.y0=0,t.x1=e,t.y1=r,t.eachBefore(l),i=[0],n&&t.eachBefore(zl),t}function l(n){var e=i[n.depth],r=n.x0+e,s=n.y0+e,l=n.x1-e,h=n.y1-e;l=e-1){var s=u[n];return s.x0=i,s.y0=o,s.x1=a,void(s.y1=c)}for(var l=f[n],h=r/2+l,d=n+1,p=e-1;d>>1;f[v]c-o){var _=(i*y+a*g)/r;t(n,d,g,i,o,_,c),t(d,e,y,_,o,a,c)}else{var b=(o*y+c*g)/r;t(n,d,g,i,o,a,b),t(d,e,y,i,b,a,c)}}(0,c,t.value,n,e,r,i)},t.treemapDice=Rl,t.treemapSlice=Xl,t.treemapSliceDice=function(t,n,e,r,i){(1&t.depth?Xl:Rl)(t,n,e,r,i)},t.treemapSquarify=$l,t.treemapResquarify=Wl,t.interpolate=ye,t.interpolateArray=se,t.interpolateBasis=Kn,t.interpolateBasisClosed=te,t.interpolateDate=le,t.interpolateDiscrete=function(t){var n=t.length;return function(e){return t[Math.max(0,Math.min(n-1,Math.floor(e*n)))]}},t.interpolateHue=function(t,n){var e=re(+t,+n);return function(t){var n=e(t);return n-360*Math.floor(n/360)}},t.interpolateNumber=he,t.interpolateObject=de,t.interpolateRound=_e,t.interpolateString=ge,t.interpolateTransformCss=Se,t.interpolateTransformSvg=Te,t.interpolateZoom=qe,t.interpolateRgb=ae,t.interpolateRgbBasis=ce,t.interpolateRgbBasisClosed=fe,t.interpolateHsl=Le,t.interpolateHslLong=Ue,t.interpolateLab=function(t,n){var e=oe((t=Rn(t)).l,(n=Rn(n)).l),r=oe(t.a,n.a),i=oe(t.b,n.b),o=oe(t.opacity,n.opacity);return function(n){return t.l=e(n),t.a=r(n),t.b=i(n),t.opacity=o(n),t+""}},t.interpolateHcl=Ye,t.interpolateHclLong=Be,t.interpolateCubehelix=Ie,t.interpolateCubehelixLong=He,t.piecewise=function(t,n){for(var e=0,r=n.length-1,i=n[0],o=new Array(r<0?0:r);e=0;--n)f.push(t[r[o[n]][2]]);for(n=+u;nu!=f>u&&a<(c-e)*(u-r)/(f-r)+e&&(s=!s),c=e,f=r;return s},t.polygonLength=function(t){for(var n,e,r=-1,i=t.length,o=t[i-1],a=o[0],u=o[1],c=0;++r0?a[n-1]:r[0],n=o?[a[o-1],r]:[a[n-1],a[n]]},c.unknown=function(t){return arguments.length?(n=t,c):c},c.thresholds=function(){return a.slice()},c.copy=function(){return t().domain([e,r]).range(u).unknown(n)},oh.apply(Nh(c),arguments)},t.scaleThreshold=function t(){var n,e=[.5],r=[0,1],o=1;function a(t){return t<=t?r[i(e,t,0,o)]:n}return a.domain=function(t){return arguments.length?(e=fh.call(t),o=Math.min(e.length,r.length-1),a):e.slice()},a.range=function(t){return arguments.length?(r=fh.call(t),o=Math.min(e.length,r.length-1),a):r.slice()},a.invertExtent=function(t){var n=r.indexOf(t);return[e[n-1],e[n]]},a.unknown=function(t){return arguments.length?(n=t,a):n},a.copy=function(){return t().domain(e).range(r).unknown(n)},oh.apply(a,arguments)},t.scaleTime=function(){return oh.apply(bv(bd,yd,rd,td,Jh,Zh,$h,jh,t.timeFormat).domain([new Date(2e3,0,1),new Date(2e3,0,2)]),arguments)},t.scaleUtc=function(){return oh.apply(bv(jd,Id,Td,Ad,Md,xd,$h,jh,t.utcFormat).domain([Date.UTC(2e3,0,1),Date.UTC(2e3,0,2)]),arguments)},t.scaleSequential=function t(){var n=Nh(mv()(vh));return n.copy=function(){return xv(n,t())},ah.apply(n,arguments)},t.scaleSequentialLog=function t(){var n=zh(mv()).domain([1,10]);return n.copy=function(){return xv(n,t()).base(n.base())},ah.apply(n,arguments)},t.scaleSequentialPow=wv,t.scaleSequentialSqrt=function(){return wv.apply(null,arguments).exponent(.5)},t.scaleSequentialSymlog=function t(){var n=Dh(mv());return n.copy=function(){return xv(n,t()).constant(n.constant())},ah.apply(n,arguments)},t.scaleSequentialQuantile=function t(){var e=[],r=vh;function o(t){if(!isNaN(t=+t))return r((i(e,t)-1)/(e.length-1))}return o.domain=function(t){if(!arguments.length)return e.slice();e=[];for(var r,i=0,a=t.length;i1)&&(t-=Math.floor(t));var n=Math.abs(t-.5);return Yg.h=360*t-100,Yg.s=1.5-1.5*n,Yg.l=.8-.9*n,Yg+""},t.interpolateWarm=Ug,t.interpolateCool=Og,t.interpolateSinebow=function(t){var n;return t=(.5-t)*Math.PI,Bg.r=255*(n=Math.sin(t))*n,Bg.g=255*(n=Math.sin(t+Fg))*n,Bg.b=255*(n=Math.sin(t+Ig))*n,Bg+""},t.interpolateViridis=jg,t.interpolateMagma=Xg,t.interpolateInferno=Gg,t.interpolatePlasma=Vg,t.create=function(t){return zt(W(t).call(document.documentElement))},t.creator=W,t.local=qt,t.matcher=tt,t.mouse=Ot,t.namespace=$,t.namespaces=V,t.clientPoint=Ut,t.select=zt,t.selectAll=function(t){return"string"==typeof t?new Ct([document.querySelectorAll(t)],[document.documentElement]):new Ct([null==t?[]:t],Et)},t.selection=Pt,t.selector=Q,t.selectorAll=K,t.style=ct,t.touch=Yt,t.touches=function(t,n){null==n&&(n=Lt().touches);for(var e=0,r=n?n.length:0,i=new Array(r);ed;if(u||(u=c=ji()),hey)if(v>oy-ey)u.moveTo(h*Qg(d),h*ty(d)),u.arc(0,0,h,d,p,!g),l>ey&&(u.moveTo(l*Qg(p),l*ty(p)),u.arc(0,0,l,p,d,g));else{var y,_,b=d,m=p,x=d,w=p,M=v,N=v,A=a.apply(this,arguments)/2,k=A>ey&&(r?+r.apply(this,arguments):ny(l*l+h*h)),S=Kg(Wg(h-l)/2,+e.apply(this,arguments)),T=S,E=S;if(k>ey){var C=ay(k/l*ty(A)),P=ay(k/h*ty(A));(M-=2*C)>ey?(x+=C*=g?1:-1,w-=C):(M=0,x=w=(d+p)/2),(N-=2*P)>ey?(b+=P*=g?1:-1,m-=P):(N=0,b=m=(d+p)/2)}var z=h*Qg(b),R=h*ty(b),q=l*Qg(w),D=l*ty(w);if(S>ey){var L,U=h*Qg(m),O=h*ty(m),Y=l*Qg(x),B=l*ty(x);if(v<=oy-ey&&(L=function(t,n,e,r,i,o,a,u){var c=e-t,f=r-n,s=a-i,l=u-o,h=l*c-s*f;if(!(h*h1?0:s<-1?ry:Math.acos(s))/2),G=ny(L[0]*L[0]+L[1]*L[1]);T=Kg(S,(l-G)/(X-1)),E=Kg(S,(h-G)/(X+1))}}N>ey?E>ey?(y=hy(Y,B,z,R,h,E,g),_=hy(U,O,q,D,h,E,g),u.moveTo(y.cx+y.x01,y.cy+y.y01),Eey&&M>ey?T>ey?(y=hy(q,D,U,O,l,-T,g),_=hy(z,R,Y,B,l,-T,g),u.lineTo(y.cx+y.x01,y.cy+y.y01),T0&&(d+=l);for(null!=n?p.sort(function(t,e){return n(v[t],v[e])}):null!=e&&p.sort(function(t,n){return e(a[t],a[n])}),u=0,f=d?(y-h*b)/d:0;u0?l*f:0)+b,v[c]={data:a[c],index:u,value:l,startAngle:g,endAngle:s,padAngle:_};return v}return a.value=function(n){return arguments.length?(t="function"==typeof n?n:$g(+n),a):t},a.sortValues=function(t){return arguments.length?(n=t,e=null,a):n},a.sort=function(t){return arguments.length?(e=t,n=null,a):e},a.startAngle=function(t){return arguments.length?(r="function"==typeof t?t:$g(+t),a):r},a.endAngle=function(t){return arguments.length?(i="function"==typeof t?t:$g(+t),a):i},a.padAngle=function(t){return arguments.length?(o="function"==typeof t?t:$g(+t),a):o},a},t.areaRadial=ky,t.radialArea=ky,t.lineRadial=Ay,t.radialLine=Ay,t.pointRadial=Sy,t.linkHorizontal=function(){return Py(zy)},t.linkVertical=function(){return Py(Ry)},t.linkRadial=function(){var t=Py(qy);return t.angle=t.x,delete t.x,t.radius=t.y,delete t.y,t},t.symbol=function(){var t=$g(Dy),n=$g(64),e=null;function r(){var r;if(e||(e=r=ji()),t.apply(this,arguments).draw(e,+n.apply(this,arguments)),r)return e=null,r+""||null}return r.type=function(n){return arguments.length?(t="function"==typeof n?n:$g(n),r):t},r.size=function(t){return arguments.length?(n="function"==typeof t?t:$g(+t),r):n},r.context=function(t){return arguments.length?(e=null==t?null:t,r):e},r},t.symbols=Qy,t.symbolCircle=Dy,t.symbolCross=Ly,t.symbolDiamond=Yy,t.symbolSquare=jy,t.symbolStar=Hy,t.symbolTriangle=Gy,t.symbolWye=Zy,t.curveBasisClosed=function(t){return new n_(t)},t.curveBasisOpen=function(t){return new e_(t)},t.curveBasis=function(t){return new t_(t)},t.curveBundle=i_,t.curveCardinalClosed=f_,t.curveCardinalOpen=l_,t.curveCardinal=u_,t.curveCatmullRomClosed=g_,t.curveCatmullRomOpen=__,t.curveCatmullRom=p_,t.curveLinearClosed=function(t){return new b_(t)},t.curveLinear=py,t.curveMonotoneX=function(t){return new N_(t)},t.curveMonotoneY=function(t){return new A_(t)},t.curveNatural=function(t){return new S_(t)},t.curveStep=function(t){return new E_(t,.5)},t.curveStepAfter=function(t){return new E_(t,1)},t.curveStepBefore=function(t){return new E_(t,0)},t.stack=function(){var t=$g([]),n=P_,e=C_,r=z_;function i(i){var o,a,u=t.apply(this,arguments),c=i.length,f=u.length,s=new Array(f);for(o=0;o0){for(var e,r,i,o=0,a=t[0].length;o1)for(var e,r,i,o,a,u,c=0,f=t[n[0]].length;c=0?(r[0]=o,r[1]=o+=i):i<0?(r[1]=a,r[0]=a+=i):r[0]=o},t.stackOffsetNone=C_,t.stackOffsetSilhouette=function(t,n){if((e=t.length)>0){for(var e,r=0,i=t[n[0]],o=i.length;r0&&(r=(e=t[n[0]]).length)>0){for(var e,r,i,o=0,a=1;adr&&e.name===n)return new Er([[t]],fi,n,+r);return null},t.interrupt=Mr,t.voronoi=function(){var t=O_,n=Y_,e=null;function r(r){return new bb(r.map(function(e,i){var o=[Math.round(t(e,i,r)/gb)*gb,Math.round(n(e,i,r)/gb)*gb];return o.index=i,o.data=e,o}),e)}return r.polygons=function(t){return r(t).polygons()},r.links=function(t){return r(t).links()},r.triangles=function(t){return r(t).triangles()},r.x=function(n){return arguments.length?(t="function"==typeof n?n:U_(+n),r):t},r.y=function(t){return arguments.length?(n="function"==typeof t?t:U_(+t),r):n},r.extent=function(t){return arguments.length?(e=null==t?null:[[+t[0][0],+t[0][1]],[+t[1][0],+t[1][1]]],r):e&&[[e[0][0],e[0][1]],[e[1][0],e[1][1]]]},r.size=function(t){return arguments.length?(e=null==t?null:[[0,0],[+t[0],+t[1]]],r):e&&[e[1][0]-e[0][0],e[1][1]-e[0][1]]},r},t.zoom=function(){var n,e,r=Sb,i=Tb,o=zb,a=Cb,u=Pb,c=[0,1/0],f=[[-1/0,-1/0],[1/0,1/0]],s=250,l=qe,h=[],d=I("start","zoom","end"),p=500,v=150,g=0;function y(t){t.property("__zoom",Eb).on("wheel.zoom",N).on("mousedown.zoom",A).on("dblclick.zoom",k).filter(u).on("touchstart.zoom",S).on("touchmove.zoom",T).on("touchend.zoom touchcancel.zoom",E).style("touch-action","none").style("-webkit-tap-highlight-color","rgba(0,0,0,0)")}function _(t,n){return(n=Math.max(c[0],Math.min(c[1],n)))===t.k?t:new wb(n,t.x,t.y)}function b(t,n,e){var r=n[0]-e[0]*t.k,i=n[1]-e[1]*t.k;return r===t.x&&i===t.y?t:new wb(t.k,r,i)}function m(t){return[(+t[0][0]+ +t[1][0])/2,(+t[0][1]+ +t[1][1])/2]}function x(t,n,e){t.on("start.zoom",function(){w(this,arguments).start()}).on("interrupt.zoom end.zoom",function(){w(this,arguments).end()}).tween("zoom",function(){var t=arguments,r=w(this,t),o=i.apply(this,t),a=e||m(o),u=Math.max(o[1][0]-o[0][0],o[1][1]-o[0][1]),c=this.__zoom,f="function"==typeof n?n.apply(this,t):n,s=l(c.invert(a).concat(u/c.k),f.invert(a).concat(u/f.k));return function(t){if(1===t)t=f;else{var n=s(t),e=u/n[2];t=new wb(e,a[0]-n[0]*e,a[1]-n[1]*e)}r.zoom(null,t)}})}function w(t,n){for(var e,r=0,i=h.length;rg}n.zoom("mouse",o(b(n.that.__zoom,n.mouse[0]=Ot(n.that),n.mouse[1]),n.extent,f))},!0).on("mouseup.zoom",function(){i.on("mousemove.zoom mouseup.zoom",null),Ht(t.event.view,n.moved),kb(),n.end()},!0),a=Ot(this),u=t.event.clientX,c=t.event.clientY;It(t.event.view),Ab(),n.mouse=[a,this.__zoom.invert(a)],Mr(this),n.start()}}function k(){if(r.apply(this,arguments)){var n=this.__zoom,e=Ot(this),a=n.invert(e),u=n.k*(t.event.shiftKey?.5:2),c=o(b(_(n,u),e,a),i.apply(this,arguments),f);kb(),s>0?zt(this).transition().duration(s).call(x,c,e):zt(this).call(y.transform,c)}}function S(){if(r.apply(this,arguments)){var e,i,o,a,u=w(this,arguments),c=t.event.changedTouches,f=c.length;for(Ab(),i=0;ia==f>-a?(h=a,a=i[++c]):(h=f,f=e[++u]);let _=0;if(ca==f>-a?(r=a+h,l=h-(r-a),a=i[++c]):(r=f+h,l=h-(r-f),f=e[++u]),h=r,0!==l&&(n[_++]=l);ca==f>-a?(r=h+a,o=r-h,l=h-(r-o)+(a-o),a=i[++c]):(r=h+f,o=r-h,l=h-(r-o)+(f-o),f=e[++u]),h=r,0!==l&&(n[_++]=l);for(;c0!=d>0)return g;const y=Math.abs(_+d);return Math.abs(g)>=33306690738754716e-32*y?g:-function(s,o,a,f,c,u,_){let d,g,y,w,b,A,k,M,p,x,S,T,z,U,m,K,L,v;const F=s-c,P=a-c,E=o-u,H=f-u;U=F*H,A=t*F,k=A-(A-F),M=F-k,A=t*H,p=A-(A-H),x=H-p,m=M*x-(U-k*p-M*p-k*x),K=E*P,A=t*E,k=A-(A-E),M=E-k,A=t*P,p=A-(A-P),x=P-p,L=M*x-(K-k*p-M*p-k*x),S=m-L,b=m-S,e[0]=m-(S+b)+(b-L),T=U+S,b=T-U,z=U-(T-b)+(S-b),S=z-K,b=z-S,e[1]=z-(S+b)+(b-K),v=T+S,b=v-T,e[2]=T-(v-b)+(S-b),e[3]=v;let I=function(t,i){let s=i[0];for(let e=1;e=N||-I>=N)return I;if(b=s-F,d=s-(F+b)+(b-c),b=a-P,y=a-(P+b)+(b-c),b=o-E,g=o-(E+b)+(b-u),b=f-H,w=f-(H+b)+(b-u),0===d&&0===g&&0===y&&0===w)return I;if(N=11093356479670487e-47*_+33306690738754706e-32*Math.abs(I),I+=F*w+H*d-(E*y+P*g),I>=N||-I>=N)return I;U=d*H,A=t*d,k=A-(A-d),M=d-k,A=t*H,p=A-(A-H),x=H-p,m=M*x-(U-k*p-M*p-k*x),K=g*P,A=t*g,k=A-(A-g),M=g-k,A=t*P,p=A-(A-P),x=P-p,L=M*x-(K-k*p-M*p-k*x),S=m-L,b=m-S,l[0]=m-(S+b)+(b-L),T=U+S,b=T-U,z=U-(T-b)+(S-b),S=z-K,b=z-S,l[1]=z-(S+b)+(b-K),v=T+S,b=v-T,l[2]=T-(v-b)+(S-b),l[3]=v;const j=i(4,e,4,l,n);U=F*w,A=t*F,k=A-(A-F),M=F-k,A=t*w,p=A-(A-w),x=w-p,m=M*x-(U-k*p-M*p-k*x),K=E*y,A=t*E,k=A-(A-E),M=E-k,A=t*y,p=A-(A-y),x=y-p,L=M*x-(K-k*p-M*p-k*x),S=m-L,b=m-S,l[0]=m-(S+b)+(b-L),T=U+S,b=T-U,z=U-(T-b)+(S-b),S=z-K,b=z-S,l[1]=z-(S+b)+(b-K),v=T+S,b=v-T,l[2]=T-(v-b)+(S-b),l[3]=v;const q=i(j,n,4,l,h);U=d*w,A=t*d,k=A-(A-d),M=d-k,A=t*w,p=A-(A-w),x=w-p,m=M*x-(U-k*p-M*p-k*x),K=g*y,A=t*g,k=A-(A-g),M=g-k,A=t*y,p=A-(A-y),x=y-p,L=M*x-(K-k*p-M*p-k*x),S=m-L,b=m-S,l[0]=m-(S+b)+(b-L),T=U+S,b=T-U,z=U-(T-b)+(S-b),S=z-K,b=z-S,l[1]=z-(S+b)+(b-K),v=T+S,b=v-T,l[2]=T-(v-b)+(S-b),l[3]=v;const D=i(q,h,4,l,r);return r[D-1]}(s,o,a,f,c,u,y)}const a=Math.pow(2,-52),f=new Uint32Array(512);class c{static from(t,i=w,s=b){const e=t.length,n=new Float64Array(2*e);for(let h=0;h>1;if(i>0&&"number"!=typeof t[0])throw new Error("Expected coords to contain numbers.");this.coords=t;const s=Math.max(2*i-5,0);this._triangles=new Uint32Array(3*s),this._halfedges=new Int32Array(3*s),this._hashSize=Math.ceil(Math.sqrt(i)),this._hullPrev=new Uint32Array(i),this._hullNext=new Uint32Array(i),this._hullTri=new Uint32Array(i),this._hullHash=new Int32Array(this._hashSize).fill(-1),this._ids=new Uint32Array(i),this._dists=new Float64Array(i),this.update()}update(){const{coords:t,_hullPrev:i,_hullNext:s,_hullTri:e,_hullHash:n}=this,h=t.length>>1;let r=1/0,l=1/0,f=-1/0,c=-1/0;for(let i=0;if&&(f=s),e>c&&(c=e),this._ids[i]=i}const _=(r+f)/2,y=(l+c)/2;let w,b,A,k=1/0;for(let i=0;i0&&(b=i,k=s)}let x=t[2*b],S=t[2*b+1],T=1/0;for(let i=0;ie&&(i[s++]=n,e=this._dists[n])}return this.hull=i.subarray(0,s),this.triangles=new Uint32Array(0),void(this.halfedges=new Uint32Array(0))}if(o(M,p,x,S,z,U)<0){const t=b,i=x,s=S;b=A,x=z,S=U,A=t,z=i,U=s}const m=function(t,i,s,e,n,h){const r=s-t,l=e-i,o=n-t,a=h-i,f=r*r+l*l,c=o*o+a*a,u=.5/(r*a-l*o);return{x:t+(a*f-l*c)*u,y:i+(r*c-o*f)*u}}(M,p,x,S,z,U);this._cx=m.x,this._cy=m.y;for(let i=0;i0&&Math.abs(c-h)<=a&&Math.abs(u-r)<=a)continue;if(h=c,r=u,f===w||f===b||f===A)continue;let _=0;for(let t=0,i=this._hashKey(c,u);t=0;)if(g=d,g===_){g=-1;break}if(-1===g)continue;let y=this._addTriangle(g,f,s[g],-1,-1,e[g]);e[f]=this._legalize(y+2),e[g]=y,K++;let k=s[g];for(;d=s[k],o(c,u,t[2*k],t[2*k+1],t[2*d],t[2*d+1])<0;)y=this._addTriangle(k,f,d,e[f],-1,e[k]),e[f]=this._legalize(y+2),s[k]=k,K--,k=d;if(g===_)for(;d=i[g],o(c,u,t[2*d],t[2*d+1],t[2*g],t[2*g+1])<0;)y=this._addTriangle(d,f,g,-1,e[g],e[d]),this._legalize(y+2),e[d]=y,s[g]=g,K--,g=d;this._hullStart=i[f]=g,s[g]=i[k]=f,s[f]=k,n[this._hashKey(c,u)]=f,n[this._hashKey(t[2*g],t[2*g+1])]=g}this.hull=new Uint32Array(K);for(let t=0,i=this._hullStart;t0?3-s:1+s)/4}(t-this._cx,i-this._cy)*this._hashSize)%this._hashSize}_legalize(t){const{_triangles:i,_halfedges:s,coords:e}=this;let n=0,h=0;for(;;){const r=s[t],l=t-t%3;if(h=l+(t+2)%3,-1===r){if(0===n)break;t=f[--n];continue}const o=r-r%3,a=l+(t+1)%3,c=o+(r+2)%3,u=i[h],d=i[t],g=i[a],y=i[c];if(_(e[2*u],e[2*u+1],e[2*d],e[2*d+1],e[2*g],e[2*g+1],e[2*y],e[2*y+1])){i[t]=y,i[r]=u;const e=s[c];if(-1===e){let i=this._hullStart;do{if(this._hullTri[i]===c){this._hullTri[i]=t;break}i=this._hullPrev[i]}while(i!==this._hullStart)}this._link(t,e),this._link(r,s[h]),this._link(h,c);const l=o+(r+1)%3;n=s&&i[t[r]]>h;)t[r+1]=t[r--];t[r+1]=e}else{let n=s+1,h=e;y(t,s+e>>1,n),i[t[s]]>i[t[e]]&&y(t,s,e),i[t[n]]>i[t[e]]&&y(t,n,e),i[t[s]]>i[t[n]]&&y(t,s,n);const r=t[n],l=i[r];for(;;){do{n++}while(i[t[n]]l);if(h=h-s?(g(t,i,n,e),g(t,i,s,h-1)):(g(t,i,s,h-1),g(t,i,n,e))}}function y(t,i,s){const e=t[i];t[i]=t[s],t[s]=e}function w(t){return t[0]}function b(t){return t[1]}return c})); diff --git a/mobile_app/assets/www/libs/dropbox-sdk.min.js b/mobile_app/assets/www/libs/dropbox-sdk.min.js new file mode 100644 index 00000000..c5e32fc2 --- /dev/null +++ b/mobile_app/assets/www/libs/dropbox-sdk.min.js @@ -0,0 +1 @@ +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).Dropbox={})}(this,(function(e){"use strict";function t(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function r(e,t){for(var r=0;t.length>r;r++){var s=t[r];s.enumerable=s.enumerable||!1,s.configurable=!0,"value"in s&&(s.writable=!0),Object.defineProperty(e,s.key,s)}}function s(e,t,s){return t&&r(e.prototype,t),s&&r(e,s),e}function i(e){return(i=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}function n(e,t){return(n=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}function u(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}function a(e,t,r){return(a=u()?Reflect.construct:function(e,t,r){var s=[null];s.push.apply(s,t);var i=new(Function.bind.apply(e,s));return r&&n(i,r.prototype),i}).apply(null,arguments)}function o(e){var t="function"==typeof Map?new Map:void 0;return(o=function(e){if(null===e||-1===Function.toString.call(e).indexOf("[native code]"))return e;if("function"!=typeof e)throw new TypeError("Super expression must either be null or a function");if(void 0!==t){if(t.has(e))return t.get(e);t.set(e,r)}function r(){return a(e,arguments,i(this).constructor)}return r.prototype=Object.create(e.prototype,{constructor:{value:r,enumerable:!1,writable:!0,configurable:!0}}),n(r,e)})(e)}function c(e,t){return!t||"object"!=typeof t&&"function"!=typeof t?function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}(e):t}var p="app",l="user",f="team",h="dropboxapi.com",m="dropbox.com",d={api:"api",notify:"bolt",content:"api-content"},_={};function q(e){var t="000".concat(e.charCodeAt(0).toString(16)).slice(-4);return"\\u".concat(t)}_.accountSetProfilePhoto=function(e){return this.request("account/set_profile_photo",e,"user","api","rpc")},_.authTokenFromOauth1=function(e){return this.request("auth/token/from_oauth1",e,"app","api","rpc")},_.authTokenRevoke=function(){return this.request("auth/token/revoke",null,"user","api","rpc")},_.checkApp=function(e){return this.request("check/app",e,"app","api","rpc")},_.checkUser=function(e){return this.request("check/user",e,"user","api","rpc")},_.contactsDeleteManualContacts=function(){return this.request("contacts/delete_manual_contacts",null,"user","api","rpc")},_.contactsDeleteManualContactsBatch=function(e){return this.request("contacts/delete_manual_contacts_batch",e,"user","api","rpc")},_.filePropertiesPropertiesAdd=function(e){return this.request("file_properties/properties/add",e,"user","api","rpc")},_.filePropertiesPropertiesOverwrite=function(e){return this.request("file_properties/properties/overwrite",e,"user","api","rpc")},_.filePropertiesPropertiesRemove=function(e){return this.request("file_properties/properties/remove",e,"user","api","rpc")},_.filePropertiesPropertiesSearch=function(e){return this.request("file_properties/properties/search",e,"user","api","rpc")},_.filePropertiesPropertiesSearchContinue=function(e){return this.request("file_properties/properties/search/continue",e,"user","api","rpc")},_.filePropertiesPropertiesUpdate=function(e){return this.request("file_properties/properties/update",e,"user","api","rpc")},_.filePropertiesTemplatesAddForTeam=function(e){return this.request("file_properties/templates/add_for_team",e,"team","api","rpc")},_.filePropertiesTemplatesAddForUser=function(e){return this.request("file_properties/templates/add_for_user",e,"user","api","rpc")},_.filePropertiesTemplatesGetForTeam=function(e){return this.request("file_properties/templates/get_for_team",e,"team","api","rpc")},_.filePropertiesTemplatesGetForUser=function(e){return this.request("file_properties/templates/get_for_user",e,"user","api","rpc")},_.filePropertiesTemplatesListForTeam=function(){return this.request("file_properties/templates/list_for_team",null,"team","api","rpc")},_.filePropertiesTemplatesListForUser=function(){return this.request("file_properties/templates/list_for_user",null,"user","api","rpc")},_.filePropertiesTemplatesRemoveForTeam=function(e){return this.request("file_properties/templates/remove_for_team",e,"team","api","rpc")},_.filePropertiesTemplatesRemoveForUser=function(e){return this.request("file_properties/templates/remove_for_user",e,"user","api","rpc")},_.filePropertiesTemplatesUpdateForTeam=function(e){return this.request("file_properties/templates/update_for_team",e,"team","api","rpc")},_.filePropertiesTemplatesUpdateForUser=function(e){return this.request("file_properties/templates/update_for_user",e,"user","api","rpc")},_.fileRequestsCount=function(){return this.request("file_requests/count",null,"user","api","rpc")},_.fileRequestsCreate=function(e){return this.request("file_requests/create",e,"user","api","rpc")},_.fileRequestsDelete=function(e){return this.request("file_requests/delete",e,"user","api","rpc")},_.fileRequestsDeleteAllClosed=function(){return this.request("file_requests/delete_all_closed",null,"user","api","rpc")},_.fileRequestsGet=function(e){return this.request("file_requests/get",e,"user","api","rpc")},_.fileRequestsListV2=function(e){return this.request("file_requests/list_v2",e,"user","api","rpc")},_.fileRequestsList=function(){return this.request("file_requests/list",null,"user","api","rpc")},_.fileRequestsListContinue=function(e){return this.request("file_requests/list/continue",e,"user","api","rpc")},_.fileRequestsUpdate=function(e){return this.request("file_requests/update",e,"user","api","rpc")},_.filesAlphaGetMetadata=function(e){return this.request("files/alpha/get_metadata",e,"user","api","rpc")},_.filesAlphaUpload=function(e){return this.request("files/alpha/upload",e,"user","content","upload")},_.filesCopyV2=function(e){return this.request("files/copy_v2",e,"user","api","rpc")},_.filesCopy=function(e){return this.request("files/copy",e,"user","api","rpc")},_.filesCopyBatchV2=function(e){return this.request("files/copy_batch_v2",e,"user","api","rpc")},_.filesCopyBatch=function(e){return this.request("files/copy_batch",e,"user","api","rpc")},_.filesCopyBatchCheckV2=function(e){return this.request("files/copy_batch/check_v2",e,"user","api","rpc")},_.filesCopyBatchCheck=function(e){return this.request("files/copy_batch/check",e,"user","api","rpc")},_.filesCopyReferenceGet=function(e){return this.request("files/copy_reference/get",e,"user","api","rpc")},_.filesCopyReferenceSave=function(e){return this.request("files/copy_reference/save",e,"user","api","rpc")},_.filesCreateFolderV2=function(e){return this.request("files/create_folder_v2",e,"user","api","rpc")},_.filesCreateFolder=function(e){return this.request("files/create_folder",e,"user","api","rpc")},_.filesCreateFolderBatch=function(e){return this.request("files/create_folder_batch",e,"user","api","rpc")},_.filesCreateFolderBatchCheck=function(e){return this.request("files/create_folder_batch/check",e,"user","api","rpc")},_.filesDeleteV2=function(e){return this.request("files/delete_v2",e,"user","api","rpc")},_.filesDelete=function(e){return this.request("files/delete",e,"user","api","rpc")},_.filesDeleteBatch=function(e){return this.request("files/delete_batch",e,"user","api","rpc")},_.filesDeleteBatchCheck=function(e){return this.request("files/delete_batch/check",e,"user","api","rpc")},_.filesDownload=function(e){return this.request("files/download",e,"user","content","download")},_.filesDownloadZip=function(e){return this.request("files/download_zip",e,"user","content","download")},_.filesExport=function(e){return this.request("files/export",e,"user","content","download")},_.filesGetFileLockBatch=function(e){return this.request("files/get_file_lock_batch",e,"user","api","rpc")},_.filesGetMetadata=function(e){return this.request("files/get_metadata",e,"user","api","rpc")},_.filesGetPreview=function(e){return this.request("files/get_preview",e,"user","content","download")},_.filesGetTemporaryLink=function(e){return this.request("files/get_temporary_link",e,"user","api","rpc")},_.filesGetTemporaryUploadLink=function(e){return this.request("files/get_temporary_upload_link",e,"user","api","rpc")},_.filesGetThumbnail=function(e){return this.request("files/get_thumbnail",e,"user","content","download")},_.filesGetThumbnailV2=function(e){return this.request("files/get_thumbnail_v2",e,"app, user","content","download")},_.filesGetThumbnailBatch=function(e){return this.request("files/get_thumbnail_batch",e,"user","content","rpc")},_.filesListFolder=function(e){return this.request("files/list_folder",e,"user","api","rpc")},_.filesListFolderContinue=function(e){return this.request("files/list_folder/continue",e,"user","api","rpc")},_.filesListFolderGetLatestCursor=function(e){return this.request("files/list_folder/get_latest_cursor",e,"user","api","rpc")},_.filesListFolderLongpoll=function(e){return this.request("files/list_folder/longpoll",e,"noauth","notify","rpc")},_.filesListRevisions=function(e){return this.request("files/list_revisions",e,"user","api","rpc")},_.filesLockFileBatch=function(e){return this.request("files/lock_file_batch",e,"user","api","rpc")},_.filesMoveV2=function(e){return this.request("files/move_v2",e,"user","api","rpc")},_.filesMove=function(e){return this.request("files/move",e,"user","api","rpc")},_.filesMoveBatchV2=function(e){return this.request("files/move_batch_v2",e,"user","api","rpc")},_.filesMoveBatch=function(e){return this.request("files/move_batch",e,"user","api","rpc")},_.filesMoveBatchCheckV2=function(e){return this.request("files/move_batch/check_v2",e,"user","api","rpc")},_.filesMoveBatchCheck=function(e){return this.request("files/move_batch/check",e,"user","api","rpc")},_.filesPaperCreate=function(e){return this.request("files/paper/create",e,"user","api","upload")},_.filesPaperUpdate=function(e){return this.request("files/paper/update",e,"user","api","upload")},_.filesPermanentlyDelete=function(e){return this.request("files/permanently_delete",e,"user","api","rpc")},_.filesPropertiesAdd=function(e){return this.request("files/properties/add",e,"user","api","rpc")},_.filesPropertiesOverwrite=function(e){return this.request("files/properties/overwrite",e,"user","api","rpc")},_.filesPropertiesRemove=function(e){return this.request("files/properties/remove",e,"user","api","rpc")},_.filesPropertiesTemplateGet=function(e){return this.request("files/properties/template/get",e,"user","api","rpc")},_.filesPropertiesTemplateList=function(){return this.request("files/properties/template/list",null,"user","api","rpc")},_.filesPropertiesUpdate=function(e){return this.request("files/properties/update",e,"user","api","rpc")},_.filesRestore=function(e){return this.request("files/restore",e,"user","api","rpc")},_.filesSaveUrl=function(e){return this.request("files/save_url",e,"user","api","rpc")},_.filesSaveUrlCheckJobStatus=function(e){return this.request("files/save_url/check_job_status",e,"user","api","rpc")},_.filesSearch=function(e){return this.request("files/search",e,"user","api","rpc")},_.filesSearchV2=function(e){return this.request("files/search_v2",e,"user","api","rpc")},_.filesSearchContinueV2=function(e){return this.request("files/search/continue_v2",e,"user","api","rpc")},_.filesUnlockFileBatch=function(e){return this.request("files/unlock_file_batch",e,"user","api","rpc")},_.filesUpload=function(e){return this.request("files/upload",e,"user","content","upload")},_.filesUploadSessionAppendV2=function(e){return this.request("files/upload_session/append_v2",e,"user","content","upload")},_.filesUploadSessionAppend=function(e){return this.request("files/upload_session/append",e,"user","content","upload")},_.filesUploadSessionFinish=function(e){return this.request("files/upload_session/finish",e,"user","content","upload")},_.filesUploadSessionFinishBatch=function(e){return this.request("files/upload_session/finish_batch",e,"user","api","rpc")},_.filesUploadSessionFinishBatchCheck=function(e){return this.request("files/upload_session/finish_batch/check",e,"user","api","rpc")},_.filesUploadSessionStart=function(e){return this.request("files/upload_session/start",e,"user","content","upload")},_.paperDocsArchive=function(e){return this.request("paper/docs/archive",e,"user","api","rpc")},_.paperDocsCreate=function(e){return this.request("paper/docs/create",e,"user","api","upload")},_.paperDocsDownload=function(e){return this.request("paper/docs/download",e,"user","api","download")},_.paperDocsFolderUsersList=function(e){return this.request("paper/docs/folder_users/list",e,"user","api","rpc")},_.paperDocsFolderUsersListContinue=function(e){return this.request("paper/docs/folder_users/list/continue",e,"user","api","rpc")},_.paperDocsGetFolderInfo=function(e){return this.request("paper/docs/get_folder_info",e,"user","api","rpc")},_.paperDocsList=function(e){return this.request("paper/docs/list",e,"user","api","rpc")},_.paperDocsListContinue=function(e){return this.request("paper/docs/list/continue",e,"user","api","rpc")},_.paperDocsPermanentlyDelete=function(e){return this.request("paper/docs/permanently_delete",e,"user","api","rpc")},_.paperDocsSharingPolicyGet=function(e){return this.request("paper/docs/sharing_policy/get",e,"user","api","rpc")},_.paperDocsSharingPolicySet=function(e){return this.request("paper/docs/sharing_policy/set",e,"user","api","rpc")},_.paperDocsUpdate=function(e){return this.request("paper/docs/update",e,"user","api","upload")},_.paperDocsUsersAdd=function(e){return this.request("paper/docs/users/add",e,"user","api","rpc")},_.paperDocsUsersList=function(e){return this.request("paper/docs/users/list",e,"user","api","rpc")},_.paperDocsUsersListContinue=function(e){return this.request("paper/docs/users/list/continue",e,"user","api","rpc")},_.paperDocsUsersRemove=function(e){return this.request("paper/docs/users/remove",e,"user","api","rpc")},_.paperFoldersCreate=function(e){return this.request("paper/folders/create",e,"user","api","rpc")},_.sharingAddFileMember=function(e){return this.request("sharing/add_file_member",e,"user","api","rpc")},_.sharingAddFolderMember=function(e){return this.request("sharing/add_folder_member",e,"user","api","rpc")},_.sharingCheckJobStatus=function(e){return this.request("sharing/check_job_status",e,"user","api","rpc")},_.sharingCheckRemoveMemberJobStatus=function(e){return this.request("sharing/check_remove_member_job_status",e,"user","api","rpc")},_.sharingCheckShareJobStatus=function(e){return this.request("sharing/check_share_job_status",e,"user","api","rpc")},_.sharingCreateSharedLink=function(e){return this.request("sharing/create_shared_link",e,"user","api","rpc")},_.sharingCreateSharedLinkWithSettings=function(e){return this.request("sharing/create_shared_link_with_settings",e,"user","api","rpc")},_.sharingGetFileMetadata=function(e){return this.request("sharing/get_file_metadata",e,"user","api","rpc")},_.sharingGetFileMetadataBatch=function(e){return this.request("sharing/get_file_metadata/batch",e,"user","api","rpc")},_.sharingGetFolderMetadata=function(e){return this.request("sharing/get_folder_metadata",e,"user","api","rpc")},_.sharingGetSharedLinkFile=function(e){return this.request("sharing/get_shared_link_file",e,"user","content","download")},_.sharingGetSharedLinkMetadata=function(e){return this.request("sharing/get_shared_link_metadata",e,"user","api","rpc")},_.sharingGetSharedLinks=function(e){return this.request("sharing/get_shared_links",e,"user","api","rpc")},_.sharingListFileMembers=function(e){return this.request("sharing/list_file_members",e,"user","api","rpc")},_.sharingListFileMembersBatch=function(e){return this.request("sharing/list_file_members/batch",e,"user","api","rpc")},_.sharingListFileMembersContinue=function(e){return this.request("sharing/list_file_members/continue",e,"user","api","rpc")},_.sharingListFolderMembers=function(e){return this.request("sharing/list_folder_members",e,"user","api","rpc")},_.sharingListFolderMembersContinue=function(e){return this.request("sharing/list_folder_members/continue",e,"user","api","rpc")},_.sharingListFolders=function(e){return this.request("sharing/list_folders",e,"user","api","rpc")},_.sharingListFoldersContinue=function(e){return this.request("sharing/list_folders/continue",e,"user","api","rpc")},_.sharingListMountableFolders=function(e){return this.request("sharing/list_mountable_folders",e,"user","api","rpc")},_.sharingListMountableFoldersContinue=function(e){return this.request("sharing/list_mountable_folders/continue",e,"user","api","rpc")},_.sharingListReceivedFiles=function(e){return this.request("sharing/list_received_files",e,"user","api","rpc")},_.sharingListReceivedFilesContinue=function(e){return this.request("sharing/list_received_files/continue",e,"user","api","rpc")},_.sharingListSharedLinks=function(e){return this.request("sharing/list_shared_links",e,"user","api","rpc")},_.sharingModifySharedLinkSettings=function(e){return this.request("sharing/modify_shared_link_settings",e,"user","api","rpc")},_.sharingMountFolder=function(e){return this.request("sharing/mount_folder",e,"user","api","rpc")},_.sharingRelinquishFileMembership=function(e){return this.request("sharing/relinquish_file_membership",e,"user","api","rpc")},_.sharingRelinquishFolderMembership=function(e){return this.request("sharing/relinquish_folder_membership",e,"user","api","rpc")},_.sharingRemoveFileMember=function(e){return this.request("sharing/remove_file_member",e,"user","api","rpc")},_.sharingRemoveFileMember2=function(e){return this.request("sharing/remove_file_member_2",e,"user","api","rpc")},_.sharingRemoveFolderMember=function(e){return this.request("sharing/remove_folder_member",e,"user","api","rpc")},_.sharingRevokeSharedLink=function(e){return this.request("sharing/revoke_shared_link",e,"user","api","rpc")},_.sharingSetAccessInheritance=function(e){return this.request("sharing/set_access_inheritance",e,"user","api","rpc")},_.sharingShareFolder=function(e){return this.request("sharing/share_folder",e,"user","api","rpc")},_.sharingTransferFolder=function(e){return this.request("sharing/transfer_folder",e,"user","api","rpc")},_.sharingUnmountFolder=function(e){return this.request("sharing/unmount_folder",e,"user","api","rpc")},_.sharingUnshareFile=function(e){return this.request("sharing/unshare_file",e,"user","api","rpc")},_.sharingUnshareFolder=function(e){return this.request("sharing/unshare_folder",e,"user","api","rpc")},_.sharingUpdateFileMember=function(e){return this.request("sharing/update_file_member",e,"user","api","rpc")},_.sharingUpdateFolderMember=function(e){return this.request("sharing/update_folder_member",e,"user","api","rpc")},_.sharingUpdateFolderPolicy=function(e){return this.request("sharing/update_folder_policy",e,"user","api","rpc")},_.teamDevicesListMemberDevices=function(e){return this.request("team/devices/list_member_devices",e,"team","api","rpc")},_.teamDevicesListMembersDevices=function(e){return this.request("team/devices/list_members_devices",e,"team","api","rpc")},_.teamDevicesListTeamDevices=function(e){return this.request("team/devices/list_team_devices",e,"team","api","rpc")},_.teamDevicesRevokeDeviceSession=function(e){return this.request("team/devices/revoke_device_session",e,"team","api","rpc")},_.teamDevicesRevokeDeviceSessionBatch=function(e){return this.request("team/devices/revoke_device_session_batch",e,"team","api","rpc")},_.teamFeaturesGetValues=function(e){return this.request("team/features/get_values",e,"team","api","rpc")},_.teamGetInfo=function(){return this.request("team/get_info",null,"team","api","rpc")},_.teamGroupsCreate=function(e){return this.request("team/groups/create",e,"team","api","rpc")},_.teamGroupsDelete=function(e){return this.request("team/groups/delete",e,"team","api","rpc")},_.teamGroupsGetInfo=function(e){return this.request("team/groups/get_info",e,"team","api","rpc")},_.teamGroupsJobStatusGet=function(e){return this.request("team/groups/job_status/get",e,"team","api","rpc")},_.teamGroupsList=function(e){return this.request("team/groups/list",e,"team","api","rpc")},_.teamGroupsListContinue=function(e){return this.request("team/groups/list/continue",e,"team","api","rpc")},_.teamGroupsMembersAdd=function(e){return this.request("team/groups/members/add",e,"team","api","rpc")},_.teamGroupsMembersList=function(e){return this.request("team/groups/members/list",e,"team","api","rpc")},_.teamGroupsMembersListContinue=function(e){return this.request("team/groups/members/list/continue",e,"team","api","rpc")},_.teamGroupsMembersRemove=function(e){return this.request("team/groups/members/remove",e,"team","api","rpc")},_.teamGroupsMembersSetAccessType=function(e){return this.request("team/groups/members/set_access_type",e,"team","api","rpc")},_.teamGroupsUpdate=function(e){return this.request("team/groups/update",e,"team","api","rpc")},_.teamLegalHoldsCreatePolicy=function(e){return this.request("team/legal_holds/create_policy",e,"team","api","rpc")},_.teamLegalHoldsGetPolicy=function(e){return this.request("team/legal_holds/get_policy",e,"team","api","rpc")},_.teamLegalHoldsListHeldRevisions=function(e){return this.request("team/legal_holds/list_held_revisions",e,"team","api","rpc")},_.teamLegalHoldsListHeldRevisionsContinue=function(e){return this.request("team/legal_holds/list_held_revisions_continue",e,"team","api","rpc")},_.teamLegalHoldsListPolicies=function(e){return this.request("team/legal_holds/list_policies",e,"team","api","rpc")},_.teamLegalHoldsReleasePolicy=function(e){return this.request("team/legal_holds/release_policy",e,"team","api","rpc")},_.teamLegalHoldsUpdatePolicy=function(e){return this.request("team/legal_holds/update_policy",e,"team","api","rpc")},_.teamLinkedAppsListMemberLinkedApps=function(e){return this.request("team/linked_apps/list_member_linked_apps",e,"team","api","rpc")},_.teamLinkedAppsListMembersLinkedApps=function(e){return this.request("team/linked_apps/list_members_linked_apps",e,"team","api","rpc")},_.teamLinkedAppsListTeamLinkedApps=function(e){return this.request("team/linked_apps/list_team_linked_apps",e,"team","api","rpc")},_.teamLinkedAppsRevokeLinkedApp=function(e){return this.request("team/linked_apps/revoke_linked_app",e,"team","api","rpc")},_.teamLinkedAppsRevokeLinkedAppBatch=function(e){return this.request("team/linked_apps/revoke_linked_app_batch",e,"team","api","rpc")},_.teamMemberSpaceLimitsExcludedUsersAdd=function(e){return this.request("team/member_space_limits/excluded_users/add",e,"team","api","rpc")},_.teamMemberSpaceLimitsExcludedUsersList=function(e){return this.request("team/member_space_limits/excluded_users/list",e,"team","api","rpc")},_.teamMemberSpaceLimitsExcludedUsersListContinue=function(e){return this.request("team/member_space_limits/excluded_users/list/continue",e,"team","api","rpc")},_.teamMemberSpaceLimitsExcludedUsersRemove=function(e){return this.request("team/member_space_limits/excluded_users/remove",e,"team","api","rpc")},_.teamMemberSpaceLimitsGetCustomQuota=function(e){return this.request("team/member_space_limits/get_custom_quota",e,"team","api","rpc")},_.teamMemberSpaceLimitsRemoveCustomQuota=function(e){return this.request("team/member_space_limits/remove_custom_quota",e,"team","api","rpc")},_.teamMemberSpaceLimitsSetCustomQuota=function(e){return this.request("team/member_space_limits/set_custom_quota",e,"team","api","rpc")},_.teamMembersAddV2=function(e){return this.request("team/members/add_v2",e,"team","api","rpc")},_.teamMembersAdd=function(e){return this.request("team/members/add",e,"team","api","rpc")},_.teamMembersAddJobStatusGetV2=function(e){return this.request("team/members/add/job_status/get_v2",e,"team","api","rpc")},_.teamMembersAddJobStatusGet=function(e){return this.request("team/members/add/job_status/get",e,"team","api","rpc")},_.teamMembersDeleteProfilePhotoV2=function(e){return this.request("team/members/delete_profile_photo_v2",e,"team","api","rpc")},_.teamMembersDeleteProfilePhoto=function(e){return this.request("team/members/delete_profile_photo",e,"team","api","rpc")},_.teamMembersGetAvailableTeamMemberRoles=function(){return this.request("team/members/get_available_team_member_roles",null,"team","api","rpc")},_.teamMembersGetInfoV2=function(e){return this.request("team/members/get_info_v2",e,"team","api","rpc")},_.teamMembersGetInfo=function(e){return this.request("team/members/get_info",e,"team","api","rpc")},_.teamMembersListV2=function(e){return this.request("team/members/list_v2",e,"team","api","rpc")},_.teamMembersList=function(e){return this.request("team/members/list",e,"team","api","rpc")},_.teamMembersListContinueV2=function(e){return this.request("team/members/list/continue_v2",e,"team","api","rpc")},_.teamMembersListContinue=function(e){return this.request("team/members/list/continue",e,"team","api","rpc")},_.teamMembersMoveFormerMemberFiles=function(e){return this.request("team/members/move_former_member_files",e,"team","api","rpc")},_.teamMembersMoveFormerMemberFilesJobStatusCheck=function(e){return this.request("team/members/move_former_member_files/job_status/check",e,"team","api","rpc")},_.teamMembersRecover=function(e){return this.request("team/members/recover",e,"team","api","rpc")},_.teamMembersRemove=function(e){return this.request("team/members/remove",e,"team","api","rpc")},_.teamMembersRemoveJobStatusGet=function(e){return this.request("team/members/remove/job_status/get",e,"team","api","rpc")},_.teamMembersSecondaryEmailsAdd=function(e){return this.request("team/members/secondary_emails/add",e,"team","api","rpc")},_.teamMembersSecondaryEmailsDelete=function(e){return this.request("team/members/secondary_emails/delete",e,"team","api","rpc")},_.teamMembersSecondaryEmailsResendVerificationEmails=function(e){return this.request("team/members/secondary_emails/resend_verification_emails",e,"team","api","rpc")},_.teamMembersSendWelcomeEmail=function(e){return this.request("team/members/send_welcome_email",e,"team","api","rpc")},_.teamMembersSetAdminPermissionsV2=function(e){return this.request("team/members/set_admin_permissions_v2",e,"team","api","rpc")},_.teamMembersSetAdminPermissions=function(e){return this.request("team/members/set_admin_permissions",e,"team","api","rpc")},_.teamMembersSetProfileV2=function(e){return this.request("team/members/set_profile_v2",e,"team","api","rpc")},_.teamMembersSetProfile=function(e){return this.request("team/members/set_profile",e,"team","api","rpc")},_.teamMembersSetProfilePhotoV2=function(e){return this.request("team/members/set_profile_photo_v2",e,"team","api","rpc")},_.teamMembersSetProfilePhoto=function(e){return this.request("team/members/set_profile_photo",e,"team","api","rpc")},_.teamMembersSuspend=function(e){return this.request("team/members/suspend",e,"team","api","rpc")},_.teamMembersUnsuspend=function(e){return this.request("team/members/unsuspend",e,"team","api","rpc")},_.teamNamespacesList=function(e){return this.request("team/namespaces/list",e,"team","api","rpc")},_.teamNamespacesListContinue=function(e){return this.request("team/namespaces/list/continue",e,"team","api","rpc")},_.teamPropertiesTemplateAdd=function(e){return this.request("team/properties/template/add",e,"team","api","rpc")},_.teamPropertiesTemplateGet=function(e){return this.request("team/properties/template/get",e,"team","api","rpc")},_.teamPropertiesTemplateList=function(){return this.request("team/properties/template/list",null,"team","api","rpc")},_.teamPropertiesTemplateUpdate=function(e){return this.request("team/properties/template/update",e,"team","api","rpc")},_.teamReportsGetActivity=function(e){return this.request("team/reports/get_activity",e,"team","api","rpc")},_.teamReportsGetDevices=function(e){return this.request("team/reports/get_devices",e,"team","api","rpc")},_.teamReportsGetMembership=function(e){return this.request("team/reports/get_membership",e,"team","api","rpc")},_.teamReportsGetStorage=function(e){return this.request("team/reports/get_storage",e,"team","api","rpc")},_.teamTeamFolderActivate=function(e){return this.request("team/team_folder/activate",e,"team","api","rpc")},_.teamTeamFolderArchive=function(e){return this.request("team/team_folder/archive",e,"team","api","rpc")},_.teamTeamFolderArchiveCheck=function(e){return this.request("team/team_folder/archive/check",e,"team","api","rpc")},_.teamTeamFolderCreate=function(e){return this.request("team/team_folder/create",e,"team","api","rpc")},_.teamTeamFolderGetInfo=function(e){return this.request("team/team_folder/get_info",e,"team","api","rpc")},_.teamTeamFolderList=function(e){return this.request("team/team_folder/list",e,"team","api","rpc")},_.teamTeamFolderListContinue=function(e){return this.request("team/team_folder/list/continue",e,"team","api","rpc")},_.teamTeamFolderPermanentlyDelete=function(e){return this.request("team/team_folder/permanently_delete",e,"team","api","rpc")},_.teamTeamFolderRename=function(e){return this.request("team/team_folder/rename",e,"team","api","rpc")},_.teamTeamFolderUpdateSyncSettings=function(e){return this.request("team/team_folder/update_sync_settings",e,"team","api","rpc")},_.teamTokenGetAuthenticatedAdmin=function(){return this.request("team/token/get_authenticated_admin",null,"team","api","rpc")},_.teamLogGetEvents=function(e){return this.request("team_log/get_events",e,"team","api","rpc")},_.teamLogGetEventsContinue=function(e){return this.request("team_log/get_events/continue",e,"team","api","rpc")},_.usersFeaturesGetValues=function(e){return this.request("users/features/get_values",e,"user","api","rpc")},_.usersGetAccount=function(e){return this.request("users/get_account",e,"user","api","rpc")},_.usersGetAccountBatch=function(e){return this.request("users/get_account_batch",e,"user","api","rpc")},_.usersGetCurrentAccount=function(){return this.request("users/get_current_account",null,"user","api","rpc")},_.usersGetSpaceUsage=function(){return this.request("users/get_space_usage",null,"user","api","rpc")};var g=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:h,r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:".";return t!==h&&void 0!==d[e]&&(e=d[e],r="-"),"https://".concat(e).concat(r).concat(t,"/2/")},b=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:m;return e!==m&&(e="meta-".concat(e)),"https://".concat(e,"/oauth2/authorize")},v=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:h,t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:".",r="api";return e!==h&&(r=d[r],t="-"),"https://".concat(r).concat(t).concat(e,"/oauth2/token")};function k(e){return JSON.stringify(e).replace(/[\u007f-\uffff]/g,q)}function y(e){return new Date(Date.now()+1e3*e)}function A(){return"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope||"undefined"==typeof module||"undefined"!=typeof window}function C(){return"undefined"!=typeof window}function S(e){return e.toString("base64").replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}var T,L,w,M=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&n(e,t)}(o,e);var r,s,a=(r=o,s=u(),function(){var e,t=i(r);if(s){var n=i(this).constructor;e=Reflect.construct(t,arguments,n)}else e=t.apply(this,arguments);return c(this,e)});function o(e,r,s){var i;return t(this,o),(i=a.call(this,"Response failed with a ".concat(e," code"))).name="DropboxResponseError",i.status=e,i.headers=r,i.error=s,i}return o}(o(Error)),P=function e(r,s,i){t(this,e),this.status=r,this.headers=s,this.result=i};function R(e){return e.text().then((function(t){var r;try{r=JSON.parse(t)}catch(e){r=t}throw new M(e.status,e.headers,r)}))}function F(e){return e.ok?e.text().then((function(t){var r;try{r=JSON.parse(t)}catch(e){r=t}return new P(e.status,e.headers,r)})):R(e)}T=C()?window.fetch.bind(window):require("node-fetch"),L=C()?window.crypto||window.msCrypto:require("crypto"),w="undefined"==typeof TextEncoder?require("util").TextEncoder:TextEncoder;var D,G=["legacy","offline","online"],U=["code","token"],x=["none","user","team"],E=function(){function e(r){t(this,e),this.fetch=(r=r||{}).fetch||T,this.accessToken=r.accessToken,this.accessTokenExpiresAt=r.accessTokenExpiresAt,this.refreshToken=r.refreshToken,this.clientId=r.clientId,this.clientSecret=r.clientSecret,this.domain=r.domain,this.domainDelimiter=r.domainDelimiter}return s(e,[{key:"setAccessToken",value:function(e){this.accessToken=e}},{key:"getAccessToken",value:function(){return this.accessToken}},{key:"setClientId",value:function(e){this.clientId=e}},{key:"getClientId",value:function(){return this.clientId}},{key:"setClientSecret",value:function(e){this.clientSecret=e}},{key:"getClientSecret",value:function(){return this.clientSecret}},{key:"getRefreshToken",value:function(){return this.refreshToken}},{key:"setRefreshToken",value:function(e){this.refreshToken=e}},{key:"getAccessTokenExpiresAt",value:function(){return this.accessTokenExpiresAt}},{key:"setAccessTokenExpiresAt",value:function(e){this.accessTokenExpiresAt=e}},{key:"setCodeVerifier",value:function(e){this.codeVerifier=e}},{key:"getCodeVerifier",value:function(){return this.codeVerifier}},{key:"generateCodeChallenge",value:function(){var e,t=this,r=(new w).encode(this.codeVerifier);if(C())return L.subtle.digest("SHA-256",r).then((function(r){var s=btoa(String.fromCharCode.apply(null,new Uint8Array(r)));e=S(s).substr(0,128),t.codeChallenge=e}));var s=L.createHash("sha256").update(r).digest();return e=S(s),this.codeChallenge=e,Promise.resolve()}},{key:"generatePKCECodes",value:function(){var e;if(C()){var t=new Uint8Array(128),r=L.getRandomValues(t);e=S(btoa(r)).substr(0,128)}else{e=S(L.randomBytes(128)).substr(0,128)}return this.codeVerifier=e,this.generateCodeChallenge()}},{key:"getAuthenticationUrl",value:function(e,t){var r,s=this,i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"token",n=arguments.length>3&&void 0!==arguments[3]?arguments[3]:null,u=arguments.length>4&&void 0!==arguments[4]?arguments[4]:null,a=arguments.length>5&&void 0!==arguments[5]?arguments[5]:"none",o=arguments.length>6&&void 0!==arguments[6]&&arguments[6],c=this.getClientId(),p=b(this.domain);if(!c)throw Error("A client id is required. You can set the client id using .setClientId().");if("code"!==i&&!e)throw Error("A redirect uri is required.");if(!U.includes(i))throw Error("Authorization type must be code or token");if(n&&!G.includes(n))throw Error("Token Access Type must be legacy, offline, or online");if(u&&!(u instanceof Array))throw Error("Scope must be an array of strings");if(!x.includes(a))throw Error("includeGrantedScopes must be none, user, or team");return r="code"===i?"".concat(p,"?response_type=code&client_id=").concat(c):"".concat(p,"?response_type=token&client_id=").concat(c),e&&(r+="&redirect_uri=".concat(e)),t&&(r+="&state=".concat(t)),n&&(r+="&token_access_type=".concat(n)),u&&(r+="&scope=".concat(u.join(" "))),"none"!==a&&(r+="&include_granted_scopes=".concat(a)),o?this.generatePKCECodes().then((function(){return r+="&code_challenge_method=S256",r+="&code_challenge=".concat(s.codeChallenge)})):Promise.resolve(r)}},{key:"getAccessTokenFromCode",value:function(e,t){var r=this.getClientId(),s=this.getClientSecret();if(!r)throw Error("A client id is required. You can set the client id using .setClientId().");var i=v(this.domain,this.domainDelimiter);if(i+="?grant_type=authorization_code",i+="&code=".concat(t),i+="&client_id=".concat(r),s)i+="&client_secret=".concat(s);else{if(!this.codeVerifier)throw Error("You must use PKCE when generating the authorization URL to not include a client secret");i+="&code_verifier=".concat(this.codeVerifier)}e&&(i+="&redirect_uri=".concat(e));return this.fetch(i,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"}}).then((function(e){return F(e)}))}},{key:"checkAndRefreshAccessToken",value:function(){var e=this.getRefreshToken()&&this.getClientId(),t=!this.getAccessTokenExpiresAt()||new Date(Date.now()+3e5)>=this.getAccessTokenExpiresAt(),r=!this.getAccessToken();return(t||r)&&e?this.refreshAccessToken():Promise.resolve()}},{key:"refreshAccessToken",value:function(){var e=this,t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,r=v(this.domain,this.domainDelimiter),s=this.getClientId(),i=this.getClientSecret();if(!s)throw Error("A client id is required. You can set the client id using .setClientId().");if(t&&!(t instanceof Array))throw Error("Scope must be an array of strings");var n={"Content-Type":"application/json"};r+="?grant_type=refresh_token&refresh_token=".concat(this.getRefreshToken()),r+="&client_id=".concat(s),i&&(r+="&client_secret=".concat(i)),t&&(r+="&scope=".concat(t.join(" ")));var u={method:"POST"};return u.headers=n,this.fetch(r,u).then((function(e){return F(e)})).then((function(t){e.setAccessToken(t.result.access_token),e.setAccessTokenExpiresAt(y(t.result.expires_in))}))}}]),e}();D="undefined"!=typeof window?window.fetch.bind(window):require("node-fetch");var V="undefined"==typeof btoa?function(e){return Buffer.from(e).toString("base64")}:btoa;e.Dropbox=function(){function e(r){t(this,e),this.auth=(r=r||{}).auth?r.auth:new E(r),this.fetch=r.fetch||D,this.selectUser=r.selectUser,this.selectAdmin=r.selectAdmin,this.pathRoot=r.pathRoot,this.domain=r.domain,this.domainDelimiter=r.domainDelimiter,Object.assign(this,_)}return s(e,[{key:"request",value:function(e,t,r,s,i){if(r.split(",").length>1){var n=r.replace(" ","").split(",");n.includes(l)&&this.auth.getAccessToken()?r=l:n.includes(f)&&this.auth.getAccessToken()?r=f:n.includes(p)&&(r=p)}switch(i){case"rpc":return this.rpcRequest(e,t,r,s);case"download":return this.downloadRequest(e,t,r,s);case"upload":return this.uploadRequest(e,t,r,s);default:throw Error("Invalid request style: ".concat(i))}}},{key:"rpcRequest",value:function(e,t,r,s){var i=this;return this.auth.checkAndRefreshAccessToken().then((function(){var e,s={method:"POST",body:t?JSON.stringify(t):null,headers:{}};switch(t&&(s.headers["Content-Type"]="application/json"),r){case p:if(!i.auth.clientId||!i.auth.clientSecret)throw Error("A client id and secret is required for this function");e=V("".concat(i.auth.clientId,":").concat(i.auth.clientSecret)),s.headers.Authorization="Basic ".concat(e);break;case f:case l:s.headers.Authorization="Bearer ".concat(i.auth.getAccessToken());break;case"noauth":break;default:throw Error("Unhandled auth type: ".concat(r))}return i.setCommonHeaders(s),s})).then((function(t){return i.fetch(g(s,i.domain,i.domainDelimiter)+e,t)})).then((function(e){return F(e)}))}},{key:"downloadRequest",value:function(e,t,r,s){var i=this;return this.auth.checkAndRefreshAccessToken().then((function(){if(r!==l)throw Error("Unexpected auth type: ".concat(r));var e={method:"POST",headers:{Authorization:"Bearer ".concat(i.auth.getAccessToken()),"Dropbox-API-Arg":k(t)}};return i.setCommonHeaders(e),e})).then((function(t){return i.fetch(g(s,i.domain,i.domainDelimiter)+e,t)})).then((function(e){return function(e){return e.ok?new Promise((function(t){A()?e.blob().then((function(e){return t(e)})):e.buffer().then((function(e){return t(e)}))})).then((function(t){var r=JSON.parse(e.headers.get("dropbox-api-result"));return A()?r.fileBlob=t:r.fileBinary=t,new P(e.status,e.headers,r)})):R(e)}(e)}))}},{key:"uploadRequest",value:function(e,t,r,s){var i=this;return this.auth.checkAndRefreshAccessToken().then((function(){if(r!==l)throw Error("Unexpected auth type: ".concat(r));var e=t.contents;delete t.contents;var s={body:e,method:"POST",headers:{Authorization:"Bearer ".concat(i.auth.getAccessToken()),"Content-Type":"application/octet-stream","Dropbox-API-Arg":k(t)}};return i.setCommonHeaders(s),s})).then((function(t){return i.fetch(g(s,i.domain,i.domainDelimiter)+e,t)})).then((function(e){return F(e)}))}},{key:"setCommonHeaders",value:function(e){this.selectUser&&(e.headers["Dropbox-API-Select-User"]=this.selectUser),this.selectAdmin&&(e.headers["Dropbox-API-Select-Admin"]=this.selectAdmin),this.pathRoot&&(e.headers["Dropbox-API-Path-Root"]=this.pathRoot)}}]),e}(),e.DropboxAuth=E,e.DropboxResponse=P,e.DropboxResponseError=M,Object.defineProperty(e,"__esModule",{value:!0})})); diff --git a/mobile_app/assets/www/libs/flatqueue.js b/mobile_app/assets/www/libs/flatqueue.js new file mode 100644 index 00000000..271aaf32 --- /dev/null +++ b/mobile_app/assets/www/libs/flatqueue.js @@ -0,0 +1,57 @@ +!(function (t, s) { + "object" == typeof exports && "undefined" != typeof module + ? (module.exports = s()) + : "function" == typeof define && define.amd + ? define(s) + : ((t = "undefined" != typeof globalThis ? globalThis : t || self).FlatQueue = s()); +})(this, function () { + "use strict"; + return class { + constructor() { + (this.ids = []), (this.values = []), (this.length = 0); + } + clear() { + this.length = 0; + } + push(t, s) { + let i = this.length++; + for (; i > 0; ) { + const t = (i - 1) >> 1, + e = this.values[t]; + if (s >= e) break; + (this.ids[i] = this.ids[t]), (this.values[i] = e), (i = t); + } + (this.ids[i] = t), (this.values[i] = s); + } + pop() { + if (0 === this.length) return; + const t = this.ids[0]; + if ((this.length--, this.length > 0)) { + const t = (this.ids[0] = this.ids[this.length]), + s = (this.values[0] = this.values[this.length]), + i = this.length >> 1; + let e = 0; + for (; e < i; ) { + let t = 1 + (e << 1); + const i = t + 1; + let h = this.ids[t], + l = this.values[t]; + const n = this.values[i]; + if ((i < this.length && n < l && ((t = i), (h = this.ids[i]), (l = n)), l >= s)) break; + (this.ids[e] = h), (this.values[e] = l), (e = t); + } + (this.ids[e] = t), (this.values[e] = s); + } + return t; + } + peek() { + if (0 !== this.length) return this.ids[0]; + } + peekValue() { + if (0 !== this.length) return this.values[0]; + } + shrink() { + this.ids.length = this.values.length = this.length; + } + }; +}); diff --git a/mobile_app/assets/www/libs/indexedDB.js b/mobile_app/assets/www/libs/indexedDB.js new file mode 100644 index 00000000..37e89c13 --- /dev/null +++ b/mobile_app/assets/www/libs/indexedDB.js @@ -0,0 +1,65 @@ +let db; + +const DATABASE_NAME = "d2"; +const STORE_NAME = "s"; + +const openDatabase = () => { + return new Promise((resolve, reject) => { + if (db) resolve(); + + if (!window.indexedDB) return reject("IndexedDB is not supported"); + const request = window.indexedDB.open(DATABASE_NAME); + + request.onsuccess = event => { + db = event.target.result; + resolve(); + }; + + request.onerror = event => { + console.error("IndexedDB request error"); + reject(); + }; + + request.onupgradeneeded = event => { + db = event.target.result; + const objectStore = db.createObjectStore(STORE_NAME, {keyPath: "key"}); + objectStore.transaction.oncomplete = () => { + db = event.target.result; + }; + }; + }); +}; + +const ldb = { + get: key => { + return new Promise((resolve, reject) => { + openDatabase().then(() => { + const hasStore = Array.from(db.objectStoreNames).includes(STORE_NAME); + if (!hasStore) return reject("IndexedDB: no store found"); + + const transaction = db.transaction(STORE_NAME, "readonly"); + const objectStore = transaction.objectStore(STORE_NAME); + const getRequest = objectStore.get(key); + + getRequest.onsuccess = event => { + const result = event.target.result?.value || null; + resolve(result); + }; + }); + }); + }, + + set: (keyName, value) => { + return new Promise(resolve => { + openDatabase().then(() => { + const transaction = db.transaction(STORE_NAME, "readwrite"); + const objectStore = transaction.objectStore([STORE_NAME]); + const putRequest = objectStore.put({key: keyName, value}); + + putRequest.onsuccess = () => { + resolve(); + }; + }); + }); + } +}; diff --git a/mobile_app/assets/www/libs/jquery-3.1.1.min.js b/mobile_app/assets/www/libs/jquery-3.1.1.min.js new file mode 100644 index 00000000..4c5be4c0 --- /dev/null +++ b/mobile_app/assets/www/libs/jquery-3.1.1.min.js @@ -0,0 +1,4 @@ +/*! jQuery v3.1.1 | (c) jQuery Foundation | jquery.org/license */ +!function(a,b){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){"use strict";var c=[],d=a.document,e=Object.getPrototypeOf,f=c.slice,g=c.concat,h=c.push,i=c.indexOf,j={},k=j.toString,l=j.hasOwnProperty,m=l.toString,n=m.call(Object),o={};function p(a,b){b=b||d;var c=b.createElement("script");c.text=a,b.head.appendChild(c).parentNode.removeChild(c)}var q="3.1.1",r=function(a,b){return new r.fn.init(a,b)},s=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,t=/^-ms-/,u=/-([a-z])/g,v=function(a,b){return b.toUpperCase()};r.fn=r.prototype={jquery:q,constructor:r,length:0,toArray:function(){return f.call(this)},get:function(a){return null==a?f.call(this):a<0?this[a+this.length]:this[a]},pushStack:function(a){var b=r.merge(this.constructor(),a);return b.prevObject=this,b},each:function(a){return r.each(this,a)},map:function(a){return this.pushStack(r.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(f.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(a<0?b:0);return this.pushStack(c>=0&&c0&&b-1 in a)}var x=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=function(a,b){for(var c=0,d=a.length;c+~]|"+K+")"+K+"*"),S=new RegExp("="+K+"*([^\\]'\"]*?)"+K+"*\\]","g"),T=new RegExp(N),U=new RegExp("^"+L+"$"),V={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L+"|[*])"),ATTR:new RegExp("^"+M),PSEUDO:new RegExp("^"+N),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+K+"*(even|odd|(([+-]|)(\\d*)n|)"+K+"*(?:([+-]|)"+K+"*(\\d+)|))"+K+"*\\)|)","i"),bool:new RegExp("^(?:"+J+")$","i"),needsContext:new RegExp("^"+K+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+K+"*((?:-\\d)?\\d*)"+K+"*\\)|)(?=[^-]|$)","i")},W=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,$=/[+~]/,_=new RegExp("\\\\([\\da-f]{1,6}"+K+"?|("+K+")|.)","ig"),aa=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:d<0?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ba=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ca=function(a,b){return b?"\0"===a?"\ufffd":a.slice(0,-1)+"\\"+a.charCodeAt(a.length-1).toString(16)+" ":"\\"+a},da=function(){m()},ea=ta(function(a){return a.disabled===!0&&("form"in a||"label"in a)},{dir:"parentNode",next:"legend"});try{G.apply(D=H.call(v.childNodes),v.childNodes),D[v.childNodes.length].nodeType}catch(fa){G={apply:D.length?function(a,b){F.apply(a,H.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s=b&&b.ownerDocument,w=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==w&&9!==w&&11!==w)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==w&&(l=Z.exec(a)))if(f=l[1]){if(9===w){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(s&&(j=s.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(l[2])return G.apply(d,b.getElementsByTagName(a)),d;if((f=l[3])&&c.getElementsByClassName&&b.getElementsByClassName)return G.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==w)s=b,r=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(ba,ca):b.setAttribute("id",k=u),o=g(a),h=o.length;while(h--)o[h]="#"+k+" "+sa(o[h]);r=o.join(","),s=$.test(a)&&qa(b.parentNode)||b}if(r)try{return G.apply(d,s.querySelectorAll(r)),d}catch(x){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(P,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("fieldset");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&a.sourceIndex-b.sourceIndex;if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return function(b){return"form"in b?b.parentNode&&b.disabled===!1?"label"in b?"label"in b.parentNode?b.parentNode.disabled===a:b.disabled===a:b.isDisabled===a||b.isDisabled!==!a&&ea(b)===a:b.disabled===a:"label"in b&&b.disabled===a}}function pa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function qa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return!!b&&"HTML"!==b.nodeName},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),v!==n&&(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Y.test(n.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){return a.getAttribute("id")===b}},d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}}):(d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}},d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c,d,e,f=b.getElementById(a);if(f){if(c=f.getAttributeNode("id"),c&&c.value===a)return[f];e=b.getElementsByName(a),d=0;while(f=e[d++])if(c=f.getAttributeNode("id"),c&&c.value===a)return[f]}return[]}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){if("undefined"!=typeof b.getElementsByClassName&&p)return b.getElementsByClassName(a)},r=[],q=[],(c.qsa=Y.test(n.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML="",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+K+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+K+"*(?:value|"+J+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){a.innerHTML="";var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+K+"*[*^$|!~]?="),2!==a.querySelectorAll(":enabled").length&&q.push(":enabled",":disabled"),o.appendChild(a).disabled=!0,2!==a.querySelectorAll(":disabled").length&&q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Y.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"*"),s.call(a,"[s!='']:x"),r.push("!=",N)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Y.test(o.compareDocumentPosition),t=b||Y.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?I(k,a)-I(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?I(k,a)-I(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?la(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(S,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&C.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.escape=function(a){return(a+"").replace(ba,ca)},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(_,aa),a[3]=(a[3]||a[4]||a[5]||"").replace(_,aa),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return V.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&T.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(_,aa).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+K+")"+a+"("+K+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?"!="===b:!b||(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(O," ")+" ").indexOf(c)>-1:"|="===b&&(e===c||e.slice(0,c.length+1)===c+"-"))}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=I(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(P,"$1"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(_,aa),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return U.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(_,aa).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:oa(!1),disabled:oa(!0),checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return X.test(a.nodeName)},input:function(a){return W.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:pa(function(){return[0]}),last:pa(function(a,b){return[b-1]}),eq:pa(function(a,b,c){return[c<0?c+b:c]}),even:pa(function(a,b){for(var c=0;c=0;)a.push(d);return a}),gt:pa(function(a,b,c){for(var d=c<0?c+b:c;++d1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function va(a,b,c){for(var d=0,e=b.length;d-1&&(f[j]=!(g[j]=l))}}else r=wa(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):G.apply(g,r)})}function ya(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ta(function(a){return a===b},h,!0),l=ta(function(a){return I(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];i1&&ua(m),i>1&&sa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(P,"$1"),c,i0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=E.call(i));u=wa(u)}G.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&ga.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=ya(b[c]),f[u]?d.push(f):e.push(f);f=A(a,za(e,d)),f.selector=a}return f},i=ga.select=function(a,b,c,e){var f,i,j,k,l,m="function"==typeof a&&a,n=!e&&g(a=m.selector||a);if(c=c||[],1===n.length){if(i=n[0]=n[0].slice(0),i.length>2&&"ID"===(j=i[0]).type&&9===b.nodeType&&p&&d.relative[i[1].type]){if(b=(d.find.ID(j.matches[0].replace(_,aa),b)||[])[0],!b)return c;m&&(b=b.parentNode),a=a.slice(i.shift().value.length)}f=V.needsContext.test(a)?0:i.length;while(f--){if(j=i[f],d.relative[k=j.type])break;if((l=d.find[k])&&(e=l(j.matches[0].replace(_,aa),$.test(i[0].type)&&qa(b.parentNode)||b))){if(i.splice(f,1),a=e.length&&sa(i),!a)return G.apply(c,e),c;break}}}return(m||h(a,n))(e,b,!p,c,!b||$.test(a)&&qa(b.parentNode)||b),c},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("fieldset"))}),ja(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){if(!c)return a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){if(!c&&"input"===a.nodeName.toLowerCase())return a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(J,function(a,b,c){var d;if(!c)return a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);r.find=x,r.expr=x.selectors,r.expr[":"]=r.expr.pseudos,r.uniqueSort=r.unique=x.uniqueSort,r.text=x.getText,r.isXMLDoc=x.isXML,r.contains=x.contains,r.escapeSelector=x.escape;var y=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&r(a).is(c))break;d.push(a)}return d},z=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},A=r.expr.match.needsContext,B=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i,C=/^.[^:#\[\.,]*$/;function D(a,b,c){return r.isFunction(b)?r.grep(a,function(a,d){return!!b.call(a,d,a)!==c}):b.nodeType?r.grep(a,function(a){return a===b!==c}):"string"!=typeof b?r.grep(a,function(a){return i.call(b,a)>-1!==c}):C.test(b)?r.filter(b,a,c):(b=r.filter(b,a),r.grep(a,function(a){return i.call(b,a)>-1!==c&&1===a.nodeType}))}r.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?r.find.matchesSelector(d,a)?[d]:[]:r.find.matches(a,r.grep(b,function(a){return 1===a.nodeType}))},r.fn.extend({find:function(a){var b,c,d=this.length,e=this;if("string"!=typeof a)return this.pushStack(r(a).filter(function(){for(b=0;b1?r.uniqueSort(c):c},filter:function(a){return this.pushStack(D(this,a||[],!1))},not:function(a){return this.pushStack(D(this,a||[],!0))},is:function(a){return!!D(this,"string"==typeof a&&A.test(a)?r(a):a||[],!1).length}});var E,F=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,G=r.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||E,"string"==typeof a){if(e="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:F.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof r?b[0]:b,r.merge(this,r.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),B.test(e[1])&&r.isPlainObject(b))for(e in b)r.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}return f=d.getElementById(e[2]),f&&(this[0]=f,this.length=1),this}return a.nodeType?(this[0]=a,this.length=1,this):r.isFunction(a)?void 0!==c.ready?c.ready(a):a(r):r.makeArray(a,this)};G.prototype=r.fn,E=r(d);var H=/^(?:parents|prev(?:Until|All))/,I={children:!0,contents:!0,next:!0,prev:!0};r.fn.extend({has:function(a){var b=r(a,this),c=b.length;return this.filter(function(){for(var a=0;a-1:1===c.nodeType&&r.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?r.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?i.call(r(a),this[0]):i.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(r.uniqueSort(r.merge(this.get(),r(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function J(a,b){while((a=a[b])&&1!==a.nodeType);return a}r.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return y(a,"parentNode")},parentsUntil:function(a,b,c){return y(a,"parentNode",c)},next:function(a){return J(a,"nextSibling")},prev:function(a){return J(a,"previousSibling")},nextAll:function(a){return y(a,"nextSibling")},prevAll:function(a){return y(a,"previousSibling")},nextUntil:function(a,b,c){return y(a,"nextSibling",c)},prevUntil:function(a,b,c){return y(a,"previousSibling",c)},siblings:function(a){return z((a.parentNode||{}).firstChild,a)},children:function(a){return z(a.firstChild)},contents:function(a){return a.contentDocument||r.merge([],a.childNodes)}},function(a,b){r.fn[a]=function(c,d){var e=r.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=r.filter(d,e)),this.length>1&&(I[a]||r.uniqueSort(e),H.test(a)&&e.reverse()),this.pushStack(e)}});var K=/[^\x20\t\r\n\f]+/g;function L(a){var b={};return r.each(a.match(K)||[],function(a,c){b[c]=!0}),b}r.Callbacks=function(a){a="string"==typeof a?L(a):r.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h-1)f.splice(c,1),c<=h&&h--}),this},has:function(a){return a?r.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=g=[],c||b||(f=c=""),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j};function M(a){return a}function N(a){throw a}function O(a,b,c){var d;try{a&&r.isFunction(d=a.promise)?d.call(a).done(b).fail(c):a&&r.isFunction(d=a.then)?d.call(a,b,c):b.call(void 0,a)}catch(a){c.call(void 0,a)}}r.extend({Deferred:function(b){var c=[["notify","progress",r.Callbacks("memory"),r.Callbacks("memory"),2],["resolve","done",r.Callbacks("once memory"),r.Callbacks("once memory"),0,"resolved"],["reject","fail",r.Callbacks("once memory"),r.Callbacks("once memory"),1,"rejected"]],d="pending",e={state:function(){return d},always:function(){return f.done(arguments).fail(arguments),this},"catch":function(a){return e.then(null,a)},pipe:function(){var a=arguments;return r.Deferred(function(b){r.each(c,function(c,d){var e=r.isFunction(a[d[4]])&&a[d[4]];f[d[1]](function(){var a=e&&e.apply(this,arguments);a&&r.isFunction(a.promise)?a.promise().progress(b.notify).done(b.resolve).fail(b.reject):b[d[0]+"With"](this,e?[a]:arguments)})}),a=null}).promise()},then:function(b,d,e){var f=0;function g(b,c,d,e){return function(){var h=this,i=arguments,j=function(){var a,j;if(!(b=f&&(d!==N&&(h=void 0,i=[a]),c.rejectWith(h,i))}};b?k():(r.Deferred.getStackHook&&(k.stackTrace=r.Deferred.getStackHook()),a.setTimeout(k))}}return r.Deferred(function(a){c[0][3].add(g(0,a,r.isFunction(e)?e:M,a.notifyWith)),c[1][3].add(g(0,a,r.isFunction(b)?b:M)),c[2][3].add(g(0,a,r.isFunction(d)?d:N))}).promise()},promise:function(a){return null!=a?r.extend(a,e):e}},f={};return r.each(c,function(a,b){var g=b[2],h=b[5];e[b[1]]=g.add,h&&g.add(function(){d=h},c[3-a][2].disable,c[0][2].lock),g.add(b[3].fire),f[b[0]]=function(){return f[b[0]+"With"](this===f?void 0:this,arguments),this},f[b[0]+"With"]=g.fireWith}),e.promise(f),b&&b.call(f,f),f},when:function(a){var b=arguments.length,c=b,d=Array(c),e=f.call(arguments),g=r.Deferred(),h=function(a){return function(c){d[a]=this,e[a]=arguments.length>1?f.call(arguments):c,--b||g.resolveWith(d,e)}};if(b<=1&&(O(a,g.done(h(c)).resolve,g.reject),"pending"===g.state()||r.isFunction(e[c]&&e[c].then)))return g.then();while(c--)O(e[c],h(c),g.reject);return g.promise()}});var P=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;r.Deferred.exceptionHook=function(b,c){a.console&&a.console.warn&&b&&P.test(b.name)&&a.console.warn("jQuery.Deferred exception: "+b.message,b.stack,c)},r.readyException=function(b){a.setTimeout(function(){throw b})};var Q=r.Deferred();r.fn.ready=function(a){return Q.then(a)["catch"](function(a){r.readyException(a)}),this},r.extend({isReady:!1,readyWait:1,holdReady:function(a){a?r.readyWait++:r.ready(!0)},ready:function(a){(a===!0?--r.readyWait:r.isReady)||(r.isReady=!0,a!==!0&&--r.readyWait>0||Q.resolveWith(d,[r]))}}),r.ready.then=Q.then;function R(){d.removeEventListener("DOMContentLoaded",R), +a.removeEventListener("load",R),r.ready()}"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll?a.setTimeout(r.ready):(d.addEventListener("DOMContentLoaded",R),a.addEventListener("load",R));var S=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===r.type(c)){e=!0;for(h in c)S(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,r.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(r(a),c)})),b))for(;h1,null,!0)},removeData:function(a){return this.each(function(){W.remove(this,a)})}}),r.extend({queue:function(a,b,c){var d;if(a)return b=(b||"fx")+"queue",d=V.get(a,b),c&&(!d||r.isArray(c)?d=V.access(a,b,r.makeArray(c)):d.push(c)),d||[]},dequeue:function(a,b){b=b||"fx";var c=r.queue(a,b),d=c.length,e=c.shift(),f=r._queueHooks(a,b),g=function(){r.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return V.get(a,c)||V.access(a,c,{empty:r.Callbacks("once memory").add(function(){V.remove(a,[b+"queue",c])})})}}),r.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length\x20\t\r\n\f]+)/i,ka=/^$|\/(?:java|ecma)script/i,la={option:[1,""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};la.optgroup=la.option,la.tbody=la.tfoot=la.colgroup=la.caption=la.thead,la.th=la.td;function ma(a,b){var c;return c="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):[],void 0===b||b&&r.nodeName(a,b)?r.merge([a],c):c}function na(a,b){for(var c=0,d=a.length;c-1)e&&e.push(f);else if(j=r.contains(f.ownerDocument,f),g=ma(l.appendChild(f),"script"),j&&na(g),c){k=0;while(f=g[k++])ka.test(f.type||"")&&c.push(f)}return l}!function(){var a=d.createDocumentFragment(),b=a.appendChild(d.createElement("div")),c=d.createElement("input");c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),b.appendChild(c),o.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="",o.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var qa=d.documentElement,ra=/^key/,sa=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,ta=/^([^.]*)(?:\.(.+)|)/;function ua(){return!0}function va(){return!1}function wa(){try{return d.activeElement}catch(a){}}function xa(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)xa(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=va;else if(!e)return a;return 1===f&&(g=e,e=function(a){return r().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=r.guid++)),a.each(function(){r.event.add(this,b,e,d,c)})}r.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=V.get(a);if(q){c.handler&&(f=c,c=f.handler,e=f.selector),e&&r.find.matchesSelector(qa,e),c.guid||(c.guid=r.guid++),(i=q.events)||(i=q.events={}),(g=q.handle)||(g=q.handle=function(b){return"undefined"!=typeof r&&r.event.triggered!==b.type?r.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(K)||[""],j=b.length;while(j--)h=ta.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n&&(l=r.event.special[n]||{},n=(e?l.delegateType:l.bindType)||n,l=r.event.special[n]||{},k=r.extend({type:n,origType:p,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&r.expr.match.needsContext.test(e),namespace:o.join(".")},f),(m=i[n])||(m=i[n]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,o,g)!==!1||a.addEventListener&&a.addEventListener(n,g)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),r.event.global[n]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=V.hasData(a)&&V.get(a);if(q&&(i=q.events)){b=(b||"").match(K)||[""],j=b.length;while(j--)if(h=ta.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n){l=r.event.special[n]||{},n=(d?l.delegateType:l.bindType)||n,m=i[n]||[],h=h[2]&&new RegExp("(^|\\.)"+o.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&p!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,o,q.handle)!==!1||r.removeEvent(a,n,q.handle),delete i[n])}else for(n in i)r.event.remove(a,n+b[j],c,d,!0);r.isEmptyObject(i)&&V.remove(a,"handle events")}},dispatch:function(a){var b=r.event.fix(a),c,d,e,f,g,h,i=new Array(arguments.length),j=(V.get(this,"events")||{})[b.type]||[],k=r.event.special[b.type]||{};for(i[0]=b,c=1;c=1))for(;j!==this;j=j.parentNode||this)if(1===j.nodeType&&("click"!==a.type||j.disabled!==!0)){for(f=[],g={},c=0;c-1:r.find(e,this,null,[j]).length),g[e]&&f.push(d);f.length&&h.push({elem:j,handlers:f})}return j=this,i\x20\t\r\n\f]*)[^>]*)\/>/gi,za=/\s*$/g;function Da(a,b){return r.nodeName(a,"table")&&r.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a:a}function Ea(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function Fa(a){var b=Ba.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Ga(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(V.hasData(a)&&(f=V.access(a),g=V.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;c1&&"string"==typeof q&&!o.checkClone&&Aa.test(q))return a.each(function(e){var f=a.eq(e);s&&(b[0]=q.call(this,e,f.html())),Ia(f,b,c,d)});if(m&&(e=pa(b,a[0].ownerDocument,!1,a,d),f=e.firstChild,1===e.childNodes.length&&(e=f),f||d)){for(h=r.map(ma(e,"script"),Ea),i=h.length;l")},clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=r.contains(a.ownerDocument,a);if(!(o.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||r.isXMLDoc(a)))for(g=ma(h),f=ma(a),d=0,e=f.length;d0&&na(g,!i&&ma(a,"script")),h},cleanData:function(a){for(var b,c,d,e=r.event.special,f=0;void 0!==(c=a[f]);f++)if(T(c)){if(b=c[V.expando]){if(b.events)for(d in b.events)e[d]?r.event.remove(c,d):r.removeEvent(c,d,b.handle);c[V.expando]=void 0}c[W.expando]&&(c[W.expando]=void 0)}}}),r.fn.extend({detach:function(a){return Ja(this,a,!0)},remove:function(a){return Ja(this,a)},text:function(a){return S(this,function(a){return void 0===a?r.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=a)})},null,a,arguments.length)},append:function(){return Ia(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Da(this,a);b.appendChild(a)}})},prepend:function(){return Ia(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Da(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return Ia(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return Ia(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(r.cleanData(ma(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null!=a&&a,b=null==b?a:b,this.map(function(){return r.clone(this,a,b)})},html:function(a){return S(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!za.test(a)&&!la[(ja.exec(a)||["",""])[1].toLowerCase()]){a=r.htmlPrefilter(a);try{for(;c1)}});function Ya(a,b,c,d,e){return new Ya.prototype.init(a,b,c,d,e)}r.Tween=Ya,Ya.prototype={constructor:Ya,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||r.easing._default,this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(r.cssNumber[c]?"":"px")},cur:function(){var a=Ya.propHooks[this.prop];return a&&a.get?a.get(this):Ya.propHooks._default.get(this)},run:function(a){var b,c=Ya.propHooks[this.prop];return this.options.duration?this.pos=b=r.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Ya.propHooks._default.set(this),this}},Ya.prototype.init.prototype=Ya.prototype,Ya.propHooks={_default:{get:function(a){var b;return 1!==a.elem.nodeType||null!=a.elem[a.prop]&&null==a.elem.style[a.prop]?a.elem[a.prop]:(b=r.css(a.elem,a.prop,""),b&&"auto"!==b?b:0)},set:function(a){r.fx.step[a.prop]?r.fx.step[a.prop](a):1!==a.elem.nodeType||null==a.elem.style[r.cssProps[a.prop]]&&!r.cssHooks[a.prop]?a.elem[a.prop]=a.now:r.style(a.elem,a.prop,a.now+a.unit)}}},Ya.propHooks.scrollTop=Ya.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},r.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2},_default:"swing"},r.fx=Ya.prototype.init,r.fx.step={};var Za,$a,_a=/^(?:toggle|show|hide)$/,ab=/queueHooks$/;function bb(){$a&&(a.requestAnimationFrame(bb),r.fx.tick())}function cb(){return a.setTimeout(function(){Za=void 0}),Za=r.now()}function db(a,b){var c,d=0,e={height:a};for(b=b?1:0;d<4;d+=2-b)c=ba[d],e["margin"+c]=e["padding"+c]=a;return b&&(e.opacity=e.width=a),e}function eb(a,b,c){for(var d,e=(hb.tweeners[b]||[]).concat(hb.tweeners["*"]),f=0,g=e.length;f1)},removeAttr:function(a){return this.each(function(){r.removeAttr(this,a)})}}),r.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return"undefined"==typeof a.getAttribute?r.prop(a,b,c):(1===f&&r.isXMLDoc(a)||(e=r.attrHooks[b.toLowerCase()]||(r.expr.match.bool.test(b)?ib:void 0)), +void 0!==c?null===c?void r.removeAttr(a,b):e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:(a.setAttribute(b,c+""),c):e&&"get"in e&&null!==(d=e.get(a,b))?d:(d=r.find.attr(a,b),null==d?void 0:d))},attrHooks:{type:{set:function(a,b){if(!o.radioValue&&"radio"===b&&r.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}},removeAttr:function(a,b){var c,d=0,e=b&&b.match(K);if(e&&1===a.nodeType)while(c=e[d++])a.removeAttribute(c)}}),ib={set:function(a,b,c){return b===!1?r.removeAttr(a,c):a.setAttribute(c,c),c}},r.each(r.expr.match.bool.source.match(/\w+/g),function(a,b){var c=jb[b]||r.find.attr;jb[b]=function(a,b,d){var e,f,g=b.toLowerCase();return d||(f=jb[g],jb[g]=e,e=null!=c(a,b,d)?g:null,jb[g]=f),e}});var kb=/^(?:input|select|textarea|button)$/i,lb=/^(?:a|area)$/i;r.fn.extend({prop:function(a,b){return S(this,r.prop,a,b,arguments.length>1)},removeProp:function(a){return this.each(function(){delete this[r.propFix[a]||a]})}}),r.extend({prop:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return 1===f&&r.isXMLDoc(a)||(b=r.propFix[b]||b,e=r.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=r.find.attr(a,"tabindex");return b?parseInt(b,10):kb.test(a.nodeName)||lb.test(a.nodeName)&&a.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),o.optSelected||(r.propHooks.selected={get:function(a){var b=a.parentNode;return b&&b.parentNode&&b.parentNode.selectedIndex,null},set:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}}),r.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){r.propFix[this.toLowerCase()]=this});function mb(a){var b=a.match(K)||[];return b.join(" ")}function nb(a){return a.getAttribute&&a.getAttribute("class")||""}r.fn.extend({addClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).addClass(a.call(this,b,nb(this)))});if("string"==typeof a&&a){b=a.match(K)||[];while(c=this[i++])if(e=nb(c),d=1===c.nodeType&&" "+mb(e)+" "){g=0;while(f=b[g++])d.indexOf(" "+f+" ")<0&&(d+=f+" ");h=mb(d),e!==h&&c.setAttribute("class",h)}}return this},removeClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).removeClass(a.call(this,b,nb(this)))});if(!arguments.length)return this.attr("class","");if("string"==typeof a&&a){b=a.match(K)||[];while(c=this[i++])if(e=nb(c),d=1===c.nodeType&&" "+mb(e)+" "){g=0;while(f=b[g++])while(d.indexOf(" "+f+" ")>-1)d=d.replace(" "+f+" "," ");h=mb(d),e!==h&&c.setAttribute("class",h)}}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):r.isFunction(a)?this.each(function(c){r(this).toggleClass(a.call(this,c,nb(this),b),b)}):this.each(function(){var b,d,e,f;if("string"===c){d=0,e=r(this),f=a.match(K)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else void 0!==a&&"boolean"!==c||(b=nb(this),b&&V.set(this,"__className__",b),this.setAttribute&&this.setAttribute("class",b||a===!1?"":V.get(this,"__className__")||""))})},hasClass:function(a){var b,c,d=0;b=" "+a+" ";while(c=this[d++])if(1===c.nodeType&&(" "+mb(nb(c))+" ").indexOf(b)>-1)return!0;return!1}});var ob=/\r/g;r.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=r.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,r(this).val()):a,null==e?e="":"number"==typeof e?e+="":r.isArray(e)&&(e=r.map(e,function(a){return null==a?"":a+""})),b=r.valHooks[this.type]||r.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=r.valHooks[e.type]||r.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(ob,""):null==c?"":c)}}}),r.extend({valHooks:{option:{get:function(a){var b=r.find.attr(a,"value");return null!=b?b:mb(r.text(a))}},select:{get:function(a){var b,c,d,e=a.options,f=a.selectedIndex,g="select-one"===a.type,h=g?null:[],i=g?f+1:e.length;for(d=f<0?i:g?f:0;d-1)&&(c=!0);return c||(a.selectedIndex=-1),f}}}}),r.each(["radio","checkbox"],function(){r.valHooks[this]={set:function(a,b){if(r.isArray(b))return a.checked=r.inArray(r(a).val(),b)>-1}},o.checkOn||(r.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var pb=/^(?:focusinfocus|focusoutblur)$/;r.extend(r.event,{trigger:function(b,c,e,f){var g,h,i,j,k,m,n,o=[e||d],p=l.call(b,"type")?b.type:b,q=l.call(b,"namespace")?b.namespace.split("."):[];if(h=i=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!pb.test(p+r.event.triggered)&&(p.indexOf(".")>-1&&(q=p.split("."),p=q.shift(),q.sort()),k=p.indexOf(":")<0&&"on"+p,b=b[r.expando]?b:new r.Event(p,"object"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=q.join("."),b.rnamespace=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:r.makeArray(c,[b]),n=r.event.special[p]||{},f||!n.trigger||n.trigger.apply(e,c)!==!1)){if(!f&&!n.noBubble&&!r.isWindow(e)){for(j=n.delegateType||p,pb.test(j+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),i=h;i===(e.ownerDocument||d)&&o.push(i.defaultView||i.parentWindow||a)}g=0;while((h=o[g++])&&!b.isPropagationStopped())b.type=g>1?j:n.bindType||p,m=(V.get(h,"events")||{})[b.type]&&V.get(h,"handle"),m&&m.apply(h,c),m=k&&h[k],m&&m.apply&&T(h)&&(b.result=m.apply(h,c),b.result===!1&&b.preventDefault());return b.type=p,f||b.isDefaultPrevented()||n._default&&n._default.apply(o.pop(),c)!==!1||!T(e)||k&&r.isFunction(e[p])&&!r.isWindow(e)&&(i=e[k],i&&(e[k]=null),r.event.triggered=p,e[p](),r.event.triggered=void 0,i&&(e[k]=i)),b.result}},simulate:function(a,b,c){var d=r.extend(new r.Event,c,{type:a,isSimulated:!0});r.event.trigger(d,null,b)}}),r.fn.extend({trigger:function(a,b){return this.each(function(){r.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];if(c)return r.event.trigger(a,b,c,!0)}}),r.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(a,b){r.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),r.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),o.focusin="onfocusin"in a,o.focusin||r.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){r.event.simulate(b,a.target,r.event.fix(a))};r.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=V.access(d,b);e||d.addEventListener(a,c,!0),V.access(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=V.access(d,b)-1;e?V.access(d,b,e):(d.removeEventListener(a,c,!0),V.remove(d,b))}}});var qb=a.location,rb=r.now(),sb=/\?/;r.parseXML=function(b){var c;if(!b||"string"!=typeof b)return null;try{c=(new a.DOMParser).parseFromString(b,"text/xml")}catch(d){c=void 0}return c&&!c.getElementsByTagName("parsererror").length||r.error("Invalid XML: "+b),c};var tb=/\[\]$/,ub=/\r?\n/g,vb=/^(?:submit|button|image|reset|file)$/i,wb=/^(?:input|select|textarea|keygen)/i;function xb(a,b,c,d){var e;if(r.isArray(b))r.each(b,function(b,e){c||tb.test(a)?d(a,e):xb(a+"["+("object"==typeof e&&null!=e?b:"")+"]",e,c,d)});else if(c||"object"!==r.type(b))d(a,b);else for(e in b)xb(a+"["+e+"]",b[e],c,d)}r.param=function(a,b){var c,d=[],e=function(a,b){var c=r.isFunction(b)?b():b;d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(null==c?"":c)};if(r.isArray(a)||a.jquery&&!r.isPlainObject(a))r.each(a,function(){e(this.name,this.value)});else for(c in a)xb(c,a[c],b,e);return d.join("&")},r.fn.extend({serialize:function(){return r.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=r.prop(this,"elements");return a?r.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!r(this).is(":disabled")&&wb.test(this.nodeName)&&!vb.test(a)&&(this.checked||!ia.test(a))}).map(function(a,b){var c=r(this).val();return null==c?null:r.isArray(c)?r.map(c,function(a){return{name:b.name,value:a.replace(ub,"\r\n")}}):{name:b.name,value:c.replace(ub,"\r\n")}}).get()}});var yb=/%20/g,zb=/#.*$/,Ab=/([?&])_=[^&]*/,Bb=/^(.*?):[ \t]*([^\r\n]*)$/gm,Cb=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Db=/^(?:GET|HEAD)$/,Eb=/^\/\//,Fb={},Gb={},Hb="*/".concat("*"),Ib=d.createElement("a");Ib.href=qb.href;function Jb(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(K)||[];if(r.isFunction(c))while(d=f[e++])"+"===d[0]?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Kb(a,b,c,d){var e={},f=a===Gb;function g(h){var i;return e[h]=!0,r.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Lb(a,b){var c,d,e=r.ajaxSettings.flatOptions||{};for(c in b)void 0!==b[c]&&((e[c]?a:d||(d={}))[c]=b[c]);return d&&r.extend(!0,a,d),a}function Mb(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===d&&(d=a.mimeType||b.getResponseHeader("Content-Type"));if(d)for(e in h)if(h[e]&&h[e].test(d)){i.unshift(e);break}if(i[0]in c)f=i[0];else{for(e in c){if(!i[0]||a.converters[e+" "+i[0]]){f=e;break}g||(g=e)}f=f||g}if(f)return f!==i[0]&&i.unshift(f),c[f]}function Nb(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}r.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:qb.href,type:"GET",isLocal:Cb.test(qb.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Hb,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":r.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Lb(Lb(a,r.ajaxSettings),b):Lb(r.ajaxSettings,a)},ajaxPrefilter:Jb(Fb),ajaxTransport:Jb(Gb),ajax:function(b,c){"object"==typeof b&&(c=b,b=void 0),c=c||{};var e,f,g,h,i,j,k,l,m,n,o=r.ajaxSetup({},c),p=o.context||o,q=o.context&&(p.nodeType||p.jquery)?r(p):r.event,s=r.Deferred(),t=r.Callbacks("once memory"),u=o.statusCode||{},v={},w={},x="canceled",y={readyState:0,getResponseHeader:function(a){var b;if(k){if(!h){h={};while(b=Bb.exec(g))h[b[1].toLowerCase()]=b[2]}b=h[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return k?g:null},setRequestHeader:function(a,b){return null==k&&(a=w[a.toLowerCase()]=w[a.toLowerCase()]||a,v[a]=b),this},overrideMimeType:function(a){return null==k&&(o.mimeType=a),this},statusCode:function(a){var b;if(a)if(k)y.always(a[y.status]);else for(b in a)u[b]=[u[b],a[b]];return this},abort:function(a){var b=a||x;return e&&e.abort(b),A(0,b),this}};if(s.promise(y),o.url=((b||o.url||qb.href)+"").replace(Eb,qb.protocol+"//"),o.type=c.method||c.type||o.method||o.type,o.dataTypes=(o.dataType||"*").toLowerCase().match(K)||[""],null==o.crossDomain){j=d.createElement("a");try{j.href=o.url,j.href=j.href,o.crossDomain=Ib.protocol+"//"+Ib.host!=j.protocol+"//"+j.host}catch(z){o.crossDomain=!0}}if(o.data&&o.processData&&"string"!=typeof o.data&&(o.data=r.param(o.data,o.traditional)),Kb(Fb,o,c,y),k)return y;l=r.event&&o.global,l&&0===r.active++&&r.event.trigger("ajaxStart"),o.type=o.type.toUpperCase(),o.hasContent=!Db.test(o.type),f=o.url.replace(zb,""),o.hasContent?o.data&&o.processData&&0===(o.contentType||"").indexOf("application/x-www-form-urlencoded")&&(o.data=o.data.replace(yb,"+")):(n=o.url.slice(f.length),o.data&&(f+=(sb.test(f)?"&":"?")+o.data,delete o.data),o.cache===!1&&(f=f.replace(Ab,"$1"),n=(sb.test(f)?"&":"?")+"_="+rb++ +n),o.url=f+n),o.ifModified&&(r.lastModified[f]&&y.setRequestHeader("If-Modified-Since",r.lastModified[f]),r.etag[f]&&y.setRequestHeader("If-None-Match",r.etag[f])),(o.data&&o.hasContent&&o.contentType!==!1||c.contentType)&&y.setRequestHeader("Content-Type",o.contentType),y.setRequestHeader("Accept",o.dataTypes[0]&&o.accepts[o.dataTypes[0]]?o.accepts[o.dataTypes[0]]+("*"!==o.dataTypes[0]?", "+Hb+"; q=0.01":""):o.accepts["*"]);for(m in o.headers)y.setRequestHeader(m,o.headers[m]);if(o.beforeSend&&(o.beforeSend.call(p,y,o)===!1||k))return y.abort();if(x="abort",t.add(o.complete),y.done(o.success),y.fail(o.error),e=Kb(Gb,o,c,y)){if(y.readyState=1,l&&q.trigger("ajaxSend",[y,o]),k)return y;o.async&&o.timeout>0&&(i=a.setTimeout(function(){y.abort("timeout")},o.timeout));try{k=!1,e.send(v,A)}catch(z){if(k)throw z;A(-1,z)}}else A(-1,"No Transport");function A(b,c,d,h){var j,m,n,v,w,x=c;k||(k=!0,i&&a.clearTimeout(i),e=void 0,g=h||"",y.readyState=b>0?4:0,j=b>=200&&b<300||304===b,d&&(v=Mb(o,y,d)),v=Nb(o,v,y,j),j?(o.ifModified&&(w=y.getResponseHeader("Last-Modified"),w&&(r.lastModified[f]=w),w=y.getResponseHeader("etag"),w&&(r.etag[f]=w)),204===b||"HEAD"===o.type?x="nocontent":304===b?x="notmodified":(x=v.state,m=v.data,n=v.error,j=!n)):(n=x,!b&&x||(x="error",b<0&&(b=0))),y.status=b,y.statusText=(c||x)+"",j?s.resolveWith(p,[m,x,y]):s.rejectWith(p,[y,x,n]),y.statusCode(u),u=void 0,l&&q.trigger(j?"ajaxSuccess":"ajaxError",[y,o,j?m:n]),t.fireWith(p,[y,x]),l&&(q.trigger("ajaxComplete",[y,o]),--r.active||r.event.trigger("ajaxStop")))}return y},getJSON:function(a,b,c){return r.get(a,b,c,"json")},getScript:function(a,b){return r.get(a,void 0,b,"script")}}),r.each(["get","post"],function(a,b){r[b]=function(a,c,d,e){return r.isFunction(c)&&(e=e||d,d=c,c=void 0),r.ajax(r.extend({url:a,type:b,dataType:e,data:c,success:d},r.isPlainObject(a)&&a))}}),r._evalUrl=function(a){return r.ajax({url:a,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,"throws":!0})},r.fn.extend({wrapAll:function(a){var b;return this[0]&&(r.isFunction(a)&&(a=a.call(this[0])),b=r(a,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstElementChild)a=a.firstElementChild;return a}).append(this)),this},wrapInner:function(a){return r.isFunction(a)?this.each(function(b){r(this).wrapInner(a.call(this,b))}):this.each(function(){var b=r(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=r.isFunction(a);return this.each(function(c){r(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(a){return this.parent(a).not("body").each(function(){r(this).replaceWith(this.childNodes)}),this}}),r.expr.pseudos.hidden=function(a){return!r.expr.pseudos.visible(a)},r.expr.pseudos.visible=function(a){return!!(a.offsetWidth||a.offsetHeight||a.getClientRects().length)},r.ajaxSettings.xhr=function(){try{return new a.XMLHttpRequest}catch(b){}};var Ob={0:200,1223:204},Pb=r.ajaxSettings.xhr();o.cors=!!Pb&&"withCredentials"in Pb,o.ajax=Pb=!!Pb,r.ajaxTransport(function(b){var c,d;if(o.cors||Pb&&!b.crossDomain)return{send:function(e,f){var g,h=b.xhr();if(h.open(b.type,b.url,b.async,b.username,b.password),b.xhrFields)for(g in b.xhrFields)h[g]=b.xhrFields[g];b.mimeType&&h.overrideMimeType&&h.overrideMimeType(b.mimeType),b.crossDomain||e["X-Requested-With"]||(e["X-Requested-With"]="XMLHttpRequest");for(g in e)h.setRequestHeader(g,e[g]);c=function(a){return function(){c&&(c=d=h.onload=h.onerror=h.onabort=h.onreadystatechange=null,"abort"===a?h.abort():"error"===a?"number"!=typeof h.status?f(0,"error"):f(h.status,h.statusText):f(Ob[h.status]||h.status,h.statusText,"text"!==(h.responseType||"text")||"string"!=typeof h.responseText?{binary:h.response}:{text:h.responseText},h.getAllResponseHeaders()))}},h.onload=c(),d=h.onerror=c("error"),void 0!==h.onabort?h.onabort=d:h.onreadystatechange=function(){4===h.readyState&&a.setTimeout(function(){c&&d()})},c=c("abort");try{h.send(b.hasContent&&b.data||null)}catch(i){if(c)throw i}},abort:function(){c&&c()}}}),r.ajaxPrefilter(function(a){a.crossDomain&&(a.contents.script=!1)}),r.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(a){return r.globalEval(a),a}}}),r.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET")}),r.ajaxTransport("script",function(a){if(a.crossDomain){var b,c;return{send:function(e,f){b=r(" + + diff --git a/mobile_app/web/manifest.json b/mobile_app/web/manifest.json new file mode 100644 index 00000000..8c5c7741 --- /dev/null +++ b/mobile_app/web/manifest.json @@ -0,0 +1,35 @@ +{ + "name": "mobile_app", + "short_name": "mobile_app", + "start_url": ".", + "display": "standalone", + "background_color": "#0175C2", + "theme_color": "#0175C2", + "description": "A new Flutter project.", + "orientation": "portrait-primary", + "prefer_related_applications": false, + "icons": [ + { + "src": "icons/Icon-192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "icons/Icon-512.png", + "sizes": "512x512", + "type": "image/png" + }, + { + "src": "icons/Icon-maskable-192.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "maskable" + }, + { + "src": "icons/Icon-maskable-512.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "maskable" + } + ] +} diff --git a/mobile_app/windows/.gitignore b/mobile_app/windows/.gitignore new file mode 100644 index 00000000..d492d0d9 --- /dev/null +++ b/mobile_app/windows/.gitignore @@ -0,0 +1,17 @@ +flutter/ephemeral/ + +# Visual Studio user-specific files. +*.suo +*.user +*.userosscache +*.sln.docstates + +# Visual Studio build-related files. +x64/ +x86/ + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ diff --git a/mobile_app/windows/CMakeLists.txt b/mobile_app/windows/CMakeLists.txt new file mode 100644 index 00000000..1d2cb74c --- /dev/null +++ b/mobile_app/windows/CMakeLists.txt @@ -0,0 +1,108 @@ +# Project-level configuration. +cmake_minimum_required(VERSION 3.14) +project(mobile_app LANGUAGES CXX) + +# The name of the executable created for the application. Change this to change +# the on-disk name of your application. +set(BINARY_NAME "mobile_app") + +# Explicitly opt in to modern CMake behaviors to avoid warnings with recent +# versions of CMake. +cmake_policy(VERSION 3.14...3.25) + +# Define build configuration option. +get_property(IS_MULTICONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) +if(IS_MULTICONFIG) + set(CMAKE_CONFIGURATION_TYPES "Debug;Profile;Release" + CACHE STRING "" FORCE) +else() + if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + set(CMAKE_BUILD_TYPE "Debug" CACHE + STRING "Flutter build mode" FORCE) + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS + "Debug" "Profile" "Release") + endif() +endif() +# Define settings for the Profile build mode. +set(CMAKE_EXE_LINKER_FLAGS_PROFILE "${CMAKE_EXE_LINKER_FLAGS_RELEASE}") +set(CMAKE_SHARED_LINKER_FLAGS_PROFILE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE}") +set(CMAKE_C_FLAGS_PROFILE "${CMAKE_C_FLAGS_RELEASE}") +set(CMAKE_CXX_FLAGS_PROFILE "${CMAKE_CXX_FLAGS_RELEASE}") + +# Use Unicode for all projects. +add_definitions(-DUNICODE -D_UNICODE) + +# Compilation settings that should be applied to most targets. +# +# Be cautious about adding new options here, as plugins use this function by +# default. In most cases, you should add new options to specific targets instead +# of modifying this function. +function(APPLY_STANDARD_SETTINGS TARGET) + target_compile_features(${TARGET} PUBLIC cxx_std_17) + target_compile_options(${TARGET} PRIVATE /W4 /WX /wd"4100") + target_compile_options(${TARGET} PRIVATE /EHsc) + target_compile_definitions(${TARGET} PRIVATE "_HAS_EXCEPTIONS=0") + target_compile_definitions(${TARGET} PRIVATE "$<$:_DEBUG>") +endfunction() + +# Flutter library and tool build rules. +set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") +add_subdirectory(${FLUTTER_MANAGED_DIR}) + +# Application build; see runner/CMakeLists.txt. +add_subdirectory("runner") + + +# Generated plugin build rules, which manage building the plugins and adding +# them to the application. +include(flutter/generated_plugins.cmake) + + +# === Installation === +# Support files are copied into place next to the executable, so that it can +# run in place. This is done instead of making a separate bundle (as on Linux) +# so that building and running from within Visual Studio will work. +set(BUILD_BUNDLE_DIR "$") +# Make the "install" step default, as it's required to run. +set(CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD 1) +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) +endif() + +set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") +set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}") + +install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" + COMPONENT Runtime) + +install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" + COMPONENT Runtime) + +install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) + +if(PLUGIN_BUNDLED_LIBRARIES) + install(FILES "${PLUGIN_BUNDLED_LIBRARIES}" + DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) +endif() + +# Copy the native assets provided by the build.dart from all packages. +set(NATIVE_ASSETS_DIR "${PROJECT_BUILD_DIR}native_assets/windows/") +install(DIRECTORY "${NATIVE_ASSETS_DIR}" + DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) + +# Fully re-copy the assets directory on each build to avoid having stale files +# from a previous install. +set(FLUTTER_ASSET_DIR_NAME "flutter_assets") +install(CODE " + file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") + " COMPONENT Runtime) +install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" + DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) + +# Install the AOT library on non-Debug builds only. +install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" + CONFIGURATIONS Profile;Release + COMPONENT Runtime) diff --git a/mobile_app/windows/flutter/CMakeLists.txt b/mobile_app/windows/flutter/CMakeLists.txt new file mode 100644 index 00000000..903f4899 --- /dev/null +++ b/mobile_app/windows/flutter/CMakeLists.txt @@ -0,0 +1,109 @@ +# This file controls Flutter-level build steps. It should not be edited. +cmake_minimum_required(VERSION 3.14) + +set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral") + +# Configuration provided via flutter tool. +include(${EPHEMERAL_DIR}/generated_config.cmake) + +# TODO: Move the rest of this into files in ephemeral. See +# https://github.com/flutter/flutter/issues/57146. +set(WRAPPER_ROOT "${EPHEMERAL_DIR}/cpp_client_wrapper") + +# Set fallback configurations for older versions of the flutter tool. +if (NOT DEFINED FLUTTER_TARGET_PLATFORM) + set(FLUTTER_TARGET_PLATFORM "windows-x64") +endif() + +# === Flutter Library === +set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/flutter_windows.dll") + +# Published to parent scope for install step. +set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) +set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) +set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) +set(AOT_LIBRARY "${PROJECT_DIR}/build/windows/app.so" PARENT_SCOPE) + +list(APPEND FLUTTER_LIBRARY_HEADERS + "flutter_export.h" + "flutter_windows.h" + "flutter_messenger.h" + "flutter_plugin_registrar.h" + "flutter_texture_registrar.h" +) +list(TRANSFORM FLUTTER_LIBRARY_HEADERS PREPEND "${EPHEMERAL_DIR}/") +add_library(flutter INTERFACE) +target_include_directories(flutter INTERFACE + "${EPHEMERAL_DIR}" +) +target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}.lib") +add_dependencies(flutter flutter_assemble) + +# === Wrapper === +list(APPEND CPP_WRAPPER_SOURCES_CORE + "core_implementations.cc" + "standard_codec.cc" +) +list(TRANSFORM CPP_WRAPPER_SOURCES_CORE PREPEND "${WRAPPER_ROOT}/") +list(APPEND CPP_WRAPPER_SOURCES_PLUGIN + "plugin_registrar.cc" +) +list(TRANSFORM CPP_WRAPPER_SOURCES_PLUGIN PREPEND "${WRAPPER_ROOT}/") +list(APPEND CPP_WRAPPER_SOURCES_APP + "flutter_engine.cc" + "flutter_view_controller.cc" +) +list(TRANSFORM CPP_WRAPPER_SOURCES_APP PREPEND "${WRAPPER_ROOT}/") + +# Wrapper sources needed for a plugin. +add_library(flutter_wrapper_plugin STATIC + ${CPP_WRAPPER_SOURCES_CORE} + ${CPP_WRAPPER_SOURCES_PLUGIN} +) +apply_standard_settings(flutter_wrapper_plugin) +set_target_properties(flutter_wrapper_plugin PROPERTIES + POSITION_INDEPENDENT_CODE ON) +set_target_properties(flutter_wrapper_plugin PROPERTIES + CXX_VISIBILITY_PRESET hidden) +target_link_libraries(flutter_wrapper_plugin PUBLIC flutter) +target_include_directories(flutter_wrapper_plugin PUBLIC + "${WRAPPER_ROOT}/include" +) +add_dependencies(flutter_wrapper_plugin flutter_assemble) + +# Wrapper sources needed for the runner. +add_library(flutter_wrapper_app STATIC + ${CPP_WRAPPER_SOURCES_CORE} + ${CPP_WRAPPER_SOURCES_APP} +) +apply_standard_settings(flutter_wrapper_app) +target_link_libraries(flutter_wrapper_app PUBLIC flutter) +target_include_directories(flutter_wrapper_app PUBLIC + "${WRAPPER_ROOT}/include" +) +add_dependencies(flutter_wrapper_app flutter_assemble) + +# === Flutter tool backend === +# _phony_ is a non-existent file to force this command to run every time, +# since currently there's no way to get a full input/output list from the +# flutter tool. +set(PHONY_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/_phony_") +set_source_files_properties("${PHONY_OUTPUT}" PROPERTIES SYMBOLIC TRUE) +add_custom_command( + OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} + ${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_PLUGIN} + ${CPP_WRAPPER_SOURCES_APP} + ${PHONY_OUTPUT} + COMMAND ${CMAKE_COMMAND} -E env + ${FLUTTER_TOOL_ENVIRONMENT} + "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.bat" + ${FLUTTER_TARGET_PLATFORM} $ + VERBATIM +) +add_custom_target(flutter_assemble DEPENDS + "${FLUTTER_LIBRARY}" + ${FLUTTER_LIBRARY_HEADERS} + ${CPP_WRAPPER_SOURCES_CORE} + ${CPP_WRAPPER_SOURCES_PLUGIN} + ${CPP_WRAPPER_SOURCES_APP} +) diff --git a/mobile_app/windows/flutter/generated_plugin_registrant.cc b/mobile_app/windows/flutter/generated_plugin_registrant.cc new file mode 100644 index 00000000..8b6d4680 --- /dev/null +++ b/mobile_app/windows/flutter/generated_plugin_registrant.cc @@ -0,0 +1,11 @@ +// +// Generated file. Do not edit. +// + +// clang-format off + +#include "generated_plugin_registrant.h" + + +void RegisterPlugins(flutter::PluginRegistry* registry) { +} diff --git a/mobile_app/windows/flutter/generated_plugin_registrant.h b/mobile_app/windows/flutter/generated_plugin_registrant.h new file mode 100644 index 00000000..dc139d85 --- /dev/null +++ b/mobile_app/windows/flutter/generated_plugin_registrant.h @@ -0,0 +1,15 @@ +// +// Generated file. Do not edit. +// + +// clang-format off + +#ifndef GENERATED_PLUGIN_REGISTRANT_ +#define GENERATED_PLUGIN_REGISTRANT_ + +#include + +// Registers Flutter plugins. +void RegisterPlugins(flutter::PluginRegistry* registry); + +#endif // GENERATED_PLUGIN_REGISTRANT_ diff --git a/mobile_app/windows/flutter/generated_plugins.cmake b/mobile_app/windows/flutter/generated_plugins.cmake new file mode 100644 index 00000000..b93c4c30 --- /dev/null +++ b/mobile_app/windows/flutter/generated_plugins.cmake @@ -0,0 +1,23 @@ +# +# Generated file, do not edit. +# + +list(APPEND FLUTTER_PLUGIN_LIST +) + +list(APPEND FLUTTER_FFI_PLUGIN_LIST +) + +set(PLUGIN_BUNDLED_LIBRARIES) + +foreach(plugin ${FLUTTER_PLUGIN_LIST}) + add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/windows plugins/${plugin}) + target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) + list(APPEND PLUGIN_BUNDLED_LIBRARIES $) + list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) +endforeach(plugin) + +foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) + add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/windows plugins/${ffi_plugin}) + list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) +endforeach(ffi_plugin) diff --git a/mobile_app/windows/runner/CMakeLists.txt b/mobile_app/windows/runner/CMakeLists.txt new file mode 100644 index 00000000..394917c0 --- /dev/null +++ b/mobile_app/windows/runner/CMakeLists.txt @@ -0,0 +1,40 @@ +cmake_minimum_required(VERSION 3.14) +project(runner LANGUAGES CXX) + +# Define the application target. To change its name, change BINARY_NAME in the +# top-level CMakeLists.txt, not the value here, or `flutter run` will no longer +# work. +# +# Any new source files that you add to the application should be added here. +add_executable(${BINARY_NAME} WIN32 + "flutter_window.cpp" + "main.cpp" + "utils.cpp" + "win32_window.cpp" + "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" + "Runner.rc" + "runner.exe.manifest" +) + +# Apply the standard set of build settings. This can be removed for applications +# that need different build settings. +apply_standard_settings(${BINARY_NAME}) + +# Add preprocessor definitions for the build version. +target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION=\"${FLUTTER_VERSION}\"") +target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MAJOR=${FLUTTER_VERSION_MAJOR}") +target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MINOR=${FLUTTER_VERSION_MINOR}") +target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_PATCH=${FLUTTER_VERSION_PATCH}") +target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_BUILD=${FLUTTER_VERSION_BUILD}") + +# Disable Windows macros that collide with C++ standard library functions. +target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX") + +# Add dependency libraries and include directories. Add any application-specific +# dependencies here. +target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app) +target_link_libraries(${BINARY_NAME} PRIVATE "dwmapi.lib") +target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}") + +# Run the Flutter tool portions of the build. This must not be removed. +add_dependencies(${BINARY_NAME} flutter_assemble) diff --git a/mobile_app/windows/runner/Runner.rc b/mobile_app/windows/runner/Runner.rc new file mode 100644 index 00000000..bee35184 --- /dev/null +++ b/mobile_app/windows/runner/Runner.rc @@ -0,0 +1,121 @@ +// Microsoft Visual C++ generated resource script. +// +#pragma code_page(65001) +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "winres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (United States) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""winres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_APP_ICON ICON "resources\\app_icon.ico" + + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +#if defined(FLUTTER_VERSION_MAJOR) && defined(FLUTTER_VERSION_MINOR) && defined(FLUTTER_VERSION_PATCH) && defined(FLUTTER_VERSION_BUILD) +#define VERSION_AS_NUMBER FLUTTER_VERSION_MAJOR,FLUTTER_VERSION_MINOR,FLUTTER_VERSION_PATCH,FLUTTER_VERSION_BUILD +#else +#define VERSION_AS_NUMBER 1,0,0,0 +#endif + +#if defined(FLUTTER_VERSION) +#define VERSION_AS_STRING FLUTTER_VERSION +#else +#define VERSION_AS_STRING "1.0.0" +#endif + +VS_VERSION_INFO VERSIONINFO + FILEVERSION VERSION_AS_NUMBER + PRODUCTVERSION VERSION_AS_NUMBER + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK +#ifdef _DEBUG + FILEFLAGS VS_FF_DEBUG +#else + FILEFLAGS 0x0L +#endif + FILEOS VOS__WINDOWS32 + FILETYPE VFT_APP + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904e4" + BEGIN + VALUE "CompanyName", "com.example" "\0" + VALUE "FileDescription", "mobile_app" "\0" + VALUE "FileVersion", VERSION_AS_STRING "\0" + VALUE "InternalName", "mobile_app" "\0" + VALUE "LegalCopyright", "Copyright (C) 2026 com.example. All rights reserved." "\0" + VALUE "OriginalFilename", "mobile_app.exe" "\0" + VALUE "ProductName", "mobile_app" "\0" + VALUE "ProductVersion", VERSION_AS_STRING "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1252 + END +END + +#endif // English (United States) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED diff --git a/mobile_app/windows/runner/flutter_window.cpp b/mobile_app/windows/runner/flutter_window.cpp new file mode 100644 index 00000000..955ee303 --- /dev/null +++ b/mobile_app/windows/runner/flutter_window.cpp @@ -0,0 +1,71 @@ +#include "flutter_window.h" + +#include + +#include "flutter/generated_plugin_registrant.h" + +FlutterWindow::FlutterWindow(const flutter::DartProject& project) + : project_(project) {} + +FlutterWindow::~FlutterWindow() {} + +bool FlutterWindow::OnCreate() { + if (!Win32Window::OnCreate()) { + return false; + } + + RECT frame = GetClientArea(); + + // The size here must match the window dimensions to avoid unnecessary surface + // creation / destruction in the startup path. + flutter_controller_ = std::make_unique( + frame.right - frame.left, frame.bottom - frame.top, project_); + // Ensure that basic setup of the controller was successful. + if (!flutter_controller_->engine() || !flutter_controller_->view()) { + return false; + } + RegisterPlugins(flutter_controller_->engine()); + SetChildContent(flutter_controller_->view()->GetNativeWindow()); + + flutter_controller_->engine()->SetNextFrameCallback([&]() { + this->Show(); + }); + + // Flutter can complete the first frame before the "show window" callback is + // registered. The following call ensures a frame is pending to ensure the + // window is shown. It is a no-op if the first frame hasn't completed yet. + flutter_controller_->ForceRedraw(); + + return true; +} + +void FlutterWindow::OnDestroy() { + if (flutter_controller_) { + flutter_controller_ = nullptr; + } + + Win32Window::OnDestroy(); +} + +LRESULT +FlutterWindow::MessageHandler(HWND hwnd, UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept { + // Give Flutter, including plugins, an opportunity to handle window messages. + if (flutter_controller_) { + std::optional result = + flutter_controller_->HandleTopLevelWindowProc(hwnd, message, wparam, + lparam); + if (result) { + return *result; + } + } + + switch (message) { + case WM_FONTCHANGE: + flutter_controller_->engine()->ReloadSystemFonts(); + break; + } + + return Win32Window::MessageHandler(hwnd, message, wparam, lparam); +} diff --git a/mobile_app/windows/runner/flutter_window.h b/mobile_app/windows/runner/flutter_window.h new file mode 100644 index 00000000..6da0652f --- /dev/null +++ b/mobile_app/windows/runner/flutter_window.h @@ -0,0 +1,33 @@ +#ifndef RUNNER_FLUTTER_WINDOW_H_ +#define RUNNER_FLUTTER_WINDOW_H_ + +#include +#include + +#include + +#include "win32_window.h" + +// A window that does nothing but host a Flutter view. +class FlutterWindow : public Win32Window { + public: + // Creates a new FlutterWindow hosting a Flutter view running |project|. + explicit FlutterWindow(const flutter::DartProject& project); + virtual ~FlutterWindow(); + + protected: + // Win32Window: + bool OnCreate() override; + void OnDestroy() override; + LRESULT MessageHandler(HWND window, UINT const message, WPARAM const wparam, + LPARAM const lparam) noexcept override; + + private: + // The project to run. + flutter::DartProject project_; + + // The Flutter instance hosted by this window. + std::unique_ptr flutter_controller_; +}; + +#endif // RUNNER_FLUTTER_WINDOW_H_ diff --git a/mobile_app/windows/runner/main.cpp b/mobile_app/windows/runner/main.cpp new file mode 100644 index 00000000..8397117b --- /dev/null +++ b/mobile_app/windows/runner/main.cpp @@ -0,0 +1,43 @@ +#include +#include +#include + +#include "flutter_window.h" +#include "utils.h" + +int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, + _In_ wchar_t *command_line, _In_ int show_command) { + // Attach to console when present (e.g., 'flutter run') or create a + // new console when running with a debugger. + if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) { + CreateAndAttachConsole(); + } + + // Initialize COM, so that it is available for use in the library and/or + // plugins. + ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); + + flutter::DartProject project(L"data"); + + std::vector command_line_arguments = + GetCommandLineArguments(); + + project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); + + FlutterWindow window(project); + Win32Window::Point origin(10, 10); + Win32Window::Size size(1280, 720); + if (!window.Create(L"mobile_app", origin, size)) { + return EXIT_FAILURE; + } + window.SetQuitOnClose(true); + + ::MSG msg; + while (::GetMessage(&msg, nullptr, 0, 0)) { + ::TranslateMessage(&msg); + ::DispatchMessage(&msg); + } + + ::CoUninitialize(); + return EXIT_SUCCESS; +} diff --git a/mobile_app/windows/runner/resource.h b/mobile_app/windows/runner/resource.h new file mode 100644 index 00000000..66a65d1e --- /dev/null +++ b/mobile_app/windows/runner/resource.h @@ -0,0 +1,16 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by Runner.rc +// +#define IDI_APP_ICON 101 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/mobile_app/windows/runner/resources/app_icon.ico b/mobile_app/windows/runner/resources/app_icon.ico new file mode 100644 index 00000000..c04e20ca Binary files /dev/null and b/mobile_app/windows/runner/resources/app_icon.ico differ diff --git a/mobile_app/windows/runner/runner.exe.manifest b/mobile_app/windows/runner/runner.exe.manifest new file mode 100644 index 00000000..153653e8 --- /dev/null +++ b/mobile_app/windows/runner/runner.exe.manifest @@ -0,0 +1,14 @@ + + + + + PerMonitorV2 + + + + + + + + + diff --git a/mobile_app/windows/runner/utils.cpp b/mobile_app/windows/runner/utils.cpp new file mode 100644 index 00000000..3a0b4651 --- /dev/null +++ b/mobile_app/windows/runner/utils.cpp @@ -0,0 +1,65 @@ +#include "utils.h" + +#include +#include +#include +#include + +#include + +void CreateAndAttachConsole() { + if (::AllocConsole()) { + FILE *unused; + if (freopen_s(&unused, "CONOUT$", "w", stdout)) { + _dup2(_fileno(stdout), 1); + } + if (freopen_s(&unused, "CONOUT$", "w", stderr)) { + _dup2(_fileno(stdout), 2); + } + std::ios::sync_with_stdio(); + FlutterDesktopResyncOutputStreams(); + } +} + +std::vector GetCommandLineArguments() { + // Convert the UTF-16 command line arguments to UTF-8 for the Engine to use. + int argc; + wchar_t** argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc); + if (argv == nullptr) { + return std::vector(); + } + + std::vector command_line_arguments; + + // Skip the first argument as it's the binary name. + for (int i = 1; i < argc; i++) { + command_line_arguments.push_back(Utf8FromUtf16(argv[i])); + } + + ::LocalFree(argv); + + return command_line_arguments; +} + +std::string Utf8FromUtf16(const wchar_t* utf16_string) { + if (utf16_string == nullptr) { + return std::string(); + } + unsigned int target_length = ::WideCharToMultiByte( + CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, + -1, nullptr, 0, nullptr, nullptr) + -1; // remove the trailing null character + int input_length = (int)wcslen(utf16_string); + std::string utf8_string; + if (target_length == 0 || target_length > utf8_string.max_size()) { + return utf8_string; + } + utf8_string.resize(target_length); + int converted_length = ::WideCharToMultiByte( + CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, + input_length, utf8_string.data(), target_length, nullptr, nullptr); + if (converted_length == 0) { + return std::string(); + } + return utf8_string; +} diff --git a/mobile_app/windows/runner/utils.h b/mobile_app/windows/runner/utils.h new file mode 100644 index 00000000..3879d547 --- /dev/null +++ b/mobile_app/windows/runner/utils.h @@ -0,0 +1,19 @@ +#ifndef RUNNER_UTILS_H_ +#define RUNNER_UTILS_H_ + +#include +#include + +// Creates a console for the process, and redirects stdout and stderr to +// it for both the runner and the Flutter library. +void CreateAndAttachConsole(); + +// Takes a null-terminated wchar_t* encoded in UTF-16 and returns a std::string +// encoded in UTF-8. Returns an empty std::string on failure. +std::string Utf8FromUtf16(const wchar_t* utf16_string); + +// Gets the command line arguments passed in as a std::vector, +// encoded in UTF-8. Returns an empty std::vector on failure. +std::vector GetCommandLineArguments(); + +#endif // RUNNER_UTILS_H_ diff --git a/mobile_app/windows/runner/win32_window.cpp b/mobile_app/windows/runner/win32_window.cpp new file mode 100644 index 00000000..60608d0f --- /dev/null +++ b/mobile_app/windows/runner/win32_window.cpp @@ -0,0 +1,288 @@ +#include "win32_window.h" + +#include +#include + +#include "resource.h" + +namespace { + +/// Window attribute that enables dark mode window decorations. +/// +/// Redefined in case the developer's machine has a Windows SDK older than +/// version 10.0.22000.0. +/// See: https://docs.microsoft.com/windows/win32/api/dwmapi/ne-dwmapi-dwmwindowattribute +#ifndef DWMWA_USE_IMMERSIVE_DARK_MODE +#define DWMWA_USE_IMMERSIVE_DARK_MODE 20 +#endif + +constexpr const wchar_t kWindowClassName[] = L"FLUTTER_RUNNER_WIN32_WINDOW"; + +/// Registry key for app theme preference. +/// +/// A value of 0 indicates apps should use dark mode. A non-zero or missing +/// value indicates apps should use light mode. +constexpr const wchar_t kGetPreferredBrightnessRegKey[] = + L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize"; +constexpr const wchar_t kGetPreferredBrightnessRegValue[] = L"AppsUseLightTheme"; + +// The number of Win32Window objects that currently exist. +static int g_active_window_count = 0; + +using EnableNonClientDpiScaling = BOOL __stdcall(HWND hwnd); + +// Scale helper to convert logical scaler values to physical using passed in +// scale factor +int Scale(int source, double scale_factor) { + return static_cast(source * scale_factor); +} + +// Dynamically loads the |EnableNonClientDpiScaling| from the User32 module. +// This API is only needed for PerMonitor V1 awareness mode. +void EnableFullDpiSupportIfAvailable(HWND hwnd) { + HMODULE user32_module = LoadLibraryA("User32.dll"); + if (!user32_module) { + return; + } + auto enable_non_client_dpi_scaling = + reinterpret_cast( + GetProcAddress(user32_module, "EnableNonClientDpiScaling")); + if (enable_non_client_dpi_scaling != nullptr) { + enable_non_client_dpi_scaling(hwnd); + } + FreeLibrary(user32_module); +} + +} // namespace + +// Manages the Win32Window's window class registration. +class WindowClassRegistrar { + public: + ~WindowClassRegistrar() = default; + + // Returns the singleton registrar instance. + static WindowClassRegistrar* GetInstance() { + if (!instance_) { + instance_ = new WindowClassRegistrar(); + } + return instance_; + } + + // Returns the name of the window class, registering the class if it hasn't + // previously been registered. + const wchar_t* GetWindowClass(); + + // Unregisters the window class. Should only be called if there are no + // instances of the window. + void UnregisterWindowClass(); + + private: + WindowClassRegistrar() = default; + + static WindowClassRegistrar* instance_; + + bool class_registered_ = false; +}; + +WindowClassRegistrar* WindowClassRegistrar::instance_ = nullptr; + +const wchar_t* WindowClassRegistrar::GetWindowClass() { + if (!class_registered_) { + WNDCLASS window_class{}; + window_class.hCursor = LoadCursor(nullptr, IDC_ARROW); + window_class.lpszClassName = kWindowClassName; + window_class.style = CS_HREDRAW | CS_VREDRAW; + window_class.cbClsExtra = 0; + window_class.cbWndExtra = 0; + window_class.hInstance = GetModuleHandle(nullptr); + window_class.hIcon = + LoadIcon(window_class.hInstance, MAKEINTRESOURCE(IDI_APP_ICON)); + window_class.hbrBackground = 0; + window_class.lpszMenuName = nullptr; + window_class.lpfnWndProc = Win32Window::WndProc; + RegisterClass(&window_class); + class_registered_ = true; + } + return kWindowClassName; +} + +void WindowClassRegistrar::UnregisterWindowClass() { + UnregisterClass(kWindowClassName, nullptr); + class_registered_ = false; +} + +Win32Window::Win32Window() { + ++g_active_window_count; +} + +Win32Window::~Win32Window() { + --g_active_window_count; + Destroy(); +} + +bool Win32Window::Create(const std::wstring& title, + const Point& origin, + const Size& size) { + Destroy(); + + const wchar_t* window_class = + WindowClassRegistrar::GetInstance()->GetWindowClass(); + + const POINT target_point = {static_cast(origin.x), + static_cast(origin.y)}; + HMONITOR monitor = MonitorFromPoint(target_point, MONITOR_DEFAULTTONEAREST); + UINT dpi = FlutterDesktopGetDpiForMonitor(monitor); + double scale_factor = dpi / 96.0; + + HWND window = CreateWindow( + window_class, title.c_str(), WS_OVERLAPPEDWINDOW, + Scale(origin.x, scale_factor), Scale(origin.y, scale_factor), + Scale(size.width, scale_factor), Scale(size.height, scale_factor), + nullptr, nullptr, GetModuleHandle(nullptr), this); + + if (!window) { + return false; + } + + UpdateTheme(window); + + return OnCreate(); +} + +bool Win32Window::Show() { + return ShowWindow(window_handle_, SW_SHOWNORMAL); +} + +// static +LRESULT CALLBACK Win32Window::WndProc(HWND const window, + UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept { + if (message == WM_NCCREATE) { + auto window_struct = reinterpret_cast(lparam); + SetWindowLongPtr(window, GWLP_USERDATA, + reinterpret_cast(window_struct->lpCreateParams)); + + auto that = static_cast(window_struct->lpCreateParams); + EnableFullDpiSupportIfAvailable(window); + that->window_handle_ = window; + } else if (Win32Window* that = GetThisFromHandle(window)) { + return that->MessageHandler(window, message, wparam, lparam); + } + + return DefWindowProc(window, message, wparam, lparam); +} + +LRESULT +Win32Window::MessageHandler(HWND hwnd, + UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept { + switch (message) { + case WM_DESTROY: + window_handle_ = nullptr; + Destroy(); + if (quit_on_close_) { + PostQuitMessage(0); + } + return 0; + + case WM_DPICHANGED: { + auto newRectSize = reinterpret_cast(lparam); + LONG newWidth = newRectSize->right - newRectSize->left; + LONG newHeight = newRectSize->bottom - newRectSize->top; + + SetWindowPos(hwnd, nullptr, newRectSize->left, newRectSize->top, newWidth, + newHeight, SWP_NOZORDER | SWP_NOACTIVATE); + + return 0; + } + case WM_SIZE: { + RECT rect = GetClientArea(); + if (child_content_ != nullptr) { + // Size and position the child window. + MoveWindow(child_content_, rect.left, rect.top, rect.right - rect.left, + rect.bottom - rect.top, TRUE); + } + return 0; + } + + case WM_ACTIVATE: + if (child_content_ != nullptr) { + SetFocus(child_content_); + } + return 0; + + case WM_DWMCOLORIZATIONCOLORCHANGED: + UpdateTheme(hwnd); + return 0; + } + + return DefWindowProc(window_handle_, message, wparam, lparam); +} + +void Win32Window::Destroy() { + OnDestroy(); + + if (window_handle_) { + DestroyWindow(window_handle_); + window_handle_ = nullptr; + } + if (g_active_window_count == 0) { + WindowClassRegistrar::GetInstance()->UnregisterWindowClass(); + } +} + +Win32Window* Win32Window::GetThisFromHandle(HWND const window) noexcept { + return reinterpret_cast( + GetWindowLongPtr(window, GWLP_USERDATA)); +} + +void Win32Window::SetChildContent(HWND content) { + child_content_ = content; + SetParent(content, window_handle_); + RECT frame = GetClientArea(); + + MoveWindow(content, frame.left, frame.top, frame.right - frame.left, + frame.bottom - frame.top, true); + + SetFocus(child_content_); +} + +RECT Win32Window::GetClientArea() { + RECT frame; + GetClientRect(window_handle_, &frame); + return frame; +} + +HWND Win32Window::GetHandle() { + return window_handle_; +} + +void Win32Window::SetQuitOnClose(bool quit_on_close) { + quit_on_close_ = quit_on_close; +} + +bool Win32Window::OnCreate() { + // No-op; provided for subclasses. + return true; +} + +void Win32Window::OnDestroy() { + // No-op; provided for subclasses. +} + +void Win32Window::UpdateTheme(HWND const window) { + DWORD light_mode; + DWORD light_mode_size = sizeof(light_mode); + LSTATUS result = RegGetValue(HKEY_CURRENT_USER, kGetPreferredBrightnessRegKey, + kGetPreferredBrightnessRegValue, + RRF_RT_REG_DWORD, nullptr, &light_mode, + &light_mode_size); + + if (result == ERROR_SUCCESS) { + BOOL enable_dark_mode = light_mode == 0; + DwmSetWindowAttribute(window, DWMWA_USE_IMMERSIVE_DARK_MODE, + &enable_dark_mode, sizeof(enable_dark_mode)); + } +} diff --git a/mobile_app/windows/runner/win32_window.h b/mobile_app/windows/runner/win32_window.h new file mode 100644 index 00000000..e901dde6 --- /dev/null +++ b/mobile_app/windows/runner/win32_window.h @@ -0,0 +1,102 @@ +#ifndef RUNNER_WIN32_WINDOW_H_ +#define RUNNER_WIN32_WINDOW_H_ + +#include + +#include +#include +#include + +// A class abstraction for a high DPI-aware Win32 Window. Intended to be +// inherited from by classes that wish to specialize with custom +// rendering and input handling +class Win32Window { + public: + struct Point { + unsigned int x; + unsigned int y; + Point(unsigned int x, unsigned int y) : x(x), y(y) {} + }; + + struct Size { + unsigned int width; + unsigned int height; + Size(unsigned int width, unsigned int height) + : width(width), height(height) {} + }; + + Win32Window(); + virtual ~Win32Window(); + + // Creates a win32 window with |title| that is positioned and sized using + // |origin| and |size|. New windows are created on the default monitor. Window + // sizes are specified to the OS in physical pixels, hence to ensure a + // consistent size this function will scale the inputted width and height as + // as appropriate for the default monitor. The window is invisible until + // |Show| is called. Returns true if the window was created successfully. + bool Create(const std::wstring& title, const Point& origin, const Size& size); + + // Show the current window. Returns true if the window was successfully shown. + bool Show(); + + // Release OS resources associated with window. + void Destroy(); + + // Inserts |content| into the window tree. + void SetChildContent(HWND content); + + // Returns the backing Window handle to enable clients to set icon and other + // window properties. Returns nullptr if the window has been destroyed. + HWND GetHandle(); + + // If true, closing this window will quit the application. + void SetQuitOnClose(bool quit_on_close); + + // Return a RECT representing the bounds of the current client area. + RECT GetClientArea(); + + protected: + // Processes and route salient window messages for mouse handling, + // size change and DPI. Delegates handling of these to member overloads that + // inheriting classes can handle. + virtual LRESULT MessageHandler(HWND window, + UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept; + + // Called when CreateAndShow is called, allowing subclass window-related + // setup. Subclasses should return false if setup fails. + virtual bool OnCreate(); + + // Called when Destroy is called. + virtual void OnDestroy(); + + private: + friend class WindowClassRegistrar; + + // OS callback called by message pump. Handles the WM_NCCREATE message which + // is passed when the non-client area is being created and enables automatic + // non-client DPI scaling so that the non-client area automatically + // responds to changes in DPI. All other messages are handled by + // MessageHandler. + static LRESULT CALLBACK WndProc(HWND const window, + UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept; + + // Retrieves a class instance pointer for |window| + static Win32Window* GetThisFromHandle(HWND const window) noexcept; + + // Update the window frame's theme to match the system theme. + static void UpdateTheme(HWND const window); + + bool quit_on_close_ = false; + + // window handle for top level window. + HWND window_handle_ = nullptr; + + // window handle for hosted content. + HWND child_content_ = nullptr; +}; + +#endif // RUNNER_WIN32_WINDOW_H_ diff --git a/package-lock.json b/package-lock.json index 53616e24..25a3c267 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1353,7 +1353,6 @@ "integrity": "sha512-zWW5KPngR/yvakJgGOmZ5vTBemDoSqF3AcV/LrO5u5wTWyEAVVh+IT39G4gtyAkh3CtTZs8aX/yRM82OfzHJRg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "undici-types": "~7.16.0" } @@ -1394,7 +1393,6 @@ "integrity": "sha512-gfajTHVCiwpxRj1qh0Sh/5bbGLG4F/ZH/V9xvFVoFddpITfMta9YGow0W6ZpTTORv2vdJuz9TnrNSmjKvpOf4g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@vitest/browser": "4.0.18", "@vitest/mocker": "4.0.18", @@ -1876,7 +1874,6 @@ "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", "license": "ISC", - "peer": true, "engines": { "node": ">=12" } @@ -2163,7 +2160,6 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -2475,7 +2471,6 @@ "integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "esbuild": "^0.27.0", "fdir": "^6.5.0", @@ -2551,7 +2546,6 @@ "integrity": "sha512-hOQuK7h0FGKgBAas7v0mSAsnvrIgAvWmRFjmzpJ7SwFHH3g1k2u37JtYwOwmEKhK6ZO3v9ggDBBm0La1LCK4uQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@vitest/expect": "4.0.18", "@vitest/mocker": "4.0.18", diff --git a/src/engine/bridge.ts b/src/engine/bridge.ts new file mode 100644 index 00000000..1fb98692 --- /dev/null +++ b/src/engine/bridge.ts @@ -0,0 +1,15 @@ +export interface MapControllerAPI { + rebuildMap: (seed: string) => void; + setWaterLevel: (level: number) => void; +} + +declare global { + interface Window { + MapController: MapControllerAPI; + } +} + +export function initBridge(api: MapControllerAPI) { + window.MapController = api; + console.log("MapController API initialized"); +} diff --git a/src/engine/control/Camera.ts b/src/engine/control/Camera.ts new file mode 100644 index 00000000..0e2cff24 --- /dev/null +++ b/src/engine/control/Camera.ts @@ -0,0 +1,114 @@ +export class Camera { + x: number = 0; // Center world X + y: number = 0; // Center world Y + zoom: number = 1; + + worldWidth: number; + worldHeight: number; + canvas: HTMLCanvasElement; + + constructor( + canvas: HTMLCanvasElement, + worldWidth: number, + worldHeight: number, + ) { + this.canvas = canvas; + this.worldWidth = worldWidth; + this.worldHeight = worldHeight; + this.x = worldWidth / 2; + this.y = worldHeight / 2; + + this.attachControls(); + } + + getMatrix(): Float32Array { + const aspect = this.canvas.width / this.canvas.height; + + // Determine view size in world units + // At zoom 1, width = worldWidth + const viewW = this.worldWidth / this.zoom; + const viewH = viewW / aspect; // Maintain square pixels + + // Scale to map viewW -> 2.0 (Clip space width) + const sx = 2.0 / viewW; + const sy = 2.0 / viewH; + + // Matrix 3x3 for 2D transform + // [ sx 0 0 ] + // [ 0 -sy 0 ] (Flip Y: World 0 is Top, Clip 0 is Center, Clip Y+ is Up) + // [ tx ty 1 ] + // + // tx = -center.x * sx + // ty = -center.y * -sy = center.y * sy + // Note: Clip space 0,0 is center. + // If x=center.x, result should be 0. + // x*sx + tx = cx*sx + (-cx*sx) = 0. Correct. + + return new Float32Array([ + sx, + 0, + 0, + 0, + -sy, + 0, + -this.x * sx, + this.y * sy, + 1, + ]); + } + + attachControls() { + let isDragging = false; + let lastX = 0; + let lastY = 0; + + this.canvas.addEventListener("mousedown", (e) => { + isDragging = true; + lastX = e.clientX; + lastY = e.clientY; + }); + + window.addEventListener("mouseup", () => { + isDragging = false; + }); + + this.canvas.addEventListener("mousemove", (e) => { + if (!isDragging) return; + const dx = e.clientX - lastX; + const dy = e.clientY - lastY; + lastX = e.clientX; + lastY = e.clientY; + + // Convert screen pixel delta to world delta + const viewW = this.worldWidth / this.zoom; + const pxScale = viewW / this.canvas.width; + + this.x -= dx * pxScale; + this.y -= dy * pxScale; + }); + + this.canvas.addEventListener( + "wheel", + (e) => { + e.preventDefault(); + const scaleFactor = 1.1; + const amount = e.deltaY < 0 ? scaleFactor : 1 / scaleFactor; + + // Apply Zoom + const newZoom = Math.max(0.1, Math.min(this.zoom * amount, 100)); + + // Adjust center so that the world point under mouse stays stationary + // newCenter = mouseWorld - (mouseWorld - oldCenter) * (oldScale / newScale) ? + // Easier: + // Mouse World Pos = this.x + worldDx + // After zoom, we want Mouse World Pos to map to same Screen Pos + + // Let's just do simple center zoom for now to avoid jumpiness bugs in first pass + this.zoom = newZoom; + }, + { passive: false }, + ); + + // Basic Touch support (Pinch) - TODO + } +} diff --git a/src/engine/data/Quadtree.ts b/src/engine/data/Quadtree.ts new file mode 100644 index 00000000..12dd304d --- /dev/null +++ b/src/engine/data/Quadtree.ts @@ -0,0 +1,104 @@ +export interface QuadNode { + x: number; + y: number; + size: number; +} + +export class Quadtree { + nodes: QuadNode[] = []; + data: Uint8ClampedArray; + width: number; + height: number; + threshold: number; + + constructor( + data: Uint8ClampedArray, + width: number, + height: number, + threshold: number = 20, + ) { + this.data = data; + this.width = width; + this.height = height; + this.threshold = threshold; + } + + build() { + this.nodes = []; + // Assuming square, POT for now + this.split(0, 0, this.width); + return this.nodes; + } + + // Returns nodes that intersect with the given AABB + queryRange( + minX: number, + minY: number, + maxX: number, + maxY: number, + ): QuadNode[] { + // Naive filter for now. A real quadtree would traverse the tree. + // Since I'm storing a flat list, I iterate. + // Optimization: The 'nodes' array could be structured as a tree object, but flat list is good for GPU. + // For 10k-50k nodes, simple filter is fast enough (1-2ms). + const result: QuadNode[] = []; + for (let i = 0; i < this.nodes.length; i++) { + const n = this.nodes[i]; + if ( + n.x < maxX && + n.x + n.size > minX && + n.y < maxY && + n.y + n.size > minY + ) { + result.push(n); + } + } + return result; + } + + private split(x: number, y: number, size: number) { + // Prevent infinite recursion or sub-pixel nodes + if (size <= 1) { + this.nodes.push({ x, y, size }); + return; + } + + if (this.shouldSplit(x, y, size)) { + const half = size / 2; + this.split(x, y, half); + this.split(x + half, y, half); + this.split(x, y + half, half); + this.split(x + half, y + half, half); + } else { + this.nodes.push({ x, y, size }); + } + } + + private shouldSplit(x: number, y: number, size: number): boolean { + // Check bounds + if (x >= this.width || y >= this.height) return false; + + let min = 255; + let max = 0; + + // Optimization: Check stride based on size to avoid reading every pixel in large blocks + const stride = Math.max(1, Math.floor(size / 8)); + + for (let py = y; py < y + size; py += stride) { + if (py >= this.height) break; + for (let px = x; px < x + size; px += stride) { + if (px >= this.width) break; + + const i = (py * this.width + px) * 4; + const val = this.data[i]; // Red channel (height) + + if (val < min) min = val; + if (val > max) max = val; + + if (max - min > this.threshold) return true; + } + } + + return false; + } +} diff --git a/src/engine/engine.html b/src/engine/engine.html new file mode 100644 index 00000000..f392d6c4 --- /dev/null +++ b/src/engine/engine.html @@ -0,0 +1,16 @@ + + + + + + Fantasy Map Engine (WebGL) + + + + + + + diff --git a/src/engine/main.ts b/src/engine/main.ts new file mode 100644 index 00000000..b11f366e --- /dev/null +++ b/src/engine/main.ts @@ -0,0 +1,131 @@ +import { initBridge } from "./bridge"; +import { Camera } from "./control/Camera"; +import { Quadtree } from "./data/Quadtree"; +import { Renderer } from "./render/Renderer"; +import type { WorkerCompleteMessage, WorkerInitMessage } from "./types"; +import Worker from "./worker/generation.worker?worker"; // Vite worker import syntax + +console.log("Fantasy Map Engine Initialized"); + +const CONFIG = { + width: 1024, + height: 1024, +}; + +// Main Entry Point +export class Engine { + canvas: HTMLCanvasElement; + worker: Worker; + sharedBuffer: SharedArrayBuffer; + dataView: Uint8ClampedArray; + renderer: Renderer; + quadtree: Quadtree | null = null; + camera: Camera; + isRendering: boolean = false; + frameCount: number = 0; + + constructor() { + this.canvas = document.getElementById("mapCanvas") as HTMLCanvasElement; + + // Initialize Renderer + this.renderer = new Renderer(this.canvas); + + // Initialize Camera + this.camera = new Camera(this.canvas, CONFIG.width, CONFIG.height); + + this.resize(); + window.addEventListener("resize", () => this.resize()); + + // Initialize Shared Memory + // 4 bytes per pixel (R, G, B, A) + const bufferSize = CONFIG.width * CONFIG.height * 4; + try { + this.sharedBuffer = new SharedArrayBuffer(bufferSize); + console.log("SharedArrayBuffer created."); + } catch (e) { + console.warn( + "SharedArrayBuffer not supported. Engine requires COOP/COEP headers.", + ); + throw e; + } + + this.dataView = new Uint8ClampedArray(this.sharedBuffer); + + // Initialize Worker + this.worker = new Worker(); + this.worker.onmessage = this.handleWorkerMessage.bind(this); + + // Initialize Bridge + initBridge({ + rebuildMap: (seed) => this.startGeneration(seed), + setWaterLevel: (level) => { + // TODO: Wire up to renderer uniform + console.log("Water level set to:", level); + }, + }); + + // Start Generation + this.startGeneration("default-seed"); + } + + resize() { + if (this.canvas) { + this.canvas.width = window.innerWidth; + this.canvas.height = window.innerHeight; + this.renderer.gl.viewport(0, 0, this.canvas.width, this.canvas.height); + } + } + + startGeneration(seed: string) { + console.log("Starting generation..."); + const msg: WorkerInitMessage = { + type: "init", + buffer: this.sharedBuffer, + width: CONFIG.width, + height: CONFIG.height, + seed: seed, + }; + this.worker.postMessage(msg); + } + + handleWorkerMessage(e: MessageEvent) { + if (e.data.type === "complete") { + console.log("Generation complete!"); + + // 1. Upload Texture + this.renderer.updateTexture(this.dataView, CONFIG.width, CONFIG.height); + + // 2. Build Quadtree + console.time("Build Quadtree"); + this.quadtree = new Quadtree(this.dataView, CONFIG.width, CONFIG.height); + const nodes = this.quadtree.build(); + console.timeEnd("Build Quadtree"); + console.log(`Quadtree generated ${nodes.length} nodes`); + + // 3. Update Instances + const instanceData = new Float32Array(nodes.length * 3); + for (let i = 0; i < nodes.length; i++) { + instanceData[i * 3 + 0] = nodes[i].x; + instanceData[i * 3 + 1] = nodes[i].y; + instanceData[i * 3 + 2] = nodes[i].size; + } + this.renderer.updateInstances(instanceData, nodes.length); + + // 4. Start Render Loop + if (!this.isRendering) { + this.isRendering = true; + this.loop(); + } + } + } + + loop() { + this.frameCount++; + + const matrix = this.camera.getMatrix(); + this.renderer.render(matrix); + requestAnimationFrame(() => this.loop()); + } +} + +new Engine(); diff --git a/src/engine/render/Renderer.ts b/src/engine/render/Renderer.ts new file mode 100644 index 00000000..bc7909a2 --- /dev/null +++ b/src/engine/render/Renderer.ts @@ -0,0 +1,240 @@ +export class Renderer { + canvas: HTMLCanvasElement; + gl: WebGL2RenderingContext; + program: WebGLProgram | null = null; + + // Buffers + quadBuffer: WebGLBuffer | null = null; + instanceBuffer: WebGLBuffer | null = null; + + // Texture + dataTexture: WebGLTexture | null = null; + + // Locations + locations: { + a_position: number; + a_instanceInfo: number; // x, y, size + u_viewMatrix: WebGLUniformLocation | null; + u_gridSize: WebGLUniformLocation | null; + u_dataTexture: WebGLUniformLocation | null; + }; + + instanceCount: number = 0; + + constructor(canvas: HTMLCanvasElement) { + this.canvas = canvas; + const gl = canvas.getContext("webgl2", { preserveDrawingBuffer: true }); + if (!gl) throw new Error("WebGL2 not supported"); + this.gl = gl; + + this.initShaders(); + this.initBuffers(); + this.initTexture(); + + // Default locations object (will be populated in initShaders) + this.locations = { + a_position: 0, + a_instanceInfo: 1, + u_viewMatrix: null, + u_gridSize: null, + u_dataTexture: null, + }; + + this.gl.enable(this.gl.BLEND); + this.gl.blendFunc(this.gl.SRC_ALPHA, this.gl.ONE_MINUS_SRC_ALPHA); + } + + private initShaders() { + const gl = this.gl; + + const vsSource = `#version 300 es + layout(location=0) in vec2 a_position; // 0..1 quad + layout(location=1) in vec3 a_instanceInfo; // x, y, size + + uniform mat3 u_viewMatrix; + uniform vec2 u_gridSize; + + out vec2 v_uv; + out float v_height; + + void main() { + // Calculate world position of this pixel in the quad + float size = a_instanceInfo.z; + vec2 worldPos = a_instanceInfo.xy + a_position * size; + + vec2 viewPos = (u_viewMatrix * vec3(worldPos, 1.0)).xy; + + gl_Position = vec4(viewPos, 0.0, 1.0); + + // UV for texture lookup (normalized 0..1 relative to whole grid) + v_uv = worldPos / u_gridSize; + }`; + + const fsSource = `#version 300 es + precision highp float; + + uniform sampler2D u_dataTexture; + + in vec2 v_uv; + + out vec4 outColor; + + void main() { + vec4 data = texture(u_dataTexture, v_uv); + float height = data.r; + float moisture = data.g; + + vec3 color; + + if (height < 0.2) { + color = vec3(0.0, 0.2, 0.6); // Deep Ocean + } else if (height < 0.25) { + color = vec3(0.0, 0.4, 0.8); // Shallow Water + } else if (height < 0.28) { + color = vec3(0.9, 0.8, 0.6); // Beach + } else if (height < 0.6) { + // Land gradient based on moisture + color = mix(vec3(0.8, 0.7, 0.4), vec3(0.1, 0.6, 0.1), moisture); + } else if (height < 0.8) { + color = vec3(0.4, 0.4, 0.4); // Rock + } else { + color = vec3(1.0, 1.0, 1.0); // Snow + } + + // Debug: Use direct height if texture fetch is working + // color = vec3(height, height, height); + + outColor = vec4(color, 1.0); + }`; + + const vertexShader = this.createShader(gl.VERTEX_SHADER, vsSource); + const fragmentShader = this.createShader(gl.FRAGMENT_SHADER, fsSource); + + this.program = gl.createProgram()!; + gl.attachShader(this.program, vertexShader); + gl.attachShader(this.program, fragmentShader); + gl.linkProgram(this.program); + + if (!gl.getProgramParameter(this.program, gl.LINK_STATUS)) { + throw new Error( + `Shader program link error: ${gl.getProgramInfoLog(this.program)}`, + ); + } + + // Cache locations + this.locations = { + a_position: 0, // Explicitly set in layout + a_instanceInfo: 1, + u_viewMatrix: gl.getUniformLocation(this.program, "u_viewMatrix"), + u_gridSize: gl.getUniformLocation(this.program, "u_gridSize"), + u_dataTexture: gl.getUniformLocation(this.program, "u_dataTexture"), + }; + } + + private createShader(type: number, source: string): WebGLShader { + const shader = this.gl.createShader(type)!; + this.gl.shaderSource(shader, source); + this.gl.compileShader(shader); + if (!this.gl.getShaderParameter(shader, this.gl.COMPILE_STATUS)) { + const info = this.gl.getShaderInfoLog(shader); + this.gl.deleteShader(shader); + throw new Error(`Shader compile error: ${info}`); + } + return shader; + } + + private initBuffers() { + const gl = this.gl; + + // Quad Geometry (0,0 to 1,1) + const quadVerts = new Float32Array([0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1]); + + this.quadBuffer = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, this.quadBuffer); + gl.bufferData(gl.ARRAY_BUFFER, quadVerts, gl.STATIC_DRAW); + + // Instance Buffer (Dynamic) + this.instanceBuffer = gl.createBuffer(); + // Initial size reserved for ~100k instances (3 floats per instance = 1.2MB) + gl.bindBuffer(gl.ARRAY_BUFFER, this.instanceBuffer); + // Using DYNAMIC_DRAW for frequent updates + gl.bufferData(gl.ARRAY_BUFFER, 100000 * 3 * 4, gl.DYNAMIC_DRAW); + } + + private initTexture() { + const gl = this.gl; + this.dataTexture = gl.createTexture(); + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, this.dataTexture); + + // Initial parameters + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + } + + updateTexture(data: Uint8ClampedArray, width: number, height: number) { + const gl = this.gl; + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, this.dataTexture); + gl.texImage2D( + gl.TEXTURE_2D, + 0, + gl.RGBA, + width, + height, + 0, + gl.RGBA, + gl.UNSIGNED_BYTE, + data, + ); + + gl.useProgram(this.program); + gl.uniform1i(this.locations.u_dataTexture, 0); // Explicitly set sampler to texture unit 0 + gl.uniform2f(this.locations.u_gridSize, width, height); + } + + updateInstances(instances: Float32Array, count: number) { + const gl = this.gl; + gl.bindBuffer(gl.ARRAY_BUFFER, this.instanceBuffer); + + // Reallocate buffer every time to avoid sync issues or subdata offset issues + gl.bufferData(gl.ARRAY_BUFFER, instances, gl.DYNAMIC_DRAW); + this.instanceCount = count; + } + + render(viewMatrix: Float32Array) { + const gl = this.gl; + gl.clear(gl.COLOR_BUFFER_BIT); // Clear buffer + + gl.useProgram(this.program); + + // Bind Uniforms + gl.uniformMatrix3fv(this.locations.u_viewMatrix, false, viewMatrix); + + // Bind Geometry + gl.bindBuffer(gl.ARRAY_BUFFER, this.quadBuffer); + gl.enableVertexAttribArray(this.locations.a_position); + gl.vertexAttribPointer(this.locations.a_position, 2, gl.FLOAT, false, 0, 0); + gl.vertexAttribDivisor(this.locations.a_position, 0); // Ensure 0 + + // Bind Instances + gl.bindBuffer(gl.ARRAY_BUFFER, this.instanceBuffer); + gl.enableVertexAttribArray(this.locations.a_instanceInfo); + gl.vertexAttribPointer( + this.locations.a_instanceInfo, + 3, + gl.FLOAT, + false, + 0, + 0, + ); + gl.vertexAttribDivisor(this.locations.a_instanceInfo, 1); // 1 per instance + + gl.drawArraysInstanced(gl.TRIANGLES, 0, 6, this.instanceCount); + + // Cleanup divisor + gl.vertexAttribDivisor(this.locations.a_instanceInfo, 0); + } +} diff --git a/src/engine/types.ts b/src/engine/types.ts new file mode 100644 index 00000000..a9fcba27 --- /dev/null +++ b/src/engine/types.ts @@ -0,0 +1,13 @@ +export interface WorkerInitMessage { + type: "init"; + buffer: SharedArrayBuffer; + width: number; + height: number; + seed: string; +} + +export interface WorkerCompleteMessage { + type: "complete"; +} + +export type WorkerMessage = WorkerInitMessage | WorkerCompleteMessage; diff --git a/src/engine/worker/generation.worker.ts b/src/engine/worker/generation.worker.ts new file mode 100644 index 00000000..337ddc7b --- /dev/null +++ b/src/engine/worker/generation.worker.ts @@ -0,0 +1,96 @@ +import Alea from "alea"; +import type { WorkerInitMessage } from "../types"; + +// Simple interpolated noise +class Noise { + private prng: any; + private map: Float32Array; + private size: number; + + constructor(seed: string, size: number = 256) { + this.prng = Alea(seed); + this.size = size; + this.map = new Float32Array(size * size); + for (let i = 0; i < this.map.length; i++) { + this.map[i] = this.prng(); + } + } + + get(x: number, y: number): number { + // Wrap coordinates + const X = Math.floor(x) & (this.size - 1); + const Y = Math.floor(y) & (this.size - 1); + + // Relative x, y in the cell + const rx = x - Math.floor(x); + const ry = y - Math.floor(y); + + // Smoothstep + const sx = rx * rx * (3 - 2 * rx); + const sy = ry * ry * (3 - 2 * ry); + + // Neighbors + const n00 = this.map[X + Y * this.size]; + const n10 = this.map[((X + 1) & (this.size - 1)) + Y * this.size]; + const n01 = this.map[X + ((Y + 1) & (this.size - 1)) * this.size]; + const n11 = + this.map[ + ((X + 1) & (this.size - 1)) + ((Y + 1) & (this.size - 1)) * this.size + ]; + + // Interpolate + const lx0 = n00 + sx * (n10 - n00); + const lx1 = n01 + sx * (n11 - n01); + + return lx0 + sy * (lx1 - lx0); + } + + // Fractal Brownian Motion + fbm(x: number, y: number, octaves: number): number { + let val = 0; + let amp = 0.5; + let freq = 1; + let max = 0; + + for (let i = 0; i < octaves; i++) { + val += this.get(x * freq, y * freq) * amp; + max += amp; + amp *= 0.5; + freq *= 2; + } + return val / max; // Normalize + } +} + +self.onmessage = (e: MessageEvent) => { + const { type } = e.data; + if (type === "init") { + const { buffer, width, height, seed } = e.data; + const view = new Uint8ClampedArray(buffer); // RGBA format + const noise = new Noise(seed); + + console.log(`Worker: Generating ${width}x${height} map with seed ${seed}`); + + // Simple generation loop + // TODO: Optimize this or chunk it if it blocks too long, but in a worker it's fine. + for (let y = 0; y < height; y++) { + for (let x = 0; x < width; x++) { + const i = (y * width + x) * 4; + + // Scale coordinates for noise + const nx = (x / width) * 4; // 4 periods across the map + const ny = (y / height) * 4; + + const h = noise.fbm(nx, ny, 6); // Height (Red) + const m = noise.fbm(nx + 17.1, ny + 31.4, 6); // Moisture (Green) - random offset + + view[i] = Math.floor(h * 255); // R: Height + view[i + 1] = Math.floor(m * 255); // G: Moisture + view[i + 2] = 0; // B: Biome ID (placeholder) + view[i + 3] = 255; // A: Alpha + } + } + + self.postMessage({ type: "complete" }); + } +}; diff --git a/vite.config.ts b/vite.config.ts index 671e6ff5..d0247c47 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,9 +1,21 @@ export default { root: './src', - base: process.env.NETLIFY ? '/' : '/Fantasy-Map-Generator/', + base: './', build: { outDir: '../dist', - assetsDir: './', + assetsDir: 'assets', // Cleaner + rollupOptions: { + input: { + main: './src/index.html', + engine: './src/engine/engine.html', + }, + }, }, publicDir: '../public', -} \ No newline at end of file + server: { + headers: { + 'Cross-Origin-Opener-Policy': 'same-origin', + 'Cross-Origin-Embedder-Policy': 'require-corp', + }, + }, +} diff --git a/vite.log b/vite.log new file mode 100644 index 00000000..5799e150 --- /dev/null +++ b/vite.log @@ -0,0 +1,42 @@ + +> fantasy-map-generator@1.110.0 dev +> vite + + + VITE v7.3.1 ready in 450 ms + + ➜ Local: http://localhost:5173/Fantasy-Map-Generator/ + ➜ Network: use --host to expose +2:38:15 AM [vite] (client) page reload engine/main.ts +2:38:15 AM [vite] (client) page reload engine/main.ts +2:39:59 AM [vite] (client) page reload engine/render/Renderer.ts +2:40:29 AM [vite] (client) page reload engine/render/Renderer.ts +2:41:26 AM [vite] (client) page reload engine/render/Renderer.ts +2:42:14 AM [vite] (client) page reload engine/render/Renderer.ts +2:42:20 AM [vite] (client) page reload engine/render/Renderer.ts +2:42:57 AM [vite] (client) page reload engine/render/Renderer.ts +2:43:43 AM [vite] (client) page reload engine/render/Renderer.ts +2:44:03 AM [vite] (client) page reload engine/render/Renderer.ts +2:44:59 AM [vite] (client) page reload engine/render/Renderer.ts +2:45:06 AM [vite] (client) page reload engine/main.ts +2:45:43 AM [vite] (client) page reload engine/render/Renderer.ts +2:45:48 AM [vite] (client) page reload engine/render/Renderer.ts +2:47:15 AM [vite] (client) page reload engine/render/Renderer.ts +2:47:57 AM [vite] (client) page reload engine/main.ts +2:48:50 AM [vite] (client) page reload engine/render/Renderer.ts +3:08:38 AM [vite] (client) page reload engine/bridge.ts +3:08:38 AM [vite] (client) page reload engine/data/Quadtree.ts +3:08:38 AM [vite] (client) page reload engine/control/Camera.ts +3:08:38 AM [vite] (client) page reload engine/main.ts +3:08:38 AM [vite] (client) page reload engine/worker/generation.worker.ts +3:08:38 AM [vite] (client) page reload engine/render/Renderer.ts +3:09:35 AM [vite] (client) page reload engine/control/Camera.ts +3:09:55 AM [vite] (client) page reload engine/control/Camera.ts +3:10:16 AM [vite] (client) page reload engine/control/Camera.ts +3:29:26 AM [vite] vite.config.ts changed, restarting server... +3:29:27 AM [vite] server restarted. + + ➜ Local: http://localhost:5173/ + ➜ Network: use --host to expose +3:40:37 AM [vite] vite.config.ts changed, restarting server... +3:40:38 AM [vite] server restarted. diff --git a/vite_mobile.log b/vite_mobile.log new file mode 100644 index 00000000..b4a9e52a --- /dev/null +++ b/vite_mobile.log @@ -0,0 +1,10 @@ + +> fantasy-map-generator@1.110.0 dev +> vite + +Port 5173 is in use, trying another one... + + VITE v7.3.1 ready in 365 ms + + ➜ Local: http://localhost:5174/ + ➜ Network: use --host to expose