koffing 0.4.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +2 -2
- package/README.md +6 -131
- package/dist/index.d.ts +106 -0
- package/dist/index.js +431 -0
- package/dist/index.mjs +400 -0
- package/package.json +27 -32
- package/dist/koffing.js +0 -940
- package/dist/koffing.min.js +0 -1
- package/src/Pokemon.js +0 -174
- package/src/PokemonTeam.js +0 -80
- package/src/PokemonTeamSet.js +0 -54
- package/src/ShowdownParser.js +0 -281
- package/src/index.js +0 -76
package/dist/koffing.min.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
!function(e,n){if("object"==typeof exports&&"object"==typeof module)module.exports=n();else if("function"==typeof define&&define.amd)define([],n);else{var t=n();for(var i in t)("object"==typeof exports?exports:e)[i]=t[i]}}("undefined"!=typeof self?self:this,function(){return function(e){var n={};function t(i){if(n[i])return n[i].exports;var r=n[i]={i:i,l:!1,exports:{}};return e[i].call(r.exports,r,r.exports,t),r.l=!0,r.exports}return t.m=e,t.c=n,t.d=function(e,n,i){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:i})},t.r=function(e){Object.defineProperty(e,"__esModule",{value:!0})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},t.p="",t(t.s=4)}([function(e,n,t){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var i,r=function(){function e(e,n){for(var t=0;t<n.length;t++){var i=n[t];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,i.key,i)}}return function(n,t,i){return t&&e(n.prototype,t),i&&e(n,i),n}}(),o=t(1),a=(i=o)&&i.__esModule?i:{default:i};var s=function(){function e(){var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"gen7",t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"Untitled",i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:void 0;!function(e,n){if(!(e instanceof n))throw new TypeError("Cannot call a class as a function")}(this,e),this.name=t,this.format=n,this.folder=i,this.pokemon=[]}return r(e,[{key:"toJson",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:2;return JSON.stringify(this,null,e)}},{key:"toShowdown",value:function(){var e=this.folder?this.folder+"/"+this.name:this.name,n="=== ["+this.format+"] "+e+" ===\n\n";return(n+=this.pokemon.map(function(e){return e.toString()}).join("\n\n")).trim()}},{key:"toString",value:function(){return this.toShowdown()}}],[{key:"fromObject",value:function(n){var t=new e;return t.name=n.name,t.format=n.format,t.folder=n.folder,t.pokemon=n.pokemon?n.pokemon.map(function(e){return a.default.fromObject(e)}):[],t}}]),e}();n.default=s},function(e,n,t){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var i=function(){function e(e,n){for(var t=0;t<n.length;t++){var i=n[t];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,i.key,i)}}return function(n,t,i){return t&&e(n.prototype,t),i&&e(n,i),n}}();var r=function(){function e(){!function(e,n){if(!(e instanceof n))throw new TypeError("Cannot call a class as a function")}(this,e),this.name=void 0,this.nickname=void 0,this.gender=void 0,this.item=void 0,this.ability=void 0,this.level=void 0,this.shiny=void 0,this.happiness=void 0,this.nature=void 0,this.evs=void 0,this.ivs=void 0,this.moves=[]}return i(e,[{key:"toJson",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:2;return JSON.stringify(this,null,e)}},{key:"toShowdown",value:function(){var e="";if(this.nickname?e+=this.nickname+" ("+this.name+")":e+=""+this.name,this.gender&&this.gender.match(/^[MF]$/i)&&(e+=" ("+this.gender.toUpperCase()+")"),this.item&&(e+=" @ "+this.item),e+="\n",isNaN(this.level)||(e+="Level: "+this.level+"\n"),this.ability&&(e+="Ability: "+this.ability+"\n"),!0===this.shiny&&(e+="Shiny: Yes\n"),isNaN(this.happiness)||(e+="Happiness: "+this.happiness+"\n"),this.nature&&(e+=this.nature+" Nature\n"),this.evs){var n=this.evs;e+="EVs: "+["HP","Atk","Def","SpA","SpD","Spe"].filter(function(e){return!isNaN(n[e.toLowerCase()])}).map(function(e){return n[e.toLowerCase()]+" "+e}).join(" / ")+"\n"}if(this.ivs){var t=this.ivs;e+="IVs: "+["HP","Atk","Def","SpA","SpD","Spe"].filter(function(e){return!isNaN(t[e.toLowerCase()])}).map(function(e){return t[e.toLowerCase()]+" "+e}).join(" / ")+"\n"}return this.moves&&(e+=this.moves.map(function(e){return"- "+e}).join("\n")+"\n"),e.trim()}},{key:"toString",value:function(){return this.toShowdown()}}],[{key:"fromObject",value:function(n){var t=new e;return t.name=n.name,t.nickname=n.nickname,t.gender=n.gender,t.item=n.item,t.ability=n.ability,t.level=n.level,t.shiny=n.shiny,t.happiness=n.happiness,t.nature=n.nature,t.evs=n.evs,t.ivs=n.ivs,t.moves=n.moves,t}}]),e}();n.default=r},function(e,n,t){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var i,r=function(){function e(e,n){for(var t=0;t<n.length;t++){var i=n[t];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,i.key,i)}}return function(n,t,i){return t&&e(n.prototype,t),i&&e(n,i),n}}(),o=t(0),a=(i=o)&&i.__esModule?i:{default:i};var s=function(){function e(){var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];!function(e,n){if(!(e instanceof n))throw new TypeError("Cannot call a class as a function")}(this,e),this.teams=n}return r(e,[{key:"toJson",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:2;return JSON.stringify(this,null,e)}},{key:"toShowdown",value:function(){return this.teams.map(function(e){return e.toString()}).join("\n\n").trim()}},{key:"toString",value:function(){return this.toShowdown()}}],[{key:"fromObject",value:function(n){var t=new e;return t.teams=n.teams?n.teams.map(function(e){return a.default.fromObject(e)}):[],t}}]),e}();n.default=s},function(e,n,t){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var i=function(){function e(e,n){for(var t=0;t<n.length;t++){var i=n[t];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,i.key,i)}}return function(n,t,i){return t&&e(n.prototype,t),i&&e(n,i),n}}(),r=s(t(1)),o=s(t(0)),a=s(t(2));function s(e){return e&&e.__esModule?e:{default:e}}var u=function(){function e(n){!function(e,n){if(!(e instanceof n))throw new TypeError("Cannot call a class as a function")}(this,e),this.code=n+""}return i(e,[{key:"parse",value:function(){var n=e.regexes,t=[],i={team:null,pokemon:null},s=this;return this.code.trim().split("\n").map(function(e){return e.trim()}).forEach(function(e){return e.match(n.team)?(i.team=new o.default,s._parseTeam(e,i.team),void t.push(i.team)):""===e||e.match(/^[- ]+$/)?void s._saveCurrent(t,i):i.pokemon?void(s._parseKeyValuePairs(e,i.pokemon)||s._parseEvsIvs(e,i.pokemon)||i.pokemon.moves.length<4&&e.match(n.move)&&i.pokemon.moves.push(n.move.exec(e)[1].trim())):(i.pokemon=new r.default,void s._parseNameLine(e,i.pokemon))}),this._saveCurrent(t,i),new a.default(t)}},{key:"_parseTeam",value:function(n,t){var i=e.regexes.team.exec(n),r=i[2].split("/"),o=void 0,a=void 0;r.length>1?(a=r.shift(),o=r.join("/")):o=i[2],t.format=i[1].trim(),t.name=o.trim(),t.folder=a?a.trim():void 0}},{key:"_parseNameLine",value:function(n,t){var i=e.regexes;if(n.match(i.nickname_name)){var r=i.nickname_name.exec(n);t.nickname=r[1].trim(),t.name=r[2].trim()}else if(n.match(i.name)){var o=i.name.exec(n);t.name=o[1].trim()}n.match(i.gender)&&(t.gender=i.gender.exec(n)[1].toUpperCase().trim()),n.match(i.item)&&(t.item=i.item.exec(n)[1].trim())}},{key:"_parseEvsIvs",value:function(n,t){var i=e.regexes;if(n.match(i.eivs)){var r=i.eivs.exec(n),o=r[1].toLowerCase(),a=r[2].split("/"),s="evs"===o?255:31;return a.forEach(function(e){var n=i.eivs_value.exec(e.trim().toLowerCase());n?(t[o]||(t[o]={}),t[o][n[2]]=parseFloat(n[1]),t[o][n[2]]>s&&(t[o][n[2]]=s)):console.error("Invalid syntax for "+o+": "+e)}),!0}return!1}},{key:"_parseKeyValuePairs",value:function(n,t){var i=e.regexes;return["ability","level","shiny","happiness","nature"].some(function(e){return!!n.match(i[e])&&(t[e]=i[e].exec(n)[1].trim(),isNaN(t[e])||(t[e]=parseFloat(t[e])),"happiness"===e&&t[e]>255&&(t[e]=255),"level"===e&&t[e]<1&&(t[e]=1),"level"===e&&t[e]>100&&(t[e]=100),"shiny"===e&&(t[e]=!!t[e].match(/yes/i)),!0)})}},{key:"_saveCurrent",value:function(e,n){return n.team||(n.team=new o.default,e.push(n.team)),n.pokemon&&(n.team.pokemon.push(n.pokemon),n.pokemon=null),this}},{key:"format",value:function(){return this.code=this.parse().toString(),this}},{key:"toString",value:function(){return this.code}}]),e}();u.regexes={team:/^===\s+\[(.*)\]\s+(.*)\s+===$/,gender:/\((F|M)\)/i,item:/@\s?(.*)$/i,name:/^([^()=@]{2,})/i,nickname_name:/^([^()=@]*)\s+\(([^()=@]{2,})\)/i,ability:/^Ability:\s?(.*)$/i,level:/^Level:\s?([0-9]{1,3})$/i,shiny:/^Shiny:\s?(Yes|No)$/i,happiness:/^Happiness:\s?([0-9]{1,3})$/i,eivs:/^([EI]Vs):\s?(.*)$/i,eivs_value:/^([0-9]+)\s+(hp|atk|def|spa|spd|spe)$/i,nature:/^(.*)\s+Nature$/,move:/^[-~]\s?(.*)$/i},n.default=u},function(e,n,t){"use strict";Object.defineProperty(n,"__esModule",{value:!0}),n.ShowdownParser=n.Koffing=void 0;var i=function(){function e(e,n){for(var t=0;t<n.length;t++){var i=n[t];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,i.key,i)}}return function(n,t,i){return t&&e(n.prototype,t),i&&e(n,i),n}}(),r=u(t(1)),o=u(t(0)),a=u(t(2)),s=u(t(3));function u(e){return e&&e.__esModule?e:{default:e}}var f=function(){function e(){!function(e,n){if(!(e instanceof n))throw new TypeError("Cannot call a class as a function")}(this,e)}return i(e,null,[{key:"parse",value:function(e){return e instanceof a.default||e instanceof o.default||e instanceof r.default?e:e instanceof s.default?e.parse():new s.default(e).parse()}},{key:"format",value:function(e){return this.parse(e).toShowdown()}},{key:"toJson",value:function(e){return this.parse(e).toJson()}},{key:"toShowdown",value:function(e){return e instanceof a.default||e instanceof o.default||e instanceof r.default?e.toShowdown():e instanceof s.default?e.parse().format():(("string"==typeof value||value instanceof String)&&(e=JSON.parse(e)),a.default.fromObject(JSON.parse(e)).toShowdown())}}]),e}();n.Koffing=f,n.ShowdownParser=s.default}])});
|
package/src/Pokemon.js
DELETED
|
@@ -1,174 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
class Pokemon {
|
|
4
|
-
constructor() {
|
|
5
|
-
/**
|
|
6
|
-
* @type {String}
|
|
7
|
-
*/
|
|
8
|
-
this.name = undefined;
|
|
9
|
-
/**
|
|
10
|
-
* @type {String}
|
|
11
|
-
*/
|
|
12
|
-
this.nickname = undefined;
|
|
13
|
-
/**
|
|
14
|
-
* @type {String}
|
|
15
|
-
*/
|
|
16
|
-
this.gender = undefined;
|
|
17
|
-
/**
|
|
18
|
-
* @type {String}
|
|
19
|
-
*/
|
|
20
|
-
this.item = undefined;
|
|
21
|
-
/**
|
|
22
|
-
* @type {String}
|
|
23
|
-
*/
|
|
24
|
-
this.ability = undefined;
|
|
25
|
-
/**
|
|
26
|
-
* @type {Number}
|
|
27
|
-
*/
|
|
28
|
-
this.level = undefined;
|
|
29
|
-
/**
|
|
30
|
-
* @type {boolean}
|
|
31
|
-
*/
|
|
32
|
-
this.shiny = undefined;
|
|
33
|
-
/**
|
|
34
|
-
* @type {Number}
|
|
35
|
-
*/
|
|
36
|
-
this.happiness = undefined;
|
|
37
|
-
/**
|
|
38
|
-
* @type {String}
|
|
39
|
-
*/
|
|
40
|
-
this.nature = undefined;
|
|
41
|
-
/**
|
|
42
|
-
* @type {{ hp:Number, atk:Number, def: Number, spa: Number, spd: Number, spe: Number}}
|
|
43
|
-
*/
|
|
44
|
-
this.evs = undefined;
|
|
45
|
-
/**
|
|
46
|
-
* @type {{ hp:Number, atk:Number, def: Number, spa: Number, spd: Number, spe: Number}}
|
|
47
|
-
*/
|
|
48
|
-
this.ivs = undefined;
|
|
49
|
-
/**
|
|
50
|
-
* @type {String[]}
|
|
51
|
-
*/
|
|
52
|
-
this.moves = [];
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* @param {object|Pokemon} obj
|
|
57
|
-
* @returns {Pokemon}
|
|
58
|
-
*/
|
|
59
|
-
static fromObject(obj) {
|
|
60
|
-
let p = new Pokemon();
|
|
61
|
-
p.name = obj.name;
|
|
62
|
-
p.nickname = obj.nickname;
|
|
63
|
-
p.gender = obj.gender;
|
|
64
|
-
p.item = obj.item;
|
|
65
|
-
p.ability = obj.ability;
|
|
66
|
-
p.level = obj.level;
|
|
67
|
-
p.shiny = obj.shiny;
|
|
68
|
-
p.happiness = obj.happiness;
|
|
69
|
-
p.nature = obj.nature;
|
|
70
|
-
p.evs = obj.evs;
|
|
71
|
-
p.ivs = obj.ivs;
|
|
72
|
-
p.moves = obj.moves;
|
|
73
|
-
|
|
74
|
-
return p;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* @param {Number} indentation
|
|
79
|
-
* @returns {string}
|
|
80
|
-
*/
|
|
81
|
-
toJson(indentation = 2) {
|
|
82
|
-
return JSON.stringify(this, null, indentation);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* @returns {string}
|
|
87
|
-
*/
|
|
88
|
-
toShowdown() {
|
|
89
|
-
let str = '';
|
|
90
|
-
|
|
91
|
-
if (this.nickname) {
|
|
92
|
-
str += `${this.nickname} (${this.name})`;
|
|
93
|
-
} else {
|
|
94
|
-
str += `${this.name}`;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
if (this.gender && this.gender.match(/^[MF]$/i)) {
|
|
98
|
-
str += ` (${this.gender.toUpperCase()})`;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
if (this.item) {
|
|
102
|
-
str += ` @ ${this.item}`;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
str += "\n";
|
|
106
|
-
|
|
107
|
-
if (!isNaN(this.level)) {
|
|
108
|
-
str += `Level: ${this.level}\n`;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
if (this.ability) {
|
|
112
|
-
str += `Ability: ${this.ability}\n`;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
if (this.shiny === true) {
|
|
116
|
-
str += `Shiny: Yes\n`;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
if (!isNaN(this.happiness)) {
|
|
120
|
-
str += `Happiness: ${this.happiness}\n`;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
if (this.nature) {
|
|
124
|
-
str += `${this.nature} Nature\n`;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
if (this.evs) {
|
|
128
|
-
let evs = this.evs;
|
|
129
|
-
str += `EVs: ` + ['HP', 'Atk', 'Def', 'SpA', 'SpD', 'Spe']
|
|
130
|
-
.filter(function (prop) {
|
|
131
|
-
return !isNaN(evs[prop.toLowerCase()]);
|
|
132
|
-
})
|
|
133
|
-
.map(
|
|
134
|
-
function (prop) {
|
|
135
|
-
let val = evs[prop.toLowerCase()];
|
|
136
|
-
return `${val} ${prop}`;
|
|
137
|
-
}
|
|
138
|
-
)
|
|
139
|
-
.join(' / ') + '\n';
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
if (this.ivs) {
|
|
143
|
-
let ivs = this.ivs;
|
|
144
|
-
str += `IVs: ` + ['HP', 'Atk', 'Def', 'SpA', 'SpD', 'Spe']
|
|
145
|
-
.filter(function (prop) {
|
|
146
|
-
return !isNaN(ivs[prop.toLowerCase()]);
|
|
147
|
-
})
|
|
148
|
-
.map(
|
|
149
|
-
function (prop) {
|
|
150
|
-
let val = ivs[prop.toLowerCase()];
|
|
151
|
-
return `${val} ${prop}`;
|
|
152
|
-
}
|
|
153
|
-
)
|
|
154
|
-
.join(' / ') + '\n';
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
if (this.moves) {
|
|
158
|
-
str += this.moves.map(function (move) {
|
|
159
|
-
return `- ${move}`;
|
|
160
|
-
}).join("\n") + "\n";
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
return str.trim();
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
/**
|
|
167
|
-
* @returns {string}
|
|
168
|
-
*/
|
|
169
|
-
toString() {
|
|
170
|
-
return this.toShowdown();
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
export default Pokemon;
|
package/src/PokemonTeam.js
DELETED
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
import Pokemon from "./Pokemon";
|
|
4
|
-
|
|
5
|
-
class PokemonTeam {
|
|
6
|
-
/**
|
|
7
|
-
* @param {string} format
|
|
8
|
-
* @param {string} name
|
|
9
|
-
* @param {string|undefined} folder
|
|
10
|
-
*/
|
|
11
|
-
constructor(format = 'gen7', name = 'Untitled', folder = undefined) {
|
|
12
|
-
/**
|
|
13
|
-
*
|
|
14
|
-
* @type {string}
|
|
15
|
-
*/
|
|
16
|
-
this.name = name;
|
|
17
|
-
/**
|
|
18
|
-
*
|
|
19
|
-
* @type {string}
|
|
20
|
-
*/
|
|
21
|
-
this.format = format;
|
|
22
|
-
/**
|
|
23
|
-
*
|
|
24
|
-
* @type {string|undefined}
|
|
25
|
-
*/
|
|
26
|
-
this.folder = folder;
|
|
27
|
-
/**
|
|
28
|
-
*
|
|
29
|
-
* @type {Pokemon[]}
|
|
30
|
-
*/
|
|
31
|
-
this.pokemon = [];
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* @param {object|PokemonTeam} obj
|
|
36
|
-
* @returns {PokemonTeam}
|
|
37
|
-
*/
|
|
38
|
-
static fromObject(obj) {
|
|
39
|
-
let team = new PokemonTeam();
|
|
40
|
-
team.name = obj.name;
|
|
41
|
-
team.format = obj.format;
|
|
42
|
-
team.folder = obj.folder;
|
|
43
|
-
team.pokemon = obj.pokemon ? obj.pokemon.map(function (pokemon) {
|
|
44
|
-
return Pokemon.fromObject(pokemon);
|
|
45
|
-
}) : [];
|
|
46
|
-
|
|
47
|
-
return team;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* @param {Number} indentation
|
|
52
|
-
* @returns {string}
|
|
53
|
-
*/
|
|
54
|
-
toJson(indentation = 2) {
|
|
55
|
-
return JSON.stringify(this, null, indentation);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* @returns {string}
|
|
60
|
-
*/
|
|
61
|
-
toShowdown() {
|
|
62
|
-
let name = this.folder ? `${this.folder}/${this.name}` : this.name;
|
|
63
|
-
let str = `=== [${this.format}] ${name} ===\n\n`;
|
|
64
|
-
|
|
65
|
-
str += this.pokemon.map(function (p) {
|
|
66
|
-
return p.toString();
|
|
67
|
-
}).join('\n\n');
|
|
68
|
-
|
|
69
|
-
return str.trim();
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* @returns {string}
|
|
74
|
-
*/
|
|
75
|
-
toString() {
|
|
76
|
-
return this.toShowdown();
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
export default PokemonTeam;
|
package/src/PokemonTeamSet.js
DELETED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
import PokemonTeam from "./PokemonTeam";
|
|
4
|
-
|
|
5
|
-
class PokemonTeamSet {
|
|
6
|
-
/**
|
|
7
|
-
* @param {PokemonTeam[]} teams
|
|
8
|
-
*/
|
|
9
|
-
constructor(teams = []) {
|
|
10
|
-
this.teams = teams;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* @param {object|PokemonTeamSet} obj
|
|
15
|
-
* @returns {PokemonTeamSet}
|
|
16
|
-
*/
|
|
17
|
-
static fromObject(obj) {
|
|
18
|
-
let teamSet = new PokemonTeamSet();
|
|
19
|
-
teamSet.teams = obj.teams ? obj.teams.map(function (team) {
|
|
20
|
-
return PokemonTeam.fromObject(team);
|
|
21
|
-
}) : [];
|
|
22
|
-
|
|
23
|
-
return teamSet;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* @param {Number} indentation
|
|
28
|
-
* @returns {string}
|
|
29
|
-
*/
|
|
30
|
-
toJson(indentation = 2) {
|
|
31
|
-
return JSON.stringify(this, null, indentation);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* @returns {string}
|
|
36
|
-
*/
|
|
37
|
-
toShowdown() {
|
|
38
|
-
return this.teams
|
|
39
|
-
.map(function (p) {
|
|
40
|
-
return p.toString();
|
|
41
|
-
})
|
|
42
|
-
.join('\n\n')
|
|
43
|
-
.trim();
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* @returns {string}
|
|
48
|
-
*/
|
|
49
|
-
toString() {
|
|
50
|
-
return this.toShowdown();
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
export default PokemonTeamSet;
|
package/src/ShowdownParser.js
DELETED
|
@@ -1,281 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
import Pokemon from "Pokemon";
|
|
4
|
-
import PokemonTeam from "PokemonTeam";
|
|
5
|
-
import PokemonTeamSet from "PokemonTeamSet";
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Ported from Pokemon Showdown Client's exportTeam/importTeam functions.
|
|
9
|
-
*
|
|
10
|
-
* @see https://github.com/Zarel/Pokemon-Showdown-Client/blob/8994e9e/js/storage.js
|
|
11
|
-
*/
|
|
12
|
-
class ShowdownParser {
|
|
13
|
-
/**
|
|
14
|
-
* @param {String} code
|
|
15
|
-
*/
|
|
16
|
-
constructor(code) {
|
|
17
|
-
/**
|
|
18
|
-
* @type {String}
|
|
19
|
-
*/
|
|
20
|
-
this.code = code + "";
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* @returns {PokemonTeamSet}
|
|
25
|
-
*/
|
|
26
|
-
parse() {
|
|
27
|
-
const regexes = ShowdownParser.regexes;
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* @type {PokemonTeam[]}
|
|
31
|
-
*/
|
|
32
|
-
let teams = [];
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* @type {{team: PokemonTeam, pokemon: Pokemon}}
|
|
36
|
-
*/
|
|
37
|
-
let current = {
|
|
38
|
-
team: null,
|
|
39
|
-
pokemon: null
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* @type {string[]}
|
|
44
|
-
*/
|
|
45
|
-
let lines = this.code
|
|
46
|
-
.trim()
|
|
47
|
-
.split("\n")
|
|
48
|
-
.map(function (line) {
|
|
49
|
-
return line.trim();
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
let $this = this;
|
|
53
|
-
|
|
54
|
-
lines.forEach(function (line) {
|
|
55
|
-
// New Team
|
|
56
|
-
if (line.match(regexes.team)) {
|
|
57
|
-
// Start new team
|
|
58
|
-
current.team = new PokemonTeam();
|
|
59
|
-
$this._parseTeam(line, current.team);
|
|
60
|
-
teams.push(current.team);
|
|
61
|
-
return;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
// Separator
|
|
65
|
-
if (line === '' || line.match(/^[- ]+$/)) {
|
|
66
|
-
// Line break (empty or as dashes separator), previous Pokemon definition ended.
|
|
67
|
-
$this._saveCurrent(teams, current);
|
|
68
|
-
return;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// New Pokemon + nickname, name, gender and item
|
|
72
|
-
if (!current.pokemon) {
|
|
73
|
-
current.pokemon = new Pokemon();
|
|
74
|
-
$this._parseNameLine(line, current.pokemon);
|
|
75
|
-
return;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// Ability, Level, etc.
|
|
79
|
-
if ($this._parseKeyValuePairs(line, current.pokemon)) {
|
|
80
|
-
return;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
// EVs and IVs
|
|
84
|
-
if ($this._parseEvsIvs(line, current.pokemon)) {
|
|
85
|
-
return;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
// Moves
|
|
89
|
-
if ((current.pokemon.moves.length < 4) && line.match(regexes.move)) {
|
|
90
|
-
current.pokemon.moves.push(regexes.move.exec(line)[1].trim());
|
|
91
|
-
}
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
this._saveCurrent(teams, current);
|
|
95
|
-
|
|
96
|
-
return new PokemonTeamSet(teams);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* @param {string} line
|
|
101
|
-
* @param {PokemonTeam} team
|
|
102
|
-
* @private
|
|
103
|
-
*/
|
|
104
|
-
_parseTeam(line, team) {
|
|
105
|
-
const rg = ShowdownParser.regexes;
|
|
106
|
-
|
|
107
|
-
let teamData = rg.team.exec(line);
|
|
108
|
-
let teamNames = teamData[2].split('/');
|
|
109
|
-
let teamName, teamFolder;
|
|
110
|
-
|
|
111
|
-
if (teamNames.length > 1) {
|
|
112
|
-
teamFolder = teamNames.shift();
|
|
113
|
-
teamName = teamNames.join('/');
|
|
114
|
-
} else {
|
|
115
|
-
teamName = teamData[2];
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
team.format = teamData[1].trim();
|
|
119
|
-
team.name = teamName.trim();
|
|
120
|
-
team.folder = teamFolder ? teamFolder.trim() : undefined;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
/**
|
|
124
|
-
* @param {string} line
|
|
125
|
-
* @param {Pokemon} pokemon
|
|
126
|
-
* @private
|
|
127
|
-
*/
|
|
128
|
-
_parseNameLine(line, pokemon) {
|
|
129
|
-
const rg = ShowdownParser.regexes;
|
|
130
|
-
|
|
131
|
-
if (line.match(rg.nickname_name)) { // has nickname?
|
|
132
|
-
let nameMatches = rg.nickname_name.exec(line);
|
|
133
|
-
pokemon.nickname = nameMatches[1].trim();
|
|
134
|
-
pokemon.name = nameMatches[2].trim();
|
|
135
|
-
} else if (line.match(rg.name)) {
|
|
136
|
-
let nameMatches = rg.name.exec(line);
|
|
137
|
-
pokemon.name = nameMatches[1].trim();
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
if (line.match(rg.gender)) {
|
|
141
|
-
pokemon.gender = rg.gender.exec(line)[1].toUpperCase().trim();
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
if (line.match(rg.item)) {
|
|
145
|
-
pokemon.item = rg.item.exec(line)[1].trim();
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
/**
|
|
150
|
-
* @param {string} line
|
|
151
|
-
* @param {Pokemon} pokemon
|
|
152
|
-
* @returns {boolean} True if it matched some, false otherwise
|
|
153
|
-
* @private
|
|
154
|
-
*/
|
|
155
|
-
_parseEvsIvs(line, pokemon) {
|
|
156
|
-
const rg = ShowdownParser.regexes;
|
|
157
|
-
|
|
158
|
-
if (line.match(rg.eivs)) {
|
|
159
|
-
let data = rg.eivs.exec(line);
|
|
160
|
-
let prop = data[1].toLowerCase();
|
|
161
|
-
let values = data[2].split('/');
|
|
162
|
-
let limit = prop === 'evs' ? 255 : 31;
|
|
163
|
-
|
|
164
|
-
values.forEach(function (stat) {
|
|
165
|
-
let statData = rg.eivs_value.exec(stat.trim().toLowerCase());
|
|
166
|
-
if (!statData) {
|
|
167
|
-
console.error("Invalid syntax for " + prop + ": " + stat);
|
|
168
|
-
return;
|
|
169
|
-
}
|
|
170
|
-
if (!pokemon[prop]) {
|
|
171
|
-
pokemon[prop] = {};
|
|
172
|
-
}
|
|
173
|
-
pokemon[prop][statData[2]] = parseFloat(statData[1]);
|
|
174
|
-
|
|
175
|
-
if (pokemon[prop][statData[2]] > limit) {
|
|
176
|
-
pokemon[prop][statData[2]] = limit;
|
|
177
|
-
}
|
|
178
|
-
});
|
|
179
|
-
return true;
|
|
180
|
-
}
|
|
181
|
-
return false;
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
/**
|
|
185
|
-
* @param {string} line
|
|
186
|
-
* @param {Pokemon} pokemon
|
|
187
|
-
* @returns {boolean} True if it matched some, false otherwise
|
|
188
|
-
* @private
|
|
189
|
-
*/
|
|
190
|
-
_parseKeyValuePairs(line, pokemon) {
|
|
191
|
-
const rg = ShowdownParser.regexes;
|
|
192
|
-
|
|
193
|
-
return ['ability', 'level', 'shiny', 'happiness', 'nature'].some(
|
|
194
|
-
function (key) {
|
|
195
|
-
if (line.match(rg[key])) {
|
|
196
|
-
pokemon[key] = rg[key].exec(line)[1].trim();
|
|
197
|
-
|
|
198
|
-
if (!isNaN(pokemon[key])) {
|
|
199
|
-
pokemon[key] = parseFloat(pokemon[key]);
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
if (key === 'happiness' && pokemon[key] > 255) {
|
|
203
|
-
pokemon[key] = 255;
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
if (key === 'level' && pokemon[key] < 1) {
|
|
207
|
-
pokemon[key] = 1;
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
if (key === 'level' && pokemon[key] > 100) {
|
|
211
|
-
pokemon[key] = 100;
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
if (key === 'shiny') {
|
|
215
|
-
pokemon[key] = !!pokemon[key].match(/yes/i);
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
return true;
|
|
219
|
-
}
|
|
220
|
-
return false;
|
|
221
|
-
}
|
|
222
|
-
);
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
/**
|
|
226
|
-
* Saves the current state of the parsed team.
|
|
227
|
-
*
|
|
228
|
-
* @param {Array} teams
|
|
229
|
-
* @param {{team: PokemonTeam, pokemon: Pokemon}} current
|
|
230
|
-
* @returns {ShowdownParser}
|
|
231
|
-
* @private
|
|
232
|
-
*/
|
|
233
|
-
_saveCurrent(teams, current) {
|
|
234
|
-
if (!current.team) {
|
|
235
|
-
// Create a team if there is no current one
|
|
236
|
-
current.team = new PokemonTeam();
|
|
237
|
-
teams.push(current.team);
|
|
238
|
-
}
|
|
239
|
-
if (current.pokemon) {
|
|
240
|
-
// Create a team if there is no current one
|
|
241
|
-
current.team.pokemon.push(current.pokemon);
|
|
242
|
-
current.pokemon = null;
|
|
243
|
-
}
|
|
244
|
-
return this;
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
/**
|
|
248
|
-
* Sanitizes and re-formats / prettifies the Showdown code
|
|
249
|
-
*
|
|
250
|
-
* @returns {ShowdownParser}
|
|
251
|
-
*/
|
|
252
|
-
format() {
|
|
253
|
-
this.code = this.parse().toString();
|
|
254
|
-
return this;
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
/**
|
|
258
|
-
* @returns {string}
|
|
259
|
-
*/
|
|
260
|
-
toString() {
|
|
261
|
-
return this.code;
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
ShowdownParser.regexes = {
|
|
266
|
-
team: /^===\s+\[(.*)\]\s+(.*)\s+===$/,
|
|
267
|
-
gender: /\((F|M)\)/i,
|
|
268
|
-
item: /@\s?(.*)$/i,
|
|
269
|
-
name: /^([^()=@]{2,})/i,
|
|
270
|
-
nickname_name: /^([^()=@]*)\s+\(([^()=@]{2,})\)/i,
|
|
271
|
-
ability: /^Ability:\s?(.*)$/i,
|
|
272
|
-
level: /^Level:\s?([0-9]{1,3})$/i,
|
|
273
|
-
shiny: /^Shiny:\s?(Yes|No)$/i,
|
|
274
|
-
happiness: /^Happiness:\s?([0-9]{1,3})$/i,
|
|
275
|
-
eivs: /^([EI]Vs):\s?(.*)$/i,
|
|
276
|
-
eivs_value: /^([0-9]+)\s+(hp|atk|def|spa|spd|spe)$/i,
|
|
277
|
-
nature: /^(.*)\s+Nature$/,
|
|
278
|
-
move: /^[-~]\s?(.*)$/i
|
|
279
|
-
};
|
|
280
|
-
|
|
281
|
-
export default ShowdownParser;
|
package/src/index.js
DELETED
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
import Pokemon from "Pokemon";
|
|
4
|
-
import PokemonTeam from "PokemonTeam";
|
|
5
|
-
import PokemonTeamSet from "PokemonTeamSet";
|
|
6
|
-
import ShowdownParser from "ShowdownParser";
|
|
7
|
-
|
|
8
|
-
class Koffing {
|
|
9
|
-
/**
|
|
10
|
-
* Converts from Showdown to a PokemonTeamSet object.
|
|
11
|
-
*
|
|
12
|
-
* @param {String|Pokemon|PokemonTeam|PokemonTeamSet|ShowdownParser} data Showdown code or object
|
|
13
|
-
* @returns {PokemonTeamSet}
|
|
14
|
-
*/
|
|
15
|
-
static parse(data) {
|
|
16
|
-
if (
|
|
17
|
-
data instanceof PokemonTeamSet
|
|
18
|
-
|| data instanceof PokemonTeam
|
|
19
|
-
|| data instanceof Pokemon
|
|
20
|
-
) {
|
|
21
|
-
return data;
|
|
22
|
-
}
|
|
23
|
-
if (data instanceof ShowdownParser) {
|
|
24
|
-
return data.parse();
|
|
25
|
-
}
|
|
26
|
-
return (new ShowdownParser(data)).parse();
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Prettifies and sanitizes the given Showdown code.
|
|
31
|
-
*
|
|
32
|
-
* @param {String|Pokemon|PokemonTeam|PokemonTeamSet|ShowdownParser} data Showdown code or object
|
|
33
|
-
* @returns {String}
|
|
34
|
-
*/
|
|
35
|
-
static format(data) {
|
|
36
|
-
return this.parse(data).toShowdown();
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Converts from Showdown to JSON code.
|
|
41
|
-
*
|
|
42
|
-
* @param {String|Pokemon|PokemonTeam|PokemonTeamSet|ShowdownParser} data Showdown code or object
|
|
43
|
-
* @returns {String}
|
|
44
|
-
*/
|
|
45
|
-
static toJson(data) {
|
|
46
|
-
return this.parse(data).toJson();
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Converts from JSON to Showdown code.
|
|
51
|
-
*
|
|
52
|
-
* @param {String|Object|Pokemon|PokemonTeam|PokemonTeamSet|ShowdownParser} data JSON code or object
|
|
53
|
-
* @returns {String}
|
|
54
|
-
*/
|
|
55
|
-
static toShowdown(data) {
|
|
56
|
-
if (
|
|
57
|
-
data instanceof PokemonTeamSet
|
|
58
|
-
|| data instanceof PokemonTeam
|
|
59
|
-
|| data instanceof Pokemon
|
|
60
|
-
) {
|
|
61
|
-
return data.toShowdown();
|
|
62
|
-
}
|
|
63
|
-
if (data instanceof ShowdownParser) {
|
|
64
|
-
return data.parse().format();
|
|
65
|
-
}
|
|
66
|
-
if (typeof value === 'string' || value instanceof String) {
|
|
67
|
-
data = JSON.parse(data);
|
|
68
|
-
}
|
|
69
|
-
return PokemonTeamSet.fromObject(JSON.parse(data)).toShowdown();
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
export {
|
|
74
|
-
Koffing,
|
|
75
|
-
ShowdownParser
|
|
76
|
-
};
|