├── .gitignore ├── LICENSE ├── README.md ├── package.json ├── public ├── favicon.ico ├── fonts │ ├── hg-FiraSans-Medium.eot │ ├── hg-FiraSans-Medium.otf │ ├── hg-FiraSans-Medium.svg │ ├── hg-FiraSans-Medium.ttf │ ├── hg-FiraSans-Medium.woff │ ├── hg-FiraSans-Medium.woff2 │ ├── hg-FiraSans-Regular.eot │ ├── hg-FiraSans-Regular.otf │ ├── hg-FiraSans-Regular.svg │ ├── hg-FiraSans-Regular.ttf │ ├── hg-FiraSans-Regular.woff │ └── hg-FiraSans-Regular.woff2 ├── index.html ├── scripts │ ├── jquery-1.8.3.min.js │ └── jquery.scrollTo.min.js └── styles │ ├── access_deny.css │ ├── all.css │ ├── forms.css │ ├── global_main.css │ └── posts.css ├── src ├── components │ ├── App.js │ ├── AuthorInfo.js │ ├── AuthorInfoByCompany.js │ ├── DefaultPageHeader.js │ ├── Feedback.js │ ├── FormAdminCauses.js │ ├── InfoAbout.js │ ├── InfoHelp.js │ ├── InfoHelpHabracentre.js │ ├── InfoHelpHubs.js │ ├── InfoHelpKarma.js │ ├── InfoHelpLenta.js │ ├── InfoHelpOther.js │ ├── InfoHelpPosts.js │ ├── InfoHelpRegistration.js │ ├── InfoHelpRules.js │ ├── InfoHelpSettings.js │ ├── MainNavBar.js │ ├── NotFound.js │ ├── PostFull.js │ ├── PostHeader.js │ ├── PostInfoPanel.js │ ├── PostTeaser.js │ ├── PostTeaserList.js │ ├── PostType.js │ ├── SearchForm.js │ ├── TopicAdd.js │ ├── TrackerButton.js │ ├── UserDropdown.js │ ├── UserMenu.js │ ├── UserNavBar.js │ └── WriteTopicButton.js ├── ducks │ ├── app.js │ ├── editPost.js │ ├── flows.js │ ├── index.js │ └── posts.js ├── index.js ├── routes.js └── utils.js └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | node_modules 5 | 6 | # testing 7 | coverage 8 | 9 | # production 10 | build 11 | 12 | # misc 13 | .DS_Store 14 | .env 15 | npm-debug.log 16 | 17 | .idea/ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 comerc 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "yobr.ru", 3 | "version": "0.1.3", 4 | "license": "MIT", 5 | "homepage": "https://comerc.github.io/yobr.ru", 6 | "devDependencies": { 7 | "gh-pages": "^0.12.0", 8 | "react-scripts": "0.8.5", 9 | "redux-devtools-extension": "^2.13.0" 10 | }, 11 | "dependencies": { 12 | "react": "^15.4.2", 13 | "react-dom": "^15.4.2", 14 | "react-helmet": "^4.0.0", 15 | "react-redux": "^5.0.2", 16 | "react-router": "^3.0.2", 17 | "react-router-redux": "^4.0.7", 18 | "react-router-scroll": "^0.4.1", 19 | "redux": "^3.6.0", 20 | "redux-act": "^1.1.0", 21 | "redux-logger": "^2.8.1", 22 | "redux-thunk": "^2.2.0", 23 | "reselect": "^2.5.4", 24 | "styled-components": "^1.4.3" 25 | }, 26 | "scripts": { 27 | "start": "react-scripts start", 28 | "build": "react-scripts build", 29 | "test": "react-scripts test --env=jsdom", 30 | "eject": "react-scripts eject", 31 | "deploy": "npm run build&&gh-pages -d build" 32 | }, 33 | "eslintConfig": { 34 | "extends": "react-app" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/comerc/habr/1a42ee41c675b5d7a5ad8842be2e009e2208a495/public/favicon.ico -------------------------------------------------------------------------------- /public/fonts/hg-FiraSans-Medium.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/comerc/habr/1a42ee41c675b5d7a5ad8842be2e009e2208a495/public/fonts/hg-FiraSans-Medium.eot -------------------------------------------------------------------------------- /public/fonts/hg-FiraSans-Medium.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/comerc/habr/1a42ee41c675b5d7a5ad8842be2e009e2208a495/public/fonts/hg-FiraSans-Medium.otf -------------------------------------------------------------------------------- /public/fonts/hg-FiraSans-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/comerc/habr/1a42ee41c675b5d7a5ad8842be2e009e2208a495/public/fonts/hg-FiraSans-Medium.ttf -------------------------------------------------------------------------------- /public/fonts/hg-FiraSans-Medium.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/comerc/habr/1a42ee41c675b5d7a5ad8842be2e009e2208a495/public/fonts/hg-FiraSans-Medium.woff -------------------------------------------------------------------------------- /public/fonts/hg-FiraSans-Medium.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/comerc/habr/1a42ee41c675b5d7a5ad8842be2e009e2208a495/public/fonts/hg-FiraSans-Medium.woff2 -------------------------------------------------------------------------------- /public/fonts/hg-FiraSans-Regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/comerc/habr/1a42ee41c675b5d7a5ad8842be2e009e2208a495/public/fonts/hg-FiraSans-Regular.eot -------------------------------------------------------------------------------- /public/fonts/hg-FiraSans-Regular.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/comerc/habr/1a42ee41c675b5d7a5ad8842be2e009e2208a495/public/fonts/hg-FiraSans-Regular.otf -------------------------------------------------------------------------------- /public/fonts/hg-FiraSans-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/comerc/habr/1a42ee41c675b5d7a5ad8842be2e009e2208a495/public/fonts/hg-FiraSans-Regular.ttf -------------------------------------------------------------------------------- /public/fonts/hg-FiraSans-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/comerc/habr/1a42ee41c675b5d7a5ad8842be2e009e2208a495/public/fonts/hg-FiraSans-Regular.woff -------------------------------------------------------------------------------- /public/fonts/hg-FiraSans-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/comerc/habr/1a42ee41c675b5d7a5ad8842be2e009e2208a495/public/fonts/hg-FiraSans-Regular.woff2 -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Хабрахабр 7 | 8 | 9 | 10 | 11 | 12 | 13 | 22 | 25 | 59 | 60 | 61 | 64 | 65 | 66 |
Загрузка...
67 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /public/scripts/jquery.scrollTo.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2007-2015 Ariel Flesler - afleslergmailcom | http://flesler.blogspot.com 3 | * Licensed under MIT 4 | * @author Ariel Flesler 5 | * @version 2.1.0 6 | */ 7 | ;(function(l){'use strict';l(['jquery'],function($){var k=$.scrollTo=function(a,b,c){return $(window).scrollTo(a,b,c)};k.defaults={axis:'xy',duration:0,limit:true};function isWin(a){return!a.nodeName||$.inArray(a.nodeName.toLowerCase(),['iframe','#document','html','body'])!==-1}$.fn.scrollTo=function(f,g,h){if(typeof g==='object'){h=g;g=0}if(typeof h==='function'){h={onAfter:h}}if(f==='max'){f=9e9}h=$.extend({},k.defaults,h);g=g||h.duration;var j=h.queue&&h.axis.length>1;if(j){g/=2}h.offset=both(h.offset);h.over=both(h.over);return this.each(function(){if(f===null)return;var d=isWin(this),elem=d?this.contentWindow||window:this,$elem=$(elem),targ=f,attr={},toff;switch(typeof targ){case'number':case'string':if(/^([+-]=?)?\d+(\.\d+)?(px|%)?$/.test(targ)){targ=both(targ);break}targ=d?$(targ):$(targ,elem);if(!targ.length)return;case'object':if(targ.is||targ.style){toff=(targ=$(targ)).offset()}}var e=$.isFunction(h.offset)&&h.offset(elem,targ)||h.offset;$.each(h.axis.split(''),function(i,a){var b=a==='x'?'Left':'Top',pos=b.toLowerCase(),key='scroll'+b,prev=$elem[key](),max=k.max(elem,a);if(toff){attr[key]=toff[pos]+(d?0:prev-$elem.offset()[pos]);if(h.margin){attr[key]-=parseInt(targ.css('margin'+b),10)||0;attr[key]-=parseInt(targ.css('border'+b+'Width'),10)||0}attr[key]+=e[pos]||0;if(h.over[pos]){attr[key]+=targ[a==='x'?'width':'height']()*h.over[pos]}}else{var c=targ[pos];attr[key]=c.slice&&c.slice(-1)==='%'?parseFloat(c)/100*max:c}if(h.limit&&/^\d+$/.test(attr[key])){attr[key]=attr[key]<=0?0:Math.min(attr[key],max)}if(!i&&h.axis.length>1){if(prev===attr[key]){attr={}}else if(j){animate(h.onAfterFirst);attr={}}}});animate(h.onAfter);function animate(a){var b=$.extend({},h,{queue:true,duration:g,complete:a&&function(){a.call(elem,targ,h)}});$elem.animate(attr,b)}})};k.max=function(a,b){var c=b==='x'?'Width':'Height',scroll='scroll'+c;if(!isWin(a))return a[scroll]-$(a)[c.toLowerCase()]();var d='client'+c,doc=a.ownerDocument||a.document,html=doc.documentElement,body=doc.body;return Math.max(html[scroll],body[scroll])-Math.min(html[d],body[d])};function both(a){return $.isFunction(a)||$.isPlainObject(a)?a:{top:a,left:a}}$.Tween.propHooks.scrollLeft=$.Tween.propHooks.scrollTop={get:function(t){return $(t.elem)[t.prop]()},set:function(t){var a=this.get(t);if(t.options.interrupt&&t._last&&t._last!==a){return $(t.elem).stop()}var b=Math.round(t.now);if(a!==b){$(t.elem)[t.prop](b);t._last=this.get(t)}}};return k})}(typeof define==='function'&&define.amd?define:function(a,b){'use strict';if(typeof module!=='undefined'&&module.exports){module.exports=b(require('jquery'))}else{b(jQuery)}})); 8 | -------------------------------------------------------------------------------- /public/styles/all.css: -------------------------------------------------------------------------------- 1 | .info_page{font-size:14px}.info_page .hotkey_btn{display:inline-block;border:1px solid #ccc;border-radius:5px;background:#eee;padding:3px 8px;min-width:14px;text-align:center;color:#333}.info_page table tr td,.info_page table tr th{vertical-align:top}.info_page .btable tr td:nth-child(2),.info_page .btable tr td:nth-child(3){text-align:center}.info_page h1{margin-bottom:.7em;letter-spacing:-1px;font:23px/100% Verdana,sans-serif}.info_page h2{clear:left;padding-top:.5em;color:#ff6000;font-family:Arial,sans-serif;font-size:18px;font-weight:400}.info_page h2>a,.info_page h2>a:hover,.info_page h2>a:visited{color:#ff6000}.info_page p{margin:1em 0;line-height:1.54em}.info_page p:first-child{margin-top:0}.info_page ol{margin-top:1em;padding:0}.info_page li{margin-bottom:.5em;line-height:1.54em}.info_page ul{margin:1em 0 1.5em 2.65em;list-style:disc;line-height:1.54em;padding:0}.info_page .block-semi{margin-bottom:1em}.madskillz_page abbr{border-bottom:.1em dotted;cursor:help}.madskillz_page blockquote{clear:both;margin:.83em 0;border-left:2px solid #bbb;padding-left:15px}.madskillz_page table{clear:both;margin:1.5em 0;border:1px solid #ccc;border-collapse:collapse;width:100%}.madskillz_page table caption{text-align:left;text-indent:1em}.madskillz_page table td,.madskillz_page table th{border:1px solid #ccc;padding:.3em;word-break:break-word}.madskillz_page table td img,.madskillz_page table th img{max-width:630px!important}.madskillz_page code,.madskillz_page pre code{font-family:Menlo,Monaco,'Courier New',monospace}.madskillz_page code{border:1px solid #e1e1e8;border-radius:3px;background-color:#f7f7f9;padding:1px 4px;white-space:normal;color:#222}.madskillz_page pre .hljs,.madskillz_page pre .nohighlight{display:block;overflow-x:auto}.madskillz_page pre{word-break:break-all;overflow-y:hidden;overflow-x:auto}.madskillz_page pre code{background:#f8f8f8;padding:1em;white-space:pre-wrap;color:#333}.madskillz_page .spoiler{overflow:hidden}.madskillz_page .spoiler:before{display:block;float:left;margin-top:2px;border:0 solid red;background:url(https://habracdn.net/habr/images/1486388270/spoiler.icon.png) no-repeat left top;width:16px;height:16px;content:' '}.madskillz_page .spoiler .spoiler_title{border-bottom:1px dashed;cursor:pointer;color:#6da3bd;font-weight:400}.madskillz_page .spoiler .spoiler_text{display:none;margin-top:10px;border:1px solid #eee;background:#f9f9f9;padding:10px;overflow:hidden}.madskillz_page .block-semi{margin-bottom:0}.madskillz_page img[align=left]{margin-top:5px;margin-right:30px;margin-bottom:5px}.habr-badge{display:inline-block;border:1px solid;border-radius:5px;padding:5px 15px;width:100%;vertical-align:top;color:#000;box-sizing:border-box}.habr-badge__desc,.habr-badge__info,.habr-badge__title{padding-bottom:25px}.habr-badge__desc{padding-left:20px;box-sizing:border-box} 2 | -------------------------------------------------------------------------------- /public/styles/forms.css: -------------------------------------------------------------------------------- 1 | input,select,textarea{font-family:Arial,'Helvetica Neue',Helvetica,sans-serif;font-size:12px}textarea{resize:none}form #company_specializm,form #user_specializm,form .item,form .spoiler_help{position:relative;margin-bottom:25px}form .spoiler_help .text{margin-top:15px;font-size:13px}form .spoiler_help .text ol{padding-left:30px;list-style:decimal}form .item.userformat{margin-top:25px}form .item .count{position:absolute;top:0;right:0;font-size:11px;color:#999;text-align:right}form .item:last-child{margin-bottom:0}form .item>label{display:block;margin-bottom:7px;font-family:Arial,'Helvetica Neue',Helvetica,sans-serif;font-size:13px;font-weight:700;line-height:13px;color:#424242}form .item>label .required_field{color:#ff7058}form .item input[type=email],form .item input[type=password],form .item input[type=text]{display:block;width:100%;height:34px;padding:0 10px;margin:0;font-size:14px;line-height:34px;color:#3b3b3b;border:1px solid #d9d9d9;box-sizing:border-box}form .item input[type=email]:focus,form .item input[type=password]:focus,form .item input[type=text]:focus,form .item textarea:focus{border:1px solid #a2bfd2;outline:0;box-shadow:none;-webkit-transition:border linear .2s,box-shadow linear .2s;transition:border linear .2s,box-shadow linear .2s}form .item input.form-control_datepicker,form .item input.form-control_timepicker{display:inline-block;vertical-align:baseline;width:auto;margin-left:13px}form .item textarea{width:99%;height:200px}form .item select,form .item select option{line-height:27px}form .item input[type=email]:disabled,form .item input[type=password]:disabled,form .item input[type=text]:disabled,form .item textarea:disabled{color:#bbb;background:#eee;border:1px solid #d9d9d9}form .item input[type=checkbox]{margin:3px}form .item .error{display:block;margin-top:5px;font-size:11px;line-height:13px;color:#ff7058}form .item .description{margin-top:5px;font-size:11px;line-height:15px;color:#999}form .item .checkbox_list{margin-top:10px;overflow:hidden}form .item .checkbox_list label{display:block;float:left;width:50%;font-weight:400}form .item.one_column .checkbox_list label{float:none;width:auto;margin-bottom:10px}form .item .radio_list{margin-top:10px}form .item .radio_list label{font-weight:400}form .item .radio_list.custom{color:#3f3f3f}form .item .radio_list.custom label{display:inline-block;margin:5px 10px;color:#3a7ca2;cursor:pointer;border-bottom:1px dashed}form .item .radio_list.custom label:first-child{margin-left:5px}form .item .radio_list.custom label.checked{padding:5px;margin:0 5px;color:#53513f;background:#eeecd8;border-bottom:0;border-radius:6px}form .item .radio_list.custom label.checked:first-child{margin-left:0}form .item .radio_list.custom label input{display:none}form .item .checkbox_single{margin-bottom:10px}form .item .checkbox_single label{display:inline-block;margin:0;font-weight:400}form .item .checkbox_in_label label{display:inline;font-weight:400}form .item .checkbox_in_label .label{font-weight:700}form .item .iframe_uploader{overflow:hidden;border:0}form .item .iframe_uploader_preview,form .item.habracaptcha{overflow:hidden}form .item .iframe_uploader_preview .image{position:relative;float:left;max-width:70%;min-width:48px;min-height:48px;margin-bottom:10px}form .item .iframe_uploader_preview .image .delete{position:absolute;top:2px;right:2px;display:none;float:right;padding:5px;font-size:10px;line-height:10px;color:#fff;text-transform:uppercase;cursor:pointer;background:#666;opacity:.9}form .item .iframe_uploader_preview .image .delete:hover{background:#8b0000}form .item .iframe_uploader_preview .image:hover .delete{display:block}form .item .iframe_uploader_preview .image img{display:block;max-width:100%;min-width:30px;padding:0;margin:0}form .item.habracaptcha .captcha_image{margin-bottom:20px;font-size:11px}form .item.habracaptcha img{width:166px;height:75px;margin-right:10px;vertical-align:middle}form .item.habracaptcha a{font-size:14px;text-decoration:none}form .item.habracaptcha a span{font-size:11px;border-bottom:1px dashed}.company_description_form #company_specializm,.company_description_form #user_specializm,.profile_settings_form #company_specializm,.profile_settings_form #user_specializm{position:relative;padding:17px 0 8px;margin:0;box-sizing:border-box}.company_description_form #company_specializm .item,.company_description_form #user_specializm .item,.profile_settings_form #company_specializm .item,.profile_settings_form #user_specializm .item{padding:0}.company_description_form #company_specializm .item .count,.company_description_form #user_specializm .item .count,.profile_settings_form #company_specializm .item .count,.profile_settings_form #user_specializm .item .count{top:0}.company_description_form .item,.profile_settings_form .item{padding:17px 0 8px;margin:0;box-sizing:border-box}.company_description_form .item:first-child,.profile_settings_form .item:first-child{padding-top:0}.company_description_form .item.avatar,.company_description_form .item.stages,.profile_settings_form .item.avatar,.profile_settings_form .item.stages{padding-bottom:25px;box-sizing:border-box}.company_description_form .item .count,.profile_settings_form .item .count{top:0}.form-field-medium .item{width:60%}.form-field-small .item{width:30%}.editor{position:relative}.editor .panel{background:#f5f5f5;border:1px solid #e0e0e0;border-bottom:0}.editor .panel .wysiwyg_wrapper:after{clear:both;content:"";display:table}.editor .panel .wysiwyg_wrapper .with-title{display:block;float:left;padding:0;margin:1px 15px 0 0}.editor .panel .wysiwyg_wrapper .btn{float:left;width:32px;height:32px;line-height:32px;color:#6da3bd;text-align:center;vertical-align:middle;border-right:1px solid #dcdcdc}.editor .panel .wysiwyg_wrapper .btn:hover{color:#4d7285;background:#dcdcdc}.editor .panel .wysiwyg_wrapper .btn .g-icon{display:inline-block;vertical-align:middle}.editor .panel .wysiwyg_wrapper .btn.btn-dropdown{position:relative;overflow:hidden}.editor .panel .wysiwyg_wrapper .btn.btn-dropdown select{position:absolute;top:0;left:0;height:32px;font-size:14px;line-height:32px;border:0;-moz-opacity:0;-khtml-opacity:0;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";filter:alpha(opacity=0);-moz-appearance:none}.editor .panel .wysiwyg_wrapper .can_use_html{float:right;height:32px;padding:0 10px;font-size:10px;line-height:32px;color:#666;text-align:center;vertical-align:middle;border-left:1px solid #dcdcdc}.editor .panel .help_holder .close_html a,.editor .panel .wysiwyg_wrapper .can_use_html a{text-decoration:none;border-bottom:1px dashed}.editor .panel .wysiwyg_wrapper .help_holder{padding:10px;clear:both;border-top:1px solid #dcdcdc}.editor .panel .wysiwyg_wrapper .help_holder h4{margin-top:20px;margin-bottom:10px;font-size:12px;font-weight:700;color:#666}.editor .panel .wysiwyg_wrapper .help_holder h4:first-child{padding-top:10px;margin-top:0;clear:both;font-size:16px}.editor .panel .wysiwyg_wrapper .help_holder dl{margin-bottom:10px;font-size:11px}.autocomplete strong,.editor .panel .wysiwyg_wrapper .help_holder dl dt{font-weight:700;color:#000}.editor .panel .wysiwyg_wrapper .help_holder dl dd{color:#666}.editor .editor__footer{height:32px;padding-left:15px;line-height:32px;background-color:#f5f5f5;border:1px solid #e0e0e0;border-top:0}.editor .editor__footer .markdown_checkbox{display:inline-block;font-family:Arial,'Helvetica Neue',Helvetica,sans-serif;font-size:13px;font-weight:400;line-height:normal;color:#464646;vertical-align:baseline}.editor .editor__footer .markdown_checkbox input[type=checkbox]{margin:0 5px 0 0}.editor .text-holder{padding:0;background:#fff;border:1px solid #dcdcdc;box-sizing:border-box}.editor .text-holder textarea{width:100%;height:120px;padding:4px;margin:0;font-size:14px;vertical-align:top;border:0;outline:none;box-sizing:border-box}.editor .panel .help_holder .close_html{font-size:10px;text-align:right}.feedback_page .editor .text-holder textarea{resize:vertical}.img_uploader{width:300px;height:60px;padding:5px;overflow:hidden;text-align:center;border:1px solid #efefef}.img_uploader img{display:block;margin:0 auto 5px}.img_uploader a.upload_again{font-size:10px;line-height:20px;text-decoration:none;border-bottom:1px dashed}.upload_form{width:278px;height:40px;padding:10px;text-align:left;background:#fff;border:0 solid red}.upload_form .progress{height:5px;margin-top:5px;border:1px solid #eee}.upload_form .progress .bar{width:0%;height:5px;background:#aaa;background:url(https://habracdn.net/habr/images/1487064702/form/loader_button.gif) repeat-x 0 0}.upload_form .state{font-size:9px;color:#666}.preview_placeholder{padding:10px;margin-bottom:20px;font-size:12px;border:4px solid #eee}.buttons .description{padding-top:10px;clear:both;font-size:11px;color:#999}.buttons .text,.dropdown-menu li a img{display:inline-block;vertical-align:middle}.buttons .text{padding-top:1px;margin-left:10px;font-size:12px}.blue_buttons_panel{padding:20px;margin-bottom:15px;background:#e0edf8}.blue_buttons_panel input{margin-right:15px}.blue_buttons_panel input.big{margin-right:30px}.dropdown-menu{overflow:hidden;background-color:#f2f2f2;border-radius:4px;padding:0;margin:0;list-style:none}.dropdown-menu li{padding:5px;font-size:12px;text-align:left;border-top:1px solid #e5e5e5}.dropdown-menu li a{color:#000}.dropdown-menu li a img{width:20px;height:20px;border-radius:20px}.dropdown-menu li a span.name{display:inline-block;margin-left:5px;vertical-align:middle}.dropdown-menu li:first-child{border-top:none}.dropdown-menu .active,.dropdown-menu li:active,.dropdown-menu li:hover{background-color:#e5e5e5}.dropdown-menu a:hover{text-decoration:none;cursor:pointer}.autocomplete-w1{position:absolute;top:5px;left:0}.autocomplete{max-height:350px;overflow:auto;font-size:12px;text-align:left;cursor:default;background:#fff;border:1px solid #999}.autocomplete .selected{background:#f0f0f0}.autocomplete div{padding:2px 5px;overflow:hidden;color:#333;white-space:nowrap}.form{display:block;font-family:Arial,'Helvetica Neue',Helvetica,sans-serif}.form.hidden{display:none}.form_admin-causes{padding:20px 15px;border:1px solid #d5e7e4;position:relative;z-index:2;margin-top:-1px}.form__fieldset{margin:0;padding:0}.form__fieldset_admin-causes{margin-bottom:20px;border:0}.form__legend{display:block;font-weight:700;color:#484848;font-size:14px;margin:0;padding:0 0 16px}.form__label_datetime{font-size:0}.form__label_block{display:block;width:100%;line-height:28px}.form__label_block:hover .form__label-text{color:#4d80aa}.form__label-text{font-size:13px;color:#484848}.form__input:checked+.form__label-text{font-weight:700;color:#4d80aa}.form-control{font-size:14px} 2 | -------------------------------------------------------------------------------- /public/styles/posts.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8";@font-face{font-family:'hgm_icons';src:url(https://habracdn.net/habr/fonts/1487064702/icons/new/hgm_icons.eot);src:url(https://habracdn.net/habr/fonts/1487064702/icons/new/hgm_icons.eot#iefix) format("embedded-opentype"),url(https://habracdn.net/habr/fonts/1487064702/icons/new/hgm_icons.ttf) format("truetype"),url(https://habracdn.net/habr/fonts/1487064702/icons/new/hgm_icons.woff) format("woff"),url(https://habracdn.net/habr/fonts/1487064702/icons/new/hgm_icons.svg#hgm_icons) format("svg");font-weight:400;font-style:normal}.icon_cog:before,.icon_logo_freelansim:before,.icon_logo_mk:before,.icon_select_arrows:before{vertical-align:text-top}.icon_cog:before,.icon_logo_freelansim:before,.icon_logo_mk:before,.icon_select_arrows:before,.post__title .icon_check:before,.post__title .icon_edit:before,.post__title .icon_lock:before{font-family:'hgm_icons';speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;display:inline-block;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.icon_cog:after,.icon_select_arrows:after,.post .hubs:before,.title_anchor:before{vertical-align:text-top}.icon_cog:after,.icon_logo_freelansim:after,.icon_logo_mk:after,.icon_select_arrows:after,.post .hubs:after,.post .hubs:before,.post__title .icon_check:after,.post__title .icon_edit:after,.post__title .icon_lock:after,.title_anchor:after,.title_anchor:before{font-family:'hgm_icons';speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;display:inline-block;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.icon_logo_freelansim:after,.post .hubs:after,.post__title .icon_check:after,.post__title .icon_edit:after,.post__title .icon_lock:after,.title_anchor:after{vertical-align:text-top}.article__button-more{box-shadow:none;cursor:pointer;background-color:transparent}.article__button-more::-moz-focus-inner{padding:0;border:0}.article__button-more:focus,.article__button-more:hover{outline:0;box-shadow:none}.article__button-more:disabled{cursor:not-allowed}.icon_down:before{content:"\e602"}.icon_up:before{content:"\e60c"}.icon_eye:before{content:"\e603"}.icon_comment:before{content:"\e600"}.icon_fav:before{content:"\e909"}.icon_abuse:before{content:"\e606"}.icon_podcast:before{content:"\e608"}.icon_translate:before{content:"\e60a"}.icon_rss:before{content:"\e609"}.icon_pocket:before{content:"\e607"}.icon_twitter:before{content:"\e60b"}.icon_vk:before{content:"\e60e"}.icon_facebook:before{content:"\e604"}.icon_user:before{content:"\e60d"}.icon_comp:before{content:"\e901"}.icon_hub:before{content:"\e902"}.icon_cross:before{content:"\e601"}.icon_asterisk:before{content:"\e903"}.icon_mail:before{content:"\e900"}.icon_answers:before{content:"\e904"}.icon_lock:before{content:"\e905"}.icon_briefcase2:before,.post .hubs:before{content:"\e906"}.icon_edit:before{content:"\e907"}.icon_edit_msg:before{content:"\e90f"}.icon_check:before{content:"\e908"}.icon_hash:before{content:"\e90a"}.icon_edit_end:after{content:"\e913"}.icon_tree:before{content:"\e90b"}.icon_up_thin:before{content:"\2b06"}.icon_slug:before{content:"\e90d"}.icon_company_pic:before{content:"\e90e"}.icon_search:before{content:"\2b91"}.icon_share:before{content:"\e90c"}.icon_rating:before{content:"\e914"}.icon_cap:before{content:"\e916"}.icon_anchor-link:after,.title_anchor:after{content:"\e915"}.icon_select_arrows{position:absolute;right:10px;top:0;z-index:2;pointer-events:none}.icon_cog:before,.icon_select_arrows:before{content:"\e915";color:#aeaeae;font-size:13px;position:relative;top:2px}.icon_cog:before{font-size:18px;text-align:center;content:"\e910";top:-1px}.icon_cog.btn_outline_grey:hover:before,.open .icon_cog:before{color:#73abdf}.open .icon_cog{background-color:#fff}.icon_logo_mk:after{font-size:20px;content:"\e911";color:#666;position:relative;vertical-align:middle}.icon_logo_freelansim:after{font-size:20px;content:"\e912";color:#666;position:relative}.post_cp{margin-top:6px;margin-bottom:20px;padding:20px;background:#d3f2c0;color:#333;position:relative}.post_cp form{display:inline-block}.i-am-your-father-luke{display:block;clear:both;border:none;font:40px/110% Arial,sans-serif;color:#cc9;letter-spacing:-2px}.i-am-your-father-luke a{color:#cc9;border-bottom:2px solid #cc9;text-decoration:none;padding-bottom:2px}.i-am-your-father-luke a:visited{color:#cc9}.i-am-your-father-luke a:hover{color:#6da3bd;border-bottom:none;text-decoration:none}.ufo-was-here{margin-bottom:20px;font:16px/110% Verdana,sans-serif;color:#666}.posts .post{margin-bottom:40px}.posts .i-am-your-father-luke{margin:0 0 40px}.posts .ufo-was-here{margin-bottom:20px}.post_show{margin-top:5px}.post__time_published{display:inline-block;vertical-align:baseline;color:#7e7e7e;font-size:11px;margin-bottom:2px}.post__time_published_md:after{content:'MD';position:relative;padding:0 10px;background:#ff0;color:#000}.post__flow,.post__title,.post__title-arrow,.post__title_link{font-family:Arial,'Helvetica Neue',Helvetica,sans-serif;font-weight:700}.post__flow,.post__title,.post__title_link{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;line-height:34px;font-size:28px}.fonts-loaded .post__flow,.fonts-loaded .post__title,.fonts-loaded .post__title-arrow,.fonts-loaded .post__title_link{font-family:'Fira Sans',sans-serif;font-weight:500}.post__title-arrow{font-size:24px;line-height:1}.post__flow{color:#5d8fa8}.post__flow:visited{color:#5f9db5}.post__flow:hover{color:#47738d}.post__title,.post__title_link{color:#555}.post__title{padding:0;margin:0 0 5px}.post__title_link:hover,.post__title_link:visited{color:#888}.post__body{padding-bottom:20px}.post__body h1:hover .title_anchor,.post__body h2:hover .title_anchor,.post__body h3:hover .title_anchor,.post__body h4:hover .title_anchor,.post__body h5:hover .title_anchor,.post__body h6:hover .title_anchor{visibility:visible}.post__tags{font-family:Verdana,sans-serif;font-size:12px;padding:0;color:#000;margin-top:10px}.post__title .icon_lock:before{color:#6da3bd}.post__title .icon_check,.post__title .icon_edit{letter-spacing:normal}.post__title .icon_check:before,.post__title .icon_edit:before,.post__title .icon_lock:before{font-size:20px;vertical-align:baseline!important}.icon_check{margin-left:-4px}.icon_check:before{color:#76a758}.icon_delayed,.post .hubs a{display:inline-block;vertical-align:baseline;color:#89a16e}.icon_delayed .icon-svg{width:22px;height:20px;color:inherit}.post.special_post{border-left:4px solid #ffe237;padding:0 20px;margin-bottom:40px}.post.special_post .content>.habracut{padding-bottom:0}.post .searched-item{background:#fffacd;font-style:normal}.post .hubs,.post .published{color:#7e7e7e;font-size:11px;margin-bottom:2px}.post h1.title{margin-bottom:8px}.post h1.title a.blog_title.corporative{color:#8277a3}.post h1.title a.blog_title.corporative:hover{color:#aba4c2}.post h1.title a.post_title,.post ul.tags li a{color:#666}.post h1.title a.post_title:visited{color:#b5b5b5}.post h1.title a.post_title:hover,.post ul.tags li a:hover{color:#a3a3a3}.post div.habracut{padding-top:20px}.post .hubs{color:#999;margin-bottom:15px;position:relative;padding:0 0 0 20px}.post .hubs:before{color:#9bbcc6;font-size:15px;margin-right:5px;position:absolute;left:0;top:1px}.post .hubs.special_hubs{background:0 0;padding-left:0}.post .hubs a{color:#999;vertical-align:middle}.post .hubs a.subscribed{color:#6c9471}.post .hubs .profiled_hub{cursor:help}.post .content{font-size:14px;line-height:160%;font-family:Verdana,sans-serif;overflow:hidden}.post .content>.habracut{padding-top:20px;padding-bottom:10px}.post .content a:visited:not(.habracut){color:#909}.post .content img{max-width:100%}.post ul.tags{font-family:Verdana,sans-serif;font-size:10px;padding:2px 0}.post ul.tags.icon_tag:before{font-size:15px}.post ul.tags li{display:inline;color:#999}.post ul.tags li.fav a{color:#390}.post ul.tags li.fav a:hover{color:#85c266}.post ul.tags li.favourites_edit_tags{margin-left:10px}.post ul.tags li.favourites_edit_tags a{color:#ccc}.post ul.tags li.favourites_edit_tags a:hover{color:#666}.post .polling{margin:20px 0}.post .polling .poll{margin-bottom:20px}.post .polling .poll:last-child{margin-bottom:0}.post .poll .poll_title{font-size:14px}.post .poll table.answer{width:auto;border:0;margin:10px 0 17px}.post .poll table.answer tr,.post .poll table.result tr{border:0}.post .poll table.answer tr td{border:0;padding:8px 0;vertical-align:top}.post .poll table.answer tr td input[type=checkbox],.post .poll table.answer tr td input[type=radio]{margin:3px}.post .poll table.answer tr td.label{padding-left:5px;font-size:13px;line-height:15px}.post .poll table.result{width:100%;font-size:12px;border:0;margin:10px 0 0}.post .poll table.result tr td{border:0;padding:2px 0;vertical-align:baseline;line-height:normal}.post .poll table.result tr td.percent{width:1%;color:#ccc;text-align:right;word-wrap:normal;word-break:normal;padding-right:10px}.post .poll .poll_title,.post .poll table.result tr td strong{font-weight:700;color:#404040}.post .poll table.result tr td .bar{height:5px;margin-top:5px;background:#dadacd}.post .poll table.result tr td .bar.winner{background:#7fa0b0}.post .poll .total{color:#999;font-size:11px;padding-top:10px;font-style:italic}.abuse_wrapper,.post .abuse_form{display:inline-block;vertical-align:middle;position:relative}.abuse_wrapper{height:16px;margin-left:5px;width:16px}.post .abuse_form{width:90%;font-family:Arial,sans-serif;font-size:11px;border:1px solid #e5e5e5;padding:0}.habralenta_settings #show_habralenta_settings.hide,.post .abuse_form.hidden{display:none}.post .abuse_form .input{margin-right:100px}.post .abuse_form .input input.text{display:inline-block;vertical-align:top;font-size:14px;margin:0;width:100%;background:0 0;box-sizing:border-box;border:0 solid #d9d9d9;padding:0;color:#3b3b3b;line-height:29px;height:29px;text-indent:8px}.post .abuse_form .buttons{position:absolute;right:2px;top:2px;display:inline-block}.post div.tags{margin-bottom:15px;font-family:Verdana,sans-serif;font-size:12px;padding:2px 0;color:#000}#edit_tags_form{font-size:12px;padding:10px;border-radius:5px;background:#eee;margin-bottom:10px}#edit_tags_form label{display:block;margin-bottom:10px}#edit_tags_form input.tags_string{width:99%}#edit_tags_form .description{font-size:10px;color:#666;margin-top:5px;margin-bottom:10px}#edit_tags_form a.close{text-decoration:none;color:green;border-bottom:1px dashed}.post_inner_banner{margin-top:40px;position:relative}.post_inner_banner a,.post_inner_banner a:hover{text-decoration:none}.post_inner_banner .left,.post_inner_banner .right{width:50%;text-align:center;vertical-align:middle;line-height:68px}.post_inner_banner .left{float:left;border-left:1px solid #e7e7e7;-webkit-border-top-left-radius:15px;-webkit-border-bottom-left-radius:15px;-moz-border-radius-topleft:15px;-moz-border-radius-bottomleft:15px;border-top-left-radius:15px;border-bottom-left-radius:15px;height:68px;border-top:1px solid #e7e7e7;border-bottom:1px solid #e7e7e7}.post_inner_banner .left .text,.post_inner_banner .right .text{display:inline-block;height:45px;font-size:14px;line-height:20px;border:0 solid red;text-align:left;vertical-align:middle}.post_inner_banner .left .text{background:url(https://habracdn.net/habr/images/1487064702/posts/inner_post_banner/hp/hp.png) no-repeat left center;padding-left:60px;color:#333}.post_inner_banner .right{position:absolute;right:0;top:0;bottom:0;border-right:1px solid #7fcaea;border-top:1px solid #7fcaea;border-bottom:1px solid #7fcaea;-webkit-border-top-right-radius:15px;-webkit-border-bottom-right-radius:15px;-moz-border-radius-topright:15px;-moz-border-radius-bottomright:15px;border-top-right-radius:15px;border-bottom-right-radius:15px;background:url(https://habracdn.net/habr/images/1487064702/posts/inner_post_banner/hp/arrow.png) no-repeat left center}.post_inner_banner .right .text{background:url(https://habracdn.net/habr/images/1487064702/posts/inner_post_banner/hp/icon.png) no-repeat left center;padding-left:43px;color:#0096d6}.habralenta_settings{margin-top:5px}.habralenta_settings p{font-size:13px;color:#666;font-weight:700;margin-bottom:15px}.habralenta_settings .category-list{margin-bottom:20px}.habralenta_settings .category-list .category,.habralenta_settings .category-list .category_all{font-size:133%;overflow:hidden;margin-bottom:10px;position:relative}.habralenta_settings .category-list .category_all .checkbox{position:absolute;top:0;left:0;cursor:pointer;width:14px;height:14px;margin-top:.2em;background:url(https://habracdn.net/habr/images/1487064702/form/checkbox.png) no-repeat -25px 0}.habralenta_settings .category-list .category .hubs .hub.subscription .checkbox,.habralenta_settings .category-list .category.full .checkbox,.habralenta_settings .category-list .category_all.selected .checkbox{background:url(https://habracdn.net/habr/images/1487064702/form/checkbox.png) no-repeat 0 0}.habralenta_settings .category-list .category_all .title{margin-left:24px;cursor:pointer;border-bottom:1px dashed;color:green}.habralenta_settings .category-list .category_all .lenta-tip{color:#666;cursor:help}.habralenta_settings .category-list .category:last-child{margin-bottom:0}.habralenta_settings .category-list .category .checkbox{float:left;position:absolute;top:0;left:0;cursor:pointer;width:14px;height:14px;margin-top:.2em;background:url(https://habracdn.net/habr/images/1487064702/form/checkbox.png) no-repeat -25px 0}.habralenta_settings .category-list .category.part .checkbox{background:url(https://habracdn.net/habr/images/1487064702/form/checkbox.png) no-repeat -50px 0}.habralenta_settings .category-list .category.disabled .checkbox,.habralenta_settings .category-list .category.disabled .hubs .hub .checkbox{cursor:default;background:url(https://habracdn.net/habr/images/1487064702/form/checkbox.png) no-repeat -25px -75px}.habralenta_settings .category-list .category.disabled .hubs .hub.subscription .checkbox,.habralenta_settings .category-list .category.disabled.full .checkbox{background:url(https://habracdn.net/habr/images/1487064702/form/checkbox.png) no-repeat 0 -75px}.habralenta_settings .category-list .category.disabled.part .checkbox{background:url(https://habracdn.net/habr/images/1487064702/form/checkbox.png) no-repeat -50px -75px}.habralenta_settings .category-list .category.disabled .count,.habralenta_settings .category-list .category.disabled .title{color:#aaa}.habralenta_settings .category-list .category.disabled .title a,.habralenta_settings .category-list .category.disabled .title a:hover{color:#aaa;border-bottom:1px dashed #aaa;cursor:default}.habralenta_settings .category-list .category .title{float:left;display:block;margin-left:24px;margin-bottom:1px;color:#aaa}.habralenta_settings .category-list .category .title a,.habralenta_settings a#hide_habralenta_settings,.habralenta_settings a#show_habralenta_settings{text-decoration:none;border-bottom:1px dashed #6da3bd}.habralenta_settings .category-list .category .title a:hover,.habralenta_settings a:hover#hide_habralenta_settings,.habralenta_settings a:hover#show_habralenta_settings{border-bottom:1px dashed #4d7285}.habralenta_settings .category-list .category .count{color:#999}.habralenta_settings .category-list .category .new{color:green;font-size:11px;vertical-align:top}.habralenta_settings .category-list .category .hubs{clear:both;padding-left:22px;display:none;padding-top:.8em}.habralenta_settings .category-list .category .hubs.show{display:block}.habralenta_settings .category-list .category .hubs .hub{font-size:85%;overflow:hidden;margin-bottom:.6em;position:relative}.habralenta_settings .category-list .category .hubs .hub:last-child{margin-bottom:0}.habralenta_settings .category-list .category .hubs .hub .checkbox{float:left;position:absolute;top:0;left:0;cursor:pointer;width:14px;height:14px;margin-top:.1em;background:url(https://habracdn.net/habr/images/1487064702/form/checkbox.png) no-repeat -25px 0}.habralenta_settings .category-list .category.disabled .hubs .hub a{color:#aaa;cursor:default}.habralenta_settings .category-list .category .hubs .hub a{float:left;display:block;margin-left:24px}.habralenta_settings .category-list .category .hubs .hub .new{color:green;font-size:11px;vertical-align:top;float:left;display:block;margin-left:4px}.habralenta_settings .category-list .category .hubs .description{font-size:85%;color:#999;margin-bottom:.6em}.habralenta_settings img.ajax_loader{display:inline;margin-left:5px;vertical-align:top}.habralenta_settings .category-list img.ajax_loader{margin-top:3px;vertical-align:top}.habralenta_settings #save_success{color:green;display:none;margin-left:10px}.habralenta_settings #save_success.show{display:inline}.habralenta_settings #form_habralenta_settings .btn,.habralenta_settings .or{margin-right:5px}.habralenta_settings #form_habralenta_settings .btn.loading{background:url(https://habracdn.net/habr/images/1487064702/form/loader_button.gif)}.habralenta_settings hr.mail-stripe{height:2px;width:300px;margin-left:-20px;border:none;background:url(https://habracdn.net/habr/images/1487064702/mail-stripe.png)}#lenta_notifications .inner_notice{margin-bottom:20px;padding:20px;background:#d3f2c0;color:#333;position:relative}#lenta_notifications a.close{position:absolute;right:10px;top:5px;text-align:right;text-decoration:none;border-bottom:1px dashed;font-size:10px}.post-additionals+div{margin-top:15px}.block_after_post{margin-top:20px}section.post-footer{padding:10px 0 20px!important}.reject_form{margin:20px 0;padding:20px;border:1px solid red;max-width:600px}.article__body{padding:30px;border-left:1px solid #ebeaea;border-right:1px solid #ebeaea;box-sizing:border-box}.article__body-text{color:#353535;font-size:14px;line-height:24px;font-weight:400;margin-bottom:25px}.article__button-more{border:2px solid #606f8c;font-size:14px;font-weight:700;height:45px;line-height:41px;padding:0 20px;display:inline-block;vertical-align:top;color:#606f8c;box-sizing:border-box;border-radius:4px}.article__button-more:hover{text-decoration:none;color:#fff;background-color:#606f8c;-webkit-transition:all .1s ease-in;transition:all .1s ease-in}.article__button-more_habr{border-color:#99c2cd;color:#99c2cd}.article__button-more_habr:hover{background-color:#99c2cd}.article__button-more_gt{border-color:#8293b6;color:#8293b6}.article__button-more_gt:hover{background-color:#8293b6}.article__button-more_mm{border-color:#7eb9df;color:#8293b6}.article__button-more_mm:hover{background-color:#7eb9df}.title_anchor{position:relative;visibility:hidden}.title_anchor:after{position:relative;top:2px;color:#b5b5b5;margin-left:7px;-webkit-transform:rotate(45deg);transform:rotate(45deg)}.list{margin:0;padding:0;list-style:none}.list__item,.list__item-link{color:#fff;font-size:14px}.article__tags .list__item,.article__tags .list__item-link{color:#87878d;font-size:13px}.megapost-cover_light .list__item,.megapost-cover_light .list__item-link{color:#fff}.megapost-cover_dark .list__item,.megapost-cover_dark .list__item-link{color:#000}.list__item-link{text-decoration:underline}.list__item-link.link_dotted{text-decoration:none;border-bottom:1px dotted}.article__tags .list__item-link:hover{color:#87878d}.list__item-link:hover,.megapost-cover_light .list__item-link:hover{color:rgba(255,255,255,.8)}.megapost-cover_dark .list__item-link:hover{color:rgba(0,0,0,.8)}.list_inline .list__item{display:inline-block;vertical-align:middle}.megapost-head__meta .list__item{margin-right:30px}.megapost-head__meta .list__item:last-child{margin:0}.article__tags .list__item,.megapost-head__hubs .list__item{white-space:nowrap;line-height:1.5em}.article__tags .list__item:after,.megapost-head__hubs .list__item:after{content:',\00a0'}.article__tags .list__item:last-child:after,.megapost-head__hubs .list__item:last-child:after{content:''}.megapost-cover__img{height:600px;background-repeat:none;background-position:center;background-size:cover;background-color:#ccc}.megapost-cover_short .megapost-cover__img{height:500px}.megapost-cover__img_darken{position:relative}.megapost-cover__img_darken:before{content:'';position:absolute;top:0;bottom:0;left:0;right:0;background-color:rgba(0,0,0,.55);z-index:0}.megapost-cover__company-blog{position:absolute;top:0;left:auto;width:100%}.megapost-cover_short .megapost-cover__company-blog{top:30px;left:0}.megapost-cover__grid-link{position:absolute;right:0;top:0;height:40px;line-height:40px;white-space:nowrap;padding:0 30px;box-sizing:border-box}.megapost-cover__inner{position:relative;z-index:2;height:100%}.megapost-cover_short .megapost-cover__inner{padding:30px;box-sizing:border-box}.megapost-head{position:relative;top:50%;-webkit-transform:translateY(-50%);transform:translateY(-50%)}.megapost-head__blog-link{color:#fff;font-size:12px;font-weight:700;text-transform:uppercase;white-space:nowrap;padding:0;display:inline-block;vertical-align:top;box-sizing:border-box;margin-bottom:10px}.megapost-cover_light .icon_briefcase:before,.megapost-cover_light .megapost-head__title,.megapost-cover_light .megapost-head__title-link,.megapost-cover_light .megapost-head__title-link:hover,.megapost-head__blog-link:hover{color:#fff}.megapost-head__title,.megapost-head__title-link{font-size:34px;font-weight:700;color:#fff;line-height:1.5em;text-indent:-3px}.megapost-cover_dark .icon_briefcase:before,.megapost-cover_dark .megapost-head__title,.megapost-cover_dark .megapost-head__title-link,.megapost-cover_dark .megapost-head__title-link:hover{color:#000}.megapost-head__title-link:hover{color:#fff;text-decoration:none}.megapost-head__title{margin:0 0 18px;max-width:580px;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility}.megapost-head__title .searched-item{color:#353535}.megapost-head__meta{position:absolute;bottom:0;left:auto;margin-bottom:30px}@font-face{font-family:'icons_megapost';src:url(https://habracdn.net/habr/fonts/1487064702/megapost_icons/icons.eot);src:url(https://habracdn.net/habr/fonts/1487064702/megapost_icons/icons.eot#iefix) format("embedded-opentype"),url(https://habracdn.net/habr/fonts/1487064702/megapost_icons/icons.ttf) format("truetype"),url(https://habracdn.net/habr/fonts/1487064702/megapost_icons/icons.woff) format("woff"),url(https://habracdn.net/habr/fonts/1487064702/megapost_icons/icons.svg#icons) format("svg");font-weight:400;font-style:normal}@font-face{font-family:"gt-icons";src:url(https://habracdn.net/habr/fonts/1487064702/gt-icons/gt-icons.eot);src:url(https://habracdn.net/habr/fonts/1487064702/gt-icons/gt-icons.eot#iefix) format("embedded-opentype"),url(https://habracdn.net/habr/fonts/1487064702/gt-icons/gt-icons.woff) format("woff"),url(https://habracdn.net/habr/fonts/1487064702/gt-icons/gt-icons.ttf) format("truetype"),url(https://habracdn.net/habr/fonts/1487064702/gt-icons/gt-icons.svg#gt-icons) format("svg");font-weight:400;font-style:normal}.icon,.icon_briefcase:before,.icon_tag:before{font-family:"icons_megapost";speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;display:inline-block;vertical-align:text-top}.icon_briefcase{position:relative;padding-left:25px;box-sizing:border-box}.icon_briefcase:before{content:"\e801";font-size:17px;color:#fff;margin-right:5px;position:absolute;left:0;top:2px}.icon_tag:before{content:"\e800";font-size:17px;color:#bac8cc;margin-right:5px}.g-icon{font-family:"gt-icons";speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.g-icon-bold:before{content:"\e613"}.g-icon-italic:before{content:"\e614"}.g-icon-underline:before{content:"\e615"}.g-icon-strike:before{content:"\e616"}.g-icon-users:before{content:"\e617"}.g-icon-cut:before{content:"\e618"}.g-icon-paragraph:before{content:"\e619"}.g-icon-video:before{content:"\e61a"}.g-icon-images:before{content:"\e61b"}.g-icon-quote:before{content:"\e61c"}.g-icon-link:before{content:"\e61d"}.g-icon-more:before{content:"\e621"}.g-icon-list:before{content:"\e60e"}.g-icon-code:before{content:"\e61e"}.g-icon-spoiler:before{content:"\e620"} 2 | -------------------------------------------------------------------------------- /src/components/App.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import { Link } from 'react-router' 3 | import Helmet from 'react-helmet' 4 | 5 | import { ga } from '../utils' 6 | 7 | import MainNavBar from './MainNavBar' 8 | import UserMenu from './UserMenu' 9 | import DefaultPageHeader from './DefaultPageHeader' 10 | 11 | class App extends Component { 12 | componentDidUpdate() { 13 | // ReactDOM.findDOMNode(this).scrollIntoView() 14 | // window.scrollTo(0, 0) 15 | } 16 | 17 | componentWillMount() { 18 | document.body.style.display = 'none' 19 | } 20 | 21 | componentDidMount() { 22 | // HACK стили подключаются в Helmet после рендеринга страницы 23 | setTimeout(() => (document.body.style.display = 'block'), 100) 24 | } 25 | 26 | render() { 27 | const title = this.props.children.props.route.title 28 | return ( 29 |
30 | 31 |
32 | 33 |
34 |
35 |
36 | {/* TODO на некоторых страницах замечено добавление css-класса js-sticky-wrapper */} 37 | {/* убрал css-класс column-wrapper_content - нигде не используется */} 38 |
39 | {/* TODO на некоторых страницах замечено добавление css-класса js-content_left */} 40 | {!!title && } 41 | {this.props.children} 42 |
43 |
44 |
45 |
46 |
47 |
48 | 187 |
188 |
189 | 196 | 207 | 208 |
209 | ) 210 | } 211 | } 212 | 213 | export default App 214 | -------------------------------------------------------------------------------- /src/components/AuthorInfo.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Link } from 'react-router' 3 | 4 | import { ga, plural } from '../utils' 5 | 6 | const AuthorInfo = ({ author: { id , nick, name, avatar, specialization, contacts, votingCounter, karma, rating } }) => { 7 | 8 | const karmaVote = () => { 9 | // TODO реализовать userKarmaVote 10 | alert('голосование за карму') 11 | } 12 | 13 | const karmaVotePlus = (event) => { 14 | karmaVote(event, id, 1, 1) 15 | ga('author_info_bottom', 'vote_plus', nick) 16 | } 17 | 18 | const karmaVoteMinus = (event) => { 19 | karmaVote(event, id, 1, -1) 20 | ga('author_info_bottom', 'vote_minus', nick) 21 | } 22 | 23 | return ( 24 |
25 | 26 | {name} 27 | 28 |
{/* убрал css-класс js-user_${id} */} 29 |
30 | {name} 31 |   32 | {`@${nick}`} 33 |
34 | 37 |
38 |
карма
39 |
{karma.toFixed(1)}
40 |
41 | 44 |
45 |
46 | рейтинг 47 | {rating.toFixed(1)} 48 |
49 |
50 | Написать 51 |
52 |
53 | { !!specialization &&
{specialization}
} 54 | { !!contacts && contacts.length > 0 && 55 |
    56 | { contacts.map(contact =>
  • {contact.type}
  • ) } 57 |
58 | } 59 |
60 |
61 | ) 62 | } 63 | 64 | export default AuthorInfo 65 | -------------------------------------------------------------------------------- /src/components/AuthorInfoByCompany.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Link } from 'react-router' 3 | 4 | const AuthorInfoByCompany = ({ company: { id, nick, name, avatar, specialization, contacts, rating }}) => ( 5 |
6 | 7 | {name} 8 | 9 |
10 |
11 | {name} 12 |
13 | рейтинг 14 | {rating} 15 |
16 |
17 | 18 | 19 |
20 |
21 | { !!specialization &&
{specialization}
} 22 | { !!contacts && contacts.length > 0 && 23 |
    24 | { contacts.map(contact =>
  • {contact.type}
  • ) } 25 |
26 | } 27 |
28 |
29 | ) 30 | 31 | export default AuthorInfoByCompany 32 | -------------------------------------------------------------------------------- /src/components/DefaultPageHeader.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | const DefaultPageHeader = ({ title }) => ( 4 |
5 |

{title}

6 |
7 | ) 8 | 9 | export default DefaultPageHeader 10 | -------------------------------------------------------------------------------- /src/components/Feedback.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | const Feedback = () => ( 4 |
Feedback
5 | ) 6 | 7 | export default Feedback 8 | -------------------------------------------------------------------------------- /src/components/FormAdminCauses.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | const FormAdminCauses = ({ userNick, postId }) => ( 4 |
5 | 6 |
7 | Выберите рекомендации для отправки автору: 8 | 12 | 16 | 20 | 24 | 28 | 32 | 36 | 40 | 44 | 48 |
49 | 50 |
51 | ) 52 | 53 | export default FormAdminCauses 54 | -------------------------------------------------------------------------------- /src/components/InfoAbout.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Link } from 'react-router' 3 | 4 | export default () => ( 5 |
6 |

Добро пожаловать на Хабрахабр, крупнейший в Европе ресурс для IT-специалистов, созданный компанией «ТМ» в 2006-м 7 | году. Со временем «Хабр» вырос из небольшого отраслевого сайта в глобальную профессиональную площадку, которую в месяц посещают более 10 миллионов пользователей.

8 |

«Хабрахабр» одинаково интересен программистам и разработчикам, администраторам и тестировщикам, дизайнерам и верстальщикам, аналитикам и копирайтерам, а также 9 | всем тем, для кого IT — это не просто две буквы алфавита.

10 |

Расширение тематики «Хабра» дало начало сайту-спутнику — Geektimes, на который переехали непрофильные хабы 11 | и значительная часть контента, не имеющего непосредственного отношения к разработке и программированию.

12 |

Благодарности

13 |
    14 |
  • Спасибо Юрию Баландину, Сергею Коровкину и Павлу Батурину за участие;
  • 15 |
  • Спасибо Turbomilk за иконки;
  • 16 |
  • Спасибо Qrator за защиту от DDoS-атак;
  • 17 |
  • Спасибо CleverPumpkin за удобные мобильные приложения для наших проектов;
  • 18 |
  • Спасибо АйТи-Лекс за юридическое сопровождение.
  • 19 |
  • И нам тоже, конечно же, спасибо. За то, что смогли всё это сделать.
  • 20 |
21 |

Обратная связь

22 |

У меня есть вопрос по сайту

23 |

Прежде чем задать вопрос, попробуйте посетить справочный раздел — в нём опубликованы ответы на большинство часто 24 | задаваемых вопросов.

25 |

У меня проблемы. Что делать?

26 |

Мы не сможем решить всех проблем, но если на «Хабре» что-то работает не так, мы стараемся реагировать оперативно — исправляем, дополняем, объясняем. Если вы нашли 27 | ошибку, напишите в нашу службу поддержки.

28 |

У меня есть идея. Как поделиться?

29 |

Если вы знаете, как сделать «Хабр» лучше, напишите в службу поддержки.

30 |
31 | ) 32 | -------------------------------------------------------------------------------- /src/components/InfoHelp.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Link } from 'react-router' 3 | 4 | export default () => ( 5 |
6 |
    7 |
  • Правила
  • 8 |
  • Регистрация и приглашения
  • 9 |
  • Хабрацентр
  • 10 |
  • Карма и рейтинг
  • 11 |
  • Настройки
  • 12 |
  • Хабы
  • 13 |
  • Лента
  • 14 |
  • Публикации
  • 15 |
  • Трекер
  • 16 |
  • Хабрапочта
  • 17 |
  • Компании
  • 18 |
  • Разное
  • 19 |
20 |
21 | ) 22 | -------------------------------------------------------------------------------- /src/components/InfoHelpHabracentre.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Link } from 'react-router' 3 | // TODO React ругается на аттрибуты таблицы: colspan, border, align, valign 4 | export default () => ( 5 |
6 |

