@samitouri / QOS-React-2 / commits / 2b9c34b5c7

sync with tastejs todomvc

Cheng Lou committed Aug 31, 2013 at 21:44 UTC 2b9c34b5c7fa88c0a67fd0b1c8639e6fa128a02c
12 files changed +451 -733
examples/todomvc-director/README.md new
+11
@@ -0,0 +1,11 @@
1 +# TodoMVC-director
2 +
3 +This is the exact copy of the React-powered [TodoMVC](http://todomvc.com/labs/architecture-examples/react/). To test it, use [bower](http://bower.io) to fetch the dependencies:
4 +
5 +`bower install`
6 +
7 +Then fire up a server here:
8 +
9 +`python -m SimpleHTTPServer`
10 +
11 +And go visit `localhost:8000`.
examples/todomvc-director/bower.json new
+9
@@ -0,0 +1,9 @@
1 +{
2 + "name": "todomvc-react",
3 + "version": "0.0.0",
4 + "dependencies": {
5 + "todomvc-common": "~0.1.7",
6 + "react": "~0.4.0",
7 + "director": "~1.2.0"
8 + }
9 +}
examples/todomvc-director/index.html new
+24
@@ -0,0 +1,24 @@
1 +<!doctype html>
2 +<html lang="en" data-framework="react">
3 + <head>
4 + <meta charset="utf-8">
5 + <meta http-equiv="X-UA-Compatible" content="IE=edge">
6 + <title>React • TodoMVC</title>
7 + <link rel="stylesheet" href="bower_components/todomvc-common/base.css">
8 + </head>
9 + <body>
10 + <section id="todoapp"></section>
11 + <footer id="info"></footer>
12 + <div id="benchmark"></div>
13 +
14 + <script src="bower_components/todomvc-common/base.js"></script>
15 + <script src="bower_components/react/react.js"></script>
16 + <script src="bower_components/react/JSXTransformer.js"></script>
17 + <script src="bower_components/director/build/director.min.js"></script>
18 +
19 + <script type="text/jsx" src="js/utils.jsx"></script>
20 + <script type="text/jsx" src="js/todoItem.jsx"></script>
21 + <script type="text/jsx" src="js/footer.jsx"></script>
22 + <script type="text/jsx" src="js/app.jsx"></script>
23 + </body>
24 +</html>
examples/todomvc-director/js/app.jsx new
+207
@@ -0,0 +1,207 @@
1 +/**
2 + * @jsx React.DOM
3 + */
4 +/*jshint quotmark:false */
5 +/*jshint white:false */
6 +/*jshint trailing:false */
7 +/*jshint newcap:false */
8 +/*global Utils, ALL_TODOS, ACTIVE_TODOS, COMPLETED_TODOS,
9 + TodoItem, TodoFooter, React, Router*/
10 +
11 +(function (window, React) {
12 + 'use strict';
13 +
14 + window.ALL_TODOS = 'all';
15 + window.ACTIVE_TODOS = 'active';
16 + window.COMPLETED_TODOS = 'completed';
17 +
18 + var ENTER_KEY = 13;
19 +
20 + var TodoApp = React.createClass({
21 + getInitialState: function () {
22 + var todos = Utils.store('react-todos');
23 + return {
24 + todos: todos,
25 + nowShowing: ALL_TODOS,
26 + editing: null
27 + };
28 + },
29 +
30 + componentDidMount: function () {
31 + var router = Router({
32 + '/': this.setState.bind(this, {nowShowing: ALL_TODOS}),
33 + '/active': this.setState.bind(this, {nowShowing: ACTIVE_TODOS}),
34 + '/completed': this.setState.bind(this, {nowShowing: COMPLETED_TODOS})
35 + });
36 + router.init();
37 + this.refs.newField.getDOMNode().focus();
38 + },
39 +
40 + handleNewTodoKeyDown: function (event) {
41 + if (event.which !== ENTER_KEY) {
42 + return;
43 + }
44 +
45 + var val = this.refs.newField.getDOMNode().value.trim();
46 + var todos;
47 + var newTodo;
48 +
49 + if (val) {
50 + todos = this.state.todos;
51 + newTodo = {
52 + id: Utils.uuid(),
53 + title: val,
54 + completed: false
55 + };
56 + this.setState({todos: todos.concat([newTodo])});
57 + this.refs.newField.getDOMNode().value = '';
58 + }
59 +
60 + return false;
61 + },
62 +
63 + toggleAll: function (event) {
64 + var checked = event.target.checked;
65 +
66 + this.state.todos.forEach(function (todo) {
67 + todo.completed = checked;
68 + });
69 +
70 + this.setState({todos: this.state.todos});
71 + },
72 +
73 + toggle: function (todo) {
74 + todo.completed = !todo.completed;
75 + this.setState({todos: this.state.todos});
76 + },
77 +
78 + destroy: function (todo) {
79 + var newTodos = this.state.todos.filter(function (candidate) {
80 + return candidate.id !== todo.id;
81 + });
82 +
83 + this.setState({todos: newTodos});
84 + },
85 +
86 + edit: function (todo, callback) {
87 + // refer to todoItem.js `handleEdit` for the reasoning behind the
88 + // callback
89 + this.setState({editing: todo.id}, function () {
90 + callback();
91 + });
92 + },
93 +
94 + save: function (todo, text) {
95 + todo.title = text;
96 + this.setState({todos: this.state.todos, editing: null});
97 + },
98 +
99 + cancel: function () {
100 + this.setState({editing: null});
101 + },
102 +
103 + clearCompleted: function () {
104 + var newTodos = this.state.todos.filter(function (todo) {
105 + return !todo.completed;
106 + });
107 +
108 + this.setState({todos: newTodos});
109 + },
110 +
111 + componentDidUpdate: function () {
112 + Utils.store('react-todos', this.state.todos);
113 + },
114 +
115 + render: function () {
116 + var footer = null;
117 + var main = null;
118 + var todoItems = {};
119 + var activeTodoCount;
120 + var completedCount;
121 +
122 + var shownTodos = this.state.todos.filter(function (todo) {
123 + switch (this.state.nowShowing) {
124 + case ACTIVE_TODOS:
125 + return !todo.completed;
126 + case COMPLETED_TODOS:
127 + return todo.completed;
128 + default:
129 + return true;
130 + }
131 + }.bind(this));
132 +
133 + shownTodos.forEach(function (todo) {
134 + todoItems[todo.id] = (
135 + <TodoItem
136 + todo={todo}
137 + onToggle={this.toggle.bind(this, todo)}
138 + onDestroy={this.destroy.bind(this, todo)}
139 + onEdit={this.edit.bind(this, todo)}
140 + editing={this.state.editing === todo.id}
141 + onSave={this.save.bind(this, todo)}
142 + onCancel={this.cancel}
143 + />
144 + );
145 + }.bind(this));
146 +
147 + activeTodoCount = this.state.todos.filter(function (todo) {
148 + return !todo.completed;
149 + }).length;
150 +
151 + completedCount = this.state.todos.length - activeTodoCount;
152 +
153 + if (activeTodoCount || completedCount) {
154 + footer =
155 + <TodoFooter
156 + count={activeTodoCount}
157 + completedCount={completedCount}
158 + nowShowing={this.state.nowShowing}
159 + onClearCompleted={this.clearCompleted}
160 + />;
161 + }
162 +
163 + if (this.state.todos.length) {
164 + main = (
165 + <section id="main">
166 + <input
167 + id="toggle-all"
168 + type="checkbox"
169 + onChange={this.toggleAll}
170 + checked={activeTodoCount === 0}
171 + />
172 + <ul id="todo-list">
173 + {todoItems}
174 + </ul>
175 + </section>
176 + );
177 + }
178 +
179 + return (
180 + <div>
181 + <header id="header">
182 + <h1>todos</h1>
183 + <input
184 + ref="newField"
185 + id="new-todo"
186 + placeholder="What needs to be done?"
187 + onKeyDown={this.handleNewTodoKeyDown}
188 + />
189 + </header>
190 + {main}
191 + {footer}
192 + </div>
193 + );
194 + }
195 + });
196 +
197 + React.renderComponent(<TodoApp />, document.getElementById('todoapp'));
198 + React.renderComponent(
199 + <div>
200 + <p>Double-click to edit a todo</p>
201 + <p>Created by{' '}
202 + <a href="http://github.com/petehunt/">petehunt</a>
203 + </p>
204 + <p>Part of{' '}<a href="http://todomvc.com">TodoMVC</a></p>
205 + </div>,
206 + document.getElementById('info'));
207 +})(window, React);
examples/todomvc-director/js/footer.jsx new
+58
@@ -0,0 +1,58 @@
1 +/**
2 + * @jsx React.DOM
3 + */
4 +/*jshint quotmark:false */
5 +/*jshint white:false */
6 +/*jshint trailing:false */
7 +/*jshint newcap:false */
8 +/*global React, ALL_TODOS, ACTIVE_TODOS, Utils, COMPLETED_TODOS */
9 +(function (window) {
10 + 'use strict';
11 +
12 + window.TodoFooter = React.createClass({
13 + render: function () {
14 + var activeTodoWord = Utils.pluralize(this.props.count, 'item');
15 + var clearButton = null;
16 +
17 + if (this.props.completedCount > 0) {
18 + clearButton = (
19 + <button
20 + id="clear-completed"
21 + onClick={this.props.onClearCompleted}>
22 + {''}Clear completed ({this.props.completedCount}){''}
23 + </button>
24 + );
25 + }
26 +
27 + var show = {
28 + ALL_TODOS: '',
29 + ACTIVE_TODOS: '',
30 + COMPLETED_TODOS: ''
31 + };
32 + show[this.props.nowShowing] = 'selected';
33 +
34 + return (
35 + <footer id="footer">
36 + <span id="todo-count">
37 + <strong>{this.props.count}</strong>
38 + {' '}{activeTodoWord}{' '}left{''}
39 + </span>
40 + <ul id="filters">
41 + <li>
42 + <a href="#/" class={show[ALL_TODOS]}>All</a>
43 + </li>
44 + {' '}
45 + <li>
46 + <a href="#/active" class={show[ACTIVE_TODOS]}>Active</a>
47 + </li>
48 + {' '}
49 + <li>
50 + <a href="#/completed" class={show[COMPLETED_TODOS]}>Completed</a>
51 + </li>
52 + </ul>
53 + {clearButton}
54 + </footer>
55 + );
56 + }
57 + });
58 +})(window);
examples/todomvc-director/js/todoItem.jsx new
+93
@@ -0,0 +1,93 @@
1 +/**
2 + * @jsx React.DOM
3 + */
4 +/*jshint quotmark: false */
5 +/*jshint white: false */
6 +/*jshint trailing: false */
7 +/*jshint newcap: false */
8 +/*global React, Utils */
9 +(function (window) {
10 + 'use strict';
11 +
12 + var ESCAPE_KEY = 27;
13 + var ENTER_KEY = 13;
14 +
15 + window.TodoItem = React.createClass({
16 + handleSubmit: function () {
17 + var val = this.state.editText.trim();
18 + if (val) {
19 + this.props.onSave(val);
20 + this.setState({editText: val});
21 + } else {
22 + this.props.onDestroy();
23 + }
24 + return false;
25 + },
26 + handleEdit: function () {
27 + // react optimizes renders by batching them. This means you can't call
28 + // parent's `onEdit` (which in this case triggeres a re-render), and
29 + // immediately manipulate the DOM as if the rendering's over. Put it as a
30 + // callback. Refer to app.js' `edit` method
31 + this.props.onEdit(function () {
32 + var node = this.refs.editField.getDOMNode();
33 + node.focus();
34 + node.setSelectionRange(node.value.length, node.value.length);
35 + }.bind(this));
36 + },
37 +
38 + handleKeyDown: function (event) {
39 + if (event.keyCode === ESCAPE_KEY) {
40 + this.setState({editText: this.props.todo.title});
41 + this.props.onCancel();
42 + } else if (event.keyCode === ENTER_KEY) {
43 + this.handleSubmit();
44 + } else {
45 + this.setState({editText: event.target.value});
46 + }
47 + },
48 +
49 + handleChange: function (event) {
50 + this.setState({editText: event.target.value});
51 + },
52 +
53 + getInitialState: function () {
54 + return {editText: this.props.todo.title};
55 + },
56 +
57 + componentWillReceiveProps: function (nextProps) {
58 + if (nextProps.todo.title !== this.props.todo.title) {
59 + this.setState(this.getInitialState());
60 + }
61 + },
62 +
63 + render: function () {
64 + return (
65 + <li class={Utils.stringifyObjKeys({
66 + completed: this.props.todo.completed,
67 + editing: this.props.editing
68 + })}>
69 + <div class="view">
70 + <input
71 + class="toggle"
72 + type="checkbox"
73 + checked={this.props.todo.completed ? 'checked' : null}
74 + onChange={this.props.onToggle}
75 + />
76 + <label onDoubleClick={this.handleEdit}>
77 + {this.props.todo.title}
78 + </label>
79 + <button class='destroy' onClick={this.props.onDestroy} />
80 + </div>
81 + <input
82 + ref="editField"
83 + class="edit"
84 + value={this.state.editText}
85 + onBlur={this.handleSubmit}
86 + onChange={this.handleChange}
87 + onKeyDown={this.handleKeyDown}
88 + />
89 + </li>
90 + );
91 + }
92 + });
93 +})(window);
examples/todomvc-director/js/utils.jsx new
+49
@@ -0,0 +1,49 @@
1 +(function (window) {
2 + 'use strict';
3 +
4 + window.Utils = {
5 + uuid: function () {
6 + /*jshint bitwise:false */
7 + var i, random;
8 + var uuid = '';
9 +
10 + for (i = 0; i < 32; i++) {
11 + random = Math.random() * 16 | 0;
12 + if (i === 8 || i === 12 || i === 16 || i === 20) {
13 + uuid += '-';
14 + }
15 + uuid += (i === 12 ? 4 : (i === 16 ? (random & 3 | 8) : random))
16 + .toString(16);
17 + }
18 +
19 + return uuid;
20 + },
21 +
22 + pluralize: function (count, word) {
23 + return count === 1 ? word : word + 's';
24 + },
25 +
26 + store: function (namespace, data) {
27 + if (data) {
28 + return localStorage.setItem(namespace, JSON.stringify(data));
29 + }
30 +
31 + var store = localStorage.getItem(namespace);
32 + return (store && JSON.parse(store)) || [];
33 + },
34 +
35 + stringifyObjKeys: function (obj) {
36 + var s = '';
37 + var key;
38 +
39 + for (key in obj) {
40 + if (obj.hasOwnProperty(key) && obj[key]) {
41 + s += key + ' ';
42 + }
43 + }
44 +
45 + return s.trim();
46 + }
47 + };
48 +
49 +})(window);
examples/todomvc/css/base.css deleted
-425
@@ -1,425 +0,0 @@
1 -html,
2 -body {
3 - margin: 0;
4 - padding: 0;
5 -}
6 -
7 -button {
8 - margin: 0;
9 - padding: 0;
10 - border: 0;
11 - background: none;
12 - font-size: 100%;
13 - vertical-align: baseline;
14 - font-family: inherit;
15 - color: inherit;
16 - -webkit-appearance: none;
17 - /*-moz-appearance: none;*/
18 - -ms-appearance: none;
19 - -o-appearance: none;
20 - appearance: none;
21 -}
22 -
23 -body {
24 - font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif;
25 - line-height: 1.4em;
26 - background: #eaeaea url('bg.png');
27 - color: #4d4d4d;
28 - width: 550px;
29 - margin: 0 auto;
30 - -webkit-font-smoothing: antialiased;
31 - -moz-font-smoothing: antialiased;
32 - -ms-font-smoothing: antialiased;
33 - -o-font-smoothing: antialiased;
34 - font-smoothing: antialiased;
35 -}
36 -
37 -.todoapp {
38 - background: #fff;
39 - background: rgba(255, 255, 255, 0.9);
40 - margin: 130px 0 40px 0;
41 - border: 1px solid #ccc;
42 - position: relative;
43 - border-top-left-radius: 2px;
44 - border-top-right-radius: 2px;
45 - box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.2),
46 - 0 25px 50px 0 rgba(0, 0, 0, 0.15);
47 -}
48 -
49 -.todoapp:before {
50 - content: '';
51 - border-left: 1px solid #f5d6d6;
52 - border-right: 1px solid #f5d6d6;
53 - width: 2px;
54 - position: absolute;
55 - top: 0;
56 - left: 40px;
57 - height: 100%;
58 -}
59 -
60 -.todoapp input::-webkit-input-placeholder {
61 - font-style: italic;
62 -}
63 -
64 -.todoapp input:-moz-placeholder {
65 - font-style: italic;
66 - color: #a9a9a9;
67 -}
68 -
69 -.todoapp h1 {
70 - position: absolute;
71 - top: -120px;
72 - width: 100%;
73 - font-size: 70px;
74 - font-weight: bold;
75 - text-align: center;
76 - color: #b3b3b3;
77 - color: rgba(255, 255, 255, 0.3);
78 - text-shadow: -1px -1px rgba(0, 0, 0, 0.2);
79 - -webkit-text-rendering: optimizeLegibility;
80 - -moz-text-rendering: optimizeLegibility;
81 - -ms-text-rendering: optimizeLegibility;
82 - -o-text-rendering: optimizeLegibility;
83 - text-rendering: optimizeLegibility;
84 -}
85 -
86 -.header {
87 - padding-top: 15px;
88 - border-radius: inherit;
89 -}
90 -
91 -.header:before {
92 - content: '';
93 - position: absolute;
94 - top: 0;
95 - right: 0;
96 - left: 0;
97 - height: 15px;
98 - z-index: 2;
99 - border-bottom: 1px solid #6c615c;
100 - background: #8d7d77;
101 - background: -webkit-gradient(linear, left top, left bottom, from(rgba(132, 110, 100, 0.8)),to(rgba(101, 84, 76, 0.8)));
102 - background: -webkit-linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
103 - background: -moz-linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
104 - background: -o-linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
105 - background: -ms-linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
106 - background: linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
107 - filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#9d8b83', EndColorStr='#847670');
108 - border-top-left-radius: 1px;
109 - border-top-right-radius: 1px;
110 -}
111 -
112 -.new-todo,
113 -.edit {
114 - position: relative;
115 - margin: 0;
116 - width: 100%;
117 - font-size: 24px;
118 - font-family: inherit;
119 - line-height: 1.4em;
120 - border: 0;
121 - outline: none;
122 - color: inherit;
123 - padding: 6px;
124 - border: 1px solid #999;
125 - box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2);
126 - -webkit-box-sizing: border-box;
127 - -moz-box-sizing: border-box;
128 - -ms-box-sizing: border-box;
129 - -o-box-sizing: border-box;
130 - box-sizing: border-box;
131 - -webkit-font-smoothing: antialiased;
132 - -moz-font-smoothing: antialiased;
133 - -ms-font-smoothing: antialiased;
134 - -o-font-smoothing: antialiased;
135 - font-smoothing: antialiased;
136 -}
137 -
138 -.new-todo {
139 - padding: 16px 16px 16px 60px;
140 - border: none;
141 - background: rgba(0, 0, 0, 0.02);
142 - z-index: 2;
143 - box-shadow: none;
144 -}
145 -
146 -.main {
147 - position: relative;
148 - z-index: 2;
149 - border-top: 1px dotted #adadad;
150 -}
151 -
152 -.toggle-all-label {
153 - display: none;
154 -}
155 -
156 -.toggle-all {
157 - position: absolute;
158 - top: -42px;
159 - left: -4px;
160 - width: 40px;
161 - text-align: center;
162 - border: none; /* Mobile Safari */
163 -}
164 -
165 -.toggle-all:before {
166 - content: '»';
167 - font-size: 28px;
168 - color: #d9d9d9;
169 - padding: 0 25px 7px;
170 -}
171 -
172 -.toggle-all:checked:before {
173 - color: #737373;
174 -}
175 -
176 -.todo-list {
177 - margin: 0;
178 - padding: 0;
179 - list-style: none;
180 -}
181 -
182 -.todo-list li {
183 - position: relative;
184 - font-size: 24px;
185 - border-bottom: 1px dotted #ccc;
186 -}
187 -
188 -.todo-list li:last-child {
189 - border-bottom: none;
190 -}
191 -
192 -.todo-list li.editing {
193 - border-bottom: none;
194 - padding: 0;
195 -}
196 -
197 -.todo-list li.editing .edit {
198 - display: block;
199 - width: 506px;
200 - padding: 13px 17px 12px 17px;
201 - margin: 0 0 0 43px;
202 -}
203 -
204 -.todo-list li.editing .view {
205 - display: none;
206 -}
207 -
208 -.todo-list li .toggle {
209 - text-align: center;
210 - width: 40px;
211 - /* auto, since non-WebKit browsers doesn't support input styling */
212 - height: auto;
213 - position: absolute;
214 - top: 0;
215 - bottom: 0;
216 - margin: auto 0;
217 - border: none; /* Mobile Safari */
218 - -webkit-appearance: none;
219 - /*-moz-appearance: none;*/
220 - -ms-appearance: none;
221 - -o-appearance: none;
222 - appearance: none;
223 -}
224 -
225 -.todo-list li .toggle:after {
226 - content: '✔';
227 - line-height: 43px; /* 40 + a couple of pixels visual adjustment */
228 - font-size: 20px;
229 - color: #d9d9d9;
230 - text-shadow: 0 -1px 0 #bfbfbf;
231 -}
232 -
233 -.todo-list li .toggle:checked:after {
234 - color: #85ada7;
235 - text-shadow: 0 1px 0 #669991;
236 - bottom: 1px;
237 - position: relative;
238 -}
239 -
240 -.todo-list li label {
241 - word-break: break-word;
242 - padding: 15px;
243 - margin-left: 45px;
244 - display: block;
245 - line-height: 1.2;
246 - -webkit-transition: color 0.4s;
247 - -moz-transition: color 0.4s;
248 - -ms-transition: color 0.4s;
249 - -o-transition: color 0.4s;
250 - transition: color 0.4s;
251 -}
252 -
253 -.todo-list li.completed label {
254 - color: #a9a9a9;
255 - text-decoration: line-through;
256 -}
257 -
258 -.todo-list li .destroy {
259 - display: none;
260 - position: absolute;
261 - top: 0;
262 - right: 10px;
263 - bottom: 0;
264 - width: 40px;
265 - height: 40px;
266 - margin: auto 0;
267 - font-size: 22px;
268 - color: #a88a8a;
269 - -webkit-transition: all 0.2s;
270 - -moz-transition: all 0.2s;
271 - -ms-transition: all 0.2s;
272 - -o-transition: all 0.2s;
273 - transition: all 0.2s;
274 -}
275 -
276 -.todo-list li .destroy:hover {
277 - text-shadow: 0 0 1px #000,
278 - 0 0 10px rgba(199, 107, 107, 0.8);
279 - -webkit-transform: scale(1.3);
280 - -moz-transform: scale(1.3);
281 - -ms-transform: scale(1.3);
282 - -o-transform: scale(1.3);
283 - transform: scale(1.3);
284 -}
285 -
286 -.todo-list li .destroy:after {
287 - content: '✖';
288 -}
289 -
290 -.todo-list li:hover .destroy {
291 - display: block;
292 -}
293 -
294 -.todo-list li .edit {
295 - display: none;
296 -}
297 -
298 -.todo-list li.editing:last-child {
299 - margin-bottom: -1px;
300 -}
301 -
302 -.footer {
303 - color: #777;
304 - padding: 0 15px;
305 - position: absolute;
306 - right: 0;
307 - bottom: -31px;
308 - left: 0;
309 - height: 20px;
310 - z-index: 1;
311 - text-align: center;
312 -}
313 -
314 -.footer:before {
315 - content: '';
316 - position: absolute;
317 - right: 0;
318 - bottom: 31px;
319 - left: 0;
320 - height: 50px;
321 - z-index: -1;
322 - box-shadow: 0 1px 1px rgba(0, 0, 0, 0.3),
323 - 0 6px 0 -3px rgba(255, 255, 255, 0.8),
324 - 0 7px 1px -3px rgba(0, 0, 0, 0.3),
325 - 0 43px 0 -6px rgba(255, 255, 255, 0.8),
326 - 0 44px 2px -6px rgba(0, 0, 0, 0.2);
327 -}
328 -
329 -.todo-count {
330 - float: left;
331 - text-align: left;
332 -}
333 -
334 -.filters {
335 - margin: 0;
336 - padding: 0;
337 - list-style: none;
338 - position: absolute;
339 - right: 0;
340 - left: 0;
341 -}
342 -
343 -.filters li {
344 - display: inline;
345 -}
346 -
347 -.filters li a {
348 - color: #83756f;
349 - margin: 2px;
350 - text-decoration: none;
351 -}
352 -
353 -.filters li a.selected {
354 - font-weight: bold;
355 -}
356 -
357 -.clear-completed {
358 - float: right;
359 - position: relative;
360 - line-height: 20px;
361 - text-decoration: none;
362 - background: rgba(0, 0, 0, 0.1);
363 - font-size: 11px;
364 - padding: 0 10px;
365 - border-radius: 3px;
366 - box-shadow: 0 -1px 0 0 rgba(0, 0, 0, 0.2);
367 -}
368 -
369 -.clear-completed:hover {
370 - background: rgba(0, 0, 0, 0.15);
371 - box-shadow: 0 -1px 0 0 rgba(0, 0, 0, 0.3);
372 -}
373 -
374 -.info {
375 - margin: 65px auto 0;
376 - color: #a6a6a6;
377 - font-size: 12px;
378 - text-shadow: 0 1px 0 rgba(255, 255, 255, 0.7);
379 - text-align: center;
380 -}
381 -
382 -.info a {
383 - color: inherit;
384 -}
385 -
386 -/*
387 - Hack to remove background from Mobile Safari.
388 - Can't use it globally since it destroys checkboxes in Firefox and Opera
389 -*/
390 -@media screen and (-webkit-min-device-pixel-ratio:0) {
391 - .toggle-all,
392 - .todo-list li .toggle {
393 - background: none;
394 - }
395 -
396 - .todo-list li .toggle {
397 - height: 40px;
398 - }
399 -
400 - .toggle-all {
401 - top: -56px;
402 - left: -15px;
403 - width: 65px;
404 - height: 41px;
405 - -webkit-transform: rotate(90deg);
406 - transform: rotate(90deg);
407 - -webkit-appearance: none;
408 - appearance: none;
409 - }
410 -}
411 -
412 -.hidden{
413 - display:none;
414 -}
415 -
416 -#benchmark {
417 - position: absolute;
418 - left: 0;
419 - top: 0;
420 - padding: 10px;
421 -}
422 -
423 -.submitButton {
424 - display: none;
425 -}
examples/todomvc/css/bg.png
Binary files a/examples/todomvc/css/bg.png and /dev/null differ
examples/todomvc/index.html deleted
-19
@@ -1,19 +0,0 @@
1 -<!doctype html>
2 -<html lang="en">
3 - <head>
4 - <meta charset="utf-8">
5 - <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
6 - <title>React • TodoMVC</title>
7 - <link rel="stylesheet" href="css/base.css">
8 - <!--[if IE]>
9 - <script src="js/ie.js"></script>
10 - <![endif]-->
11 - </head>
12 - <body>
13 - <div id="todoapp"></div>
14 - <div id="benchmark"></div>
15 - <script src="../../build/react.js"></script>
16 - <script src="../../build/JSXTransformer.js"></script>
17 - <script type="text/jsx" src="js/app.js"></script>
18 - </body>
19 -</html>
examples/todomvc/js/app.js deleted
-255
@@ -1,255 +0,0 @@
1 -/**
2 - * @jsx React.DOM
3 - */
4 -
5 -var Utils = {
6 - // https://gist.github.com/1308368
7 - uuid: function(a,b){for(b=a='';a++<36;b+=a*51&52?(a^15?8^Math.random()*(a^20?16:4):4).toString(16):'-');return b},
8 - pluralize: function( count, word ) {
9 - return count === 1 ? word : word + 's';
10 - },
11 - store: function( namespace, data ) {
12 - if ( arguments.length > 1 ) {
13 - return localStorage.setItem( namespace, JSON.stringify( data ) );
14 - } else {
15 - var store = localStorage.getItem( namespace );
16 - return ( store && JSON.parse( store ) ) || [];
17 - }
18 - }
19 -};
20 -
21 -function cx(obj) {
22 - var s = '';
23 - for (var key in obj) {
24 - if (!obj.hasOwnProperty(key)) {
25 - continue;
26 - }
27 - if (obj[key]) {
28 - s += key + ' ';
29 - }
30 - }
31 - return s;
32 -}
33 -
34 -var TodoItem = React.createClass({
35 - handleSubmit: function() {
36 - var val = this.state.editText;
37 - if (val) {
38 - this.props.onSave(val);
39 - this.setState({editField: ''});
40 - }
41 - return false;
42 - },
43 - handleEdit: function() {
44 - this.props.onEdit();
45 - this.refs.editField.getDOMNode().focus();
46 - },
47 - handleKey: function(event) {
48 - if (event.nativeEvent.keyCode === 27) {
49 - this.handleSubmit();
50 - }
51 - this.setState({editText: event.target.value});
52 - },
53 - getInitialState: function() {
54 - return {editText: this.props.todo.title};
55 - },
56 - componentWillReceiveProps: function(nextProps) {
57 - if (nextProps.todo.title !== this.props.todo.title) {
58 - this.setState(this.getInitialState());
59 - }
60 - },
61 - render: function() {
62 - return (
63 - <li class={cx({completed: this.props.todo.completed, editing: this.props.editing})}>
64 - <div class="view">
65 - <input
66 - class="toggle"
67 - type="checkbox"
68 - checked={this.props.todo.completed ? 'checked' : null}
69 - onChange={this.props.onToggle}
70 - />
71 - <label onDoubleClick={this.handleEdit}>{this.props.todo.title}</label>
72 - <button class="destroy" onClick={this.props.onDestroy} />
73 - </div>
74 - <form onSubmit={this.handleSubmit}>
75 - <input
76 - ref="editField"
77 - class="edit"
78 - value={this.state.editText}
79 - onBlur={this.handleSubmit}
80 - onKeyUp={this.handleKey}
81 - />
82 - <input type="submit" class="submitButton" />
83 - </form>
84 - </li>
85 - );
86 - }
87 -});
88 -
89 -var TodoFooter = React.createClass({
90 - render: function() {
91 - var activeTodoWord = Utils.pluralize(this.props.count, 'todo');
92 - var clearButton = null;
93 -
94 - if (this.props.completedCount > 0) {
95 - clearButton = (
96 - <button class="clear-completed" onClick={this.props.onClearCompleted}>Clear completed ({this.props.completedCount})</button>
97 - );
98 - }
99 -
100 - return (
101 - <footer class="footer">
102 - <span class="todo-count"><strong>{this.props.count}</strong>{' '}{activeTodoWord}{' '}left</span>
103 - {clearButton}
104 - </footer>
105 - );
106 - }
107 -});
108 -
109 -var TodoApp = React.createClass({
110 - getInitialState: function() {
111 - return {
112 - todos: Utils.store('react-todos'),
113 - editing: {}
114 - };
115 - },
116 -
117 - handleSubmit: function() {
118 - var val = this.refs.newField.getDOMNode().value.trim();
119 - if (val) {
120 - var todos = this.state.todos;
121 - var newTodo = {
122 - id: Utils.uuid(),
123 - title: val,
124 - completed: false
125 - };
126 - this.setState({todos: todos.concat([newTodo])});
127 - this.refs.newField.getDOMNode().value = '';
128 - }
129 - return false;
130 - },
131 -
132 - toggleAll: function(event) {
133 - var checked = event.nativeEvent.target.checked;
134 - this.state.todos.map(function(todo) {
135 - todo.completed = checked;
136 - });
137 - this.setState({todos: this.state.todos});
138 - },
139 -
140 - toggle: function(todo) {
141 - todo.completed = !todo.completed;
142 - this.setState({todos: this.state.todos});
143 - },
144 -
145 - destroy: function(todo) {
146 - var newTodos = this.state.todos.filter(function(candidate) {
147 - return candidate.id !== todo.id;
148 - });
149 - this.setState({todos: newTodos});
150 - },
151 -
152 - edit: function(todo) {
153 - this.state.todos.map(function(todo) {
154 - this.state.editing[todo.id] = false;
155 - }.bind(this));
156 - this.state.editing[todo.id] = true;
157 - this.setState({editing: this.state.editing});
158 - },
159 -
160 - save: function(todo, text) {
161 - todo.title = text;
162 - this.state.editing[todo.id] = false;
163 - this.setState({todos: this.state.todos, editing: this.state.editing});
164 - },
165 -
166 - clearCompleted: function() {
167 - var newTodos = this.state.todos.filter(function(todo) {
168 - return !todo.completed;
169 - });
170 - this.setState({todos: newTodos});
171 - },
172 -
173 - render: function() {
174 - Utils.store('react-todos', this.state.todos);
175 - var footer = null;
176 - var main = null;
177 - var todoItems = this.state.todos.map(function(todo) {
178 - return (
179 - <TodoItem
180 - todo={todo}
181 - onToggle={this.toggle.bind(this, todo)}
182 - onDestroy={this.destroy.bind(this, todo)}
183 - onEdit={this.edit.bind(this, todo)}
184 - editing={this.state.editing[todo.id]}
185 - onSave={this.save.bind(this, todo)}
186 - />
187 - );
188 - }.bind(this));
189 -
190 - var activeTodoCount = this.state.todos.filter(function(todo) {
191 - return !todo.completed;
192 - }).length;
193 - var completedCount = todoItems.length - activeTodoCount;
194 - if (activeTodoCount || completedCount) {
195 - footer =
196 - <TodoFooter
197 - count={activeTodoCount}
198 - completedCount={completedCount}
199 - onClearCompleted={this.clearCompleted.bind(this)}
200 - />;
201 - }
202 -
203 - if (todoItems.length) {
204 - main = (
205 - <section class="main">
206 - <input class="toggle-all" type="checkbox" onChange={this.toggleAll.bind(this)} />
207 - <label class="toggle-all-label">Mark all as complete</label>
208 - <ul class="todo-list">
209 - {todoItems}
210 - </ul>
211 - </section>
212 - );
213 - }
214 -
215 - return (
216 - <div>
217 - <section class="todoapp">
218 - <header class="header">
219 - <h1>todos</h1>
220 - <form onSubmit={this.handleSubmit}>
221 - <input
222 - ref="newField"
223 - class="new-todo"
224 - placeholder="What needs to be done?"
225 - autofocus="autofocus"
226 - />
227 - <input type="submit" class="submitButton" />
228 - </form>
229 - </header>
230 - {main}
231 - {footer}
232 - </section>
233 - <footer class="info">
234 - <p>Double-click to edit a todo</p>
235 - <p>Created by{' '}<a href="http://github.com/petehunt/">petehunt</a></p>
236 - <p>Part of{' '}<a href="http://todomvc.com">TodoMVC</a></p>
237 - </footer>
238 - </div>
239 - );
240 - }
241 -});
242 -
243 -React.renderComponent(<TodoApp />, document.getElementById('todoapp'));
244 -
245 -// Some benchmarking that requires either a custom build of React or more
246 -// modules exposed from React.*
247 -// var initTime = ReactMount.totalInstantiationTime + ReactMount.totalInjectionTime;
248 -// var benchmark = document.getElementById('benchmark');
249 -// setInterval(function() {
250 -// benchmark.innerHTML = (
251 -// 'Init render time = ' + initTime + 'ms' +
252 -// '<br />' +
253 -// 'Post-init render time = ' + (ReactMount.totalInstantiationTime + ReactMount.totalInjectionTime - initTime) + 'ms'
254 -// );
255 -// }, 1000);
examples/todomvc/js/ie.js deleted
-34
@@ -1,34 +0,0 @@
1 -/*! HTML5 Shiv pre3.6 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
2 - Uncompressed source: https://github.com/aFarkas/html5shiv */
3 - (function(l,f){function m(){var a=e.elements;return"string"==typeof a?a.split(" "):a}function i(a){var b=n[a[o]];b||(b={},h++,a[o]=h,n[h]=b);return b}function p(a,b,c){b||(b=f);if(g)return b.createElement(a);c||(c=i(b));b=c.cache[a]?c.cache[a].cloneNode():r.test(a)?(c.cache[a]=c.createElem(a)).cloneNode():c.createElem(a);return b.canHaveChildren&&!s.test(a)?c.frag.appendChild(b):b}function t(a,b){if(!b.cache)b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag();
4 - a.createElement=function(c){return!e.shivMethods?b.createElem(c):p(c,a,b)};a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+m().join().replace(/\w+/g,function(a){b.createElem(a);b.frag.createElement(a);return'c("'+a+'")'})+");return n}")(e,b.frag)}function q(a){a||(a=f);var b=i(a);if(e.shivCSS&&!j&&!b.hasCSS){var c,d=a;c=d.createElement("p");d=d.getElementsByTagName("head")[0]||d.documentElement;c.innerHTML="x<style>article,aside,figcaption,figure,footer,header,hgroup,nav,section{display:block}mark{background:#FF0;color:#000}</style>";
5 - c=d.insertBefore(c.lastChild,d.firstChild);b.hasCSS=!!c}g||t(a,b);return a}var k=l.html5||{},s=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,r=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,j,o="_html5shiv",h=0,n={},g;(function(){try{var a=f.createElement("a");a.innerHTML="<xyz></xyz>";j="hidden"in a;var b;if(!(b=1==a.childNodes.length)){f.createElement("a");var c=f.createDocumentFragment();b="undefined"==typeof c.cloneNode||
6 - "undefined"==typeof c.createDocumentFragment||"undefined"==typeof c.createElement}g=b}catch(d){g=j=!0}})();var e={elements:k.elements||"abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video",shivCSS:!1!==k.shivCSS,supportsUnknownElements:g,shivMethods:!1!==k.shivMethods,type:"default",shivDocument:q,createElement:p,createDocumentFragment:function(a,b){a||(a=f);if(g)return a.createDocumentFragment();
7 - for(var b=b||i(a),c=b.frag.cloneNode(),d=0,e=m(),h=e.length;d<h;d++)c.createElement(e[d]);return c}};l.html5=e;q(f)})(this,document);
8 -
9 -/* ES5-shim
10 -https://github.com/kriskowal/es5-shim
11 -Copyright 2009-2012 by contributors, MIT License */
12 -(function(definition){if(typeof define=="function")define(definition);else if(typeof YUI=="function")YUI.add("es5",definition);else definition()})(function(){if(!Function.prototype.bind)Function.prototype.bind=function bind(that){var target=this;if(typeof target!="function")throw new TypeError("Function.prototype.bind called on incompatible "+target);var args=slice.call(arguments,1);var bound=function(){if(this instanceof bound){var result=target.apply(this,args.concat(slice.call(arguments)));if(Object(result)===
13 -result)return result;return this}else return target.apply(that,args.concat(slice.call(arguments)))};if(target.prototype)bound.prototype=Object.create(target.prototype);return bound};var call=Function.prototype.call;var prototypeOfArray=Array.prototype;var prototypeOfObject=Object.prototype;var slice=prototypeOfArray.slice;var _toString=call.bind(prototypeOfObject.toString);var owns=call.bind(prototypeOfObject.hasOwnProperty);var defineGetter;var defineSetter;var lookupGetter;var lookupSetter;var supportsAccessors;
14 -if(supportsAccessors=owns(prototypeOfObject,"__defineGetter__")){defineGetter=call.bind(prototypeOfObject.__defineGetter__);defineSetter=call.bind(prototypeOfObject.__defineSetter__);lookupGetter=call.bind(prototypeOfObject.__lookupGetter__);lookupSetter=call.bind(prototypeOfObject.__lookupSetter__)}if([1,2].splice(0).length!=2){var array_splice=Array.prototype.splice;Array.prototype.splice=function(start,deleteCount){if(!arguments.length)return[];else return array_splice.apply(this,[start===void 0?
15 -0:start,deleteCount===void 0?this.length-start:deleteCount].concat(slice.call(arguments,2)))}}if(!Array.isArray)Array.isArray=function isArray(obj){return _toString(obj)=="[object Array]"};var boxedString=Object("a"),splitString=boxedString[0]!="a"||!(0 in boxedString);if(!Array.prototype.forEach)Array.prototype.forEach=function forEach(fun){var object=toObject(this),self=splitString&&_toString(this)=="[object String]"?this.split(""):object,thisp=arguments[1],i=-1,length=self.length>>>0;if(_toString(fun)!=
16 -"[object Function]")throw new TypeError;while(++i<length)if(i in self)fun.call(thisp,self[i],i,object)};if(!Array.prototype.map)Array.prototype.map=function map(fun){var object=toObject(this),self=splitString&&_toString(this)=="[object String]"?this.split(""):object,length=self.length>>>0,result=Array(length),thisp=arguments[1];if(_toString(fun)!="[object Function]")throw new TypeError(fun+" is not a function");for(var i=0;i<length;i++)if(i in self)result[i]=fun.call(thisp,self[i],i,object);return result};
17 -if(!Array.prototype.filter)Array.prototype.filter=function filter(fun){var object=toObject(this),self=splitString&&_toString(this)=="[object String]"?this.split(""):object,length=self.length>>>0,result=[],value,thisp=arguments[1];if(_toString(fun)!="[object Function]")throw new TypeError(fun+" is not a function");for(var i=0;i<length;i++)if(i in self){value=self[i];if(fun.call(thisp,value,i,object))result.push(value)}return result};if(!Array.prototype.every)Array.prototype.every=function every(fun){var object=
18 -toObject(this),self=splitString&&_toString(this)=="[object String]"?this.split(""):object,length=self.length>>>0,thisp=arguments[1];if(_toString(fun)!="[object Function]")throw new TypeError(fun+" is not a function");for(var i=0;i<length;i++)if(i in self&&!fun.call(thisp,self[i],i,object))return false;return true};if(!Array.prototype.some)Array.prototype.some=function some(fun){var object=toObject(this),self=splitString&&_toString(this)=="[object String]"?this.split(""):object,length=self.length>>>
19 -0,thisp=arguments[1];if(_toString(fun)!="[object Function]")throw new TypeError(fun+" is not a function");for(var i=0;i<length;i++)if(i in self&&fun.call(thisp,self[i],i,object))return true;return false};if(!Array.prototype.reduce)Array.prototype.reduce=function reduce(fun){var object=toObject(this),self=splitString&&_toString(this)=="[object String]"?this.split(""):object,length=self.length>>>0;if(_toString(fun)!="[object Function]")throw new TypeError(fun+" is not a function");if(!length&&arguments.length==
20 -1)throw new TypeError("reduce of empty array with no initial value");var i=0;var result;if(arguments.length>=2)result=arguments[1];else{do{if(i in self){result=self[i++];break}if(++i>=length)throw new TypeError("reduce of empty array with no initial value");}while(true)}for(;i<length;i++)if(i in self)result=fun.call(void 0,result,self[i],i,object);return result};if(!Array.prototype.reduceRight)Array.prototype.reduceRight=function reduceRight(fun){var object=toObject(this),self=splitString&&_toString(this)==
21 -"[object String]"?this.split(""):object,length=self.length>>>0;if(_toString(fun)!="[object Function]")throw new TypeError(fun+" is not a function");if(!length&&arguments.length==1)throw new TypeError("reduceRight of empty array with no initial value");var result,i=length-1;if(arguments.length>=2)result=arguments[1];else{do{if(i in self){result=self[i--];break}if(--i<0)throw new TypeError("reduceRight of empty array with no initial value");}while(true)}do if(i in this)result=fun.call(void 0,result,
22 -self[i],i,object);while(i--);return result};if(!Array.prototype.indexOf||[0,1].indexOf(1,2)!=-1)Array.prototype.indexOf=function indexOf(sought){var self=splitString&&_toString(this)=="[object String]"?this.split(""):toObject(this),length=self.length>>>0;if(!length)return-1;var i=0;if(arguments.length>1)i=toInteger(arguments[1]);i=i>=0?i:Math.max(0,length+i);for(;i<length;i++)if(i in self&&self[i]===sought)return i;return-1};if(!Array.prototype.lastIndexOf||[0,1].lastIndexOf(0,-3)!=-1)Array.prototype.lastIndexOf=
23 -function lastIndexOf(sought){var self=splitString&&_toString(this)=="[object String]"?this.split(""):toObject(this),length=self.length>>>0;if(!length)return-1;var i=length-1;if(arguments.length>1)i=Math.min(i,toInteger(arguments[1]));i=i>=0?i:length-Math.abs(i);for(;i>=0;i--)if(i in self&&sought===self[i])return i;return-1};if(!Object.keys){var hasDontEnumBug=true,dontEnums=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],dontEnumsLength=
24 -dontEnums.length;for(var key in{"toString":null})hasDontEnumBug=false;Object.keys=function keys(object){if(typeof object!="object"&&typeof object!="function"||object===null)throw new TypeError("Object.keys called on a non-object");var keys=[];for(var name in object)if(owns(object,name))keys.push(name);if(hasDontEnumBug)for(var i=0,ii=dontEnumsLength;i<ii;i++){var dontEnum=dontEnums[i];if(owns(object,dontEnum))keys.push(dontEnum)}return keys}}var negativeDate=-621987552E5,negativeYearString="-000001";
25 -if(!Date.prototype.toISOString||(new Date(negativeDate)).toISOString().indexOf(negativeYearString)===-1)Date.prototype.toISOString=function toISOString(){var result,length,value,year,month;if(!isFinite(this))throw new RangeError("Date.prototype.toISOString called on non-finite value.");year=this.getUTCFullYear();month=this.getUTCMonth();year+=Math.floor(month/12);month=(month%12+12)%12;result=[month+1,this.getUTCDate(),this.getUTCHours(),this.getUTCMinutes(),this.getUTCSeconds()];year=(year<0?"-":
26 -year>9999?"+":"")+("00000"+Math.abs(year)).slice(0<=year&&year<=9999?-4:-6);length=result.length;while(length--){value=result[length];if(value<10)result[length]="0"+value}return year+"-"+result.slice(0,2).join("-")+"T"+result.slice(2).join(":")+"."+("000"+this.getUTCMilliseconds()).slice(-3)+"Z"};var dateToJSONIsSupported=false;try{dateToJSONIsSupported=Date.prototype.toJSON&&(new Date(NaN)).toJSON()===null&&(new Date(negativeDate)).toJSON().indexOf(negativeYearString)!==-1&&Date.prototype.toJSON.call({toISOString:function(){return true}})}catch(e){}if(!dateToJSONIsSupported)Date.prototype.toJSON=
27 -function toJSON(key){var o=Object(this),tv=toPrimitive(o),toISO;if(typeof tv==="number"&&!isFinite(tv))return null;toISO=o.toISOString;if(typeof toISO!="function")throw new TypeError("toISOString property is not callable");return toISO.call(o)};if(!Date.parse||"Date.parse is buggy")Date=function(NativeDate){function Date(Y,M,D,h,m,s,ms){var length=arguments.length;if(this instanceof NativeDate){var date=length==1&&String(Y)===Y?new NativeDate(Date.parse(Y)):length>=7?new NativeDate(Y,M,D,h,m,s,ms):
28 -length>=6?new NativeDate(Y,M,D,h,m,s):length>=5?new NativeDate(Y,M,D,h,m):length>=4?new NativeDate(Y,M,D,h):length>=3?new NativeDate(Y,M,D):length>=2?new NativeDate(Y,M):length>=1?new NativeDate(Y):new NativeDate;date.constructor=Date;return date}return NativeDate.apply(this,arguments)}var isoDateExpression=new RegExp("^"+"(\\d{4}|[+-]\\d{6})"+"(?:-(\\d{2})"+"(?:-(\\d{2})"+"(?:"+"T(\\d{2})"+":(\\d{2})"+"(?:"+":(\\d{2})"+"(?:\\.(\\d{3}))?"+")?"+"("+"Z|"+"(?:"+"([-+])"+"(\\d{2})"+":(\\d{2})"+")"+")?)?)?)?"+
29 -"$");var months=[0,31,59,90,120,151,181,212,243,273,304,334,365];function dayFromMonth(year,month){var t=month>1?1:0;return months[month]+Math.floor((year-1969+t)/4)-Math.floor((year-1901+t)/100)+Math.floor((year-1601+t)/400)+365*(year-1970)}for(var key in NativeDate)Date[key]=NativeDate[key];Date.now=NativeDate.now;Date.UTC=NativeDate.UTC;Date.prototype=NativeDate.prototype;Date.prototype.constructor=Date;Date.parse=function parse(string){var match=isoDateExpression.exec(string);if(match){var year=
30 -Number(match[1]),month=Number(match[2]||1)-1,day=Number(match[3]||1)-1,hour=Number(match[4]||0),minute=Number(match[5]||0),second=Number(match[6]||0),millisecond=Number(match[7]||0),offset=!match[4]||match[8]?0:Number(new NativeDate(1970,0)),signOffset=match[9]==="-"?1:-1,hourOffset=Number(match[10]||0),minuteOffset=Number(match[11]||0),result;if(hour<(minute>0||second>0||millisecond>0?24:25)&&minute<60&&second<60&&millisecond<1E3&&month>-1&&month<12&&hourOffset<24&&minuteOffset<60&&day>-1&&day<dayFromMonth(year,
31 -month+1)-dayFromMonth(year,month)){result=((dayFromMonth(year,month)+day)*24+hour+hourOffset*signOffset)*60;result=((result+minute+minuteOffset*signOffset)*60+second)*1E3+millisecond+offset;if(-864E13<=result&&result<=864E13)return result}return NaN}return NativeDate.parse.apply(this,arguments)};return Date}(Date);if(!Date.now)Date.now=function now(){return(new Date).getTime()};if("0".split(void 0,0).length){var string_split=String.prototype.split;String.prototype.split=function(separator,limit){if(separator===
32 -void 0&&limit===0)return[];return string_split.apply(this,arguments)}}if("".substr&&"0b".substr(-1)!=="b"){var string_substr=String.prototype.substr;String.prototype.substr=function(start,length){return string_substr.call(this,start<0?(start=this.length+start)<0?0:start:start,length)}}var ws="\t\n\x0B\f\r \u00a0\u1680\u180e\u2000\u2001\u2002\u2003"+"\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028"+"\u2029\ufeff";if(!String.prototype.trim||ws.trim()){ws="["+ws+"]";var trimBeginRegexp=
33 -new RegExp("^"+ws+ws+"*"),trimEndRegexp=new RegExp(ws+ws+"*$");String.prototype.trim=function trim(){if(this===undefined||this===null)throw new TypeError("can't convert "+this+" to object");return String(this).replace(trimBeginRegexp,"").replace(trimEndRegexp,"")}}function toInteger(n){n=+n;if(n!==n)n=0;else if(n!==0&&n!==1/0&&n!==-(1/0))n=(n>0||-1)*Math.floor(Math.abs(n));return n}function isPrimitive(input){var type=typeof input;return input===null||type==="undefined"||type==="boolean"||type===
34 -"number"||type==="string"}function toPrimitive(input){var val,valueOf,toString;if(isPrimitive(input))return input;valueOf=input.valueOf;if(typeof valueOf==="function"){val=valueOf.call(input);if(isPrimitive(val))return val}toString=input.toString;if(typeof toString==="function"){val=toString.call(input);if(isPrimitive(val))return val}throw new TypeError;}var toObject=function(o){if(o==null)throw new TypeError("can't convert "+o+" to object");return Object(o)}});