diff --git a/CHANGELOG.md b/CHANGELOG.md
index 64de67ed26..94ffe4f2b4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -42,6 +42,12 @@ mongodb:
 8. master ブランチに戻す
 9. enjoy
 
+11.9.0 (2019/05/02)
+-------------------
+### Improvements
+* MisskeyPagesで編集時にページブロックをドラッグで並べ替えられるように
+* MisskeyPagesにカウンターボタンブロックを追加
+
 11.8.1 (2019/05/02)
 -------------------
 ### Fixes
diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml
index a8a5cbafd1..5d85819d54 100644
--- a/locales/ja-JP.yml
+++ b/locales/ja-JP.yml
@@ -1915,6 +1915,12 @@ pages:
       text: "タイトル"
       default: "デフォルト値"
 
+    counter: "カウンター"
+    _counter:
+      name: "変数名"
+      text: "タイトル"
+      inc: "増加値"
+
     _button:
       text: "タイトル"
       action: "ボタンを押したときの動作"
diff --git a/package.json b/package.json
index 2dddb678f6..d1a51e6ea2 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
 {
 	"name": "misskey",
 	"author": "syuilo <i@syuilo.com>",
-	"version": "11.8.1",
+	"version": "11.9.0",
 	"codename": "daybreak",
 	"repository": {
 		"type": "git",
diff --git a/src/client/app/common/scripts/collect-page-vars.ts b/src/client/app/common/scripts/collect-page-vars.ts
index 683f9b73a5..4c40d5d88e 100644
--- a/src/client/app/common/scripts/collect-page-vars.ts
+++ b/src/client/app/common/scripts/collect-page-vars.ts
@@ -26,6 +26,12 @@ export function collectPageVars(content) {
 					type: 'boolean',
 					value: x.default || false
 				});
+			} else if (x.type === 'counter') {
+				pageVars.push({
+					name: x.name,
+					type: 'number',
+					value: 0
+				});
 			} else if (x.children) {
 				collect(x.children);
 			}
diff --git a/src/client/app/common/views/components/page-editor/els/page-editor.el.button.vue b/src/client/app/common/views/components/page-editor/els/page-editor.el.button.vue
index 3e2d3fe19d..f89279f05a 100644
--- a/src/client/app/common/views/components/page-editor/els/page-editor.el.button.vue
+++ b/src/client/app/common/views/components/page-editor/els/page-editor.el.button.vue
@@ -1,5 +1,5 @@
 <template>
-<x-container @remove="() => $emit('remove')">
+<x-container @remove="() => $emit('remove')" :draggable="true">
 	<template #header><fa :icon="faBolt"/> {{ $t('blocks.button') }}</template>
 
 	<section class="xfhsjczc">
diff --git a/src/client/app/common/views/components/page-editor/els/page-editor.el.counter.vue b/src/client/app/common/views/components/page-editor/els/page-editor.el.counter.vue
new file mode 100644
index 0000000000..95c15b01b2
--- /dev/null
+++ b/src/client/app/common/views/components/page-editor/els/page-editor.el.counter.vue
@@ -0,0 +1,42 @@
+<template>
+<x-container @remove="() => $emit('remove')" :draggable="true">
+	<template #header><fa :icon="faBolt"/> {{ $t('blocks.counter') }}</template>
+
+	<section style="padding: 0 16px 0 16px;">
+		<ui-input v-model="value.name"><template #prefix><fa :icon="faMagic"/></template><span>{{ $t('blocks._counter.name') }}</span></ui-input>
+		<ui-input v-model="value.text"><span>{{ $t('blocks._counter.text') }}</span></ui-input>
+		<ui-input v-model="value.inc" type="number"><span>{{ $t('blocks._counter.increment') }}</span></ui-input>
+	</section>
+</x-container>
+</template>
+
+<script lang="ts">
+import Vue from 'vue';
+import { faBolt, faMagic } from '@fortawesome/free-solid-svg-icons';
+import i18n from '../../../../../i18n';
+import XContainer from '../page-editor.container.vue';
+
+export default Vue.extend({
+	i18n: i18n('pages'),
+
+	components: {
+		XContainer
+	},
+
+	props: {
+		value: {
+			required: true
+		},
+	},
+
+	data() {
+		return {
+			faBolt, faMagic
+		};
+	},
+
+	created() {
+		if (this.value.name == null) Vue.set(this.value, 'name', '');
+	},
+});
+</script>
diff --git a/src/client/app/common/views/components/page-editor/els/page-editor.el.if.vue b/src/client/app/common/views/components/page-editor/els/page-editor.el.if.vue
index 87fc9e6faf..c83cd421ae 100644
--- a/src/client/app/common/views/components/page-editor/els/page-editor.el.if.vue
+++ b/src/client/app/common/views/components/page-editor/els/page-editor.el.if.vue
@@ -1,5 +1,5 @@
 <template>