Это страница вида habrahabr.ru/users/имя_пользователя, которая содержит:

7 | 8 |
    9 |
  • Аватар пользователя, его никнейм и (если указано) настоящее имя.
  • 10 |
  • Значения кармы и рейтинга, а также занимаемое на текущий момент место в рейтинге.
  • 11 |
  • Значки пользователя, которые он заработал благодаря своей активности на ресурсе.
  • 12 |
  • Ссылки на социальные аккаунты, мессенджеры, личные сайты.
  • 13 |
  • Даты регистрации на ресурсе, получения приглашения и последнего посещения сайта.
  • 14 |
  • Список хабов, на которые подписан пользователь.
  • 15 |
  • Иная информация «О себе», которую он пожелал указать.
  • 16 |
17 | 18 |

Ряд информации из профиля выводится на специально созданной плашке автора, которая отображается под каждой публикацией пользователя. Чтобы выбрать, что именно отображать в своей плашке, нужно отметить соответствующие контакты чекбоксом на странице настроек профиля.

19 | 20 |

Как изменить информацию о себе?

21 | 22 |

Очень просто. Авторизируйтесь — ссылка на страницу настроек будет видна в левом меню.

23 | 24 |

Что такое значки?

25 | 26 |

За время своего пребывания пользователи зарабатывают различные значки, которые потом отображаются в хабрацентре. Значки зависят от поведения пользователя, отношения к нему сообщества и его активности на сайте.

