diff --git a/src/main/resources/static/menu.js b/src/main/resources/static/menu.js
deleted file mode 100644
index c3820d0..0000000
--- a/src/main/resources/static/menu.js
+++ /dev/null
@@ -1,29 +0,0 @@
-
-export default {
- data() {
- return {
- 'items': [
- { 'title': '쐐기 기록', 'url': 'recent.html' },
- { 'title': '친구 그래프', 'url': 'relation.html' },
- { 'title': '쐐기평점 타임라인', 'url': 'score-timeline.html' },
- ]
- }
- },
- methods: {
- menu_selected(index) {
- location.href = this.items[index].url;
- }
- },
- template: `
-
-
- 이동
-
-
-
- {{ item.title }}
-
-
-
- `
-}
diff --git a/src/main/resources/static/recent.js b/src/main/resources/static/recent.js
deleted file mode 100644
index 060bebf..0000000
--- a/src/main/resources/static/recent.js
+++ /dev/null
@@ -1,116 +0,0 @@
-import Login from './login.js'
-import Menu from './menu.js'
-import Utils from './utils.js'
-
-export default {
- data() {
- return {
- 'characterName': '',
- 'server': '',
- 'servers': {},
- 'serverNames': [],
- 'dungeons': {},
- 'player': null,
- 'records': [],
- 'showOption': true,
- }
- },
- components: {
- Login, Menu
- },
- methods: {
- search() {
- if (this.characterName == '') {
- return;
- }
- this.characterName = this.characterName.substring(0, 1).toUpperCase() +
- this.characterName.substring(1).toLowerCase();
-
- if (window.localStorage) {
- window.localStorage.setItem('relation_server', this.server);
- window.localStorage.setItem('relation_character', this.characterName);
- }
-
- fetch('char/recent/' + encodeURI(this.server) + '/' + encodeURI(this.characterName)).then(async resp => {
- const data = await resp.json();
- this.player = data.player;
- this.records = data.data;
- });
- },
- scan() {
- if (this.characterName == '') {
- return;
- }
- this.characterName = this.characterName.substring(0, 1).toUpperCase() +
- this.characterName.substring(1).toLowerCase();
-
- fetch('char/scan/' + encodeURI(this.server) + '/' + encodeURI(this.characterName));
- },
- formatDate(d) {
- return Utils.formatDate(d);
- },
- },
- beforeMount() {
- if (window.localStorage) {
- this.server = window.localStorage.getItem('relation_server')
- this.characterName = window.localStorage.getItem('relation_character')
- }
- if (this.server == '' || this.server == null) {
- this.server = '아즈샤라';
- }
- },
- mounted() {
- fetch('form/realms').then(async resp => {
- this.servers = await resp.json()
- for (var key in this.servers) {
- this.serverNames.push(this.servers[key]);
- }
- if (this.server == '') {
- this.server = this.serverNames[0]['value']
- }
- });
- fetch('form/dungeons').then(async resp => {
- this.dungeons = await resp.json()
- })
- },
- template: `
-
-
-
-
-
-
-
-
-
-
-
- 검색
- {{ showOption ? "검색 조건 닫기" : "검색 조건 열기" }}
-
-
- 재검사
-
-
-
-
- 마지막 갱신 일자: {{ formatDate(player?.lastUpdateTs ?? 0) }}
-
-
-
-
- {{ formatDate(record.completedTimestamp) }}
-
-
- {{ dungeons[record.dungeonId] }}
-
-
- {{ record.keystoneLevel }}
-
-
- {{ record.keystoneUpgrade }}
-
-
-
- `,
-}
diff --git a/src/main/resources/static/relation.js b/src/main/resources/static/relation.js
deleted file mode 100644
index 65d059b..0000000
--- a/src/main/resources/static/relation.js
+++ /dev/null
@@ -1,148 +0,0 @@
-import Login from './login.js'
-import Menu from './menu.js'
-
-export default {
- data() {
- return {
- 'characterName': '',
- 'server': '',
- 'servers': {},
- 'serverNames': [],
- 'minimumRun': 1,
- 'players': new vis.DataSet([]),
- 'relations': new vis.DataSet([]),
- 'nextId': 1,
- 'showOption': true,
- }
- },
- components: {
- Login, Menu
- },
- methods: {
- search() {
- if (this.characterName == '') {
- return;
- }
- this.characterName = this.characterName.substring(0, 1).toUpperCase() +
- this.characterName.substring(1).toLowerCase();
-
- if (window.localStorage) {
- window.localStorage.setItem('relation_server', this.server);
- window.localStorage.setItem('relation_character', this.characterName);
- window.localStorage.setItem('relation_run', this.minimumRun);
- }
-
- fetch('char/relation/' + encodeURI(this.server) + '/' + encodeURI(this.characterName) + '/' + this.minimumRun).then(async resp => {
- const data = await resp.json();
- let i1 = this.players.get().find(p => p.label == this.characterName + '-' + this.server);
- if (i1 === undefined) {
- i1 = {
- id: this.nextId++,
- label: this.characterName + '-' + this.server
- };
- this.players.add(i1);
- }
-
- data.forEach(dd => {
- if (dd.value >= this.minimumRun) {
- let i2 = this.players.get().find(p => p.label == dd.name + '-' + dd.realm);
- if (i2 === undefined) {
- i2 = {
- id: this.nextId++,
- label: dd.name + '-' + dd.realm
- };
- this.players.add(i2);
- }
-
- var exists = this.relations.get().some(rel => (rel.from == i1.id && rel.to == i2.id) || (rel.from == i2.id && rel.to == i1.id));
- // this.relations.forEach(rel => {
- // if (rel.from == i1.id && rel.to == i2.id) {
- // exists = true
- // } else if (rel.from == i2.id && rel.to == i1.id) {
- // exists = true
- // }
- // })
- if (!exists) {
- this.relations.add({from: i1.id, to: i2.id, value: dd.value, title: dd.value })
- }
- }
- })
- })
- },
- },
- beforeMount() {
- if (window.localStorage) {
- const server = window.localStorage.getItem('relation_server')
- const run = parseInt(window.localStorage.getItem('relation_run'))
- this.server = server
- this.characterName = window.localStorage.getItem('relation_character')
- if (run > 0) {
- this.minimumRun = run
- }
- }
- if (this.server == '' || this.server == null) {
- this.server = '아즈샤라';
- }
- },
- mounted() {
- fetch('form/realms').then(async resp => {
- this.servers = await resp.json()
- for (var key in this.servers) {
- this.serverNames.push(this.servers[key]);
- // {
- // "label": this.servers[key],
- // "value": this.servers[key],
- // })
- }
- if (this.server == '') {
- this.server = this.serverNames[0]['value']
- }
- })
-
- var container = document.getElementById('relations')
- var data = {
- nodes: this.players,
- edges: this.relations
- }
- var options = {}
- var network = new vis.Network(container, data, options)
- network.on('doubleClick', e => {
- if (e.nodes.length > 0) {
- var id = e.nodes[0];
- var pl = this.players.get().find(p => p.id == id);
- var name = pl.label;
- this.server = name.substring(name.indexOf('-') + 1);
- this.characterName = name.substring(0, name.indexOf('-'));
- this.search();
- }
- })
- },
- template: `
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 검색
- {{ showOption ? "검색 조건 닫기" : "검색 조건 열기" }}
-
-
-
-
-
-
-
-
-
-
- `,
-}
diff --git a/src/main/resources/static/score-timeline.js b/src/main/resources/static/score-timeline.js
deleted file mode 100644
index 9a415da..0000000
--- a/src/main/resources/static/score-timeline.js
+++ /dev/null
@@ -1,301 +0,0 @@
-import Login from './login.js'
-import Menu from './menu.js'
-
-export default {
- data() {
- return {
- 'characterName': '',
- 'server': '',
- 'servers': {},
- 'serverNames': [],
- 'showOption': true,
- 'showDungeons': true,
- 'allSeason': false,
- 'graph2d': null,
- 'graphs': {
- '1': {
- 'items': [],
- 'groups': [{
- id: '0',
- content: "total",
- options: {
- excludeFromStacking: true
- }
- }],
- 'options': {
- style: 'bar',
- stack: true,
- legend: true,
- locale: 'en',
- // zoomable: false,
- // barChart: { width: 50, align: 'center' },
- drawPoints: {
- onRender: function(item, group, grap2d) {
- return item.label != null;
- },
- style: 'circle'
- },
- dataAxis: {
- icons: true,
- left: { range: { min: 0, max: 0 } }
- },
- height: 900
- }
- },
- '0': {
- 'items': [],
- 'groups': [{
- id: '0',
- content: "total",
- options: {
- excludeFromStacking: true
- }
- }],
- 'options': {
- style: 'bar',
- stack: false,
- legend: false,
- locale: 'en',
- // zoomable: false,
- // barChart: { width: 50, align: 'center' },
- drawPoints: {
- onRender: function(item, group, grap2d) {
- return item.label != null;
- },
- style: 'circle'
- },
- dataAxis: {
- icons: true,
- left: { range: { min: 0, max: 0 } }
- },
- height: 900
- }
- }
- }
- }
- },
- components: {
- Login, Menu
- },
- watch: {
- showDungeons(newVal, oldVal) {
- if (this.graph2d == null) {
- return;
- }
- const g = this.graphs[this.showDungeons ? 1 : 0];
- this.graph2d.setItems(g.items);
- this.graph2d.setGroups(g.groups);
- this.graph2d.setOptions(g.options);
- }
- },
- methods: {
- async search() {
- if (this.characterName == '') {
- return;
- }
- this.characterName = this.characterName.substring(0, 1).toUpperCase() +
- this.characterName.substring(1).toLowerCase();
-
- if (window.localStorage) {
- window.localStorage.setItem('relation_server', this.server);
- window.localStorage.setItem('relation_character', this.characterName);
- }
-
- const resp = await fetch(`char/mythic_rating/${encodeURI(this.server)}/${encodeURI(this.characterName)}?season=${this.allSeason?1:0}`);
- const body = await resp.json();
- const data = body;
-
- let season = 0;
- let period = 0;
- let dungeonScore = {};
- let minTimestamp = 0;
- let maxTimestamp = 0;
- let periodTimestamp = 0;
- const oneWeek = 7*24*3600*1000;
-
- this.graphs['1'].items = [];
- this.graphs['1'].groups = [{
- id: '0',
- content: "total",
- options: {
- excludeFromStacking: true
- }
- }];
- this.graphs['0'].items = [];
- const items1 = this.graphs['1'].items;
- const groups = this.graphs['1'].groups;
- const items2 = this.graphs['0'].items;
-
- const addSummary = () => {
- let score = 0
- for (let did in dungeonScore) {
- const arr = dungeonScore[did]
- const dscore = Math.max(arr[0], arr[1]) * 1.5 + Math.min(arr[0], arr[1]) * 0.5
- score += dscore
-
- const dname = groups.find(g => g.id == String(did)).content
-
- items1.push({
- x: periodTimestamp,
- y: dscore,
- end: periodTimestamp + oneWeek,
- group: String(did),
- label: {
- content: String(Math.round(dscore)) + '(' + dname.substring(0, 1) + ')',
- xOffset: 0,
- yOffset: 20
- }
- })
- }
- if (score > 0) {
- items1.push({
- x: periodTimestamp,
- y: score,
- end: periodTimestamp + oneWeek,
- group: '0',
- label: {
- content: String(Math.round(score)),
- xOffset: 0,
- yOffset: -20
- }
- })
- items2.push({
- x: periodTimestamp,
- y: score,
- end: periodTimestamp + oneWeek,
- group: '0',
- label: {
- content: String(Math.round(score)),
- xOffset: 0,
- yOffset: -20
- }
- })
- }
- }
-
- data.forEach(data => {
- if (data.season != season) {
- dungeonScore = {};
- season = data.season;
- period = 0;
- }
- if (data.period != period) {
- if (minTimestamp == 0) {
- minTimestamp = data.timestamp;
- } else {
- while (period < data.period) {
- addSummary();
- period++;
- periodTimestamp += oneWeek;
- }
- }
- period = data.period
- periodTimestamp = data.timestamp
- maxTimestamp = data.timestamp
- }
- if (!dungeonScore[data.dungeon_id]) {
- dungeonScore[data.dungeon_id] = [0, 0]
- }
- dungeonScore[data.dungeon_id][period % 2] = Math.max(dungeonScore[data.dungeon_id][period % 2], data.mythic_rating)
- if (!(groups.some(g => g.id == String(data.dungeon_id)))) {
- groups.push({
- id: String(data.dungeon_id),
- content: data.dungeon_name
- })
- }
- })
- addSummary()
- if (items1.length >= 0) {
- const timelineMargin = oneWeek;
- const container = document.getElementById('timeline');
- container.innerHTML = '';
- const g = this.graphs[this.showDungeons ? 1 : 0];
-
- const xRangeMin = minTimestamp - timelineMargin;
- const xRangeMax = maxTimestamp + timelineMargin * 2;
- const yRangeMax = Math.ceil(Math.max.apply(null, items1.filter(it => it.group == '0').map(it => it.y)) / 100) * 100 + 200;
-
- this.graphs['0'].options.min = xRangeMin;
- this.graphs['0'].options.max = xRangeMax;
- this.graphs['0'].options.dataAxis.left.range.max = yRangeMax;
- this.graphs['1'].options.min = xRangeMin;
- this.graphs['1'].options.max = xRangeMax;
- this.graphs['1'].options.dataAxis.left.range.max = yRangeMax;
-
- this.graph2d = new vis.Graph2d(container, g.items, g.groups, g.options);
- this.graph2d.setWindow(xRangeMin, xRangeMax);
- }
- },
-
- scan() {
- if (this.characterName == '') {
- return;
- }
- this.characterName = this.characterName.substring(0, 1).toUpperCase() +
- this.characterName.substring(1).toLowerCase();
-
- fetch('char/scan/' + encodeURI(this.server) + '/' + encodeURI(this.characterName));
- },
-
- toggleDungeon() {
- this.showDungeons = !this.showDungeons;
- },
-
- toggleSeason() {
- this.allSeason = !this.allSeason;
- },
- },
- beforeMount() {
- if (window.localStorage) {
- const server = window.localStorage.getItem('relation_server')
- const run = parseInt(window.localStorage.getItem('relation_run'))
- this.server = server
- this.characterName = window.localStorage.getItem('relation_character')
- if (run > 0) {
- this.minimumRun = run
- }
- }
- if (this.server == '' || this.server == null) {
- this.server = '아즈샤라';
- }
- },
- mounted() {
- fetch('form/realms').then(async resp => {
- this.servers = await resp.json()
- for (let key in this.servers) {
- this.serverNames.push(this.servers[key]);
- }
- if (this.server == '') {
- this.server = this.serverNames[0]['value']
- }
- })
- },
- template: `
-
-
-
-
-
-
-
-
-
-
-
- 검색
- {{ showOption ? "검색 조건 닫기" : "검색 조건 열기" }}
-
-
- {{ showDungeons ? "던전별 표시" : "총점 표시" }}
- {{ allSeason ? "전체시즌" : "현재시즌" }}
- 재검사
-
-
-
-
-
-
-
-
- `,
-};
diff --git a/src/main/webapp/app.js b/src/main/webapp/app.js
new file mode 100644
index 0000000..e69de29
diff --git a/src/main/webapp/character-list.js b/src/main/webapp/character-list.js
new file mode 100644
index 0000000..6a8de5d
--- /dev/null
+++ b/src/main/webapp/character-list.js
@@ -0,0 +1,67 @@
+export default {
+ data() {
+ return {
+ characterName: "",
+ server: "",
+ };
+ },
+ components: {},
+ props: ["serverNames", "characters"],
+ methods: {
+ insert() {
+ if (this.characterName == "") {
+ return;
+ }
+ this.characterName =
+ this.characterName.substring(0, 1).toUpperCase() +
+ this.characterName.substring(1).toLowerCase();
+
+ this.$emit("added", {
+ name: this.characterName,
+ server: this.server,
+ });
+ },
+ remove(index) {
+ this.$emit("removed", index);
+ },
+ },
+ beforeMount() {
+ if (window.localStorage) {
+ const server = window.localStorage.getItem("relation_server");
+ const run = parseInt(window.localStorage.getItem("relation_run"));
+ this.server = server;
+ this.characterName = window.localStorage.getItem("relation_character");
+ }
+ if (this.server == "" || this.server == null) {
+ this.server = "아즈샤라";
+ }
+ },
+ mounted() {},
+ template: `
+
+
+
+
+
+
+
+
+
+ 추가
+
+
+
+
+
+ {{ item.name }}
+
+
+ {{ item.server }}
+
+
+ 삭제
+
+
+
+ `,
+};
diff --git a/src/main/resources/static/css/vis.min.css b/src/main/webapp/css/vis.min.css
similarity index 100%
rename from src/main/resources/static/css/vis.min.css
rename to src/main/webapp/css/vis.min.css
diff --git a/src/main/webapp/index.html b/src/main/webapp/index.html
new file mode 100644
index 0000000..5a8d2b1
--- /dev/null
+++ b/src/main/webapp/index.html
@@ -0,0 +1,40 @@
+
+
+
+
+Mythic+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/static/js/vis.min.js b/src/main/webapp/js/vis.min.js
similarity index 100%
rename from src/main/resources/static/js/vis.min.js
rename to src/main/webapp/js/vis.min.js
diff --git a/src/main/resources/static/login.js b/src/main/webapp/login.js
similarity index 100%
rename from src/main/resources/static/login.js
rename to src/main/webapp/login.js
diff --git a/src/main/resources/static/index.html b/src/main/webapp/recent.html
similarity index 74%
rename from src/main/resources/static/index.html
rename to src/main/webapp/recent.html
index 31a0f92..cc1df71 100644
--- a/src/main/resources/static/index.html
+++ b/src/main/webapp/recent.html
@@ -9,8 +9,8 @@
-