{"id":221171,"date":"2014-04-29T01:20:03","date_gmt":"2014-04-28T21:20:03","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=221171"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=221171","title":{"rendered":"<span class=\"post_title\">\u0421\u0447\u0435\u0442 \u043d\u0430 \u043e\u043f\u043b\u0430\u0442\u0443. \u0420\u0430\u0431\u043e\u0447\u0435\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043d\u0430 sails.js, ractive.js, Backbone.js<\/span>"},"content":{"rendered":"<div class=\"content html_format\">   \t<img decoding=\"async\" src=\"http:\/\/habrastorage.org\/files\/88f\/b6a\/e18\/88fb6ae1887d4fdab691e9e985a18894.png\"\/><\/p>\n<p>  \u0414\u043e\u0431\u0440\u043e\u0433\u043e \u0434\u043d\u044f, \u043d\u0430 \u0432\u044b\u0445\u043e\u0434\u043d\u044b\u0445 \u043e\u0442 \u0441\u043a\u0443\u043a\u0438 \u0438 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0440\u0435\u0448\u0438\u043b \u0441\u0435\u0431\u044f \u0440\u0430\u0437\u0432\u043b\u0435\u0447\u044c \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u0435\u043c \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0441\u0433\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0443\u0447\u0435\u0431\u043d\u043e\u0433\u043e \u043c\u0435\u0442\u0430\u0440\u0438\u0430\u043b\u0430 \u0434\u043b\u044f \u0438\u0437\u0443\u0447\u0435\u043d\u0438\u044f \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439 \u0434\u0432\u0443\u0445 \u0437\u0430\u043c\u0435\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a \u2014 <a href=\"http:\/\/ractivejs.org\/\">ractive.js<\/a> \u0438 <a href=\"http:\/\/sailsjs.org\">sails.js<\/a> <\/p>\n<h5>\u041f\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0437\u0430\u0434\u0430\u0447\u0438<\/h5>\n<p>  \u041f\u043e \u0440\u0430\u0431\u043e\u0442\u0435 \u0447\u0430\u0441\u0442\u043e \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043f\u043e\u0441\u043b\u0435 \u0432\u044b\u043f\u043e\u043b\u0435\u043d\u0435\u043d\u0438\u044f \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u0433\u043e \u0437\u0430\u0434\u0430\u043d\u0438\u044f (\u044f \u2014 \u0444\u0440\u0438\u043b\u0430\u043d\u0441\u0435\u0440) \u0432\u044b\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u0437\u0430\u043a\u0430\u0437\u0447\u0438\u043a\u0443 \u0441\u0447\u0435\u0442 \u043d\u0430 \u043e\u043f\u043b\u0430\u0442\u0443 \u0443\u0441\u043b\u0443\u0433. \u0422\u0435\u043c \u0431\u043e\u043b\u0435\u0435 \u0435\u0441\u043b\u0438 \u0438\u043c\u0435\u0435\u0448\u044c \u0434\u0435\u043b\u043e \u0441 \u044e\u0440\u0438\u0434\u0438\u0447\u0435\u0441\u043a\u0438\u043c\u0438 \u043b\u0438\u0446\u0430\u043c\u0438. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b \u043f\u0440\u043e\u0441\u0442\u043e\u0439 html-\u0448\u0430\u0431\u043b\u043e\u043d, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u0430\u043d\u043d\u044b\u0435 \u0437\u0430\u043d\u043e\u0441\u0438\u043b \u0440\u0443\u043a\u0430\u043c\u0438, \u0438\u0441\u043f\u0440\u0430\u0432\u043b\u044f\u044f \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u044b\u0435 <code>&lt;td&gt;&lt;\/tr&gt;<\/code>\u2026<\/p>\n<p>  \u0412\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a<br \/>  <a name=\"habracut\"><\/a><br \/>  <img decoding=\"async\" src=\"http:\/\/habrastorage.org\/files\/c2e\/fb5\/0d6\/c2efb50d67ac4ae3ad6b90c9814b5285.png\" alt=\"image\"\/><\/p>\n<p>  \u041f\u0440\u0438\u0437\u043d\u0430\u044e\u0441\u044c, \u0441\u0442\u0438\u043b\u0438 \u0438 \u0440\u0430\u0437\u043c\u0435\u0442\u043a\u0430 \u0443\u0433\u043d\u0430\u043d\u044b \u0441 freshbooks.com, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b \u0432 \u0441\u0432\u043e\u0435 \u0432\u0440\u0435\u043c\u044f. \u041a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e, \u0434\u043b\u044f \u0440\u0443\u0441\u0441\u043a\u0438\u0445 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432 \u043e\u043d \u043c\u043d\u0435 \u043d\u0435 \u043f\u043e\u0434\u043e\u0448\u0435\u043b, \u0434\u0430 \u0438 \u043f\u0440\u043e\u0441\u0442\u043e\u0433\u043e html-\u0448\u0430\u0431\u043b\u043e\u043d\u0430 \u043c\u043d\u0435 \u0445\u0432\u0430\u0442\u0430\u043b\u043e.<\/p>\n<h5>\u0412\u044b\u0431\u043e\u0440 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0439<\/h5>\n<p>  \u0412 \u0442\u0435\u043a\u0443\u0449\u0435\u043c \u0442\u0440\u0435\u043d\u0434\u0435 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u043e\u0441\u0442\u0438 js-\u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u043e\u0432 \u0432\u0441\u0435\u0445 \u043c\u0430\u0441\u0442\u0435\u0439 \u0438 \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u043e\u0439 js \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u044f \u0445\u043e\u0442\u0435\u043b \u0434\u043b\u044f \u044d\u0442\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u0435\u0447\u0442\u043e \u0432\u043a\u0443\u0441\u043d\u043e\u0435 \u0438 \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0435, \u0434\u0430\u0431\u044b \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043f\u043e\u0431\u044b\u0442\u044c \u0432 \u044d\u0442\u043e\u043c \u043f\u043e\u0442\u043e\u043a\u0435 js \u0441\u0447\u0430\u0441\u0442\u044c\u044f\u2026 \u0418 \u043f\u0430\u0440\u0430\u043b\u0435\u043b\u044c\u043d\u043e \u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u0438 \u0438\u0433\u0440\u0443\u0448\u043a\u0438.<\/p>\n<p>  \u041f\u043e\u0441\u043b\u0435 \u043d\u0435\u0434\u043e\u043b\u0433\u0438\u0445 \u0438\u0437\u0443\u0447\u0435\u043d\u0438\u0439, \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0439 \u0438 \u0438\u043d\u0442\u0443\u0438\u0442\u0438\u0432\u043d\u044b\u0445 \u043e\u0437\u0430\u0440\u0435\u043d\u0438\u0439 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b\u0441\u044f \u043d\u0430 <a href=\"http:\/\/sailsjs.org\">sails.js<\/a> \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0441\u0435\u0440\u0432\u0435\u0440\u0430. \u0412\u044b\u0431\u0438\u0440\u0430\u043b \u043c\u0435\u0436\u0434\u0443 derby \u0438 sails \u2014 \u0432 \u0438\u0442\u043e\u0433\u0435 \u0432\u044b\u0431\u0440\u0430\u043b \u043f\u0430\u0440\u0443\u0441\u043d\u0438\u043a, \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c \u0438\u0437-\u0437\u0430 \u0435\u0433\u043e \u043f\u0440\u043e\u0441\u0442\u043e\u0442\u044b (\u0434\u043e\u043a\u0430 \u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044f \u043b\u0435\u0433\u043a\u043e \u0438 \u043f\u0440\u0438\u044f\u0442\u043d\u043e), \u0442\u0430\u043a\u0436\u0435 \u0432 \u043d\u0435\u043c \u0435\u0441\u0442\u044c \u043e\u0447\u0435\u043d\u044c \u043a\u043b\u0430\u0441\u0441\u043d\u044b\u0439 \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 rest api \u0438\u0437 \u043a\u043e\u0440\u043e\u0431\u043a\u0438. Derby \u0432 \u043f\u043b\u0430\u043d\u0435 \u0438\u0437\u0443\u0447\u0435\u043d\u0438\u044f \u043f\u043e\u043a\u0430\u0437\u0430\u043b\u0441\u044f \u0442\u0440\u0443\u0434\u043d\u0435\u0435 \u0438 \u043c\u043e\u043d\u0441\u0442\u0440\u0443\u043e\u0437\u043d\u0435\u0435 (\u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u2014 \u044f\u0432\u043d\u044b\u0439 \u043e\u0432\u0435\u0440\u0445\u044d\u0434).<\/p>\n<p>  \u041d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0435 \u0440\u0435\u0448\u0438\u043b \u043f\u043e\u0438\u0433\u0440\u0430\u0442\u044c\u0441\u044f \u0441 <a href=\"http:\/\/ractivejs.org\/\">ractive.js<\/a>. \u0418 \u0443\u0436\u0435 \u043f\u043e\u0437\u0436\u0435 \u0440\u0435\u0448\u0435\u043d\u043e \u0431\u044b\u043b\u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c backbone.js \u2014 \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c \u0438\u0437-\u0437\u0430 \u0443\u0434\u043e\u0431\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043c\u043e\u0434\u0435\u043b\u044f\u043c\u0438.<\/p>\n<p>  \u0414\u043e \u044d\u0442\u043e\u0433\u043e \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u043e\u043f\u044b\u0442\u0430 <b>sails.js<\/b> \u0438 <b>ractive.js<\/b> \u0443 \u043c\u0435\u043d\u044f \u043d\u0435 \u0431\u044b\u043b\u043e. \u0412 \u0440\u0430\u0431\u043e\u0442\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b \u0442\u043e\u043b\u044c\u043a\u043e \u0431\u044d\u043a\u0431\u043e\u043d.<br \/>  \u041f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u043c.,<\/p>\n<h4>\u0421\u0435\u0440\u0432\u0435\u0440<\/h4>\n<p>  \u0414\u043b\u044f \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c sails v0.10 \u2014 \u043e\u043d\u0430 \u0435\u0449\u0435 \u0432 \u0441\u0442\u0430\u0434\u0438\u0438 \u0431\u0435\u0442\u0430, \u043d\u043e \u043f\u043e \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044e \u0441 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0435\u0439 0.9.x \u0432 \u043d\u0435\u0439 \u0435\u0441\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u043b\u044e\u0448\u0435\u043a, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u0440\u0438\u0433\u043e\u0434\u044f\u0442\u0441\u044f. \u0412 \u0447\u0430\u0441\u0442\u043d\u043e\u0441\u0442\u0438 <a href=\"http:\/\/beta.sailsjs.org\/#!documentation\/reference\/ModelAssociations\/ModelAssociations.html\">model assocoations<\/a>, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u0437\u0430\u0434\u0430\u0432\u0430\u0442\u044c one-to-many, many-to-many (\u0438 \u0434\u0440\u0443\u0433\u0438\u0435 \u0441\u0432\u044f\u0437\u0438 \u043c\u0435\u0436\u0434\u0443 \u043c\u043e\u0434\u0435\u043b\u044f\u043c\u0438), \u0442\u0430\u043a\u0436\u0435 \u0432 0.10 \u043f\u0435\u0440\u0435\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u0430 \u0441\u0438\u0441\u0442\u0435\u043c\u0430 grunt \u0442\u0430\u0441\u043a\u043e\u0432. \u0412 <a href=\"http:\/\/beta.sailsjs.org\/#!documentation\">\u0434\u043e\u043a\u0435<\/a> \u043f\u043e 0.10 \u0432\u0441\u0435 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u044f\u0441\u043d\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043e<\/p>\n<p>  sails v0.10 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0447\u0435\u0440\u0435\u0437 npm (\u044f \u0441\u0442\u0430\u0432\u0438\u043b \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e)  <\/p>\n<pre><code class=\"bash\">sudo npm install -g  &quot;git:\/\/github.com\/balderdashy\/sails.git#v0.10&quot; <\/code><\/pre>\n<p>  \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c  <\/p>\n<pre><code class=\"bash\">sails -v <\/code><\/pre>\n<p>  0.10.0 \u2014 \u043e\u0442\u043b\u0438\u0447\u043d\u043e<\/p>\n<h5>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0441\u043a\u0435\u043b\u0435\u0442\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f sailsjs<\/h5>\n<p>  \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043d\u043e\u0432\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, invoicer \u0438 \u0441\u0442\u0430\u0432\u0438\u043c \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438   <\/p>\n<pre><code class=\"bash\">sails new invoicer cd invoicer npm install <\/code><\/pre>\n<p>  \u0414\u0430\u043b\u0435\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0432 \u043a\u043e\u043c\u0430\u043d\u0434\u0443 <code>sails lift<\/code> \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0439 express.js \u0441\u0435\u0440\u0432\u0435\u0440 \u043d\u0430 <code>http:\/\/localhost:1337<\/code><\/p>\n<h5>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 API \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439 (\u043c\u043e\u0434\u0435\u043b\u0435\u0439)<\/h5>\n<p>  \u041d\u0430\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0442\u0435\u0441\u044f 3 \u043c\u043e\u0434\u0435\u043b\u0438 \u0434\u043b\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f:  <\/p>\n<ul>\n<li> <code>user<\/code> \u2014 \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0435 \u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435<\/li>\n<li> <code>invoice<\/code> \u2014 \u0434\u043b\u044f \u0441\u043f\u0438\u0441\u043a\u0430 \u0441\u0447\u0435\u0442\u043e\u0432<\/li>\n<li> <code>task<\/code> \u2014 \u0434\u043b\u044f \u0437\u0430\u0434\u0430\u0447 \u0432 \u0441\u0447\u0435\u0442\u0435 (\u0438\u043d\u0432\u043e\u0439\u0441\u0435)<\/li>\n<\/ul>\n<p>  \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u043c\u0430\u043d\u0434\u044b <code>sails generate api &lt;api_name&gt;<\/code>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f API<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"bash\">zaebee@zaeboo$ sails generate api user debug: Generated a new model `User` at api\/models\/User.js! debug: Generated a new controller `user` at api\/controllers\/UserController.js!  info: REST API generated @ http:\/\/localhost:1337\/user info: and will be available the next time you run `sails lift`.  zaebee@zaeboo$ sails generate api invoice debug: Generated a new model `Invoice` at api\/models\/Invoice.js! debug: Generated a new controller `invoice` at api\/controllers\/InvoiceController.js!  info: REST API generated @ http:\/\/localhost:1337\/invoice info: and will be available the next time you run `sails lift`.  zaebee@zaeboo$ sails generate api task debug: Generated a new controller `task` at api\/controllers\/TaskController.js! debug: Generated a new model `Task` at api\/models\/Task.js!  info: REST API generated @ http:\/\/localhost:1337\/task info: and will be available the next time you run `sails lift`. <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u043f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u0432 \u043f\u0430\u043f\u043a\u0435 api\/controllers \u043f\u043e\u044f\u0432\u044f\u0442\u0441\u044f 3 \u0444\u0430\u0439\u043b\u0430  <\/p>\n<pre><code class=\"bash\">-rw-r--r-- 1  146 \u0410\u043f\u0440 28 17:15 InvoiceController.js -rw-r--r-- 1  143 \u0410\u043f\u0440 28 17:15 TaskController.js -rw-r--r-- 1  143 \u0410\u043f\u0440 28 17:15 UserController.js <\/code><\/pre>\n<p>  \u0442\u0430\u043a\u0436\u0435 api\/models   <\/p>\n<pre><code class=\"bash\">-rw-r--r-- 1  146 \u0410\u043f\u0440 28 17:15 Invoice.js -rw-r--r-- 1  143 \u0410\u043f\u0440 28 17:15 Task.js -rw-r--r-- 1  143 \u0410\u043f\u0440 28 17:15 User.js <\/code><\/pre>\n<p>  \u041b\u0435\u0433\u043a\u043e \u0438 \u043f\u0440\u043e\u0441\u0442\u043e sails \u0441\u043e\u0437\u0434\u0430\u043b \u0434\u043b\u044f \u043d\u0430\u0441 3 \u043c\u0435\u0442\u043e\u0434\u0430, <br \/>  <code>http:\/\/localhost:1337\/user<\/code><br \/>  <code>http:\/\/localhost:1337\/invoice<\/code> <br \/>  <code>http:\/\/localhost:1337\/task<\/code><br \/>  \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044e\u0442 CRUD \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438. \u0422\u0430\u043a\u0436\u0435 \u0435\u0441\u0442\u044c \u0430\u043b\u0438\u0430\u0441\u044b \u0434\u043b\u044f \u043d\u0438\u0445, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <code>http:\/\/localhost:1337\/user\/create?name=Andrey&address=Russia<\/code> \u2014 \u0441\u043e\u0437\u0434\u0430\u0441\u0442 \u043d\u043e\u0432\u044b\u0439 \u0438\u043d\u0441\u0442\u0430\u043d\u0441 \u044e\u0437\u0435\u0440\u0430. \u041c\u043e\u0436\u043d\u043e \u043f\u043e\u0438\u0433\u0440\u0430\u0442\u044c\u0441\u044f \u0447\u0435\u0440\u0435\u0437 <a href=\"http:\/\/www.getpostman.com\/\">postman<\/a><\/p>\n<p>  \u0422\u0430\u043a\u0436\u0435 \u0441\u043e\u0432\u0435\u0442\u0443\u044e \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u0441\u044f \u0441 <a href=\"http:\/\/beta.sailsjs.org\/#!documentation\/reference\/Controllers\/Controllers.html\">\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0435\u0439 \u043f\u043e \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430\u043c<\/a><\/p>\n<h5>\u041a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 (\u0411\u0414)<\/h5>\n<p>  \u0413\u0434\u0435 \u0436\u0435 \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435? \u041f\u043e \u0434\u0435\u0444\u043e\u043b\u0442\u0443 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0442\u0435\u0441\u044f \u0434\u0438\u0441\u043a, \u0447\u0442\u043e \u0443\u043a\u0430\u0437\u0430\u043d\u043e \u0432 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u0445 <code>config\/connections.js<\/code> \u0438 <code>config\/models.js<\/code>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u043a\u043e\u0434 config\/connections.js<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"javascript\">module.exports.connections = {    localDiskDb: {     adapter: 'sails-disk'   },     someMysqlServer: {     adapter : 'sails-mysql',     host    : 'YOUR_MYSQL_SERVER_HOSTNAME_OR_IP_ADDRESS',     user    : 'YOUR_MYSQL_USER',     password: 'YOUR_MYSQL_PASSWORD',     database: 'YOUR_MYSQL_DB'   },    someMongodbServer: {     adapter   : 'sails-mongo',     host      : 'localhost',     port      : 27017,     \/\/user      : 'username',     \/\/password  : 'password',     database  : 'invoicer'   },    somePostgresqlServer: {     adapter   : 'sails-postgresql',     host      : 'YOUR_POSTGRES_SERVER_HOSTNAME_OR_IP_ADDRESS',     user      : 'YOUR_POSTGRES_USER',     password  : 'YOUR_POSTGRES_PASSWORD',      database  : 'YOUR_POSTGRES_DB'   } }; <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u041c\u044b \u0436\u0435 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c mongo \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0437\u0430\u043f\u0438\u0441\u0435\u0439, \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0438\u0437\u043c\u0435\u043d\u0438\u043c config\/models.js:  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u043a\u043e\u0434 config\/models.js<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"javascript\">\/**  * Models  * (sails.config.models)  *  * Unless you override them, the following properties will be included  * in each of your models.  *\/  module.exports.models = {    \/\/ Your app's default connection.   \/\/ i.e. the name of one of your app's connections (see `config\/connections.js`)   \/\/   \/\/ (defaults to localDiskDb)   connection: 'someMongodbServer' }; <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u041e\u043f\u0438\u0448\u0435\u043c \u043d\u0443\u0436\u043d\u044b\u0435 \u043d\u0430\u043c \u043f\u043e\u043b\u044f \u043c\u043e\u0434\u0435\u043b\u0438 User, Invoice \u0438 Task  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">api\/models\/User.js<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"javascript\">module.exports = {      attributes: {     name: 'string',     email: 'string',     avatar: 'string',     address: 'text',     account: 'text',     invoices: {       collection: 'invoice',       via: 'owner',     }      },   }; <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">api\/models\/Invoice.js<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"javascript\">module.exports = {    attributes: {     total_amount: 'float',     name: 'string',     address: 'text',     owner: {       required: false,       model: 'user',     },     tasks: {       required: false,       collection: 'task',       via: 'invoice',     }   }, }; <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">api\/models\/Task.js<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"javascript\">module.exports = {    attributes: {     name: 'string',     description: 'text',     hours: 'float',     rate: 'float',     invoice: {       required: false,       model: 'invoice',       via: 'tasks',     }   }, }; <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u0434\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043c\u043e\u043d\u0433\u043e \u0430\u0434\u0430\u043f\u0442\u0435\u0440\u0430 \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043f\u0430\u043a\u0435\u0442 sails-mongo  <\/p>\n<pre><code class=\"bash\">npm install sails-mongo@0.10 <\/code><\/pre>\n<h5>\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 `action` \u0434\u043b\u044f \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430, \u0438 \u0448\u0430\u0431\u043b\u043e\u043d\u0430 (view) \u0434\u043b\u044f \u043d\u0435\u0433\u043e<\/h5>\n<p>  \u041d\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0440\u0430\u043d\u0438\u0447\u043a\u0443 \u0434\u043b\u044f \u043d\u0430\u0448\u0435\u0439 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438 (\u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0438\u043d\u0432\u043e\u0439\u0441\u0430):  <\/p>\n<pre><code class=\"bash\">sails generate controller main generate <\/code><\/pre>\n<p>  \u041c\u044b \u0441\u043e\u0437\u0434\u0430\u043b\u0438 \u043d\u043e\u0432\u044b\u0439 <code>MainController.js<\/code>, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0441\u043e\u0437\u0434\u0430\u043d\u0430 \u043e\u0434\u043d\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>generate<\/code> \u0442\u0430\u043a \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u043c\u044b\u0439 action<br \/>  \u0435\u0441\u043b\u0438 \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043f\u043e \u0443\u0440\u043b\u0443 <code>http:\/\/localhost:1337\/main\/generate<\/code> \u043c\u044b \u0443\u0432\u0438\u0434\u0438\u043c \u0442\u043e, \u0447\u0442\u043e \u043d\u0430\u043c \u0432\u0435\u0440\u043d\u0443\u043b\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>generate<\/code><br \/>  \u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u043e\u043d\u0430 \u0432\u0435\u0440\u043d\u0435\u0442 json   <\/p>\n<pre><code class=\"javascript\">return res.json({       todo: 'Not implemented yet!'  });  <\/code><\/pre>\n<p>  \u041c\u044b \u0436\u0435 \u0445\u043e\u0442\u0438\u043c \u0432\u0438\u0434\u0435\u0442\u044c \u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435 html-\u0441\u0442\u0440\u0430\u043d\u0438\u0447\u043a\u0443. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0432\u044b\u0448\u0435\u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u043d\u044b\u0439 \u043a\u043e\u0434 \u0437\u0430\u043c\u0435\u043d\u0438\u043c \u043d\u0430   <\/p>\n<pre><code class=\"javascript\">return res.view() <\/code><\/pre>\n<p>  \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u0441\u0442\u0440\u0430\u043d\u0438\u0447\u043a\u0443 \u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435 \u0438 \u0432\u0438\u0434\u0438\u043c \u043e\u0448\u0438\u0431\u043a\u0443  <\/p>\n<pre><code class=\"javascript\">{   &quot;view&quot;: {     &quot;name&quot;: &quot;main\/generate&quot;,     &quot;root&quot;: &quot;\/home\/zaebee\/projects\/invoicer\/views&quot;,     &quot;defaultEngine&quot;: &quot;ejs&quot;,     &quot;ext&quot;: &quot;.ejs&quot;   } } <\/code><\/pre>\n<p>  \u044d\u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442 \u0447\u0442\u043e \u0443 \u043d\u0430\u0441 \u043d\u0435 \u0441\u043e\u0437\u0434\u0430\u043d \u0448\u0431\u0430\u043b\u043e\u043d \u0434\u043b\u044f view. \u0412\u0441\u0435 htnl-\u0448\u0430\u0431\u043b\u043e\u043d\u044b \u0434\u043b\u044f \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u043e\u0432 \u043b\u0435\u0436\u0430\u0442 \u0432 \u043f\u0430\u043f\u043a\u0435 views \u0438 \u0438\u043c\u0435\u044e\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 <code>views\/&lt;controller_name&gt;\/&lt;action_name&gt;<\/code><\/p>\n<p>  \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043f\u0443\u0441\u0442\u043e\u0439 \u0448\u0430\u0431\u043b\u043e\u043d views\/main\/generate  <\/p>\n<pre><code class=\"bash\">zaebee@zaeboo$ mkdir views\/main zaebee@zaeboo$ touch views\/main\/generate.ejs <\/code><\/pre>\n<p>  \u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0448\u0430\u0431\u043b\u043e\u043d\u043d\u043e\u0433\u043e \u0434\u0432\u0438\u0436\u043a\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f ejs. Sails \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u043c\u043d\u043e\u0433\u043e \u0448\u0430\u0431\u043b\u043e\u043d\u0438\u0437\u0430\u0442\u043e\u0440\u043e\u0432 \u0438 \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0435\u0433\u043e \u0432 \u0444\u0430\u0439\u043b\u0435 config\/views.js \u043d\u0430 \u0432\u0430\u0448 \u043b\u044e\u0431\u0438\u043c\u044b\u0439:<br \/>  <code> ejs, jade, handlebars, mustache underscore, hogan, haml, haml-coffee, dust atpl, eco, ect, jazz, jqtpl, JUST, liquor, QEJS,  swig, templayed, toffee, walrus, & whiskers <\/code><\/p>\n<p>  <b>\u0412\u041d\u0418\u041c\u0410\u041d\u0418\u0415!<\/b> \u0432 \u0432\u0435\u0440\u0441\u0438\u0438 sails 0.10 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 \u043b\u0430\u0439\u043e\u0443\u0442\u043e\u0432 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0441 ejs. \u0412\u043a\u0440\u0430\u0442\u0446\u0435, \u0435\u0441\u0442\u044c \u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u043b\u0435\u0439\u043e\u0443\u0442 <code>views\/layout.ejs<\/code>, \u043e\u0442 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043d\u0430\u0441\u043b\u0435\u0434\u0443\u044e\u0442\u0441\u044f \u0432\u0441\u0435 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u0432\u044c\u044e\u0445\u0438. \u0418 \u043f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u0448\u0430\u0431\u043b\u043e\u043d\u0438\u0437\u0430\u0442\u043e\u0440\u0430 \u043e\u0442\u043b\u0438\u0447\u043d\u043e\u0433\u043e \u043e\u0442 ejs \u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f \u043d\u0435 \u0431\u0443\u0434\u0435\u0442. Sails \u0434\u0430\u0435\u0442 \u044d\u0442\u043e \u043f\u043e\u043d\u044f\u0442\u044c, \u0435\u0441\u043b\u0438 \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u043e\u043f\u0446\u0438\u044e engine \u0432 \u0444\u0430\u0439\u043b\u0435 <code>config\/views.js<\/code>  <\/p>\n<pre><code class=\"javascript\">warn: Sails' built-in layout support only works with the `ejs` view engine. warn: You're using `hogan`. warn: Ignoring `sails.config.views.layout`... <\/code><\/pre>\n<h4>\u041a\u043b\u0438\u0435\u043d\u0442<\/h4>\n<p>  \u0421\u0435\u0440\u0432\u0435\u0440 \u0433\u043e\u0442\u043e\u0432, \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u043c \u043a \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044e \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043f\u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0438\u043d\u0432\u043e\u0439\u0441\u043e\u0432.<\/p>\n<h5>\u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0441\u0442\u0430\u0442\u0438\u043a\u0438<\/h5>\n<p>  \u0412\u0441\u044f \u0441\u0442\u0430\u0442\u0438\u043a\u0430 (\u0438\u043b\u0438 \u043f\u0443\u0431\u043b\u0438\u0447\u043d\u044b\u0439 \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u0438\u0439 \u043a\u043e\u0434) \u043b\u0435\u0436\u0438\u0442 \u0432 \u043f\u0430\u043f\u043a\u0435 assets. \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043d\u043e\u0432\u044b\u0435 \u0444\u0430\u0439\u043b\u044b \u043a \u0432\u0430\u0448\u0435\u043c\u0443 \u0448\u0430\u0431\u043b\u043e\u043d\u0443 \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e\u043c\u0435\u0441\u0442\u0438\u0442\u0435 \u0438\u0445 \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0443\u044e \u043f\u0430\u043f\u043a\u0443 (\u0441\u043a\u0440\u0438\u043f\u0442\u044b \u0432 assets\/js, \u0441\u0442\u0438\u043b\u0438 \u0432 assets\/styles, \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u0438\u0435 \u0448\u0430\u0431\u043b\u043e\u043d\u044b \u0432 assets\/templates) \u0438 sails \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0441\u0432\u043e\u0438\u0445 grunt \u0442\u0430\u0441\u043a\u043e\u0432 \u0437\u0430\u043f\u0438\u0448\u0435\u0442 \u0438\u0445 \u0432 \u0432\u0430\u0448 index\/layout.ejs \u2014 \u0432 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0435 \u0441\u0435\u043a\u0446\u0438\u0438:  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u041b\u0438\u0441\u0442\u0438\u043d\u0433 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430 \/views\/layout.ejs<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"html\"> &lt;!DOCTYPE html&gt;  &lt;html&gt;    &lt;head&gt;      &lt;title&gt;New Sails App&lt;\/title&gt;        &lt;!-- Viewport mobile tag for sensible mobile support --&gt;      &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1, maximum-scale=1&quot;&gt;              &lt;!--STYLES--&gt;      &lt;link rel=&quot;stylesheet&quot; href=&quot;\/styles\/importer.css&quot;&gt;      &lt;!--STYLES END--&gt;    &lt;\/head&gt;      &lt;body&gt;      &lt;%- body %&gt;        &lt;!--TEMPLATES--&gt;                &lt;!--TEMPLATES END--&gt;        &lt;!--SCRIPTS--&gt;      &lt;script src=&quot;\/js\/dependencies\/sails.io.js&quot;&gt;&lt;\/script&gt;      &lt;!--SCRIPTS END--&gt;    &lt;\/body&gt;  &lt;\/html&gt;  <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u043c \u0432 \u043d\u0430\u0448 layout \u043d\u0443\u0436\u043d\u044b\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 (Jquery, Underscore, Backbone, Ractive) \u0447\u0435\u0440\u0435\u0437 cdn, \u0442\u0430\u043a\u0436\u043a \u043f\u043e\u043c\u0435\u0441\u0442\u0438\u043c <code>bootstrap.min.css<\/code> \u0438 \u0433\u043e\u0442\u043e\u0432\u044b\u0439 \u0444\u0430\u0439\u043b <code>app.css<\/code> \u0432 \u043f\u0430\u043f\u043a\u0443 <code>assets\/styles<\/code>. \u0422\u0430\u043a\u0436\u0435 \u0440\u0430\u0437\u043c\u0435\u0441\u0442\u0438\u043c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 js \u043b\u0438\u0431\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u044f\u0442\u0441\u044f (<code>bootstrap.min.css<\/code>, <code>moment.ru.js<\/code> \u0438 <code>moment.min.js<\/code> \u2014 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u043a\u0430 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0434\u0430\u0442\u0430\u043c\u0438) \u0432 \u043f\u0430\u043f\u043a\u0443 <code>assets\/js\/vendor<\/code> \u0438 \u043f\u0443\u0441\u0442\u043e\u0439 \u0444\u0430\u0439\u043b <code>app.js<\/code> \u0432 \u043f\u0430\u043f\u043a\u0443 <code>assets\/js<\/code>. \u0417\u0430\u043f\u0443\u0441\u0442\u0438\u043c <code>sails lift<\/code> \u0438 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u0447\u0442\u043e \u0442\u0435\u043f\u0435\u0440\u044c \u0443 \u043d\u0430\u0441 \u0432 \u0444\u0430\u0439\u043b\u0435 <code>views\/layout.ejs<\/code>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u041b\u0438\u0441\u0442\u0438\u043d\u0433 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430 \/views\/layout.ejs<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"html\">  &lt;!DOCTYPE html&gt;  &lt;html&gt;    &lt;head&gt;      &lt;title&gt;New Sails App&lt;\/title&gt;        &lt;!-- Viewport mobile tag for sensible mobile support --&gt;      &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1, maximum-scale=1&quot;&gt;        &lt;!--STYLES--&gt;      &lt;link rel=&quot;stylesheet&quot; href=&quot;\/styles\/app.css&quot;&gt;      &lt;link rel=&quot;stylesheet&quot; href=&quot;\/styles\/bootstrap.min.css&quot;&gt;      &lt;link rel=&quot;stylesheet&quot; href=&quot;\/styles\/importer.css&quot;&gt;      &lt;!--STYLES END--&gt;       &lt;script src=&quot;\/\/cdnjs.cloudflare.com\/ajax\/libs\/jquery\/1.9.1\/jquery.min.js&quot;&gt;&lt;\/script&gt;      &lt;script src=&quot;\/\/cdnjs.cloudflare.com\/ajax\/libs\/underscore.js\/1.4.4\/underscore-min.js&quot;&gt;&lt;\/script&gt;      &lt;script src=&quot;\/\/cdnjs.cloudflare.com\/ajax\/libs\/backbone.js\/1.0.0\/backbone-min.js&quot;&gt;&lt;\/script&gt;      &lt;script src=&quot;\/\/cdn.ractivejs.org\/latest\/ractive.min.js&quot;&gt;&lt;\/script&gt;      &lt;script src=&quot;\/\/api.filepicker.io\/v1\/filepicker.js&quot;&gt;&lt;\/script    &lt;\/head&gt;      &lt;body&gt;      &lt;%- body %&gt;        &lt;!--TEMPLATES--&gt;                &lt;!--TEMPLATES END--&gt;        &lt;!--SCRIPTS--&gt;      &lt;script src=&quot;\/js\/dependencies\/sails.io.js&quot;&gt;&lt;\/script&gt;      &lt;script src=&quot;\/js\/app.js&quot;&gt;&lt;\/script&gt;      &lt;script src=&quot;\/js\/vendor\/bootstrap.min.js&quot;&gt;&lt;\/script&gt;      &lt;script src=&quot;\/js\/vendor\/moment.min.js&quot;&gt;&lt;\/script&gt;      &lt;script src=&quot;\/js\/vendor\/moment.ru.js&quot;&gt;&lt;\/script&gt;      &lt;!--SCRIPTS END--&gt;    &lt;\/body&gt;  &lt;\/html&gt; <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u041e\u0442\u043b\u0438\u0447\u043d\u043e, sails \u0441\u0434\u0435\u043b\u0430\u043b \u0437\u0430 \u043d\u0430\u0441, \u0432\u0441\u0435 \u0447\u0442\u043e \u043d\u0443\u0436\u043d\u043e. \u041f\u0440\u0430\u0432\u0434\u0430, \u0435\u0441\u0442\u044c \u043e\u0434\u0438\u043d \u043c\u0438\u043d\u0443\u0441 \u2014 \u0432\u0435\u043d\u0434\u043e\u0440\u0441\u043a\u0438\u0435 \u0441\u043a\u0440\u0438\u043f\u0442\u044b \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u044b \u043d\u0438\u0436\u0435 \u043d\u0430\u0448\u0435\u0433\u043e app.js. \u0418\u0441\u043f\u0440\u0430\u0432\u0438\u043c \u0444\u0430\u0439\u043b <code>tasks\/pipeline.js<\/code> \u0443\u043a\u0430\u0436\u0435\u043c grunt`\u0443, \u0447\u0442\u043e \u043f\u0430\u043f\u043a\u0443 vendor \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0442\u044c \u0440\u0430\u043d\u044c\u0448\u0435:  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u0427\u0430\u0441\u0442\u044c \u043b\u0438\u0441\u0442\u0438\u043d\u0433\u0430 \u0444\u0430\u0439\u043b\u0430 tasks\/pipeline.js<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"javascript\">......  \/\/ CSS files to inject in order \/\/ \/\/ (if you're using LESS with the built-in default config, you'll want \/\/  to change `assets\/styles\/importer.less` instead.) var cssFilesToInject = [         'styles\/**\/*.css' ];  \/\/ Client-side javascript files to inject in order \/\/ (uses Grunt-style wildcard\/glob\/splat expressions) var jsFilesToInject = [          \/\/ Dependencies like sails.io.js, jQuery, or Angular         \/\/ are brought in here         'js\/dependencies\/**\/*.js',         'js\/vendor\/**\/*.js', \/\/ \u0432\u044b\u043d\u043e\u0441\u0438\u043c \u043f\u0430\u043f\u043a\u0443 vendor          \/\/ All of the rest of your client-side js files         \/\/ will be injected here in no particular order.         'js\/**\/*.js' ];  ........ <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u041f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430 \u043a\u043b\u0438\u0435\u043d\u0441\u043a\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0430 \u2014 \u043c\u043e\u0436\u0435\u043c \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0430\u0442\u044c \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043a \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044e \u0431\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<h5>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0441\u043a\u0435\u043b\u0435\u0442\u0430 \u0440\u0430\u0437\u043c\u0435\u0442\u043a\u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b. <b>Ractive.js<\/b> \u0448\u0430\u0431\u043b\u043e\u043d\u044b<\/h5>\n<p>  \u0412\u0437\u0433\u043b\u044f\u043d\u0435\u043c \u0435\u0449\u0435 \u0440\u0430\u0437 \u043d\u0430 \u043d\u0430\u0448 \u043c\u0430\u043a\u0435\u0442. \u041d\u0430 \u043d\u0435\u043c \u044f \u0432\u044b\u0434\u0435\u043b\u0438\u043b \u0431\u043b\u043e\u043a\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u043f\u0440\u0438\u0432\u044f\u0437\u044b\u0432\u0430\u0442\u044c \u043a \u043d\u0430\u0448\u0438\u043c \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u043c \u0434\u0430\u043d\u043d\u044b\u043c<br \/>  <img decoding=\"async\" src=\"http:\/\/habrastorage.org\/files\/443\/dd1\/968\/443dd19687dd434e8f1001551d8fd322.png\"\/><br \/>  \u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0431\u0430\u0437\u043e\u0432\u0443\u044e \u0440\u0430\u0437\u043c\u0435\u0442\u043a\u0443 \u0432 \u0444\u0430\u0439\u043b\u0435 views\/main\/generate.ejs \u0432 \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0431\u0443\u0434\u0443\u0442 \u0438\u043d\u043a\u043b\u044e\u0434\u0438\u0442\u044c\u0441\u044f \u043d\u0430\u0448\u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u0438\u0435 \u0448\u0430\u0431\u043b\u043e\u043d\u044b  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u043b\u0438\u0441\u0442\u0438\u043d\u0433 \u0444\u0430\u0439\u043b\u0430 views\/main\/generate.ejs<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"html\"> &lt;div class=&quot;main_bg&quot;&gt;    &lt;div class=&quot;container primary-content&quot;&gt;      &lt;div class=&quot;invoice-container rounded-container peel-shadows col-sm-8 col-sm-offset-2&quot;&gt;        &lt;h2 style=&quot;text-align:center;margin-bottom:30px;&quot;&gt;\u0421\u0447\u0435\u0442 \u043d\u0430 \u043e\u043f\u043b\u0430\u0442\u0443&lt;\/h2&gt;                  &lt;div class=&quot;invheader&quot;&gt;          &lt;div class=&quot;invheader-upper&quot;&gt;            &lt;!-- User \u043c\u043e\u0434\u0435\u043b\u044c. \u0421\u044e\u0434\u0430 \u0431\u0443\u0434\u0435\u043c \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0442\u044c \u0448\u0430\u0431\u043b\u043e\u043d \u0441 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f: \u0438\u043c\u044f, \u0430\u0434\u0440\u0435\u0441, \u0430\u0432\u0430\u0442\u0430\u0440 --&gt;          &lt;\/div&gt;          &lt;div class=&quot;invheader-lower&quot;&gt;            &lt;!-- Invoice \u043c\u043e\u0434\u0435\u043b\u044c. \u0421\u044e\u0434\u0430 \u0431\u0443\u0434\u0435\u043c \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0442\u044c \u0448\u0430\u0431\u043b\u043e\u043d \u0441 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u043d\u0430\u0448\u0435\u0433\u043e \u0441\u0447\u0435\u0442\u0430 \u0438 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u0437\u0430\u043a\u0430\u0437\u0447\u0438\u043a\u0430 --&gt;          &lt;\/div&gt;        &lt;\/div&gt;            &lt;div class=&quot;invbody&quot;&gt;          &lt;div class=&quot;invbody-tasks&quot;&gt;            &lt;!-- Task \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044f. \u0421\u044e\u0434\u0430 \u0431\u0443\u0434\u0435\u043c \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0442\u044c \u0448\u0430\u0431\u043b\u043e\u043d \u0441\u043e \u0441\u043f\u0438\u0441\u043a\u043e\u043c \u0437\u0430\u0434\u0430\u0447 --&gt;          &lt;\/div&gt;            &lt;div class=&quot;clearb&quot; style=&quot;height: 1px; overflow: hidden;&quot;&gt;&lt;\/div&gt;            &lt;div class=&quot;invbody-account&quot;&gt;            &lt;!-- User \u043c\u043e\u0434\u0435\u043b\u044c \u0441\u043d\u043e\u0432\u0430. \u0421\u044e\u0434\u0430 \u0431\u0443\u0434\u0435\u043c \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0442\u044c \u0440\u0435\u043a\u0432\u0438\u0437\u0438\u0442\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0434\u043b\u044f \u043e\u043f\u043b\u0430\u0442\u044b --&gt;          &lt;\/div&gt;        &lt;\/div&gt;      &lt;\/div&gt;    &lt;\/div&gt;  &lt;\/div&gt;  <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u0418\u0442\u0430\u043a, \u0431\u0430\u0437\u043e\u0432\u0430\u044f \u0440\u0430\u0437\u043c\u0435\u0442\u043a\u0430 \u0433\u043e\u0442\u043e\u0432\u0430 \u2014 \u043f\u0440\u0438\u0448\u043b\u043e \u0432\u0440\u0435\u043c\u044f \u0434\u043b\u044f \u0448\u0430\u0431\u043b\u043e\u043d\u043e\u0432 <b>ractive.js<\/b><br \/>  \u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043d\u0430\u0448\u0435\u0433\u043e \u0431\u043b\u043e\u043a\u0430 \u043f\u043e \u0448\u0430\u0431\u043b\u043e\u043d\u0443 (\u0438\u0442\u043e\u0433\u043e \u0438\u0445 \u0431\u0443\u0434\u0435\u0442 \u0447\u0435\u0442\u044b\u0440\u0435) \u0438 \u043f\u043e\u043c\u0435\u0441\u0442\u0438\u043c \u0438\u0445 \u0432 assets\/templates  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u043b\u0438\u0441\u0442\u0438\u043d\u0433 \u0444\u0430\u0439\u043b\u0430 assets\/templates\/invheader-upper.html<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"html\"> &lt;div class=&quot;invheader-address-account&quot; on-hover=&quot;toggleBtn&quot;&gt;    &lt;a role=&quot;button&quot; title=&quot;{{ .editing ? '\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c' : '\u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044f' }}&quot;      class=&quot;hidden-print btn btn-primary btn-sm hide&quot;      on-click=&quot;edit&quot;&gt;&lt;i class=&quot;glyphicon glyphicon-{{ .editing ? 'ok' : 'pencil' }}&quot;&gt;&lt;\/i&gt;    &lt;\/a&gt;    &lt;b&gt;\u0418\u0441\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c:&lt;\/b&gt;    &lt;div class=&quot;user-name {{ .editing ? 'editing' : '' }}&quot;&gt;      &lt;span&gt;{{^name}}\u0411\u0435\u0437 \u0438\u043c\u0435\u043d\u0438{{\/name}}{{name}}&lt;\/span&gt;      {{#.editing}}        &lt;div class='edit-container'&gt;          &lt;input intro=&quot;select&quot; value=&quot;{{name}}&quot; class=&quot;form-control&quot;          placeholder=&quot;\u041d\u0430\u043f\u0438\u0448\u0438\u0442\u0435 \u0432\u0430\u0448\u0435 \u0424\u0418\u041e&quot;&gt;        &lt;\/div&gt;      {{\/.editing}}    &lt;\/div&gt;    &lt;div class=&quot;user-address {{ .editing ? 'editing' : '' }}&quot;&gt;      &lt;span&gt;{{^address}}\u0410\u0434\u0440\u0435\u0441 \u043d\u0435 \u0443\u043a\u0430\u0437\u0430\u043d{{\/address}}{{{address}}}&lt;\/span&gt;      {{#.editing}}        &lt;div class='edit-container'&gt;          &lt;textarea value=&quot;{{address}}&quot; class='edit form-control'            placeholder=&quot;\u041d\u0430\u043f\u0438\u0448\u0438\u0442\u0435 \u0432\u0430\u0448 \u0430\u0434\u0440\u0435\u0441&quot;&gt;{{address}}&lt;\/textarea&gt;        &lt;\/div&gt;      {{\/.editing}}    &lt;\/div&gt;  &lt;\/div&gt;    &lt;div on-hover=&quot;togglePicker&quot; class=&quot;invheader-logo-container&quot;&gt;    &lt;div class=&quot;invheader-logo&quot;&gt;      {{#avatar}}        &lt;img src=&quot;{{avatar}}\/convert?h=110&w=250&quot; alt=&quot;{{name}}&quot;&gt;      {{\/avatar}}      &lt;div class=&quot;hidden-print BoardCreateRep {{ avatar ? 'hide' : '' }}&quot;&gt;        &lt;input type=&quot;filepicker-dragdrop&quot; data-fp-mimetype=&quot;image\/png&quot;          data-fp-apikey=&quot;A3lXl09sRSejY4e0pOOSQz&quot;          data-fp-button-class=&quot;btn btn-primary hidden-print&quot;          data-fp-button-text=&quot;\u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u0435 \u0430\u0432\u0430\u0442\u0430\u0440&quot;          data-fp-drag-text=&quot;\u0438\u043b\u0438 \u0431\u0440\u043e\u0441\u044c\u0442\u0435 \u0441\u044e\u0434\u0430&quot;          data-fp-drag-class=&quot;hidden-print drop-avatar&quot;          onchange=&quot;app.user.fire('setAvatar', event)&quot;&gt;      &lt;\/div&gt;    &lt;\/div&gt;  &lt;\/div&gt; <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u043b\u0438\u0441\u0442\u0438\u043d\u0433 \u0444\u0430\u0439\u043b\u0430 assets\/templates\/invheader-lower.html<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"html\"> &lt;div class=&quot;invheader-address-client&quot; on-hover=&quot;toggleBtn&quot;&gt;    &lt;a role=&quot;button&quot; title=&quot;{{ .editing ? '\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c' : '\u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0437\u0430\u043a\u0430\u0437\u0447\u0438\u043a\u0430' }}&quot;      class=&quot;hidden-print btn btn-primary btn-sm hide&quot;      on-click=&quot;edit&quot;&gt;&lt;i class=&quot;glyphicon glyphicon-{{ .editing ? 'ok' : 'pencil' }}&quot;&gt;&lt;\/i&gt;    &lt;\/a&gt;    &lt;b&gt;\u0417\u0430\u043a\u0430\u0437\u0447\u0438\u043a:&lt;\/b&gt;    &lt;div class=&quot;cleint-name {{ .editing ? 'editing' : '' }}&quot;&gt;      &lt;span&gt;{{^invoice.name}}\u0411\u0435\u0437 \u0438\u043c\u0435\u043d\u0438{{\/invoice.name}}{{invoice.name}}&lt;\/span&gt;      {{#.editing}}        &lt;div class='edit-container'&gt;          &lt;input intro=&quot;select&quot; value=&quot;{{invoice.name}}&quot;          class=&quot;form-control&quot; placeholder=&quot;\u041d\u0430\u043f\u0438\u0448\u0438\u0442\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u0430&quot;&gt;        &lt;\/div&gt;      {{\/.editing}}    &lt;\/div&gt;    &lt;div class=&quot;client-address {{ .editing ? 'editing' : '' }}&quot;&gt;      &lt;span&gt;{{^invoice.address}}\u0410\u0434\u0440\u0435\u0441 \u043d\u0435 \u0443\u043a\u0430\u0437\u0430\u043d{{\/invoice.address}}{{{invoice.address}}}&lt;\/span&gt;      {{#.editing}}        &lt;div class='edit-container'&gt;          &lt;textarea value=&quot;{{invoice.address}}&quot; class=&quot;edit form-control&quot;            placeholder=&quot;\u041d\u0430\u043f\u0438\u0448\u0438\u0442\u0435 \u0430\u0434\u0440\u0435\u0441 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u0430&quot;&gt;{{invoice.address}}&lt;\/textarea&gt;        &lt;\/div&gt;      {{\/.editing}}    &lt;\/div&gt;  &lt;\/div&gt;    &lt;div class=&quot;invheader-invoicedetails&quot;&gt;    &lt;table cellspacing=&quot;0&quot;&gt;      &lt;tbody&gt;        &lt;tr&gt;          &lt;th&gt;\u041d\u043e\u043c\u0435\u0440 \u0441\u0447\u0435\u0442\u0430&lt;\/th&gt;          &lt;td&gt;#{{ lastFour(invoice.id) }}&lt;\/td&gt;        &lt;\/tr&gt;        &lt;tr&gt;          &lt;th&gt;\u0414\u0430\u0442\u0430 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&lt;\/th&gt;          &lt;td&gt;{{ date(invoice.createdAt) }}&lt;\/td&gt;        &lt;\/tr&gt;        &lt;tr class=&quot;invheader-invoicedetails-balance&quot;&gt;          &lt;th&gt;&lt;div&gt;\u0418\u0442\u043e\u0433\u043e \u043a \u043e\u043f\u043b\u0430\u0442\u0435 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&lt;\/div&gt;&lt;\/th&gt;          &lt;td&gt;&lt;div&gt;&nbsp;{{^invoice.total_amount}}0.00{{\/invoice.total_amount}}{{ invoice.total_amount }}  \u0440\u0443\u0431 &nbsp; &nbsp; &nbsp;&lt;\/div&gt;&lt;\/td&gt;        &lt;\/tr&gt;      &lt;\/tbody&gt;    &lt;\/table&gt;  &lt;\/div&gt; <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u043b\u0438\u0441\u0442\u0438\u043d\u0433 \u0444\u0430\u0439\u043b\u0430 assets\/templates\/invbody-tasks.html<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"html\"> &lt;table class=&quot;invbody-items&quot; cellspacing=&quot;0&quot;&gt;    &lt;thead&gt;      &lt;tr&gt;        &lt;th class=&quot;first&quot;&gt;&lt;div class=&quot;item&quot;&gt;\u041d\u0430\u0438\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u0438\u0435 \u0440\u0430\u0431\u043e\u0442 &nbsp; &nbsp;&nbsp;&lt;\/div&gt;&lt;\/th&gt;        &lt;th&gt;&lt;div class=&quot;description&quot;&gt;\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435, \u0437\u0430\u043c\u0435\u0447\u0430\u043d\u0438\u044f \u043f\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u043c &nbsp; &nbsp;&nbsp;&lt;\/div&gt;&lt;\/th&gt;        &lt;th&gt;&lt;div class=&quot;unitcost&quot;&gt;\u0421\u0442\u0430\u0432\u043a\u0430 (\u0440\u0443\u0431)&lt;\/div&gt;&lt;\/th&gt;        &lt;th&gt;&lt;div class=&quot;quantity&quot;&gt;\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0447\u0430\u0441\u043e\u0432 &nbsp; &nbsp;&nbsp;&lt;\/div&gt;&lt;\/th&gt;        &lt;th class=&quot;last&quot;&gt;&lt;div class=&quot;linetotal&quot;&gt;\u0421\u0443\u043c\u043c\u0430 (\u0440\u0443\u0431)&lt;\/div&gt;&lt;\/th&gt;      &lt;\/tr&gt;    &lt;\/thead&gt;    &lt;tbody&gt;      {{#tasks}}      &lt;tr&gt;        &lt;td style=&quot;width: 160px;&quot;&gt;          &lt;a on-tap=&quot;destroy:{{this}}&quot; role=&quot;button&quot; class='hidden-print destroy'&gt;&lt;\/a&gt;          &lt;div on-click=&quot;edit&quot; class=&quot;item&quot;&gt;{{name}}&lt;\/div&gt;          &lt;input intro=&quot;select&quot; class=&quot;form-control hide&quot; value=&quot;{{name}}&quot; on-blur-enter=&quot;hide:{{this}}&quot;&gt;        &lt;\/td&gt;        &lt;td&gt;          &lt;div on-click=&quot;edit&quot; class=&quot;description&quot;&gt;{{description}}&lt;\/div&gt;          &lt;textarea class=&quot;form-control hide&quot; value=&quot;{{description}}&quot; on-blur-enter=&quot;hide:{{this}}&quot;&gt;{{description}}&lt;\/textarea&gt;        &lt;\/td&gt;        &lt;td style=&quot;width: 85px;&quot;&gt;          &lt;div on-click=&quot;edit&quot; class=&quot;unitcost&quot;&gt;{{ format(rate) }}&lt;\/div&gt;          &lt;input class=&quot;form-control hide&quot; value=&quot;{{rate}}&quot; on-blur-enter=&quot;hide:{{this}}&quot;&gt;        &lt;\/td&gt;        &lt;td style=&quot;width: 80px;&quot;&gt;          &lt;div on-click=&quot;edit&quot; class=&quot;quantity&quot;&gt;{{ format(hours) }}&lt;\/div&gt;          &lt;input class=&quot;form-control hide&quot; value=&quot;{{hours}}&quot; on-blur-enter=&quot;hide:{{this}}&quot;&gt;        &lt;\/td&gt;        &lt;td style=&quot;width: 90px;&quot;&gt;          &lt;div class=&quot;linetotal&quot;&gt;{{ format(rate * hours) }}&lt;\/div&gt;        &lt;\/td&gt;      &lt;\/tr&gt;      {{\/tasks}}        &lt;tr&gt;        &lt;td class=&quot;hidden-print text-center&quot; colspan=&quot;5&quot;&gt;          &lt;button on-click=&quot;add&quot; class=&quot;btn btn-primary btn-sm&quot;&gt;&lt;i class=&quot;glyphicon glyphicon-plus &quot;&gt;&lt;\/i&gt; \u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c&lt;\/button&gt;        &lt;\/td&gt;      &lt;\/tr&gt;      &lt;\/tbody&gt;  &lt;\/table&gt;  &lt;table class=&quot;invbody-summary&quot; cellspacing=&quot;0&quot;&gt;    &lt;tbody&gt;      &lt;tr&gt;        &lt;td class=&quot;invbody-summary-clean&quot;&gt;&nbsp;&lt;\/td&gt;        &lt;td style=&quot;width: 150px;&quot;&gt;&lt;strong&gt;\u041a \u043e\u043f\u043b\u0430\u0442\u0435: &nbsp; &nbsp;&lt;\/strong&gt;&lt;\/td&gt;        &lt;td style=&quot;width: 120px;&quot;&gt;&lt;strong&gt;            {{ total(tasks) }}        &lt;\/strong&gt;&lt;\/td&gt;      &lt;\/tr&gt;      &lt;tr class=&quot;invbody-summary-paid&quot;&gt;        &lt;td class=&quot;invbody-summary-clean&quot;&gt;&nbsp;&lt;\/td&gt;        &lt;td style=&quot;width: 150px;&quot;&gt;\u041e\u043f\u043b\u0430\u0447\u0435\u043d\u043e &nbsp; &nbsp;&lt;\/td&gt;        &lt;td style=&quot;width: 120px;&quot;&gt;-0.00&lt;\/td&gt;      &lt;\/tr&gt;      &lt;tr class=&quot;invbody-summary-total&quot;&gt;        &lt;td class=&quot;invbody-summary-clean&quot;&gt;&nbsp;&lt;\/td&gt;        &lt;td style=&quot;width: 150px;&quot;&gt;&lt;div&gt;&lt;strong&gt;\u0418\u0442\u043e\u0433\u043e \u043a \u043e\u043f\u043b\u0430\u0442\u0435: &nbsp; &nbsp;&lt;\/strong&gt;&lt;\/div&gt;&lt;\/td&gt;        &lt;td style=&quot;width: 120px;&quot;&gt;&lt;div&gt;&lt;strong&gt;            {{ total(tasks) }}        &lt;\/strong&gt;&lt;\/div&gt;&lt;\/td&gt;      &lt;\/tr&gt;    &lt;\/tbody&gt;  &lt;\/table&gt; <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u043b\u0438\u0441\u0442\u0438\u043d\u0433 \u0444\u0430\u0439\u043b\u0430 assets\/templates\/invbody-account.html<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"html\"> &lt;div class=&quot;invbody-terms&quot; on-hover=&quot;toggleBtn&quot;&gt;    &lt;a role=&quot;button&quot; title=&quot;{{ .editing ? '\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c' : '\u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0440\u0435\u043a\u0432\u0438\u0437\u0438\u0442\u044b' }}&quot;      class=&quot;hidden-print btn btn-primary btn-sm hide&quot;      on-click=&quot;edit&quot;&gt;&lt;i class=&quot;glyphicon glyphicon-{{ .editing ? 'ok' : 'pencil' }}&quot;&gt;&lt;\/i&gt;    &lt;\/a&gt;    &lt;b&gt;\u0420\u0435\u043a\u0432\u0438\u0437\u0438\u0442\u044b:&lt;\/b&gt;    &lt;div class=&quot;user-account {{ .editing ? 'editing' : '' }}&quot;&gt;      &lt;span&gt;{{^account}}\u0420\u0435\u043a\u0432\u0438\u0437\u0438\u0442\u044b \u043d\u0435 \u0443\u043a\u0430\u0437\u0430\u043d\u044b{{\/account}}{{{account}}}&lt;\/span&gt;      {{#.editing}}        &lt;div class='edit-container'&gt;          &lt;textarea value=&quot;{{account}}&quot; class='edit form-control' placeholder=&quot;\u041d\u0430\u043f\u0438\u0448\u0438\u0442\u0435 \u0432\u0430\u0448\u0438 \u0440\u0435\u043a\u0432\u0438\u0437\u0438\u0442\u044b \u0434\u043b\u044f \u043f\u043b\u0430\u0442\u0435\u0436\u0435\u0439&quot;&gt;{{account}}&lt;\/textarea&gt;        &lt;\/div&gt;      {{\/.editing}}    &lt;\/div&gt;  &lt;\/div&gt; <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u0412 \u0446\u0435\u043b\u043e\u043c \u044d\u0442\u043e \u043e\u0431\u044b\u0447\u043d\u044b\u0439 html, c \u0432\u043a\u0440\u0430\u043f\u043b\u0435\u043d\u0438\u044f\u043c\u0438 mustache-\u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0445 \u0442\u044d\u0433\u043e\u0432 <code>{{}}<\/code>, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 <b>ractive.js<\/b> \u0432\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u0432\u043e\u0438 \u0434\u0430\u043d\u043d\u044b\u0435. \u0422\u0430\u043a\u0436\u0435 \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0434\u0438\u0440\u0435\u043a\u0442\u0438\u0432\u044b <code>on-click=&quot;edit&quot;<\/code> \u2014 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u043c\u0435\u0442\u043e\u0434 <code>edit<\/code> \u043f\u043e \u043a\u043b\u0438\u043a\u0443; <code>on-hover=&quot;toggleBtn&quot;<\/code>, <code>on-tap=&quot;destroy:{{this}}&quot;<\/code> \u044d\u0442\u043e\u0442 \u043c\u043e\u043c\u0435\u043d\u0442 \u043e\u0441\u0432\u0435\u0442\u0438\u043c \u043f\u043e\u0437\u0436\u0435, \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043a\u0430 \u0438\u0437\u0443\u0447\u0438\u0442\u044c <a href=\"http:\/\/docs.ractivejs.org\/latest\/events\">\u0434\u043e\u043a\u0443 \u043f\u043e \u0435\u0432\u0435\u043d\u0442\u0430\u043c<\/a> ractive.js<\/p>\n<p>  \u0421\u043e\u0431\u044b\u0442\u0438\u044f \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u044e\u0442\u0441\u044f \u0432 ractive \u0432 \u0432\u0438\u0434\u0435 \u043f\u043b\u0430\u0433\u0438\u043d\u043e\u0432 \u2014 \u0442\u0430\u043a \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u043c\u044b\u0435 proxy-events. \u0427\u0442\u043e\u0431\u044b \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0437\u0430\u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0438, \u043d\u0443\u0436\u043d\u043e <a href=\"http:\/\/docs.ractivejs.org\/latest\/plugins#-a-href-events-events-a-\">\u0441\u043a\u0430\u0447\u0430\u0442\u044c \u043d\u0443\u0436\u043d\u044b\u0435 \u043d\u0430\u043c<\/a> (\u044f \u0441\u043a\u0430\u0447\u0430\u043b \u0432\u0441\u0435 \u043f\u043b\u0430\u0433\u0438\u043d\u044b \u0434\u043b\u044f \u0441\u043e\u0431\u044b\u0442\u0438\u0439) \u0438 \u043f\u043e\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u0438\u0445 \u0432 \u043f\u0430\u043f\u043a\u0443 <code>assets\/js\/vendor<\/code><br \/>  \u041f\u043e\u043c\u0435\u0441\u0442\u0438\u043c \u0432 \u044d\u0442\u0443 \u0436\u0435 \u043f\u0430\u043f\u043a\u0443 <a href=\"https:\/\/github.com\/ractivejs\/ractive-adaptors-backbone\">\u0430\u0434\u0430\u043f\u0442\u0435\u0440 \u0434\u043b\u044f Backbone<\/a>, \u0447\u0442\u043e\u0431\u044b ractive.js \u0441\u043c\u043e\u0433 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u043c\u043e\u0434\u0435\u043b\u0438 backbone.<\/p>\n<h5>\u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445. \u0411\u0438\u043d\u0434\u0438\u043d\u0433 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u0448\u0430\u0431\u043b\u043e\u043d\u043e\u0432<\/h5>\n<p>  \u041f\u043e\u0434\u0432\u0435\u0434\u0435\u043c \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u044b\u0439 \u0438\u0442\u043e\u0433, \u0447\u0442\u043e \u0435\u0441\u0442\u044c \u043d\u0430 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u0438 \u0447\u0442\u043e \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0432 \u0438\u0442\u043e\u0433\u0435  <\/p>\n<ul>\n<li>\u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 sails \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e rest api \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u044e\u0437\u0435\u0440\u043e\u0432, \u0438\u043d\u0432\u043e\u0439\u0441\u044b \u0438 \u0437\u0430\u0434\u0430\u0447\u0438. \u0414\u0435\u043b\u0430\u0442\u044c \u0441\u0432\u044f\u0437\u0438 \u043c\u0435\u0436\u0434\u0443 \u043d\u0438\u043c\u0438 \u0437\u0430 \u0441\u0447\u0435\u0442 <a href=\"http:\/\/beta.sailsjs.org\/#!documentation\/reference\/ModelAssociations\/ModelAssociations.html\">model associations<\/a>. \u0414\u0430\u043d\u043d\u044b\u0435 \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0432 \u0431\u0430\u0437\u0435 mongodb<\/li>\n<li>\u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0435 backbone \u043c\u043e\u0434\u0435\u043b\u0438 \u0431\u0443\u0434\u0443\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0432\u0432\u0435\u0434\u0435\u043d\u043d\u044b\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0435 \u0438 \u0441\u0438\u0445\u043d\u0440\u043e\u043d\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0441 sails \u0441\u0435\u0440\u0432\u0435\u0440\u043e\u043c \u0447\u0435\u0440\u0435\u0437 rest api <\/li>\n<li>\u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0435 ractive \u0431\u0443\u0434\u0435\u0442 \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0442\u044c two-way \u0431\u0438\u043d\u0434\u0438\u043d\u0433 \u043c\u0435\u0436\u0434\u0443 html-\u0448\u0430\u0431\u043b\u043e\u043d\u0430\u043c\u0438 \u0438 backbone \u043c\u043e\u0434\u0435\u043b\u044f\u043c\u0438 (\u0437\u0430 \u0441\u0447\u0435\u0442 <a href=\"https:\/\/github.com\/ractivejs\/ractive-adaptors-backbone\">\u0430\u0434\u0430\u043f\u0442\u0435\u0440\u0430 \u0434\u043b\u044f Backbone<\/a>) <\/li>\n<li>&#8230;.<\/li>\n<li>PROFIT?<\/li>\n<\/ul>\n<p>  \u0434\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043d\u0443\u0436\u043d\u044b\u0435 \u043d\u0430\u043c Backbone \u043c\u043e\u0434\u0435\u043b\u0438 \u0432 \u043d\u0430\u0448\u0435\u043c \u043f\u0443\u0441\u0442\u043e\u043c \u0444\u0430\u0439\u043b\u0435 <code>assets\/js\/app.js<\/code>:  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u041b\u0438\u0441\u0442\u0438\u043d\u0433 assets\/js\/app.js<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"javascript\">var app = app || {};  (function (app) {   app.User = Backbone.Model.extend({     urlRoot: '\/user',   });    app.Invoice = Backbone.Model.extend({     urlRoot: '\/invoice',   });    app.Task = Backbone.Model.extend({     urlRoot: '\/task',   });    app.Tasks = Backbone.Collection.extend({     url: '\/task',     model: app.Task   }); })(app); <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u0425\u043e\u0440\u043e\u0448\u043e, \u0442\u0435\u043f\u0435\u0440\u044c \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c ractive \u0438\u043d\u0441\u0442\u0430\u043d\u0441, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0438\u0432\u044f\u0437\u0430\u043d \u043a \u043d\u0430\u0448\u0435\u0439 \u043c\u043e\u0434\u0435\u043b\u0438 app.User \u0438 \u0431\u0443\u0434\u0435\u0442 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u0442\u044c \u043d\u0430\u0448 \u0448\u0430\u0431\u043b\u043e\u043d <code>assets\/templates\/invheader-upper.html<\/code> \u0438 <code>assets\/templates\/invbody-account.html<\/code><br \/>  \u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0444\u0430\u0439\u043b assets\/js\/user.js  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u041b\u0438\u0441\u0442\u0438\u043d\u0433 assets\/js\/user.js<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"javascript\">var app = app || {};  (function (app) {   var backboneUser = new app.User;    \/\/ \u0417\u0434\u0435\u0441\u044c \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0435\u043c ractive \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0447\u0435\u0440\u0435\u0437 Ractive.extend   \/\/ \u0432\u043c\u0435\u0441\u0442\u043e new Ractive({}), \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0443 \u043d\u0430\u0441 \u0431\u0443\u0434\u0435\u0442 2 \u043e\u0434\u043d\u043e\u0442\u0438\u043f\u043d\u044b\u0445 \u0431\u043b\u043e\u043a\u0430   var RactiveUser = Ractive.extend({     init: function (options) {       this.data = options.data;       this.on({          \/\/ \u041e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u043d\u0430\u0436\u0430\u0442\u0438\u0435 \u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0443 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f         \/\/ \u0432 \u0448\u0430\u0431\u043b\u043e\u043d\u0435 `on-click=&quot;edit&quot;`         edit: function (event) {           var editing = this.get('editing');          this.set( 'editing', !editing );           if (editing) {             this.data.save(); \/\/ \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u043c\u043e\u0434\u0435\u043b\u044c \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440           }         },          \/\/ \u0421\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0430\u0432\u0430\u0442\u0430\u0440 \u043f\u043e\u0441\u043b\u0435 \u0443\u0441\u043f\u0435\u0448\u043d\u043e\u0439 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0438         \/\/ \u043d\u0430 https:\/\/www.inkfilepicker.com         \/\/ \u0432 \u0448\u0430\u0431\u043b\u043e\u043d\u0435 `onchange=&quot;app.user.fire('setAvatar', event)&quot;`         setAvatar: function (event) {           if (event.fpfile) {             var url = event.fpfile.url;             this.set('avatar', url);           } else {             this.set('avatar', null);           }           this.data.save(); \/\/ \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u043c\u043e\u0434\u0435\u043b\u044c \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440         },          \/\/ \u0421\u043a\u0440\u044b\u0432\u0430\u0435\u043c \u0438\u043b\u0438 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0444\u043e\u0440\u043c\u0443 \u0434\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0430\u0432\u0430\u0442\u0430\u0440\u0430         \/\/ \u0432 \u0448\u0430\u0431\u043b\u043e\u043d\u0435 `on-hover=&quot;togglePicker&quot;`         togglePicker: function (event) {           if (!this.get('avatar')) return;           if ( event.hover ) {             $(event.node).find('.BoardCreateRep').removeClass('hide');           } else {             $(event.node).find('.BoardCreateRep').addClass('hide');           }         },                  \/\/ \u041f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0438\u043b\u0438 \u0441\u043a\u0440\u044b\u0432\u0430\u0435\u043c \u043a\u043d\u043e\u043f\u043a\u0443 \u0434\u043b\u044f \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445         \/\/ \u0432 \u0448\u0430\u0431\u043b\u043e\u043d\u0435 `on-hover=&quot;toggleBtn&quot;`         toggleBtn: function (event) {           if ( event.hover ) {             $(event.node).find('[role=button]').removeClass('hide');           } else {             $(event.node).find('[role=button]').addClass('hide');           }         }       });     }   });    \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c RactiveUser \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0441\u0432\u0435\u0440\u0445\u0443 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b   \/\/ \u043f\u0440\u0438\u0441\u043e\u0435\u0434\u0438\u043d\u044f\u0435\u043c \u043a \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0443 \u0441 \u043a\u043b\u0430\u0441\u0441\u043e\u043c `.invheader-upper`   app.user = new RactiveUser({     el: '.invheader-upper',     template: JST['assets\/templates\/invheader-upper.html'](),     data: backboneUser,     adaptors: [ 'Backbone' ],   });    \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c RactiveUser \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0441\u043d\u0438\u0437\u0443 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b   \/\/ \u043f\u0440\u0438\u0441\u043e\u0435\u0434\u0438\u043d\u044f\u0435\u043c \u043a \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0443 \u0441 \u043a\u043b\u0430\u0441\u0441\u043e\u043c `.invheader-account`   app.account = new RactiveUser({     el: '.invbody-account',     template: JST['assets\/templates\/invbody-account.html'](),     data: backboneUser,     adaptors: [ 'Backbone' ],   });    \/\/ \u041f\u043e\u0434\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c\u0441\u044f \u043d\u0430 \u0438\u0437\u043c\u0435\u043d\u0438\u043d\u0438\u044f Id \u044e\u0437\u0435\u0440\u0430   \/\/ \u0435\u0441\u043b\u0438 id \u0438\u0437\u043c\u0435\u043d\u0438\u043b\u043e\u0441\u044c (\u0442\u043e \u0435\u0441\u0442\u044c \u044e\u0437\u0435\u0440\u0430 \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u043b\u0438)   \/\/ \u043f\u0440\u0438\u0432\u044f\u0437\u0432\u0430\u0435\u043c \u0438\u043d\u0432\u043e\u0439\u0441 \u043a \u044d\u0442\u043e\u043c\u0443 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e   app.user.observe('id', function(id){     if (id && app.invoice) {       app.invoice.data.invoice.set('owner', id);       app.invoice.data.invoice.save();     }   }); })(app); <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u041a\u043e\u0434 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u043e\u0441\u0442. \u0417\u0434\u0435\u0441\u044c \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 <code>RactiveUser<\/code>. \u041e\u0431\u044b\u0447\u043d\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0438\u043d\u0441\u0442\u0430\u043d\u0441 \u0447\u0435\u0440\u0435\u0437 <code>new Ractive({})<\/code>, \u043d\u043e \u0432 \u0447\u0430\u0441\u0442\u043d\u043e\u0441\u0442\u0438 \u0437\u0434\u0435\u0441\u044c \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e 2 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u0434\u043b\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u0440\u0438\u0432\u044f\u0437\u0430\u043d\u044b \u043a \u043e\u0434\u043d\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u0438 \u0438 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u0434\u043f\u0438\u0441\u043d\u044b \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043d\u0430 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u044f. \u0421\u0430\u043c\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0432 \u0442\u0435\u043b\u0435 <code>init<\/code> \u0444\u0443\u043d\u043a\u0446\u0438\u0438.<\/p>\n<p>  \u0415\u0434\u0435\u043c \u0434\u0430\u043b\u044c\u0448\u0435, \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043f\u043e \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0438 <code>assets\/js\/invoice.js<\/code> \u0438 <code>assets\/js\/task.js<\/code>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u041b\u0438\u0441\u0442\u0438\u043d\u0433 assets\/js\/invoice.js<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"javascript\">var app = app || {};  (function (app) {    app.invoice = new Ractive({     el: '.invheader-lower',     template: JST['assets\/templates\/invheader-lower.html'](),     data: {       invoice: new app.Invoice, \/\/ \u043d\u0430\u0448\u0430 Backbone \u043c\u043e\u0434\u0435\u043b\u044c              \/\/ \u0445\u044d\u043b\u043f\u0435\u0440 \u0434\u043b\u044f \u043a\u0440\u0430\u0441\u0438\u0432\u043e\u0439 \u0434\u0430\u0442\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0432 \u0448\u0430\u0431\u043b\u043e\u043d\u0435 {{ date(createdAt) }}       date: function (date) {         return moment(date).format('D MMMM YYYY');       },        \/\/ \u0445\u044d\u043b\u043f\u0435\u0440 \u0434\u0432 \u0448\u0430\u0431\u043b\u043e\u043d\u0435 {{ lastFour(id) }}       lastFour: function (str) {           return str.slice(-4);       }     },     adaptors: [ 'Backbone' ],     transitions: {       select: function ( t ) {         setTimeout( function () {           t.node.select();           t.complete();         }, 200 );       }     }   });    app.invoice.on({     \/\/ \u041e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u043d\u0430\u0436\u0430\u0442\u0438\u0435 \u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0443 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f     \/\/ \u0432 \u0448\u0430\u0431\u043b\u043e\u043d\u0435 `on-click=&quot;edit&quot;`     edit: function (event) {       console.log(event);       var editing = this.get('editing');       this.set( 'editing', !editing );       if (editing) {         this.data.invoice.save({owner: app.user.data.id});       }     },     \/\/ \u041f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0438\u043b\u0438 \u0441\u043a\u0440\u044b\u0432\u0430\u0435\u043c \u043a\u043d\u043e\u043f\u043a\u0443 \u0434\u043b\u044f \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445     \/\/ \u0432 \u0448\u0430\u0431\u043b\u043e\u043d\u0435 `on-hover=&quot;toggleBtn&quot;`     toggleBtn: function (event) {       if ( event.hover ) {         $(event.node).find('[role=button]').removeClass('hide');       } else {         $(event.node).find('[role=button]').addClass('hide');       }     }   });    \/\/ \u0441\u0440\u0430\u0437\u0443 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0438\u043d\u0432\u043e\u0439\u0441 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440   app.invoice.data.invoice.save();  })(app); <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u041b\u0438\u0441\u0442\u0438\u043d\u0433 assets\/js\/task.js<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"javascript\">var app = app || {};  (function (app) {   app.tasks = new Ractive({     el: '.invbody-tasks',     template: JST['assets\/templates\/invbody-tasks.html'](),     data: {       tasks: new app.Tasks, \/\/ \u043d\u0430\u0448\u0430 Backbone \u043c\u043e\u0434\u0435\u043b\u044c        \/\/ \u0445\u044d\u043b\u043f\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0432 \u0448\u0430\u0431\u043b\u043e\u043d\u0435 {{ format(price) }}       format: function ( num ) {         return num.toFixed( 2 );       },        \/\/ \u0445\u044d\u043b\u043f\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0432 \u0448\u0430\u0431\u043b\u043e\u043d\u0435 {{ total(tasks) }}       total: function ( collection ) {         var total = collection.reduce(function( sum, el ) {           return el.get('rate') * el.get('hours') + sum;         }, 0 );         return total.toFixed( 2 );       },     },     adaptors: [ 'Backbone' ],     transitions: {       select: function ( t ) {         setTimeout( function () {           t.node.select();           t.complete();         }, 200 );       }     }   });    app.tasks.on({      \/\/ \u041e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u043d\u0430\u0436\u0430\u0442\u0438\u0435 \u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0443 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0442\u0430\u0441\u043a\u0430     \/\/ \u0432 \u0448\u0430\u0431\u043b\u043e\u043d\u0435 `on-click=&quot;add&quot;`     add: function ( event ) {       var tasks = this.get('tasks');       var task = new app.Task({         name: '\u0411\u0435\u0437 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f',         description: '\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043d\u0435\u0442',         hours: 0,         rate: 0,       });       tasks.add(task);       task.save(null, {         \/\/ \u0445\u0430\u043a, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0438\u0432\u044f\u0437\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0439 \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0439 \u0442\u0430\u0441\u043a \u043a \u0442\u0435\u043a\u0443\u0449\u0435\u043c\u0443 \u0438\u043d\u0432\u043e\u0439\u0441\u0443         success: function() {           task.set('invoice', app.invoice.data.invoice.id);           task.save();         }       });     },      \/\/ \u0443\u0434\u0430\u043b\u044f\u0435\u043c \u0442\u0430\u0441\u043a \u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0442\u043e\u0436\u0435     \/\/ \u0432 \u0448\u0430\u0431\u043b\u043e\u043d\u0435 `on-tap=&quot;destroy:{{this}}&quot;`     destroy: function ( event, task ) {       task.destroy();     },      \/\/ \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0438\u043d\u043f\u0443\u0442 \u0434\u043b\u044f \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u0432\u043e\u0439\u0441\u0442\u0432 \u0442\u0430\u0441\u043a\u0430     \/\/ \u0432 \u0448\u0430\u0431\u043b\u043e\u043d\u0435 `on-click=&quot;edit&quot;`     edit: function ( event ) {       $(event.node).hide();       $(event.node).next().removeClass('hide').focus().select();     },      \/\/ \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0442\u0430\u043a\u0441 \u043f\u043e\u0441\u043b\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043a\u0430\u043a\u043e\u0433\u043e-\u043b\u0438\u0431\u043e \u043f\u043e\u043b\u044f     \/\/ \u0432 \u0448\u0430\u0431\u043b\u043e\u043d\u0435 `on-blur-enter=&quot;hide&quot;`     hide: function ( event, task ) {       $(event.node).addClass('hide');       $(event.node).prev().show();       task.save({invoice: app.invoice.data.invoice.id});     },   });    \/\/ \u043f\u043e\u0434\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c\u0441\u044f \u043d\u0430 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 `hours` \u0438 `rate` \u0434\u043b\u044f \u0442\u0430\u0441\u043a\u043e\u0432   \/\/ \u0447\u0442\u043e\u0431\u044b \u043f\u0435\u0440\u0435\u0441\u0447\u0438\u0442\u0438\u0432\u0430\u0442\u044c \u0441\u0443\u043c\u043c\u0443   \/\/ \u0441\u0443\u043c\u043c\u0443 \u0442\u0430\u043a\u0436\u0435 \u043c\u0435\u043d\u044f\u0435\u043c \u0443 \u0438\u043d\u0432\u043e\u0439\u0441\u0430   \/\/ TODO \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c \u0438\u043d\u0432\u043e\u0439\u0441 \u043f\u043e\u0441\u043b\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0441\u0443\u043c\u043c\u044b   app.tasks.observe('tasks.*.hours tasks.*.rate', function(tasks, old, keypath){     var total = this.data.total(this.data.tasks);     app.invoice.data.invoice.set('total_amount', total);   });  })(app); <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u0417\u0434\u0435\u0441\u044c \u0442\u0430\u043a\u0436\u0435 \u043a\u043e\u0434 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u043e\u043d\u044f\u0442\u0435\u043d, \u0434\u043b\u044f \u044d\u0432\u0435\u043d\u0442\u043e\u0432 \u0434\u043e\u0431\u0430\u0432\u0438\u043b \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438. \u041f\u043e \u0441\u0443\u0442\u0438 \u044d\u0442\u043e \u0432\u0435\u0441\u044c \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u0438\u0439 \u043a\u043e\u0434. \u041f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043b \u0435\u0449\u0435 \u043f\u0440\u0438\u043a\u0440\u0443\u0442\u0438\u0442\u044c \u043c\u0435\u0442\u043e\u0434 \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0438\u043d\u0432\u043e\u0439\u0441\u0430 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 id (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <code>http:\/\/localhost:1337\/main\/generate\/535ea7aa6113230d773fd160<\/code>) \u0438\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c api pdfcrowd.com, \u0431\u043b\u0430\u0433\u043e \u0443 \u043d\u0438\u0445 \u0435\u0441\u0442\u044c \u043c\u043e\u0434\u0443\u043b\u044c \u0434\u043b\u044f node, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u043e \u0443\u0440\u043b\u0443 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c pdf\u2026 \u041e\u0434\u043d\u0430\u043a\u043e \u0437\u0430 \u0432\u044b\u0445\u043e\u0434\u043d\u044b\u0435 \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043d\u0435 \u0443\u0441\u043f\u0435\u043b. \u0421\u0435\u0439\u0447\u0430\u0441 \u044f \u0441\u043e\u0437\u0434\u0430\u044e pdf \u0447\u0435\u0440\u0435\u0437 ctrp+P (\u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u043d\u0430 \u043f\u0435\u0447\u0430\u0442\u044c) -&gt; \u00ab\u041f\u0435\u0447\u0430\u0442\u044c \u0432 \u0444\u0430\u0439\u043b\u00bb. \u0410 \u0434\u043b\u044f \u0442\u043e\u0433\u043e \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u0432\u044b\u043b\u0435\u0437\u043b\u0438 \u043d\u0435\u043d\u0443\u0436\u043d\u044b\u0435 html \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043a\u043d\u043e\u043f\u043a\u0438) \u2014 \u0434\u043e\u0431\u0430\u0432\u0438\u043b \u0434\u043b\u044f \u043d\u0438\u0445 \u043a\u043b\u0430\u0441\u0441 <code>hidden-print<\/code>.<\/p>\n<h5>\u0414\u0435\u043f\u043b\u043e\u0439 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440<\/h5>\n<p>  \u041d\u0430 \u044d\u0442\u043e\u043c \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0432\u0441\u0435 \u2014 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0433\u043e\u0442\u043e\u0432\u043e. \u0414\u0430\u043d\u043d\u044b\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 <a href=\"https:\/\/github.com\/zaebee\/sailsjs-ractive-backbone-demo\">\u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043d\u0430 \u0433\u0438\u0442\u0445\u0430\u0431\u0435 <\/a><\/p>\n<p>  \u041d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 \u043a\u043b\u043e\u043d\u0438\u0440\u0443\u0435\u043c \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439, \u0441\u0442\u0430\u0432\u0438\u043c \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c sails \u0432 \u043f\u0440\u043e\u0434\u0430\u043a\u0448\u043d \u0440\u0435\u0436\u0438\u043c\u0435:  <\/p>\n<pre><code class=\"bash\">node app.js --port=8000 --prod <\/code><\/pre>\n<p>  \u0417\u0430\u043f\u0443\u0441\u0442\u0438\u043b \u0440\u0430\u0431\u043e\u0447\u0435\u0435 <a href=\"http:\/\/clearway.name:8000\/main\/generate\/\">\u0434\u0435\u043c\u043e<\/a> \u0432 \u043f\u0440\u043e\u0434\u0430\u043a\u0448\u043d \u0440\u0435\u0436\u0438\u043c\u0435<\/p>\n<h4>\u0420\u0435\u0437\u044e\u043c\u0435<\/h4>\n<p>  \u0418\u0442\u043e\u0433 \u0440\u0430\u0431\u043e\u0442\u044b \u043a\u0430\u043a \u0441 sailsjs \u0442\u0430\u043a \u0438 \u0441 ractive \u2014 \u043e\u0447\u0435\u043d\u044c \u043f\u043e\u0440\u0430\u0434\u043e\u0432\u0430\u043b.<br \/>  Sailsjs \u2014 \u043f\u043b\u044e\u0441\u044b:<br \/>  + \u041f\u043e\u043d\u0440\u0430\u0432\u0438\u043b\u043e\u0441\u044c, \u043d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0432 sails \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f api <br \/>  + \u041e\u0447\u0435\u043d\u044c \u043a\u043b\u0430\u0441\u0441\u043d\u044b\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u043d\u0430\u0447\u0438\u043d\u0430\u044f \u043e\u0442 \u0448\u0430\u0431\u043b\u043e\u043d\u043d\u043e\u0433\u043e \u0434\u0432\u0438\u0436\u043a\u0430, \u0411\u0414, \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u043e\u0433\u043e \u041e\u0420\u041c (\u043f\u043b\u0430\u043d\u0438\u0440\u0443\u044e \u043f\u0440\u0438\u043a\u0440\u0443\u0442\u0438\u0442\u044c <a href=\"http:\/\/bookshelfjs.org\/\">bookshelfjs.org\/<\/a> \u043d\u0430 sails )<br \/>  + \u041e\u0447\u0435\u043d\u044c \u043f\u043e\u043d\u0440\u0430\u0432\u0438\u043b\u043e\u0441\u044c, \u0447\u0442\u043e \u0435\u0441\u0442\u044c \u0433\u043e\u0442\u043e\u0432\u044b\u0435 grunt \u0442\u0430\u0441\u043a\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435\u043f\u043b\u043e\u0445\u043e \u0440\u0435\u0448\u0430\u044e\u0442 \u0437\u0430\u0434\u0430\u0447\u0443 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u0430\u043a \u043f\u0440\u043e\u0434 \u0442\u0430\u043a \u0438 \u0434\u0435\u0432 \u0431\u0430\u043d\u0434\u043b\u043e\u0432. <br \/>  + \u0435\u0441\u0442\u044c \u043a\u043e\u043c\u0430\u043d\u0434\u0430 (<code>sails www<\/code>) \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043a\u043b\u0438\u0435\u043d\u0441\u043a\u0438\u0439 \u043a\u043e\u0434 \u2014 \u0443\u0434\u043e\u0431\u043d\u043e \u0434\u043b\u044f \u043e\u0442\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0444\u0440\u043e\u043d\u0442\u0430 \u0438 \u0441\u0435\u0440\u0432\u0435\u0440\u0430.<br \/>  + \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 \u043c\u0443\u043b\u044c\u0442\u0438\u044f\u0437\u044b\u0447\u043d\u043e\u0441\u0442\u0438 (\u043d\u0435 \u044e\u0437\u0430\u043b, \u043d\u043e \u0437\u043d\u0430\u044e, \u0447\u0442\u043e \u0435\u0441\u0442\u044c)<\/p>\n<p>  \u041c\u0438\u043d\u0443\u0441\u044b:<br \/>   \u2014 \u043d\u0430 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u0431\u0430\u0433\u043d\u0443\u0442\u0430\u044f \u0440\u0430\u0431\u043e\u0442\u0430 model assocoations (\u043f\u043e\u043d\u0438\u043c\u0430\u044e, \u0447\u0442\u043e v0.10 \u2014 \u0435\u0449\u0435 \u0431\u0435\u0442\u0430, \u0430 \u0432 v0.9.x \u2014 \u044d\u0442\u043e\u0433\u043e \u0432\u043e\u043e\u0431\u0449\u0435 \u043d\u0435\u0442)<br \/>   \u2014 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 \u043b\u0435\u0439\u043e\u0443\u0442\u043e\u0432 \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f ejs \u0448\u0430\u0431\u043b\u043e\u043d\u043e\u0432<\/p>\n<p>  Ractivejs -\u043f\u043b\u044e\u0441\u044b:<br \/>  + \u0440\u0435\u0448\u0430\u0435\u0442 \u0441\u0432\u043e\u044e \u0437\u0430\u0434\u0430\u0447\u0443 two-way \u0431\u0438\u043d\u0434\u0438\u043d\u0433\u0430<br \/>  + \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u0440\u0438\u0432\u044f\u0437\u043a\u0438 \u043a backbone<br \/>  + \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u0435\u043c\u043e\u0441\u0442\u044c (\u043c\u043e\u0436\u043d\u043e \u043f\u0438\u0441\u0430\u0442\u044c \u0441\u0432\u043e\u0438 \u043f\u043b\u0430\u0433\u0438\u043d\u044b)<br \/>  + \u0443\u0434\u043e\u0431\u043d\u044b\u0439 \u0448\u0430\u0431\u043b\u043e\u043d\u0438\u0437\u0430\u0442\u043e\u0440 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 mustache (\u043d\u0435 \u043b\u044e\u0431\u043b\u044e ejs \u2014 \u043e\u0447\u0435\u043d\u044c \u0433\u0440\u043e\u043c\u043e\u0437\u0434\u043a\u0438\u0439 \u043a\u0430\u043a \u043f\u043e \u043c\u043d\u0435)<br \/>  + \u0445\u043e\u0440\u043e\u0448\u0430\u044f \u0434\u043e\u043a\u0430, <a href=\"http:\/\/examples.ractivejs.org\/\">\u043f\u0440\u0438\u043c\u0435\u0440\u044b<\/a> \u0438 <a href=\"http:\/\/learn.ractivejs.org\/\">\u0442\u0443\u0442\u043e\u0440\u0438\u0430\u043b<\/a><\/p>\n<p>  \u041c\u0438\u043d\u0443\u0441\u043e\u0432 \u0437\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0434\u043d\u0435\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043d\u0435 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u043b\u2026<\/p>\n<p>  \u0411\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044e \u0437\u0430 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435.    \t<\/p>\n<div class=\"clear\"><\/div>\n<\/p><\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"http:\/\/habrahabr.ru\/post\/221171\/\"> http:\/\/habrahabr.ru\/post\/221171\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div class=\"content html_format\">   \t<img decoding=\"async\" src=\"http:\/\/habrastorage.org\/files\/88f\/b6a\/e18\/88fb6ae1887d4fdab691e9e985a18894.png\"\/><\/p>\n<p>  \u0414\u043e\u0431\u0440\u043e\u0433\u043e \u0434\u043d\u044f, \u043d\u0430 \u0432\u044b\u0445\u043e\u0434\u043d\u044b\u0445 \u043e\u0442 \u0441\u043a\u0443\u043a\u0438 \u0438 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0440\u0435\u0448\u0438\u043b \u0441\u0435\u0431\u044f \u0440\u0430\u0437\u0432\u043b\u0435\u0447\u044c \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u0435\u043c \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0441\u0433\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0443\u0447\u0435\u0431\u043d\u043e\u0433\u043e \u043c\u0435\u0442\u0430\u0440\u0438\u0430\u043b\u0430 \u0434\u043b\u044f \u0438\u0437\u0443\u0447\u0435\u043d\u0438\u044f \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439 \u0434\u0432\u0443\u0445 \u0437\u0430\u043c\u0435\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a \u2014 <a href=\"http:\/\/ractivejs.org\/\">ractive.js<\/a> \u0438 <a href=\"http:\/\/sailsjs.org\">sails.js<\/a> <\/p>\n<h5>\u041f\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0437\u0430\u0434\u0430\u0447\u0438<\/h5>\n<p>  \u041f\u043e \u0440\u0430\u0431\u043e\u0442\u0435 \u0447\u0430\u0441\u0442\u043e \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043f\u043e\u0441\u043b\u0435 \u0432\u044b\u043f\u043e\u043b\u0435\u043d\u0435\u043d\u0438\u044f \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u0433\u043e \u0437\u0430\u0434\u0430\u043d\u0438\u044f (\u044f \u2014 \u0444\u0440\u0438\u043b\u0430\u043d\u0441\u0435\u0440) \u0432\u044b\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u0437\u0430\u043a\u0430\u0437\u0447\u0438\u043a\u0443 \u0441\u0447\u0435\u0442 \u043d\u0430 \u043e\u043f\u043b\u0430\u0442\u0443 \u0443\u0441\u043b\u0443\u0433. \u0422\u0435\u043c \u0431\u043e\u043b\u0435\u0435 \u0435\u0441\u043b\u0438 \u0438\u043c\u0435\u0435\u0448\u044c \u0434\u0435\u043b\u043e \u0441 \u044e\u0440\u0438\u0434\u0438\u0447\u0435\u0441\u043a\u0438\u043c\u0438 \u043b\u0438\u0446\u0430\u043c\u0438. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b \u043f\u0440\u043e\u0441\u0442\u043e\u0439 html-\u0448\u0430\u0431\u043b\u043e\u043d, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u0430\u043d\u043d\u044b\u0435 \u0437\u0430\u043d\u043e\u0441\u0438\u043b \u0440\u0443\u043a\u0430\u043c\u0438, \u0438\u0441\u043f\u0440\u0430\u0432\u043b\u044f\u044f \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u044b\u0435 <code>&lt;td&gt;&lt;\/tr&gt;<\/code>\u2026<\/p>\n<p>  \u0412\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a  <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-221171","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/221171","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=221171"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/221171\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=221171"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=221171"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=221171"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}