27 | 28 |

Некоторые значки являются артефактами и дают своим владельцам дополнительные возможности:

29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 |
ЗахабренныйПользователь с положительной кармой (больше 0). В зависимости от величины кармы может размещать публикации в различные хабы, писать комментарии и голосовать. Может использовать в комментариях HTML-теги.
ОтхабренныйПользователь с отрицательной кармой (меньше 0). В зависимости от «глубины погружения» начинает испытывать трудности с комментированием. Более того, не может размещать публикации, голосовать и использовать HTML-теги в комментариях.
КомментаторПользователь, на счету которого имеется более 5 очень полезных или удачных комментариев (с рейтингом более +50 каждый).
ПереводчикПользователь, на счету которого имеется более 5 публикаций-переводов (с рейтингом более +50 каждый). По праву гордится своим значком.
СтарожилПользователь, зарегистрированный более 3 лет назад и имеющий карму +50 и выше. Может участвовать в ППА. Вес положительного голоса за публикацию равен +2.
АвторПользователь, на счету которого от 10 публикаций, тепло встреченных хабрасообществом (от +50 голосов за каждый). Имеет карму +50 и выше, может участвовать в ППА и получает ещё одно особо секретное преимущество. Вес положительного голоса за публикацию равен +2.
ЗвездаКарандашик подлиннее выдаётся за карму от +50 и 20+ публикаций с рейтингом от +50 баллов каждый. Может всё то же самое, что и «Автор». Вес положительного голоса за публикацию равен +2.
ЛегендаУсовершенствованная версия «Звезды». Самый длинный карандаш, даётся за карму от +50 при 30+ публикациях с рейтингом от +50 каждый. Может всё то же самое, что и «Автор». Вес положительного голоса за публикацию равен +3.
Значки «Автор», «Звезда» и «Легенда» поглощают друг друга в процессе самосовершенствования Автора.
ТролльС таким значком на сайте особо нечего делать — он даётся за падение на дно кармической бездны (-100 и ниже). Один шанс стать белым и пушистым всё же есть, но если им вовремя не воспользоваться, то аккаунт может быть заблокирован НЛО без каких-либо уведомлений. Троллем быть фуфуфу, заметите их — не кормите.