-<x-container @remove="() => $emit('remove')">
+<x-container @remove="() => $emit('remove')" :draggable="true">
 	<template #header><fa :icon="faQuestion"/> {{ $t('blocks.if') }}</template>
 	<template #func>
 		<button @click="add()">
@@ -19,9 +19,7 @@
 			</optgroup>
 		</ui-select>
 
-		<div class="children">
-			<x-block v-for="child in value.children" :value="child" @input="v => updateItem(v)" @remove="() => remove(child)" :key="child.id" :ai-script="aiScript"/>
-		</div>
+		<x-blocks class="children" v-model="value.children" :ai-script="aiScript"/>
 	</section>
 </x-container>
 </template>
@@ -58,7 +56,7 @@ export default Vue.extend({
 	},
 
 	beforeCreate() {
-		this.$options.components.XBlock = require('../page-editor.block.vue').default
+		this.$options.components.XBlocks = require('../page-editor.blocks.vue').default
 	},
 
 	created() {
@@ -81,27 +79,6 @@ export default Vue.extend({
 			const id = uuid.v4();
 			this.value.children.push({ id, type });
 		},
-
-		updateItem(v) {
-			const i = this.value.children.findIndex(x => x.id === v.id);
-			const newValue = [
-				...this.value.children.slice(0, i),
-				v,
-				...this.value.children.slice(i + 1)
-			];
-			this.value.children = newValue;
-			this.$emit('input', this.value);
-		},
-
-		remove(el) {
-			const i = this.value.children.findIndex(x => x.id === el.id);
-			const newValue = [
-				...this.value.children.slice(0, i),
-				...this.value.children.slice(i + 1)
-			];
-			this.value.children = newValue;
-			this.$emit('input', this.value);
-		}
 	}
 });
 </script>
diff --git a/src/client/app/common/views/components/page-editor/els/page-editor.el.image.vue b/src/client/app/common/views/components/page-editor/els/page-editor.el.image.vue
index 5ada8c77ba..98ec39a512 100644
--- a/src/client/app/common/views/components/page-editor/els/page-editor.el.image.vue
+++ b/src/client/app/common/views/components/page-editor/els/page-editor.el.image.vue
@@ -1,5 +1,5 @@
 <template>
-<x-container @remove="() => $emit('remove')">
+<x-container @remove="() => $emit('remove')" :draggable="true">
 	<template #header><fa :icon="faImage"/> {{ $t('blocks.image') }}</template>
 	<template #func>
 		<button @click="choose()">
diff --git a/src/client/app/common/views/components/page-editor/els/page-editor.el.number-input.vue b/src/client/app/common/views/components/page-editor/els/page-editor.el.number-input.vue
index 923f4ea339..30c3938111 100644
--- a/src/client/app/common/views/components/page-editor/els/page-editor.el.number-input.vue
+++ b/src/client/app/common/views/components/page-editor/els/page-editor.el.number-input.vue
@@ -1,5 +1,5 @@
 <template>
-<x-container @remove="() => $emit('remove')">
+<x-container @remove="() => $emit('remove')" :draggable="true">
 	<template #header><fa :icon="faBolt"/> {{ $t('blocks.numberInput') }}</template>
 
 	<section style="padding: 0 16px 0 16px;">
