UNPKG

72.3 kBJavaScriptView Raw
1/*! mockjs 18-06-2014 04:36:07 */
2/*! src/mock-prefix.js */
3/*!
4 Mock - 模拟请求 & 模拟数据
5 https://github.com/nuysoft/Mock
6 墨智 mozhi.gyy@taobao.com nuysoft@gmail.com
7*/
8(function(undefined) {
9 var Mock = {
10 version: "0.1.2",
11 _mocked: {}
12 };
13 /*! src/util.js */
14 var Util = function() {
15 var Util = {};
16 Util.extend = function extend() {
17 var target = arguments[0] || {}, i = 1, length = arguments.length, options, name, src, copy, clone;
18 if (length === 1) {
19 target = this;
20 i = 0;
21 }
22 for (;i < length; i++) {
23 options = arguments[i];
24 if (!options) continue;
25 for (name in options) {
26 src = target[name];
27 copy = options[name];
28 if (target === copy) continue;
29 if (copy === undefined) continue;
30 if (Util.isArray(copy) || Util.isObject(copy)) {
31 if (Util.isArray(copy)) clone = src && Util.isArray(src) ? src : [];
32 if (Util.isObject(copy)) clone = src && Util.isObject(src) ? src : {};
33 target[name] = Util.extend(clone, copy);
34 } else {
35 target[name] = copy;
36 }
37 }
38 }
39 return target;
40 };
41 Util.each = function each(obj, iterator, context) {
42 var i, key;
43 if (this.type(obj) === "number") {
44 for (i = 0; i < obj; i++) {
45 iterator(i, i);
46 }
47 } else if (obj.length === +obj.length) {
48 for (i = 0; i < obj.length; i++) {
49 if (iterator.call(context, obj[i], i, obj) === false) break;
50 }
51 } else {
52 for (key in obj) {
53 if (iterator.call(context, obj[key], key, obj) === false) break;
54 }
55 }
56 };
57 Util.type = function type(obj) {
58 return obj === null || obj === undefined ? String(obj) : Object.prototype.toString.call(obj).match(/\[object (\w+)\]/)[1].toLowerCase();
59 };
60 Util.each("String Object Array RegExp Function".split(" "), function(value) {
61 Util["is" + value] = function(obj) {
62 return Util.type(obj) === value.toLowerCase();
63 };
64 });
65 Util.isObjectOrArray = function(value) {
66 return Util.isObject(value) || Util.isArray(value);
67 };
68 Util.isNumeric = function(value) {
69 return !isNaN(parseFloat(value)) && isFinite(value);
70 };
71 Util.keys = function(obj) {
72 var keys = [];
73 for (var key in obj) {
74 if (obj.hasOwnProperty(key)) keys.push(key);
75 }
76 return keys;
77 };
78 Util.values = function(obj) {
79 var values = [];
80 for (var key in obj) {
81 if (obj.hasOwnProperty(key)) values.push(obj[key]);
82 }
83 return values;
84 };
85 Util.heredoc = function heredoc(fn) {
86 return fn.toString().replace(/^[^\/]+\/\*!?/, "").replace(/\*\/[^\/]+$/, "").replace(/^[\s\xA0]+/, "").replace(/[\s\xA0]+$/, "");
87 };
88 Util.noop = function() {};
89 return Util;
90 }();
91 /*! src/random.js */
92 var Random = function() {
93 var Random = {
94 extend: Util.extend
95 };
96 Random.extend({
97 "boolean": function(min, max, cur) {
98 if (cur !== undefined) {
99 min = typeof min !== "undefined" && !isNaN(min) ? parseInt(min, 10) : 1;
100 max = typeof max !== "undefined" && !isNaN(max) ? parseInt(max, 10) : 1;
101 return Math.random() > 1 / (min + max) * min ? !cur : cur;
102 }
103 return Math.random() >= .5;
104 },
105 bool: function(min, max, cur) {
106 return this.boolean(min, max, cur);
107 },
108 natural: function(min, max) {
109 min = typeof min !== "undefined" ? parseInt(min, 10) : 0;
110 max = typeof max !== "undefined" ? parseInt(max, 10) : 9007199254740992;
111 return Math.round(Math.random() * (max - min)) + min;
112 },
113 integer: function(min, max) {
114 min = typeof min !== "undefined" ? parseInt(min, 10) : -9007199254740992;
115 max = typeof max !== "undefined" ? parseInt(max, 10) : 9007199254740992;
116 return Math.round(Math.random() * (max - min)) + min;
117 },
118 "int": function(min, max) {
119 return this.integer(min, max);
120 },
121 "float": function(min, max, dmin, dmax) {
122 dmin = dmin === undefined ? 0 : dmin;
123 dmin = Math.max(Math.min(dmin, 17), 0);
124 dmax = dmax === undefined ? 17 : dmax;
125 dmax = Math.max(Math.min(dmax, 17), 0);
126 var ret = this.integer(min, max) + ".";
127 for (var i = 0, dcount = this.natural(dmin, dmax); i < dcount; i++) {
128 ret += this.character("number");
129 }
130 return parseFloat(ret, 10);
131 },
132 character: function(pool) {
133 var pools = {
134 lower: "abcdefghijklmnopqrstuvwxyz",
135 upper: "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
136 number: "0123456789",
137 symbol: "!@#$%^&*()[]"
138 };
139 pools.alpha = pools.lower + pools.upper;
140 pools["undefined"] = pools.lower + pools.upper + pools.number + pools.symbol;
141 pool = pools[("" + pool).toLowerCase()] || pool;
142 return pool.charAt(Random.natural(0, pool.length - 1));
143 },
144 "char": function(pool) {
145 return this.character(pool);
146 },
147 string: function(pool, min, max) {
148 var length;
149 if (arguments.length === 3) {
150 length = Random.natural(min, max);
151 }
152 if (arguments.length === 2) {
153 if (typeof arguments[0] === "string") {
154 length = min;
155 } else {
156 length = Random.natural(pool, min);
157 pool = undefined;
158 }
159 }
160 if (arguments.length === 1) {
161 length = pool;
162 pool = undefined;
163 }
164 if (arguments.length === 0) {
165 length = Random.natural(3, 7);
166 }
167 var text = "";
168 for (var i = 0; i < length; i++) {
169 text += Random.character(pool);
170 }
171 return text;
172 },
173 str: function(pool, min, max) {
174 return this.string(pool, min, max);
175 },
176 range: function(start, stop, step) {
177 if (arguments.length <= 1) {
178 stop = start || 0;
179 start = 0;
180 }
181 step = arguments[2] || 1;
182 start = +start, stop = +stop, step = +step;
183 var len = Math.max(Math.ceil((stop - start) / step), 0);
184 var idx = 0;
185 var range = new Array(len);
186 while (idx < len) {
187 range[idx++] = start;
188 start += step;
189 }
190 return range;
191 }
192 });
193 Random.extend({
194 patternLetters: {
195 yyyy: "getFullYear",
196 yy: function(date) {
197 return ("" + date.getFullYear()).slice(2);
198 },
199 y: "yy",
200 MM: function(date) {
201 var m = date.getMonth() + 1;
202 return m < 10 ? "0" + m : m;
203 },
204 M: function(date) {
205 return date.getMonth() + 1;
206 },
207 dd: function(date) {
208 var d = date.getDate();
209 return d < 10 ? "0" + d : d;
210 },
211 d: "getDate",
212 HH: function(date) {
213 var h = date.getHours();
214 return h < 10 ? "0" + h : h;
215 },
216 H: "getHours",
217 hh: function(date) {
218 var h = date.getHours() % 12;
219 return h < 10 ? "0" + h : h;
220 },
221 h: function(date) {
222 return date.getHours() % 12;
223 },
224 mm: function(date) {
225 var m = date.getMinutes();
226 return m < 10 ? "0" + m : m;
227 },
228 m: "getMinutes",
229 ss: function(date) {
230 var s = date.getSeconds();
231 return s < 10 ? "0" + s : s;
232 },
233 s: "getSeconds",
234 SS: function(date) {
235 var ms = date.getMilliseconds();
236 return ms < 10 && "00" + ms || ms < 100 && "0" + ms || ms;
237 },
238 S: "getMilliseconds",
239 A: function(date) {
240 return date.getHours() < 12 ? "AM" : "PM";
241 },
242 a: function(date) {
243 return date.getHours() < 12 ? "am" : "pm";
244 },
245 T: "getTime"
246 }
247 });
248 Random.extend({
249 rformat: new RegExp(function() {
250 var re = [];
251 for (var i in Random.patternLetters) re.push(i);
252 return "(" + re.join("|") + ")";
253 }(), "g"),
254 format: function(date, format) {
255 var patternLetters = Random.patternLetters, rformat = Random.rformat;
256 return format.replace(rformat, function($0, flag) {
257 return typeof patternLetters[flag] === "function" ? patternLetters[flag](date) : patternLetters[flag] in patternLetters ? arguments.callee($0, patternLetters[flag]) : date[patternLetters[flag]]();
258 });
259 },
260 randomDate: function(min, max) {
261 min = min === undefined ? new Date(0) : min;
262 max = max === undefined ? new Date() : max;
263 return new Date(Math.random() * (max.getTime() - min.getTime()));
264 },
265 date: function(format) {
266 format = format || "yyyy-MM-dd";
267 return this.format(this.randomDate(), format);
268 },
269 time: function(format) {
270 format = format || "HH:mm:ss";
271 return this.format(this.randomDate(), format);
272 },
273 datetime: function(format) {
274 format = format || "yyyy-MM-dd HH:mm:ss";
275 return this.format(this.randomDate(), format);
276 },
277 now: function(unit, format) {
278 if (arguments.length === 1) {
279 if (!/year|month|week|day|hour|minute|second|week/.test(unit)) {
280 format = unit;
281 unit = "";
282 }
283 }
284 unit = (unit || "").toLowerCase();
285 format = format || "yyyy-MM-dd HH:mm:ss";
286 var date = new Date();
287 switch (unit) {
288 case "year":
289 date.setMonth(0);
290
291 case "month":
292 date.setDate(1);
293
294 case "week":
295 case "day":
296 date.setHours(0);
297
298 case "hour":
299 date.setMinutes(0);
300
301 case "minute":
302 date.setSeconds(0);
303
304 case "second":
305 date.setMilliseconds(0);
306 }
307 switch (unit) {
308 case "week":
309 date.setDate(date.getDate() - date.getDay());
310 }
311 return this.format(date, format);
312 }
313 });
314 Random.extend({
315 ad_size: [ "300x250", "250x250", "240x400", "336x280", "180x150", "720x300", "468x60", "234x60", "88x31", "120x90", "120x60", "120x240", "125x125", "728x90", "160x600", "120x600", "300x600" ],
316 screen_size: [ "320x200", "320x240", "640x480", "800x480", "800x480", "1024x600", "1024x768", "1280x800", "1440x900", "1920x1200", "2560x1600" ],
317 video_size: [ "720x480", "768x576", "1280x720", "1920x1080" ],
318 image: function(size, background, foreground, format, text) {
319 if (arguments.length === 4) {
320 text = format;
321 format = undefined;
322 }
323 if (arguments.length === 3) {
324 text = foreground;
325 foreground = undefined;
326 }
327 if (!size) size = this.pick(this.ad_size);
328 if (background && ~background.indexOf("#")) background = background.slice(1);
329 if (foreground && ~foreground.indexOf("#")) foreground = foreground.slice(1);
330 return "http://dummyimage.com/" + size + (background ? "/" + background : "") + (foreground ? "/" + foreground : "") + (format ? "." + format : "") + (text ? "&text=" + text : "");
331 },
332 img: function() {
333 return this.image.apply(this, arguments);
334 }
335 });
336 Random.extend({
337 brandColors: {
338 "4ormat": "#fb0a2a",
339 "500px": "#02adea",
340 "About.me (blue)": "#00405d",
341 "About.me (yellow)": "#ffcc33",
342 Addvocate: "#ff6138",
343 Adobe: "#ff0000",
344 Aim: "#fcd20b",
345 Amazon: "#e47911",
346 Android: "#a4c639",
347 "Angie's List": "#7fbb00",
348 AOL: "#0060a3",
349 Atlassian: "#003366",
350 Behance: "#053eff",
351 "Big Cartel": "#97b538",
352 bitly: "#ee6123",
353 Blogger: "#fc4f08",
354 Boeing: "#0039a6",
355 "Booking.com": "#003580",
356 Carbonmade: "#613854",
357 Cheddar: "#ff7243",
358 "Code School": "#3d4944",
359 Delicious: "#205cc0",
360 Dell: "#3287c1",
361 Designmoo: "#e54a4f",
362 Deviantart: "#4e6252",
363 "Designer News": "#2d72da",
364 Devour: "#fd0001",
365 DEWALT: "#febd17",
366 "Disqus (blue)": "#59a3fc",
367 "Disqus (orange)": "#db7132",
368 Dribbble: "#ea4c89",
369 Dropbox: "#3d9ae8",
370 Drupal: "#0c76ab",
371 Dunked: "#2a323a",
372 eBay: "#89c507",
373 Ember: "#f05e1b",
374 Engadget: "#00bdf6",
375 Envato: "#528036",
376 Etsy: "#eb6d20",
377 Evernote: "#5ba525",
378 "Fab.com": "#dd0017",
379 Facebook: "#3b5998",
380 Firefox: "#e66000",
381 "Flickr (blue)": "#0063dc",
382 "Flickr (pink)": "#ff0084",
383 Forrst: "#5b9a68",
384 Foursquare: "#25a0ca",
385 Garmin: "#007cc3",
386 GetGlue: "#2d75a2",
387 Gimmebar: "#f70078",
388 GitHub: "#171515",
389 "Google Blue": "#0140ca",
390 "Google Green": "#16a61e",
391 "Google Red": "#dd1812",
392 "Google Yellow": "#fcca03",
393 "Google+": "#dd4b39",
394 Grooveshark: "#f77f00",
395 Groupon: "#82b548",
396 "Hacker News": "#ff6600",
397 HelloWallet: "#0085ca",
398 "Heroku (light)": "#c7c5e6",
399 "Heroku (dark)": "#6567a5",
400 HootSuite: "#003366",
401 Houzz: "#73ba37",
402 HTML5: "#ec6231",
403 IKEA: "#ffcc33",
404 IMDb: "#f3ce13",
405 Instagram: "#3f729b",
406 Intel: "#0071c5",
407 Intuit: "#365ebf",
408 Kickstarter: "#76cc1e",
409 kippt: "#e03500",
410 Kodery: "#00af81",
411 LastFM: "#c3000d",
412 LinkedIn: "#0e76a8",
413 Livestream: "#cf0005",
414 Lumo: "#576396",
415 Mixpanel: "#a086d3",
416 Meetup: "#e51937",
417 Nokia: "#183693",
418 NVIDIA: "#76b900",
419 Opera: "#cc0f16",
420 Path: "#e41f11",
421 "PayPal (dark)": "#1e477a",
422 "PayPal (light)": "#3b7bbf",
423 Pinboard: "#0000e6",
424 Pinterest: "#c8232c",
425 PlayStation: "#665cbe",
426 Pocket: "#ee4056",
427 Prezi: "#318bff",
428 Pusha: "#0f71b4",
429 Quora: "#a82400",
430 "QUOTE.fm": "#66ceff",
431 Rdio: "#008fd5",
432 Readability: "#9c0000",
433 "Red Hat": "#cc0000",
434 Resource: "#7eb400",
435 Rockpack: "#0ba6ab",
436 Roon: "#62b0d9",
437 RSS: "#ee802f",
438 Salesforce: "#1798c1",
439 Samsung: "#0c4da2",
440 Shopify: "#96bf48",
441 Skype: "#00aff0",
442 Snagajob: "#f47a20",
443 Softonic: "#008ace",
444 SoundCloud: "#ff7700",
445 "Space Box": "#f86960",
446 Spotify: "#81b71a",
447 Sprint: "#fee100",
448 Squarespace: "#121212",
449 StackOverflow: "#ef8236",
450 Staples: "#cc0000",
451 "Status Chart": "#d7584f",
452 Stripe: "#008cdd",
453 StudyBlue: "#00afe1",
454 StumbleUpon: "#f74425",
455 "T-Mobile": "#ea0a8e",
456 Technorati: "#40a800",
457 "The Next Web": "#ef4423",
458 Treehouse: "#5cb868",
459 Trulia: "#5eab1f",
460 Tumblr: "#34526f",
461 "Twitch.tv": "#6441a5",
462 Twitter: "#00acee",
463 TYPO3: "#ff8700",
464 Ubuntu: "#dd4814",
465 Ustream: "#3388ff",
466 Verizon: "#ef1d1d",
467 Vimeo: "#86c9ef",
468 Vine: "#00a478",
469 Virb: "#06afd8",
470 "Virgin Media": "#cc0000",
471 Wooga: "#5b009c",
472 "WordPress (blue)": "#21759b",
473 "WordPress (orange)": "#d54e21",
474 "WordPress (grey)": "#464646",
475 Wunderlist: "#2b88d9",
476 XBOX: "#9bc848",
477 XING: "#126567",
478 "Yahoo!": "#720e9e",
479 Yandex: "#ffcc00",
480 Yelp: "#c41200",
481 YouTube: "#c4302b",
482 Zalongo: "#5498dc",
483 Zendesk: "#78a300",
484 Zerply: "#9dcc7a",
485 Zootool: "#5e8b1d"
486 },
487 brands: function() {
488 var brands = [];
489 for (var b in this.brandColors) {
490 brands.push(b);
491 }
492 return brands;
493 },
494 dataImage: function(size, text) {
495 var canvas = typeof document !== "undefined" && document.createElement("canvas"), ctx = canvas && canvas.getContext && canvas.getContext("2d");
496 if (!canvas || !ctx) return "";
497 if (!size) size = this.pick(this.ad_size);
498 text = text !== undefined ? text : size;
499 size = size.split("x");
500 var width = parseInt(size[0], 10), height = parseInt(size[1], 10), background = this.brandColors[this.pick(this.brands())], foreground = "#FFF", text_height = 14, font = "sans-serif";
501 canvas.width = width;
502 canvas.height = height;
503 ctx.textAlign = "center";
504 ctx.textBaseline = "middle";
505 ctx.fillStyle = background;
506 ctx.fillRect(0, 0, width, height);
507 ctx.fillStyle = foreground;
508 ctx.font = "bold " + text_height + "px " + font;
509 ctx.fillText(text, width / 2, height / 2, width);
510 return canvas.toDataURL("image/png");
511 }
512 });
513 Random.extend({
514 color: function() {
515 var colour = Math.floor(Math.random() * (16 * 16 * 16 * 16 * 16 * 16 - 1)).toString(16);
516 colour = "#" + ("000000" + colour).slice(-6);
517 return colour;
518 }
519 });
520 Random.extend({
521 capitalize: function(word) {
522 return (word + "").charAt(0).toUpperCase() + (word + "").substr(1);
523 },
524 upper: function(str) {
525 return (str + "").toUpperCase();
526 },
527 lower: function(str) {
528 return (str + "").toLowerCase();
529 },
530 pick: function(arr) {
531 arr = arr || [];
532 return arr[this.natural(0, arr.length - 1)];
533 },
534 shuffle: function(arr) {
535 arr = arr || [];
536 var old = arr.slice(0), result = [], index = 0, length = old.length;
537 for (var i = 0; i < length; i++) {
538 index = this.natural(0, old.length - 1);
539 result.push(old[index]);
540 old.splice(index, 1);
541 }
542 return result;
543 }
544 });
545 Random.extend({
546 paragraph: function(min, max) {
547 var len;
548 if (arguments.length === 0) len = Random.natural(3, 7);
549 if (arguments.length === 1) len = max = min;
550 if (arguments.length === 2) {
551 min = parseInt(min, 10);
552 max = parseInt(max, 10);
553 len = Random.natural(min, max);
554 }
555 var arr = [];
556 for (var i = 0; i < len; i++) {
557 arr.push(Random.sentence());
558 }
559 return arr.join(" ");
560 },
561 sentence: function(min, max) {
562 var len;
563 if (arguments.length === 0) len = Random.natural(12, 18);
564 if (arguments.length === 1) len = max = min;
565 if (arguments.length === 2) {
566 min = parseInt(min, 10);
567 max = parseInt(max, 10);
568 len = Random.natural(min, max);
569 }
570 var arr = [];
571 for (var i = 0; i < len; i++) {
572 arr.push(Random.word());
573 }
574 return Random.capitalize(arr.join(" ")) + ".";
575 },
576 word: function(min, max) {
577 var len;
578 if (arguments.length === 0) len = Random.natural(3, 10);
579 if (arguments.length === 1) len = max = min;
580 if (arguments.length === 2) {
581 min = parseInt(min, 10);
582 max = parseInt(max, 10);
583 len = Random.natural(min, max);
584 }
585 var result = "";
586 for (var i = 0; i < len; i++) {
587 result += Random.character("lower");
588 }
589 return result;
590 },
591 title: function(min, max) {
592 var len, result = [];
593 if (arguments.length === 0) len = Random.natural(3, 7);
594 if (arguments.length === 1) len = max = min;
595 if (arguments.length === 2) {
596 min = parseInt(min, 10);
597 max = parseInt(max, 10);
598 len = Random.natural(min, max);
599 }
600 for (var i = 0; i < len; i++) {
601 result.push(this.capitalize(this.word()));
602 }
603 return result.join(" ");
604 }
605 });
606 Random.extend({
607 first: function() {
608 var names = [ "James", "John", "Robert", "Michael", "William", "David", "Richard", "Charles", "Joseph", "Thomas", "Christopher", "Daniel", "Paul", "Mark", "Donald", "George", "Kenneth", "Steven", "Edward", "Brian", "Ronald", "Anthony", "Kevin", "Jason", "Matthew", "Gary", "Timothy", "Jose", "Larry", "Jeffrey", "Frank", "Scott", "Eric" ].concat([ "Mary", "Patricia", "Linda", "Barbara", "Elizabeth", "Jennifer", "Maria", "Susan", "Margaret", "Dorothy", "Lisa", "Nancy", "Karen", "Betty", "Helen", "Sandra", "Donna", "Carol", "Ruth", "Sharon", "Michelle", "Laura", "Sarah", "Kimberly", "Deborah", "Jessica", "Shirley", "Cynthia", "Angela", "Melissa", "Brenda", "Amy", "Anna" ]);
609 return this.pick(names);
610 return this.capitalize(this.word());
611 },
612 last: function() {
613 var names = [ "Smith", "Johnson", "Williams", "Brown", "Jones", "Miller", "Davis", "Garcia", "Rodriguez", "Wilson", "Martinez", "Anderson", "Taylor", "Thomas", "Hernandez", "Moore", "Martin", "Jackson", "Thompson", "White", "Lopez", "Lee", "Gonzalez", "Harris", "Clark", "Lewis", "Robinson", "Walker", "Perez", "Hall", "Young", "Allen" ];
614 return this.pick(names);
615 return this.capitalize(this.word());
616 },
617 name: function(middle) {
618 return this.first() + " " + (middle ? this.first() + " " : "") + this.last();
619 }
620 });
621 Random.extend({
622 url: function() {
623 return "http://" + this.domain() + "/" + this.word();
624 },
625 domain: function(tld) {
626 return this.word() + "." + (tld || this.tld());
627 },
628 email: function(domain) {
629 return this.character("lower") + "." + this.last().toLowerCase() + "@" + this.last().toLowerCase() + "." + this.tld();
630 return this.word() + "@" + (domain || this.domain());
631 },
632 ip: function() {
633 return this.natural(0, 255) + "." + this.natural(0, 255) + "." + this.natural(0, 255) + "." + this.natural(0, 255);
634 },
635 tlds: [ "com", "org", "edu", "gov", "co.uk", "net", "io" ],
636 tld: function() {
637 return this.pick(this.tlds);
638 }
639 });
640 Random.extend({
641 areas: [ "东北", "华北", "华东", "华中", "华南", "西南", "西北" ],
642 area: function() {
643 return this.pick(this.areas);
644 },
645 regions: [ "110000 北京市", "120000 天津市", "130000 河北省", "140000 山西省", "150000 内蒙古自治区", "210000 辽宁省", "220000 吉林省", "230000 黑龙江省", "310000 上海市", "320000 江苏省", "330000 浙江省", "340000 安徽省", "350000 福建省", "360000 江西省", "370000 山东省", "410000 河南省", "420000 湖北省", "430000 湖南省", "440000 广东省", "450000 广西壮族自治区", "460000 海南省", "500000 重庆市", "510000 四川省", "520000 贵州省", "530000 云南省", "540000 西藏自治区", "610000 陕西省", "620000 甘肃省", "630000 青海省", "640000 宁夏回族自治区", "650000 新疆维吾尔自治区", "650000 新疆维吾尔自治区", "710000 台湾省", "810000 香港特别行政区", "820000 澳门特别行政区" ],
646 region: function() {
647 return this.pick(this.regions).split(" ")[1];
648 },
649 address: function() {},
650 city: function() {},
651 phone: function() {},
652 areacode: function() {},
653 street: function() {},
654 street_suffixes: function() {},
655 street_suffix: function() {},
656 states: function() {},
657 state: function() {},
658 zip: function(len) {
659 var zip = "";
660 for (var i = 0; i < (len || 6); i++) zip += this.natural(0, 9);
661 return zip;
662 }
663 });
664 Random.extend({
665 todo: function() {
666 return "todo";
667 }
668 });
669 Random.extend({
670 d4: function() {
671 return this.natural(1, 4);
672 },
673 d6: function() {
674 return this.natural(1, 6);
675 },
676 d8: function() {
677 return this.natural(1, 8);
678 },
679 d12: function() {
680 return this.natural(1, 12);
681 },
682 d20: function() {
683 return this.natural(1, 20);
684 },
685 d100: function() {
686 return this.natural(1, 100);
687 },
688 guid: function() {
689 var pool = "ABCDEF1234567890", guid = this.string(pool, 8) + "-" + this.string(pool, 4) + "-" + this.string(pool, 4) + "-" + this.string(pool, 4) + "-" + this.string(pool, 12);
690 return guid;
691 },
692 id: function() {
693 var id, sum = 0, rank = [ "7", "9", "10", "5", "8", "4", "2", "1", "6", "3", "7", "9", "10", "5", "8", "4", "2" ], last = [ "1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2" ];
694 id = this.pick(this.regions).split(" ")[0] + this.date("yyyyMMdd") + this.string("number", 3);
695 for (var i = 0; i < id.length; i++) {
696 sum += id[i] * rank[i];
697 }
698 id += last[sum % 11];
699 return id;
700 },
701 autoIncrementInteger: 0,
702 increment: function(step) {
703 return this.autoIncrementInteger += +step || 1;
704 },
705 inc: function(step) {
706 return this.increment(step);
707 }
708 });
709 return Random;
710 }();
711 /*! src/mock.js */
712 var rkey = /(.+)\|(?:\+(\d+)|([\+\-]?\d+-?[\+\-]?\d*)?(?:\.(\d+-?\d*))?)/, rrange = /([\+\-]?\d+)-?([\+\-]?\d+)?/, rplaceholder = /\\*@([^@#%&()\?\s\/\.]+)(?:\((.*?)\))?/g;
713 Mock.extend = Util.extend;
714 Mock.mock = function(rurl, rtype, template) {
715 if (arguments.length === 1) {
716 return Handle.gen(rurl);
717 }
718 if (arguments.length === 2) {
719 template = rtype;
720 rtype = undefined;
721 }
722 Mock._mocked[rurl + (rtype || "")] = {
723 rurl: rurl,
724 rtype: rtype,
725 template: template
726 };
727 return Mock;
728 };
729 var Handle = {
730 extend: Util.extend
731 };
732 Handle.rule = function(name) {
733 name = (name || "") + "";
734 var parameters = (name || "").match(rkey), range = parameters && parameters[3] && parameters[3].match(rrange), min = range && parseInt(range[1], 10), max = range && parseInt(range[2], 10), count = range ? !range[2] && parseInt(range[1], 10) || Random.integer(min, max) : 1, decimal = parameters && parameters[4] && parameters[4].match(rrange), dmin = decimal && parseInt(decimal[1], 10), dmax = decimal && parseInt(decimal[2], 10), dcount = decimal ? !decimal[2] && parseInt(decimal[1], 10) || Random.integer(dmin, dmax) : 0, point = parameters && parameters[4];
735 return {
736 parameters: parameters,
737 range: range,
738 min: min,
739 max: max,
740 count: count,
741 decimal: decimal,
742 dmin: dmin,
743 dmax: dmax,
744 dcount: dcount,
745 point: point
746 };
747 };
748 Handle.gen = function(template, name, context) {
749 name = name = (name || "") + "";
750 context = context || {};
751 context = {
752 path: context.path || [],
753 templatePath: context.templatePath || [],
754 currentContext: context.currentContext,
755 templateCurrentContext: context.templateCurrentContext || template,
756 root: context.root,
757 templateRoot: context.templateRoot
758 };
759 var rule = Handle.rule(name);
760 var type = Util.type(template);
761 if (Handle[type]) {
762 return Handle[type]({
763 type: type,
764 template: template,
765 name: name,
766 parsedName: name ? name.replace(rkey, "$1") : name,
767 rule: rule,
768 context: context
769 });
770 }
771 return template;
772 };
773 Handle.extend({
774 array: function(options) {
775 var result = [], i, j;
776 if (!options.rule.parameters) {
777 for (i = 0; i < options.template.length; i++) {
778 options.context.path.push(i);
779 result.push(Handle.gen(options.template[i], i, {
780 currentContext: result,
781 templateCurrentContext: options.template,
782 path: options.context.path
783 }));
784 options.context.path.pop();
785 }
786 } else {
787 if (options.rule.count === 1 && options.template.length > 1) {
788 options.context.path.push(options.name);
789 result = Random.pick(Handle.gen(options.template, undefined, {
790 currentContext: result,
791 templateCurrentContext: options.template,
792 path: options.context.path
793 }));
794 options.context.path.pop();
795 } else {
796 for (i = 0; i < options.rule.count; i++) {
797 j = 0;
798 do {
799 result.push(Handle.gen(options.template[j++]));
800 } while (j < options.template.length);
801 }
802 }
803 }
804 return result;
805 },
806 object: function(options) {
807 var result = {}, keys, fnKeys, key, parsedKey, inc, i;
808 if (options.rule.min) {
809 keys = Util.keys(options.template);
810 keys = Random.shuffle(keys);
811 keys = keys.slice(0, options.rule.count);
812 for (i = 0; i < keys.length; i++) {
813 key = keys[i];
814 parsedKey = key.replace(rkey, "$1");
815 options.context.path.push(parsedKey);
816 result[parsedKey] = Handle.gen(options.template[key], key, {
817 currentContext: result,
818 templateCurrentContext: options.template,
819 path: options.context.path
820 });
821 options.context.path.pop();
822 }
823 } else {
824 keys = [];
825 fnKeys = [];
826 for (key in options.template) {
827 (typeof options.template[key] === "function" ? fnKeys : keys).push(key);
828 }
829 keys = keys.concat(fnKeys);
830 for (i = 0; i < keys.length; i++) {
831 key = keys[i];
832 parsedKey = key.replace(rkey, "$1");
833 options.context.path.push(parsedKey);
834 result[parsedKey] = Handle.gen(options.template[key], key, {
835 currentContext: result,
836 templateCurrentContext: options.template,
837 path: options.context.path
838 });
839 options.context.path.pop();
840 inc = key.match(rkey);
841 if (inc && inc[2] && Util.type(options.template[key]) === "number") {
842 options.template[key] += parseInt(inc[2], 10);
843 }
844 }
845 }
846 return result;
847 },
848 number: function(options) {
849 var result, parts, i;
850 if (options.rule.point) {
851 options.template += "";
852 parts = options.template.split(".");
853 parts[0] = options.rule.range ? options.rule.count : parts[0];
854 parts[1] = (parts[1] || "").slice(0, options.rule.dcount);
855 for (i = 0; parts[1].length < options.rule.dcount; i++) {
856 parts[1] += Random.character("number");
857 }
858 result = parseFloat(parts.join("."), 10);
859 } else {
860 result = options.rule.range && !options.rule.parameters[2] ? options.rule.count : options.template;
861 }
862 return result;
863 },
864 "boolean": function(options) {
865 var result;
866 result = options.rule.parameters ? Random.bool(options.rule.min, options.rule.max, options.template) : options.template;
867 return result;
868 },
869 string: function(options) {
870 var result = "", i, placeholders, ph, phed;
871 if (options.template.length) {
872 for (i = 0; i < options.rule.count; i++) {
873 result += options.template;
874 }
875 placeholders = result.match(rplaceholder) || [];
876 for (i = 0; i < placeholders.length; i++) {
877 ph = placeholders[i];
878 if (/^\\/.test(ph)) {
879 placeholders.splice(i--, 1);
880 continue;
881 }
882 phed = Handle.placeholder(ph, options.context.currentContext, options.context.templateCurrentContext);
883 if (placeholders.length === 1 && ph === result && typeof phed !== typeof result) {
884 result = phed;
885 break;
886 if (Util.isNumeric(phed)) {
887 result = parseFloat(phed, 10);
888 break;
889 }
890 if (/^(true|false)$/.test(phed)) {
891 result = phed === "true" ? true : phed === "false" ? false : phed;
892 break;
893 }
894 }
895 result = result.replace(ph, phed);
896 }
897 } else {
898 result = options.rule.range ? Random.string(options.rule.count) : options.template;
899 }
900 return result;
901 },
902 "function": function(options) {
903 return options.template.call(options.context.currentContext);
904 }
905 });
906 Handle.extend({
907 _all: function() {
908 var re = {};
909 for (var key in Random) re[key.toLowerCase()] = key;
910 return re;
911 },
912 placeholder: function(placeholder, obj, templateContext) {
913 rplaceholder.exec("");
914 var parts = rplaceholder.exec(placeholder), key = parts && parts[1], lkey = key && key.toLowerCase(), okey = this._all()[lkey], params = parts && parts[2] || "";
915 try {
916 params = eval("(function(){ return [].splice.call(arguments, 0 ) })(" + params + ")");
917 } catch (error) {
918 params = parts[2].split(/,\s*/);
919 }
920 if (obj && key in obj) return obj[key];
921 if (templateContext && typeof templateContext === "object" && key in templateContext && placeholder !== templateContext[key]) {
922 templateContext[key] = Handle.gen(templateContext[key], key, {
923 currentContext: obj,
924 templateCurrentContext: templateContext
925 });
926 return templateContext[key];
927 }
928 if (!(key in Random) && !(lkey in Random) && !(okey in Random)) return placeholder;
929 for (var i = 0; i < params.length; i++) {
930 rplaceholder.exec("");
931 if (rplaceholder.test(params[i])) {
932 params[i] = Handle.placeholder(params[i], obj);
933 }
934 }
935 var handle = Random[key] || Random[lkey] || Random[okey];
936 switch (Util.type(handle)) {
937 case "array":
938 return Random.pick(handle);
939
940 case "function":
941 var re = handle.apply(Random, params);
942 if (re === undefined) re = "";
943 return re;
944 }
945 }
946 });
947 /*! src/mockjax.js */
948 function find(options) {
949 for (var sUrlType in Mock._mocked) {
950 var item = Mock._mocked[sUrlType];
951 if ((!item.rurl || match(item.rurl, options.url)) && (!item.rtype || match(item.rtype, options.type.toLowerCase()))) {
952 return item;
953 }
954 }
955 function match(expected, actual) {
956 if (Util.type(expected) === "string") {
957 return expected === actual;
958 }
959 if (Util.type(expected) === "regexp") {
960 return expected.test(actual);
961 }
962 }
963 }
964 function convert(item, options) {
965 return Util.isFunction(item.template) ? item.template(options) : Mock.mock(item.template);
966 }
967 Mock.mockjax = function mockjax(jQuery) {
968 function mockxhr() {
969 return {
970 readyState: 4,
971 status: 200,
972 statusText: "",
973 open: jQuery.noop,
974 send: function() {
975 this.onload();
976 },
977 setRequestHeader: jQuery.noop,
978 getAllResponseHeaders: jQuery.noop,
979 getResponseHeader: jQuery.noop,
980 statusCode: jQuery.noop,
981 abort: jQuery.noop
982 };
983 }
984 function prefilter(options, originalOptions, jqXHR) {
985 var item = find(options);
986 if (item) {
987 options.dataFilter = options.converters["text json"] = options.converters["text jsonp"] = options.converters["text script"] = options.converters["script json"] = function() {
988 return convert(item, options);
989 };
990 options.xhr = mockxhr;
991 if (originalOptions.dataType !== "script") return "json";
992 }
993 }
994 jQuery.ajaxPrefilter("json jsonp script", prefilter);
995 return Mock;
996 };
997 if (typeof jQuery != "undefined") Mock.mockjax(jQuery);
998 if (typeof Zepto != "undefined") {
999 Mock.mockjax = function(Zepto) {
1000 var __original_ajax = Zepto.ajax;
1001 var xhr = {
1002 readyState: 4,
1003 responseText: "",
1004 responseXML: null,
1005 state: 2,
1006 status: 200,
1007 statusText: "success",
1008 timeoutTimer: null
1009 };
1010 Zepto.ajax = function(options) {
1011 var item = find(options);
1012 if (item) {
1013 var data = Mock.mock(item.template);
1014 if (options.success) options.success(data, xhr, options);
1015 if (options.complete) options.complete(xhr.status, xhr, options);
1016 return xhr;
1017 }
1018 return __original_ajax.call(Zepto, options);
1019 };
1020 };
1021 Mock.mockjax(Zepto);
1022 }
1023 if (typeof KISSY != "undefined" && KISSY.add) {
1024 Mock.mockjax = function mockjax(KISSY) {
1025 var _original_ajax = KISSY.io;
1026 var xhr = {
1027 readyState: 4,
1028 responseText: "",
1029 responseXML: null,
1030 state: 2,
1031 status: 200,
1032 statusText: "success",
1033 timeoutTimer: null
1034 };
1035 KISSY.io = function(options) {
1036 var item = find(options);
1037 if (item) {
1038 var data = Mock.mock(item.template);
1039 if (options.success) options.success(data, xhr, options);
1040 if (options.complete) options.complete(xhr.status, xhr, options);
1041 return xhr;
1042 }
1043 return _original_ajax.apply(this, arguments);
1044 };
1045 for (var name in _original_ajax) {
1046 KISSY.io[name] = _original_ajax[name];
1047 }
1048 };
1049 }
1050 /*! src/expose.js */
1051 Mock.Util = Util;
1052 Mock.Random = Random;
1053 Mock.heredoc = Util.heredoc;
1054 if (typeof module === "object" && module.exports) {
1055 module.exports = Mock;
1056 } else if (typeof define === "function" && define.amd) {
1057 define(function() {
1058 return Mock;
1059 });
1060 } else if (typeof define === "function" && define.cmd) {
1061 define(function() {
1062 return Mock;
1063 });
1064 }
1065 this.Mock = Mock;
1066 this.Random = Random;
1067 if (typeof KISSY != "undefined") {
1068 Util.each([ "mock", "components/mock/", "mock/dist/mock", "gallery/Mock/0.1.1/", "gallery/Mock/0.1.2/", "gallery/Mock/0.1.3/" ], function register(name) {
1069 KISSY.add(name, function(S) {
1070 Mock.mockjax(S);
1071 return Mock;
1072 }, {
1073 requires: [ "ajax" ]
1074 });
1075 });
1076 }
1077 /*! src/mock4tpl.js */
1078 (function(undefined) {
1079 var Mock4Tpl = {
1080 version: "0.0.1"
1081 };
1082 if (!this.Mock) module.exports = Mock4Tpl;
1083 Mock.tpl = function(input, options, helpers, partials) {
1084 return Mock4Tpl.mock(input, options, helpers, partials);
1085 };
1086 Mock.parse = function(input) {
1087 return Handlebars.parse(input);
1088 };
1089 Mock4Tpl.mock = function(input, options, helpers, partials) {
1090 helpers = helpers ? Util.extend({}, helpers, Handlebars.helpers) : Handlebars.helpers;
1091 partials = partials ? Util.extend({}, partials, Handlebars.partials) : Handlebars.partials;
1092 return Handle.gen(input, null, options, helpers, partials);
1093 };
1094 var Handle = {
1095 debug: Mock4Tpl.debug || false,
1096 extend: Util.extend
1097 };
1098 Handle.gen = function(node, context, options, helpers, partials) {
1099 if (Util.isString(node)) {
1100 var ast = Handlebars.parse(node);
1101 options = Handle.parseOptions(node, options);
1102 var data = Handle.gen(ast, context, options, helpers, partials);
1103 return data;
1104 }
1105 context = context || [ {} ];
1106 options = options || {};
1107 if (this[node.type] === Util.noop) return;
1108 options.__path = options.__path || [];
1109 if (Mock4Tpl.debug || Handle.debug) {
1110 console.log();
1111 console.group("[" + node.type + "]", JSON.stringify(node));
1112 console.log("[options]", options.__path.length, JSON.stringify(options));
1113 }
1114 var preLength = options.__path.length;
1115 this[node.type](node, context, options, helpers, partials);
1116 options.__path.splice(preLength);
1117 if (Mock4Tpl.debug || Handle.debug) {
1118 console.groupEnd();
1119 }
1120 return context[context.length - 1];
1121 };
1122 Handle.parseOptions = function(input, options) {
1123 var rComment = /<!--\s*\n*Mock\s*\n*([\w\W]+?)\s*\n*-->/g;
1124 var comments = input.match(rComment), ret = {}, i, ma, option;
1125 for (i = 0; comments && i < comments.length; i++) {
1126 rComment.lastIndex = 0;
1127 ma = rComment.exec(comments[i]);
1128 if (ma) {
1129 option = new Function("return " + ma[1]);
1130 option = option();
1131 Util.extend(ret, option);
1132 }
1133 }
1134 return Util.extend(ret, options);
1135 };
1136 Handle.val = function(name, options, context, def) {
1137 if (name !== options.__path[options.__path.length - 1]) throw new Error(name + "!==" + options.__path);
1138 if (Mock4Tpl.debug || Handle.debug) console.log("[options]", name, options.__path);
1139 if (def !== undefined) def = Mock.mock(def);
1140 if (options) {
1141 var mocked = Mock.mock(options);
1142 if (Util.isString(mocked)) return mocked;
1143 if (name in mocked) {
1144 return mocked[name];
1145 }
1146 }
1147 if (Util.isArray(context[0])) return {};
1148 return def !== undefined ? def : name || Random.word();
1149 };
1150 Handle.program = function(node, context, options, helpers, partials) {
1151 for (var i = 0; i < node.statements.length; i++) {
1152 this.gen(node.statements[i], context, options, helpers, partials);
1153 }
1154 };
1155 Handle.mustache = function(node, context, options, helpers, partials) {
1156 var i, currentContext = context[0], contextLength = context.length;
1157 if (Util.type(currentContext) === "array") {
1158 currentContext.push({});
1159 currentContext = currentContext[currentContext.length - 1];
1160 context.unshift(currentContext);
1161 }
1162 if (node.isHelper || helpers && helpers[node.id.string]) {
1163 if (node.params.length === 0) {} else {
1164 for (i = 0; i < node.params.length; i++) {
1165 this.gen(node.params[i], context, options, helpers, partials);
1166 }
1167 }
1168 if (node.hash) this.gen(node.hash, context, options, helpers, partials);
1169 } else {
1170 this.gen(node.id, context, options, helpers, partials);
1171 }
1172 if (context.length > contextLength) context.splice(0, context.length - contextLength);
1173 };
1174 Handle.block = function(node, context, options, helpers, partials) {
1175 var parts = node.mustache.id.parts, i, len, cur, val, type, currentContext = context[0], contextLength = context.length;
1176 if (node.inverse) {}
1177 if (node.mustache.isHelper || helpers && helpers[node.mustache.id.string]) {
1178 type = parts[0];
1179 val = (Helpers[type] || Helpers.custom).apply(this, arguments);
1180 currentContext = context[0];
1181 } else {
1182 for (i = 0; i < parts.length; i++) {
1183 options.__path.push(parts[i]);
1184 cur = parts[i];
1185 val = this.val(cur, options, context, {});
1186 currentContext[cur] = Util.isArray(val) && [] || val;
1187 type = Util.type(currentContext[cur]);
1188 if (type === "object" || type === "array") {
1189 currentContext = currentContext[cur];
1190 context.unshift(currentContext);
1191 }
1192 }
1193 }
1194 if (node.program) {
1195 if (Util.type(currentContext) === "array") {
1196 len = val.length || Random.integer(3, 7);
1197 for (i = 0; i < len; i++) {
1198 currentContext.push(typeof val[i] !== "undefined" ? val[i] : {});
1199 options.__path.push("[]");
1200 context.unshift(currentContext[currentContext.length - 1]);
1201 this.gen(node.program, context, options, helpers, partials);
1202 options.__path.pop();
1203 context.shift();
1204 }
1205 } else this.gen(node.program, context, options, helpers, partials);
1206 }
1207 if (context.length > contextLength) context.splice(0, context.length - contextLength);
1208 };
1209 Handle.hash = function(node, context, options, helpers, partials) {
1210 var pairs = node.pairs, pair, i, j;
1211 for (i = 0; i < pairs.length; i++) {
1212 pair = pairs[i];
1213 for (j = 1; j < pair.length; j++) {
1214 this.gen(pair[j], context, options, helpers, partials);
1215 }
1216 }
1217 };
1218 Handle.ID = function(node, context, options) {
1219 var parts = node.parts, i, len, cur, prev, def, val, type, valType, preOptions, currentContext = context[node.depth], contextLength = context.length;
1220 if (Util.isArray(currentContext)) currentContext = context[node.depth + 1];
1221 if (!parts.length) {} else {
1222 for (i = 0, len = parts.length; i < len; i++) {
1223 options.__path.push(parts[i]);
1224 cur = parts[i];
1225 prev = parts[i - 1];
1226 preOptions = options[prev];
1227 def = i === len - 1 ? currentContext[cur] : {};
1228 val = this.val(cur, options, context, def);
1229 type = Util.type(currentContext[cur]);
1230 valType = Util.type(val);
1231 if (type === "undefined") {
1232 if (i < len - 1 && valType !== "object" && valType !== "array") {
1233 currentContext[cur] = {};
1234 } else {
1235 currentContext[cur] = Util.isArray(val) && [] || val;
1236 }
1237 } else {
1238 if (i < len - 1 && type !== "object" && type !== "array") {
1239 currentContext[cur] = Util.isArray(val) && [] || {};
1240 }
1241 }
1242 type = Util.type(currentContext[cur]);
1243 if (type === "object" || type === "array") {
1244 currentContext = currentContext[cur];
1245 context.unshift(currentContext);
1246 }
1247 }
1248 }
1249 if (context.length > contextLength) context.splice(0, context.length - contextLength);
1250 };
1251 Handle.partial = function(node, context, options, helpers, partials) {
1252 var name = node.partialName.name, partial = partials && partials[name], contextLength = context.length;
1253 if (partial) Handle.gen(partial, context, options, helpers, partials);
1254 if (context.length > contextLength) context.splice(0, context.length - contextLength);
1255 };
1256 Handle.content = Util.noop;
1257 Handle.PARTIAL_NAME = Util.noop;
1258 Handle.DATA = Util.noop;
1259 Handle.STRING = Util.noop;
1260 Handle.INTEGER = Util.noop;
1261 Handle.BOOLEAN = Util.noop;
1262 Handle.comment = Util.noop;
1263 var Helpers = {};
1264 Helpers.each = function(node, context, options) {
1265 var i, len, cur, val, parts, def, type, currentContext = context[0];
1266 parts = node.mustache.params[0].parts;
1267 for (i = 0, len = parts.length; i < len; i++) {
1268 options.__path.push(parts[i]);
1269 cur = parts[i];
1270 def = i === len - 1 ? [] : {};
1271 val = this.val(cur, options, context, def);
1272 currentContext[cur] = Util.isArray(val) && [] || val;
1273 type = Util.type(currentContext[cur]);
1274 if (type === "object" || type === "array") {
1275 currentContext = currentContext[cur];
1276 context.unshift(currentContext);
1277 }
1278 }
1279 return val;
1280 };
1281 Helpers["if"] = Helpers.unless = function(node, context, options) {
1282 var params = node.mustache.params, i, j, cur, val, parts, def, type, currentContext = context[0];
1283 for (i = 0; i < params.length; i++) {
1284 parts = params[i].parts;
1285 for (j = 0; j < parts.length; j++) {
1286 if (i === 0) options.__path.push(parts[j]);
1287 cur = parts[j];
1288 def = j === parts.length - 1 ? "@BOOL(2,1,true)" : {};
1289 val = this.val(cur, options, context, def);
1290 if (j === parts.length - 1) {
1291 val = val === "true" ? true : val === "false" ? false : val;
1292 }
1293 currentContext[cur] = Util.isArray(val) ? [] : val;
1294 type = Util.type(currentContext[cur]);
1295 if (type === "object" || type === "array") {
1296 currentContext = currentContext[cur];
1297 context.unshift(currentContext);
1298 }
1299 }
1300 }
1301 return val;
1302 };
1303 Helpers["with"] = function(node, context, options) {
1304 var i, cur, val, parts, def, currentContext = context[0];
1305 parts = node.mustache.params[0].parts;
1306 for (i = 0; i < parts.length; i++) {
1307 options.__path.push(parts[i]);
1308 cur = parts[i];
1309 def = {};
1310 val = this.val(cur, options, context, def);
1311 currentContext = currentContext[cur] = val;
1312 context.unshift(currentContext);
1313 }
1314 return val;
1315 };
1316 Helpers.log = function() {};
1317 Helpers.custom = function(node, context, options) {
1318 var i, len, cur, val, parts, def, type, currentContext = context[0];
1319 if (node.mustache.params.length === 0) {
1320 return;
1321 options.__path.push(node.mustache.id.string);
1322 cur = node.mustache.id.string;
1323 def = "@BOOL(2,1,true)";
1324 val = this.val(cur, options, context, def);
1325 currentContext[cur] = Util.isArray(val) && [] || val;
1326 type = Util.type(currentContext[cur]);
1327 if (type === "object" || type === "array") {
1328 currentContext = currentContext[cur];
1329 context.unshift(currentContext);
1330 }
1331 } else {
1332 parts = node.mustache.params[0].parts;
1333 for (i = 0, len = parts.length; i < len; i++) {
1334 options.__path.push(parts[i]);
1335 cur = parts[i];
1336 def = i === len - 1 ? [] : {};
1337 val = this.val(cur, options, context, def);
1338 currentContext[cur] = Util.isArray(val) && [] || val;
1339 type = Util.type(currentContext[cur]);
1340 if (type === "object" || type === "array") {
1341 currentContext = currentContext[cur];
1342 context.unshift(currentContext);
1343 }
1344 }
1345 }
1346 return val;
1347 };
1348 }).call(this);
1349 /*! src/mock4xtpl.js */
1350 (function(undefined) {
1351 if (typeof KISSY === "undefined") return;
1352 var Mock4XTpl = {
1353 debug: false
1354 };
1355 var XTemplate;
1356 KISSY.use("xtemplate", function(S, T) {
1357 XTemplate = T;
1358 });
1359 if (!this.Mock) module.exports = Mock4XTpl;
1360 Mock.xtpl = function(input, options, helpers, partials) {
1361 return Mock4XTpl.mock(input, options, helpers, partials);
1362 };
1363 Mock.xparse = function(input) {
1364 return XTemplate.compiler.parse(input);
1365 };
1366 Mock4XTpl.mock = function(input, options, helpers, partials) {
1367 helpers = helpers ? Util.extend({}, helpers, XTemplate.RunTime.commands) : XTemplate.RunTime.commands;
1368 partials = partials ? Util.extend({}, partials, XTemplate.RunTime.subTpls) : XTemplate.RunTime.subTpls;
1369 return this.gen(input, null, options, helpers, partials, {});
1370 };
1371 Mock4XTpl.parse = function(input) {
1372 return XTemplate.compiler.parse(input);
1373 };
1374 Mock4XTpl.gen = function(node, context, options, helpers, partials, other) {
1375 if (typeof node === "string") {
1376 if (Mock4XTpl.debug) {
1377 console.log("[tpl ]\n", node);
1378 }
1379 var ast = this.parse(node);
1380 options = this.parseOptions(node, options);
1381 var data = this.gen(ast, context, options, helpers, partials, other);
1382 return data;
1383 }
1384 context = context || [ {} ];
1385 options = options || {};
1386 node.type = node.type;
1387 if (this[node.type] === Util.noop) return;
1388 options.__path = options.__path || [];
1389 if (Mock4XTpl.debug) {
1390 console.log();
1391 console.group("[" + node.type + "]", JSON.stringify(node));
1392 console.log("[context]", "[before]", context.length, JSON.stringify(context));
1393 console.log("[options]", "[before]", options.__path.length, JSON.stringify(options));
1394 console.log("[other ]", "[before]", JSON.stringify(other));
1395 }
1396 var preLength = options.__path.length;
1397 this[node.type](node, context, options, helpers, partials, other);
1398 if (Mock4XTpl.debug) {
1399 console.log("[__path ]", "[after ]", options.__path);
1400 }
1401 if (!other.hold || typeof other.hold === "function" && !other.hold(node, options, context)) {
1402 options.__path.splice(preLength);
1403 }
1404 if (Mock4XTpl.debug) {
1405 console.log("[context]", "[after ]", context.length, JSON.stringify(context));
1406 console.groupEnd();
1407 }
1408 return context[context.length - 1];
1409 };
1410 Mock4XTpl.parseOptions = function(input, options) {
1411 var rComment = /<!--\s*\n*Mock\s*\n*([\w\W]+?)\s*\n*-->/g;
1412 var comments = input.match(rComment), ret = {}, i, ma, option;
1413 for (i = 0; comments && i < comments.length; i++) {
1414 rComment.lastIndex = 0;
1415 ma = rComment.exec(comments[i]);
1416 if (ma) {
1417 option = new Function("return " + ma[1]);
1418 option = option();
1419 Util.extend(ret, option);
1420 }
1421 }
1422 return Util.extend(ret, options);
1423 };
1424 Mock4XTpl.parseVal = function(expr, object) {
1425 function queryArray(prop, context) {
1426 if (typeof context === "object" && prop in context) return [ context[prop] ];
1427 var ret = [];
1428 for (var i = 0; i < context.length; i++) {
1429 ret.push.apply(ret, query(prop, [ context[i] ]));
1430 }
1431 return ret;
1432 }
1433 function queryObject(prop, context) {
1434 if (typeof context === "object" && prop in context) return [ context[prop] ];
1435 var ret = [];
1436 for (var key in context) {
1437 ret.push.apply(ret, query(prop, [ context[key] ]));
1438 }
1439 return ret;
1440 }
1441 function query(prop, set) {
1442 var ret = [];
1443 for (var i = 0; i < set.length; i++) {
1444 if (typeof set[i] !== "object") continue;
1445 if (prop in set[i]) ret.push(set[i][prop]); else {
1446 ret.push.apply(ret, Util.isArray(set[i]) ? queryArray(prop, set[i]) : queryObject(prop, set[i]));
1447 }
1448 }
1449 return ret;
1450 }
1451 function parse(expr, context) {
1452 var parts = typeof expr === "string" ? expr.split(".") : expr.slice(0), set = [ context ];
1453 while (parts.length) {
1454 set = query(parts.shift(), set);
1455 }
1456 return set;
1457 }
1458 return parse(expr, object);
1459 };
1460 Mock4XTpl.val = function(name, options, context, def) {
1461 if (name !== options.__path[options.__path.length - 1]) throw new Error(name + "!==" + options.__path);
1462 if (def !== undefined) def = Mock.mock(def);
1463 if (options) {
1464 var mocked = Mock.mock(options);
1465 if (Util.isString(mocked)) return mocked;
1466 var ret = Mock4XTpl.parseVal(options.__path, mocked);
1467 if (ret.length > 0) return ret[0];
1468 if (name in mocked) {
1469 return mocked[name];
1470 }
1471 }
1472 if (Util.isArray(context[0])) return {};
1473 return def !== undefined ? def : name;
1474 };
1475 Mock4XTpl.program = function(node, context, options, helpers, partials, other) {
1476 for (var i = 0; i < node.statements.length; i++) {
1477 this.gen(node.statements[i], context, options, helpers, partials, other);
1478 }
1479 for (var j = 0; node.inverse && j < node.inverse.length; j++) {
1480 this.gen(node.inverse[j], context, options, helpers, partials, other);
1481 }
1482 };
1483 Mock4XTpl.block = function(node, context, options, helpers, partials, other) {
1484 var contextLength = context.length;
1485 this.gen(node.tpl, context, options, helpers, partials, Util.extend({}, other, {
1486 def: {},
1487 hold: true
1488 }));
1489 var currentContext = context[0], mocked, i, len;
1490 if (Util.type(currentContext) === "array") {
1491 mocked = this.val(options.__path[options.__path.length - 1], options, context);
1492 len = mocked && mocked.length || Random.integer(3, 7);
1493 for (i = 0; i < len; i++) {
1494 currentContext.push(mocked && mocked[i] !== undefined ? mocked[i] : {});
1495 options.__path.push(i);
1496 context.unshift(currentContext[currentContext.length - 1]);
1497 this.gen(node.program, context, options, helpers, partials, other);
1498 options.__path.pop();
1499 context.shift();
1500 }
1501 } else this.gen(node.program, context, options, helpers, partials, other);
1502 if (!other.hold || typeof other.hold === "function" && !other.hold(node, options, context)) {
1503 context.splice(0, context.length - contextLength);
1504 }
1505 };
1506 Mock4XTpl.tpl = function(node, context, options, helpers, partials, other) {
1507 if (node.params && node.params.length) {
1508 other = Util.extend({}, other, {
1509 def: {
1510 each: [],
1511 "if": "@BOOL(2,1,true)",
1512 unless: "@BOOL(2,1,false)",
1513 "with": {}
1514 }[node.path.string],
1515 hold: {
1516 each: true,
1517 "if": function(_, __, ___, name, value) {
1518 return typeof value === "object";
1519 },
1520 unless: function(_, __, ___, name, value) {
1521 return typeof value === "object";
1522 },
1523 "with": true,
1524 include: false
1525 }[node.path.string]
1526 });
1527 for (var i = 0, input; i < node.params.length; i++) {
1528 if (node.path.string === "include") {
1529 input = partials && partials[node.params[i].value];
1530 } else input = node.params[i];
1531 if (input) this.gen(input, context, options, helpers, partials, other);
1532 }
1533 if (node.hash) {
1534 this.gen(node.hash, context, options, helpers, partials, other);
1535 }
1536 } else {
1537 this.gen(node.path, context, options, helpers, partials, other);
1538 }
1539 };
1540 Mock4XTpl.tplExpression = function(node, context, options, helpers, partials, other) {
1541 this.gen(node.expression, context, options, helpers, partials, other);
1542 };
1543 Mock4XTpl.content = Util.noop;
1544 Mock4XTpl.unaryExpression = Util.noop;
1545 Mock4XTpl.multiplicativeExpression = Mock4XTpl.additiveExpression = function(node, context, options, helpers, partials, other) {
1546 this.gen(node.op1, context, options, helpers, partials, Util.extend({}, other, {
1547 def: function() {
1548 return node.op2.type === "number" ? node.op2.value.indexOf(".") > -1 ? Random.float(-Math.pow(10, 10), Math.pow(10, 10), 1, Math.pow(10, 6)) : Random.integer() : undefined;
1549 }()
1550 }));
1551 this.gen(node.op2, context, options, helpers, partials, Util.extend({}, other, {
1552 def: function() {
1553 return node.op1.type === "number" ? node.op1.value.indexOf(".") > -1 ? Random.float(-Math.pow(10, 10), Math.pow(10, 10), 1, Math.pow(10, 6)) : Random.integer() : undefined;
1554 }()
1555 }));
1556 };
1557 Mock4XTpl.relationalExpression = function(node, context, options, helpers, partials, other) {
1558 this.gen(node.op1, context, options, helpers, partials, other);
1559 this.gen(node.op2, context, options, helpers, partials, other);
1560 };
1561 Mock4XTpl.equalityExpression = Util.noop;
1562 Mock4XTpl.conditionalAndExpression = Util.noop;
1563 Mock4XTpl.conditionalOrExpression = Util.noop;
1564 Mock4XTpl.string = Util.noop;
1565 Mock4XTpl.number = Util.noop;
1566 Mock4XTpl.boolean = Util.noop;
1567 Mock4XTpl.hash = function(node, context, options, helpers, partials, other) {
1568 var pairs = node.value, key;
1569 for (key in pairs) {
1570 this.gen(pairs[key], context, options, helpers, partials, other);
1571 }
1572 };
1573 Mock4XTpl.id = function(node, context, options, helpers, partials, other) {
1574 var contextLength = context.length;
1575 var parts = node.parts, currentContext = context[node.depth], i, len, cur, def, val;
1576 function fix(currentContext, index, length, name, val) {
1577 var type = Util.type(currentContext[name]), valType = Util.type(val);
1578 val = val === "true" ? true : val === "false" ? false : val;
1579 if (type === "undefined") {
1580 if (index < length - 1 && !Util.isObjectOrArray(val)) {
1581 currentContext[name] = {};
1582 } else {
1583 currentContext[name] = Util.isArray(val) && [] || val;
1584 }
1585 } else {
1586 if (index < length - 1 && type !== "object" && type !== "array") {
1587 currentContext[name] = Util.isArray(val) && [] || {};
1588 } else {
1589 if (type !== "object" && type !== "array" && valType !== "object" && valType !== "array") {
1590 currentContext[name] = val;
1591 }
1592 }
1593 }
1594 return currentContext[name];
1595 }
1596 if (Util.isArray(currentContext)) currentContext = context[node.depth + 1];
1597 for (i = 0, len = parts.length; i < len; i++) {
1598 if (i === 0 && parts[i] === "this") continue;
1599 if (/^(xindex|xcount|xkey)$/.test(parts[i])) continue;
1600 if (i === 0 && len === 1 && parts[i] in helpers) continue;
1601 options.__path.push(parts[i]);
1602 cur = parts[i];
1603 def = i === len - 1 ? other.def !== undefined ? other.def : context[0][cur] : {};
1604 val = this.val(cur, options, context, def);
1605 if (Mock4XTpl.debug) {
1606 console.log("[def ]", JSON.stringify(def));
1607 console.log("[val ]", JSON.stringify(val));
1608 }
1609 val = fix(currentContext, i, len, cur, val);
1610 if (Util.isObjectOrArray(currentContext[cur])) {
1611 context.unshift(currentContext = currentContext[cur]);
1612 }
1613 }
1614 if (!other.hold || typeof other.hold === "function" && !other.hold(node, options, context, cur, val)) {
1615 context.splice(0, context.length - contextLength);
1616 }
1617 };
1618 }).call(this);
1619}).call(this);
\No newline at end of file