71 |
72 | ) 73 | -------------------------------------------------------------------------------- /src/components/InfoHelpHubs.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Link } from 'react-router' 3 | 4 | export default () => ( 5 |
6 | 7 |

Это разделы, в которых размещены публикации на определённую тематику. Помогают не только удобно структурировать всю информацию на сайте, но и формировать ленту пользователя — подписываться только на те хабы, которые интересны.

8 | 9 |

Как подписаться на хаб

10 | 11 |

Подписаться на хаб (добавить его в свою ленту) можно в центре подписки или на странице со списком всех хабов, нажав на кнопку «Подписаться», которая появляется при наведении на его название. Или же с помощью кнопки «Присоединиться», которая есть в правой верхней части страницы каждого хаба.

12 | 13 |

Кстати, при успешной подписке эта кнопка сменится на «Покинуть» — так можно отписаться от хаба.

14 | 15 |

Есть два основных вида хабов.

16 | 17 |
    18 |
  • 19 | Тематические.

    Их тематика наиболее тесно связана с IT. Самые полезные хабы, поэтому их больше всего. Полезны не только читателям в силу своей интересности, но и авторам публикаций — именно написанные в эти хабы публикации могут принести автору добавочное приглашение, поднять рейтинг, а также поправить материальное положение благодаря Программе Поощрения Авторов (ППА).

    20 | 21 |

    Подразделяются на:

    22 |
      23 |
    • профильные. Непосредственно связаны с IT. Порог минимальной кармы для создания публикации — от 0 и выше. Хабы отмечены иконкой шестерёнки в общем списке хабов и звездочкой в ниспадающем меню выбора хаба при создании публикации. К участию в ППА принимаются публикации только из этих хабов.
    • 24 |
    • непрофильные. Не так тесно связаны с IT, поэтому не участвуют в ППА, а минимальный порог кармы — от +5 и выше.
    • 25 |
    26 |
  • 27 | 28 |
  • 29 | Оффтопики.

    Связь с тематикой сайта — на грани, но всё же есть. Минимальный порог кармы — от +5 и выше, в случае с хабом «Я пиарюсь» — от +20 и выше.

    30 | 31 |

    В связи с этим у данных хабов есть ряд особенностей:

    32 |
      33 |
    • не приносят автору приглашений, рейтинга, не участвуют в ППА;
    • 34 |
    • не индексируются поисковиками.
    • 35 |
    • не попадают в раздел «Лучшее»;
    • 36 |
    • не транслируются в наши сообщества в социальных сетях.
    • 37 |
    38 |
  • 39 |
40 | 41 |

Из чего состоят хабы?

42 | 43 |

В каждом тематическом хабе есть подразделы (в виде вкладок) для фильтрации контента:

44 |
    45 |
  • Интересное. Записи, получившие положительную оценку (рейтинг ≥-4) пользователей. Хорошенькое и интересненькое.
  • 46 |
  • Всё подряд. Все записи хаба (в хронологическом порядке).
  • 47 |
  • Лучшее. Лучшие публикации хаба (с рейтингом > 50).
  • 48 |
49 | 50 |

Невероятно, но факт: у каждого подраздела каждого раздела каждого хаба есть свой отдельный RSS-фид!

51 | 52 |

Как создать новый хаб?

53 | 54 |

Если вы считаете, что на сайте не хватает какого-то хаба, то предложите его через форму обратной связи. В сопроводительном письме укажите не менее 10 ссылок на публикации, которые на данный момент расположены «не там».

55 |

Как узнать о появлении нового хаба? Через центр подписки на главной странице.

56 | 57 |

Кстати, а кто такие лидеры хаба?

58 | 59 |

В правой части каждого тематического хаба есть специальный блок, в котором выводится список из 10 пользователей. Как несложно догадаться, это те пользователи, которые внесли в развитие хаба наибольший вклад в виде публикаций. Эти пользователи — большие молодцы.

60 |
61 | ) 62 | -------------------------------------------------------------------------------- /src/components/InfoHelpKarma.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Link } from 'react-router' 3 | // TODO React ругается на аттрибуты таблицы: bgcolor 4 | 5 | export default () => ( 6 |
7 |