diff --git a/src/client/app/common/views/components/page-editor/els/page-editor.el.post.vue b/src/client/app/common/views/components/page-editor/els/page-editor.el.post.vue
index a01fc57f26..fc2f5f9032 100644
--- a/src/client/app/common/views/components/page-editor/els/page-editor.el.post.vue
+++ b/src/client/app/common/views/components/page-editor/els/page-editor.el.post.vue
@@ -1,5 +1,5 @@
 <template>
-<x-container @remove="() => $emit('remove')">
+<x-container @remove="() => $emit('remove')" :draggable="true">
 	<template #header><fa :icon="faPaperPlane"/> {{ $t('blocks.post') }}</template>
 
 	<section style="padding: 0 16px 16px 16px;">
@@ -33,10 +33,6 @@ export default Vue.extend({
 		};
 	},
 
-	beforeCreate() {
-		this.$options.components.XBlock = require('../page-editor.block.vue').default
-	},
-
 	created() {
 		if (this.value.text == null) Vue.set(this.value, 'text', '');
 	},
diff --git a/src/client/app/common/views/components/page-editor/els/page-editor.el.section.vue b/src/client/app/common/views/components/page-editor/els/page-editor.el.section.vue
index 747de481a6..c20f824e23 100644
--- a/src/client/app/common/views/components/page-editor/els/page-editor.el.section.vue
+++ b/src/client/app/common/views/components/page-editor/els/page-editor.el.section.vue
@@ -1,5 +1,5 @@
 <template>
-<x-container @remove="() => $emit('remove')">
+<x-container @remove="() => $emit('remove')" :draggable="true">
 	<template #header><fa :icon="faStickyNote"/> {{ value.title }}</template>
 	<template #func>
 		<button @click="rename()">
@@ -11,9 +11,7 @@
 	</template>
 
 	<section class="ilrvjyvi">
-		<div class="children">
-			<x-block v-for="child in value.children" :value="child" @input="v => updateItem(v)" @remove="() => remove(child)" :key="child.id" :ai-script="aiScript"/>
-		</div>
+		<x-blocks class="children" v-model="value.children" :ai-script="aiScript"/>
 	</section>
 </x-container>
 </template>
@@ -51,7 +49,7 @@ export default Vue.extend({
 	},
 
 	beforeCreate() {
-		this.$options.components.XBlock = require('../page-editor.block.vue').default
+		this.$options.components.XBlocks = require('../page-editor.blocks.vue').default
 	},
 
 	created() {
@@ -93,27 +91,6 @@ export default Vue.extend({
 			const id = uuid.v4();
 			this.value.children.push({ id, type });
 		},
-
-		updateItem(v) {
-			const i = this.value.children.findIndex(x => x.id === v.id);
-			const newValue = [
-				...this.value.children.slice(0, i),
-				v,
-				...this.value.children.slice(i + 1)
-			];
-			this.value.children = newValue;
-			this.$emit('input', this.value);
-		},
-
-		remove(el) {
-			const i = this.value.children.findIndex(x => x.id === el.id);
-			const newValue = [
-				...this.value.children.slice(0, i),
-				...this.value.children.slice(i + 1)
-			];
-			this.value.children = newValue;
-			this.$emit('input', this.value);
-		}
 	}
 });
 </script>
diff --git a/src/client/app/common/views/components/page-editor/els/page-editor.el.switch.vue b/src/client/app/common/views/components/page-editor/els/page-editor.el.switch.vue
index 60d102f8ae..174a344640 100644
--- a/src/client/app/common/views/components/page-editor/els/page-editor.el.switch.vue
+++ b/src/client/app/common/views/components/page-editor/els/page-editor.el.switch.vue
@@ -1,5 +1,5 @@
 <template>
-<x-container @remove="() => $emit('remove')">
+<x-container @remove="() => $emit('remove')" :draggable="true">
 	<template #header><fa :icon="faBolt"/> {{ $t('blocks.switch') }}</template>
 
 	<section class="kjuadyyj">
diff --git a/src/client/app/common/views/components/page-editor/els/page-editor.el.text-input.vue b/src/client/app/common/views/components/page-editor/els/page-editor.el.text-input.vue
index 168a58f349..50f95fd205 100644
--- a/src/client/app/common/views/components/page-editor/els/page-editor.el.text-input.vue
+++ b/src/client/app/common/views/components/page-editor/els/page-editor.el.text-input.vue
@@ -1,5 +1,5 @@
 <template>