Что такое карма?

8 | 9 |

Карма — это один из механизмов ресурса, позволяющий наделять пользователей правами (или ограничивать их). Чем больше ваша карма — тем больше у вас прав (голосование за комментарии, публикации и карму других пользователей, возможность писать в хаб «Я пиарюсь», и не только), чем меньше карма — тем сильнее на вашем аккаунте будут сказываться некоторые ограничения (невозможность голосовать, писать публикации и комментарии). Подробную зависимость прав аккаунта от значений кармы можно увидеть в таблице ниже.

10 | 11 |

Помните главное: карма — это субъективное отношение каждого, кто за нее проголосовал, к вашему аккаунту. Оно никак не связано с оценкой ваших комментариев или публикаций (их могут оценивать положительно, при этом карму — отрицательно).

12 | 13 |

Положительная карма

14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 |
КармаДействие
≥ 0Создавать публикации в профильные хабы (только для полноценных аккаунтов)
≥ 5Создавать публикации в тематические хабы и голосовать за публикации, комментарии, а также за карму других пользователей
≥ 20Доступна возможность публиковать публикации в «Я пиарюсь»
> 50Начисление одного приглашения (единовременно)

37 | 38 |

Отрицательная карма

39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 |
КармаДействие
От −1 до −10Можно комментировать лишь 1 раз в 5 минут
От −11 до −301 комментарий в час
От −31 до −1001 комментарий в день
От −100 и ниже1 комментарий в неделю и значок «Тролль»

62 | 63 |

От величины кармы напрямую зависит количество ваших голосов за карму, публикации и комментарии других участников сообщества.

64 |

1 единица кармы = 1 голос, который вы можете отдать за карму или публикацию пользователя, и 2 голоса за комментарии.
65 | К примеру, вы не нарушали правила и были интересным автором либо комментатором, что позволило набрать вам +200 единиц кармы (200 человек с кармой ≥5 зашли в ваш профиль и повысили её).

66 | 67 |

Значит, в сутки у вас будет 200 голосов за карму, публикации и 400 голосов за комментарии. Если вы потратите весь заряд за одни сутки, то через 24 часа он восстановится.

68 |

Для некоторых пользователей существуют особые правила — вес их голоса при оценке публикаций отличается от веса голоса остальных членов сообщества. 69 |
70 | Обладатели значков «Автор», «Старожил», «Звезда» в случае положительной оценки публикации добавляют ей +2 пункта рейтинга. 71 |
72 | Обладатели же значка «Легенда» одним голосом добавляют +3 пункта рейтинга. 73 |
74 | Данное правило распространяется только на голосование за публикации и не распространяется на голосование в минус: такой голос за публикацию отнимает −1 пункт рейтинга.

75 |

Помните, что даже написав сотню самых полезных публикаций и искромётных комментариев, набрав +300 кармы, к примеру, вы можете потерять всё это с помощью одного глупого комментария не по теме или ещё какой гадости. Поэтому берегите себя и свою карму.

76 | 77 |

Что такое рейтинг?

78 | 79 |

Еще один параметр, определяющий вес пользователя на ресурсе.

80 | 81 |

Чем больше рейтинг участника, тем выше он находится в общем списке пользователей.

82 | 83 |

Рейтинг - это динамичный показатель, зависящий от активности пользователя на сайте: все плюсы и минусы к публикациям и комментариям прямым образом влияют на величину рейтинга (но не влияют на карму, как отмечалось выше). Если кто-то положительно оценивает ваши публикации и комментарии, то рейтинг будет расти (справедливо и обратное), но если бездействовать, то со временем рейтинг примет нулевое значение.

84 | 85 |

Впрочем, даже если проявлять активность, рейтинг всё равно будет падать: за былые заслуги. Иногда он начинает жить своей жизнью, и это нормально.

86 | 87 |

Наглядный пример. Допустим, вы написали публикацию с рейтингом +100 — это добавило к вашему персональному рейтингу величину Х. Через несколько десятков дней этот самый Х вычтется, тем самым вернув вас на прежнее место.

88 | 89 |

Это явление называется пессимизацией рейтинга и создано для того, чтобы общий рейтинг пользователей был максимально объективным — возглавить его может даже только что пришедший новичок. Вывод простой: чтобы удерживать позицию лидера, нужно постоянно публиковать интересные статьи (которые будут набирать высокий рейтинг).

90 | 91 |

Голосование

92 | 93 |

Выше приведён перечень возможностей в зависимости от кармы — если она у вас будет положительная, то вы сможете голосовать (как когда-то кто-то голосовал за вас). Технически всё просто — в футере каждой публикации есть стрелочки «Вверх» и «Вниз», повышающие и понижающие рейтинг публикации на 1 единицу. У комментариев и ответов стрелки голосования находятся в правой части. Везде можно проголосовать лишь однажды, изменив рейтинг лишь на 1 единицу.

94 | 95 |

Для голосования за карму пользователя нужно либо пройти в его профиль, либо проголосовать со страницы публикации пользователя (показатели пользователя размещены в шапке его публикаций), либо при наведении на никнейм пользователя в комментариях, с помощью всплывающей плашки автора.

96 | 97 |

Стрелки изменения кармы находятся по обе стороны от числа, показывающего нынешний уровень кармы. Карму каждого пользователя можно также изменять лишь на 1 единицу («Вверх» или «Вниз»), но сам полюс оценки можно со временем поменять. То есть, однажды повысив карму кому-то из пользователей, вы сможете потом изменить её на противоположную (если вдруг появится такая необходимость). Само собой, голосовать за свою карму нельзя.

98 | 99 |

Как восстановить аккаунт?

100 | 101 |

Если так получилось, что ваша карма стала отрицательной и вам хотелось бы это исправить — такая возможность есть.

102 | 103 |

Как известно, бороться надо с причиной, а не со следствием. Скорее всего, отрицательная карма является следствием некорректного поведения на сайте, так что комплексный анализ ошибок позволит не наступать на одни и те же грабли в дальнейшем.

104 | 105 |

Ну а потом есть несколько вариантов:

106 | 107 |
    108 |
  • Recovery mode. У пользователей с отрицательной кармой (до −30 включительно) есть шанс вернуться в ряды захабренных — раз в неделю есть возможность написать публикацию или перевод в любой профильный хаб. У таких публикаций будет пометка «Recovery Mode» — если повезёт, то сообщество оценит старания и вытащит пользователя из кармаямы.
  • 109 | 110 |
  • Reset. Эта опция находится в хабрацентре и позволяет обнулить любую (как положительную, так и сильно отрицательную) карму. Крайняя мера на тот случай, когда уже ничто другое не помогает, или хочется начать «с чистого листа». Но имейте в виду, что воспользоваться этой опцией можно только один раз за всё время регистрации на сайте. Мы даём второй шанс, но только однажды.
  • 111 |
112 | 113 |

Ещё можно попытаться писать восхитительные комментарии, но это вряд ли поможет оперативно выйти из большого минуса.

114 | 115 |

Другие рейтинги

116 | 117 |

Раз уж мы заговорили о рейтингах, то огласим сразу весь список:

118 |
    119 |
  • Рейтинг публикаций
  • 120 |
  • Рейтинг компаний
  • 121 |
  • Рейтинг хабов
  • 122 |
  • Рейтинг людей
  • 123 |
124 | 125 |

В общем и целом принцип работы везде один: чем выше активность, тем выше рейтинг.

126 |
127 | ) 128 | -------------------------------------------------------------------------------- /src/components/InfoHelpLenta.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Link } from 'react-router' 3 | 4 | export default () => ( 5 |
6 |

Лента — это поток публикаций, настроенный в соответствии с вашими интересами. Собственно, все хабы, на которые вы подписаны — это и есть то, что формирует вашу ленту (если вы залогинены на ресурсе). Настроить ленту под себя за пару минут можно тут.

7 | 8 |

Если же вы любите читать сайт как гость, то по умолчанию вам будет выдаваться лента «Интересное» — это те публикации, которые по оценкам пользователей получили такой статус (их рейтинг больше или равен +5). При этом вы можете переключиться на «Всё подряд» (выводятся по дате публикации) или «Лучшее за сутки / неделю / месяц / все время».

9 | 10 |

Обратите внимание — в таком случае вам показываются публикации из всех существующих хабов, фильтрация ленты работает только для авторизованных пользователей.

11 | 12 |

RSS

13 | 14 |

У каждой из этих лент, включая вашу собственную, есть RSS. Как и у каждого хаба. Ссылку на RSS можно найти в исходном коде страницы ленты. Например:

15 | https://habrahabr.ru/rss/feed/posts/6266e7ec4301addaf92d10eb212b4546

16 | 17 |

Кроме этого, вы можете использовать ключи ?with_hubs=true: и ?with_tags=true:, если вам хочется видеть в RSS еще и хабы и теги публикации соответственно.

18 |
19 | ) 20 | -------------------------------------------------------------------------------- /src/components/InfoHelpOther.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Link } from 'react-router' 3 | 4 | export default () => ( 5 |
6 |

RSS-фиды

7 | 8 |

Уж чего-чего, а вот фидов у нас на сайте... в общем, много. Настолько много, что мы даже не стали выносить иконку для каждого из мест. Тем не менее, вы должны знать, что они у нас есть.

9 | 10 |

Самый главный фид (он уникален) — у вашей ленты: https://habrahabr.ru/rss/feed/posts/9714fef01241b028fe113f5f1a700566

11 | 12 |

В остальных местах ссылки на фиды не уникальные — просто знайте, что они у нас есть у:

13 |
    14 |
  • каждого тематического хаба
  • 15 |
  • каждого раздела хаба (всё/публикации/q&a)
  • 16 |
  • каждого подраздела хаба (захабренные/новые/отхабренные)
  • 17 |
  • раздела лучших публикаций (за сутки/неделю/месяц/всё время)
  • 18 |
  • раздела публикации (тематические и корпоративные)
  • 19 |
  • каждого результата поиска
  • 20 |
  • каждого корпоративного блога
  • 21 |
  • каждого тега к статье
  • 22 |
  • каждой публикации
  • 23 |
24 | 25 | 26 |

Горячие клавиши

27 |

Для тех, кто привык осуществлять навигацию по сайтам с помощью клавиатуры, мы прописали ряд сочетаний. Если они вам мешают, вы можете отключить их в настройках профиля.

28 | 29 |

Страницы со списком публикаций поиска и так далее

30 | 31 |
    32 |
  • j — переход к следующему элементу списка
  • 33 |
  • k — переход к предыдущему элементу списка
  • 34 |
  • h — прокрутка в самый верх страницы
  • 35 |
  • l — прокрутка в самый низ страницы
  • 36 |
  • o — открыть выбранную публикацию
  • 37 |
38 | 39 |

Страница публикации:

40 | 41 |
    42 |
  • c — написание нового комментария: прокрутка к форме написания комментария с установкой фокуса в неё
  • 43 |
  • r — обновление/подгрузка комментариев
  • 44 |
  • t — отслеживать новые комментарии в трекере
  • 45 |
  • m — присылать уведомления о новых комментариях на почту
  • 46 |
  • f — переход к следующему непрочитанному комментарию (с пометкой комментария как прочитанный)
  • 47 |
  • k — переход к предыдущему непрочитанному комментарию
  • 48 |
  • j — переход к следующему непрочитанному комментарию
  • 49 |
50 | 51 |

Вообще все страницы

52 | 53 |
    54 |
  • CTRL/ALT + Enter — отправка данных из формы, в которой находится курсор (поле комментариев, поиск и так далее)
  • 55 |
  • / — прокрутка к полю поиска с установкой фокуса на него
  • 56 |
  • ESC — закрытие левой навигационной панели
  • 57 |
58 | 59 |

А ниже просто идёт всякая всячина, которую кто-то когда-то придумал.

60 | 61 |

Кодекс авторов «Хабрахабра»

62 | 63 |

Это не документ, которого нужно строго придерживаться. Это вообще не документ. Это правила, которые соблюдают некоторые авторы на ресурсе.

64 |
    65 |
  • Я стремлюсь создавать авторские материалы и уходить от перепечатки с других сайтов.
  • 66 |
  • Публикуя материалы других авторов (графику, текст), я всегда привожу ссылки на источники.
  • 67 |
  • Я не создаю глупых комментариев с содержанием «+1», «ф топку», «афтар жжот».
  • 68 |
  • Я отказываюсь от употребления матерных слов и оскорблений на страницах ресурса.
  • 69 |
  • Я прикладываю максимум усилий для того, чтобы мои тексты были написаны без ошибок.
  • 70 |
  • Я уважаю администрацию и пользователей ресурса, не унижаю и не оскорбляю их — я здесь не для этого.
  • 71 |
  • При споре с кем-либо на страницах ресурса я стараюсь не раздувать конфликт, а самостоятельно по внутренней переписке решить проблему.
  • 72 |
  • Если мне не удалось разрешить какой-либо конфликт, я не призываю пользователей к активному противодействию и не произвожу его самостоятельно.
  • 73 |
  • Я сам решаю, публиковать или не публиковать материалы на ресурсе, и не требую за это денег.
  • 74 |
  • В случае необходимости я помогаю новичкам на ресурсе.
  • 75 |
  • Я пользуюсь поиском для уточнения, был ли подготовленный мной материал опубликован на ресурсе ранее. Если это произошло, я дополняю его в комментариях.
  • 76 |
  • Каждым своим действием на ресурсе я стремлюсь добавить порядка, а не внести хаоса.
  • 77 |
  • Своими действиями я не собираюсь способствовать разрушению сообщества или его дискредитации.
  • 78 |
  • Я не клянчу карму, я отношусь к изменениям рейтинга спокойно, но вместе с тем стараюсь учесть конструктивную критику и пожелания.
  • 79 |
  • Я — позитивен. Даже когда вокруг всё плохо, я найду выход из сложившейся ситуации и сделаю лучше.
  • 80 |
  • Я понимаю, что Хабрахабр является сообществом людей с различными интересами, и если какая-то тема мне не интересна, я не мешаю другим ее обсуждать.
  • 81 |
  • Я действую в согласии с настоящим кодексом и считаю, что только при соответствии настоящему кодексу ресурс будет настоящим социальным новостным сайтом, растущим и развивающимся.
  • 82 |
83 | 84 |

Хабраэтикет

85 | 86 |

Это не рекомендации для обязательного выполнения, это — правила этикета, придерживаться которых совсем несложно.

87 |
    88 |
  • Сетевой этикет — он и на Хабре сетевой этикет.
  • 89 |
  • Уважайте мнение других. Оно не обязано совпадать с вашим.
  • 90 |
  • Откажитесь от постинга сообщений, направленных лишь на увеличение Хабрасилы. Стремитесь просто писать интереснее и лучше.
  • 91 |
  • Аргументированная публикация, даже если она противоположна вашему мнению, не должна получать минус. Человек не обязан подстраиваться под ваши вкусы.
  • 92 |
  • Если схожие темы неоднократно поднимаются под разными предлогами, это не значит, что надо ставить минус. Это лишь значит, что проблема до сих пор не решена.
  • 93 |
  • Каждый автор имеет свою индивидуальность, потому если вы уже где-то видели подобную статью, это не значит, что в сообщении нет ничего нового и интересного. Вчитайтесь и вдумайтесь — поймите авторское мнение.
  • 94 |
  • Изменения кармы несёт гораздо большую ответственность, чем выставление оценки комментарию. 1-2 комментария не должны становиться причиной для занижения кармы.
  • 95 |
  • Не злоупотребляйте своей возможностью голосования. Необходимо понимать, что минус сильно отличается от плюса — минус угнетает человека, а не развивает его. Ставьте плюсы, когда вам что-то нравится, но подумайте, прежде чем ставить минус, если что-то не понравилось.
  • 96 |
  • Первый комментарий — это не единственный комментарий в теме. Прежде чем ставить ему оценку, прочитайте ещё парочку.
  • 97 |
  • Минус — это не аргумент, и, тем более, не контраргумент.
  • 98 |
  • Не стоит делать того, что не принято в цивилизованном обществе, противоречит законам, морали и этике.
  • 99 |
  • Не делай другим то, что не хочешь получить от них сам. Поставьте себя на место человека, с которым общаетесь. Отстаивайте свою точку зрения, но не оскорбляйте окружающих.
  • 100 |
  • Помогайте другим там, где вы это можете делать.
  • 101 |
102 | 103 |

Хабразависимость

104 | 105 |

Хабразависимость — тяжёлая форма психического расстройства, начинающаяся с регистрации на Хабрахабре.

106 | 107 |

Симптомы:

108 |
    109 |
  • Неудержимое желание посещать Хабрахабр;
  • 110 |
  • Перепады настроения прямо пропорциональны изменению кармы;
  • 111 |
  • Ежедневное посещение страницы рейтинга;
  • 112 |
  • Появление эйфории при попадании публикации на главную;
  • 113 |
  • Поиск стрелочек вверх и вниз на комментариях в ЖЖ;
  • 114 |
  • Стойкое ощущение, что за тобой следит НЛО.
  • 115 |
116 |

(Список не полон и может расширяться)

117 | 118 |

Лечение: на данный момент эффективные методы лечения науке неизвестны.

119 | 120 |

Хабраэффект

121 | 122 |

Хабраэффект — резкое увеличение посещаемости сайта после того, как ссылка на данный ресурс появилась на Хабрахабре.

123 | 124 |

Бяка данного эффекта заключается в том, что из-за резкого повышения посещаемости сайта генерируется огромный трафик, превращаясь в неумышленную, но тем не менее небезобидную DoS-атаку.

125 | 126 |

Хабраэффект чаще всего наблюдается в течение нескольких десятков минут, но может затянуться и до нескольких часов. Наплыв пользователей может не проходить и в течение дня — двух, пока новость с адресом ресурса не пропадёт с главной страницы Хабра.

127 | 128 |

Бытует мнение, что хабраэффекту подвержены только новые и не раскрученные сайты с малыми мощностями, но это не так. В своё время хабраэффект смог «положить на лопатки» немало крупных проектов — обо всех случаях можно узнать из несложного поискового запроса на Хабре. 129 |

130 | 131 |

API

132 | 133 |

У «Хабрахабра» есть непубличный API, доступ к которому предоставляется только по запросу через форму обратной связи.

134 |

135 |
136 | ) 137 | -------------------------------------------------------------------------------- /src/components/InfoHelpPosts.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Link } from 'react-router' 3 | import styled from 'styled-components' 4 | 5 | const InfoHelpPosts = () => ( 6 |
7 |

Самое важное, что есть на сайте — это публикации. Создавать их могут пользователи с полноценными аккаунтами и положительной кармой (для ряда хабов входной порог по карме может отличаться).

8 | 9 |

Создание публикации

10 | 11 |

Сам процесс создания публикации довольно прост:

12 |
    13 |
  • кликните по иконке карандаша в левом меню — {window.location.origin}/topic/add/;
  • 14 |
  • выберите поток, в который будет размещена публикация;
  • 15 |
  • выберите хаб, лучше всего подходящий по тематике (или нескольких хабов);
  • 16 |
  • если ваша публикация является обучающей, уроком или how-to — отметьте чекбокс «Обучающий материал», это поможет визуально выделить ее среди прочих;
  • 17 |
  • дайте публикации понятный заголовок, заполните тело публикации, используя нужные теги или markdown-разметку для форматирования текста, и не забудьте указать метки;
  • 18 |
  • при желании — добавьте опрос с вариантами ответа;
  • 19 |
  • c помощью кнопки «Предпросмотр» оцените то, что у вас получилось (возможно, где-то не закрыт тег, не вставилась картинка или еще что-то);
  • 20 |
  • если всё в порядке — нажмите зеленую кнопку «Опубликовать»;
  • 21 |
  • если захочется внести в публикацию какие-то изменения — воспользуйтесь иконкой карандаша справа от её заголовка, это позволит отредактировать ее или убрать ее в черновики.
  • 22 |
23 | 24 |

Черновики видны только вам (о статусе черновика говорит иконка замка слева от заголовка публикации).

25 | 26 |

Перевод

27 | 28 |

Если нажать на слово «Публикацию» во фразе «Хочу опубликовать публикацию», то ниспадающее меню предложит вам выбрать второй доступный для создания вид записи — «Перевод». Механизм создания тот же, что и у публикации, но есть два дополнительных поля — «Автор оригинала» (тут надо указать имя автора оригинального текста) и «Ссылка на оригинал» (здесь — URL страницы оригинала).

29 | 30 |

Признаки хорошей и плохой публикации

31 |

Хорошая публикация:

32 |
  • Содержит авторский контент;
  • 33 |
  • Удобна для чтения, разбита на абзацы и в целом хорошо отформатирована. Картинки залиты на Habrastorage;
  • 34 |
  • Написана максимально грамотным для индивида русским языком;
  • 35 |
  • Не содержит того, что есть в плохих публикациях.
  • 36 |
37 | 38 |

Плохая публикация:

39 |
  • Имеет кричащий заголовок вида «Шок! ВИДЕО! ВИРУСЫ В МАКАХ!»;
  • 40 |
  • Переполнена грамматическими и орфографическими ошибками, игнорирует правила русского языка в общем;
  • 41 |
  • Содержит слова из «падонкаффского» сленга и прочую нечисть;
  • 42 |
  • Содержит изображения с нестабильных фотохостингов;
  • 43 |
  • Состоит из информации с других ресурсов;
  • 44 |
  • Является жалобой на что-либо;
  • 45 |
  • Содержит реферальные ссылки на что угодно;
  • 46 |
  • Содержит запрещённый или просто нелицеприятный контент;
  • 47 |
  • Является рекламой своего или чужого проекта, сервиса, приложения, сайта, etc.
  • 48 |
49 | 50 |

Разрешённые html-теги

51 |

При написании публикаций и комментариев можно использовать следующие html- и не совсем html-теги:

52 | 53 |
54 | 55 |

Стандартные

56 | 57 | 58 | 59 | 60 | 61 | 62 | 65 | 69 | 70 | 71 | 72 | 73 | 77 | 78 | 79 | 80 | 81 | 85 | 86 | 87 | 88 | 89 | 93 | 94 | 95 | 96 | 97 | 101 | 102 | 103 | 104 | 105 | 109 | 110 | 111 | 112 | 113 | 117 | 118 | 119 | 120 | 121 | 125 | 126 | 127 | 128 | 129 | 133 | 134 | 135 | 136 | 137 | 141 | 142 | 143 | 144 | 147 | 152 | 153 | 154 | 155 | 156 | 160 | 161 | 162 | 163 | 164 | 169 | 170 | 171 | 172 | 173 | 177 | 178 | 179 | 180 | 181 | 185 | 186 | 187 | 188 | 193 | 197 | 198 | 199 | 200 | 203 | 207 | 208 |
ТегОписание
63 | <h1></h1>...<h4></h4> 64 | 66 |

Заголовки разного уровня.

67 |
<h1>Заголовок первого уровня</h1>...<h4>Заголовок четвертого уровня</h4>
68 |
<img/> 74 |

Вставка изображения, в атрибуте src нужно указывать полный путь к изображению. Возможно выравнивание картинки атрибутом align.

75 |
<img src="" alt="image alt" align="left" />
76 |
<a></a> 82 |

Вставка ссылки, в атрибуте href указывается желаемый интернет-адрес или якорь (anchor) для навигации по странице.

83 |
<a to="http://your_link_path.ru">Текст ссылки</a>
84 |
<anchor></anchor> 90 |

Тег для указания якоря. Для вызова используйте тег вставки ссылок.

91 |
<a to="#example">Example</a>
92 |
<strong></strong> 98 |

Выделение важного текста, на странице выделяется жирным начертанием. Также возможно использование альтернативного тега <b></b>

99 |
<strong>Жирное начертание</strong>
100 |
<em></em> 106 |

Выделение важного текста, на странице выделяется курсивом. Также возможно использование альтернативного тега <i></i>

107 |
<em>Курсивное начертание</em>
108 |
<strike></strike> 114 |

Текст между этими тегами будет отображаться как зачеркнутый. Также возможно использование альтернативного тега <s></s>

115 |
<strike>Зачеркнутый текст</strike>
116 |
<u></u> 122 |

Текст между этими тегами будет отображаться как подчеркнутый.

123 |
<u>Подчеркнутый текст</u>
124 |
<hr/> 130 |

Тег для вставки горизонтальной линии.

131 |
<hr/>
132 |
<blockquote></blockquote> 138 |

Используйте этот тег для выделения цитат.

139 |
<blockquote>Текст цитаты</blockquote>
140 |
145 | <table></table>
146 |
148 |

Набор тегов для создания таблицы. Тег <td> обозначает ячейку таблицы, тег <th> - ячейку в заголовке, <tr> - строчку таблицы. Все содержимое таблицы помещайте в тег <table>.

149 | 150 |
<table>
  <tr>
    <th>Колонка 1</th>
    <th>Колонка 2</th>
     <th>Колонка 3</th>
  </tr>
  <tr>
    <td>Ячейка 1</td>
    <td>Ячейка 2</td>
    <td>Ячейка 3</td>
  </tr>
  <tr>
    <td>Ячейка 1</td>
    <td>Ячейка 2</td>
    <td>Ячейка 3</td>
  </tr>
</table>
151 |
<sup></sup>,
<sub></sub>
157 |

Текст, заключенный в тег <sup> отображается в виде надстрочного, <sub> - в виде подстрочного.

158 |
<sup>надстрочный</sup>, <sub>подстрочный</sub>
159 |
<abbr></abbr>
165 |

Тегом <abbr> выделяется аббревиатура, в атрибуте title=""указывайте её расшифровку. Используйте тег <acronym> для устоявшихся аббревиатур.

166 |
<abbr title="ABBR">Рашифровка аббревиатуры</abbr>
167 |
<acronym title="Accronym">Рашифровка аббревиатуры</acronym>
168 |
<pre></pre> 174 |

Текст в теге <pre> не форматируется автоматически.

175 |
<pre>Неформатированный текст</pre>
176 |
<nobr></nobr> 182 |

Текст, помещенный в тег <nobr>, не переносится на странице; для принудительного переноса текста используйте тег <br/> ; для аккуратного выравнивания изображений используйте атрибут clear="all|left||right" в теге <br />.

183 |
<nobr>Текст без переносов</nobr>, <br clear="all|left||right" />
184 |
189 | 190 | <ul></ul> 191 | 192 | 194 |

Ненумерованный список; каждый элемент списка задается тегом <li>, набор элементов списка помещайте в тег <ul>.

195 |
<ul>
  <li>Пункт 1</li>
  <li>Пункт 2</li>
  <li>Пункт 3</li>
</ul>
196 |
201 | <ol></ol> 202 | 204 |

Нумерованный список; каждый элемент списка задается тегом <li>, набор элементов списка помещайте в тег <ol>.

205 |
<ol>
  <li>Пункт 1</li>
  <li>Пункт 2</li>
  <li>Пункт 3</li>
</ol>
206 |


209 | 210 |

Теги Хабрахабра

211 | 212 | 213 | 214 | 215 | 216 | 217 | 223 | 224 | 225 | 226 | 231 | 232 | 233 | 234 | 235 | 239 | 240 | 241 | 242 | 243 | 247 | 248 | 249 | 250 | 251 | 255 | 256 |
ТегОписание
<cut/> 218 | 219 | 220 |

Используется только в текстах публикаций, скрывает под кат часть текста, следующую за тегом (появится кнопка с текстом «Читать дальше»). Чтобы изменить текст в кнопке, используйте аттрибут text="..."

221 |
<cut/>, <cut text="Ваш текст"/>
222 |
<source></source> 227 | 228 |

Подсвечивает исходный код. Для поддержки конккретного синтаксиса, используйте аттрибут lang=""

229 |
<source lang="javascript">Исходный код</source>
230 |
<oembed></oembed> 236 |

Вставка интерактивного слайд-шоу. Пока поддерживается только сервис Slideshare.net и Scribd.com.

237 |
<oembed>http://slideshare.net/</oembed>
238 |
<spoiler></spoiler> 244 |

Вставка спойлера (разворачиваемый блок информации). Чтобы изменить текст заголовка спойлера используйте аттрибут title="…"

245 |
<spoiler title="Заголовок спойлера">Содержимое спойлера</spoiler>
246 |
@username 252 |

Выводит имя пользователя в тексте и отправляет пользователю уведомление о том, что его упомянули в публикации/комментарии. Вы можете использовать конструкцию @username, где username — это имя пользователя.

253 |
@username
254 |
257 |


258 | 259 |

Добавление формул

260 | 261 |

Вы также можете добавлять в свои публикации математические формулы, используя язык разметки LaTeX.

262 |

Для отрисовки формул на странице мы используем библиотеку MathJax.

263 | 264 |

Чтобы добавить формулу нажмите на иконку Σ в тулбаре. В появившемся модальном окне выберите строчный или блочный тип формулы.

265 |
    266 |
  • cтрочная формула используется для вставки формулы в абзац текста
  • 267 |
  • блочная формула используется для вставки формулы с новой строки
  • 268 |
269 | 270 |

После составления формулы нажмите на кнопку «Добавить формулу» и она появится в тексте публикации.

271 | 272 |

ППА

273 |

Аббревиатура «ППА» на Хабрахабре расшифровывается как Программа Поощрения Авторов. Помимо признания аудитории, авторы могут получать денежное вознаграждение за хорошие публикации — очевидно же!

274 | 275 |

В программе могут принимать участие пользователи, обладающие хотя бы одним из значков: «Автор», «Звезда», «Легенда» и «Старожил». А дальше, всё, что надо — просто размещать интересные публикации или переводы в профильные хабы, не более того. Более подробно узнать о ППА можно на отдельной странице.

276 | 277 | 278 | 279 |
280 | ) 281 | 282 | export default styled(InfoHelpPosts)` 283 | .table{ 284 | table-layout: fixed; 285 | } 286 | .table__head th{ 287 | background-color: #eaecea!important; 288 | } 289 | .table__column_html{ 290 | width: 25%; 291 | } 292 | .table__column_desc{ 293 | width: 75%; 294 | } 295 | ` 296 | -------------------------------------------------------------------------------- /src/components/InfoHelpRegistration.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Link } from 'react-router' 3 | 4 | export default () => ( 5 |
6 |

Для регистрации на ресурсе используется единый аккаунт TM ID. Зарегистрировавшись, вы сможете входить на «Хабрахабр», Geektimes, «Тостер», «Фрилансим» в 1 клик по кнопке «Войти с TM ID». На ресурсах общие никнейм и почта, поэтому учтите, что просьба изменить никнейм или почту приведет к их смене на всех этих сайтах, кроме «Фрилансим».

7 | 8 |

Это же касается и удаления аккаунта — при запросе на удаление с «Хабрахабра», Geektimes или «Тостера» аккаунт будет удален со всех этих ресурсов.

9 | 10 |

Права

11 | 12 |

Права вашего аккаунта зависят от цели вашего пребывания на ресурсе.

13 | 14 |
    15 |
  • ReadOnly — базовый аккаунт, доступен сразу после регистрации. Позволяет читать материалы, опубликованные на сайте, добавлять их в «Избранное», формировать собственную ленту по интересам. Голосовать за что-либо, писать с него личные сообщения или публикации сразу на сайт нельзя — только в Песочницу.
    16 | ReadOnly-аккаунт имеет возможность писать комментарии к статьям в течение 10 дней с момента их публикации.
    17 | Комментарии попадают на модерацию к авторам публикаций и модераторам сайта. Как только один из ваших комментариев будет одобрен, аккаунт автоматически переводится в статус Read&Comment.
  • 18 | 19 |
  • Read&Comment — тип аккаунта, обозначающий, что у вас уже есть как минимум один опубликованный комментарий. Профиль пользователя выглядит как и у полноценного аккаунта — есть рейтинг и карма, за которую другие пользователи могут голосовать с некоторым ограничением: карма пользователя не имеющего публикации на сайте не может подняться выше +4. Появляется возможность писать личные сообщения другим участникам сообщества.
    20 | Комментарии начинают появляться на сайте сразу, без модерации, как только пользователь получает 10 одобрений от 10 разных авторов или модераторов.
    21 | Голосование на данном этапе еще не доступно, а публикации по-прежнему можно публиковать только в Песочницу.
  • 22 | 23 |
  • Полноценный аккаунт — получен с помощью приглашения и позволяет писать публикации напрямую на сайт. До тех пор, пока у вас нет ни одной публикации на сайте ваша карма не может подняться выше +4. Данное ограничение снимается сразу после написания первой публикации.
  • 24 |
25 | 26 |

Приглашение

27 | 28 |

Получить приглашение не так сложно, как кажется. Достаточно сделать что-то из следующего:

29 | 30 |
    31 |
  • написать публикацию в Песочницу. Если она пройдет проверку модератором на соответствие тематике сайта, то или сразу получит приглашение от модераторов, или окажется в общей Песочнице, которую читают пользователи. И кто-то вполне сможет выдать вам приглашение, после чего аккаунт станет полноценным.
  • 32 | 33 |
  • быть сотрудником компании, которая ведет на «Хабре» корпоративный блог, и писать для него. В таких случаях администратор блога может использовать приглашения компании для перевода вашего аккаунта в полноценный.
  • 34 | 35 |
  • быть другом пользователя, у которого есть приглашение. Такой пользователь может самостоятельно использовать своё приглашения для вашего аккаунта, будь то ReadOnly или Read&Comment (только если ваш аккаунт в ReadOnly не потому, что вы нарушали правила).
  • 36 | 37 |
  • выиграть приглашение в конкурсах, временами проводимых в наших официальных группах ВКонтакте, Twitter или Facebook.
  • 38 | 39 |
40 | 41 |

Некоторые сомнительные ресурсы предлагают продажу приглашений на «Хабр», но этим стоит пользоваться только в случаях, если хочется и заплатить кому-то, и всё равно остаться без аккаунта. Будьте бдительны.

42 | 43 |

А вот способы заработать приглашение для друга (или просто про запас), если у вас уже есть полноценный аккаунт:

44 | 45 |
    46 |
  • набрать 50 единиц кармы (даётся 1 приглашение единовременно, даже если карму после этого понизят — приглашение остаётся на балансе аккаунта);
  • 47 | 48 |
  • написать публикацию, которая после окончания срока голосования получит рейтинг выше +50. За каждую такую публикацию, если это не хаб-оффтопик, выдаётся 1 приглашение.
  • 49 |
50 | 51 |

Песочница

52 | 53 |

Раздел, куда попадают публикации от желающих получить приглашение. Перед попаданием в общую Песочницу каждая публикация проходит проверку модератором на соответствие правилам, тематике и общую адекватность.

54 | 55 |

Вот что можно сразу не писать в Песочницу, чтобы сэкономить время:

56 | 57 |
    58 |
  • публикации, которые не имеют отношения к тематике сайта;
  • 59 |
  • уже где-то опубликованные тексты;
  • 60 |
  • публикации, нарушающие общие правила сайта;
  • 61 |
  • новости и анонсы;
  • 62 |
  • статьи рекламного характера и PR-тексты;
  • 63 |
  • вопросы и просьбы о помощи (ведь есть toster.ru).
  • 64 |
65 | 66 |

Проверка модератором может длиться долгое время (но вы можете написать в Песочницу более одной публикации). Даже очень долгое время. После проверки вам на почту придет письмо о вердикте.

67 | 68 |

Вердиктов может быть три:

69 | 70 |
    71 |
  • модератору понравилась публикация и он сам выдал за неё приглашение;
  • 72 |
  • модератор счел публикацию подходящей и просто пропустил в общую Песочницу, оставив решение о выдаче приглашения за пользователями сайта;
  • 73 |
  • модератор отклонил публикацию и сообщил, почему. Или не сообщил, тут уж как повезет.
  • 74 |
75 | 76 |

Обратите внимание — если публикация отклоняется совсем, мы более не храним у себя её текст, поэтому заранее дублируйте важные сведения у себя.

77 | 78 |

Как видите, Песочница не так страшна, как вам могли рассказывать.

79 | 80 |

Приятный бонус — если вы успешно проходите Песочницу на «Хабре», то получаете ещё и приглашение на Geektimes. Песочница же на Geektimes приносит приглашения только на Geektimes.

81 |
82 | ) 83 | -------------------------------------------------------------------------------- /src/components/InfoHelpRules.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | export default () => ( 4 |
5 |

Последнее редактирование — 16 мая 2016.

6 | 7 |

Обычно IT-специалисты и интересующиеся данной сферой — это люди культурные, уважающие не только себя, но и собеседников и читателей. Для того чтобы ресурс оставался площадкой для общения таких людей, существуют правила, за нарушение которых модераторы могут понизить права аккаунта до ReadOnly.

8 | 9 |

Вот список того, чего на ресурсе делать не следует

10 | 11 |
    12 |
  • Рекламировать собственные ресурсы в обход правил. Для самопиара или официального продвижения своих продуктов и сервисов в потоке «Разное» у нас есть специальный хаб «Я пиарюсь» и корпоративные блоги. Попытки поместить такую рекламу вне указанных разделов влекут за собой понижение прав аккаунта. На первый раз — временно.
    13 | Для рекламы и анонсов событий или мероприятий следует использовать возможности корпоративных блогов.
    14 | Обратите внимание — не имеет значения, рекламируете ли вы платный продукт или бесплатный. Если это OpenSource-решение, достаточно ссылки на GitHub, ссылка же на собственный сайт проекта — это уже реклама. Для продвижения youtube-каналов и групп в соцсетях следует также использовать «Я пиарюсь».
    15 | Однако, в настройках профиля пользователя или компании вы можете указать несколько ссылок на собственные ресурсы и социальные аккаунты, которые будут отображаться в вашем профиле, а также в блоке с информацией об авторе после текста публикации.
  • 16 | 17 |
  • Заниматься копипастом и кросспостом. Мы всячески приветствуем интересный и полезный сообществу контент, но только если он оригинальный. Поэтому не следует копипастить на «Хабр» тексты, которые ранее были опубликованы на других ресурсах (даже если вы — автор такого текста).
  • 18 | 19 |
  • Путать «Хабр» с Твиттером. Односложные публикации вида «Смотрите, какую я нашел ссылку», «Chrome обновился, вот тут чейнджлог» и подобное не приветствуются.
    20 | Даже если новость изначально короткая, постарайтесь сопроводить её развёрнутым комментарием.
  • 21 | 22 |
  • Путать «Хабр» с жалобной книгой. Если у вас проблемы с сотовым оператором, с провайдером интернета или хостинга, или с чем-то ещё, всегда можно связаться со службой поддержки нужного вам ресурса. Или с компетентными органами. Но не следует использовать «Хабр» как рупор, дабы рассказать всем о постигшей вас ситуации.
  • 23 | 24 |
  • Инициировать политические дискуссии и участвовать в них. Тематика нашего ресурса определена довольно чётко. Для рассуждений о политике есть куда более подходящие сайты. Но не «Хабр».
  • 25 | 26 |
  • Пытаться собирать средства на проекты. Здесь тоже всё просто — для сбора средств существуют специально созданные для этого площадки.
  • 27 | 28 |
  • Постоянно использовать смайлики, коверкать слова, игнорировать правила русского языка. Даже если русский язык был не самым вашим любимым предметом в школе или не является родным — проверка орфографии в браузере у вас наверняка есть, не стоит ею пренебрегать. Это сохранит как вашу карму от минусов, так и ваш аккаунт.
  • 29 | 30 |
  • Оскорблять других пользователей, не следить за эмоциями. Мат, оскорбления, переходы на личности, эвфемизмы, троллинг — хорошие способы быстро и надежно сменить текущий статус аккаунта на ReadOnly.
  • 31 | 32 |
  • Создавать виртуалов. Всегда приятно поговорить с умным человеком, но создавать для этого добавочные аккаунты и накручивать с них карму и голоса за публикации не стоит.
  • 33 |
34 | 35 |

Список нарушений остаётся открытым, потому что всегда можно придумать что-то, не описанное выше. В таких случаях модераторы руководствуются здравым смыслом и собственным чувством прекрасного. Обсуждать их решения и создавать на эту темы агитационные публикации не стоит — если они кого-то забанили, значит, у них была довольно веская причина.

36 | 37 |

Как видите, ничего сложного в правилах нет, и мы будем рады, если вы будете их соблюдать.

38 |
39 | ); 40 | -------------------------------------------------------------------------------- /src/components/InfoHelpSettings.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Link } from 'react-router' 3 | 4 | export default () => ( 5 |
6 |

Настроить у нас можно вот что:

7 | 8 |

Профиль

9 |

Именно эта страница поможет установить аватар, задать отображаемое имя, написать «О себе» и указать контакты в социальных сетях. Тут же настраиваются ссылки, которые будут отображаться в вашей панели автора публикаций.

10 |

Никнейм самостоятельно не меняется, для этого нужно обратиться в службу поддержки с темой «Смена данных»

11 | 12 |

Аккаунт

13 |

По клику на эту вкладку произойдет редирект на https://id.tmtm.ru/settings/ — так и задумано. Здесь можно сменить свой пароль для TM ID, указать новую почту или привязать к аккаунту профили социальных сетей для авторизации в 1 клик.

14 | 15 |

Приватность

16 |

Если вы хотите, чтобы вам в личные сообщения могли писать только те, на кого вы подписаны, а не все подряд — вам помогут настройки с этой вкладки. Также здесь можно настроить, кому именно показывать вашу активность на ресурсе в трекере и указанные в профиле контакты.

17 | 18 |

Уведомления

19 |

Всё, что связано с уведомлениями, которые сайт посылает вам на почту или в трекер.
20 | Обратите внимание, настройка дайджеста интересных публикаций по вашим тегам находится на этой же странице.

21 | 22 |

Приложения

23 |

Отображает список приложений, в которых выполнен вход, используя логин на сайте TM ID.
Также выводит список ваших приложений и их ключей, для которых есть доступ к API сайта habr/ahabr/.

24 | 25 |

Разные

26 |

У нас есть горячие клавиши и панель обновления комментариев, пользоваться ими или нет — можно решить на этой вкладке. Здесь же пользователи со значками «Легенда» могут отключить отображение рекламы на ресурсе.

27 |
28 | ) 29 | -------------------------------------------------------------------------------- /src/components/MainNavBar.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Link } from 'react-router' 3 | import SearchForm from './SearchForm'; 4 | import UserNavBar from './UserNavBar'; 5 | 6 | const MainNavBar = () => ( 7 |
8 |
9 | 10 | 16 | 17 | 34 | 35 |
36 | 37 |
38 | ); 39 | 40 | export default MainNavBar; 41 | -------------------------------------------------------------------------------- /src/components/NotFound.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import { Link } from 'react-router' 3 | import Helmet from 'react-helmet' 4 | 5 | class NotFound extends Component { 6 | componentWillMount() { 7 | document.body.style.display = 'none' 8 | } 9 | 10 | componentDidMount() { 11 | // HACK стили подключаются в Helmet после рендеринга страницы 12 | // TODO: https://habrahabr.ru/post/322084/#comment_10266132 13 | setTimeout(() => (document.body.style.display = 'block'), 100) 14 | } 15 | 16 | render() { 17 | return ( 18 |
19 | 23 |
24 |
25 | 26 | 27 | 28 |
29 | 30 |

Страница не найдена

31 |

Страница устарела, была удалена или не существовала вовсе

32 | 33 |
34 | Вернуться на главную 35 |
36 |
37 |
38 | ) 39 | } 40 | } 41 | 42 | export default NotFound 43 | -------------------------------------------------------------------------------- /src/components/PostFull.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Link } from 'react-router' 3 | import { connect } from 'react-redux' 4 | import { createSelector } from 'reselect' 5 | 6 | import { urlencode } from '../utils' 7 | 8 | import PostHeader from './PostHeader' 9 | import PostInfoPanel from './PostInfoPanel' 10 | import FormAdminCauses from './FormAdminCauses' 11 | import PostType from './PostType' 12 | import AuthorInfoByCompany from './AuthorInfoByCompany' 13 | import AuthorInfo from './AuthorInfo' 14 | 15 | const PostFull = ({ id, published, flow, hubs, title, author, company, tags, content, viewsCount, favoritesCount }) => ( 16 |
17 |
{/* TODO убрать, добавил для отступа, пока не реализован PageHeader */} 18 |
19 |
20 | 21 |
22 |
{content}
23 | { !!tags && tags.length > 0 && 24 |
25 |
    26 | { tags.map(tag =>
  • {tag}
  • )} 27 |
28 |
29 | } 30 |
31 |
32 |
33 | 34 | 35 | 36 | { !!company ? : } 37 |
38 |
39 |
40 | ) 41 | 42 | const getPostId = (state, props) => 43 | parseInt(props.params.postId, 10) 44 | 45 | const getPosts = (state) => 46 | state.posts 47 | 48 | const getPost = createSelector( 49 | [getPosts, getPostId], 50 | (posts, postId) => 51 | posts.find(element => 52 | element.id === postId) 53 | ) 54 | 55 | const mapStateToProps = (state, ownProps) => { 56 | const post = getPost(state, ownProps) 57 | return {...post} 58 | } 59 | 60 | const mapDispatchToProps = (dispatch) => { 61 | return {} 62 | } 63 | 64 | export default connect(mapStateToProps, mapDispatchToProps)(PostFull) 65 | -------------------------------------------------------------------------------- /src/components/PostHeader.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Link } from 'react-router' 3 | 4 | import { ga, formatDateTime } from '../utils' 5 | 6 | // TODO получать flow в props, как объект (нужна нормализация данных) 7 | // TODO хаб "Блок компании Рога и копыта" для собственнных хабов компании 8 | // TODO флажки к названию: Tutorial, Recovery mode, Из песочницы, Перевод 9 | // TODO кнопка редактирования для собственных статей 10 | 11 | const PostHeader = ({ isTeaser, id, title, published, flow, hubs }) => ( 12 |
13 | {formatDateTime(published)} 14 |