-<x-container @remove="() => $emit('remove')">
+<x-container @remove="() => $emit('remove')" :draggable="true">
 	<template #header><fa :icon="faBolt"/> {{ $t('blocks.textInput') }}</template>
 
 	<section style="padding: 0 16px 0 16px;">
diff --git a/src/client/app/common/views/components/page-editor/els/page-editor.el.text.vue b/src/client/app/common/views/components/page-editor/els/page-editor.el.text.vue
index 1d07c9157a..c09f9cc1cf 100644
--- a/src/client/app/common/views/components/page-editor/els/page-editor.el.text.vue
+++ b/src/client/app/common/views/components/page-editor/els/page-editor.el.text.vue
@@ -1,5 +1,5 @@
 <template>
-<x-container @remove="() => $emit('remove')">
+<x-container @remove="() => $emit('remove')" :draggable="true">
 	<template #header><fa :icon="faAlignLeft"/> {{ $t('blocks.text') }}</template>
 
 	<section class="ihymsbbe">
diff --git a/src/client/app/common/views/components/page-editor/els/page-editor.el.textarea-input.vue b/src/client/app/common/views/components/page-editor/els/page-editor.el.textarea-input.vue
index 4b6d334d9b..da3eead080 100644
--- a/src/client/app/common/views/components/page-editor/els/page-editor.el.textarea-input.vue
+++ b/src/client/app/common/views/components/page-editor/els/page-editor.el.textarea-input.vue
@@ -1,5 +1,5 @@
 <template>
-<x-container @remove="() => $emit('remove')">
+<x-container @remove="() => $emit('remove')" :draggable="true">
 	<template #header><fa :icon="faBolt"/> {{ $t('blocks.textareaInput') }}</template>
 
 	<section style="padding: 0 16px 16px 16px;">
diff --git a/src/client/app/common/views/components/page-editor/els/page-editor.el.textarea.vue b/src/client/app/common/views/components/page-editor/els/page-editor.el.textarea.vue
index 4fbe497960..a0cc1966e8 100644
--- a/src/client/app/common/views/components/page-editor/els/page-editor.el.textarea.vue
+++ b/src/client/app/common/views/components/page-editor/els/page-editor.el.textarea.vue
@@ -1,5 +1,5 @@
 <template>
-<x-container @remove="() => $emit('remove')">
+<x-container @remove="() => $emit('remove')" :draggable="true">
 	<template #header><fa :icon="faAlignLeft"/> {{ $t('blocks.textarea') }}</template>
 
 	<section class="ihymsbbe">
diff --git a/src/client/app/common/views/components/page-editor/page-editor.block.vue b/src/client/app/common/views/components/page-editor/page-editor.block.vue
deleted file mode 100644
index 7d4505fca8..0000000000
--- a/src/client/app/common/views/components/page-editor/page-editor.block.vue
+++ /dev/null
@@ -1,33 +0,0 @@
-<template>
-<component :is="'x-' + value.type" :value="value" @input="v => updateItem(v)" @remove="() => $emit('remove', value)" :key="value.id" :ai-script="aiScript"/>
-</template>
-
-<script lang="ts">
-import Vue from 'vue';
-import XSection from './els/page-editor.el.section.vue';
-import XText from './els/page-editor.el.text.vue';
-import XTextarea from './els/page-editor.el.textarea.vue';
-import XImage from './els/page-editor.el.image.vue';
-import XButton from './els/page-editor.el.button.vue';
-import XTextInput from './els/page-editor.el.text-input.vue';
-import XTextareaInput from './els/page-editor.el.textarea-input.vue';
-import XNumberInput from './els/page-editor.el.text-input.vue';
-import XSwitch from './els/page-editor.el.switch.vue';
-import XIf from './els/page-editor.el.if.vue';
-import XPost from './els/page-editor.el.post.vue';
-
-export default Vue.extend({
-	components: {
-		XSection, XText, XImage, XButton, XTextarea, XTextInput, XTextareaInput, XNumberInput, XSwitch, XIf, XPost
-	},
-
-	props: {
-		value: {
-			required: true
-		},
-		aiScript: {
-			required: true,
-		},
-	},
-});
-</script>
diff --git a/src/client/app/common/views/components/page-editor/page-editor.blocks.vue b/src/client/app/common/views/components/page-editor/page-editor.blocks.vue
new file mode 100644
index 0000000000..894feb34cc
--- /dev/null
+++ b/src/client/app/common/views/components/page-editor/page-editor.blocks.vue
@@ -0,0 +1,65 @@
+<template>
+<x-draggable tag="div" :list="blocks" handle=".drag-handle" :group="{ name: 'blocks' }" animation="150">
+	<component v-for="block in blocks" :is="'x-' + block.type" :value="block" @input="updateItem" @remove="removeItem" :key="block.id" :ai-script="aiScript"/>
+</x-draggable>
+</template>
+
+<script lang="ts">
+import Vue from 'vue';
+import * as XDraggable from 'vuedraggable';
+import XSection from './els/page-editor.el.section.vue';
+import XText from './els/page-editor.el.text.vue';
+import XTextarea from './els/page-editor.el.textarea.vue';
+import XImage from './els/page-editor.el.image.vue';
+import XButton from './els/page-editor.el.button.vue';
+import XTextInput from './els/page-editor.el.text-input.vue';
+import XTextareaInput from './els/page-editor.el.textarea-input.vue';
+import XNumberInput from './els/page-editor.el.text-input.vue';
+import XSwitch from './els/page-editor.el.switch.vue';
+import XIf from './els/page-editor.el.if.vue';
+import XPost from './els/page-editor.el.post.vue';
+import XCounter from './els/page-editor.el.counter.vue';
+
+export default Vue.extend({
+	components: {
+		XDraggable, XSection, XText, XImage, XButton, XTextarea, XTextInput, XTextareaInput, XNumberInput, XSwitch, XIf, XPost, XCounter
+	},
+
+	props: {
+		value: {
+			type: Array,
+			required: true
+		},
+		aiScript: {
+			required: true,
+		},
+	},
+
+	computed: {
+		blocks() {
+			return this.value;
+		}
+	},
+
+	methods: {
+		updateItem(v) {
+			const i = this.blocks.findIndex(x => x.id === v.id);
+			const newValue = [
+				...this.blocks.slice(0, i),
+				v,
+				...this.blocks.slice(i + 1)
+			];
+			this.$emit('input', newValue);
+		},
+
+		removeItem(el) {
+			const i = this.blocks.findIndex(x => x.id === el.id);
+			const newValue = [
+				...this.blocks.slice(0, i),
+				...this.blocks.slice(i + 1)
+			];
+			this.$emit('input', newValue);
+		},
+	}
+});
+</script>
diff --git a/src/client/app/common/views/components/page-editor/page-editor.container.vue b/src/client/app/common/views/components/page-editor/page-editor.container.vue
index 698fdfee45..4127cd39e0 100644
--- a/src/client/app/common/views/components/page-editor/page-editor.container.vue
+++ b/src/client/app/common/views/components/page-editor/page-editor.container.vue
@@ -1,6 +1,6 @@
 <template>
-<div class="cpjygsrt" :class="{ error: error != null, warn: warn != null }">
-	<header>
+<div class="cpjygsrt" :class="{ error: error != null, warn: warn != null, draggable }">
+	<header class="drag-handle">
 		<div class="title"><slot name="header"></slot></div>
 		<div class="buttons">
 			<slot name="func"></slot>