15 | { isTeaser ?
{flow.name} → {title}
: {title} } 16 |

17 |
{/* TODO добавить запятые между элементами списка посредством CSS */} 18 | {/* TODO обернуть каждый хаб в
для отображения .profiled_hub */} 19 | {/* hub.isProfiled && * */} 20 | {hubs.map(hub => 21 | {hub.name} 22 | )} 23 |
24 |
25 | ) 26 | 27 | export default PostHeader 28 | -------------------------------------------------------------------------------- /src/components/PostInfoPanel.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Link } from 'react-router' 3 | 4 | import { ga } from '../utils' 5 | 6 | // TODO через трое суток вводится запрет на голосование и отображаются результаты 7 | 8 | // TODO format viewsCount & favoritesCount 9 | 10 | // TODO исправить выравнивание "-" между стрелочек голосования за статью 11 | 12 | const PostInfoPanel = ({ id, author, viewsCount, favoritesCount, isTeaser }) => { 13 | 14 | const postsAddToFavorites = (event) => { 15 | // TODO posts_add_to_favorite}(this, '2', id) 16 | alert('postsAddToFavorite') 17 | } 18 | 19 | const postsVotePlus = (event) => { 20 | // TODO posts_vote(this, id, '2', 1) 21 | alert('postsVotePlus') 22 | ga('voting_location', 'plus', window.location.href) 23 | } 24 | 25 | const postsVoteMinus = (event) => { 26 | // TODO posts_vote(this, id, '2', -1) 27 | alert('postsVoteMinus') 28 | ga('voting_location', 'minus', window.location.href) 29 | } 30 | 31 | const postsVoteZero = (event) => { 32 | // TODO posts_vote(this, id, '2', 0) 33 | alert('postsVoteZero') 34 | ga('voting_location', 'zero', window.location.href) 35 | } 36 | 37 | return ( 38 |
{/* убрал js-user_ */} 39 |
    40 |
  • 41 |
    42 | 45 |
    46 | 47 |
    48 | 51 |
    52 |
  • 53 |
  • 54 |
    {viewsCount}
    55 |
  • 56 |
  • 57 |
    58 | 61 | {favoritesCount} 62 |
    63 |
  • 64 | {isTeaser && 65 |
  • 66 | 67 | {!!author.avatar ? {author.name} : }@{author.nick} 68 | 69 |
  • 70 | } 71 | {isTeaser && 72 |
  • 73 |
    74 | 75 | Комментировать 76 | 77 |
    78 |
  • 79 | } 80 |
  • 81 | {!isTeaser && 82 |
      {/* TODO реализовать шеринг в соцсети, пока удалил код из якорей */} 83 |
    • 84 | 85 |
    • 86 |
    • 87 | 88 |
    • 89 |
    • 90 | 91 |
    • 92 |
    • 93 | 94 |
    • 95 |
    96 | } 97 |
  • 98 |
99 |
100 | ) 101 | } 102 | 103 | export default PostInfoPanel 104 | -------------------------------------------------------------------------------- /src/components/PostTeaser.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Link } from 'react-router' 3 | import PostHeader from './PostHeader' 4 | import PostInfoPanel from './PostInfoPanel' 5 | 6 | const PostTeaser = ({ id, published, flow, hubs, title, content, author, viewsCount, favoritesCount }) => ( 7 |
8 | 9 |
10 |
{content}
11 |
12 | {/* TODO изменяемое название для habracut */} 13 | Читать дальше → 14 |
15 |
16 |
17 | 18 |
19 |
20 | ) 21 | 22 | export default PostTeaser 23 | -------------------------------------------------------------------------------- /src/components/PostTeaserList.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { connect } from 'react-redux' 3 | // import { Link } from 'react-router' 4 | import { createSelector } from 'reselect' 5 | 6 | import PostTeaser from './PostTeaser' 7 | 8 | // TODO при скролировании страницы, зачем-то присваивается класс focus для