@@ -38,6 +38,10 @@ export default Vue.extend({
 			type: Boolean,
 			default: true
 		},
+		draggable: {
+			type: Boolean,
+			default: false
+		},
 		error: {
 			required: false,
 			default: null
@@ -120,6 +124,10 @@ export default Vue.extend({
 				&:active
 					color var(--faceTextButtonActive)
 
+	&.draggable
+		> header
+			cursor move
+
 	> .warn
 		color #b19e49
 		margin 0
diff --git a/src/client/app/common/views/components/page-editor/page-editor.vue b/src/client/app/common/views/components/page-editor/page-editor.vue
index 6d07c5dc6b..d70049121d 100644
--- a/src/client/app/common/views/components/page-editor/page-editor.vue
+++ b/src/client/app/common/views/components/page-editor/page-editor.vue
@@ -44,9 +44,7 @@
 				</div>
 			</template>
 
-			<div class="content" v-for="child in content">
-				<x-block :value="child" @input="v => updateItem(v)" @remove="() => remove(child)" :key="child.id" :ai-script="aiScript"/>
-			</div>
+			<x-blocks class="content" v-model="content" :ai-script="aiScript"/>
 
 			<ui-button @click="add()" v-if="!readonly"><fa :icon="faPlus"/></ui-button>
 		</section>
@@ -98,7 +96,7 @@ import { faICursor, faPlus, faMagic, faCog, faCode, faExternalLinkSquareAlt } fr
 import { faSave, faStickyNote, faTrashAlt } from '@fortawesome/free-regular-svg-icons';
 import i18n from '../../../../i18n';
 import XVariable from './page-editor.script-block.vue';
-import XBlock from './page-editor.block.vue';
+import XBlocks from './page-editor.blocks.vue';
 import * as uuid from 'uuid';
 import { blockDefs } from '../../../../../../misc/aiscript/index';
 import { ASTypeChecker } from '../../../../../../misc/aiscript/type-checker';
@@ -109,7 +107,7 @@ export default Vue.extend({
 	i18n: i18n('pages'),
 
 	components: {
-		XVariable, XBlock
+		XVariable, XBlocks
 	},
 
 	props: {
@@ -299,25 +297,6 @@ export default Vue.extend({
 			this.variables.push({ id, name, type: null });
 		},
 
-		updateItem(v) {
-			const i = this.content.findIndex(x => x.id === v.id);
-			const newValue = [
-				...this.content.slice(0, i),
-				v,
-				...this.content.slice(i + 1)
-			];
-			this.content = newValue;
-		},
-
-		remove(el) {
-			const i = this.content.findIndex(x => x.id === el.id);
-			const newValue = [
-				...this.content.slice(0, i),
-				...this.content.slice(i + 1)
-			];
-			this.content = newValue;
-		},
-
 		removeVariable(v) {
 			const i = this.variables.findIndex(x => x.name === v.name);
 			const newValue = [
@@ -343,7 +322,8 @@ export default Vue.extend({
 					{ value: 'textInput', text: this.$t('blocks.textInput') },
 					{ value: 'textareaInput', text: this.$t('blocks.textareaInput') },
 					{ value: 'numberInput', text: this.$t('blocks.numberInput') },
-					{ value: 'switch', text: this.$t('blocks.switch') }
+					{ value: 'switch', text: this.$t('blocks.switch') },
+					{ value: 'counter', text: this.$t('blocks.counter') }
 				]
 			}, {
 				label: this.$t('special-blocks'),
diff --git a/src/client/app/common/views/pages/page/page.block.vue b/src/client/app/common/views/pages/page/page.block.vue
index f348107cc7..1c421fc2c0 100644
--- a/src/client/app/common/views/pages/page/page.block.vue
+++ b/src/client/app/common/views/pages/page/page.block.vue
@@ -15,10 +15,11 @@ import XSwitch from './page.switch.vue';
 import XIf from './page.if.vue';
 import XTextarea from './page.textarea.vue';
 import XPost from './page.post.vue';
+import XCounter from './page.counter.vue';
 
 export default Vue.extend({
 	components: {
-		XText, XSection, XImage, XButton, XNumberInput, XTextInput, XTextareaInput, XTextarea, XPost, XSwitch, XIf
+		XText, XSection, XImage, XButton, XNumberInput, XTextInput, XTextareaInput, XTextarea, XPost, XSwitch, XIf, XCounter
 	},
 
 	props: {
diff --git a/src/client/app/common/views/pages/page/page.counter.vue b/src/client/app/common/views/pages/page/page.counter.vue
new file mode 100644
index 0000000000..8d55319fe9
--- /dev/null
+++ b/src/client/app/common/views/pages/page/page.counter.vue
@@ -0,0 +1,47 @@
+<template>
+<div>
+	<ui-button class="llumlmnx" @click="click()">{{ script.interpolate(value.text) }}</ui-button>
+</div>
+</template>
+
+<script lang="ts">
+import Vue from 'vue';
+
+export default Vue.extend({
+	props: {
+		value: {
+			required: true
+		},
+		script: {
+			required: true
+		}
+	},
+
+	data() {
+		return {
+			v: 0,
+		};
+	},
+
+	watch: {
+		v() {
+			this.script.aiScript.updatePageVar(this.value.name, this.v);
+			this.script.eval();
+		}
+	},
+
+	methods: {
+		click() {
+			this.v = this.v + (this.value.inc || 1);
+		}
+	}
+});
+</script>
+
+<style lang="stylus" scoped>
+.llumlmnx
+	display inline-block
+	min-width 300px
+	max-width 450px
+	margin 8px 0
+</style>
diff --git a/src/misc/aiscript/evaluator.ts b/src/misc/aiscript/evaluator.ts
index fef2d4f3a5..2bc866dc43 100644
--- a/src/misc/aiscript/evaluator.ts
+++ b/src/misc/aiscript/evaluator.ts
@@ -7,56 +7,6 @@ type Fn = {
 	exec: (args: Record<string, any>) => ReturnType<ASEvaluator['evaluate']>;
 };
 
-class AiScriptError extends Error {
-	public info?: any;
-
-	constructor(message: string, info?: any) {
-		super(message);
-
-		this.info = info;
-
-		// Maintains proper stack trace for where our error was thrown (only available on V8)
-		if (Error.captureStackTrace) {
-			Error.captureStackTrace(this, AiScriptError);
-		}
-	}
-}
-
-class Scope {
-	private layerdStates: Record<string, any>[];
-	public name: string;
-
-	constructor(layerdStates: Scope['layerdStates'], name?: Scope['name']) {
-		this.layerdStates = layerdStates;
-		this.name = name || 'anonymous';
-	}
-
-	@autobind
-	public createChildScope(states: Record<string, any>, name?: Scope['name']): Scope {
-		const layer = [states, ...this.layerdStates];
-		return new Scope(layer, name);
-	}
-
-	/**
-	 * 指定した名前の変数の値を取得します
-	 * @param name 変数名
-	 */
-	@autobind
-	public getState(name: string): any {
-		for (const later of this.layerdStates) {
-			const state = later[name];
-			if (state !== undefined) {
-				return state;
-			}
-		}
-
-		throw new AiScriptError(
-			`No such variable '${name}' in scope '${this.name}'`, {
-				scope: this.layerdStates
-			});
-	}
-}
-
 /**
  * AiScript evaluator
  */
@@ -238,3 +188,53 @@ export class ASEvaluator {
 		}
 	}
 }
+
+class AiScriptError extends Error {
+	public info?: any;
+
+	constructor(message: string, info?: any) {
+		super(message);
+
+		this.info = info;
+
+		// Maintains proper stack trace for where our error was thrown (only available on V8)
+		if (Error.captureStackTrace) {
+			Error.captureStackTrace(this, AiScriptError);
+		}
+	}
+}
+
+class Scope {
+	private layerdStates: Record<string, any>[];
+	public name: string;
+
+	constructor(layerdStates: Scope['layerdStates'], name?: Scope['name']) {
+		this.layerdStates = layerdStates;
+		this.name = name || 'anonymous';
+	}
+
+	@autobind
+	public createChildScope(states: Record<string, any>, name?: Scope['name']): Scope {
+		const layer = [states, ...this.layerdStates];
+		return new Scope(layer, name);
+	}
+
+	/**
+	 * 指定した名前の変数の値を取得します
+	 * @param name 変数名
+	 */
+	@autobind
+	public getState(name: string): any {
+		for (const later of this.layerdStates) {
+			const state = later[name];
+			if (state !== undefined) {
+				return state;
+			}
+		}
+
+		throw new AiScriptError(
+			`No such variable '${name}' in scope '${this.name}'`, {
+				scope: this.layerdStates
+			});
+	}
+}